png.c revision af9320404a7b05014476f844b11110157a21b73e
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N   N   GGGG                              %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P   P  NN  N  G                                  %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N N N  G  GG                              %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N  NN  G   G                              %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N   N   GGG                               %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              Read/Write Portable Network Graphics Image Format              %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                           Glenn Randers-Pehrson                             %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               November 1997                                 %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21b56bb24a985ca4366713bcd8ffdfacbb48a98a2fcristy%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/studio.h"
4516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/artifact.h"
4616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/attribute.h"
4716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/blob.h"
4816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/blob-private.h"
4916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/cache.h"
50aa2c16cb5e695053aa78e40f66bc36fbef4b1ed1cristy#include "MagickCore/channel.h"
5116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color.h"
5216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/color-private.h"
5316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colormap.h"
5416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace.h"
5516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/colorspace-private.h"
5616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/constitute.h"
5716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/enhance.h"
5816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception.h"
5916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/exception-private.h"
6016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/geometry.h"
6116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/histogram.h"
6216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image.h"
6316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/image-private.h"
6416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/layer.h"
6516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/list.h"
6616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/log.h"
6716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/MagickCore.h"
6816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/memory_.h"
6916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/module.h"
7016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor.h"
7116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/monitor-private.h"
7216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/option.h"
7316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel.h"
7416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/pixel-accessor.h"
7516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/profile.h"
7616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/property.h"
7716ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
7816ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/resource_.h"
7916ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/semaphore.h"
8016ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/quantum-private.h"
8116ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/static.h"
8216ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/statistic.h"
8316ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string_.h"
8416ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/string-private.h"
8516ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/transform.h"
8616ea139d53d867211d3bb0fa859a83de653f687ecristy#include "MagickCore/utility.h"
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
88286a6355c4544b794da2b6df973faad07c69e541glennrp
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
907ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
91faa852bad40107edae19405e76a299057668d795glennrp * migration to libpng-1.5, remove these defines and then
927ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
937ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
94991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp/* #define PNG_DEPRECATED   Use of this function is deprecated */
95faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_USE_RESULT   The result of this function must be checked */
96faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_NORETURN     This function does not return */
97faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_ALLOCATED    The result of the function is new memory */
988371ecc013ff231ce380d8717e517312e62e1f01glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
995b927348e949d94f3a64b055eccb03459f115c69glennrp
1005b927348e949d94f3a64b055eccb03459f115c69glennrp/* PNG_PTR_NORETURN does not work on some platforms, in libpng-1.5.x */
10175cfe702843fd25dba7cb241c05fa65957c67129cristy#define PNG_PTR_NORETURN
102286a6355c4544b794da2b6df973faad07c69e541glennrp
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1278e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp       (((color).red == (target).red) && \
1288e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).green == (target).green) && \
1298e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).blue == (target).blue))
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp/* Table of recognized sRGB ICC profiles */
133ecab7d7b7fc598881ff3c72240381caa5c444a56glennrpstruct sRGB_info_struct
134ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp{
135ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    png_uint_32 len;
136ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    png_uint_32 crc;
137ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    png_byte intent;
138ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp};
139ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
140ecab7d7b7fc598881ff3c72240381caa5c444a56glennrpconst struct sRGB_info_struct sRGB_info[] =
141ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp{
142c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v2 perceptual sRGB_IEC61966-2-1_black_scaled.icc */
143ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    { 3048, 0x3b8772b9UL, 0},
144ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
145c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v2 relative sRGB_IEC61966-2-1_no_black_scaling.icc */
146ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    { 3052, 0x427ebb21UL, 1},
147ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
148c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v4 perceptual sRGB_v4_ICC_preference_displayclass.icc */
149ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {60988, 0x306fd8aeUL, 0},
150ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
151c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* ICC v4 perceptual sRGB_v4_ICC_preference.icc perceptual */
152ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     {60960, 0xbbef7812UL, 0},
153ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
154c241d3cdc951647513766801b3f1cfc74b773b5eglennrp    /* HP? sRGB v2 media-relative sRGB_IEC61966-2-1_noBPC.icc */
155ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     { 3024, 0x5d5129ceUL, 1},
156ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
157ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     /* HP-Microsoft sRGB v2 perceptual */
158ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     { 3144, 0x182ea552UL, 0},
159ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
160ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     /* HP-Microsoft sRGB v2 media-relative */
161ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     { 3144, 0xf29e526dUL, 1},
162ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
163c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     /* Facebook's "2012/01/25 03:41:57", 524, "TINYsRGB.icc" */
164c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     {  524, 0xd4938c39UL, 0},
165c241d3cdc951647513766801b3f1cfc74b773b5eglennrp
166c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     /* "2012/11/28 22:35:21", 3212, "Argyll_sRGB.icm") */
167c241d3cdc951647513766801b3f1cfc74b773b5eglennrp     { 3212, 0x034af5a1UL, 0},
168c241d3cdc951647513766801b3f1cfc74b773b5eglennrp
169ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     /* Not recognized */
170ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     {    0, 0x00000000UL, 0},
171ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp};
172ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
1738e58efdecda887b08ef730d68290a61081ef2566glennrp/* Macros for left-bit-replication to ensure that pixels
17416ea139d53d867211d3bb0fa859a83de653f687ecristy * and PixelInfos all have the same image->depth, and for use
1758e58efdecda887b08ef730d68290a61081ef2566glennrp * in PNG8 quantization.
1768e58efdecda887b08ef730d68290a61081ef2566glennrp */
1778e58efdecda887b08ef730d68290a61081ef2566glennrp
1788e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR01: Replicate top bit */
1798e58efdecda887b08ef730d68290a61081ef2566glennrp
18005001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR01PacketRed(pixelpacket) \
1818e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=(ScaleQuantumToChar((pixelpacket).red) < 0x10 ? \
1828e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1838e58efdecda887b08ef730d68290a61081ef2566glennrp
18491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketGreen(pixelpacket) \
1858e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=(ScaleQuantumToChar((pixelpacket).green) < 0x10 ? \
1868e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1878e58efdecda887b08ef730d68290a61081ef2566glennrp
18891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketBlue(pixelpacket) \
1898e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=(ScaleQuantumToChar((pixelpacket).blue) < 0x10 ? \
1908e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1918e58efdecda887b08ef730d68290a61081ef2566glennrp
19216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PacketAlpha(pixelpacket) \
19316ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=(ScaleQuantumToChar((pixelpacket).alpha) < 0x10 ? \
1948e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1958e58efdecda887b08ef730d68290a61081ef2566glennrp
19691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGB(pixelpacket) \
197bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
19805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR01PacketRed((pixelpacket)); \
19991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketGreen((pixelpacket)); \
20091d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketBlue((pixelpacket)); \
201bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2028e58efdecda887b08ef730d68290a61081ef2566glennrp
20391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGBO(pixelpacket) \
204bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
20591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketRGB((pixelpacket)); \
20616ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PacketAlpha((pixelpacket)); \
207bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2088e58efdecda887b08ef730d68290a61081ef2566glennrp
209ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR01PixelRed(pixel) \
210360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelRed(image, \
211360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
212c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2138e58efdecda887b08ef730d68290a61081ef2566glennrp
21454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelGreen(pixel) \
215360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelGreen(image, \
216360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
217c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2188e58efdecda887b08ef730d68290a61081ef2566glennrp
21954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelBlue(pixel) \
220360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelBlue(image, \
221360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
222c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2238e58efdecda887b08ef730d68290a61081ef2566glennrp
22416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelAlpha(pixel) \
225360c1549eac5e4759deeaf2a80b027498bea291eglennrp        (SetPixelAlpha(image, \
226360c1549eac5e4759deeaf2a80b027498bea291eglennrp        ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) < 0x10 ? \
227c7375f9f4105dd03f69c115a3d9c1a2087d1742bglennrp        0 : QuantumRange,(pixel)));
2288e58efdecda887b08ef730d68290a61081ef2566glennrp
22954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelRGB(pixel) \
230bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
231ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR01PixelRed((pixel)); \
23254cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelGreen((pixel)); \
23354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelBlue((pixel)); \
234bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2358e58efdecda887b08ef730d68290a61081ef2566glennrp
23616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR01PixelRGBA(pixel) \
237bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
23854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelRGB((pixel)); \
23916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR01PixelAlpha((pixel)); \
240bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2418e58efdecda887b08ef730d68290a61081ef2566glennrp
2428e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR02: Replicate top 2 bits */
2438e58efdecda887b08ef730d68290a61081ef2566glennrp
24405001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR02PacketRed(pixelpacket) \
2458e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2468e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xc0; \
2478e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2488e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketGreen(pixelpacket) \
2518e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2528e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xc0; \
2538e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2548e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2558e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketBlue(pixelpacket) \
2578e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2588e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xc0; \
2598e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
2608e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2618e58efdecda887b08ef730d68290a61081ef2566glennrp   }
26216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PacketAlpha(pixelpacket) \
2638e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
26416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
26516ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum( \
2668e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2678e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2688e58efdecda887b08ef730d68290a61081ef2566glennrp
26991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGB(pixelpacket) \
270bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
27105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR02PacketRed((pixelpacket)); \
27291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketGreen((pixelpacket)); \
27391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue((pixelpacket)); \
274bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2758e58efdecda887b08ef730d68290a61081ef2566glennrp
27691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGBO(pixelpacket) \
277bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
27891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketRGB((pixelpacket)); \
27916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PacketAlpha((pixelpacket)); \
280bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2818e58efdecda887b08ef730d68290a61081ef2566glennrp
282ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR02PixelRed(pixel) \
2838e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
28416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
2858e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
28616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
28716ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
28816ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2898e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelGreen(pixel) \
2918e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
29216ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
2938e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
29416ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
29516ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
29616ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
2978e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29854cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelBlue(pixel) \
2998e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3008e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
30116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
30216ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
30316ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
30416ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel)); \
3058e58efdecda887b08ef730d68290a61081ef2566glennrp   }
30616ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelAlpha(pixel) \
3078e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3088e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
30916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
31016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image, ScaleCharToQuantum( \
31116ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
31216ea139d53d867211d3bb0fa859a83de653f687ecristy       (pixel) ); \
3138e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3148e58efdecda887b08ef730d68290a61081ef2566glennrp
31554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGB(pixel) \
316bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
317ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR02PixelRed((pixel)); \
31854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelGreen((pixel)); \
31954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelBlue((pixel)); \
320bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3218e58efdecda887b08ef730d68290a61081ef2566glennrp
32216ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR02PixelRGBA(pixel) \
323bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
32454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelRGB((pixel)); \
32516ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR02PixelAlpha((pixel)); \
326bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3278e58efdecda887b08ef730d68290a61081ef2566glennrp
3288e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR03: Replicate top 3 bits (only used with opaque pixels during
3298e58efdecda887b08ef730d68290a61081ef2566glennrp   PNG8 quantization) */
3308e58efdecda887b08ef730d68290a61081ef2566glennrp
33105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR03PacketRed(pixelpacket) \
3328e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3338e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xe0; \
3348e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
3358e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3368e58efdecda887b08ef730d68290a61081ef2566glennrp   }
33791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketGreen(pixelpacket) \
3388e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3398e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xe0; \
3408e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
3418e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
34391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketBlue(pixelpacket) \
3448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xe0; \
3468e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
3478e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3488e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3498e58efdecda887b08ef730d68290a61081ef2566glennrp
35091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketRGB(pixelpacket) \
351bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
35205001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR03PacketRed((pixelpacket)); \
35391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketGreen((pixelpacket)); \
35491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketBlue((pixelpacket)); \
355bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3568e58efdecda887b08ef730d68290a61081ef2566glennrp
357ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR03PixelRed(pixel) \
3588e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
35916ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3608e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
36116ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image, ScaleCharToQuantum( \
36216ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3638e58efdecda887b08ef730d68290a61081ef2566glennrp   }
36416ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Green(pixel) \
3658e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
36616ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3678e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
36816ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image, ScaleCharToQuantum( \
36916ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3708e58efdecda887b08ef730d68290a61081ef2566glennrp   }
37116ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03Blue(pixel) \
3728e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
37316ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
3748e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
37516ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image, ScaleCharToQuantum( \
37616ea139d53d867211d3bb0fa859a83de653f687ecristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3778e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3788e58efdecda887b08ef730d68290a61081ef2566glennrp
37916ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR03RGB(pixel) \
380bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
381ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR03PixelRed((pixel)); \
38216ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Green((pixel)); \
38316ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR03Blue((pixel)); \
384bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3858e58efdecda887b08ef730d68290a61081ef2566glennrp
3868e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR04: Replicate top 4 bits */
3878e58efdecda887b08ef730d68290a61081ef2566glennrp
38805001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR04PacketRed(pixelpacket) \
3898e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3908e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xf0; \
3918e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3928e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketGreen(pixelpacket) \
3948e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3958e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xf0; \
3968e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3978e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketBlue(pixelpacket) \
3998e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4008e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xf0; \
4018e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
4028e58efdecda887b08ef730d68290a61081ef2566glennrp   }
40316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PacketAlpha(pixelpacket) \
4048e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
40516ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
40616ea139d53d867211d3bb0fa859a83de653f687ecristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
4078e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4088e58efdecda887b08ef730d68290a61081ef2566glennrp
40991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGB(pixelpacket) \
410bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR04PacketRed((pixelpacket)); \
41291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketGreen((pixelpacket)); \
41391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketBlue((pixelpacket)); \
414bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4158e58efdecda887b08ef730d68290a61081ef2566glennrp
41691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGBO(pixelpacket) \
417bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB((pixelpacket)); \
41916ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PacketAlpha((pixelpacket)); \
420bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4218e58efdecda887b08ef730d68290a61081ef2566glennrp
422ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR04PixelRed(pixel) \
4238e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
42416ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
4258e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
42616ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelRed(image,\
42716ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4288e58efdecda887b08ef730d68290a61081ef2566glennrp   }
42954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelGreen(pixel) \
4308e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
43116ea139d53d867211d3bb0fa859a83de653f687ecristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
4328e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
43316ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelGreen(image,\
43416ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4358e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelBlue(pixel) \
4378e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4388e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
43916ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
44016ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelBlue(image,\
44116ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4428e58efdecda887b08ef730d68290a61081ef2566glennrp   }
44316ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelAlpha(pixel) \
4448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
44616ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
44716ea139d53d867211d3bb0fa859a83de653f687ecristy     SetPixelAlpha(image,\
44816ea139d53d867211d3bb0fa859a83de653f687ecristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4498e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4508e58efdecda887b08ef730d68290a61081ef2566glennrp
45154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelRGB(pixel) \
452bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
453ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR04PixelRed((pixel)); \
45454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelGreen((pixel)); \
45554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelBlue((pixel)); \
456bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4578e58efdecda887b08ef730d68290a61081ef2566glennrp
45816ea139d53d867211d3bb0fa859a83de653f687ecristy#define LBR04PixelRGBA(pixel) \
459bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
46054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelRGB((pixel)); \
46116ea139d53d867211d3bb0fa859a83de653f687ecristy        LBR04PixelAlpha((pixel)); \
462bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4638e58efdecda887b08ef730d68290a61081ef2566glennrp
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
469868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef PNG_SETJMP_SUPPORTED
470868fff35aea4233c40dca33989293cb5bc91601aglennrp# ifndef IMPNG_SETJMP_IS_THREAD_SAFE
471868fff35aea4233c40dca33989293cb5bc91601aglennrp#   define IMPNG_SETJMP_NOT_THREAD_SAFE
472868fff35aea4233c40dca33989293cb5bc91601aglennrp# endif
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
474868fff35aea4233c40dca33989293cb5bc91601aglennrp# ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
476cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
477868fff35aea4233c40dca33989293cb5bc91601aglennrp# endif
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
52985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
53085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
53185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
53285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
53385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
53485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
53585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
53685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
53785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
53885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
53985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
54085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
54185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
54285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
54385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
54485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
54585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
54685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
54785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
54885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
54985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
55085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
55185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
55285dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
55385dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
55485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
55585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
55685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
55785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
55885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
55985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
56085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
56185dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
56485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
56585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
56685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
56785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
56885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
56985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
572689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
573689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp/* Other known chunks that are not yet supported by ImageMagick: */
57485dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
57585dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
57685dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
57785dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
57885dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
57985dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
58085dcf873093881b3ed4da55c3681aa3209767aa9glennrpstatic png_byte mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
581689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
603bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
681bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72735ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
737b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
738b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
739b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
7571868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_level,
7581868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_strategy,
7591868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_filter,
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
762fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png32,
763fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png48,
764fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    write_png64;
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
80026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
80126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
80226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
803a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
80426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
80526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
80626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
80726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
80826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
80926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
81026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
81126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
812a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
81326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
81426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
8158d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_exclude_zTXt,
816ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_colormap,
817ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  /* Added at version 6.8.5-7 */
818fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_preserve_iCCP,
819fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  /* Added at version 6.8.9-9 */
820fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_exclude_tIME;
82126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
82916ea139d53d867211d3bb0fa859a83de653f687ecristy  WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
8300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
83216ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
8330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
83616ea139d53d867211d3bb0fa859a83de653f687ecristy  WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
8400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
841fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
8430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
84416ea139d53d867211d3bb0fa859a83de653f687ecristyLosslessReduceDepthOK(Image *image,ExceptionInfo *exception)
8450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
8469d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp    /* Reduce bit depth if it can be reduced losslessly from 16+ to 8.
84767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
84867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * This is true if the high byte and the next highest byte of
84967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * each sample of the image, the colormap, and the background color
8503faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are equal to each other.  We check this by seeing if the samples
8513faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are unchanged when we scale them down to 8 and back up to Quantum.
85267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
85367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * We don't use the method GetImageDepth() because it doesn't check
8543faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * background and doesn't handle PseudoClass specially.
8559d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp     */
85605a549971fd661147ade177e2bc10f6cfcfc32b4glennrp
8573faa9a3fb01696daaf976d595f492cb530bffb21glennrp#define QuantumToCharToQuantumEqQuantum(quantum) \
8583faa9a3fb01696daaf976d595f492cb530bffb21glennrp  ((ScaleCharToQuantum((unsigned char) ScaleQuantumToChar(quantum))) == quantum)
8593faa9a3fb01696daaf976d595f492cb530bffb21glennrp
86067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    MagickBooleanType
86167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      ok_to_reduce=MagickFalse;
86267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
86303e11f6e8d7f01a32b53d7e8e6a3bfd5ef1c5c9dglennrp    if (image->depth >= 16)
8640c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
8650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
86616ea139d53d867211d3bb0fa859a83de653f687ecristy        const Quantum
8670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
8680c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8690c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
8703faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.red) &&
8713faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.green) &&
8723faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.blue) ?
8733faa9a3fb01696daaf976d595f492cb530bffb21glennrp           MagickTrue : MagickFalse;
8740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
8760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
8770c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
8780c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8790c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
8800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
8813faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=(
8823faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
8833faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].red) &&
8843faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
8853faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].green) &&
8863faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
8873faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].blue)) ?
8883faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
8893faa9a3fb01696daaf976d595f492cb530bffb21glennrp
8900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
8913faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   break;
8920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
8930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
8940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
8950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
8960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
8970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
8980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
8990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
9000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
9020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
9030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
9050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
90616ea139d53d867211d3bb0fa859a83de653f687ecristy              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
9070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
90816ea139d53d867211d3bb0fa859a83de653f687ecristy              if (p == (const Quantum *) NULL)
9090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
9100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
9110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
9120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
9130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
9150c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
9163faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=
91716ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
91816ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
91916ea139d53d867211d3bb0fa859a83de653f687ecristy                   QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
9203faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
9210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
9230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
9240c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
92516ea139d53d867211d3bb0fa859a83de653f687ecristy                p+=GetPixelChannels(image);
9260c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
9278640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
9280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
9290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
9300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
9310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
9330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
9340c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
935fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
9360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
937a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
938a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
939a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
940fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
941a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
9420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
9430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9440c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
9450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
9460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
9470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9481a56e9c9268976936eeab9fe97eb664b847e444cglennrpstatic const char* PngColorTypeToString(const unsigned int color_type)
9491a56e9c9268976936eeab9fe97eb664b847e444cglennrp{
9501a56e9c9268976936eeab9fe97eb664b847e444cglennrp  const char
9511a56e9c9268976936eeab9fe97eb664b847e444cglennrp    *result = "Unknown";
9521a56e9c9268976936eeab9fe97eb664b847e444cglennrp
9531a56e9c9268976936eeab9fe97eb664b847e444cglennrp  switch (color_type)
9541a56e9c9268976936eeab9fe97eb664b847e444cglennrp    {
9551a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY:
9561a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray";
9571a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9581a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_GRAY_ALPHA:
9591a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Gray+Alpha";
9601a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9611a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_PALETTE:
9621a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "Palette";
9631a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9641a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB:
9651a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB";
9661a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9671a56e9c9268976936eeab9fe97eb664b847e444cglennrp    case PNG_COLOR_TYPE_RGB_ALPHA:
9681a56e9c9268976936eeab9fe97eb664b847e444cglennrp      result = "RGB+Alpha";
9691a56e9c9268976936eeab9fe97eb664b847e444cglennrp      break;
9701a56e9c9268976936eeab9fe97eb664b847e444cglennrp    }
9711a56e9c9268976936eeab9fe97eb664b847e444cglennrp
9721a56e9c9268976936eeab9fe97eb664b847e444cglennrp  return result;
9731a56e9c9268976936eeab9fe97eb664b847e444cglennrp}
9741a56e9c9268976936eeab9fe97eb664b847e444cglennrp
975e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
976cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
9770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
978e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
979e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
980e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
981e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
9820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
983e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
984e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
9850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
986e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
987e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
9880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
989e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
990e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
9910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
992e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
993e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
994e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
995e610a071534e448c46460a5aa39ede33bf56b329glennrp}
996e610a071534e448c46460a5aa39ede33bf56b329glennrp
997e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
998cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
9990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1000cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
1001e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1002e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
1003e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
10040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1005e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
1006e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
10070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1008e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
1009e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
10100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1011e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
1012e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
10130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1014e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1015e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
1016e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
1017e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1018e610a071534e448c46460a5aa39ede33bf56b329glennrp
10199d8c12213abd15fee2d84da62d3e5145d9db06cdcristystatic const char *
102098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrpMagick_RenderingIntentString_from_PNG_RenderingIntent(const int ping_intent)
102198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp{
102298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  switch (ping_intent)
102398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
102498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 0:
102598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Perceptual Intent";
102698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
102798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 1:
102898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Relative Intent";
102998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
103098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 2:
103198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Saturation Intent";
103298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
103398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    case 3:
103498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Absolute Intent";
103598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
103698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    default:
103798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      return "Undefined Intent";
103898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
103998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp}
104098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
1041bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
10450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1049d9ecd04e9c567113b4b605cf76681cbb37c093cdcristystatic const char *
10505dff435eceea4f80207a906b11e65aed48fe3f27glennrpMagick_ColorType_from_PNG_ColorType(const int ping_colortype)
10515dff435eceea4f80207a906b11e65aed48fe3f27glennrp{
10525dff435eceea4f80207a906b11e65aed48fe3f27glennrp  switch (ping_colortype)
10535dff435eceea4f80207a906b11e65aed48fe3f27glennrp  {
10545dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 0:
10555dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Grayscale";
10565dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10575dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 2:
10585dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Truecolor";
10595dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10605dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 3:
10615dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "Indexed";
10625dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10635dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 4:
10645dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "GrayAlpha";
10655dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10665dff435eceea4f80207a906b11e65aed48fe3f27glennrp    case 6:
10675dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "RGBA";
10685dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10695dff435eceea4f80207a906b11e65aed48fe3f27glennrp    default:
10705dff435eceea4f80207a906b11e65aed48fe3f27glennrp      return "UndefinedColorType";
10715dff435eceea4f80207a906b11e65aed48fe3f27glennrp    }
10725dff435eceea4f80207a906b11e65aed48fe3f27glennrp}
10735dff435eceea4f80207a906b11e65aed48fe3f27glennrp
10745dff435eceea4f80207a906b11e65aed48fe3f27glennrp
1075bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
10790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1082d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
11150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
11180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
11520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
11550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
11880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
11910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1200d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1201bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1223a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1231a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124403812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
124503812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1249e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1250e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1252d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1258d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
1340f54e295d6fa414fa04aa4f43767c20eda8ae555eglennrp%    the original PNG from files that have been converted to Xcode-PNG,
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
13608fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (length != 0)
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13713b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy          (void) FormatLocaleString(msg,MaxTextExtent,
1372e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1373e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1401bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14148fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (length != 0)
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
14170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
14200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
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_PLTE,4) == 0)
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
14380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
14728fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (length != 0)
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
14780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1492bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
14970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
15000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
15030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1504bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
15260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
15310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1544bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1546bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
155021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
155121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
155321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1555bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
15600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
15640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
15780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
15810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
15840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
15870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1600bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1601bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16228182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
16238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
16240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16348182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16368182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
163916ea139d53d867211d3bb0fa859a83de653f687ecristytypedef struct _PNGErrorInfo
164016ea139d53d867211d3bb0fa859a83de653f687ecristy{
164116ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
164216ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
164316ea139d53d867211d3bb0fa859a83de653f687ecristy
164416ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
164516ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
164616ea139d53d867211d3bb0fa859a83de653f687ecristy} PNGErrorInfo;
164716ea139d53d867211d3bb0fa859a83de653f687ecristy
1648cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
165016ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
165116ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
165216ea139d53d867211d3bb0fa859a83de653f687ecristy
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
165616ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
165716ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
16580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
165916ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
166016ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
166116ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
1662c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy
166316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1664b989d32f1a878692144c3b76764f931575f22131glennrp    "  libpng-%s error: %s", png_get_libpng_ver(NULL),message);
166516ea139d53d867211d3bb0fa859a83de653f687ecristy
166616ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,message,
166716ea139d53d867211d3bb0fa859a83de653f687ecristy    "`%s'",image->filename);
16680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1669e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
16708371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
16718371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
16728371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1674faa852bad40107edae19405e76a299057668d795glennrp#else
1675faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1676faa852bad40107edae19405e76a299057668d795glennrp#endif
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1679cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
168116ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo
168216ea139d53d867211d3bb0fa859a83de653f687ecristy    *exception;
168316ea139d53d867211d3bb0fa859a83de653f687ecristy
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
168716ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
168816ea139d53d867211d3bb0fa859a83de653f687ecristy    *error_info;
168916ea139d53d867211d3bb0fa859a83de653f687ecristy
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
16920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
169316ea139d53d867211d3bb0fa859a83de653f687ecristy  error_info=(PNGErrorInfo *) png_get_error_ptr(ping);
169416ea139d53d867211d3bb0fa859a83de653f687ecristy  image=error_info->image;
169516ea139d53d867211d3bb0fa859a83de653f687ecristy  exception=error_info->exception;
169616ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1697b989d32f1a878692144c3b76764f931575f22131glennrp    "  libpng-%s warning: %s", png_get_libpng_ver(NULL),message);
16980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
169916ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1704943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#if PNG_LIBPNG_VER >= 10400
1705a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_alloc_size_t size)
1706a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
1707a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristystatic png_voidp Magick_png_malloc(png_structp png_ptr,png_size_t size)
1708a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1710df0d90e1d3bbfa3956818ac7bf43aa0d008020dccristy  (void) png_ptr;
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1717cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17193bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) png_ptr;
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1730edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrpMagick_png_read_raw_profile(png_struct *ping,Image *image,
1731edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   const ImageInfo *image_info, png_textp text,int ii,ExceptionInfo *exception)
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1733bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
17610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
17650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1766f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
17670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
176897f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
176997f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
177097f90e23c85b9c58387880125c29d8c99126f83aglennrp
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
17730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1777edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping,"invalid profile length");
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17818723e4bcd840478cecfd29891e792edb499cd0e9cristy  profile=BlobToStringInfo((const void *) NULL,length);
17820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1785edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_warning(ping, "unable to copy profile");
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
17920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1799edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp          png_warning(ping, "ran out of profile data");
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
18080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
181516ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProfile(image,&text[ii].key[17],profile,exception);
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
18170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
18200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18392ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  LogMagickEvent(CoderEvent,GetMagickModule(),
18402ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp     " read_vpag_chunk: found %c%c%c%c chunk",
18412ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp       chunk->name[0],chunk->name[1],chunk->name[2],chunk->name[3]);
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1857bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
18590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1860bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1873fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
1874fd6fd07e58e3d37313bec849313ac6e2b92e3957dirkstatic void read_tIME_chunk(Image *image,png_struct *ping,png_info *info,
1875fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  ExceptionInfo *exception)
1876fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk{
1877fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_timep
1878fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    time;
1879fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1880fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (png_get_tIME(ping,info,&time))
1881fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
1882fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      char
1883fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        timestamp[21];
1884fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1885fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      FormatLocaleString(timestamp,21,"%04d-%02d-%02dT%02d:%02d:%02dZ",
1886fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        time->year,time->month,time->day,time->hour,time->minute,time->second);
1887fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      SetImageProperty(image,"png:tIME",timestamp,exception);
1888fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
1889fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk}
1890fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
1891fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1927cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
1928cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1932d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  char
1933ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    im_vers[32],
1934ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_runv[32],
1935ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    libpng_vers[32],
1936ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_runv[32],
1937ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp    zlib_vers[32];
1938d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
194098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    intent, /* "PNG Rendering intent", which is ICC intent + 1 */
1941cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
19434eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1945913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp    number_colors,
1946faa852bad40107edae19405e76a299057668d795glennrp    pass,
1947faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1948faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1949fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp    ping_file_depth,
1950faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1951faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1952faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
19534eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
19544eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
19554eb3931feb349dd87142c78503b779228f3e1a0fglennrp
19564eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
19574eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
19604383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
196198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_cHRM,
196298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_gAMA,
196398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_iCCP,
196498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    ping_found_sRGB,
19653d627862fb79aad8a20be4f1587f0b8761db441aglennrp    ping_found_sRGB_cHRM,
1966ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_iCCP,
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19690997332e2c35a821b271d6e7473c01c10dc206adcristy  MemoryInfo
19700997332e2c35a821b271d6e7473c01c10dc206adcristy    *volatile pixel_info;
19710997332e2c35a821b271d6e7473c01c10dc206adcristy
197216ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
197316ea139d53d867211d3bb0fa859a83de653f687ecristy    transparent_color;
197416ea139d53d867211d3bb0fa859a83de653f687ecristy
197516ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
197616ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
197716ea139d53d867211d3bb0fa859a83de653f687ecristy
1978faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1979faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1980faa852bad40107edae19405e76a299057668d795glennrp
1981faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1982faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1983faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1984faa852bad40107edae19405e76a299057668d795glennrp
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1995faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1996faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1997faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
19984eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
19994eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
2000faa852bad40107edae19405e76a299057668d795glennrp
200116ea139d53d867211d3bb0fa859a83de653f687ecristy  QuantumInfo
200216ea139d53d867211d3bb0fa859a83de653f687ecristy    *quantum_info;
200316ea139d53d867211d3bb0fa859a83de653f687ecristy
2004bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2005756ae430d36380dfab8ca703538f5922f3796351cristy    ping_rowbytes,
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2011bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
201516ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
201939992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2022eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
2023eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
2024eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
202575fc68f33e6e766a22e8ed653c3ed50b0d142827cristy  unsigned char
20260997332e2c35a821b271d6e7473c01c10dc206adcristy    *ping_pixels;
202755b78b53f1e013e0af19565ac04aaa7660d53795cristy
2028629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
2036fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if !defined(PNG_tIME_SUPPORTED)
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
2038fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
2039629960f505ebba710ec9b6953a539a21dab176f2glennrp#ifdef PNG_APNG_SUPPORTED /* libpng was built with APNG patch; */
2040629960f505ebba710ec9b6953a539a21dab176f2glennrp                          /* ignore the APNG chunks */
2041629960f505ebba710ec9b6953a539a21dab176f2glennrp     97,  99,  84,  76, (png_byte) '\0',   /* acTL */
2042629960f505ebba710ec9b6953a539a21dab176f2glennrp    102,  99,  84,  76, (png_byte) '\0',   /* fcTL */
2043629960f505ebba710ec9b6953a539a21dab176f2glennrp    102, 100,  65,  84, (png_byte) '\0',   /* fdAT */
2044629960f505ebba710ec9b6953a539a21dab176f2glennrp#endif
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2048d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
2049d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
2050d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
2051d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
2052d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
2053ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         MagickLibVersionText,32);
2054d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
2055ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         MagickLibAddendum,32);
2056ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
2057d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
2058d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
2059ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
2060ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
2061ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
2062ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
2063ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
2064d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
2065d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
2066ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
2067ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
2068ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
2069ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
2070ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
20712dd1906783a5ece58a6105b4f59239e28b13caddglennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
20722dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "  Enter ReadOnePNGImage()\n"
20732dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "    IM version     = %s\n"
20742dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "    Libpng version = %s",
20752dd1906783a5ece58a6105b4f59239e28b13caddglennrp       im_vers, libpng_vers);
20762dd1906783a5ece58a6105b4f59239e28b13caddglennrp
20772dd1906783a5ece58a6105b4f59239e28b13caddglennrp  if (logging != MagickFalse)
20782dd1906783a5ece58a6105b4f59239e28b13caddglennrp  {
20792dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (LocaleCompare(libpng_vers,libpng_runv) != 0)
2080d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
20812dd1906783a5ece58a6105b4f59239e28b13caddglennrp    LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
20822dd1906783a5ece58a6105b4f59239e28b13caddglennrp        libpng_runv);
2083d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
20842dd1906783a5ece58a6105b4f59239e28b13caddglennrp    LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
20852dd1906783a5ece58a6105b4f59239e28b13caddglennrp        zlib_vers);
20862dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (LocaleCompare(zlib_vers,zlib_runv) != 0)
20872dd1906783a5ece58a6105b4f59239e28b13caddglennrp    {
20882dd1906783a5ece58a6105b4f59239e28b13caddglennrp    LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
20892dd1906783a5ece58a6105b4f59239e28b13caddglennrp        zlib_runv);
20902dd1906783a5ece58a6105b4f59239e28b13caddglennrp    }
20912dd1906783a5ece58a6105b4f59239e28b13caddglennrp  }
2092d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
209325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
209961b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
210061b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
210161b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
210261b4c957269727a0a2526edc2331881da8346100glennrp    {
210361b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
210461b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
210561b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
210661b4c957269727a0a2526edc2331881da8346100glennrp    }
210761b4c957269727a0a2526edc2331881da8346100glennrp#  endif
210861b4c957269727a0a2526edc2331881da8346100glennrp#endif
210961b4c957269727a0a2526edc2331881da8346100glennrp
211016ea139d53d867211d3bb0fa859a83de653f687ecristy
211116ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info = (QuantumInfo *) NULL;
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2114a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
211598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  {
2116a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
21172dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "    Before reading:\n"
21182dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->alpha_trait=%d"
21192dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->rendering_intent=%d\n"
21202dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->colorspace=%d\n"
21212dd1906783a5ece58a6105b4f59239e28b13caddglennrp       "      image->gamma=%f",
21222dd1906783a5ece58a6105b4f59239e28b13caddglennrp       (int) image->alpha_trait, (int) image->rendering_intent,
21232dd1906783a5ece58a6105b4f59239e28b13caddglennrp       (int) image->colorspace, image->gamma);
212498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  }
212598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  intent=Magick_RenderingIntent_to_PNG_RenderingIntent(image->rendering_intent);
212698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21270e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
21280e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
21290e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
21300e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
213116ea139d53d867211d3bb0fa859a83de653f687ecristy  transparent_color.alpha=65537;
21320e319739731741c52a6303723e0c8678a0df5579glennrp
2133913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp  number_colors=0;
2134cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
21354eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
2136cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
2137cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
213898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_cHRM = MagickFalse;
213998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_gAMA = MagickFalse;
214098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_iCCP = MagickFalse;
214198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  ping_found_sRGB = MagickFalse;
21424b917593e694424be469d250448c05c878663812glennrp  ping_found_sRGB_cHRM = MagickFalse;
2143ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  ping_preserve_iCCP = MagickFalse;
2144ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
214598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
215016ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
215116ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
21523e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
2153cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
2154cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21563e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,&error_info,
2157cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
21630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
21710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21780997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=(MemoryInfo *) NULL;
21790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2180faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2186edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2187868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
2188cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2190edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
21910997332e2c35a821b271d6e7473c01c10dc206adcristy      if (pixel_info != (MemoryInfo *) NULL)
21920997332e2c35a821b271d6e7473c01c10dc206adcristy        pixel_info=RelinquishVirtualMemory(pixel_info);
2193edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
21970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
2199f078e391816b7033081339865c711a5547d6aecadirk        image->columns=0;
22000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2203edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2204edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
2205edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
2206edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
2207edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
2208edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2209868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
2210edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
2211edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
2212edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2213943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
2214a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
2215a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
2216a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
2217a3a5f956194e91458e2789966ad15308e8f3df47glennrp
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;
2341a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2342a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     value=GetImageOption(image_info,"png:swap-bytes");
2343a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2344a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value == NULL)
2345a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        value=GetImageArtifact(image,"png:swap-bytes");
2346a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
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
23545830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        msg[MaxTextExtent];
23555830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
23565830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_color_type);
23573398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.color-type-orig",msg,exception);
23585830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
23595830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%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
2881a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             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    }
2974e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
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        {
3041bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3044fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale=(QuantumRange/((1UL << ping_file_depth)-1));
30450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
30480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3049bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3057147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3058cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
3059cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
3060147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
3061147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
3062147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3063fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     /* encode ping_width, ping_height, ping_file_depth, ping_color_type,
3064147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
3065147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30663b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
30677cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
30683398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.width,height",msg,exception);
3069147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3070fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_file_depth);
30713398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.bit_depth",msg,exception);
3072147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30735dff435eceea4f80207a906b11e65aed48fe3f27glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d (%s)",
30745dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
30755dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
30763398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.color_type",msg,exception);
3077147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3078913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
3079913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3080913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Not interlaced)",
3081913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3082913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3083913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
3084913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3085913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Adam7 method)",
3086913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3087913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3088913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
3089913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3090913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Unknown method)",
3091913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3092913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3093913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
3094913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
3095913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
3096913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3097913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d",
3098913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
30993398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors",msg,
3100913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
3101913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
310239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   }
3103fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
310439d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp   read_tIME_chunk(image,ping,ping_info,exception);
3105fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
310639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
3107147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
31130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31140ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
3115347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
3116347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31181b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
31191b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
31201b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
31211b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3124e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3127edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3128868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3129cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3131edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
31350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
31420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
31440997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(image->rows,ping_rowbytes*
3145cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
31460997332e2c35a821b271d6e7473c01c10dc206adcristy  else
31470997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(ping_rowbytes,sizeof(*ping_pixels));
31480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31490997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
3150edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
31510997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
31520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
315916ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info=AcquireQuantumInfo(image_info,image);
316016ea139d53d867211d3bb0fa859a83de653f687ecristy
316116ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
3162edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
31630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31644b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
31654b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp
3166c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
3167c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3168c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
3169c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
3170c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3171c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3172c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3175c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3176c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3177c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3178c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3179c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
3180ccc36af759d30fb50b1deda241d038402a393b17glennrp        image->alpha_trait=
3181ccc36af759d30fb50b1deda241d038402a393b17glennrp            (((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3182c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3183c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3184b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
31850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3186c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3187c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3188c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3189c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
31900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3191c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3192c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
31930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3194cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3195c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3196c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          if (pass < num_passes-1)
3197c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp            continue;
3198c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3199862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
320116ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3202c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
32030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320416ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
320516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
320616ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
32070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320816ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
320916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321016ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
32110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
321216ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
321316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321416ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
32150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
321616ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
321716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321816ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
32190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
322016ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
322116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
322216ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
32233faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3224c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3225c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3226c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3227a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3228a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3229a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3230a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3231c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3232c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
32335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
32345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
323516ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3236c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3237a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3238a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3239a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3240a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3241c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3242c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3243c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
32444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
32454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
324616ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
324716ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
324816ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
324916ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
325016ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
325116ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
32524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3253a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3254a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3255a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
32564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
32574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
32584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
325916ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3260c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3261c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
32620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3263af9320404a7b05014476f844b11110157a21b73eglennrp          if (num_passes == 1)
3264c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3265af9320404a7b05014476f844b11110157a21b73eglennrp              status=SetImageProgress(image,LoadImageTag,
3266af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) y, image->rows);
32670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3268c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3269c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3270c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3271c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3272c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3273c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
32740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3275af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes != 1)
32767a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3277c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
32787a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32797a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32807a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3285c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3297c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3298c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3299c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
330016ea139d53d867211d3bb0fa859a83de653f687ecristy
33018a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3302b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
33030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3305b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3306b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
33070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3309edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
33100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3311bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33134f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        Quantum
33144f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp           alpha;
33154f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3317faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3318c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3321c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3322cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
3323c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3324c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp        if (pass < num_passes-1)
3325c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          continue;
3326c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
33274f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
33280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
332916ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
33310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3332cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3334c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3335faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33394f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
3340faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3341bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3343a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33444f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33454f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                alpha=ScaleCharToQuantum((unsigned char)*p++);
33464f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33474f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                SetPixelAlpha(image,alpha,q);
33484f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33494f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                if (alpha != OpaqueAlpha)
33500b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
33514f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
335216ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3356bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3357a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
336147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3364bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3365a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3366c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
336787281ec8d96ad26dfed9968c29b2920cb3d96744cristy              unsigned short
336858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
336958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
337058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3371c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
337258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
337358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3374c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
337558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
337658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3377c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
337858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
33790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3380faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3382c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3383c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3384c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3385c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3386c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3387c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
33884f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33894f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  alpha=ScaleShortToQuantum(quantum);
33904f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  SetPixelAlpha(image,alpha,q);
33914f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33924f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  if (alpha != OpaqueAlpha)
339358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
33944f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
339516ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
339658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
339758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
339858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
339958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
340058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
340147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
340258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
340358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
340416ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
34054f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
340616ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
34070b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
34084f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
340958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
341016ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3413a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
341447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
341747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34213faa9a3fb01696daaf976d595f492cb530bffb21glennrp
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
34260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
342716ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
342816ea139d53d867211d3bb0fa859a83de653f687ecristy
342916ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
343016ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3431bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
343216ea139d53d867211d3bb0fa859a83de653f687ecristy        {
343316ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
343416ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
343516ea139d53d867211d3bb0fa859a83de653f687ecristy        }
34360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
34390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3440af9320404a7b05014476f844b11110157a21b73eglennrp        if (num_passes == 1)
34417a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3442cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
34439fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
344447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34457a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
34467a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
34477a287bfadeadea12e47c2376ca78a5d101687142cristy          }
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3449c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3450af9320404a7b05014476f844b11110157a21b73eglennrp      if (num_passes != 1)
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
345347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3457c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3461b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3462b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3463c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3464c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3465c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3466c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
34705aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
34715aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34725aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3473bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
34745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
34755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3476c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3477c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3478c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
347916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
348016ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
348116ea139d53d867211d3bb0fa859a83de653f687ecristy
34825c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
34835c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3484b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3485b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
34865c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3487b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
34888a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
348916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3490b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
34915c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
349247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34934eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3495ccc36af759d30fb50b1deda241d038402a393b17glennrp  if (logging != MagickFalse)
3496ccc36af759d30fb50b1deda241d038402a393b17glennrp  {
3497ccc36af759d30fb50b1deda241d038402a393b17glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3498ccc36af759d30fb50b1deda241d038402a393b17glennrp       "  image->storage_class=%d\n",(int) image->storage_class);
3499ccc36af759d30fb50b1deda241d038402a393b17glennrp  }
3500ccc36af759d30fb50b1deda241d038402a393b17glennrp
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3502bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
35050997332e2c35a821b271d6e7473c01c10dc206adcristy      pixel_info=RelinquishVirtualMemory(pixel_info);
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
350716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3508868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3509cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
351647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3517faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
35268a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3527c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35283c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3529c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
35310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3533c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
35340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
35350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35368a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
353716ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
353816ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
35390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3540c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
354147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
35430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
35440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
35450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
354716ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
35480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
35498a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
355016ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
35510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
35520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
35530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
355416ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
35550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
355647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3557a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3558a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3559a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
35600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
35610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
35630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
35640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
35650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3566c11cf6a442f3046940608a5743a68cc891deb13eglennrp
356716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
35680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3569c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3571a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3572a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3573a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
35740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
35750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
357616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
357716ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
357816ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
357916ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
358016ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
358116ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
35824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
358316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
35844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
35850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
358667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
35870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
35884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
358916ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
35904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3591a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
35920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
359316ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
35940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
35950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
35970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3598c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
35990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3600a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3601c11cf6a442f3046940608a5743a68cc891deb13eglennrp
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36043c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3605eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
36064eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
36074eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3608a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3609a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36104eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3611a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3612a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36144eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
36154eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
36164eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
36174eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
36180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36194eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
36204eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36214eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
36220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36234eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
36244eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
362599f968111025b4fadb966ca482c6f57750bf007bglennrp            const char
362699f968111025b4fadb966ca482c6f57750bf007bglennrp              *value;
362799f968111025b4fadb966ca482c6f57750bf007bglennrp
362899f968111025b4fadb966ca482c6f57750bf007bglennrp            value=GetImageOption(image_info,"profile:skip");
362999f968111025b4fadb966ca482c6f57750bf007bglennrp
363099f968111025b4fadb966ca482c6f57750bf007bglennrp            if (IsOptionMember(text[i].key+17,value) == MagickFalse)
363199f968111025b4fadb966ca482c6f57750bf007bglennrp            {
363299f968111025b4fadb966ca482c6f57750bf007bglennrp               (void) Magick_png_read_raw_profile(ping,image,image_info,text,
363399f968111025b4fadb966ca482c6f57750bf007bglennrp                  (int) i,exception);
363499f968111025b4fadb966ca482c6f57750bf007bglennrp               num_raw_profiles++;
363599f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
363699f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
363799f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Read raw profile %s",text[i].key+17);
363899f968111025b4fadb966ca482c6f57750bf007bglennrp            }
363999f968111025b4fadb966ca482c6f57750bf007bglennrp            else
364099f968111025b4fadb966ca482c6f57750bf007bglennrp            {
364199f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
364299f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
364399f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Skipping raw profile %s",text[i].key+17);
364499f968111025b4fadb966ca482c6f57750bf007bglennrp            }
36454eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
36464eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36474eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
36484eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
36494eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
36504eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
36514eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36524eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
36534eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
36544eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
36554eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
36564eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3657edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
36584eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
36594eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
36604eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
36614eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
36624eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36634eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
36644eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
36654eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
36664eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
36674eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
36684eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
366916ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36714eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36734eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36742dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      length: %lu\n"
36752dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      Keyword: %s",
36762dd1906783a5ece58a6105b4f59239e28b13caddglennrp                (unsigned long) length,
36772dd1906783a5ece58a6105b4f59239e28b13caddglennrp                text[i].key);
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36804eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
368197f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
36824eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
3683fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    num_text_total += num_text;
3684fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
36853c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
369873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
36990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
370647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3711edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
37120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3714edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
37230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
372516ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
37260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
37290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3731edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
37320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3733faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
37350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3736faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3737faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3738faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3739faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3740faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3741faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3742faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3743faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
37440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3745faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
37553c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
376147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37670a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
37688a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
37690a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
37700a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
37710a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
37728a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
37730a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
37740a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3775b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
37760a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3777224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#if 0  /* I'm not sure what's wrong here but it does not work. */
377835553db9b7d0d812b53b09e3906628239d908e1ccristy    if (image->alpha_trait == BlendPixelTrait)
37795830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37805830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
37815830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleMatteType,exception);
37825830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37835830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37845830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteMatteType,exception);
37855830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37865830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37875830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
37885830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
37895830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37905830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    else
37915830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37925830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
37935830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleType,exception);
37945830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37955830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37965830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteType,exception);
37975830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37985830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37995830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorType,exception);
38005830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
3801224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#endif
38025830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
3803cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3804cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3805cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3806cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3807cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38084eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3809cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3810cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
38113b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3812613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
38133398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:text",msg,
381416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3815cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3816cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3817cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3818cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
38193b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3820cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
382116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
382216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3823cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3824cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
382598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
38265961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
38273b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38285961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
38293398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:cHRM",msg,
383016ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38315961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3832cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3833cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
38345961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
38353b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38365961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
38373398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:bKGD",msg,
383816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38395961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
38405961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
38413b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38425961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3843cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
384498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
384598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
38463398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:iCCP",msg,
384716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
384898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3849cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38504eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
38513398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:tRNS",msg,
385216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38534eb3931feb349dd87142c78503b779228f3e1a0fglennrp
38544eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
385598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
38564eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38573b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
385898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
385998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
386098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
38613398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:sRGB",msg,
386298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
38634eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38644eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38654eb3931feb349dd87142c78503b779228f3e1a0fglennrp
386698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
38674eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38683b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
386916ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
387016ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
38713398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:gAMA",msg,
387216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38734eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3874cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38754eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3876cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
38774eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38783b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
387907523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
38804eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
38813398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:pHYs",msg,
388216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38834eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38844eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3885cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38864eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
38874eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
38884eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38893b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
38904eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
38913398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:oFFs",msg,
389216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38934eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38944eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38954eb3931feb349dd87142c78503b779228f3e1a0fglennrp
3896fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
3897fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk     read_tIME_chunk(image,ping,end_info,exception);
3898fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
3899fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
390007523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
390107523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
390207523c7d2e40370804c2036295571e4b6426f94dglennrp       {
39033b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
390407523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
390507523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
39063398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:vpAg",msg,
390716ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
390807523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3909cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3910cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39160997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
39210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3922868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3923edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3924edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3925edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3926edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3927edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3928edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3929edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
3938919429921a43880a338ed87e128d3b96219442efglennrp    *image;
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
394121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
394221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
395947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
396347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3966fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
396716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
397047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
397347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
397847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3979dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
398147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
398673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
398747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
399047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
400047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
40060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
400947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
401147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
40170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
402047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
402172715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
40223d627862fb79aad8a20be4f1587f0b8761db441aglennrp      ((image->gamma < .45) || (image->gamma > .46)) &&
40233d627862fb79aad8a20be4f1587f0b8761db441aglennrp           !(image->chromaticity.red_primary.x>0.6399f &&
40243d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
40253d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
40263d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
40273d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
40283d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
40293d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
40303d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
40313d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
40323d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
40333d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
40343d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
40353d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
40363d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
40373d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
40383d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f))
4039ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4040ccc36af759d30fb50b1deda241d038402a393b17glennrp       SetImageColorspace(image,RGBColorspace,exception);
4041ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
404272715f5c299a6482f8eb175070b056d77b74a43fcristy
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
4044ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4045ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4046ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
4047ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.width,(double) image->page.height,
4048ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.x,(double) image->page.y);
4049ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4050ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  image->colorspace: %d", (int) image->colorspace);
4051ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
405297f90e23c85b9c58387880125c29d8c99126f83aglennrp
405397f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
40550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41074383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
41084383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
41094383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
4110bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413016ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4133bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413716ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
4145e0421fec74bee9a6f9def3d51aed4204f970ad73glennrp    reading_idat;
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4147bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
4161fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
41640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
416516ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
41730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
417416ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
41750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
41780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
42050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
42080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4216e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
4217e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
4220af9320404a7b05014476f844b11110157a21b73eglennrp      {
4221af9320404a7b05014476f844b11110157a21b73eglennrp        ThrowReaderException(CorruptImageError,"CorruptImage");
4222af9320404a7b05014476f844b11110157a21b73eglennrp        return (Image *) NULL;
4223af9320404a7b05014476f844b11110157a21b73eglennrp      }
42240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
422747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42288fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
42310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4235bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
42370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
424047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4247bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
4248e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[2] << 8) | p[3]);
4249bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
4250e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[6] << 8) | p[7]);
4251e2440c250d94d64f8c70e596fe90808795aaa07ecristy            if ((jng_width == 0) || (jng_height == 0))
4252e2440c250d94d64f8c70e596fe90808795aaa07ecristy              ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
425747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
426047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
426547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42692dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_width:      %16lu,    jng_height:     %16lu\n"
42702dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_color_type: %16d,     jng_image_sample_depth: %3d\n"
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
42722dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (unsigned long) jng_width, (unsigned long) jng_height,
42732dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_color_type, jng_image_sample_depth,
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
427547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42772dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_image_interlace_method:  %3d"
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
42792dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_image_interlace_method,
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
428147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42832dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_compression_method:%3d\n"
42842dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_filter_method:     %3d\n"
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
42862dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_compression_method,
42872dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_filter_method,
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
429147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42928fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
429447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
431073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
431147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
431447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
431616ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
43170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
43240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
43280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
433573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
43360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
434116ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
43420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
43530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
43570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
43600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
43690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
437503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
439247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
439947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44008fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
440247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
441147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4419bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
442103812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44288fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
443647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44478fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
44560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44578fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
44868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
44870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
44978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
44988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
44998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
45008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
45018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
45028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
45038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
450547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4514e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4515cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4516da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
452647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45355eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
45365eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
45370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
454447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45458fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
455516ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
455616ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
456016ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
456116ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4572fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
45738fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45808fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
45850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
460816ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
461447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
46180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4619f0eec7524321f1be1bfe568a13ab7d4d0333c814cristy  assert(color_image_info != (ImageInfo *) NULL);
46203b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
46220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
46250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
46390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
46420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
464516ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
464716ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
464816ea139d53d867211d3bb0fa859a83de653f687ecristy    {
464916ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
465016ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
465116ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
465216ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
465316ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
465416ea139d53d867211d3bb0fa859a83de653f687ecristy    }
465547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
46590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
46610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
467203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
46780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
468116ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46833b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
46870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4689bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
469216ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
469447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
469535553db9b7d0d812b53b09e3906628239d908e1ccristy             if (image->alpha_trait == BlendPixelTrait)
469616ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
469716ea139d53d867211d3bb0fa859a83de653f687ecristy               {
469816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
469916ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
470016ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
470116ea139d53d867211d3bb0fa859a83de653f687ecristy               }
47020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
470416ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
470616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
470716ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
47088a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
470916ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
471016ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
47120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
472447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
472547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
47330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
47350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
47360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
47390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
47410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
47450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
47520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
47560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
47947ee973a2149db53911459cbf26f28eccdbc99efbglennrp    *image;
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
479721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
479821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4818fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
481916ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
48220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
48250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
482947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
483047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
483247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48333b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
483647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
483747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
483973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
48400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
48430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
484447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
484547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
48520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
486247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
48740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48884383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
488921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
489021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
48914383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4898bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
491616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4923bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4929bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4946bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
495538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
495638ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
495738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4958bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
498047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
498147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4987fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
498816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
49910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
49940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
499847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
499947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
500047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
500173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
50020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
50050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
500647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
500747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
501747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
502147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
502247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5025bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
5026bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
503047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5073e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
5074e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
50780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
50810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
50840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50858fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
508847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
509147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5092bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
509447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
51040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
510616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
51080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
51150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
511716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
51190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
512447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
51290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51308fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
51360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5142bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
51440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5145bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
51470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5151e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5153e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
51578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
51580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
51610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
51650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
51680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
51728182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
51760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
51790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
51820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
518716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
518947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
519016ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
51910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
51940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
52020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52033b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
5204e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
5205f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
52060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
5208bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
5210bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
52120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
52150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52268fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
52280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52318182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
52328182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
52330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
52360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5244280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  "    repeat=%d,  final_delay=%.20g,  iterations=%.20g",
5245280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  repeat,(double) final_delay, (double) image->iterations);
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
525416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
52590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
526116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5268edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
527116ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
528016ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
52880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
52910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
52980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
52990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
53010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
53020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5306280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      "  x_off[%d]: %.20g,  y_off[%d]: %.20g",
5307280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->x_off[object_id],
5308280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->y_off[object_id]);
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
53180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
53250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
53480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
53510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
536316ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
537447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
537747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
537847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
53840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5385bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
539235ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
54010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54028fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
54070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
541147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5417bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
542412560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5432bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54358182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
54420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
544947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
545047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
54548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
54558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
54578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
54598182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
54618182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
54638182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
54658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
547047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
547447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54808fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5482e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5483cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
548847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
549247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5495fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55008fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
550247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
550547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
550916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
55120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
55150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
551947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55208fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
55230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
55270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
553047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
553147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
553347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
553647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
553847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5539bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
555047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
55548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
55550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
55578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
55580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5559bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5560bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
55610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
55640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5569e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
557147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5574bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5575bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
55760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5577bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5578bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
55790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5580bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5581bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
55820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
55850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5590e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
559247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
55980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5602e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5603e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
560447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
56120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5613bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
56150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5616bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5624e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5625e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
56260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
563047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
563116ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
563316ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
563447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
564147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
56460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
56560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
56648a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
566616ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
56670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5671e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5672e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
568947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
570147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57178fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
572547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
572647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57458fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
575047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
575747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
575847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5761bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
577847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
578847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
578947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
57908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
57910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5794e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5795e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
57960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
57990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
58050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
581047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
581447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
582647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
58330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5837e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5838f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
583947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
58440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
584947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
586747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
587147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
587516ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
587847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
588147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
58980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
59010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
59040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
591116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
591547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
592147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
592747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
593047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
593647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
593947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
594547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
594847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
595447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
595747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
596347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
596647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
597247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
597547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
598147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
598547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
598916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
599347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
601247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
601616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
601947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
602247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
602616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
602947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
603247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
603747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
60538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
60558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
605947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
606616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
606847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
607447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
607616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
607947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
6082bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
6084bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
609247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
609547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
609847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
610147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
610447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
610747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
611047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
611847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
612147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
612447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
612947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
61378fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
613947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
614647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
614947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
615547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
616347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61648182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
61658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
6178bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
6180bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
618216ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
618716ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
618847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
619547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
619947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
620647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
620947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
621047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
621147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
622016ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6223e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6224e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
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            }
62510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
62530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
626347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
62728a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
627316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
62740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6278e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6279e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
628347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
628416ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
628916ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
629047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
629747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
63030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
63060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
63150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
63240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
633047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
633447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
633947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6340bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
634147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
635347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
636647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
639947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
640247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
640447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
640547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
640747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64104e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
641147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
641447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
641747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
641947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
642047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
642247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
642647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
642947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
643147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
643247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
643447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64374e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
643847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
644147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
644447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
644647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
644747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
644947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
645916ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
646016ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
646116ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
646216ea139d53d867211d3bb0fa859a83de653f687ecristy
646316ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
646416ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
646516ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
646616ea139d53d867211d3bb0fa859a83de653f687ecristy
6467bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
647116ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
647516ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
647616ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
647847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
647947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
648347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
648416ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
648547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65013faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6509bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
651347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
651616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
651716ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
651816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
651916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
652016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
652116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
652216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
652316ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
652416ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
652647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
653535553db9b7d0d812b53b09e3906628239d908e1ccristy                if (image->alpha_trait == BlendPixelTrait)
653616ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
653747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
654016ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
654116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
654247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
654547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
654847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
655147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6560e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
656316ea139d53d867211d3bb0fa859a83de653f687ecristy                length=(size_t) image->columns*GetPixelChannels(image);
656416ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
656516ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
656647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
656716ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
656816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
657547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
657847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6579bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
658347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6585bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
658647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6587bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
658947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6590bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
659247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
659547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
659947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6600bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
660647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
660916ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6612bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
66169fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
661716ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
661816ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
661947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6622fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6631bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
663216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
663316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
663416ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
663516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
663616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
663716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
663816ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
664047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6644bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
664516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
664616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
664716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
664816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
664916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
665016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
665116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
665216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6653bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
665447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
665816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
665916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
666016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6661bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
666216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
666316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
666416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
666516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6666bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
666716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
666816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
666916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
667016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6671bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
667216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
667347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
667435553db9b7d0d812b53b09e3906628239d908e1ccristy                              if (image->alpha_trait == BlendPixelTrait)
667516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
667616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
667716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6678bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
667916ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
668147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
668616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
668716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
668916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
669016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
669347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6698bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
670016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
670116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
670216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
670316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
670416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
670516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
670616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6707bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
670847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6710bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
671116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
671216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
671316ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
671416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
671516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
671616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
671716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6718bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
671947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
672216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
672316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
672416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6725bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
672616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
672916ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
673016ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
673116ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
673347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
673647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
673947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
674016ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
674116ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6758e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
676216ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
676616ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
676716ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
676847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6769bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
677216ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
67737c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6775bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
677647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6777bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6778bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
677947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6781bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
678247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6783bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
678547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6787bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
678847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
679416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
679516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
679616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
679716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
679947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6803bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
680416ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
680516ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
680616ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
680716ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6808bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
680947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
681016ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
681416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
681516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
681616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6817bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
681816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6819bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
682016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
682116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
682216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6823bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
682416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6825bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
682616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
682716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
682816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6829bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
683016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
683135553db9b7d0d812b53b09e3906628239d908e1ccristy                              if (image->alpha_trait == BlendPixelTrait)
683216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
683316ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
683416ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6835bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
683616ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
683847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6843bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
684416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
684516ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6846bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6848bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
684916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
685016ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6851bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
685447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6859bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
686016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
686116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
686216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
686316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6864bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
686547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6867bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
686816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
686916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
687016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
687116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6872bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
687347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
687716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
687816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
687916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6880bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
688116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
688416ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
688616ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
688847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68923faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6898bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
690147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6902bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
690416ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
690516ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
690616ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
690716ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
690816ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
690916ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
691016ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
691116ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
691216ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
691447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
694847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6964bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6965bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
697147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
698347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
699416ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70062b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
70072b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
700816ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
70092b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
70102b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
70112b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
70122b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
70132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
70143faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7015cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
7016cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
7017cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
7018cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
7019cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
7020cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
702116ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
70228640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7024d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
7028bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7031d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
7035d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
703747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
703947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
704347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
70540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
705516ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
706016ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
706547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
706947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
70818a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
70820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
708416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
70850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
70900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
70930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
710147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
710216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
710547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
71100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
711547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
711616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
712147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
712947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
713016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
713447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
714047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
714116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
714347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
714647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
71540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
71600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
716547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
71710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
71730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7176e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
7177e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
71780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
718647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
718947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7191e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
719247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7197e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7209bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
721447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
721616ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
721747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
722047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
722347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
723247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
723547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
725247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
726247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
726547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7267e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7268e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
726947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7271f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7272f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
727347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7274f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7275e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7276e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7277f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7278f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
727947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
728347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
728647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
728925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
729447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
729747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
730047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
730525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7328bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7331bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
734447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
735047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
735847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
736247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
737047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
737347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
737847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
738147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
738447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7385afc97b1e31b78c973c4bf5e0be8d5090cfca8065glennrp  entry->mime_type=ConstantString("video/x-mng");
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
739147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
739647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
7400d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
740247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
740547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
741047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
741547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
7420d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
742647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
743047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
743747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
744047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
744547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
7448fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 24-bit RGB");
7449d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
745447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
745947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
7463d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7467fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG48");
7468fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7469fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7470fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7471fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7472fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7473fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7474fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7475fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7476fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 48-bit RGB");
7477d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7478fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7479fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7480fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7481fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG64");
7482fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7483fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7484fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7485fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7486fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7487fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7488fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7489fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7490fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or transparent 64-bit RGBA");
7491d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7492fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7493fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7494fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
74955830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry=SetMagickInfo("PNG00");
74965830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
74975830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
74985830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74995830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
75005830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#endif
75015830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75025830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
75035830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->adjoin=MagickFalse;
75046270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp  entry->description=ConstantString(
75056270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp    "PNG inheriting bit-depth and color-type from original");
7506d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
75075830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->module=ConstantString("PNG");
75085830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) RegisterMagickInfo(entry);
75095830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
751147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
751847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
75227fee329aec1090ff832c1b07fc4cc70c3b604f65glennrp  entry->mime_type=ConstantString("image/x-jng");
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
75243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
752647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7527868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
75283d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy  ping_semaphore=AcquireSemaphoreInfo();
752918b17443128598500357da7bff2f01683cf32890cristy#endif
753047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
7560fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG48");
7561fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG64");
75625830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) UnregisterMagickInfo("PNG00");
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
756447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7565868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
7566cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
75673d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy    RelinquishSemaphoreInfo(&ping_semaphore);
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
757225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
759116ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
759216ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
760016ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7650cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7657bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
76780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
76790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
76810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7682ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7683a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7684a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7685a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7686a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7690ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7691a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7692a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7693a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7694a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7695a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7696a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7697a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77093b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7710f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
771247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
772047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
772747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
773047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7736cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
77374383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
775147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
775247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
775347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
775547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7759cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
776147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
776247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
776347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
776447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
776547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
776647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7767cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7768cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7769cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
777047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
777147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
777247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
777347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
777447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
777547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
777647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7777cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
777847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
778047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
778347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7787fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
7788fd6fd07e58e3d37313bec849313ac6e2b92e3957dirkstatic void write_tIME_chunk(Image *image,png_struct *ping,png_info *info,
7789fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  const char *date,ExceptionInfo *exception)
7790fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk{
7791fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  unsigned int
7792fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    day,
7793fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    hour,
7794fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    minute,
7795fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    month,
7796fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    second,
7797fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    year;
7798fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7799fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_time
7800fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ptime;
7801fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7802fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  time_t
7803fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ttime;
7804fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7805fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (date != (const char *) NULL)
7806fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
7807fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      if (sscanf(date,"%d-%d-%dT%d:%d:%dZ",&year,&month,&day,&hour,&minute,
7808fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          &second) != 6)
7809fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
7810fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
7811fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            "Invalid date format specified for png:tIME","`%s'",
7812fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            image->filename);
7813fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          return;
7814fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
7815fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.year=(png_uint_16) year;
7816fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.month=(png_byte) month;
7817fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.day=(png_byte) day;
7818fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.hour=(png_byte) hour;
7819fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.minute=(png_byte) minute;
7820fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.second=(png_byte) second;
7821fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
7822fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  else
7823fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  {
7824fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    time(&ttime);
7825fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    png_convert_from_time_t(&ptime,ttime);
7826fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
7827fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_set_tIME(ping,info,&ptime);
7828fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk}
7829fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
7830b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7831b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
783316ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
78343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
78350997332e2c35a821b271d6e7473c01c10dc206adcristy  char
78360997332e2c35a821b271d6e7473c01c10dc206adcristy    im_vers[32],
78370997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_runv[32],
78380997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_vers[32],
78390997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_runv[32],
78400997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_vers[32];
78410997332e2c35a821b271d6e7473c01c10dc206adcristy
784216ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
784316ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
784416ea139d53d867211d3bb0fa859a83de653f687ecristy
784516ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
784616ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
784716ea139d53d867211d3bb0fa859a83de653f687ecristy
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
78583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
78603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7861cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7862cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7863e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7864e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
78655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
786639992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
786739992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
78705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
78715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
78725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
78805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
78815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
78825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
788758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
788821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
788958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
789058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7891da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7892fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7893d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
78948d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
789539992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7896991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7897918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_iCCP,
7898991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7899918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_sRGB,
7900991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
790126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
790226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
790326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7904a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7905e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
790626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
790726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
790826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
790926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
791026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
791126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
791226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7913fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_exclude_tIME,
7914e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
791526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
791626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
791726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
791826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
79198d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
7920ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_iCCP,
79210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
79220e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
792382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
79248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7925d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7926d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79280997332e2c35a821b271d6e7473c01c10dc206adcristy  MemoryInfo
7929af1534a4abd2d6ef7f7e2833b95400301faff3d3cristy    *volatile pixel_info;
79300997332e2c35a821b271d6e7473c01c10dc206adcristy
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
793416ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
793516ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
793616ea139d53d867211d3bb0fa859a83de653f687ecristy
7937bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
79420997332e2c35a821b271d6e7473c01c10dc206adcristy    *ping_pixels;
7943d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
79445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7945f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
79460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
79475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
79485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
79495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
79505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
79515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
79525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7953bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
79545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
79555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7962dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7963fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7964f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
79658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
79668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
79678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7968dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7969dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7970dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7971dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7972dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7973dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7975fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
797716ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
797816ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
797916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
798016ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7981b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7982d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
7983d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
7984d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
7985d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
7986d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7987d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibVersionText,MaxTextExtent);
7988d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
7989d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibAddendum,MaxTextExtent);
7990ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7991d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
7992d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
7993ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
7994ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
7995ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
7996ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
7997ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
7998d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
7999d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
8000ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
8001ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
8002ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
8003ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
8004ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
80058fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (logging != MagickFalse)
8006d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
8007d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    IM version     = %s",
8008d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           im_vers);
8009d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Libpng version = %s",
8010d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           libpng_vers);
8011ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(libpng_vers,libpng_runv) != 0)
8012ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8013ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8014ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           libpng_runv);
8015ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8016d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
8017d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           zlib_vers);
8018ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(zlib_vers,zlib_runv) != 0)
8019ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8020ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8021ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           zlib_runv);
8022ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8023d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
8024d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
80255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
80260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
80275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
80285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
80295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
80305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
80315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
80325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
80345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
80355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
80365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
80375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
80385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
80405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
80415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
80425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
80435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
8044dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
8045dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
8046dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
8047dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8048da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
8049f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp  ping_have_cheap_transparency=MagickFalse;
8050d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
80518d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
805239992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
8053991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
8054918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_iCCP=MagickFalse;
8055991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
8056918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_sRGB=MagickFalse;
8057991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
8058991d11dd9c33e65872778b81aff1347cd2878154glennrp
80590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
80600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
8061a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
8062dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
80630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
80640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
80650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
80660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
80670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
80680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
80690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
8070fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  ping_exclude_tIME=mng_info->ping_exclude_tIME;
8071dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
80720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
80730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
80740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
80750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80768d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
8077ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  ping_preserve_iCCP = mng_info->ping_preserve_iCCP;
80780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
80790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80800d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
80810d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
80820d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
80830d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
80840d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
8085ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8086ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * To do: recognize other variants of the sRGB profile, using the CRC to
8087ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * verify all recognized variants including the 7 already known.
8088ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8089ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Work around libpng16+ rejecting some "known invalid sRGB profiles".
8090ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8091ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Use something other than image->rendering_intent to record the fact
8092ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * that the sRGB profile was found.
8093ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8094ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Record the ICC version (currently v2 or v4) of the incoming sRGB ICC
8095ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * profile.  Record the Blackpoint Compensation, if any.
80960d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
8097ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   if (ping_exclude_sRGB == MagickFalse && ping_preserve_iCCP == MagickFalse)
80980d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
80990d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
81000d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
81010d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81020d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
81030d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
81040d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81050d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
81060d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
81070d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
81080d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
81090d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81100d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
81110d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
81120d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
8113ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                (LocaleCompare(name,"ICM") == 0))
8114ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
8115ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             {
8116ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
8117ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
8118ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
81190d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81200d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8121ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
8122ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
8123ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
812429a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8125ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
8126ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
81270d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8128ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
812929a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8130ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
813129a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
8132ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
8133ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
8134ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
8135ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
8136ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8137ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
8138ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
81390d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8140ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
8141ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
81420d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8143ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8144ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
8145ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
8146ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
8147ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
8148ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
8149ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
8150ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8151ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
8152ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
8153ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
8154ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
8155ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
8156ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
8157ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
8158ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
8159ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
8160ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_iCCP = MagickTrue;
8161ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_zCCP = MagickTrue;
8162ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_have_sRGB = MagickTrue;
8163ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
8164ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
816529a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
81660d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
8167ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
816829a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8169ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
817029a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
817129a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
81720d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
81730d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
81740d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
81750d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
81760d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
81788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
81798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
81808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8181fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
8182fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8183fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
8184fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8185f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=UndefinedClass");
8186fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
8187fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8188f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=DirectClass");
8189fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
8190fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8191f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp          "    image->storage_class=PseudoClass");
8192f3794ae8cfb6e17f5161c2ecfe15a29fba5ece80glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(), image->taint ?
8193cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickTrue":
8194cc96f2d3d09f91c9333d05e2e7216d4006f8a5eaglennrp          "    image->taint=MagickFalse");
8195fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
819628af3713c9111a471cc868c787760de89236fa3cglennrp
8197750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
81987e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
8199fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png48 || mng_info->write_png64 ||
8200fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     (mng_info->write_png_colortype != 1 &&
8201fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png_colortype != 5)))
82027e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
820316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
82047e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
82057e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
82067e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
8207c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
820828af3713c9111a471cc868c787760de89236fa3cglennrp    {
8209c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
8210c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
8211c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
8212c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
8213c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8214c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
8215e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
8216c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
8217c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
821828af3713c9111a471cc868c787760de89236fa3cglennrp    }
8219bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8220c28acd632b7ea1724a54191d15db932f2e4d25e6glennrp  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
822116ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
82220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82233241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
82243241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
82253241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
82263241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
82273241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
822816ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
82293241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8230a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
8231a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
8232a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
8233a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
8234a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8235a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
8236a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8237a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
8238a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
8239a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
8240a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
82418e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
8242cd979955e4249aab3bdd79043718fa3b120239b8dirk  if (image->depth < 4)
824367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
824416ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
82458e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
82468e58efdecda887b08ef730d68290a61081ef2566glennrp
8247aac49630945ded4a68aca4f7c892e18b21afeba8dirk       if (image->depth > 2)
82488e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82498e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
825091d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
82518e58efdecda887b08ef730d68290a61081ef2566glennrp
82528e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82538e58efdecda887b08ef730d68290a61081ef2566glennrp           {
825416ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82558e58efdecda887b08ef730d68290a61081ef2566glennrp
825616ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82578e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82588e58efdecda887b08ef730d68290a61081ef2566glennrp
82598e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82608e58efdecda887b08ef730d68290a61081ef2566glennrp             {
826116ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
826216ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82638e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8264bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82658e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82668e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82678e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82688e58efdecda887b08ef730d68290a61081ef2566glennrp
82698e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82708e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82713e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82728e58efdecda887b08ef730d68290a61081ef2566glennrp             {
827391d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
82748e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82758e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82768e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82778e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
82788e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82798e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
828091d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
82818e58efdecda887b08ef730d68290a61081ef2566glennrp
82828e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82838e58efdecda887b08ef730d68290a61081ef2566glennrp           {
828416ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82858e58efdecda887b08ef730d68290a61081ef2566glennrp
828616ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82878e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82888e58efdecda887b08ef730d68290a61081ef2566glennrp
82898e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82908e58efdecda887b08ef730d68290a61081ef2566glennrp             {
829116ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
829216ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82938e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8294bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82958e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82968e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82978e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82988e58efdecda887b08ef730d68290a61081ef2566glennrp
82998e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83008e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83013e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83028e58efdecda887b08ef730d68290a61081ef2566glennrp             {
830391d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
83048e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83058e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83068e58efdecda887b08ef730d68290a61081ef2566glennrp         }
83078e58efdecda887b08ef730d68290a61081ef2566glennrp       else
83088e58efdecda887b08ef730d68290a61081ef2566glennrp         {
83098e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
831091d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
83118e58efdecda887b08ef730d68290a61081ef2566glennrp
83128e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
83138e58efdecda887b08ef730d68290a61081ef2566glennrp           {
831416ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83158e58efdecda887b08ef730d68290a61081ef2566glennrp
831616ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
83178e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83188e58efdecda887b08ef730d68290a61081ef2566glennrp
83198e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83208e58efdecda887b08ef730d68290a61081ef2566glennrp             {
832116ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
832216ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83238e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8324bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83258e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83268e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83278e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83288e58efdecda887b08ef730d68290a61081ef2566glennrp
83298e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83308e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83313e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83328e58efdecda887b08ef730d68290a61081ef2566glennrp             {
833391d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
83348e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83358e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83368e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8337cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8338cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
833967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
834067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
834170e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8342a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
83432b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
83442b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
83452b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
83462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
83478e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
83482b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
83492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
83502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83513faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8352cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8353cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8354cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8355cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8356cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8357cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8358c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
835916ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
83608640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
83618640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
83628640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8363d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  image_colors = (int) image->colors;
8364d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_opaque = (int) image->colors;
8365d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_transparent = 0;
8366d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_semitransparent = 0;
8367d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
8368197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype &&
8369a8036d6466b63ead629795b60772f160cca77c4cglennrp     (mng_info->write_png_colortype > 4 || (mng_info->write_png_depth >= 8 &&
8370a8036d6466b63ead629795b60772f160cca77c4cglennrp     mng_info->write_png_colortype < 4 &&
837135553db9b7d0d812b53b09e3906628239d908e1ccristy     image->alpha_trait != BlendPixelTrait)))
8372a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8373a8036d6466b63ead629795b60772f160cca77c4cglennrp     /* Avoid the expensive BUILD_PALETTE operation if we're sure that we
8374a8036d6466b63ead629795b60772f160cca77c4cglennrp      * are not going to need the result.
8375a8036d6466b63ead629795b60772f160cca77c4cglennrp      */
8376a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (mng_info->write_png_colortype == 1 ||
8377a8036d6466b63ead629795b60772f160cca77c4cglennrp        mng_info->write_png_colortype == 5)
8378a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickFalse;
8379a8036d6466b63ead629795b60772f160cca77c4cglennrp
838035553db9b7d0d812b53b09e3906628239d908e1ccristy     if (image->alpha_trait == BlendPixelTrait)
8381a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8382a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 2;
8383a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 1;
8384a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8385a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8386a8036d6466b63ead629795b60772f160cca77c4cglennrp
8387197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype < 7)
8388a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8389a8036d6466b63ead629795b60772f160cca77c4cglennrp  /* BUILD_PALETTE
8390a8036d6466b63ead629795b60772f160cca77c4cglennrp   *
8391a8036d6466b63ead629795b60772f160cca77c4cglennrp   * Normally we run this just once, but in the case of writing PNG8
8392e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8393e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
83948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
83958ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
83968ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
83978ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8398c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
839982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
84008ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
840182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8402d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
840382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
84048ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8406a8036d6466b63ead629795b60772f160cca77c4cglennrp    /*
8407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8408d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8410d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
84168a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8420d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8423d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
84263c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
84298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
843016ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
84348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
843516ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
843616ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8437d6bf1617e99df0272b231855a933a74e99b6578fglennrp
843816ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
843916ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8440fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8441fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8443d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8447d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84538a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
845403812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
84563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8457fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
84587ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
84597ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
84618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
846216ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
84632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
84657ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
847216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
84737ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
84742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8479d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
848516ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8488d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
84892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
849283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
849416ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
849516ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
84967ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
84978d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
84988d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84998d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8500d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
85017ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8503fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8504fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8505fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
85062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
85107ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
851116ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8512d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
851397fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8514d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8515d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
851635553db9b7d0d812b53b09e3906628239d908e1ccristy           if (image->alpha_trait != BlendPixelTrait ||
851716ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
85188d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
85208d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8522d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
852316ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
852416ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
853016ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8531d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
853416ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8535d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
853716ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
853816ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85408d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85418d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
854216ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
85438d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
85458d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8547d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
854816ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
854916ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
855016ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
855116ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
855216ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
855316ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
855416ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
855516ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8556972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
856216ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8565d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8566d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8569d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
857016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8571d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85728d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85738d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8574d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
858016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85838d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
858616ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
858716ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
858816ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8589d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8590d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8592d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8593d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8594d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8595d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
859616ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8597d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8598d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
85998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
860016ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8601d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8602d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
86033c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
86044054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
86054054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8606d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8607d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8608d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8609d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8610c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8611c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8612c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8613c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8614c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8615c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8616c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8617c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8618d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8619d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8620ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8621ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8622ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8623ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8624d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8625d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
862603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
86278e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8628c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8629388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8630c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8631c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8632c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8633c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8634c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8635c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
863603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8637a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8638a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8639a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8640d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8642d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
86433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8644d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8645d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8646d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8647d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8648d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
86493241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8650d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8651d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8652d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8653d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86543241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
86558d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
86568d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
86578d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8658fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8659d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8660d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
86610fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
86620fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
866345d4c34ce93ff377b9671844ffa1153b821061f6glennrp         if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
86640fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
866596bc620815234aaec28b928df51d1754cbe390dcglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
866696bc620815234aaec28b928df51d1754cbe390dcglennrp              "incompatible colorspace");
86677fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
866898b95773e388844e22c6e4006bb88396b33cf6b4glennrp           ping_have_non_bw=MagickTrue;
86690fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
86700fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
8671d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8672d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8673d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8674d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8675d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
86766185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
867716ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8678d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
86796185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8680e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8681e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8682e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
868316ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
868416ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8685e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8686e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8687e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8688e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8689e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
869016ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8691e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8692e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8693e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8694e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8695e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8696d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8697d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8698d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
86996185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8700d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8701d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8702d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8703d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
87046185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
870516ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
870616ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8707d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8708d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8709e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8710d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
871116ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8712d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8713e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8714d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8715bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8716bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
87174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8718d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8719d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
872016ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8721d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8722bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8723d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8724d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8725d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8726d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8727d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8728d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8729d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8730d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8731d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8732d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8733d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
87343241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8735d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8736d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
87373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8738d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8739d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8740d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8741d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8742d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8743d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8744c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8745c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8746bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8747d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8748d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8749d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8750d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8751d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8752d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8753d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8754d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8755d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8756d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8757d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8758d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8759d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8760d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8761d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8762d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8763d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8764d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8765d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8766d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8767d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8768d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
87693241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8770d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8771d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8772d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8773d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8774d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8775d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8776d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
87776185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8778d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8779d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8780d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8781d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
87822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8783d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8784d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8785d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8786d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8787d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8788d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
878916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8790d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
87913faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
87923faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8793d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8794d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8795d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8796d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8797d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8798d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8799d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8800d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8801d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8802bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8803d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8804d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8805d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8806d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8807fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8808fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8809d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8810d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
881116ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
88123c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
881316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8814d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
88153c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8816d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8817d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8818d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
881903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
882035553db9b7d0d812b53b09e3906628239d908e1ccristy                  if ((image->alpha_trait != BlendPixelTrait ||
882116ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
882216ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
882316ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
882416ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
88256185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
882616ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8827d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
88286185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
882903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
883016ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8831d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8832d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8833d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8834d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8835d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8836d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8837d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8838d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8839d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8840d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8841d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8842d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8843d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8844d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8845d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8846d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
884716ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
884883c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8849d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8850d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
885172988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8852d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8853d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8854d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8855d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8856d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8857d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8858d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
885916ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8860d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
88616185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
88626185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
88633c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8864d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8865d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8866d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8867d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8868d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
88693c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8870d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8871d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
88723c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8873d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8874d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8875d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8876d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
887703812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8878d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8879d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8880d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
88816185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8882d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8883d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8884d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8885d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
88866185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8887d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8888d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8889d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8890a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8891d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8892d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8893d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8894a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8895d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8896d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8897d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8898d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8899d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8900d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8901d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
89026185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
890303812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
890403812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8905d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
89063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8907c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8908c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8909fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8910c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8911c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8912c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8913c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8914c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8915c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8916fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8917c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8918130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8919130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8920130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8921c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8922130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8923c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8924c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8925c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8926fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8927c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8928c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
892916ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8930fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
893116ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8932c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8933fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8934c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8935c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
893616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
89378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
893816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelInfoPixel(image,&image->background_color,r);
893916ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
89408ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
89418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
894216ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
894316ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8944c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8945bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8946c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8947c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8948fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8949c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8950c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8951c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
895216ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
895316ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
895416ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8955c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8956c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8957c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8958c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8959c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8960e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8961e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8962e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8963c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8964d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8965d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8966d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8967d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8968d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8969d337164012450d70d62e71cf4a308a29004f7d57glennrp
8970d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8971d337164012450d70d62e71cf4a308a29004f7d57glennrp
897291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8973d337164012450d70d62e71cf4a308a29004f7d57glennrp
8974d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8975d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8976d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8977d337164012450d70d62e71cf4a308a29004f7d57glennrp
8978d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8979d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8980d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8981d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
898216ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8983d337164012450d70d62e71cf4a308a29004f7d57glennrp
898416ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
8985d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8986d337164012450d70d62e71cf4a308a29004f7d57glennrp
8987d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8988d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
898916ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
899054cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
899116ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8992d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8993bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8994d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8995d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8996d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8997d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8998d337164012450d70d62e71cf4a308a29004f7d57glennrp
8999d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
9000d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
9001d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
9002d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
9003d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9004d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
90058e58efdecda887b08ef730d68290a61081ef2566glennrp
9006d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
9007d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
900891d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
9009d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
9010d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9011d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
9012d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
9013d337164012450d70d62e71cf4a308a29004f7d57glennrp
901482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
901582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
901682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
901782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
901882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
901982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
902082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
902182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
902291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
902382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
902482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
902582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9026e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
902782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
902882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
902982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
903082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
903182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
903216ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
903382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
903416ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
903582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
903682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
903782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
903882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
903916ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
904016ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
904116ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
904282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
9043bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
904482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
904582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
904682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
904782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
904882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
904982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
905082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
905182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
905282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
905382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9054e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
905582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
905682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
905791d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
905882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
9059d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9060d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
906182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
9062c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90638ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
9064c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
9065c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9066c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9067c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
9068c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90698ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
90708ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
90713faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
90723faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
90733faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
90743faa9a3fb01696daaf976d595f492cb530bffb21glennrp
907591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
9076fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9077c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9078c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9079e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
9080fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9081c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
9082c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9083c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
9084c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
908516ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
90868d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
908716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9088c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
9089c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
9090c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
9091c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
909216ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
909354cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
909416ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9095c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
9096bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9097c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9098c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
9099c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9100c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
9101c722dd852e8abe407c2846d39662f7ade9c234deglennrp
9102c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
9103c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
9104c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9105c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
9106c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9107e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
9108c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
9109c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
911091d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
9111c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9112c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
9113c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
9114c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
91158ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91168ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
91178ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
911834ef720923a27004960cbcf4d75a8075445e85d7glennrp      /* Take care of special case with 256 opaque colors + 1 transparent
91198ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
91208ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
91218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
91228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
912334ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
912434ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
912534ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red background colors to 3-3-2-1");
912634ef720923a27004960cbcf4d75a8075445e85d7glennrp
91278ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
91288ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
91298ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
91308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91318ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
91328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
9133bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
913434ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
913534ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
913634ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red pixel colors to 3-3-2-1");
913734ef720923a27004960cbcf4d75a8075445e85d7glennrp
91388ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
91398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91408ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
91418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
914216ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9143bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
914416ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
91458ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
9146bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91478ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
91488ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
914916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
915016ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
915116ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
915216ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
91538ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
915416ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
91558ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
915616ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
91578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
9158bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91598ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
91608ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
9161bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91628ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
91638ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91648ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91658ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
91668ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91678ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
91688ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
91698ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
91708ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
91718ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
91728ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
91738ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
91748ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
91758ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
91768ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91778ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
9178fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
9179a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
9180fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
9181fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9182fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
9183fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
9184fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
9185fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
91860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
91870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
91880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
9189d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
91900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
91920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
91930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
91950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
91960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91978d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
9198d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
91990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
92000b206f5daa453dc1035db5890cabc899736dc2d0glennrp
92010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
92020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
9203fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
9204fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
9205fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
92065a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
92075a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
92085a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
9209fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
92105a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
92115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
9212fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
9213fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
9214fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9215fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
9216fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
9217fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9218fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
9219fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
9220fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
922116ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
9222fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
9223fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9224fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
9225fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
9226fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
9227fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
922816ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
9229fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
9230fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9231fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
9232fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
923316ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
923416ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
923516ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
923616ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
923716ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
923816ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
923916ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
9240fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
9241fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
9242fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
9243fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
9244fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
924516ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
9246fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
9247bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9248fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
9249fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
9250fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
9251fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9252fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
9253fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
925467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
925567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
925667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
9257fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
925867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
925967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
926067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
926167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
9262fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
926367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
926467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
9265fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
9266fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9267bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9268fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
9269fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
9270fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
9271fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9272fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
9273fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9274fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
9275fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9276fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
9277fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9278fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
9279fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
9280fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
9281fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
92823c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
92833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
92843c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
92853c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
9286f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
928735553db9b7d0d812b53b09e3906628239d908e1ccristy  image_matte=image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse;
928883c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
928948c20621d4ce02a3833b107f710843d1e524d559glennrp  if (mng_info->write_png_colortype < 5)
9290197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette=image->storage_class == PseudoClass &&
9291197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      image_colors <= 256 && image->colormap != NULL;
9292197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  else
9293197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette = MagickFalse;
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
929552a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
929652a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
929752a479ca718756af72f96e127f8256499ab68f76glennrp    {
929816ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
929916ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
930016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
930115e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
930216ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
930352a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
930452a479ca718756af72f96e127f8256499ab68f76glennrp    }
930552a479ca718756af72f96e127f8256499ab68f76glennrp
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
931016ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
931116ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
93123e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
9313cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
9314cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
93150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
93173e0971dc28bdc9227481f5a7f9e1510be662ec4aglennrp  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9318cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
93190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
93250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
93330997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=(MemoryInfo *) NULL;
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9345868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9346cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9348edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
93490997332e2c35a821b271d6e7473c01c10dc206adcristy      if (pixel_info != (MemoryInfo *) NULL)
93500997332e2c35a821b271d6e7473c01c10dc206adcristy        pixel_info=RelinquishVirtualMemory(pixel_info);
9351edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9352edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9353edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9354edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
935516ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
935616ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
935716ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
935816ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9361edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9362edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9363edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9364edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9365edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9366edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9367868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9368edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9369edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9370edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9371943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
9372a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
9373a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
9374a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
9375a3a5f956194e91458e2789966ad15308e8f3df47glennrp
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93799bf97b6c2143eb20c330346b01e82102cc082725glennrp
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
938225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
938425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
938525024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
938625024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
938725024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
938825024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
938925024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
939025024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
93912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
93962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
94012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94024e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
94034e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
94042b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9408fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48 || mng_info->write_png64)
9409fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     image_depth=16;
9410fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
94130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
94170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
94230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9427e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9429e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94318a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94338640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94358640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94378640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
94395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9440dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
944126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
944326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
944426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
944516ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9449dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9450dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9454dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9455823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
945616ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9457823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
945816ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9460dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9463dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
946416ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
946516ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9467991d11dd9c33e65872778b81aff1347cd2878154glennrp
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9470dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
947116ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
947216ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9474991d11dd9c33e65872778b81aff1347cd2878154glennrp
9475823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9476823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9477823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9478823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9479823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9480991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
948226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9484a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
948526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
948626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9487a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9489a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9490a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9491a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9492a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9493a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9494a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
94950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9496a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9497a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
94980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9499a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9500a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
95010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9502a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9503a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
95040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9505a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9506a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
95070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9508a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9509a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
95100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9511a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9512a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9513c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9514c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
95150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
95160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
95183b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
95193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95203b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9521c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9522c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9523c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
95243b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
95253b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
95273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
95280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
953026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
95370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95381273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9540fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
95410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
95420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
95448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
95458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
95460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
95480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
95490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
95500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
95510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
95530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9555f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
95560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
95580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
95590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
95600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
95610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
95620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
95630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
956467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
95650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
956667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
956767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
956867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
95690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
95703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
95722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
95748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
95758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
95765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
957758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
95788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
95790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
95800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
95810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
95820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
95838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
95843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
95868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
95870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95892cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
95908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
95910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
95930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
95940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
95968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
95978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
95980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95991273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
96004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
96011273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
96021273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
96031273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
96041273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
96054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
96064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
96074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
96080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9610c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9611c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9612c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9613c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9614c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9615c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9616c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
96174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
96190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9620fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png_colortype == 1)
9621fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
9622fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image_matte=MagickFalse;
9623fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
9624fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
9625fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
9626fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png24 || mng_info->write_png48 ||
9627fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 3)
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
96305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9633fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png32 || mng_info->write_png64 ||
9634fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 7)
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
96375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
96430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
96470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
96495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
96512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
96547c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
96557c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
96567c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96577c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96607c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96643c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
96650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9666d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
96678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
96680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9669d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
96703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
96733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9675d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
96763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96815aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
96825aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
96835aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
96845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
96857c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
9686261f64eea2c3a5a9586da65af2c59d2a39b05de0glennrp             image_info->type == UndefinedType)
96873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96885aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
96898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96905aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
96915aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96925aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
96935aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
96945aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
96950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96960b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
96975aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
96985aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
96995aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
97005aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
97025aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
97035aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
97045aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
97055aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97065aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
97075aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
97085aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
97100b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
97115aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97125aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
97135aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
97145aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97155aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
97160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
97175aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
972126c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97228640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
972326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
97245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
97250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
97260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
97270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
97280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
97290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
97300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9732d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9733d6bf1617e99df0272b231855a933a74e99b6578fglennrp
97345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
973635553db9b7d0d812b53b09e3906628239d908e1ccristy          if (image->alpha_trait != BlendPixelTrait && ping_have_non_bw == MagickFalse)
97378d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97398640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
974235ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
97435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
97440f111984738842d27d04aed2a3f823d82a943506glennrp
97450f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
97460f111984738842d27d04aed2a3f823d82a943506glennrp           {
97470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9748edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
97490f111984738842d27d04aed2a3f823d82a943506glennrp           }
97500f111984738842d27d04aed2a3f823d82a943506glennrp
975135ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
97525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9753d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9755d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9756d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9757d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9758d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
97590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9760d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9761d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9762d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
97630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9764d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9765d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
97692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97731a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
97741a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
97751a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
97760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9778e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
97790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9781e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
97820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97843c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
97858640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
97868640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97878640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9788e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
979158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
97923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
97944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
97957c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
97967c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
97977c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
97982b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97997c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
98007c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
98017c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
98022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
98074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
98094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
98104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9811a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
98124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
98137c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
98147c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98157c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
98164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
98194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9821bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
98240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
98264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
98270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
98294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
98300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
98324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
98330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
98354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
98360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
98384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
98390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
98414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
98420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
98444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
98450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
984716ea139d53d867211d3bb0fa859a83de653f687ecristy                (ScaleQuantumToShort(GetPixelInfoIntensity(
98484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
98490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
98510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
98534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9858fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9859fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9860fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9861fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9862fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
98634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98677c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98687c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
98690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
98714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
98724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
98734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
98744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
98754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
98764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
98774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
98794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
98804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
98835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
98845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
98855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
98865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98908640fb5e9b1094f35f8beab436f81661b8a99448glennrp
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
98920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98932e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
98950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
989639992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
98988d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
98998d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
99003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
990135ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
99020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
99049c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
99050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99067c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
99073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
99094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
99114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
99124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
99134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
99144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
99164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
99174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
99184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
99230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9924136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9925d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9926f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
99270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
99295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
99300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
99345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
99353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
99385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
99390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
994035ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9941bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
99425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99452b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
99470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
99511a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
99684bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
99712b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
99739c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
99740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
99769c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
99770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
99799c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99822b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
99850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
99870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
999017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
999117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
99953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
99975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
99980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99993d627862fb79aad8a20be4f1587f0b8761db441aglennrp            if (!(mng_info->have_write_global_plte && matte == MagickFalse))
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10001bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
100023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
100070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1001098156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
10011f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
100120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1001339992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
100143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
10017d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10019befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
10020befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
10021befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
100225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
10023befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
100240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1002516ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
100265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
100300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1003158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
100320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
100330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
10034d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
10035d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
100360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10038d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
10039d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
100403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
100420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
100430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10044d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
100450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
10046c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
10047c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
10048c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10049c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
10050c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
10051d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
10052d6bf1617e99df0272b231855a933a74e99b6578fglennrp
10053d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
10054d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
10055750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
1005616ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
10057d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
100580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
100590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10065c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
100680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
100703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
100754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
100815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
100825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
100835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
100844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
100894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100964383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
100974383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
100982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
101025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
101033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
101043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
101053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1010835ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
1010935ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
1011035ef824baa82511126ff0072ae30eee0da9c05a3cristy
1011122ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
101123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
1011426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
101153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1011616ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
1011716ea139d53d867211d3bb0fa859a83de653f687ecristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(
1011816ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
1011916ea139d53d867211d3bb0fa859a83de653f687ecristy
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
101218f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1012216ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
1012316ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1012416ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
1012516ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
101263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
10127991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
1012826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101303e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101313e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101323e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
101333e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
101343e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101359be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
101363e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
101373e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101383e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101393e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101403e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
101413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1014217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1014326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1014426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
101451273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
1014617a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
1014717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
1014817a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
1014917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
1015017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1015117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1015217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10153a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
10154a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
1015517a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
1015617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1015717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
1015817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101593b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
101600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
101610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
101630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
10164a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1016513d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
10166a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
101670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
101683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101693b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
101710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
101730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
101740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
101750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
101760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
10177a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
1017817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10179d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
101803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
101813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101833b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
101843c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
101853c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
1018617a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
1018726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1018817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101911a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
101921a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
101943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
101963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
101980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
102000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
102030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
102040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
102060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
102100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102114054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
102124054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
1021310d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
1021410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021510d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
1021610d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
1021710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1021810d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
1021910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10220ef804f5802b3d6517d516556b64fccc5843710b6glennrp        0 or omitted: Use Z_HUFFMAN_ONLY strategy with the
1022110d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
1022210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
1022410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022510d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
1022610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
1022810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1022910d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
1023010d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
1023110d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
10232750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
1023310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
1023410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
1023685dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             a MNG, otherwise "none".  Did not work in IM-6.7.0-9
1023710d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
1023810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023985dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp        8:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), adaptive
1024085dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             filtering. Unused prior to IM-6.7.0-10, was same as 6
1024110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10242ef804f5802b3d6517d516556b64fccc5843710b6glennrp        9:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), no PNG filters
102431868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
1024410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1024510d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
1024610d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
1024716ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
1024816ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
1024910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1025010d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
1025110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1025229dd80efe8d7489d5f689a8a723454e684f92a8fdirk  quality=image_info->quality == UndefinedCompressionQuality ? 75UL :
1025329dd80efe8d7489d5f689a8a723454e684f92a8fdirk     image_info->quality;
102540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102551868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
102561868258559ddf946fa73ef72dd43507b32623705glennrp    {
102571868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
102581868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
102591868258559ddf946fa73ef72dd43507b32623705glennrp    }
10260750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
102611868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
102623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
102643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
102653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10266bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
102670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102681868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
102691868258559ddf946fa73ef72dd43507b32623705glennrp    }
102700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102711868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
102721868258559ddf946fa73ef72dd43507b32623705glennrp    {
102731868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
10274a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
10275a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
10276a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
10277a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
10278a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102811868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
102821868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
102831868258559ddf946fa73ef72dd43507b32623705glennrp
102841868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
102853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102861868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
102873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102881868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
102891868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
102900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102911868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
102921868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102931868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
102941868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
102950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102961868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102971868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102994054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
1030010d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103011868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
103024054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
103034054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
103041868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103051868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
103061868258559ddf946fa73ef72dd43507b32623705glennrp        else
103071868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103081868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
103091868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
103103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103121868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
103131868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
103140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103151868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
103161868258559ddf946fa73ef72dd43507b32623705glennrp    {
103171868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
103181868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
103191868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
103201868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103211868258559ddf946fa73ef72dd43507b32623705glennrp      else
103221868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
103231868258559ddf946fa73ef72dd43507b32623705glennrp     }
103244054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
103251868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
103261868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1032710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
103281868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
103291868258559ddf946fa73ef72dd43507b32623705glennrp    {
103301868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
103311868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
103321868258559ddf946fa73ef72dd43507b32623705glennrp      {
103331868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
103341868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
103351868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
103361868258559ddf946fa73ef72dd43507b32623705glennrp      }
103371868258559ddf946fa73ef72dd43507b32623705glennrp#endif
103384054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103391868258559ddf946fa73ef72dd43507b32623705glennrp    }
103400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103411868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
103421868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103441868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
103451868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
103461868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
103470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103481868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
103491868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
103501868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
103512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10352dec72c9b492c176af9813be3105518e91835ed37glennrp  ping_interlace_method=image_info->interlace != NoInterlace;
10353dec72c9b492c176af9813be3105518e91835ed37glennrp
10354dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_mng)
10355dec72c9b492c176af9813be3105518e91835ed37glennrp    png_set_sig_bytes(ping,8);
10356dec72c9b492c176af9813be3105518e91835ed37glennrp
10357dec72c9b492c176af9813be3105518e91835ed37glennrp  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
10358dec72c9b492c176af9813be3105518e91835ed37glennrp
10359dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_png_colortype != 0)
10360dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10361dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
10362dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10363dec72c9b492c176af9813be3105518e91835ed37glennrp         {
10364dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
10365dec72c9b492c176af9813be3105518e91835ed37glennrp
10366dec72c9b492c176af9813be3105518e91835ed37glennrp           if (ping_bit_depth < 8)
10367dec72c9b492c176af9813be3105518e91835ed37glennrp             ping_bit_depth=8;
10368dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10369dec72c9b492c176af9813be3105518e91835ed37glennrp
10370dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
10371dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10372dec72c9b492c176af9813be3105518e91835ed37glennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
10373dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10374dec72c9b492c176af9813be3105518e91835ed37glennrp
10375dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_need_colortype_warning != MagickFalse ||
10376dec72c9b492c176af9813be3105518e91835ed37glennrp     ((mng_info->write_png_depth &&
10377dec72c9b492c176af9813be3105518e91835ed37glennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
10378dec72c9b492c176af9813be3105518e91835ed37glennrp     (mng_info->write_png_colortype &&
10379dec72c9b492c176af9813be3105518e91835ed37glennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10380dec72c9b492c176af9813be3105518e91835ed37glennrp      mng_info->write_png_colortype != 7 &&
10381dec72c9b492c176af9813be3105518e91835ed37glennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
10382dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10383dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10384dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10385dec72c9b492c176af9813be3105518e91835ed37glennrp          if (ping_need_colortype_warning != MagickFalse)
10386dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10387dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10388dec72c9b492c176af9813be3105518e91835ed37glennrp                 "  Image has transparency but tRNS chunk was excluded");
10389dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10390dec72c9b492c176af9813be3105518e91835ed37glennrp
10391dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_depth)
10392dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10393dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10394dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:bit-depth=%u, Computed depth=%u",
10395dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_depth,
10396dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_bit_depth);
10397dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10398dec72c9b492c176af9813be3105518e91835ed37glennrp
10399dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_colortype)
10400dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10401dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10402dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:color-type=%u, Computed color type=%u",
10403dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_colortype-1,
10404dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_color_type);
10405dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10406dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10407dec72c9b492c176af9813be3105518e91835ed37glennrp
10408dec72c9b492c176af9813be3105518e91835ed37glennrp      png_warning(ping,
10409dec72c9b492c176af9813be3105518e91835ed37glennrp        "Cannot write image with defined png:bit-depth or png:color-type.");
10410dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10411dec72c9b492c176af9813be3105518e91835ed37glennrp
1041235553db9b7d0d812b53b09e3906628239d908e1ccristy  if (image_matte != MagickFalse && image->alpha_trait != BlendPixelTrait)
10413dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10414dec72c9b492c176af9813be3105518e91835ed37glennrp      /* Add an opaque matte channel */
10415dec72c9b492c176af9813be3105518e91835ed37glennrp      image->alpha_trait = BlendPixelTrait;
10416dec72c9b492c176af9813be3105518e91835ed37glennrp      (void) SetImageAlpha(image,OpaqueAlpha,exception);
10417dec72c9b492c176af9813be3105518e91835ed37glennrp
10418dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10419dec72c9b492c176af9813be3105518e91835ed37glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10420dec72c9b492c176af9813be3105518e91835ed37glennrp          "  Added an opaque matte channel");
10421dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10422dec72c9b492c176af9813be3105518e91835ed37glennrp
10423dec72c9b492c176af9813be3105518e91835ed37glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10424dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10425dec72c9b492c176af9813be3105518e91835ed37glennrp      if (ping_color_type < 4)
10426dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10427dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_have_tRNS=MagickTrue;
10428dec72c9b492c176af9813be3105518e91835ed37glennrp           if (logging != MagickFalse)
10429dec72c9b492c176af9813be3105518e91835ed37glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10430dec72c9b492c176af9813be3105518e91835ed37glennrp               "  Setting ping_have_tRNS=MagickTrue.");
10431dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10432dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10433dec72c9b492c176af9813be3105518e91835ed37glennrp
10434dec72c9b492c176af9813be3105518e91835ed37glennrp  if (logging != MagickFalse)
10435dec72c9b492c176af9813be3105518e91835ed37glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10436dec72c9b492c176af9813be3105518e91835ed37glennrp      "  Writing PNG header chunks");
10437dec72c9b492c176af9813be3105518e91835ed37glennrp
10438dec72c9b492c176af9813be3105518e91835ed37glennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
10439dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_bit_depth,ping_color_type,
10440dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_interlace_method,ping_compression_method,
10441dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_filter_method);
10442dec72c9b492c176af9813be3105518e91835ed37glennrp
10443dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
10444dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10445dec72c9b492c176af9813be3105518e91835ed37glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
10446dec72c9b492c176af9813be3105518e91835ed37glennrp
10447dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10448dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10449dec72c9b492c176af9813be3105518e91835ed37glennrp          for (i=0; i< (ssize_t) number_colors; i++)
10450dec72c9b492c176af9813be3105518e91835ed37glennrp          {
10451dec72c9b492c176af9813be3105518e91835ed37glennrp            if (i < ping_num_trans)
10452dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10453dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10454dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10455dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10456dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10457dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue,
10458dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10459dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) ping_trans_alpha[i]);
10460dec72c9b492c176af9813be3105518e91835ed37glennrp             else
10461dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10462dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d)",
10463dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10464dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10465dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10466dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue);
10467dec72c9b492c176af9813be3105518e91835ed37glennrp           }
10468dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10469dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10470dec72c9b492c176af9813be3105518e91835ed37glennrp
104710d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
104720d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
104733d627862fb79aad8a20be4f1587f0b8761db441aglennrp     (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
104740d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
104750d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
104760d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
104770d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10478c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10479c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
104813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10482c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
104830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10484c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10485c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10486c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10487c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10488c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1048926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10490c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10491c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10492c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
10493ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10494ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          "  Setting up iCCP chunk");
10495ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
1049616ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10497e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10499e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10500e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
10501e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10502c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10503918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                       ping_have_iCCP = MagickTrue;
10504c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1050526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
105060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10507c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
105083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10509c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10510c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10511ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10512ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      "  Setting up zTXT chunk with uuencoded ICC");
10513cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10514c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10515c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10516c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10517ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  ping_have_iCCP = MagickTrue;
10518c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10519c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
105200b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10521c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10522c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10523c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
105240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10525c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10526c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
105270d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
10532ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_have_iCCP != MagickTrue &&
10533ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      (ping_have_sRGB != MagickFalse ||
10534ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1053626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1053726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1053826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1053926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1054026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1054126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1054226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
105440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1054526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10546cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10547cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
10548918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp
10549918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB = MagickTrue;
1055026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1055226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
105535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105562cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
10557918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_iCCP == MagickFalse &&
10558918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB == MagickFalse &&
105592cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1056026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1056126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
105713b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1057426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
105752b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10576918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp      if (ping_exclude_cHRM == MagickFalse && ping_have_sRGB == MagickFalse)
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1057826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1057926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1058026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1058126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1058226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
10583918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                Note: if cHRM+gAMA == sRGB write sRGB instead.
1058426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1058526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1058626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1058726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1058826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1058926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1059026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1059126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1059226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1059326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1059426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1059526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1059626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1059726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1059826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1059926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1060026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1060126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1060226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1060326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10605dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1060626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1060726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1060826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10609c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1061026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
106118fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10612c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10613c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10614c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10615c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10616c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10617c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10618c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10619c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10620c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10621c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10622c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10623c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10624c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10625c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1062626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10627991d11dd9c33e65872778b81aff1347cd2878154glennrp
1062826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10629dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1063026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1063126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1063226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1063326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1063426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1063526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10636823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
106378fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10638823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10639823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10640823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10641823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10642823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10643823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10644823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10645823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10646823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10647823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10648823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10649823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10650823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1065126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10652dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10653dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10654dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
106554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10656dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1065726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1065826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1065926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1066026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10661dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1066226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1066326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1066426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1066526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1066626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10667dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10668dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10669dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10670fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
10671fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (ping_exclude_tIME == MagickFalse)
10672fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
10673fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      const char
10674fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        *timestamp;
10675fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
1067639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (image->taint == MagickFalse)
10677fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
1067839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageOption(image_info,"png:tIME");
1067939d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1068039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          if (timestamp == (const char *) NULL)
10681fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            timestamp=GetImageProperty(image,"png:tIME",exception);
10682fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
1068339d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1068439d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      else
1068539d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        {
1068639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1068739d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp             "  Reset tIME in tainted image");
1068839d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1068939d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          timestamp=GetImageProperty(image,"date:modify",exception);
1069039d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp        }
1069139d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
1069239d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp      if (timestamp != (const char *) NULL)
1069339d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp          write_tIME_chunk(image,ping,ping_info,timestamp,exception);
10694fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
10695fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
1069639d99e13b7e8233a9ce9fc6d9fd425829426525bglennrp
10697da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10698da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1069916ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10700da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10701da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10702da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10703da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10704da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10705da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10707991d11dd9c33e65872778b81aff1347cd2878154glennrp
1070839992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10709991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
107103b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
107110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
107140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10715991d11dd9c33e65872778b81aff1347cd2878154glennrp
107160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
107170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
107180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
107190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
107200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10721991d11dd9c33e65872778b81aff1347cd2878154glennrp
107220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
107230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
107250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
107260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
107270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
107280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107293b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
107300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
107310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10732c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
107330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
107340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
107350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
107360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
107370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
107380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10739991d11dd9c33e65872778b81aff1347cd2878154glennrp
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10741cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10742da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10744991d11dd9c33e65872778b81aff1347cd2878154glennrp
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10746cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1074826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
107514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1075226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1075326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1075426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1075526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1075626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1075726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1075803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1075926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1076026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1076126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1076226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1076326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1076426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
107689c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
107709c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10779b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10780b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
107817202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10783b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10785b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10787b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10788b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10789b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10791b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10793b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10795b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10796b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107983b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
107993b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10801b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10802b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
108030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10804b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10805e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108070997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=AcquireVirtualMemory(rowbytes,sizeof(*ping_pixels));
108080997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
10809edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
108100997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
108110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10815ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10816ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10817edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
108204b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
108228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10824fd164d2bf84b111e304959af5698757d60e9b8aeglennrp       !mng_info->write_png48 && !mng_info->write_png64 &&
108258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
108268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
108288d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
108298d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1083216ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
108340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10841bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10843d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
108443b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108453b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10846a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1084716ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
108480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1084916ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
108510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1085416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1085516ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10861bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10862cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1086916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1087016ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10875cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
108770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108783b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10879b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10880b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
108810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10882cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
10883af9320404a7b05014476f844b11110157a21b73eglennrp
10884af9320404a7b05014476f844b11110157a21b73eglennrp          status=SetImageProgress(image,LoadImageTag,
10885af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
10886af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
10887af9320404a7b05014476f844b11110157a21b73eglennrp          if (status == MagickFalse)
10888af9320404a7b05014476f844b11110157a21b73eglennrp            break;
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10896fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png48 && !mng_info->write_png64 &&
10897fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png32) && (image_matte != MagickFalse ||
10898fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
10899fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (mng_info->IsPalette) && ping_have_color == MagickFalse)
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1090116ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
109028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
109030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10907bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1090916ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
109102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1091116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
109132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1091716ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1091816ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
109192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1092116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1092216ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
109232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
109258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10930b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
109313b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10932b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
109342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1093516ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1093616ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10937b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
109382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109393b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10940b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
109422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10943cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
109442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10945af9320404a7b05014476f844b11110157a21b73eglennrp            status=SetImageProgress(image,LoadImageTag,
10946af9320404a7b05014476f844b11110157a21b73eglennrp              (MagickOffsetType) (pass * image->rows + y),
10947af9320404a7b05014476f844b11110157a21b73eglennrp              num_passes * image->rows);
10948af9320404a7b05014476f844b11110157a21b73eglennrp            if (status == MagickFalse)
10949af9320404a7b05014476f844b11110157a21b73eglennrp              break;
109508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
109518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
109528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
109530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1095616ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
109578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
109580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10961fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            if ((image_depth > 8) ||
10962fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 ||
109638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
10964fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 ||
10965fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png64 ||
10966fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
109678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
109688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10969b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
10970862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
109712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1097216ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
109738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
109742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
109778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1097816ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1097916ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
109802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1098216ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1098316ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
109848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
109878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1098816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10989cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1099016ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
109912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
109938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
109958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1099816ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1099916ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
110002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1100216ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1100316ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
110042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110053b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
11006b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
110082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11009cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
11010af9320404a7b05014476f844b11110157a21b73eglennrp
11011af9320404a7b05014476f844b11110157a21b73eglennrp                status=SetImageProgress(image,LoadImageTag,
11012af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
11013af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
11014af9320404a7b05014476f844b11110157a21b73eglennrp                if (status == MagickFalse)
11015af9320404a7b05014476f844b11110157a21b73eglennrp                  break;
11016b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
110178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
11020fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            /* not ((image_depth > 8) ||
11021fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 || mng_info->write_png32 ||
11022fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 || mng_info->write_png64 ||
11023fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
11024fd164d2bf84b111e304959af5698757d60e9b8aeglennrp             */
110258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
110268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
110278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
110288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
110298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
110308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
110322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
110348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
110358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
110362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
110388640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
110398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
110408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
110422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1104316ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
110442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1104516ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
110468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1104944757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
110504bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
110514bf89731a90c6e03598950223e19e7be7b95d630glennrp
1105216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1105316ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1105444757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
110552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
110578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
110588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
110598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
110612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1106216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
11063cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1106416ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
110658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
110662cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
110688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1106916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1107016ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
110712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110725eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
110735eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
110745eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110751a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
110765eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
110775eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110785eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
110795eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
110805eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
110818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
11082cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
110832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11084af9320404a7b05014476f844b11110157a21b73eglennrp                status=SetImageProgress(image,LoadImageTag,
11085af9320404a7b05014476f844b11110157a21b73eglennrp                  (MagickOffsetType) (pass * image->rows + y),
11086af9320404a7b05014476f844b11110157a21b73eglennrp                  num_passes * image->rows);
110878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
110888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110898640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
11090af9320404a7b05014476f844b11110157a21b73eglennrp            }
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
110948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
11095b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
11096b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11101b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
111020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11104e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
111050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11107e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
111080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111125d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
111170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111215d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
111260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11131a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11133823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1113526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1113626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1113726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1113826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1113926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1114026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
111412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1114216ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
11143a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11144e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      /* Don't write any "png:" or "jpeg:" properties; those are just for
11145e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       * "identify" or for passing through to another JPEG
11146e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       */
11147e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      if ((LocaleNCompare(property,"png:",4) != 0 &&
11148a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp           LocaleNCompare(property,"jpeg:",5) != 0) &&
11149e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp
11150a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11151a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
11152a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
11153823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
11154a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
11155a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11156a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
11157a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
11158a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1115926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
11160c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
11161c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
11162a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
11163ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
11164a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
11165a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
11166a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
11167a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
11168a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
11169c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
11170c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
11171c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
111722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11173c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
11174c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
111752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11176c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
11177c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
111782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11179c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1118026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
11181c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
11182c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
11183c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
11184c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1118526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
111862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11187c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
11188c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
11189c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11190c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
11191c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11192c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11193cbc9215c23fce410bf0bea825dee908c15271bb3glennrp                  "    keyword: '%s'",text[0].key);
11194c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
11195c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11196c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
11197c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
11198c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1119926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1120026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1120126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
11205cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
112100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
112120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
112165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
112175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1122703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
112385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
112415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
112453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
112470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
112523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
11253edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
112540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112610997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1126316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1126416ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1126516ea139d53d867211d3bb0fa859a83de653f687ecristy
1126616ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1126716ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1126816ea139d53d867211d3bb0fa859a83de653f687ecristy
11269b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
11270b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
11271b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
11272b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1127316ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
11274b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
112780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11279868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
11280edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
11281edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
11282edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
11283edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
11284edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
11285edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
11286edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
11289edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1131016ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1131116ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1131916ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1132016ea139d53d867211d3bb0fa859a83de653f687ecristy%
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
113223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
113243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
113275d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
113283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113295a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
113305a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
113313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
113335a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
113345a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
11335e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
11336130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
11337130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
11338130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
11339e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
11340e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
11341e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
113425a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
113435a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
113443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
113455a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
113465a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
113475a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
113503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
113515a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
113525a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
113535a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
113545a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
113555a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
113583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
113593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
113600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
113615a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
113625a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11364fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG48:   A 16-bit per sample RGB PNG datastream is written.  The tRNS
11365fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               chunk can be present to convey binary transparency by naming
11366fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               one of the colors as transparent.  If the image has more
11367fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               than one transparent color, has semitransparent pixels, or
11368fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               has an opaque pixel with the same RGB components as the
11369fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparent color, an image is not written.
11370fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
11371fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG64:   A 16-bit per sample RGBA PNG is written.  Partial
11372fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparency is permitted, i.e., the alpha sample for
11373fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               each pixel can have any value from 0 to 65535. The alpha
11374fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               channel is present even if the image is fully opaque.
11375fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
113765830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%    o PNG00:   A PNG that inherits its colortype and bit-depth from the input
113775830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               image, if the input was a PNG, is written.  If these values
113785830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               cannot be found, then "PNG00" falls back to the regular "PNG"
113795830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               format.
113805830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
11384bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
11385bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
11386bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11404fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               If the image cannot be written without loss with the
11405fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               requested bit-depth and color-type, a PNG file will not
11406fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               be written, a warning will be issued, and the encoder will
11407fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               return MagickFalse.
114085a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
114103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
114113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
114125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1141316ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
114163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
114203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
114273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11428bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11429bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
114323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
114333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11434bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
114353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11436bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114383241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
114390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11440d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
114410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
114420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
114430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11444cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
114450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11446d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11447d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
114485d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11449d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11450d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11451d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11452d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
114530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
114543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
114563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1145716ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1146021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1146121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1146221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
114643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
114725c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
114735c7cf4e469a4dad7e277783749155932252c52dfglennrp
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11482fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1148773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
114880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
114910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11497a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
11505fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
11506fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11508092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:format");
115095a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value == (char *) NULL)
115105a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp    if (LocaleCompare(image_info->magick,"PNG00") == 0)
11511b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
115125a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value != (char *) NULL || LocaleCompare(image_info->magick,"PNG00") == 0)
11513b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11514f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11515f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp         "  Format=%s",value);
11516f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11517fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png8 = MagickFalse;
11518fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png24 = MagickFalse;
11519fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png32 = MagickFalse;
11520fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png48 = MagickFalse;
11521fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png64 = MagickFalse;
11522fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11523b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11524b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11525b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11526b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11527b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11528b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11529b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11530b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11531fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11532fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png48") == 0)
11533fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png48 = MagickTrue;
11534fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11535fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png64") == 0)
11536fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png64 = MagickTrue;
115375830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115385a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp      else if ((LocaleCompare(value,"png00") == 0) ||
115395a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp         LocaleCompare(image_info->magick,"PNG00") == 0)
115405830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        {
115413398b5b62521b49754d9391aae9e4511857bd63bglennrp          /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig. */
115423398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.bit-depth-orig",exception);
11543f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11544f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11545f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11546f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11547f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited bit depth=%s",value);
11548f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11549f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"1") == 0)
11550f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 1;
11551f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115525a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"2") == 0)
11553f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 2;
11554f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115555a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"4") == 0)
11556f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 4;
11557f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11558f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"8") == 0)
11559f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 8;
11560f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11561f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"16") == 0)
11562f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 16;
11563f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
11564f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115653398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.color-type-orig",exception);
11566f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11567f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11568f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11569f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11570f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited color type=%s",value);
11571f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11572f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"0") == 0)
11573f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 1;
11574f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11575f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"2") == 0)
11576f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 3;
11577f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11578f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"3") == 0)
11579f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 4;
11580f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11581f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"4") == 0)
11582f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 5;
11583f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11584f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"6") == 0)
11585f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 7;
11586f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
115875830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        }
115885830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
115895830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
115913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115929c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
115939c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115949c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
115983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115999c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
116009c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116019c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
116020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1160335553db9b7d0d812b53b09e3906628239d908e1ccristy      if (image->alpha_trait == BlendPixelTrait)
1160416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
116050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116069c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1160716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
116080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1160916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
116133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116149c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
116159c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116169c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
1161747da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
116180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11619197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      (void) SetImageType(image,TrueColorMatteType,exception);
1162016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11623fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48)
11624fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11625fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 2 */ 3;
11626fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11627fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
11628fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
1162935553db9b7d0d812b53b09e3906628239d908e1ccristy      if (image->alpha_trait == BlendPixelTrait)
116304dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
11631fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11632fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else
116334dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorType,exception);
11634fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
116354dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11636fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11637fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11638fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png64)
11639fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11640fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 6 */  7;
11641fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11642fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
1164347da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
11644fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11645197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      (void) SetImageType(image,TrueColorMatteType,exception);
116464dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11647fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11648fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11649092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:bit-depth");
116508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
116513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
116549c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
116550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116579c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
116580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116609c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
116610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
116639c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
116640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
116669c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
116670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11668bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1166916ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11670bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11671bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11672bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11673bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
116743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116759c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11676bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
116773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11679092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:color-type");
116800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
116843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
116859c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
116860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1168716ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1168816ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1168916ea139d53d867211d3bb0fa859a83de653f687ecristy
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116919c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
116920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
116949c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
116950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116979c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
116980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
117009c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
117010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11702bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1170316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11704bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11705bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11706bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11707bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
117083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
117099c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11710d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
117113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
117140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117150dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
117160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
117170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117185d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
117190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
117200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
117210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
117220e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
117230e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117240e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
117250e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117265d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
117275d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
117280e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
117290dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
117300dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
117310dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11732aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11733aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11734aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
117350e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
117370e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
117380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
117390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
117410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
117420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
117430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
117450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
117460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11748104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
117490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
117500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1175126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1175226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11753a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1175426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1175526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1175626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1175726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1175826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1175926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1176026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1176126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11762fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  mng_info->ping_exclude_tIME=MagickFalse;
11763a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1176426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1176526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1176626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1176726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
117688d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
117698d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11770092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:preserve-colormap");
117718d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
117728b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:preserve-colormap");
117738d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
117748d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
117758d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11776ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  mng_info->ping_preserve_iCCP=MagickFalse;
11777ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11778ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  value=GetImageOption(image_info,"png:preserve-iCCP");
11779ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value == NULL)
11780ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     value=GetImageArtifact(image,"png:preserve-iCCP");
11781ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value != NULL)
11782ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     mng_info->ping_preserve_iCCP=MagickTrue;
11783ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11784ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  /* These compression-level, compression-strategy, and compression-filter
117851868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
117861868258559ddf946fa73ef72dd43507b32623705glennrp   */
11787092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-level");
117881868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
117898b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-level");
117901868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
117911868258559ddf946fa73ef72dd43507b32623705glennrp  {
117921868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
117931868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
117941868258559ddf946fa73ef72dd43507b32623705glennrp       */
117951868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
117961868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
117971868258559ddf946fa73ef72dd43507b32623705glennrp
117980ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
117991868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
118001868258559ddf946fa73ef72dd43507b32623705glennrp
118011868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118021868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
118031868258559ddf946fa73ef72dd43507b32623705glennrp
118041868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118051868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
118061868258559ddf946fa73ef72dd43507b32623705glennrp
118071868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118081868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
118091868258559ddf946fa73ef72dd43507b32623705glennrp
118101868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118111868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
118121868258559ddf946fa73ef72dd43507b32623705glennrp
118131868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
118141868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
118151868258559ddf946fa73ef72dd43507b32623705glennrp
118161868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
118171868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
118181868258559ddf946fa73ef72dd43507b32623705glennrp
118191868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
118201868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
118211868258559ddf946fa73ef72dd43507b32623705glennrp
118221868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
118231868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
118241868258559ddf946fa73ef72dd43507b32623705glennrp
118251868258559ddf946fa73ef72dd43507b32623705glennrp      else
1182616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118271868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118281868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
118291868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118301868258559ddf946fa73ef72dd43507b32623705glennrp    }
118311868258559ddf946fa73ef72dd43507b32623705glennrp
11832092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-strategy");
118331868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118348b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-strategy");
118351868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118361868258559ddf946fa73ef72dd43507b32623705glennrp  {
118371868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118381868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
118391868258559ddf946fa73ef72dd43507b32623705glennrp
118401868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
118411868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
118421868258559ddf946fa73ef72dd43507b32623705glennrp
118431868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118441868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
118451868258559ddf946fa73ef72dd43507b32623705glennrp
118461868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1184798c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
118481868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1184998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1185098c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1185198c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118521868258559ddf946fa73ef72dd43507b32623705glennrp
118531868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1185498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
118551868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1185698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1185798c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1185898c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118591868258559ddf946fa73ef72dd43507b32623705glennrp
118601868258559ddf946fa73ef72dd43507b32623705glennrp      else
1186116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118621868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118631868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
118641868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118651868258559ddf946fa73ef72dd43507b32623705glennrp    }
118661868258559ddf946fa73ef72dd43507b32623705glennrp
11867092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-filter");
118681868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118698b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-filter");
118701868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118711868258559ddf946fa73ef72dd43507b32623705glennrp  {
118721868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
118731868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
118741868258559ddf946fa73ef72dd43507b32623705glennrp       *
118751868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
118761868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
118771868258559ddf946fa73ef72dd43507b32623705glennrp       */
118781868258559ddf946fa73ef72dd43507b32623705glennrp
118791868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118801868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
118811868258559ddf946fa73ef72dd43507b32623705glennrp
11882b19b8125320afb5954bd73b82d00700e8ed9e984cristy      else if (LocaleCompare(value,"1") == 0)
118831868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
118841868258559ddf946fa73ef72dd43507b32623705glennrp
118851868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118861868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
118871868258559ddf946fa73ef72dd43507b32623705glennrp
118881868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118891868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
118901868258559ddf946fa73ef72dd43507b32623705glennrp
118911868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118921868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
118931868258559ddf946fa73ef72dd43507b32623705glennrp
118941868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118951868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
118961868258559ddf946fa73ef72dd43507b32623705glennrp
118971868258559ddf946fa73ef72dd43507b32623705glennrp      else
1189816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118991868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
119001868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
119011868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
119021a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  }
1190303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119041a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  for (source=0; source<8; source++)
119055c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
119061a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    value = NULL;
11907acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
119082dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 0)
119092dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunks");
119102dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119112dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 1)
119122dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunks");
119132dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119142dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 2)
119152dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunk");
119162dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119172dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 3)
119182dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunk");
119192dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119202dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 4)
119212dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunks");
119222dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119232dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 5)
119242dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunks");
119252dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119262dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 6)
119272dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunk");
119282dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119292dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 7)
119302dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunk");
1193126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
119321a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (value == NULL)
119331a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp       continue;
119341a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp
119351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (source < 4)
119361a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickTrue;
119371a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    else
119381a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickFalse;
1193926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1194003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
119412cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
119421a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        if (source == 0 || source == 2)
119431a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119441a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:exclude-chunk=%s found in image options.\n", value);
119451a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 1 || source == 3)
119462cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119472cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
119481a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 4 || source == 6)
119492cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119501a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image options.\n", value);
119511a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else /* if (source == 5 || source == 7) */
119521a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119531a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
119542cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1195503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119561a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (IsOptionMember("all",value) != MagickFalse)
119571a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
119581a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_bKGD=excluding;
119591a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_cHRM=excluding;
119601a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_date=excluding;
119611a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_EXIF=excluding;
119621a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_gAMA=excluding;
119631a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_iCCP=excluding;
119641a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=excluding; */
119651a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_oFFs=excluding;
119661a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_pHYs=excluding;
119671a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_sRGB=excluding;
119681a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tEXt=excluding;
11969fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding;
119701a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tRNS=excluding;
119711a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_vpAg=excluding;
119721a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zCCP=excluding;
119731a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zTXt=excluding;
119741a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
11975280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp
11976689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("none",value) != MagickFalse)
119771a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
11978a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_bKGD=excluding != MagickFalse ? MagickFalse :
11979a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11980a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_cHRM=excluding != MagickFalse ? MagickFalse :
11981a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11982a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_date=excluding != MagickFalse ? MagickFalse :
11983a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11984a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_EXIF=excluding != MagickFalse ? MagickFalse :
11985a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11986a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_gAMA=excluding != MagickFalse ? MagickFalse :
11987a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11988a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_iCCP=excluding != MagickFalse ? MagickFalse :
11989a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
119901a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=!excluding; */
11991a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_oFFs=excluding != MagickFalse ? MagickFalse :
11992a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11993a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_pHYs=excluding != MagickFalse ? MagickFalse :
11994a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11995a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_sRGB=excluding != MagickFalse ? MagickFalse :
11996a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11997a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tEXt=excluding != MagickFalse ? MagickFalse :
11998a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11999fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding != MagickFalse ? MagickFalse :
12000fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          MagickTrue;
12001a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tRNS=excluding != MagickFalse ? MagickFalse :
12002a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12003a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_vpAg=excluding != MagickFalse ? MagickFalse :
12004a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12005a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zCCP=excluding != MagickFalse ? MagickFalse :
12006a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12007a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zTXt=excluding != MagickFalse ? MagickFalse :
12008a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
120091a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
1201003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
12011689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("bkgd",value) != MagickFalse)
120121a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_bKGD=excluding;
120132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12014689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("chrm",value) != MagickFalse)
120151a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_cHRM=excluding;
12016a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
12017689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("date",value) != MagickFalse)
120181a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_date=excluding;
120192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12020689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("exif",value) != MagickFalse)
120211a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_EXIF=excluding;
120222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12023689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("gama",value) != MagickFalse)
120241a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_gAMA=excluding;
120252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12026689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("iccp",value) != MagickFalse)
120271a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iCCP=excluding;
120282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12029689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
12030689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("itxt",value) != MagickFalse)
120311a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iTXt=excluding;
12032689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
120332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12034689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("offs",value) != MagickFalse)
120351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_oFFs=excluding;
120362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12037689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("phys",value) != MagickFalse)
120381a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_pHYs=excluding;
120392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12040689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("srgb",value) != MagickFalse)
120411a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_sRGB=excluding;
120422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12043689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("text",value) != MagickFalse)
120441a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tEXt=excluding;
120452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12046fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (IsOptionMember("time",value) != MagickFalse)
12047fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      mng_info->ping_exclude_tIME=excluding;
12048fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
12049689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("trns",value) != MagickFalse)
120501a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tRNS=excluding;
12051a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
12052689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("vpag",value) != MagickFalse)
120531a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_vpAg=excluding;
120542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12055689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("zccp",value) != MagickFalse)
120561a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zCCP=excluding;
120572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12058689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("ztxt",value) != MagickFalse)
120591a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zTXt=excluding;
1206026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1206126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
120621a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  if (logging != MagickFalse)
1206326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1206426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120655d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1206626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1206726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1206826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1206926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1207026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
12072a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
12073a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12074a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1207526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1207626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1207826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1207926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1208126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1208226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
12084689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
1208526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1208626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
12088689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
12089689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp
1209026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1209126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1209326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1209426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1209626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1209726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1209926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1210026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1210126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
12102fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (mng_info->ping_exclude_tIME != MagickFalse)
12103fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12104fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          "    tIME");
12105a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
12106a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12107a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1210826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1210926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1211126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1211226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1211426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1211526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1211726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1211826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
12119b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
121203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1212116ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
121223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
121240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
121270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
121323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1213516ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
121363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
121373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
121393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
121413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
121423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1214403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
121453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
121483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
121513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
121543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
121583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
121593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12161bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1216259575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
121633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
12166fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
121673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
121703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
121713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
1217435553db9b7d0d812b53b09e3906628239d908e1ccristy     image_info->type==TrueColorMatteType || image->alpha_trait == BlendPixelTrait;
121753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121764b917593e694424be469d250448c05c878663812glennrp  jng_alpha_sample_depth = 0;
121774b917593e694424be469d250448c05c878663812glennrp
1217859575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1217959575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1218059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1218159575fa5c228308a41d7f5028390be2083aaaf6dglennrp
12182750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1218359575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1218459575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1218559575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1218659575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12188d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  length=0;
12189d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
121908fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
121930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
121963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1219716ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
121980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
122000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
122023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
122070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1220816ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
122103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122128a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
122138f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1221416ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1221516ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
122163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
122173b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
122183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
122193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1222059575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1222159575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1222259575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1222359575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1222459575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1222559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
122263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
122283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
122317fb2652ba366fc984d1dbb0c66560b91c57dab78cristy    TrueColorType && IsImageGray(image,exception))
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
122333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1223459575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1223559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1223659575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1223759575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1223859575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1223959575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
122408fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (transparent != 0)
1224159575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1224259575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224359575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1224459575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224559575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1224659575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224759575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1224859575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1224959575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1225059575fa5c228308a41d7f5028390be2083aaaf6dglennrp
122518fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
122523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
122543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
122563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
122573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1225816ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
122593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1226016ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
122643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
122673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12269cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
12270cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
12271cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1227316ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1227616ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
122783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
122813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1228216ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1228516ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
122883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1229416ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
122960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12299e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
12300e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
123013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
123033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
123043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
123063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
123103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1231203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
123134e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
123144e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
123173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
123183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
123203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12328f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
123290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12331f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
123320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
123350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
123380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
123410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
123440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
123470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
123500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
123530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
12359cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
123603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123658fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
123673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
123803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12383bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1238503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
123873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
123883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
123893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
123933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
123973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1240603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
124070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12409e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12410cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12411e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
124120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12414e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12415cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12416e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
124170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
124203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1243003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1243135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
124323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
124383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1244703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1244935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1245035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
124513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1245235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1245335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
124543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1245535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1245635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
124573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1245835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1245935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
124603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
124613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1246516ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1247203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
124743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1247535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1247616ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
124770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1247835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1247916ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
124800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
124823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
124853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1248835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1248916ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
124900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1249135ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1249216ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
124930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
124953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
124960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
124983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1249916ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1250016ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
125013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
125093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
125123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1251503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12516bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12517bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1252603812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
125283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
125293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
125313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125358fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
125363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
125383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12539bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12542fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy          size_t
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
125463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12548e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12549f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
125523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
125533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12554bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
125565389e5ad63c880fe6885e3b24c76acbdbf63bd61cristy            len=(size_t) (*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
125580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
125603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12562fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image,len);
12563fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                LogPNGChunk(logging,mng_IDAT,len);
12564fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlob(image,len+4,p);
12565fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image, crc32(0,p,(uInt) len+4));
125663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
125693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12572e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12573e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
125793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12583e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1258603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
125883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
125903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
125993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
126073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1260816ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
126093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
126103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
126123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
126143b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
126153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1261816ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12622e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12623e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
126263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
126270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1262859575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1262959575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
126303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
126313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
126320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
126360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1263716ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
126380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12642e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12643e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12646e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12650bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
126513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1265203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
126553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
126583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
126593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12663cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
126643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1266803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
126713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
126750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1269716ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1269816ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1270616ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1270716ea139d53d867211d3bb0fa859a83de653f687ecristy%
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1271016ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1271116ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1271421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1271503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12729fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1273016ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
127323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
127333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
127363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1273873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1275016ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
127523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
127543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
127573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1276116ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1276216ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1277121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1277403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1277503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1277603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
127773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
127893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
127933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12794bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
127983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
128033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12804bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
128063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12807bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
128083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12811d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12825fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1282616ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
128293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1283473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
128413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
128523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
128573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
128683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128742dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "  Checking input image(s)\n"
128752dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    Image_info depth: %.20g,    Type: %d",
128762dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) image_info->depth, image_info->type);
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
128793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
128810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12883280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           "    Scene: %.20g\n,   Image depth: %.20g",
12884280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           (double) scene++, (double) p->depth);
128850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1288635553db9b7d0d812b53b09e3906628239d908e1ccristy        if (p->alpha_trait == BlendPixelTrait)
128873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
128890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
128930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
128970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
129010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
129033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12904e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
129050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
129090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
129123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
129243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
129433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
129603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
129633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
129643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
129653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
129673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
129713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
129720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
129790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1298035553db9b7d0d812b53b09e3906628239d908e1ccristy        if (next_image->alpha_trait == BlendPixelTrait)
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
129820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
1298435553db9b7d0d812b53b09e3906628239d908e1ccristy          if ((next_image->alpha_trait == BlendPixelTrait) ||
12985dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy               next_image->page.x || next_image->page.y ||
129863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
129873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
129883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
129890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
129913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
129920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
129940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
129980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
1300435553db9b7d0d812b53b09e3906628239d908e1ccristy        if (image->alpha_trait == BlendPixelTrait)
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
130060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
130083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130097fb2652ba366fc984d1dbb0c66560b91c57dab78cristy            if (IsImageGray(image,exception) == MagickFalse)
130103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
130113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
130133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
130153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
130203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
130253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
130260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
130290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
130313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
130330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1303516ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1303616ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
130373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
130380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
130403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
130423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
130453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
130533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
130633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
130653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
130733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
130753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
130760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
130783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
130793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
130803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
130813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
130833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
130853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
130863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
130873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
130893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
130900261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
13091d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
13092d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1309316ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1309416ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
13095d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
13096d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
13097d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
130983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
130993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
131013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
13103cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
13104cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
131070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
131100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
131130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
13116d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp            (final_delay != 25) && (final_delay != 50) && (1UL*final_delay !=
131173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
131183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
131193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
131233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
131273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1313403812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
131354e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
131364e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
131383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
131393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
131403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
131423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
131470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
131560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
131633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
131680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
131713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
131770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
131833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
13184092ec8d083fedaedfb7792995e7ea42164553cffcristy     option=GetImageOption(image_info,"mng:need-cacheoff");
131853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
131883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
131893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
131913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
131923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
131943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
13195bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1319603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
131973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
131983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
131993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
132003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
132023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
132033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
132043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
132073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
132093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1321003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
132113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
132123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
132133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
132143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
132150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
132173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
132180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
132210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
132233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13225e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
13226e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
132270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
132293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13230e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
132310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13234e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
132353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
132373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
132383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
132403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
132413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
132423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
132433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
132493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1325003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
132510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
13253e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13254cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13255e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
132560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
13258e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13259cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13260cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
132610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
132633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
132643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
132653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
132683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
132703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
132733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
132753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1327603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1327735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
132783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
132793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
132803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
132813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
132833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
132853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
132863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
132893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
132913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1329203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
132933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1329435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1329535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
132963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1329735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1329835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
132993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1330035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1330135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
133023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1330335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1330435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
133053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
133063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
133073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
133083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1331016ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
133113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
133143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
133163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1331703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
133180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
133203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1332135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1332216ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
133230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1332435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1332516ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
133260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
133283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
133313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
133333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1333435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1333516ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
133360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1333735ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1333816ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
133390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
133413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
133443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1334516ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1334616ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
133473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
133483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
133513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
133523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
133543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
133553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
133563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
1335735553db9b7d0d812b53b09e3906628239d908e1ccristy     if (write_mng && ((image->alpha_trait == BlendPixelTrait) ||
13358dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy         image->page.x > 0 || image->page.y > 0 || (image->page.width &&
133593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
133603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
133613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
133623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
133643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1336503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
133663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
133673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
133683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
133693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
133703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
133713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
133723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
133733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
133753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
133773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1337803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
133793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
133803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
133853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
133863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
133873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
133883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13389bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
133903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
133913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
133943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
133963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
133973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1339803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
133990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13400bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
134013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1340216ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1340316ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1340416ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1340516ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1340616ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1340716ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
134083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
134090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
134113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
134123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
134133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
134163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
134173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
134183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
134213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
134233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
134243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
134253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
134263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
134293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
134303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
134313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
134323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
134333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
134343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
134353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
134373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
134383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
134393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
134403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
134413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
134423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
134433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
134443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
134453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
134463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13447bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
134483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
134493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
134513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
134523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1345303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
134540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13455bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
134563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
134573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
134583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
134593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
134603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
134610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
134633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
134643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
134653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
134663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
134673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
134703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
134713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
134733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13474bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
134753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
134763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
134773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
134793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
134813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
134823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
134863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
134873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
134893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
134903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
134913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
134933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1349403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
134953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
134963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
134973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
134983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
134993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
135003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
135013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
135023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
135033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
135053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
135063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
135083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
135103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
135113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
135133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
135143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
135153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
135173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
135203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
135223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1352303812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
135243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
135263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
135273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
135293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
135323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
135343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1353503812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
135363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
135383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
135393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
135403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
135413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
135423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
135433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
135443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
135453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
135463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
135474e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
135483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
135503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
135533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
135543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
135563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
135573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
135613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
135623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
135633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1356416ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
135653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
135663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
135683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
135693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
135732f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13574b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
135758d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
135762f2e514554975d510c88df54de98c6cdc1080f1cglennrp
135772f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
135782f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
135792f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13580a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
135812f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
135822f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
135832f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
135842f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
135852f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
135862f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
135872f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
135882f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13589a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
135902f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
135912f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
135922f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
135932f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1359416ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
135953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
135983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
135993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
136003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
136013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
136023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
136033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
136043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
136053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
136073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
136083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
136090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
136140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
136163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
136173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
136183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
136193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
136203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
136213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
136223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
136233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1362403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
136253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
136263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
136273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
136283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
136293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
136303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
136313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
136323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
136330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
136353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
136360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
136383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13639d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1364039992b4dd9b12ef752d55b8e402c069698851f72glennrp
136413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
136423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136433bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
136443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
136453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
136460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
136483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
136493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1365039992b4dd9b12ef752d55b8e402c069698851f72glennrp
136513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
136523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
136543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13655d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
136563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13657