png.c revision 8fe9159929faad07fb14f2bb0fac9c14d0fd4e20
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%                                                                             %
21fe676ee3a9cf43404bdc9ba8b27f597b5e4e28f7cristy%  Copyright 1999-2014 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(),
166416ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,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(),
169716ea139d53d867211d3bb0fa859a83de653f687ecristy    "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,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;
215216ea139d53d867211d3bb0fa859a83de653f687ecristy 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
215616ea139d53d867211d3bb0fa859a83de653f687ecristy  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)
21997b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
220016ea139d53d867211d3bb0fa859a83de653f687ecristy          InheritException(exception,exception);
22017b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
22027b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
22030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2206edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2207edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
2208edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
2209edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
2210edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
2211edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2212868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
2213edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
2214edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
2215edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
2216943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
2217a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
2218a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
2219a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
2220a3a5f956194e91458e2789966ad15308e8f3df47glennrp
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2224faa852bad40107edae19405e76a299057668d795glennrp
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
22270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2250e604a757f40a91c286711c49577eeced17ea97adglennrp  {
2251e604a757f40a91c286711c49577eeced17ea97adglennrp    const char
2252e604a757f40a91c286711c49577eeced17ea97adglennrp      *value;
2253e604a757f40a91c286711c49577eeced17ea97adglennrp
2254e604a757f40a91c286711c49577eeced17ea97adglennrp    value=GetImageOption(image_info,"profile:skip");
2255e604a757f40a91c286711c49577eeced17ea97adglennrp
2256e604a757f40a91c286711c49577eeced17ea97adglennrp    if (IsOptionMember("ICC",value) == MagickFalse)
2257e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2258e604a757f40a91c286711c49577eeced17ea97adglennrp
2259e604a757f40a91c286711c49577eeced17ea97adglennrp       value=GetImageOption(image_info,"png:preserve-iCCP");
2260e604a757f40a91c286711c49577eeced17ea97adglennrp
2261e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value == NULL)
2262e604a757f40a91c286711c49577eeced17ea97adglennrp          value=GetImageArtifact(image,"png:preserve-iCCP");
2263e604a757f40a91c286711c49577eeced17ea97adglennrp
2264e604a757f40a91c286711c49577eeced17ea97adglennrp       if (value != NULL)
2265e604a757f40a91c286711c49577eeced17ea97adglennrp          ping_preserve_iCCP=MagickTrue;
2266201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp
2267201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED)
2268201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp       /* Don't let libpng check for ICC/sRGB profile because we're going
2269201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        * to do that anyway.  This feature was added at libpng-1.6.12.
2270cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp        * If logging, go ahead and check and issue a warning as appropriate.
2271201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp        */
2272cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp       if (logging == MagickFalse)
2273cf45b20b2d8abda43638bdcece704c78090ecbb2glennrp          png_set_option(ping, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
2274201f0c995969c480e7cf0285e5826c4c6903b7a1glennrp#endif
2275e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2276e604a757f40a91c286711c49577eeced17ea97adglennrp#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
2277e604a757f40a91c286711c49577eeced17ea97adglennrp    else
2278e604a757f40a91c286711c49577eeced17ea97adglennrp    {
2279e604a757f40a91c286711c49577eeced17ea97adglennrp       png_set_keep_unknown_chunks(ping, 1, mng_iCCP, 1);
2280e604a757f40a91c286711c49577eeced17ea97adglennrp    }
2281e604a757f40a91c286711c49577eeced17ea97adglennrp#endif
2282e604a757f40a91c286711c49577eeced17ea97adglennrp  }
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
22852ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#if PNG_LIBPNG_VER < 10700 /* Avoid libpng16 warning */
22862ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp  png_set_keep_unknown_chunks(ping, 2, NULL, 0);
22872ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#else
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
22892ad70151f4224c47dd9e23caf7d6620c4434fc57glennrp#endif
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22972feb141b6f74ce425fed3272286fab1f50366bb9glennrp#ifdef PNG_SET_USER_LIMITS_SUPPORTED
229809cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  if (PNG_LIBPNG_VER >= 10400)
22992feb141b6f74ce425fed3272286fab1f50366bb9glennrp    /* Limit the size of the chunk storage cache used for sPLT, text,
2300687361928f16a28ea56e200d00e970e68173cc25glennrp     * and unknown chunks.
23012feb141b6f74ce425fed3272286fab1f50366bb9glennrp     */
2302687361928f16a28ea56e200d00e970e68173cc25glennrp    png_set_chunk_cache_max(ping, 32767);
230309cd96287f72032f4d49a779d65e1546e85f6b9fglennrp#  endif
23042feb141b6f74ce425fed3272286fab1f50366bb9glennrp#endif
23052feb141b6f74ce425fed3272286fab1f50366bb9glennrp
23069bf97b6c2143eb20c330346b01e82102cc082725glennrp#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
23079bf97b6c2143eb20c330346b01e82102cc082725glennrp    /* Disable new libpng-1.5.10 feature */
23089bf97b6c2143eb20c330346b01e82102cc082725glennrp    png_set_check_for_invalid_index (ping, 0);
23099bf97b6c2143eb20c330346b01e82102cc082725glennrp#endif
23109bf97b6c2143eb20c330346b01e82102cc082725glennrp
2311991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2312991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2313991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2327991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2331faa852bad40107edae19405e76a299057668d795glennrp
2332faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2333faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2334faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2335faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2336faa852bad40107edae19405e76a299057668d795glennrp
2337fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp  ping_file_depth = ping_bit_depth;
2338fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp
23390d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  /* Swap bytes if requested */
23400d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  if (ping_file_depth == 16)
23410d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  {
23420d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp     const char
2343a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp       *value;
2344a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2345a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     value=GetImageOption(image_info,"png:swap-bytes");
2346a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2347a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value == NULL)
2348a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        value=GetImageArtifact(image,"png:swap-bytes");
2349a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp
2350a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp     if (value != NULL)
2351a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp        png_set_swap(ping);
23520d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp  }
23530d767725a26a52a3c8362cbb1b88cbe0fd52522dglennrp
23545830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  /* Save bit-depth and color-type in case we later want to write a PNG00 */
23555830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  {
23565830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      char
23575830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        msg[MaxTextExtent];
23585830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
23595830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_color_type);
23603398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.color-type-orig",msg,exception);
23615830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
23625830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
23633398b5b62521b49754d9391aae9e4511857bd63bglennrp      (void) SetImageProperty(image,"png:IHDR.bit-depth-orig",msg,exception);
23645830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  }
23655830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
2366faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2367faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2368faa852bad40107edae19405e76a299057668d795glennrp
2369faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2370faa852bad40107edae19405e76a299057668d795glennrp
2371faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2373fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       png_set_packing(ping);
2374fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp       ping_bit_depth = 8;
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2376faa852bad40107edae19405e76a299057668d795glennrp
2377faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2379faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
238098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2381176b29a003f11fd934137871d574995319408665cristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2382176b29a003f11fd934137871d574995319408665cristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2383176b29a003f11fd934137871d574995319408665cristy    {
2384176b29a003f11fd934137871d574995319408665cristy      image->rendering_intent=UndefinedIntent;
238598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      intent=Magick_RenderingIntent_to_PNG_RenderingIntent(UndefinedIntent);
2386176b29a003f11fd934137871d574995319408665cristy      image->gamma=1.000;
2387176b29a003f11fd934137871d574995319408665cristy      (void) ResetMagickMemory(&image->chromaticity,0,
2388176b29a003f11fd934137871d574995319408665cristy        sizeof(image->chromaticity));
2389176b29a003f11fd934137871d574995319408665cristy    }
239098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23942dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG width: %.20g, height: %.20g\n"
23952dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG color_type: %d, bit_depth: %d\n"
23962dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    PNG compression_method: %d\n"
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
23982dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) ping_width, (double) ping_height,
23992dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_color_type, ping_bit_depth,
24002dd1906783a5ece58a6105b4f59239e28b13caddglennrp        ping_compression_method,
2401faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
24022dd1906783a5ece58a6105b4f59239e28b13caddglennrp
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2405ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (png_get_valid(ping,ping_info, PNG_INFO_iCCP))
2406ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2407ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
2408ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (logging != MagickFalse)
2409ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2410ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
2411ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2412ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
241398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
241498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
241598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_gAMA=MagickTrue;
241698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
241798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
241898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG gAMA chunk.");
241998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
242098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
242198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
242298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
242398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      ping_found_cHRM=MagickTrue;
242498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
242598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
242698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp          "    Found PNG cHRM chunk.");
242798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
242898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2429ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (ping_found_iCCP != MagickTrue && png_get_valid(ping,ping_info,
2430ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      PNG_INFO_sRGB))
243198b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2432ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB=MagickTrue;
243398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
243498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2435ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG sRGB chunk.");
243698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
243798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2438ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2439e604a757f40a91c286711c49577eeced17ea97adglennrp    if (ping_found_iCCP !=MagickTrue &&
2440ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_sRGB != MagickTrue &&
2441ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info, PNG_INFO_iCCP))
244298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    {
2443ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_found_iCCP=MagickTrue;
244498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp      if (logging != MagickFalse)
244598b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2446ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          "    Found PNG iCCP chunk.");
244798b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp    }
244898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2449faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2454e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2455e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2456e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2457e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2458e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2459e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2460e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2461e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
24700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
2479ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2480e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          profile=BlobToStringInfo(info,profile_length);
2481ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2482e8f8f3877ede9cbc125b64c8f760c7c4a63bc00fcristy          if (profile == (StringInfo *) NULL)
2483ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2484ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            png_warning(ping, "ICC profile is NULL");
2485ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2486ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
2487ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          else
2488ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          {
2489ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            if (ping_preserve_iCCP == MagickFalse)
2490edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2491ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 int
2492ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
2493ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
2494ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2495ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2496ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 png_uint_32
2497ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   length,
2498ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
2499ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2500ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 unsigned char
2501ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   *data;
2502ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2503ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
2504ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2505ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
2506ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2507ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
2508ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   {
2509ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
2510ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2511ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2512ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
2513ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                         (unsigned long) length);
2514ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2515ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
2516ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
2517ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2518ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2519ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
2520ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
2521ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2522ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2523ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
2524ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
2525ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2526ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
2527ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
2528ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
2529ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        if (image->rendering_intent==UndefinedIntent)
2530ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
2531ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
2532ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
2533ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
2534ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
2535ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        break;
2536ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
2537ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   }
2538ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2539ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
2540ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 {
2541ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2542ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
2543ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        (unsigned long) length);
2544ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2545ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 }
2546edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2547ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            else /* Preserve-iCCP */
2548edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            {
2549ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                    (void) SetImageProfile(image,"icc",profile,exception);
2550edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            }
2551ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2552ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            profile=DestroyStringInfo(profile);
2553ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          }
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2557ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2560ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    if (ping_found_iCCP==MagickFalse && png_get_valid(ping,ping_info,
2561ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        PNG_INFO_sRGB))
2562ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    {
2563ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      if (png_get_sRGB(ping,ping_info,&intent))
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2565ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2566ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2567ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             Magick_RenderingIntent_from_PNG_RenderingIntent (intent);
25680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2571e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2573ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    }
2574ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2575ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    else if (mng_info->have_global_srgb)
2576ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      {
2577ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp        if (image->rendering_intent == UndefinedIntent)
2578ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp          image->rendering_intent=
2579ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            Magick_RenderingIntent_from_PNG_RenderingIntent
2580ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp            (mng_info->global_srgb_intent);
2581ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      }
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2584ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
2585ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2587faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2588faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2589faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
25900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
259998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp
2600faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2601faa852bad40107edae19405e76a299057668d795glennrp    {
2602faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2603faa852bad40107edae19405e76a299057668d795glennrp        {
2604faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2605faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2606faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2607faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2608faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2609faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2610faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2611faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2612faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2613faa852bad40107edae19405e76a299057668d795glennrp        }
2614faa852bad40107edae19405e76a299057668d795glennrp    }
26150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2616faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
26270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2628ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp       ping_found_cHRM=MagickTrue;
2629ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
26303d627862fb79aad8a20be4f1587f0b8761db441aglennrp       if (image->chromaticity.red_primary.x>0.6399f &&
26313d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
26323d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
26333d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
26343d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
26353d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
26363d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
26373d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
26383d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
26393d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
26403d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
26413d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
26423d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
26433d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
26443d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
26453d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f)
26463d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_sRGB_cHRM=MagickTrue;
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2649e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26513d627862fb79aad8a20be4f1587f0b8761db441aglennrp      if (ping_found_sRGB != MagickTrue &&
26523d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_gAMA != MagickTrue ||
265384288238d90b2e1831857d6b2427abd7875b7e1bglennrp          (image->gamma > .45 && image->gamma < .46)) &&
26543d627862fb79aad8a20be4f1587f0b8761db441aglennrp          (ping_found_cHRM != MagickTrue ||
2655cd8b331760407523f2a59cc65c1cd9c3d4422bafcristy          ping_found_sRGB_cHRM != MagickFalse) &&
26563d627862fb79aad8a20be4f1587f0b8761db441aglennrp          ping_found_iCCP != MagickTrue)
26575cf1bff142633838354b1080183c957900bc80e8glennrp      {
26585cf1bff142633838354b1080183c957900bc80e8glennrp         png_set_sRGB(ping,ping_info,
26595cf1bff142633838354b1080183c957900bc80e8glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent
26605cf1bff142633838354b1080183c957900bc80e8glennrp            (image->rendering_intent));
26615cf1bff142633838354b1080183c957900bc80e8glennrp         file_gamma=1.000f/2.200f;
26625cf1bff142633838354b1080183c957900bc80e8glennrp         ping_found_sRGB=MagickTrue;
266384288238d90b2e1831857d6b2427abd7875b7e1bglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2664918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp           "    Setting sRGB as if in input");
26655cf1bff142633838354b1080183c957900bc80e8glennrp      }
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26675cf1bff142633838354b1080183c957900bc80e8glennrp
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2669faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2671905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2672905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
26730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2677e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2678e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2682faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2683faa852bad40107edae19405e76a299057668d795glennrp    {
2684faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2685faa852bad40107edae19405e76a299057668d795glennrp        {
2686faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2687faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2688faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2689faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2690faa852bad40107edae19405e76a299057668d795glennrp        }
2691faa852bad40107edae19405e76a299057668d795glennrp    }
2692faa852bad40107edae19405e76a299057668d795glennrp
26935c97f62ba919c3c109f0072df3b560056565e9e7cristy  x_resolution=0;
26945c97f62ba919c3c109f0072df3b560056565e9e7cristy  y_resolution=0;
26955c97f62ba919c3c109f0072df3b560056565e9e7cristy  unit_type=0;
2696faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
27020881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
270316ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.x=(double) x_resolution;
270416ea139d53d867211d3bb0fa859a83de653f687ecristy      image->resolution.y=(double) y_resolution;
27050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
270916ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.x=(double) x_resolution/100.0;
271016ea139d53d867211d3bb0fa859a83de653f687ecristy          image->resolution.y=(double) y_resolution/100.0;
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2715e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2716e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2719823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2720faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
27260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2728faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
27340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2735faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2736edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp              {
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
2739edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                    png_warning(ping,
2740edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                      "global tRNS has more entries than global PLTE");
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2742edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                else
2743edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  {
2744edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                     png_set_tRNS(ping,ping_info,mng_info->global_trns,
2745edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                       (int) mng_info->global_trns_length,NULL);
2746edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  }
2747edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp               }
2748bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2753faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2762faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2763faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
27640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
27670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
27700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
27730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2774c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2775c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2776c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2782edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"No global PLTE in file");
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2786bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2787faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2788faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
27900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2791faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2793bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2794bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2795bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
27962dd1906783a5ece58a6105b4f59239e28b13caddglennrp      /* Set image background color.
27972dd1906783a5ece58a6105b4f59239e28b13caddglennrp       * Scale background components to 16-bit, then scale
2798bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2799bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
28002cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2801bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
28020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2803fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth == 1)
2804bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
28050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2806fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 2)
2807bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
28080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2809fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        else if (ping_file_depth == 4)
2810bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
28110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2812fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp        if (ping_file_depth <= 8)
2813bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
28142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2815bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2816bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2817bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
28182cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2819bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2820bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
28212dd1906783a5ece58a6105b4f59239e28b13caddglennrp            if (logging != MagickFalse)
28222dd1906783a5ece58a6105b4f59239e28b13caddglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28232dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    Reading PNG bKGD chunk, raw ping_background=(%d,%d,%d).\n"
28242dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 "    bkgd_scale=%d.  ping_background=(%d,%d,%d).",
28252dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->red,ping_background->green,
28262dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->blue,
28272dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 bkgd_scale,ping_background->red,
28282dd1906783a5ece58a6105b4f59239e28b13caddglennrp                 ping_background->green,ping_background->blue);
2829bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
28302cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2831bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2832faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
28330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2834bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2835faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
28360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2837bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2838bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
28390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
284016ea139d53d867211d3bb0fa859a83de653f687ecristy        image->background_color.alpha=OpaqueAlpha;
28412cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2842bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2843bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2844bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2845bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2846bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2847bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2849bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2850a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2851faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2854a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
285935ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
286035ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
286135ef824baa82511126ff0072ae30eee0da9c05a3cristy
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
28653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2866fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      max_sample = (int) ((one << ping_file_depth) - 1);
28673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2868faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2869faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2870faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2871faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2872faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2873faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2879faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
28808a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          image->alpha_trait=UndefinedPixelTrait;
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2884a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2885a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2886a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2887fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale_to_short = 65535L/((1UL << ping_file_depth)-1);
2888a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2889a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2890a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2891a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2892a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
289316ea139d53d867211d3bb0fa859a83de653f687ecristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
289405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2895faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28970f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
28980f111984738842d27d04aed2a3f823d82a943506glennrp              {
28990f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29002dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    Raw tRNS graylevel = %d, scaled graylevel = %d.",
29012dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (int) ping_trans_color->gray,(int) transparent_color.alpha);
29020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29030f111984738842d27d04aed2a3f823d82a943506glennrp              }
290416ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.red=transparent_color.alpha;
290516ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.green=transparent_color.alpha;
290616ea139d53d867211d3bb0fa859a83de653f687ecristy              transparent_color.blue=transparent_color.alpha;
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2913faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2918faa852bad40107edae19405e76a299057668d795glennrp
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2920faa852bad40107edae19405e76a299057668d795glennrp
2921faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2922faa852bad40107edae19405e76a299057668d795glennrp
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2927bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2929bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2932faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2933faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2944faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2945faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2946a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
294716ea139d53d867211d3bb0fa859a83de653f687ecristy  if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
294816ea139d53d867211d3bb0fa859a83de653f687ecristy      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
29498d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    {
29500a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      double
29510a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp        image_gamma = image->gamma;
29520a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29530a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29540a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp         "    image->gamma=%f",(float) image_gamma);
29550a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp
29560a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      if (image_gamma > 0.75)
29578d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        {
29580a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp          /* Set image->rendering_intent to Undefined,
2959e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp           * image->colorspace to GRAY, and reset image->chromaticity.
29608d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp           */
296167429939a9bdca8c2ea541cd690b8e479c921527glennrp          image->intensity = Rec709LuminancePixelIntensityMethod;
29628d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp          SetImageColorspace(image,GRAYColorspace,exception);
29638d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp        }
2964ccc36af759d30fb50b1deda241d038402a393b17glennrp      else
2965ccc36af759d30fb50b1deda241d038402a393b17glennrp        {
2966ccc36af759d30fb50b1deda241d038402a393b17glennrp          RenderingIntent
2967ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_rendering_intent = image->rendering_intent;
2968ccc36af759d30fb50b1deda241d038402a393b17glennrp          ChromaticityInfo
2969ccc36af759d30fb50b1deda241d038402a393b17glennrp            save_chromaticity = image->chromaticity;
2970ccc36af759d30fb50b1deda241d038402a393b17glennrp
2971ccc36af759d30fb50b1deda241d038402a393b17glennrp          SetImageColorspace(image,GRAYColorspace,exception);
2972ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->rendering_intent = save_rendering_intent;
2973ccc36af759d30fb50b1deda241d038402a393b17glennrp          image->chromaticity = save_chromaticity;
2974ccc36af759d30fb50b1deda241d038402a393b17glennrp        }
2975ccc36af759d30fb50b1deda241d038402a393b17glennrp
2976ccc36af759d30fb50b1deda241d038402a393b17glennrp      image->gamma = image_gamma;
29778d0bca5eb90971dbd2100bb5d7a8de9e39f76595glennrp    }
2978e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp
2979e88af7706d1540872ed85dd059a8faf3339d3f5bglennrp  (void)LogMagickEvent(CoderEvent,GetMagickModule(),
29800a5b92ca99910144e70ca19c74d7bfe35eec6fc6glennrp      "    image->colorspace=%d",(int) image->colorspace);
2981a6c5d34901e480ed05ae3d7be9b4725d6e5ea246glennrp
2982faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
298332340ffa74550819f755f966e397ed58bbccd8e5glennrp      ((int) ping_bit_depth < 16 &&
298432340ffa74550819f755f966e397ed58bbccd8e5glennrp      (int) ping_color_type == PNG_COLOR_TYPE_GRAY))
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2986befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2987befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2988befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2990befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2991fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp      image->colors=one << ping_file_depth;
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
299467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
299567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
299667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
299767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2999faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
3005bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
30060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
301816ea139d53d867211d3bb0fa859a83de653f687ecristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
3019edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
30200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3021faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
30270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30286af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30346af6cf1a950b111ad0ac706269a703086693ba71glennrp
303567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
30366af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
30376af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
30386af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
30396af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
30406af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3048fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp          scale=(QuantumRange/((1UL << ping_file_depth)-1));
30490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
30520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3053bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3061147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3062cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
3063cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
3064147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
3065147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
3066147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3067fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     /* encode ping_width, ping_height, ping_file_depth, ping_color_type,
3068147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
3069147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30703b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
30717cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
30723398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.width,height",msg,exception);
3073147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3074fcf06169b67cb58a2ab649c11889f91cb400dfd8glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_file_depth);
30753398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.bit_depth",msg,exception);
3076147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
30775dff435eceea4f80207a906b11e65aed48fe3f27glennrp     (void) FormatLocaleString(msg,MaxTextExtent,"%d (%s)",
30785dff435eceea4f80207a906b11e65aed48fe3f27glennrp         (int) ping_color_type,
30795dff435eceea4f80207a906b11e65aed48fe3f27glennrp         Magick_ColorType_from_PNG_ColorType((int)ping_color_type));
30803398b5b62521b49754d9391aae9e4511857bd63bglennrp     (void) SetImageProperty(image,"png:IHDR.color_type",msg,exception);
3081147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
3082913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (ping_interlace_method == 0)
3083913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3084913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Not interlaced)",
3085913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3086913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3087913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else if (ping_interlace_method == 1)
3088913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3089913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Adam7 method)",
3090913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3091913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3092913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     else
3093913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3094913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d (Unknown method)",
3095913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) ping_interlace_method);
3096913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3097913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       (void) SetImageProperty(image,"png:IHDR.interlace_method",msg,exception);
3098913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp
3099913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp     if (number_colors != 0)
3100913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       {
3101913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp         (void) FormatLocaleString(msg,MaxTextExtent,"%d",
3102913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            (int) number_colors);
31033398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:PLTE.number_colors",msg,
3104913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp            exception);
3105913f961818c9b07fd49b9167cbbd6620bbde52fcglennrp       }
3106fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
3107fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
3108fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk     read_tIME_chunk(image,ping,ping_info,exception);
3109fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
3110cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3111147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
31170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31180ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
3119347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
3120347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31221b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      /* This happens later in non-ping decodes */
31231b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
31241b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp        image->storage_class=DirectClass;
31251b888c4e54e47ba7659d081d3c2d72dfb2d09bacglennrp
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3128e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3131edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3132868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3133cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3135edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
31390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
31460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
31480997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(image->rows,ping_rowbytes*
3149cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
31500997332e2c35a821b271d6e7473c01c10dc206adcristy  else
31510997332e2c35a821b271d6e7473c01c10dc206adcristy    pixel_info=AcquireVirtualMemory(ping_rowbytes,sizeof(*ping_pixels));
31520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31530997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
3154edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation failed");
31550997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
31560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
316316ea139d53d867211d3bb0fa859a83de653f687ecristy  quantum_info=AcquireQuantumInfo(image_info,image);
316416ea139d53d867211d3bb0fa859a83de653f687ecristy
316516ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info == (QuantumInfo *) NULL)
3166edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping,"Failed to allocate quantum_info");
31670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31684b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
31694b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp
3170c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
3171c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3172c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
3173c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
3174c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3175c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
3176c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3179c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
3180c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3181c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
3182c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
3183c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
3184ccc36af759d30fb50b1deda241d038402a393b17glennrp        image->alpha_trait=
3185ccc36af759d30fb50b1deda241d038402a393b17glennrp            (((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
3186c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
3187c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3188b0a657e13c4aefba39c51292005427b47277869dcristy            BlendPixelTrait : UndefinedPixelTrait;
31890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3190c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
3191c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
3192c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
3193c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
31940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3195c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
3196c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
31970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3198cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
3199c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3200c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          if (pass < num_passes-1)
3201c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp            continue;
3202c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3203862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy          q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
320516ea139d53d867211d3bb0fa859a83de653f687ecristy          if (q == (Quantum *) NULL)
3206c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
32070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
320816ea139d53d867211d3bb0fa859a83de653f687ecristy          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
320916ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321016ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayQuantum,ping_pixels+row_offset,exception);
32110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
321216ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
321316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321416ea139d53d867211d3bb0fa859a83de653f687ecristy              GrayAlphaQuantum,ping_pixels+row_offset,exception);
32150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
321616ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
321716ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
321816ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBAQuantum,ping_pixels+row_offset,exception);
32190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
322016ea139d53d867211d3bb0fa859a83de653f687ecristy          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
322116ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
322216ea139d53d867211d3bb0fa859a83de653f687ecristy              IndexQuantum,ping_pixels+row_offset,exception);
32230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
322416ea139d53d867211d3bb0fa859a83de653f687ecristy          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
322516ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
322616ea139d53d867211d3bb0fa859a83de653f687ecristy              RGBQuantum,ping_pixels+row_offset,exception);
32273faa9a3fb01696daaf976d595f492cb530bffb21glennrp
3228c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
3229c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3230c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
3231a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
3232a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3233a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
3234a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3235c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3236c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
32375aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
32385aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
323916ea139d53d867211d3bb0fa859a83de653f687ecristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
3240c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
3241a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3242a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3243a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
3244a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
3245c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
3246c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
3247c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
32484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
32494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
325016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
325116ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.red &&
325216ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
325316ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.green &&
325416ea139d53d867211d3bb0fa859a83de653f687ecristy                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
325516ea139d53d867211d3bb0fa859a83de653f687ecristy                    transparent_color.blue))
32564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
3257a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
3258a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3259a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
32604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
32614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
32624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
326316ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
3264c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
3265c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
32660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3267c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
3268c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
3269c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
3270c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
32710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3272c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
3273c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
3274c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
3275c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
3276c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
3277c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
32780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3279c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
32807a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3281c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
32827a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
32837a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
32847a287bfadeadea12e47c2376ca78a5d101687142cristy          }
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
3289c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3301c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
3302c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3303c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
330416ea139d53d867211d3bb0fa859a83de653f687ecristy
33058a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
3306b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
33070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
3309b0a657e13c4aefba39c51292005427b47277869dcristy        (image->alpha_trait  == BlendPixelTrait?  2 : 1)*
3310b0a657e13c4aefba39c51292005427b47277869dcristy        sizeof(*quantum_scanline));
33110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
3313edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        png_error(ping,"Memory allocation failed");
33140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3315bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33174f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        Quantum
33184f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp           alpha;
33194f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3321faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3322c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3325c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3326cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
3327c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
3328c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp        if (pass < num_passes-1)
3329c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp          continue;
3330c5c31be334ad2c5e7a99c4d3b1a28b330b26d4dcglennrp
33314f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
33320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
333316ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
33350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3336cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3338c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3339faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33434f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
3344faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3345bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3347a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33484f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33494f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                alpha=ScaleCharToQuantum((unsigned char)*p++);
33504f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33514f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                SetPixelAlpha(image,alpha,q);
33524f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33534f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                if (alpha != OpaqueAlpha)
33540b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
33554f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
335616ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3360bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3361a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
33620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
336547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3368bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3369a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3370c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
337187281ec8d96ad26dfed9968c29b2920cb3d96744cristy              unsigned short
337258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
337358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
337458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3375c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
337658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
337758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3378c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
337958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
338058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3381c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
338258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
33830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3384faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3386c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3387c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3388c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3389c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3390c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3391c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
33924f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33934f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  alpha=ScaleShortToQuantum(quantum);
33944f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  SetPixelAlpha(image,alpha,q);
33954f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
33964f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp                  if (alpha != OpaqueAlpha)
339758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
33984f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
339916ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
340058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
340158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
340258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
340358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
340458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
340547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
340658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
340758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
340816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,*p++,q);
34094f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
341016ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
34110b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
34124f99639dd26d0b38e2d421f3758b74c215e9cd4aglennrp
341358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
341416ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3417a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
341847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
342147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34253faa9a3fb01696daaf976d595f492cb530bffb21glennrp
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
34300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
343116ea139d53d867211d3bb0fa859a83de653f687ecristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
343216ea139d53d867211d3bb0fa859a83de653f687ecristy
343316ea139d53d867211d3bb0fa859a83de653f687ecristy        if (q == (Quantum *) NULL)
343416ea139d53d867211d3bb0fa859a83de653f687ecristy          break;
3435bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
343616ea139d53d867211d3bb0fa859a83de653f687ecristy        {
343716ea139d53d867211d3bb0fa859a83de653f687ecristy          SetPixelIndex(image,*r++,q);
343816ea139d53d867211d3bb0fa859a83de653f687ecristy          q+=GetPixelChannels(image);
343916ea139d53d867211d3bb0fa859a83de653f687ecristy        }
34400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
34430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34447a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
34457a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3446cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
34479fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
344847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34497a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
34507a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
34517a287bfadeadea12e47c2376ca78a5d101687142cristy          }
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3453c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34547a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
345747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3464c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3465b0a657e13c4aefba39c51292005427b47277869dcristy    image->alpha_trait=found_transparent_pixel ? BlendPixelTrait :
3466b0a657e13c4aefba39c51292005427b47277869dcristy      UndefinedPixelTrait;
3467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3470c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3471c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3473c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
34745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
34755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34765aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3477bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
34785aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
34795aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3481c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3482c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
348316ea139d53d867211d3bb0fa859a83de653f687ecristy  if (quantum_info != (QuantumInfo *) NULL)
348416ea139d53d867211d3bb0fa859a83de653f687ecristy    quantum_info=DestroyQuantumInfo(quantum_info);
348516ea139d53d867211d3bb0fa859a83de653f687ecristy
34865c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
34875c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3488b0a657e13c4aefba39c51292005427b47277869dcristy      PixelTrait
3489b0a657e13c4aefba39c51292005427b47277869dcristy        alpha_trait;
34905c6f789db7a30bad01ace12b09ad9cd471339e94cristy
3491b0a657e13c4aefba39c51292005427b47277869dcristy      alpha_trait=image->alpha_trait;
34928a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
349316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
3494b0a657e13c4aefba39c51292005427b47277869dcristy      image->alpha_trait=alpha_trait;
34955c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
349647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34974eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3499ccc36af759d30fb50b1deda241d038402a393b17glennrp  if (logging != MagickFalse)
3500ccc36af759d30fb50b1deda241d038402a393b17glennrp  {
3501ccc36af759d30fb50b1deda241d038402a393b17glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3502ccc36af759d30fb50b1deda241d038402a393b17glennrp       "  image->storage_class=%d\n",(int) image->storage_class);
3503ccc36af759d30fb50b1deda241d038402a393b17glennrp  }
3504ccc36af759d30fb50b1deda241d038402a393b17glennrp
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3506bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
35090997332e2c35a821b271d6e7473c01c10dc206adcristy      pixel_info=RelinquishVirtualMemory(pixel_info);
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
351116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageBackgroundColor(image,exception);
3512868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3513cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
352047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3521faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
35308a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=BlendPixelTrait;
3531c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35323c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3533c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
35350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3537c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
35380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
35390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35408a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                 image->colormap[x].alpha_trait=BlendPixelTrait;
354116ea139d53d867211d3bb0fa859a83de653f687ecristy                 image->colormap[x].alpha =
354216ea139d53d867211d3bb0fa859a83de653f687ecristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
35430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3544c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
354547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
35470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
35480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
35490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
35500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
355116ea139d53d867211d3bb0fa859a83de653f687ecristy                     transparent_color.alpha)
35520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
35538a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->colormap[x].alpha_trait=BlendPixelTrait;
355416ea139d53d867211d3bb0fa859a83de653f687ecristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
35550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
35560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
35570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
355816ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) SyncImage(image,exception);
35590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
356047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3561a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3562a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3563a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
35640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
35650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
35660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
35670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
35680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
35690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3570c11cf6a442f3046940608a5743a68cc891deb13eglennrp
357116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (q == (Quantum *) NULL)
35720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3573c11cf6a442f3046940608a5743a68cc891deb13eglennrp
35740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3575a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3576a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3577a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
35780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
35790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
358016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
358116ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.red &&
358216ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
358316ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.green &&
358416ea139d53d867211d3bb0fa859a83de653f687ecristy                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
358516ea139d53d867211d3bb0fa859a83de653f687ecristy                  transparent_color.blue)
35864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
358716ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,q);
35884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
35890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
359067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
35910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
35924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
359316ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
35944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3595a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
35960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
359716ea139d53d867211d3bb0fa859a83de653f687ecristy              q+=GetPixelChannels(image);
35980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
35990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
36010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3602c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
36030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3604a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3605c11cf6a442f3046940608a5743a68cc891deb13eglennrp
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36083c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3609eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
36104eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
36114eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3612a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3613a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36144eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3615a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3616a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36184eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
36194eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
36204eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
36214eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
36220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36234eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
36244eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36254eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
36260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36274eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
36284eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
362999f968111025b4fadb966ca482c6f57750bf007bglennrp            const char
363099f968111025b4fadb966ca482c6f57750bf007bglennrp              *value;
363199f968111025b4fadb966ca482c6f57750bf007bglennrp
363299f968111025b4fadb966ca482c6f57750bf007bglennrp            value=GetImageOption(image_info,"profile:skip");
363399f968111025b4fadb966ca482c6f57750bf007bglennrp
363499f968111025b4fadb966ca482c6f57750bf007bglennrp            if (IsOptionMember(text[i].key+17,value) == MagickFalse)
363599f968111025b4fadb966ca482c6f57750bf007bglennrp            {
363699f968111025b4fadb966ca482c6f57750bf007bglennrp               (void) Magick_png_read_raw_profile(ping,image,image_info,text,
363799f968111025b4fadb966ca482c6f57750bf007bglennrp                  (int) i,exception);
363899f968111025b4fadb966ca482c6f57750bf007bglennrp               num_raw_profiles++;
363999f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
364099f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
364199f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Read raw profile %s",text[i].key+17);
364299f968111025b4fadb966ca482c6f57750bf007bglennrp            }
364399f968111025b4fadb966ca482c6f57750bf007bglennrp            else
364499f968111025b4fadb966ca482c6f57750bf007bglennrp            {
364599f968111025b4fadb966ca482c6f57750bf007bglennrp               if (logging != MagickFalse)
364699f968111025b4fadb966ca482c6f57750bf007bglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
364799f968111025b4fadb966ca482c6f57750bf007bglennrp                   "    Skipping raw profile %s",text[i].key+17);
364899f968111025b4fadb966ca482c6f57750bf007bglennrp            }
36494eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
36504eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36514eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
36524eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
36534eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
36544eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
36554eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36564eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
36574eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
36584eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
36594eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
36604eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
3661edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"Memory allocation failed");
36624eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
36634eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
36644eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
36654eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
36664eb3931feb349dd87142c78503b779228f3e1a0fglennrp
36674eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
36684eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
36694eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
36704eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
36714eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
36724eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
367316ea139d53d867211d3bb0fa859a83de653f687ecristy               (void) SetImageProperty(image,text[i].key,value,exception);
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36754eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
36774eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36782dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      length: %lu\n"
36792dd1906783a5ece58a6105b4f59239e28b13caddglennrp                "      Keyword: %s",
36802dd1906783a5ece58a6105b4f59239e28b13caddglennrp                (unsigned long) length,
36812dd1906783a5ece58a6105b4f59239e28b13caddglennrp                text[i].key);
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
36830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36844eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
368597f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
36864eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
3687fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    num_text_total += num_text;
3688fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
36893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
370273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
37030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
371047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
3715edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp             png_error(ping,"Memory allocation failed");
37160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
3718edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping,"Cannot overwrite frozen MNG object buffer");
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
37270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
372916ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
37300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
37330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
3735edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp            png_error(ping, "Cloning image for object buffer failed");
37360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3737faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
37390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3740faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3741faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3742faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3743faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3744faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3745faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3746faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3747faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
37480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3749faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
37593c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
376547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37710a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
37728a46d827a124555f0c48fb2368ec1bba8e079ab6cristy   /* Set image->alpha_trait to MagickTrue if the input colortype supports
37730a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
37740a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
37750a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
37768a46d827a124555f0c48fb2368ec1bba8e079ab6cristy    image->alpha_trait=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
37770a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
37780a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
3779b0a657e13c4aefba39c51292005427b47277869dcristy        BlendPixelTrait : UndefinedPixelTrait;
37800a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3781224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#if 0  /* I'm not sure what's wrong here but it does not work. */
37825830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    if (image->alpha_trait == BlendPixelTrait)
37835830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37845830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
37855830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleMatteType,exception);
37865830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37875830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
37885830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteMatteType,exception);
37895830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37905830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
37915830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
37925830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
37935830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37945830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    else
37955830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    {
37965830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
37975830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,GrayscaleType,exception);
37985830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
37995830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
38005830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,PaletteType,exception);
38015830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
38025830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp      else
38035830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        (void) SetImageType(image,TrueColorType,exception);
38045830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
3805224ad8d90905c1c81d949c30e4a808246b4d5165glennrp#endif
38065830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
3807cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3808cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3809cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3810cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3811cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38124eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3813cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3814cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
38153b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3816613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
38173398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:text",msg,
381816ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3819cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3820cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3821cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3822cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
38233b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3824cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
382516ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) SetImageProperty(image,"png:text-encoded profiles",msg,
382616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
3827cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3828cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
382998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_cHRM != MagickFalse)
38305961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
38313b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38325961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
38333398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:cHRM",msg,
383416ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38355961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3836cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3837cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
38385961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
38393b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38405961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
38413398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:bKGD",msg,
384216ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38435961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
38445961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
38453b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
38465961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3847cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
384898b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#if defined(PNG_iCCP_SUPPORTED)
384998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_iCCP != MagickFalse)
38503398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:iCCP",msg,
385116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
385298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp#endif
3853cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38544eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
38553398b5b62521b49754d9391aae9e4511857bd63bglennrp        (void) SetImageProperty(image,"png:tRNS",msg,
385616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38574eb3931feb349dd87142c78503b779228f3e1a0fglennrp
38584eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
385998b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_sRGB != MagickFalse)
38604eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38613b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
386298b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            "intent=%d (%s)",
386398b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            (int) intent,
386498b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp            Magick_RenderingIntentString_from_PNG_RenderingIntent(intent));
38653398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:sRGB",msg,
386698b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp                 exception);
38674eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38684eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38694eb3931feb349dd87142c78503b779228f3e1a0fglennrp
387098b83d44ee0acdfb9854edd714e4f2f4f0f787e4glennrp     if (ping_found_gAMA != MagickFalse)
38714eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38723b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
387316ea139d53d867211d3bb0fa859a83de653f687ecristy            "gamma=%.8g (See Gamma, above)",
387416ea139d53d867211d3bb0fa859a83de653f687ecristy            file_gamma);
38753398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:gAMA",msg,
387616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38774eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3878cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38794eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3880cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
38814eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38823b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
388307523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
38844eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
38853398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:pHYs",msg,
388616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38874eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38884eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3889cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
38904eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
38914eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
38924eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
38933b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
38944eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
38953398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:oFFs",msg,
389616ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
38974eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
38984eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
38994eb3931feb349dd87142c78503b779228f3e1a0fglennrp
3900fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
3901fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk     read_tIME_chunk(image,ping,end_info,exception);
3902fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
3903fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
390407523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
390507523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
390607523c7d2e40370804c2036295571e4b6426f94dglennrp       {
39073b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
390807523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
390907523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
39103398b5b62521b49754d9391aae9e4511857bd63bglennrp         (void) SetImageProperty(image,"png:vpAg",msg,
391116ea139d53d867211d3bb0fa859a83de653f687ecristy                exception);
391207523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3913cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3914cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39200997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
39250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3926868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
3927edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
3928edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
3929edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
3930edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* }  for navigation to beginning of SETJMP-protected block, revert to
3931edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    Throwing an Exception when an error occurs.
3932edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
3933edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
394621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
394721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
396447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
396847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3971fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
397216ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
397547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
397847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
398347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3984dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
398647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
399173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
399247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
399547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
400647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
40130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
40170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
40210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
402447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
402647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
40320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
403547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
403672715f5c299a6482f8eb175070b056d77b74a43fcristy  if ((IssRGBColorspace(image->colorspace) != MagickFalse) &&
40373d627862fb79aad8a20be4f1587f0b8761db441aglennrp      ((image->gamma < .45) || (image->gamma > .46)) &&
40383d627862fb79aad8a20be4f1587f0b8761db441aglennrp           !(image->chromaticity.red_primary.x>0.6399f &&
40393d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.x<0.6401f &&
40403d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y>0.3299f &&
40413d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.red_primary.y<0.3301f &&
40423d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x>0.2999f &&
40433d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.x<0.3001f &&
40443d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y>0.5999f &&
40453d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.green_primary.y<0.6001f &&
40463d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x>0.1499f &&
40473d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.x<0.1501f &&
40483d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y>0.0599f &&
40493d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.blue_primary.y<0.0601f &&
40503d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x>0.3126f &&
40513d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.x<0.3128f &&
40523d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y>0.3289f &&
40533d627862fb79aad8a20be4f1587f0b8761db441aglennrp           image->chromaticity.white_point.y<0.3291f))
4054ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4055ccc36af759d30fb50b1deda241d038402a393b17glennrp       SetImageColorspace(image,RGBColorspace,exception);
4056ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
405772715f5c299a6482f8eb175070b056d77b74a43fcristy
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
4059ccc36af759d30fb50b1deda241d038402a393b17glennrp    {
4060ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4061ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
4062ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.width,(double) image->page.height,
4063ccc36af759d30fb50b1deda241d038402a393b17glennrp               (double) image->page.x,(double) image->page.y);
4064ccc36af759d30fb50b1deda241d038402a393b17glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4065ccc36af759d30fb50b1deda241d038402a393b17glennrp           "  image->colorspace: %d", (int) image->colorspace);
4066ccc36af759d30fb50b1deda241d038402a393b17glennrp    }
406797f90e23c85b9c58387880125c29d8c99126f83aglennrp
406897f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
40700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41224383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
41234383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
41244383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
4125bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
414516ea139d53d867211d3bb0fa859a83de653f687ecristy  register const Quantum
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4148bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
415216ea139d53d867211d3bb0fa859a83de653f687ecristy  register Quantum
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
4160e0421fec74bee9a6f9def3d51aed4204f970ad73glennrp    reading_idat;
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
4176fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
41790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
418016ea139d53d867211d3bb0fa859a83de653f687ecristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
41880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
418916ea139d53d867211d3bb0fa859a83de653f687ecristy      AcquireNextImage(image_info,image,exception);
41900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
41930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
42200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
42230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4231e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
4232e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
42360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
423947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42408fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
42430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4247bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
42490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
425247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4259bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
4260e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[2] << 8) | p[3]);
4261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
4262e2440c250d94d64f8c70e596fe90808795aaa07ecristy              (p[6] << 8) | p[7]);
4263e2440c250d94d64f8c70e596fe90808795aaa07ecristy            if ((jng_width == 0) || (jng_height == 0))
4264e2440c250d94d64f8c70e596fe90808795aaa07ecristy              ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
426947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
427247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
427747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42812dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_width:      %16lu,    jng_height:     %16lu\n"
42822dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_color_type: %16d,     jng_image_sample_depth: %3d\n"
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
42842dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  (unsigned long) jng_width, (unsigned long) jng_height,
42852dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_color_type, jng_image_sample_depth,
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
428747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42892dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_image_interlace_method:  %3d"
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
42912dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_image_interlace_method,
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
429347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42952dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_compression_method:%3d\n"
42962dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  "    jng_alpha_filter_method:     %3d\n"
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
42982dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_compression_method,
42992dd1906783a5ece58a6105b4f59239e28b13caddglennrp                  jng_alpha_filter_method,
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
430347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43048fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
430647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
432273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
432347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
432647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
432816ea139d53d867211d3bb0fa859a83de653f687ecristy        color_image=AcquireImage(color_image_info,exception);
43290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
43360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
43400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
434773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
43480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
43510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
435316ea139d53d867211d3bb0fa859a83de653f687ecristy            alpha_image=AcquireImage(alpha_image_info,exception);
43540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
43650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
43690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
43810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
43840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
438703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
440447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
441147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44128fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
441447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
442347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4431bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
443303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44408fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
444847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44598fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
44680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44698fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
44988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
44990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
45098182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
45108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
45118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
45128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
45138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
45148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
45158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
451747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4526e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4527cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
4528da7803d6b1161960bc1e7db4d9718284c116fab8cristy            image->gamma=1.000f/2.200f;
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
453847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45475eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
45485eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
45490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
455647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45578fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
456716ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.x=(double) mng_get_long(p);
456816ea139d53d867211d3bb0fa859a83de653f687ecristy            image->resolution.y=(double) mng_get_long(&p[4]);
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
457216ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.x=image->resolution.x/100.0f;
457316ea139d53d867211d3bb0fa859a83de653f687ecristy                image->resolution.y=image->resolution.y/100.0f;
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4584fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
45858fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45928fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp    if (length != 0)
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
45970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
462016ea139d53d867211d3bb0fa859a83de653f687ecristy         alpha samples of main image.
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
462647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
46300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4631f0eec7524321f1be1bfe568a13ab7d4d0333c814cristy  assert(color_image_info != (ImageInfo *) NULL);
46323b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
46340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
46370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
46510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
46540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
465716ea139d53d867211d3bb0fa859a83de653f687ecristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,exception);
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
465916ea139d53d867211d3bb0fa859a83de653f687ecristy    for (x=(ssize_t) image->columns; x != 0; x--)
466016ea139d53d867211d3bb0fa859a83de653f687ecristy    {
466116ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
466216ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
466316ea139d53d867211d3bb0fa859a83de653f687ecristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
466416ea139d53d867211d3bb0fa859a83de653f687ecristy      q+=GetPixelChannels(image);
466516ea139d53d867211d3bb0fa859a83de653f687ecristy      s+=GetPixelChannels(jng_image);
466616ea139d53d867211d3bb0fa859a83de653f687ecristy    }
466747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
46710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
46730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
468403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
46880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
46900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
469316ea139d53d867211d3bb0fa859a83de653f687ecristy             "    Reading alpha from alpha_blob.");
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46953b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
46990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4701bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
470416ea139d53d867211d3bb0fa859a83de653f687ecristy               exception);
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
470647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47078a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             if (image->alpha_trait == BlendPixelTrait)
470816ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
470916ea139d53d867211d3bb0fa859a83de653f687ecristy               {
471016ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
471116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
471216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
471316ea139d53d867211d3bb0fa859a83de653f687ecristy               }
47140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
471616ea139d53d867211d3bb0fa859a83de653f687ecristy               for (x=(ssize_t) image->columns; x != 0; x--)
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
471816ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
471916ea139d53d867211d3bb0fa859a83de653f687ecristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
47208a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                    image->alpha_trait=BlendPixelTrait;
472116ea139d53d867211d3bb0fa859a83de653f687ecristy                  q+=GetPixelChannels(image);
472216ea139d53d867211d3bb0fa859a83de653f687ecristy                  s+=GetPixelChannels(jng_image);
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
47240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
473647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
473747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
47430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
47450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
47470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
47480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
47510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
47530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
47570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
47580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
47590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
47600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
47640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
47680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
481021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
481121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4831fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
483216ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
48350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
48380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
484247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
484347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
484547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48463b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
484947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
485047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
485273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
48530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
48560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
485747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
485847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
48660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
48740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
488247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
48880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
48910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
48940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49084383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
490921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
491021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
49114383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
493616ea139d53d867211d3bb0fa859a83de653f687ecristy  PixelInfo
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4943bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4949bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4966bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
497538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
497638ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
497738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4978bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
500047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
500147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
5007fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
500816ea139d53d867211d3bb0fa859a83de653f687ecristy  image=AcquireImage(image_info,exception);
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
50110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
50140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
501847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
501947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
502047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
502173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
50220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
50250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
502647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
502747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
503747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
504147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
504247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
5046bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
505047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5093e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
5094e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
50980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
51010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
51040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51058fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (length != 0)
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
510847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
511147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5112bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
511447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
51240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
512616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
51280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
51350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
513716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
51390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
514447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
51490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51508fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
51560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
51640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
51670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5171e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5173e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
51778182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
51780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
51810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
51850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
51880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
51928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
51960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
51990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
52020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
520716ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
520947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
521016ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
52110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
52140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
52220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52233b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
5224e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
5225f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
52260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
5228bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
5230bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
52320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
52350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52468fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
52480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
52528182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
52530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
52560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5264280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  "    repeat=%d,  final_delay=%.20g,  iterations=%.20g",
5265280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                  repeat,(double) final_delay, (double) image->iterations);
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
527416ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
52790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
528116ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
5288edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                  Instead of using a warning we should allocate a larger
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
529116ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ThrowMagickException(exception,GetMagickModule(),
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
530016ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
53080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
53110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
53180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
53190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
53210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
53220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5326280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      "  x_off[%d]: %.20g,  y_off[%d]: %.20g",
5327280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->x_off[object_id],
5328280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp                      object_id,(double) mng_info->y_off[object_id]);
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
53380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
53450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
53680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
53710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
53760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
53790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
53820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
538316ea139d53d867211d3bb0fa859a83de653f687ecristy                mng_background_color.alpha=OpaqueAlpha;
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
539447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
539747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
539847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
54040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5405bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
541235ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
54210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54228fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
54270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
543147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5437bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
544412560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
54620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
546947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
547047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
54748182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
54758182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
54778182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
54798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
54818182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
54838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
54858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
549047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
549447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55008fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5502e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5503cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
550847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
551247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5515fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55208fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
552247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
552547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
552916ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
55320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
55350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
553947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55408fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
55430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
55470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
555047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
555147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
555347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5554bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
555647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
555847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5559bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
557047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
55748182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
55750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55768182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
55778182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
55780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5579bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5580bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
55810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
55840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
55860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5589e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
559147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5594bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5595bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
55960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5597bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5598bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
55990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5600bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5601bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
56020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
56050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
56070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5610e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
561247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
56180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5622e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5623e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
562447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
56320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5633bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
56350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5644e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5645e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
56460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
565047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
565116ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
565316ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
565447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
566147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
56660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
56760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
56848a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                image->alpha_trait=UndefinedPixelTrait;
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
568616ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
56870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5691e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5692e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
570947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
572147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57378fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
574547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
574647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5755bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5758bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57658fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
57670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
577047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5773bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
577747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
577847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5781bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
579847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5805bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
580847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
580947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
58108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
58110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5814e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5815e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
58160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
58190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
58250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
583047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
583447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
584647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
58530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5857e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5858f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
585947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
58640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
586947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
588747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
589147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
589516ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
589847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
590147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
59180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
59210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
59240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
593116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
593547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
594147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
594747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
595047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
595647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
595947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
596547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
596847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
597447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
597747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
598347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
598647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
599247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
599547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
600147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
600547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
600916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ThrowMagickException(exception,
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
601347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
603247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
603616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
603947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
604247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
604616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
604947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
605247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
605747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
60738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
60758182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
607947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
608616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
608847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
609447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
609616ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ThrowMagickException(exception,GetMagickModule(),
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
609947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
6102bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
6104bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
611247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
611547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
611847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
612147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
612447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
612747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
613047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
613847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
614147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
614447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
614947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
61578fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp            if (length != 0)
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
615947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
616647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
616947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
617547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
618347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61848182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
61858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
6198bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
6200bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
620216ea139d53d867211d3bb0fa859a83de653f687ecristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
620716ea139d53d867211d3bb0fa859a83de653f687ecristy                    AcquireNextImage(image_info,image,exception);
620847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
621547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
621947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
622647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
622947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
623047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
623147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
624016ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6243e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
6244e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
625516ea139d53d867211d3bb0fa859a83de653f687ecristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
626016ea139d53d867211d3bb0fa859a83de653f687ecristy              AcquireNextImage(image_info,image,exception);
626147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
626847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
62710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
62730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
62800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
628347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
62928a46d827a124555f0c48fb2368ec1bba8e079ab6cristy            image->alpha_trait=UndefinedPixelTrait;
629316ea139d53d867211d3bb0fa859a83de653f687ecristy            (void) SetImageBackgroundColor(image,exception);
62940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
6298e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
6299e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
630347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
630416ea139d53d867211d3bb0fa859a83de653f687ecristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
630916ea139d53d867211d3bb0fa859a83de653f687ecristy            AcquireNextImage(image_info,image,exception);
631047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
631747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
63230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
63260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
63350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
63410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
63440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
635047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
635447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
635947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6360bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
636147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
637347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
638647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
641947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
642247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
642447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
642547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
642747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64304e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
643147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
643447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
643747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
643947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
644047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
644247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
644647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
644947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
645147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
645247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
645447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64574e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
645847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
646147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
646447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
646647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
646747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
646947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
647916ea139d53d867211d3bb0fa859a83de653f687ecristy                Quantum
648016ea139d53d867211d3bb0fa859a83de653f687ecristy                  *next,
648116ea139d53d867211d3bb0fa859a83de653f687ecristy                  *prev;
648216ea139d53d867211d3bb0fa859a83de653f687ecristy
648316ea139d53d867211d3bb0fa859a83de653f687ecristy                png_uint_16
648416ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methx,
648516ea139d53d867211d3bb0fa859a83de653f687ecristy                  magn_methy;
648616ea139d53d867211d3bb0fa859a83de653f687ecristy
6487bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
649116ea139d53d867211d3bb0fa859a83de653f687ecristy                register Quantum
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
649516ea139d53d867211d3bb0fa859a83de653f687ecristy                register ssize_t
649616ea139d53d867211d3bb0fa859a83de653f687ecristy                  x;
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
649847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
649947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
650347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
650416ea139d53d867211d3bb0fa859a83de653f687ecristy                AcquireNextImage(image_info,image,exception);
650547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65213faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6529bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
653347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
653616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,ScaleQuantumToShort(
653716ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelRed(image,q)),q);
653816ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,ScaleQuantumToShort(
653916ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelGreen(image,q)),q);
654016ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,ScaleQuantumToShort(
654116ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelBlue(image,q)),q);
654216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,ScaleQuantumToShort(
654316ea139d53d867211d3bb0fa859a83de653f687ecristy                            GetPixelAlpha(image,q)),q);
654416ea139d53d867211d3bb0fa859a83de653f687ecristy                          q+=GetPixelChannels(image);
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
654647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65558a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                if (image->alpha_trait == BlendPixelTrait)
655616ea139d53d867211d3bb0fa859a83de653f687ecristy                   (void) SetImageBackgroundColor(large_image,exception);
655747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
656016ea139d53d867211d3bb0fa859a83de653f687ecristy                    large_image->background_color.alpha=OpaqueAlpha;
656116ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) SetImageBackgroundColor(large_image,exception);
656247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
656547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
656847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
657147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6580e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
658316ea139d53d867211d3bb0fa859a83de653f687ecristy                length=(size_t) image->columns*GetPixelChannels(image);
658416ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
658516ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
658647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
658716ea139d53d867211d3bb0fa859a83de653f687ecristy                if ((prev == (Quantum *) NULL) ||
658816ea139d53d867211d3bb0fa859a83de653f687ecristy                    (next == (Quantum *) NULL))
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
659547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
659847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
660347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
660647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6607bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
660947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
661247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6614bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
661547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
661947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
662647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
662916ea139d53d867211d3bb0fa859a83de653f687ecristy                    register Quantum
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
66369fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
663716ea139d53d867211d3bb0fa859a83de653f687ecristy                    q+=(large_image->columns-image->columns)*
663816ea139d53d867211d3bb0fa859a83de653f687ecristy                      GetPixelChannels(large_image);
663947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6640bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6642fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6651bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
665216ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
665316ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(large_image,GetPixelGreen(image,
665416ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
665516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(large_image,GetPixelBlue(image,
665616ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
665716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(large_image,GetPixelAlpha(image,
665816ea139d53d867211d3bb0fa859a83de653f687ecristy                             pixels),q);
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
666047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6664bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
666516ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,GetPixelRed(image,
666616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
666716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,GetPixelGreen(image,
666816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
666916ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,GetPixelBlue(image,
667016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
667116ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,GetPixelAlpha(image,
667216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 pixels),q);
6673bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
667447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
667816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(large_image,((QM) (((ssize_t)
667916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelRed(image,n)
668016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels)+m))/
6681bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
668216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelRed(image,pixels)))),q);
668316ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
668416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelGreen(image,n)
668516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels)+m))/
6686bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
668716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelGreen(image,pixels)))),q);
668816ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
668916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (2*i*(GetPixelBlue(image,n)
669016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels)+m))/
6691bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
669216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelBlue(image,pixels)))),q);
669347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66948a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
669516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
669616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    (2*i*(GetPixelAlpha(image,n)
669716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    -GetPixelAlpha(image,pixels)+m))
6698bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
669916ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)))),q);
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
670147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
670616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
670716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
670916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
671016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    n),q);
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
671347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6718bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
671916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,
672016ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
672116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,
672216ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
672316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,
672416ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
672516ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,
672616ea139d53d867211d3bb0fa859a83de653f687ecristy                                    pixels),q);
6727bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
672847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6730bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
673116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
673216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(large_image,GetPixelGreen(image,n),
673316ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
673416ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(large_image,GetPixelBlue(image,n),
673516ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
673616ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
673716ea139d53d867211d3bb0fa859a83de653f687ecristy                                    q);
6738bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
673947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
674216ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
674316ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (GetPixelAlpha(image,n)
674416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))
6745bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
674616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
674916ea139d53d867211d3bb0fa859a83de653f687ecristy                      n+=GetPixelChannels(image);
675016ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(large_image);
675116ea139d53d867211d3bb0fa859a83de653f687ecristy                      pixels+=GetPixelChannels(image);
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
675347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
675647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
675947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
676016ea139d53d867211d3bb0fa859a83de653f687ecristy                prev=(Quantum *) RelinquishMagickMemory(prev);
676116ea139d53d867211d3bb0fa859a83de653f687ecristy                next=(Quantum *) RelinquishMagickMemory(next);
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6778e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
678216ea139d53d867211d3bb0fa859a83de653f687ecristy                  register Quantum
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
678616ea139d53d867211d3bb0fa859a83de653f687ecristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
678716ea139d53d867211d3bb0fa859a83de653f687ecristy                  n=pixels+GetPixelChannels(image);
678847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6789bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
679216ea139d53d867211d3bb0fa859a83de653f687ecristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
67937c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6794bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6795bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
679647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6797bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
679947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6800bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6801bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
680247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
680547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6807bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
680847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
681416ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
681516ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
681616ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
681716ea139d53d867211d3bb0fa859a83de653f687ecristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
681947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6823bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
682416ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
682516ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
682616ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
682716ea139d53d867211d3bb0fa859a83de653f687ecristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6828bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
682947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
683016ea139d53d867211d3bb0fa859a83de653f687ecristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
683416ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelRed(image,(QM) ((2*i*(
683516ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,n)
683616ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelRed(image,pixels))+m)
6837bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
683816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelRed(image,pixels)),q);
6839bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
684016ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelGreen(image,(QM) ((2*i*(
684116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,n)
684216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelGreen(image,pixels))+m)
6843bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
684416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelGreen(image,pixels)),q);
6845bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
684616ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelBlue(image,(QM) ((2*i*(
684716ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,n)
684816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelBlue(image,pixels))+m)
6849bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
685016ea139d53d867211d3bb0fa859a83de653f687ecristy                                 GetPixelBlue(image,pixels)),q);
68518a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                              if (image->alpha_trait == BlendPixelTrait)
685216ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,(QM) ((2*i*(
685316ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)
685416ea139d53d867211d3bb0fa859a83de653f687ecristy                                   -GetPixelAlpha(image,pixels))+m)
6855bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
685616ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)),q);
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
685847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6863bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
686416ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
686516ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,pixels)+0,q);
6866bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6868bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
686916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 SetPixelAlpha(image,
687016ea139d53d867211d3bb0fa859a83de653f687ecristy                                   GetPixelAlpha(image,n)+0,q);
6871bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
687447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6879bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
688016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
688116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
688216ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
688316ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6884bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
688547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6887bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
688816ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelRed(image,GetPixelRed(image,n),q);
688916ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
689016ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
689116ea139d53d867211d3bb0fa859a83de653f687ecristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6892bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
689347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
689716ea139d53d867211d3bb0fa859a83de653f687ecristy                              SetPixelAlpha(image,
689816ea139d53d867211d3bb0fa859a83de653f687ecristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
689916ea139d53d867211d3bb0fa859a83de653f687ecristy                                 -GetPixelAlpha(image,pixels))+m)/
6900bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
690116ea139d53d867211d3bb0fa859a83de653f687ecristy                                 +GetPixelAlpha(image,pixels)),q);
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
690416ea139d53d867211d3bb0fa859a83de653f687ecristy                      q+=GetPixelChannels(image);
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
690616ea139d53d867211d3bb0fa859a83de653f687ecristy                    n+=GetPixelChannels(image);
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
690847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69123faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
692147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6922bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
692416ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelRed(image,ScaleShortToQuantum(
692516ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelRed(image,q)),q);
692616ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelGreen(image,ScaleShortToQuantum(
692716ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelGreen(image,q)),q);
692816ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelBlue(image,ScaleShortToQuantum(
692916ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelBlue(image,q)),q);
693016ea139d53d867211d3bb0fa859a83de653f687ecristy                        SetPixelAlpha(image,ScaleShortToQuantum(
693116ea139d53d867211d3bb0fa859a83de653f687ecristy                          GetPixelAlpha(image,q)),q);
693216ea139d53d867211d3bb0fa859a83de653f687ecristy                        q+=GetPixelChannels(image);
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
693447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
696847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6984bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6985bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
699147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
700347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
701416ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) SetImageBackgroundColor(image,exception);
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70262b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
70272b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
702816ea139d53d867211d3bb0fa859a83de653f687ecristy       * if lossy.
70292b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
70302b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
70312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
70322b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
70332b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
70343faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7035cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      if (image->depth > 8)
7036cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        {
7037cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* To do: fill low byte properly */
7038cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          image->depth=16;
7039cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp        }
7040cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
704116ea139d53d867211d3bb0fa859a83de653f687ecristy      if (LosslessReduceDepthOK(image,exception) != MagickFalse)
70428640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7044d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
7048bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7051d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
7055d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
705747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
705947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
706347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
70703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
70740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
707516ea139d53d867211d3bb0fa859a83de653f687ecristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
708016ea139d53d867211d3bb0fa859a83de653f687ecristy          AcquireNextImage(image_info,image,exception);
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
708547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
708947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
71018a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      image->alpha_trait=UndefinedPixelTrait;
71020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
710416ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageBackgroundColor(image,exception);
71050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
71100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
712147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
712216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
712547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
71300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
713547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
713616ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,GetMagickModule(),
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
714147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
714947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
715016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
715447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
716047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
716116ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
716347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
716647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
71740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
71770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
71800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
718547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
71910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
71930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7196e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
7197e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
71980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
720647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
720947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7211e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
721247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7217e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
723447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
723616ea139d53d867211d3bb0fa859a83de653f687ecristy      next_image=CoalesceImages(image,exception);
723747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
724047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
724347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
725247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
725547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
727247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
728247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
728547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7287e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
7288e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
728947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
7291f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
7292f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
729347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7294f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7295e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
7296e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
7297f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
7298f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
729947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
730347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
730647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
730925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
731447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
731747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
732047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
732525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7348bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7351bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
736447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
737047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
737847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
738247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
739047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
739347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
739847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
740147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
740447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7405afc97b1e31b78c973c4bf5e0be8d5090cfca8065glennrp  entry->mime_type=ConstantString("video/x-mng");
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
741147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
741647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
7420d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
742247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
742547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
743047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
743547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
7440d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
744647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
745047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
745747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
746047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
746547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
7468fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 24-bit RGB");
7469d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
747447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
747947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
7483d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7487fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG48");
7488fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7489fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7490fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7491fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7492fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7493fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7494fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7495fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7496fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or binary transparent 48-bit RGB");
7497d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7498fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7499fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7500fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7501fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry=SetMagickInfo("PNG64");
7502fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7503fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
7504fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
7505fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
7506fd164d2bf84b111e304959af5698757d60e9b8aeglennrp#endif
7507fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
7508fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
7509fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->adjoin=MagickFalse;
7510fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->description=ConstantString("opaque or transparent 64-bit RGBA");
7511d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
7512fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  entry->module=ConstantString("PNG");
7513fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) RegisterMagickInfo(entry);
7514fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
75155830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry=SetMagickInfo("PNG00");
75165830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75175830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#if defined(MAGICKCORE_PNG_DELEGATE)
75185830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
75195830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->encoder=(EncodeImageHandler *) WritePNGImage;
75205830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp#endif
75215830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75225830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->magick=(IsImageFormatHandler *) IsPNG;
75235830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->adjoin=MagickFalse;
75246270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp  entry->description=ConstantString(
75256270857991c1a3fb1d05e652e81835ee4fcf0a34glennrp    "PNG inheriting bit-depth and color-type from original");
7526d625c5209f3ea468a8494fb5a2a73ac36eead2b5cristy  entry->mime_type=ConstantString("image/png");
75275830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  entry->module=ConstantString("PNG");
75285830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) RegisterMagickInfo(entry);
75295830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
753147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
753847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
75427fee329aec1090ff832c1b07fc4cc70c3b604f65glennrp  entry->mime_type=ConstantString("image/x-jng");
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
754647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7547868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
75483d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy  ping_semaphore=AcquireSemaphoreInfo();
754918b17443128598500357da7bff2f01683cf32890cristy#endif
755047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
75603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
7580fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG48");
7581fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  (void) UnregisterMagickInfo("PNG64");
75825830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp  (void) UnregisterMagickInfo("PNG00");
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
758447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7585868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
7586cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
75873d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy    RelinquishSemaphoreInfo(&ping_semaphore);
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
759225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
761116ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
761216ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
762016ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7670cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7677bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
76943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
76980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
76990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
77010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7702ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7703a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
7704a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7705a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
7706a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
7710ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
7711a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping,
7712a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy      (png_alloc_size_t) allocated_length);
7713a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
7714a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
7715a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
7716a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy   text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
7717a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77293b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7730f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
773247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7733bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
774047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
774747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
775047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7756cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
77574383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
777147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
777247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
777347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
77743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
777547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7779cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
778147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
778247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
778347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
778447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
778547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
778647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7787cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7788cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7789cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
779047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
779147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
779247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
779347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
779447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
779547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
779647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7797cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
779847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
77993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
780047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
78013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
78023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
780347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
78053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7807fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
7808fd6fd07e58e3d37313bec849313ac6e2b92e3957dirkstatic void write_tIME_chunk(Image *image,png_struct *ping,png_info *info,
7809fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  const char *date,ExceptionInfo *exception)
7810fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk{
7811fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  unsigned int
7812fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    day,
7813fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    hour,
7814fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    minute,
7815fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    month,
7816fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    second,
7817fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    year;
7818fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7819fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_time
7820fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ptime;
7821fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7822fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  time_t
7823fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ttime;
7824fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
7825fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (date != (const char *) NULL)
7826fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
7827fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      if (sscanf(date,"%d-%d-%dT%d:%d:%dZ",&year,&month,&day,&hour,&minute,
7828fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          &second) != 6)
7829fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
7830fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
7831fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            "Invalid date format specified for png:tIME","`%s'",
7832fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            image->filename);
7833fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          return;
7834fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
7835fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.year=(png_uint_16) year;
7836fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.month=(png_byte) month;
7837fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.day=(png_byte) day;
7838fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.hour=(png_byte) hour;
7839fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.minute=(png_byte) minute;
7840fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      ptime.second=(png_byte) second;
7841fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
7842fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  else
7843fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  {
7844fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    time(&ttime);
7845fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    png_convert_from_time_t(&ptime,ttime);
7846fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  }
7847fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  png_set_tIME(ping,info,&ptime);
7848fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk}
7849fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
7850b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7851b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
785316ea139d53d867211d3bb0fa859a83de653f687ecristy  const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
78550997332e2c35a821b271d6e7473c01c10dc206adcristy  char
78560997332e2c35a821b271d6e7473c01c10dc206adcristy    im_vers[32],
78570997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_runv[32],
78580997332e2c35a821b271d6e7473c01c10dc206adcristy    libpng_vers[32],
78590997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_runv[32],
78600997332e2c35a821b271d6e7473c01c10dc206adcristy    zlib_vers[32];
78610997332e2c35a821b271d6e7473c01c10dc206adcristy
786216ea139d53d867211d3bb0fa859a83de653f687ecristy  Image
786316ea139d53d867211d3bb0fa859a83de653f687ecristy    *image;
786416ea139d53d867211d3bb0fa859a83de653f687ecristy
786516ea139d53d867211d3bb0fa859a83de653f687ecristy  ImageInfo
786616ea139d53d867211d3bb0fa859a83de653f687ecristy    *image_info;
786716ea139d53d867211d3bb0fa859a83de653f687ecristy
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7881cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7882cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7883e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7884e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
78855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
788639992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
788739992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
78883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
78905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
78915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
78925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
78933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
78943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
78973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
79005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
79015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
79025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7903bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
790758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
790821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
790958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
791058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7911da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7912fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7913d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
79148d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
791539992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7916991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7917918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_iCCP,
7918991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7919918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp    ping_have_sRGB,
7920991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
792126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
792226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
792326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7924a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7925e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
792626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
792726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
792826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
792926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
793026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
793126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
793226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7933fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    ping_exclude_tIME,
7934e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
793526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
793626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
793726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
793826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
79398d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
7940ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp    ping_preserve_iCCP,
79410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
79420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
794382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
79448ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7945d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7946d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79480997332e2c35a821b271d6e7473c01c10dc206adcristy  MemoryInfo
7949af1534a4abd2d6ef7f7e2833b95400301faff3d3cristy    *volatile pixel_info;
79500997332e2c35a821b271d6e7473c01c10dc206adcristy
79513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
79523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
795416ea139d53d867211d3bb0fa859a83de653f687ecristy  PNGErrorInfo
795516ea139d53d867211d3bb0fa859a83de653f687ecristy    error_info;
795616ea139d53d867211d3bb0fa859a83de653f687ecristy
7957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
79620997332e2c35a821b271d6e7473c01c10dc206adcristy    *ping_pixels;
7963d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
79645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7965f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
79660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
79675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
79685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
79695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
79705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
79715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
79725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7973bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
79745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
79755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7982dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7983fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7984f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
79858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
79868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
79878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7988dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7989dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7990dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7991dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7992dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7993dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7995fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
799716ea139d53d867211d3bb0fa859a83de653f687ecristy  image = CloneImage(IMimage,0,0,MagickFalse,exception);
799816ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
799916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image_info == (ImageInfo *) NULL)
800016ea139d53d867211d3bb0fa859a83de653f687ecristy     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
8001b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
8002d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  /* Define these outside of the following "if logging()" block so they will
8003d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   * show in debuggers.
8004d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp   */
8005d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *im_vers='\0';
8006d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
8007d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibVersionText,MaxTextExtent);
8008d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(im_vers,
8009d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp         MagickLibAddendum,MaxTextExtent);
8010ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
8011d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *libpng_vers='\0';
8012d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(libpng_vers,
8013ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         PNG_LIBPNG_VER_STRING,32);
8014ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *libpng_runv='\0';
8015ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(libpng_runv,
8016ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         png_get_libpng_ver(NULL),32);
8017ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
8018d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  *zlib_vers='\0';
8019d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp  (void) ConcatenateMagickString(zlib_vers,
8020ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         ZLIB_VERSION,32);
8021ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  *zlib_runv='\0';
8022ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp  (void) ConcatenateMagickString(zlib_runv,
8023ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp         zlib_version,32);
8024ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp
80258fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (logging != MagickFalse)
8026d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    {
8027d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    IM version     = %s",
8028d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           im_vers);
8029d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Libpng version = %s",
8030d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           libpng_vers);
8031ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(libpng_vers,libpng_runv) != 0)
8032ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8033ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8034ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           libpng_runv);
8035ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8036d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"    Zlib version   = %s",
8037d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp           zlib_vers);
8038ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       if (LocaleCompare(zlib_vers,zlib_runv) != 0)
8039ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       {
8040ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       LogMagickEvent(CoderEvent,GetMagickModule(),"      running with   %s",
8041ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp           zlib_runv);
8042ec0ddbc89d50eda4c550fb76c06d6b7dccd147acglennrp       }
8043d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp    }
8044d0cae2599e87ce432f40fd50ad66439f4281ee64glennrp
80455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
80460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
80475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
80485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
80495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
80505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
80515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
80525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
80545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
80555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
80565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
80575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
80585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
80605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
80615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
80625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
80635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
8064dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
8065dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
8066dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
8067dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8068da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
8069f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp  ping_have_cheap_transparency=MagickFalse;
8070d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
80718d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
807239992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
8073991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
8074918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_iCCP=MagickFalse;
8075991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
8076918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp  ping_have_sRGB=MagickFalse;
8077991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
8078991d11dd9c33e65872778b81aff1347cd2878154glennrp
80790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
80800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
8081a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
8082dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
80830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
80840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
80850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
80860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
80870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
80880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
80890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
8090fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  ping_exclude_tIME=mng_info->ping_exclude_tIME;
8091dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
80920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
80930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
80940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
80950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80968d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
8097ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  ping_preserve_iCCP = mng_info->ping_preserve_iCCP;
80980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
80990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
81000d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
81010d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * i.e., eliminate the ICC profile and set image->rendering_intent.
81020d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * Note that this will not involve any changes to the actual pixels
81030d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * but merely passes information to applications that read the resulting
81040d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   * PNG image.
8105ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8106ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * To do: recognize other variants of the sRGB profile, using the CRC to
8107ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * verify all recognized variants including the 7 already known.
8108ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8109ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Work around libpng16+ rejecting some "known invalid sRGB profiles".
8110ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8111ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Use something other than image->rendering_intent to record the fact
8112ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * that the sRGB profile was found.
8113ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   *
8114ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * Record the ICC version (currently v2 or v4) of the incoming sRGB ICC
8115ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   * profile.  Record the Blackpoint Compensation, if any.
81160d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   */
8117ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp   if (ping_exclude_sRGB == MagickFalse && ping_preserve_iCCP == MagickFalse)
81180d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy   {
81190d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      char
81200d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *name;
81210d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81220d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      const StringInfo
81230d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        *profile;
81240d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81250d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      ResetImageProfileIterator(image);
81260d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
81270d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      {
81280d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        profile=GetImageProfile(image,name);
81290d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81300d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        if (profile != (StringInfo *) NULL)
81310d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          {
81320d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy            if ((LocaleCompare(name,"ICC") == 0) ||
8133ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                (LocaleCompare(name,"ICM") == 0))
8134ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
8135ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp             {
8136ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 int
8137ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   icheck,
8138ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   got_crc=0;
81390d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81400d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8141ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 png_uint_32
8142ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   length,
8143ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   profile_crc=0;
814429a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8145ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 unsigned char
8146ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   *data;
81470d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8148ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                 length=(png_uint_32) GetStringInfoLength(profile);
814929a106ed9ec29e243521b0f2a26c14281de8347fglennrp
8150ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 for (icheck=0; sRGB_info[icheck].len > 0; icheck++)
815129a106ed9ec29e243521b0f2a26c14281de8347fglennrp                 {
8152ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                   if (length == sRGB_info[icheck].len)
8153ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                   {
8154ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (got_crc == 0)
8155ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     {
8156ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8157ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         "    Got a %lu-byte ICC profile (potentially sRGB)",
8158ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                         (unsigned long) length);
81590d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8160ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       data=GetStringInfoDatum(profile);
8161ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       profile_crc=crc32(0,data,length);
81620d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
8163ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8164ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                           "      with crc=%8x",(unsigned int) profile_crc);
8165ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                       got_crc++;
8166ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     }
8167ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp
8168ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                     if (profile_crc == sRGB_info[icheck].crc)
8169ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     {
8170ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8171ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                            "      It is sRGB with rendering intent = %s",
8172ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        Magick_RenderingIntentString_from_PNG_RenderingIntent(
8173ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent));
8174ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        if (image->rendering_intent==UndefinedIntent)
8175ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        {
8176ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          image->rendering_intent=
8177ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          Magick_RenderingIntent_from_PNG_RenderingIntent(
8178ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                             sRGB_info[icheck].intent);
8179ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        }
8180ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_iCCP = MagickTrue;
8181ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_exclude_zCCP = MagickTrue;
8182ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        ping_have_sRGB = MagickTrue;
8183ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                        break;
8184ee7b4c0ec5013e84a2ab2e0fe9c4beaed4b75606glennrp                     }
818529a106ed9ec29e243521b0f2a26c14281de8347fglennrp                   }
81860d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy                 }
8187ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                 if (sRGB_info[icheck].len == 0)
818829a106ed9ec29e243521b0f2a26c14281de8347fglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8189ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                        "    Got a %lu-byte ICC profile not recognized as sRGB",
819029a106ed9ec29e243521b0f2a26c14281de8347fglennrp                        (unsigned long) length);
819129a106ed9ec29e243521b0f2a26c14281de8347fglennrp              }
81920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy          }
81930d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy        name=GetNextImageProfile(image);
81940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy      }
81950d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  }
81960d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy
81978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
81988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
81998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
82008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8201fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
8202fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8203fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
8204fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8205fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
8206fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
8207fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8208fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
8209fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
8210fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8211fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
8212fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
821328af3713c9111a471cc868c787760de89236fa3cglennrp
8214750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  if (image->storage_class == PseudoClass &&
82157e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
8216fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png48 || mng_info->write_png64 ||
8217fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     (mng_info->write_png_colortype != 1 &&
8218fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     mng_info->write_png_colortype != 5)))
82197e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
822016ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
82217e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
82227e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
82237e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
8224c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
822528af3713c9111a471cc868c787760de89236fa3cglennrp    {
8226c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
8227c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
8228c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
8229c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
8230c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8231c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
8232e9ac4c3545df599381509bfa2a60d58971d3c5b8cristy           (void) RelinquishMagickMemory(image->colormap);
8233c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
8234c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
823528af3713c9111a471cc868c787760de89236fa3cglennrp    }
8236bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8237c28acd632b7ea1724a54191d15db932f2e4d25e6glennrp  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
823816ea139d53d867211d3bb0fa859a83de653f687ecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
82390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82403241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
82413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
82423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
82433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
82443241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
824516ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) SyncImage(image,exception);
82463241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8247a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
8248a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
8249a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
8250a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
8251a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8252a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
8253a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8254a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
8255a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
8256a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
8257a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
82588e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
8259cd979955e4249aab3bdd79043718fa3b120239b8dirk  if (image->depth < 4)
826067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
826116ea139d53d867211d3bb0fa859a83de653f687ecristy       register Quantum
82628e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
82638e58efdecda887b08ef730d68290a61081ef2566glennrp
8264aac49630945ded4a68aca4f7c892e18b21afeba8dirk       if (image->depth > 2)
82658e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82668e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
826791d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
82688e58efdecda887b08ef730d68290a61081ef2566glennrp
82698e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
82708e58efdecda887b08ef730d68290a61081ef2566glennrp           {
827116ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
82728e58efdecda887b08ef730d68290a61081ef2566glennrp
827316ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
82748e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
82758e58efdecda887b08ef730d68290a61081ef2566glennrp
82768e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
82778e58efdecda887b08ef730d68290a61081ef2566glennrp             {
827816ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR04PixelRGBA(r);
827916ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
82808e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8281bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
82828e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
82838e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
82848e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82858e58efdecda887b08ef730d68290a61081ef2566glennrp
82868e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
82878e58efdecda887b08ef730d68290a61081ef2566glennrp           {
82883e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
82898e58efdecda887b08ef730d68290a61081ef2566glennrp             {
829091d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
82918e58efdecda887b08ef730d68290a61081ef2566glennrp             }
82928e58efdecda887b08ef730d68290a61081ef2566glennrp           }
82938e58efdecda887b08ef730d68290a61081ef2566glennrp         }
82948e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
82958e58efdecda887b08ef730d68290a61081ef2566glennrp         {
82968e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
829791d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
82988e58efdecda887b08ef730d68290a61081ef2566glennrp
82998e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
83008e58efdecda887b08ef730d68290a61081ef2566glennrp           {
830116ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83028e58efdecda887b08ef730d68290a61081ef2566glennrp
830316ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
83048e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83058e58efdecda887b08ef730d68290a61081ef2566glennrp
83068e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83078e58efdecda887b08ef730d68290a61081ef2566glennrp             {
830816ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR02PixelRGBA(r);
830916ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83108e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8311bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83128e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83138e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83148e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83158e58efdecda887b08ef730d68290a61081ef2566glennrp
83168e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83178e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83183e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83198e58efdecda887b08ef730d68290a61081ef2566glennrp             {
832091d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
83218e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83228e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83238e58efdecda887b08ef730d68290a61081ef2566glennrp         }
83248e58efdecda887b08ef730d68290a61081ef2566glennrp       else
83258e58efdecda887b08ef730d68290a61081ef2566glennrp         {
83268e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
832791d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
83288e58efdecda887b08ef730d68290a61081ef2566glennrp
83298e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
83308e58efdecda887b08ef730d68290a61081ef2566glennrp           {
833116ea139d53d867211d3bb0fa859a83de653f687ecristy             r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
83328e58efdecda887b08ef730d68290a61081ef2566glennrp
833316ea139d53d867211d3bb0fa859a83de653f687ecristy             if (r == (Quantum *) NULL)
83348e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
83358e58efdecda887b08ef730d68290a61081ef2566glennrp
83368e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
83378e58efdecda887b08ef730d68290a61081ef2566glennrp             {
833816ea139d53d867211d3bb0fa859a83de653f687ecristy                LBR01PixelRGBA(r);
833916ea139d53d867211d3bb0fa859a83de653f687ecristy                r+=GetPixelChannels(image);
83408e58efdecda887b08ef730d68290a61081ef2566glennrp             }
8341bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
83428e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
83438e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
83448e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83458e58efdecda887b08ef730d68290a61081ef2566glennrp
83468e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
83478e58efdecda887b08ef730d68290a61081ef2566glennrp           {
83483e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
83498e58efdecda887b08ef730d68290a61081ef2566glennrp             {
835091d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
83518e58efdecda887b08ef730d68290a61081ef2566glennrp             }
83528e58efdecda887b08ef730d68290a61081ef2566glennrp           }
83538e58efdecda887b08ef730d68290a61081ef2566glennrp         }
8354cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
8355cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
835667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
835767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
835870e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
8359a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
83602b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
83612b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
83622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
83632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
83648e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
83652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
83662b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
83672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83683faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
8369cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp  if (image->depth > 8)
8370cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    {
8371cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      /* To do: fill low byte properly */
8372cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp      image->depth=16;
8373cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp    }
8374cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
8375c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
837616ea139d53d867211d3bb0fa859a83de653f687ecristy    if (mng_info->write_png8 || LosslessReduceDepthOK(image,exception) != MagickFalse)
83778640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
83788640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
83798640fb5e9b1094f35f8beab436f81661b8a99448glennrp
8380d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  image_colors = (int) image->colors;
8381d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_opaque = (int) image->colors;
8382d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_transparent = 0;
8383d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  number_semitransparent = 0;
8384d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
8385197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype &&
8386a8036d6466b63ead629795b60772f160cca77c4cglennrp     (mng_info->write_png_colortype > 4 || (mng_info->write_png_depth >= 8 &&
8387a8036d6466b63ead629795b60772f160cca77c4cglennrp     mng_info->write_png_colortype < 4 &&
8388a8036d6466b63ead629795b60772f160cca77c4cglennrp     image->alpha_trait != BlendPixelTrait)))
8389a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8390a8036d6466b63ead629795b60772f160cca77c4cglennrp     /* Avoid the expensive BUILD_PALETTE operation if we're sure that we
8391a8036d6466b63ead629795b60772f160cca77c4cglennrp      * are not going to need the result.
8392a8036d6466b63ead629795b60772f160cca77c4cglennrp      */
8393a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (mng_info->write_png_colortype == 1 ||
8394a8036d6466b63ead629795b60772f160cca77c4cglennrp        mng_info->write_png_colortype == 5)
8395a8036d6466b63ead629795b60772f160cca77c4cglennrp       ping_have_color=MagickFalse;
8396a8036d6466b63ead629795b60772f160cca77c4cglennrp
8397a8036d6466b63ead629795b60772f160cca77c4cglennrp     if (image->alpha_trait == BlendPixelTrait)
8398a8036d6466b63ead629795b60772f160cca77c4cglennrp       {
8399a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_transparent = 2;
8400a8036d6466b63ead629795b60772f160cca77c4cglennrp         number_semitransparent = 1;
8401a8036d6466b63ead629795b60772f160cca77c4cglennrp       }
8402a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
8403a8036d6466b63ead629795b60772f160cca77c4cglennrp
8404197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  if (mng_info->write_png_colortype < 7)
8405a8036d6466b63ead629795b60772f160cca77c4cglennrp  {
8406a8036d6466b63ead629795b60772f160cca77c4cglennrp  /* BUILD_PALETTE
8407a8036d6466b63ead629795b60772f160cca77c4cglennrp   *
8408a8036d6466b63ead629795b60772f160cca77c4cglennrp   * Normally we run this just once, but in the case of writing PNG8
8409e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
8410e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
84118ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
84128ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
84138ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
84148ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
8415c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
841682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
84178ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
841882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
8419d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
842082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
84218ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
8422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
8423a8036d6466b63ead629795b60772f160cca77c4cglennrp    /*
8424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
8425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
8426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
8428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
8429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
8430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
8431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
8432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
84338a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     * If image->alpha_trait is MagickFalse, we ignore the alpha channel
8434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
8435d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
8437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
8438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
8439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
8440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
8441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
8442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
84433c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
8445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
84468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
844716ea139d53d867211d3bb0fa859a83de653f687ecristy   PixelInfo
8448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
8449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
8450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
84518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
845216ea139d53d867211d3bb0fa859a83de653f687ecristy   register const Quantum
845316ea139d53d867211d3bb0fa859a83de653f687ecristy     *s;
8454d6bf1617e99df0272b231855a933a74e99b6578fglennrp
845516ea139d53d867211d3bb0fa859a83de653f687ecristy   register Quantum
845616ea139d53d867211d3bb0fa859a83de653f687ecristy     *q,
8457fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
8458fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
8462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
8464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
8467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
8469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84708a46d827a124555f0c48fb2368ec1bba8e079ab6cristy             "      image->alpha_trait=%.20g",(double) image->alpha_trait);
847103812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
84733c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8474fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
84757ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
84767ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
84788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
847916ea139d53d867211d3bb0fa859a83de653f687ecristy             "        i    (red,green,blue,alpha)");
84802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
84827ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
8483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8488d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
848916ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
84907ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
84912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8492d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
8493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
8495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
8498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
8499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
8500d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
8501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
850216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (int) image->colormap[i].alpha);
8503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8504d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
8505d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
85062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
850983c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8510d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
851116ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
851216ea139d53d867211d3bb0fa859a83de653f687ecristy             "        (zero means unknown)");
85137ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
85148d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
85158d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85168d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
8517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
85187ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
8519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
8520fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
8521fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
8522fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
85232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8524d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
8525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
8526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
85277ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
852816ea139d53d867211d3bb0fa859a83de653f687ecristy       if (q == (Quantum *) NULL)
8529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
853097fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
8531d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
8532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
85338a46d827a124555f0c48fb2368ec1bba8e079ab6cristy           if (image->alpha_trait != BlendPixelTrait ||
853416ea139d53d867211d3bb0fa859a83de653f687ecristy              GetPixelAlpha(image,q) == OpaqueAlpha)
85358d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
85378d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
8539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
854016ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque);
854116ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[0].alpha=OpaqueAlpha;
8542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
8543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8545d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
8546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
854716ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, opaque+i))
8548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8549d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8550d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
855116ea139d53d867211d3bb0fa859a83de653f687ecristy                   if (i ==  (ssize_t) number_opaque && number_opaque < 259)
8552d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
855416ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, opaque+i);
855516ea139d53d867211d3bb0fa859a83de653f687ecristy                       opaque[i].alpha=OpaqueAlpha;
8556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85578d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85588d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
855916ea139d53d867211d3bb0fa859a83de653f687ecristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
85608d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
85628d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
856516ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, transparent);
856616ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.red=(unsigned short)
856716ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,q);
856816ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.green=(unsigned short)
856916ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelGreen(image,q);
857016ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.blue=(unsigned short)
857116ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelBlue(image,q);
857216ea139d53d867211d3bb0fa859a83de653f687ecristy                       ping_trans_color.gray=(unsigned short)
8573972d1c4895c4ee6da1b6745e1bb9cb71ee5d6d08cristy                         GetPixelGray(image,q);
8574d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
857916ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, transparent+i))
8580d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8583d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
858716ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,transparent+i);
8588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
85898d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
85908d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8592d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8593d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8594d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8595d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8596d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
859716ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image,q,semitransparent);
8598d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8599d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
86008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8601d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8602d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
860316ea139d53d867211d3bb0fa859a83de653f687ecristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
860416ea139d53d867211d3bb0fa859a83de653f687ecristy                           && GetPixelAlpha(image,q) ==
860516ea139d53d867211d3bb0fa859a83de653f687ecristy                           semitransparent[i].alpha)
8606d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8607d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8608d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8609d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8610d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8611d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8612d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
861316ea139d53d867211d3bb0fa859a83de653f687ecristy                       GetPixelInfoPixel(image, q, semitransparent+i);
8614d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8615d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
86168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
861716ea139d53d867211d3bb0fa859a83de653f687ecristy           q+=GetPixelChannels(image);
8618d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8619d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
86203c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
86214054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
86224054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8623d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8624d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8625d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8626d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8627c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8628c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8629c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8630c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8631c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8632c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8633c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8634c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8635d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8636d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8637ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8638ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8639ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8640ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8641d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8642d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
864303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
86448e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8645c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8646388a8c871db8f82488f34c4f41fc64a58b8cfbf7glennrp               number_opaque++;
8647c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8648c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8649c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8650c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8651c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8652c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
865303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8654a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8655a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8656a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8657d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8659d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
86603241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8661d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8662d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8663d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8664d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8665d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
86663241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8667d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8668d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8669d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8670d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
86713241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
86728d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
86738d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
86748d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8675fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8676d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8677d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
86780fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         ping_have_non_bw=MagickFalse;
86790fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
868045d4c34ce93ff377b9671844ffa1153b821061f6glennrp         if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
86810fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         {
868296bc620815234aaec28b928df51d1754cbe390dcglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
868396bc620815234aaec28b928df51d1754cbe390dcglennrp              "incompatible colorspace");
86847fb2652ba366fc984d1dbb0c66560b91c57dab78cristy           ping_have_color=MagickTrue;
868598b95773e388844e22c6e4006bb88396b33cf6b4glennrp           ping_have_non_bw=MagickTrue;
86860fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp         }
86870fa2580a52ea729dca17269f8c2b17f93ff263d6glennrp
8688d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8689d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8690d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8691d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8692d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
86936185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
869416ea139d53d867211d3bb0fa859a83de653f687ecristy               if (q == (Quantum *) NULL)
8695d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
86966185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8697e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8698e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8699e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
870016ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
870116ea139d53d867211d3bb0fa859a83de653f687ecristy                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8702e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8703e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8704e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8705e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8706e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
870716ea139d53d867211d3bb0fa859a83de653f687ecristy                 s+=GetPixelChannels(image);
8708e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8709e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8710e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8711e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8712e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8713d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8714d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8715d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
87166185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8717d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8718d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8719d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8720d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
87216185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
872216ea139d53d867211d3bb0fa859a83de653f687ecristy                     if (GetPixelRed(image,s) != 0 &&
872316ea139d53d867211d3bb0fa859a83de653f687ecristy                         GetPixelRed(image,s) != QuantumRange)
8724d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8725d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8726e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8727d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
872816ea139d53d867211d3bb0fa859a83de653f687ecristy                     s+=GetPixelChannels(image);
8729d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8730e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8731d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8732bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8733bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
87344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8735d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8736d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
873716ea139d53d867211d3bb0fa859a83de653f687ecristy         PixelInfo
8738d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8739bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8740d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8741d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8742d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8743d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8744d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8745d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8746d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8747d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8748d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8749d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8750d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
87513241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8752d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8753d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
87543241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8755d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8756d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8757d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8758d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8759d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8760d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8761c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8762c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8763bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8764d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8765d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8766d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8767d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8768d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8769d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8770d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8771d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8772d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8773d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8774d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8775d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8776d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8777d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8778d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8779d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8780d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8781d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8782d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8783d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8784d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8785d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
87863241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8787d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8788d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8789d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8790d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8791d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8792d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8793d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
87946185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8795d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8796d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8797d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8798d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
87992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8800d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8801d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8802d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8803d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8804d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8805d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
880616ea139d53d867211d3bb0fa859a83de653f687ecristy            if (AcquireImageColormap(image,image_colors,exception) ==
8807d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
88083faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
88093faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8810d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8811d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8812d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8813d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8814d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8815d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8816d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8817d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8818d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8819bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8820d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8821d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8822d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8823d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8824fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8825fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8826d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8827d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
882816ea139d53d867211d3bb0fa859a83de653f687ecristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
88293c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
883016ea139d53d867211d3bb0fa859a83de653f687ecristy              if (q == (Quantum *) NULL)
8831d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
88323c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8833d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8834d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8835d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
883603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
88378a46d827a124555f0c48fb2368ec1bba8e079ab6cristy                  if ((image->alpha_trait != BlendPixelTrait ||
883816ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
883916ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].red == GetPixelRed(image,q) &&
884016ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
884116ea139d53d867211d3bb0fa859a83de653f687ecristy                      image->colormap[i].blue == GetPixelBlue(image,q))
88426185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
884316ea139d53d867211d3bb0fa859a83de653f687ecristy                    SetPixelIndex(image,i,q);
8844d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
88456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
884603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
884716ea139d53d867211d3bb0fa859a83de653f687ecristy                q+=GetPixelChannels(image);
8848d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8849d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8850d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8851d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8852d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8853d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8854d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8855d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8856d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8857d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8858d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8859d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8860d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8861d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8862d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8863d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
886416ea139d53d867211d3bb0fa859a83de653f687ecristy                 "       i     (red,green,blue,alpha)");
886583c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8866d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8867d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
886872988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8869d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8870d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8871d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8872d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8873d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8874d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8875d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
887616ea139d53d867211d3bb0fa859a83de653f687ecristy                        (int) image->colormap[i].alpha);
8877d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
88786185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
88796185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
88803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8881d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8882d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8883d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8884d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8885d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
88863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8887d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8888d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
88893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8890d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8891d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8892d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8893d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
889403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8895d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8896d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8897d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
88986185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8899d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8900d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8901d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8902d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
89036185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8904d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8905d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8906d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8907a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8908d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8909d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8910d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8911a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8912d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8913d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8914d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8915d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8916d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8917d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8918d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
89196185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
892003812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
892103812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8922d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
89233c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8924c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8925c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8926fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8927c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8928c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8929c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8930c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8931c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8932c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8933fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8934c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8935130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8936130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8937130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8938c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8939130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8940c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8941c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8942c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8943fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8944c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8945c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
894616ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8947fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
894816ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
8949c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8950fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8951c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8952c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
895316ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
89548ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
895516ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelInfoPixel(image,&image->background_color,r);
895616ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,TransparentAlpha,r);
89578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
89588ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
895916ea139d53d867211d3bb0fa859a83de653f687ecristy                  SetPixelAlpha(image,OpaqueAlpha,r);
896016ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
8961c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8962bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8963c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8964c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8965fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8966c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8967c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8968c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
896916ea139d53d867211d3bb0fa859a83de653f687ecristy                image->colormap[i].alpha =
897016ea139d53d867211d3bb0fa859a83de653f687ecristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
897116ea139d53d867211d3bb0fa859a83de653f687ecristy                    TransparentAlpha : OpaqueAlpha);
8972c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8973c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8974c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8975c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8976c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8977e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8978e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8979e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8980c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8981d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8982d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8983d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8984d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8985d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8986d337164012450d70d62e71cf4a308a29004f7d57glennrp
8987d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8988d337164012450d70d62e71cf4a308a29004f7d57glennrp
898991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8990d337164012450d70d62e71cf4a308a29004f7d57glennrp
8991d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8992d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8993d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8994d337164012450d70d62e71cf4a308a29004f7d57glennrp
8995d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8996d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8997d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8998d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
899916ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9000d337164012450d70d62e71cf4a308a29004f7d57glennrp
900116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9002d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
9003d337164012450d70d62e71cf4a308a29004f7d57glennrp
9004d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
9005d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
900616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
900754cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
900816ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9009d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
9010bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9011d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9012d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
9013d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
9014d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9015d337164012450d70d62e71cf4a308a29004f7d57glennrp
9016d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
9017d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
9018d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
9019d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
9020d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9021d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
90228e58efdecda887b08ef730d68290a61081ef2566glennrp
9023d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
9024d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
902591d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
9026d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
9027d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9028d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
9029d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
9030d337164012450d70d62e71cf4a308a29004f7d57glennrp
903182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
903282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
903382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
903482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
903582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
903682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
903782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
903882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
903991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
904082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
904182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
904282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9043e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
904482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
904582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
904682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
904782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
904882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
904916ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
905082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
905116ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
905282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
905382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
905482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
905582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
905616ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
905716ea139d53d867211d3bb0fa859a83de653f687ecristy                  LBR03RGB(r);
905816ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
905982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
9060bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
906182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
906282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
906382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
906482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
906582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
906682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
906782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
906882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
906982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
907082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9071e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
907282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
907382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
907491d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
907582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
9076d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
9077d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
907882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
9079c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90808ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
9081c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
9082c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9083c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9084c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
9085c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
90868ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
90878ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
90883faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
90893faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
90903faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
90913faa9a3fb01696daaf976d595f492cb530bffb21glennrp
909291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
9093fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9094c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
9095c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9096e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
9097fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9098c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
9099c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9100c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
9101c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
910216ea139d53d867211d3bb0fa859a83de653f687ecristy            r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
91038d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
910416ea139d53d867211d3bb0fa859a83de653f687ecristy            if (r == (Quantum *) NULL)
9105c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
9106c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
9107c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
9108c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
910916ea139d53d867211d3bb0fa859a83de653f687ecristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
911054cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
911116ea139d53d867211d3bb0fa859a83de653f687ecristy              r+=GetPixelChannels(image);
9112c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
9113bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9114c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
9115c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
9116c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9117c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
9118c722dd852e8abe407c2846d39662f7ade9c234deglennrp
9119c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
9120c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
9121c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
9122c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
9123c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9124e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
9125c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
9126c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
912791d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
9128c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
9129c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
9130c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
9131c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
91328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91338ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
91348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
913534ef720923a27004960cbcf4d75a8075445e85d7glennrp      /* Take care of special case with 256 opaque colors + 1 transparent
91368ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
91378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
91388ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
91398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
914034ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
914134ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
914234ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red background colors to 3-3-2-1");
914334ef720923a27004960cbcf4d75a8075445e85d7glennrp
91448ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
91458ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
91468ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
91478ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91488ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
91498ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
9150bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
915134ef720923a27004960cbcf4d75a8075445e85d7glennrp      if (logging != MagickFalse)
915234ef720923a27004960cbcf4d75a8075445e85d7glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
915334ef720923a27004960cbcf4d75a8075445e85d7glennrp            "    Merging two dark red pixel colors to 3-3-2-1");
915434ef720923a27004960cbcf4d75a8075445e85d7glennrp
91558ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
91568ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
91588ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
915916ea139d53d867211d3bb0fa859a83de653f687ecristy          r=GetAuthenticPixels(image,0,y,image->columns,1,exception);
9160bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
916116ea139d53d867211d3bb0fa859a83de653f687ecristy          if (r == (Quantum *) NULL)
91628ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
9163bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91648ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
91658ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
916616ea139d53d867211d3bb0fa859a83de653f687ecristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
916716ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
916816ea139d53d867211d3bb0fa859a83de653f687ecristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
916916ea139d53d867211d3bb0fa859a83de653f687ecristy                GetPixelAlpha(image,r) == OpaqueAlpha)
91708ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
917116ea139d53d867211d3bb0fa859a83de653f687ecristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
91728ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
917316ea139d53d867211d3bb0fa859a83de653f687ecristy            r+=GetPixelChannels(image);
91748ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
9175bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91768ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
91778ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
9178bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
91798ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
91808ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91818ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
91828ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
91838ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
91848ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
91858ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
91868ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
91878ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
91888ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
91898ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
91908ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
91918ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
91928ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
91938ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
91948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
9195fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
9196a8036d6466b63ead629795b60772f160cca77c4cglennrp  }
9197fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
9198fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9199fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
9200fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
9201fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
9202fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
92030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
92040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
92050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
9206d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
92070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
92090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
92100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
92120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
92130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92148d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
9215d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
92160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
92170b206f5daa453dc1035db5890cabc899736dc2d0glennrp
92180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
92190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
9220fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
9221fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
9222fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
92235a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
92245a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
92255a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
9226fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
92275a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
92285a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
9229fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
9230fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
9231fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9232fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
9233fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
9234fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9235fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
9236fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
9237fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
923816ea139d53d867211d3bb0fa859a83de653f687ecristy           register const Quantum
9239fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
9240fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9241fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
9242fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
9243fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
9244fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
924516ea139d53d867211d3bb0fa859a83de653f687ecristy             if (q == (Quantum *) NULL)
9246fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
9247fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9248fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
9249fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
925016ea139d53d867211d3bb0fa859a83de653f687ecristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
925116ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelRed(image,q) ==
925216ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.red &&
925316ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelGreen(image,q) ==
925416ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.green &&
925516ea139d53d867211d3bb0fa859a83de653f687ecristy                     (unsigned short) GetPixelBlue(image,q) ==
925616ea139d53d867211d3bb0fa859a83de653f687ecristy                                     ping_trans_color.blue)
9257fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
9258fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
9259fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
9260fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
9261fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
926216ea139d53d867211d3bb0fa859a83de653f687ecristy                 q+=GetPixelChannels(image);
9263fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
9264bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9265fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
9266fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
9267fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
9268fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9269fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
9270fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
927167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
927267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
927367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
9274fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
927567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
927667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
927767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
927867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
9279fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
928067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
928167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
9282fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
9283fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9284bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
9285fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
9286fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
9287fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
9288fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9289fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
9290fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9291fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
9292fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9293fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
9294fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
9295fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
9296fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
9297fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
9298fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
92993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
93003c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
93013c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
93023c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
9303f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
9304b0a657e13c4aefba39c51292005427b47277869dcristy  image_matte=image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse;
930583c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
930648c20621d4ce02a3833b107f710843d1e524d559glennrp  if (mng_info->write_png_colortype < 5)
9307197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette=image->storage_class == PseudoClass &&
9308197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      image_colors <= 256 && image->colormap != NULL;
9309197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp  else
9310197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp    mng_info->IsPalette = MagickFalse;
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
931252a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
931352a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
931452a479ca718756af72f96e127f8256499ab68f76glennrp    {
931516ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
931616ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
931716ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
931815e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
931916ea139d53d867211d3bb0fa859a83de653f687ecristy          "`%s'",IMimage->filename);
932052a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
932152a479ca718756af72f96e127f8256499ab68f76glennrp    }
932252a479ca718756af72f96e127f8256499ab68f76glennrp
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
932716ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.image=image;
932816ea139d53d867211d3bb0fa859a83de653f687ecristy error_info.exception=exception;
932916ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,&error_info,
9330cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
9331cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
93320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
933416ea139d53d867211d3bb0fa859a83de653f687ecristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,&error_info,
9335cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
93360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
93420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
93500997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=(MemoryInfo *) NULL;
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
9362868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9363cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9365edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
93660997332e2c35a821b271d6e7473c01c10dc206adcristy      if (pixel_info != (MemoryInfo *) NULL)
93670997332e2c35a821b271d6e7473c01c10dc206adcristy        pixel_info=RelinquishVirtualMemory(pixel_info);
9368edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9369edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp      if (quantum_info != (QuantumInfo *) NULL)
9370edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp        quantum_info=DestroyQuantumInfo(quantum_info);
9371edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
937216ea139d53d867211d3bb0fa859a83de653f687ecristy      if (ping_have_blob != MagickFalse)
937316ea139d53d867211d3bb0fa859a83de653f687ecristy          (void) CloseBlob(image);
937416ea139d53d867211d3bb0fa859a83de653f687ecristy      image_info=DestroyImageInfo(image_info);
937516ea139d53d867211d3bb0fa859a83de653f687ecristy      image=DestroyImage(image);
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9378edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9379edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  /* {  For navigation to end of SETJMP-protected block.  Within this
9380edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    block, use png_error() instead of Throwing an Exception, to ensure
9381edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   *    that libpng is able to clean up, and that the semaphore is unlocked.
9382edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   */
9383edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9384868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
9385edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  LockSemaphoreInfo(ping_semaphore);
9386edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
9387edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
9388943b7d3decdd71b57fba7c2fe73fa26f380d692fglennrp#ifdef PNG_BENIGN_ERRORS_SUPPORTED
9389a3a5f956194e91458e2789966ad15308e8f3df47glennrp  /* Allow benign errors */
9390a3a5f956194e91458e2789966ad15308e8f3df47glennrp  png_set_benign_errors(ping, 1);
9391a3a5f956194e91458e2789966ad15308e8f3df47glennrp#endif
9392a3a5f956194e91458e2789966ad15308e8f3df47glennrp
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93969bf97b6c2143eb20c330346b01e82102cc082725glennrp
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
939925024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  {
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
940125024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
940225024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     /* Disable new libpng-1.5.10 feature when writing a MNG because
940325024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      * zero-length PLTE is OK
940425024a6b81adca7509dfd90b03c27dbb42c5889bglennrp      */
940525024a6b81adca7509dfd90b03c27dbb42c5889bglennrp     png_set_check_for_invalid_index (ping, 0);
940625024a6b81adca7509dfd90b03c27dbb42c5889bglennrp# endif
940725024a6b81adca7509dfd90b03c27dbb42c5889bglennrp  }
94082b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
94132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94162b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
94182b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94194e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
94204e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
94212b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9425fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48 || mng_info->write_png64)
9426fd164d2bf84b111e304959af5698757d60e9b8aeglennrp     image_depth=16;
9427fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
94300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
94340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
94370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
94400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9444e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9446e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94488a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        "    image_matte=%.20g",(double) image->alpha_trait);
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94508640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94528640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94548640fb5e9b1094f35f8beab436f81661b8a99448glennrp
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
94565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
9457dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
945826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
946026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
946126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
946216ea139d53d867211d3bb0fa859a83de653f687ecristy  if ((image->resolution.x != 0) && (image->resolution.y != 0) &&
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
9466dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9467dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9471dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
9472823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
947316ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.x+0.5)/2.54);
9474823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
947516ea139d53d867211d3bb0fa859a83de653f687ecristy             (png_uint_32) ((100.0*image->resolution.y+0.5)/2.54);
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9477dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9480dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
948116ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->resolution.x+0.5);
948216ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->resolution.y+0.5);
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9484991d11dd9c33e65872778b81aff1347cd2878154glennrp
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9487dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
948816ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_x_resolution=(png_uint_32) image->resolution.x;
948916ea139d53d867211d3bb0fa859a83de653f687ecristy          ping_pHYs_y_resolution=(png_uint_32) image->resolution.y;
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9491991d11dd9c33e65872778b81aff1347cd2878154glennrp
9492823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
9493823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9494823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
9495823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
9496823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
9497991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
949926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9501a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
950226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
950326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
9504a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9506a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
9507a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
9508a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
9509a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
9510a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
9511a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
95120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9513a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
9514a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
95150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9516a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
9517a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
95180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9519a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
9520a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
95210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9522a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
9523a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
95240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9525a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
9526a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
95270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9528a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
9529a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
9530c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9531c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
95320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
95330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
95353b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
95363b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95373b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
9538c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9539c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
9540c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
95413b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
95423b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95433b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
95443b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
95450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
954726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
95483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
95533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
95540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95551273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9557fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
95580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
95590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
95618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
95628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
95630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
95650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
95660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
95670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
95680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
95700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
9572f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
95730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
95750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
95760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
95770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
95780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
95790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
95800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
958167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
95820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
958367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
958467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
958567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
95860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
95892b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
95908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
95918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
95928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
95935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
959458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
95958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
95960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
95970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
95980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
95990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
96008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
96038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
96040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96062cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
96078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
96080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
96100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
96110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
96148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
96150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96161273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
96174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
96181273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
96191273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
96201273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
96211273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
96224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
96234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
96244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
96250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9627c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9628c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9629c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9630c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9631c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9632c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9633c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
96344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
96360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9637fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png_colortype == 1)
9638fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
9639fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image_matte=MagickFalse;
9640fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
9641fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
9642fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
9643fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png24 || mng_info->write_png48 ||
9644fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 3)
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
96475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9650fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  else if (mng_info->write_png32 || mng_info->write_png64 ||
9651fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype == 7)
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
96545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
96600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
96640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
96665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
96682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
96717c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
96727c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
96737c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96747c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
96753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96777c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96813c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
96820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9683d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
96848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
96850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9686d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
96873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
96893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
96903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9692d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
96945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
96953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
96963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96985aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
96995aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
97005aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
97015aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
97027c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
9703261f64eea2c3a5a9586da65af2c59d2a39b05de0glennrp             image_info->type == UndefinedType)
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
97055aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
97068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
97075aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
97085aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97095aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
97105aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
97115aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97130b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
97145aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97155aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
97165aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
97175aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
97195aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
97205aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
97215aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
97225aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
97245aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
97255aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
97270b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
97285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
97295aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
97305aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
97315aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
97325aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
97330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
97345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
973826c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97398640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
974026c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
97415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
97420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
97430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
97440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
97450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
97460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
97470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9749d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9750d6bf1617e99df0272b231855a933a74e99b6578fglennrp
97515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97538a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait != BlendPixelTrait && ping_have_non_bw == MagickFalse)
97548d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97568640fb5e9b1094f35f8beab436f81661b8a99448glennrp
97575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
975935ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
97605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
97610f111984738842d27d04aed2a3f823d82a943506glennrp
97620f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
97630f111984738842d27d04aed2a3f823d82a943506glennrp           {
97640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9765edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp                png_error(ping,"image has 0 colors");
97660f111984738842d27d04aed2a3f823d82a943506glennrp           }
97670f111984738842d27d04aed2a3f823d82a943506glennrp
976835ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
97695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9770d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9772d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9773d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9774d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9775d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
97760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9777d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9778d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9779d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
97800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9781d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9782d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
97862b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97901a56e9c9268976936eeab9fe97eb664b847e444cglennrp        "    Tentative PNG color type: %s (%.20g)",
97911a56e9c9268976936eeab9fe97eb664b847e444cglennrp        PngColorTypeToString(ping_color_type),
97921a56e9c9268976936eeab9fe97eb664b847e444cglennrp        (double) ping_color_type);
97930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9795e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
97960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9798e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
97990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98013c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
98028640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
98038640fb5e9b1094f35f8beab436f81661b8a99448glennrp
98048640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9805e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
980858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
98114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
98127c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
98137c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
98147c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
98152b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98167c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
98177c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
98187c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
98192b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
98244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
98264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
98274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9828a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
98294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
98307c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
98317c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98327c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
98334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
98364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9838bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
98410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
98434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
98440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
98464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
98470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
98494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
98500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
98524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
98530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
98554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
98560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
98584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
98590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
98614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
98620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
986416ea139d53d867211d3bb0fa859a83de653f687ecristy                (ScaleQuantumToShort(GetPixelInfoIntensity(
98654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
98660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
98680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
98704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9875fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9876fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9877fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9878fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9879fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
98804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98812b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
98824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
98834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
98847c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
98857c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
98860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
98884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
98894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
98904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
98914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
98924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
98934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
98944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
98954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
98964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
98974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
98993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
99005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
99015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
99025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
99035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
99053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99078640fb5e9b1094f35f8beab436f81661b8a99448glennrp
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
99090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99102e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
99120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
991339992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
99158d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
99168d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
991835ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
99190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
99219c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
99220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99237c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
99264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
99284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
99294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
99304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
99314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
99334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
99344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
99354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
99400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9941136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9942d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9943f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
99440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
99465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
99470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
99505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
99515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
99555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
99560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
995735ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9958bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
99595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
99640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
99681a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9974bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
99854bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
99882b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
99909c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
99910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
99939c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
99940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
99969c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
99992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
100005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1000717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1000817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
100133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
100145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
100150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100163d627862fb79aad8a20be4f1587f0b8761db441aglennrp            if (!(mng_info->have_write_global_plte && matte == MagickFalse))
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10018bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
100240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100253b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1002798156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
10028f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
100290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1003039992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
10034d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
100353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10036befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
10037befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
10038befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
100395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
10040befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
100410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1004216ea139d53d867211d3bb0fa859a83de653f687ecristy                while ((one << ping_bit_depth) < (size_t) number_colors)
100435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
100443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
100470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1004858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
100490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
100500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
10051d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
10052d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
100530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10055d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
10056d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
100590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
100600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10061d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
100620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
10063c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
10064c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
10065c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10066c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
10067c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
10068d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
10069d6bf1617e99df0272b231855a933a74e99b6578fglennrp
10070d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
10071d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
10072750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp                       ping_trans_alpha[i]= (png_byte)
1007316ea139d53d867211d3bb0fa859a83de653f687ecristy                         ScaleQuantumToChar(image->colormap[i].alpha);
10074d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
100750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
100760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
100790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10082c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
100833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
100843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
100850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
100894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
100904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
100924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
100934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
100944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
100954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
100964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
100975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
100985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
100995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
101005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
101014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
101024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
101034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
101044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
101064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
101074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
101084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
101094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
101103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
101113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
101123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101134383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
101144383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
101152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
101163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
101173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
101183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
101195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1012535ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
1012635ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
1012735ef824baa82511126ff0072ae30eee0da9c05a3cristy
1012822ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
1013126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1013316ea139d53d867211d3bb0fa859a83de653f687ecristy         ping_background.gray=(png_uint_16) ((maxval/65535.)*
1013416ea139d53d867211d3bb0fa859a83de653f687ecristy           (ScaleQuantumToShort(((GetPixelInfoIntensity(
1013516ea139d53d867211d3bb0fa859a83de653f687ecristy           &image->background_color))) +.5)));
1013616ea139d53d867211d3bb0fa859a83de653f687ecristy
101373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
101388f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1013916ea139d53d867211d3bb0fa859a83de653f687ecristy             "  Setting up bKGD chunk (2)");
1014016ea139d53d867211d3bb0fa859a83de653f687ecristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1014116ea139d53d867211d3bb0fa859a83de653f687ecristy             "      background_color index is %d",
1014216ea139d53d867211d3bb0fa859a83de653f687ecristy             (int) ping_background.index);
101433b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
10144991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
1014526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101473e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101483e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101493e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
101503e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
101513e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101529be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
101533e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
101543e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
101553e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
101563e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101573e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
101583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1015917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1016026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1016126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
101621273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
1016317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
1016417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
1016517a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
1016617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
1016717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1016817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
1016917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10170a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
10171a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
1017217a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
1017317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
1017417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
1017517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
101763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
101770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
101780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
101800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
10181a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1018213d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
10183a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
101840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
101853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
101880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
101900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
101910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
101920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
101930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
10194a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
1019517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
10196d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
101973c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
101983b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
101993b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102003b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
102013c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
102023c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
1020317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
1020426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1020517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
102063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102081a56e9c9268976936eeab9fe97eb664b847e444cglennrp      "    PNG color type: %s (%d)", PngColorTypeToString(ping_color_type),
102091a56e9c9268976936eeab9fe97eb664b847e444cglennrp      ping_color_type);
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
102150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
102170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
102200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
102210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
102230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
102270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102284054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
102294054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
1023010d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
1023110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023210d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
1023310d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
1023410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1023510d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
1023610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10237ef804f5802b3d6517d516556b64fccc5843710b6glennrp        0 or omitted: Use Z_HUFFMAN_ONLY strategy with the
1023810d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
1023910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1024010d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
1024110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1024210d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
1024310d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1024410d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
1024510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1024610d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
1024710d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
1024810d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
10249750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
1025010d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
1025110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1025210d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
1025385dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             a MNG, otherwise "none".  Did not work in IM-6.7.0-9
1025410d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
1025510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1025685dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp        8:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), adaptive
1025785dfe1a0f14d543ecebd2cc0741ba9dcb2fe67bbglennrp             filtering. Unused prior to IM-6.7.0-10, was same as 6
1025810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
10259ef804f5802b3d6517d516556b64fccc5843710b6glennrp        9:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), no PNG filters
102601868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
1026110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1026210d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
1026310d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
1026416ea139d53d867211d3bb0fa859a83de653f687ecristy    strategy are possible.  This will be addressed soon in a
1026516ea139d53d867211d3bb0fa859a83de653f687ecristy    release that accomodates "-define png:compression-strategy", etc.
1026610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1026710d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
1026810d739ef54404090a55cb8977fc51f85cafa81a5glennrp
1026929dd80efe8d7489d5f689a8a723454e684f92a8fdirk  quality=image_info->quality == UndefinedCompressionQuality ? 75UL :
1027029dd80efe8d7489d5f689a8a723454e684f92a8fdirk     image_info->quality;
102710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102721868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
102731868258559ddf946fa73ef72dd43507b32623705glennrp    {
102741868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
102751868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
102761868258559ddf946fa73ef72dd43507b32623705glennrp    }
10277750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp
102781868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
102813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
102823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
102840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102851868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
102861868258559ddf946fa73ef72dd43507b32623705glennrp    }
102870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102881868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
102891868258559ddf946fa73ef72dd43507b32623705glennrp    {
102901868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
10291a24b245fac14ef0617d691de0942697f2eb31b05glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
10292a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy=Z_RLE+1;
10293a24b245fac14ef0617d691de0942697f2eb31b05glennrp#else
10294a24b245fac14ef0617d691de0942697f2eb31b05glennrp          mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
10295a24b245fac14ef0617d691de0942697f2eb31b05glennrp#endif
102963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102981868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
102991868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
103001868258559ddf946fa73ef72dd43507b32623705glennrp
103011868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
103023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103031868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
103043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103051868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
103061868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
103070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103081868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
103091868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103101868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
103111868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
103120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103131868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103141868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
103153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103164054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
1031710d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103181868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
103194054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
103204054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
103211868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103221868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
103231868258559ddf946fa73ef72dd43507b32623705glennrp        else
103241868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103251868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
103261868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103291868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
103301868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
103310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103321868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
103331868258559ddf946fa73ef72dd43507b32623705glennrp    {
103341868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
103351868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
103361868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
103371868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103381868258559ddf946fa73ef72dd43507b32623705glennrp      else
103391868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
103401868258559ddf946fa73ef72dd43507b32623705glennrp     }
103414054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
103421868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
103431868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
1034410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
103451868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
103461868258559ddf946fa73ef72dd43507b32623705glennrp    {
103471868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
103481868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
103491868258559ddf946fa73ef72dd43507b32623705glennrp      {
103501868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
103511868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
103521868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
103531868258559ddf946fa73ef72dd43507b32623705glennrp      }
103541868258559ddf946fa73ef72dd43507b32623705glennrp#endif
103554054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103561868258559ddf946fa73ef72dd43507b32623705glennrp    }
103570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103581868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
103591868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
103600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103611868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
103621868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
103631868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
103640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103651868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
103661868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
103671868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
103682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10369dec72c9b492c176af9813be3105518e91835ed37glennrp  ping_interlace_method=image_info->interlace != NoInterlace;
10370dec72c9b492c176af9813be3105518e91835ed37glennrp
10371dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_mng)
10372dec72c9b492c176af9813be3105518e91835ed37glennrp    png_set_sig_bytes(ping,8);
10373dec72c9b492c176af9813be3105518e91835ed37glennrp
10374dec72c9b492c176af9813be3105518e91835ed37glennrp  /* Bail out if cannot meet defined png:bit-depth or png:color-type */
10375dec72c9b492c176af9813be3105518e91835ed37glennrp
10376dec72c9b492c176af9813be3105518e91835ed37glennrp  if (mng_info->write_png_colortype != 0)
10377dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10378dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
10379dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10380dec72c9b492c176af9813be3105518e91835ed37glennrp         {
10381dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
10382dec72c9b492c176af9813be3105518e91835ed37glennrp
10383dec72c9b492c176af9813be3105518e91835ed37glennrp           if (ping_bit_depth < 8)
10384dec72c9b492c176af9813be3105518e91835ed37glennrp             ping_bit_depth=8;
10385dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10386dec72c9b492c176af9813be3105518e91835ed37glennrp
10387dec72c9b492c176af9813be3105518e91835ed37glennrp     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
10388dec72c9b492c176af9813be3105518e91835ed37glennrp       if (ping_have_color != MagickFalse)
10389dec72c9b492c176af9813be3105518e91835ed37glennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
10390dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10391dec72c9b492c176af9813be3105518e91835ed37glennrp
10392dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_need_colortype_warning != MagickFalse ||
10393dec72c9b492c176af9813be3105518e91835ed37glennrp     ((mng_info->write_png_depth &&
10394dec72c9b492c176af9813be3105518e91835ed37glennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
10395dec72c9b492c176af9813be3105518e91835ed37glennrp     (mng_info->write_png_colortype &&
10396dec72c9b492c176af9813be3105518e91835ed37glennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
10397dec72c9b492c176af9813be3105518e91835ed37glennrp      mng_info->write_png_colortype != 7 &&
10398dec72c9b492c176af9813be3105518e91835ed37glennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
10399dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10400dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10401dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10402dec72c9b492c176af9813be3105518e91835ed37glennrp          if (ping_need_colortype_warning != MagickFalse)
10403dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10404dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10405dec72c9b492c176af9813be3105518e91835ed37glennrp                 "  Image has transparency but tRNS chunk was excluded");
10406dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10407dec72c9b492c176af9813be3105518e91835ed37glennrp
10408dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_depth)
10409dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10410dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10411dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:bit-depth=%u, Computed depth=%u",
10412dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_depth,
10413dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_bit_depth);
10414dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10415dec72c9b492c176af9813be3105518e91835ed37glennrp
10416dec72c9b492c176af9813be3105518e91835ed37glennrp          if (mng_info->write_png_colortype)
10417dec72c9b492c176af9813be3105518e91835ed37glennrp            {
10418dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10419dec72c9b492c176af9813be3105518e91835ed37glennrp                  "  Defined png:color-type=%u, Computed color type=%u",
10420dec72c9b492c176af9813be3105518e91835ed37glennrp                  mng_info->write_png_colortype-1,
10421dec72c9b492c176af9813be3105518e91835ed37glennrp                  ping_color_type);
10422dec72c9b492c176af9813be3105518e91835ed37glennrp            }
10423dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10424dec72c9b492c176af9813be3105518e91835ed37glennrp
10425dec72c9b492c176af9813be3105518e91835ed37glennrp      png_warning(ping,
10426dec72c9b492c176af9813be3105518e91835ed37glennrp        "Cannot write image with defined png:bit-depth or png:color-type.");
10427dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10428dec72c9b492c176af9813be3105518e91835ed37glennrp
10429dec72c9b492c176af9813be3105518e91835ed37glennrp  if (image_matte != MagickFalse && image->alpha_trait != BlendPixelTrait)
10430dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10431dec72c9b492c176af9813be3105518e91835ed37glennrp      /* Add an opaque matte channel */
10432dec72c9b492c176af9813be3105518e91835ed37glennrp      image->alpha_trait = BlendPixelTrait;
10433dec72c9b492c176af9813be3105518e91835ed37glennrp      (void) SetImageAlpha(image,OpaqueAlpha,exception);
10434dec72c9b492c176af9813be3105518e91835ed37glennrp
10435dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10436dec72c9b492c176af9813be3105518e91835ed37glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10437dec72c9b492c176af9813be3105518e91835ed37glennrp          "  Added an opaque matte channel");
10438dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10439dec72c9b492c176af9813be3105518e91835ed37glennrp
10440dec72c9b492c176af9813be3105518e91835ed37glennrp  if (number_transparent != 0 || number_semitransparent != 0)
10441dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10442dec72c9b492c176af9813be3105518e91835ed37glennrp      if (ping_color_type < 4)
10443dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10444dec72c9b492c176af9813be3105518e91835ed37glennrp           ping_have_tRNS=MagickTrue;
10445dec72c9b492c176af9813be3105518e91835ed37glennrp           if (logging != MagickFalse)
10446dec72c9b492c176af9813be3105518e91835ed37glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10447dec72c9b492c176af9813be3105518e91835ed37glennrp               "  Setting ping_have_tRNS=MagickTrue.");
10448dec72c9b492c176af9813be3105518e91835ed37glennrp        }
10449dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10450dec72c9b492c176af9813be3105518e91835ed37glennrp
10451dec72c9b492c176af9813be3105518e91835ed37glennrp  if (logging != MagickFalse)
10452dec72c9b492c176af9813be3105518e91835ed37glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10453dec72c9b492c176af9813be3105518e91835ed37glennrp      "  Writing PNG header chunks");
10454dec72c9b492c176af9813be3105518e91835ed37glennrp
10455dec72c9b492c176af9813be3105518e91835ed37glennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
10456dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_bit_depth,ping_color_type,
10457dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_interlace_method,ping_compression_method,
10458dec72c9b492c176af9813be3105518e91835ed37glennrp               ping_filter_method);
10459dec72c9b492c176af9813be3105518e91835ed37glennrp
10460dec72c9b492c176af9813be3105518e91835ed37glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
10461dec72c9b492c176af9813be3105518e91835ed37glennrp    {
10462dec72c9b492c176af9813be3105518e91835ed37glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
10463dec72c9b492c176af9813be3105518e91835ed37glennrp
10464dec72c9b492c176af9813be3105518e91835ed37glennrp      if (logging != MagickFalse)
10465dec72c9b492c176af9813be3105518e91835ed37glennrp        {
10466dec72c9b492c176af9813be3105518e91835ed37glennrp          for (i=0; i< (ssize_t) number_colors; i++)
10467dec72c9b492c176af9813be3105518e91835ed37glennrp          {
10468dec72c9b492c176af9813be3105518e91835ed37glennrp            if (i < ping_num_trans)
10469dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10470dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10471dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10472dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10473dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10474dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue,
10475dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10476dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) ping_trans_alpha[i]);
10477dec72c9b492c176af9813be3105518e91835ed37glennrp             else
10478dec72c9b492c176af9813be3105518e91835ed37glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10479dec72c9b492c176af9813be3105518e91835ed37glennrp                "     PLTE[%d] = (%d,%d,%d)",
10480dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) i,
10481dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].red,
10482dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].green,
10483dec72c9b492c176af9813be3105518e91835ed37glennrp                      (int) palette[i].blue);
10484dec72c9b492c176af9813be3105518e91835ed37glennrp           }
10485dec72c9b492c176af9813be3105518e91835ed37glennrp         }
10486dec72c9b492c176af9813be3105518e91835ed37glennrp    }
10487dec72c9b492c176af9813be3105518e91835ed37glennrp
104880d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
104890d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  if (ping_exclude_sRGB != MagickFalse ||
104903d627862fb79aad8a20be4f1587f0b8761db441aglennrp     (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
104910d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy  {
104920d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    if ((ping_exclude_tEXt == MagickFalse ||
104930d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       ping_exclude_zTXt == MagickFalse) &&
104940d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy       (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
10495c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
10496c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
10497c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
104983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10499c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
105000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10501c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
10502c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
10503c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
10504c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
10505c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
1050626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
10507c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
10508c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
10509c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
10510ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10511ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                          "  Setting up iCCP chunk");
10512ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
1051316ea139d53d867211d3bb0fa859a83de653f687ecristy                       png_set_iCCP(ping,ping_info,(png_charp) name,0,
10514e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
10515c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
10516e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
10517e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
10518e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
10519c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
10520918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                       ping_have_iCCP = MagickTrue;
10521c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
1052226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
105230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10524c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10526c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
10527c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
10528ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10529ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                      "  Setting up zTXT chunk with uuencoded ICC");
10530cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
10531c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
10532c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
10533c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
10534ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp                  ping_have_iCCP = MagickTrue;
10535c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
10536c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
105370b206f5daa453dc1035db5890cabc899736dc2d0glennrp
10538c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
10539c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10540c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
105410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10542c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
10543c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
105440d57eecc316d3f57bd2c77ebbda7fc5fc95f2523cristy    }
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
10549ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      ping_have_iCCP != MagickTrue &&
10550ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      (ping_have_sRGB != MagickFalse ||
10551ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp      png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1055326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
1055426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1055526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
1055626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
1055726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
1055826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
1055926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1056026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
105610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1056226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
10563cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
10564cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
10565918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp
10566918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB = MagickTrue;
1056726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1056926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
105705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105732cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
10574918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_iCCP == MagickFalse &&
10575918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp          ping_have_sRGB == MagickFalse &&
105762cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
1057726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
1057826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
105883b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1059126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
105922b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
10593918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp      if (ping_exclude_cHRM == MagickFalse && ping_have_sRGB == MagickFalse)
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1059526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
1059626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
1059726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
1059826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
1059926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
10600918b9dc4bb00c06632ccc6169ea05a828f7b6fc1glennrp                Note: if cHRM+gAMA == sRGB write sRGB instead.
1060126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
1060226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
1060326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
1060426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
1060526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
1060626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
1060726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1060826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
1060926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
1061026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
1061126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
1061226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1061326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
1061426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1061526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
1061626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1061726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
1061826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
1061926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
1062026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10622dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1062326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1062426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1062526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10626c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1062726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
106288fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10629c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10630c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10631c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10632c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10633c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10634c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10635c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10636c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10637c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10638c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10639c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10640c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10641c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10642c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1064326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10644991d11dd9c33e65872778b81aff1347cd2878154glennrp
1064526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10646dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1064726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1064826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1064926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1065026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1065126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1065226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10653823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
106548fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp          if (logging != MagickFalse)
10655823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10656823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10657823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10658823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10659823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10660823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10661823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10662823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10663823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10664823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10665823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10666823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10667823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1066826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10669dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10670dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10671dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
106724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10673dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1067426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1067526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1067626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1067726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10678dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1067926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1068026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1068126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1068226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1068326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10684dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10685dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10686dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10687fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#if defined(PNG_tIME_SUPPORTED)
10688fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  if (ping_exclude_tIME == MagickFalse)
10689fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    {
10690fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      const char
10691fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        *timestamp;
10692fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
10693fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      timestamp=GetImageOption(image_info,"png:tIME");
10694fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      if (timestamp != (const char *) NULL)
10695fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        write_tIME_chunk(image,ping,ping_info,timestamp,exception);
10696fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      else
10697fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        {
10698fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          if (image->taint == MagickFalse)
10699fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk            timestamp=GetImageProperty(image,"png:tIME",exception);
10700fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          write_tIME_chunk(image,ping,ping_info,timestamp,exception);
10701fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        }
10702fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    }
10703fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk#endif
10704fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
10705da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10706da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
1070716ea139d53d867211d3bb0fa859a83de653f687ecristy    if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
10708da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10709da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10710da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10711da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10712da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10713da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10715991d11dd9c33e65872778b81aff1347cd2878154glennrp
1071639992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10717991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
107183b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
107190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
107220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10723991d11dd9c33e65872778b81aff1347cd2878154glennrp
107240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
107250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
107260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
107270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
107280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10729991d11dd9c33e65872778b81aff1347cd2878154glennrp
107300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
107310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
107320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
107330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
107340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
107350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
107360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107373b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
107380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
107390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10740c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
107410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
107420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
107430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
107440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
107450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
107460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10747991d11dd9c33e65872778b81aff1347cd2878154glennrp
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10749cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10750da8f3a7bfddac2680a3069a490db541e7944edafglennrp
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10752991d11dd9c33e65872778b81aff1347cd2878154glennrp
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10754cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1075626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
107594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1076026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1076126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1076226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1076326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1076426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1076526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1076603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1076726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1076826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1076926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1077026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1077126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1077226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
107769c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
107789c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
107803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10787b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10788b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
107897202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10791b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10793b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10795b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10796b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10797b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
107980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10799b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10801b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
108020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10803b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10804b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108063b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
108073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10809b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10810b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
108110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10812b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10813e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108150997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=AcquireVirtualMemory(rowbytes,sizeof(*ping_pixels));
108160997332e2c35a821b271d6e7473c01c10dc206adcristy  if (pixel_info == (MemoryInfo *) NULL)
10817edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Allocation of memory for pixels failed");
108180997332e2c35a821b271d6e7473c01c10dc206adcristy  ping_pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
108190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10823ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10824ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10825edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    png_error(ping,"Memory allocation for quantum_info failed");
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
108284b840d7930c24dbb98f8b9926b8f09f1e1b98970glennrp  (void) SetQuantumEndian(image,quantum_info,MSBEndian);
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
108308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10832fd164d2bf84b111e304959af5698757d60e9b8aeglennrp       !mng_info->write_png48 && !mng_info->write_png64 &&
108338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
108348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
108368d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
108378d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
1084016ea139d53d867211d3bb0fa859a83de653f687ecristy      register const Quantum
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
108420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10849bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10851d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
108523b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108533b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10854a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
1085516ea139d53d867211d3bb0fa859a83de653f687ecristy          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
108560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1085716ea139d53d867211d3bb0fa859a83de653f687ecristy          if (p == (const Quantum *) NULL)
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
108590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1086216ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1086316ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,GrayQuantum,ping_pixels,exception);
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10869bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10870cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1087716ea139d53d867211d3bb0fa859a83de653f687ecristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
1087816ea139d53d867211d3bb0fa859a83de653f687ecristy                quantum_info,RedQuantum,ping_pixels,exception);
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10882bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10883cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
108850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10887b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10888b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
108890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10890cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
10904fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png48 && !mng_info->write_png64 &&
10905fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          !mng_info->write_png32) && (image_matte != MagickFalse ||
10906fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
10907fd164d2bf84b111e304959af5698757d60e9b8aeglennrp          (mng_info->IsPalette) && ping_have_color == MagickFalse)
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1090916ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
109108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
109110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10915bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1091716ea139d53d867211d3bb0fa859a83de653f687ecristy            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
109182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1091916ea139d53d867211d3bb0fa859a83de653f687ecristy            if (p == (const Quantum *) NULL)
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
109212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
1092516ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1092616ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,GrayQuantum,ping_pixels,exception);
109272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
1092916ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1093016ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RedQuantum,ping_pixels,exception);
109312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
109338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10938b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
109393b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10940b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
109422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1094316ea139d53d867211d3bb0fa859a83de653f687ecristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
1094416ea139d53d867211d3bb0fa859a83de653f687ecristy                  quantum_info,GrayAlphaQuantum,ping_pixels,exception);
10945b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
109462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109473b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10948b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
109502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10951cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
109558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
109568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
109578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
109588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
109598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
109608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
109618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
109620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1096516ea139d53d867211d3bb0fa859a83de653f687ecristy          register const Quantum
109668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
109670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10970fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            if ((image_depth > 8) ||
10971fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 ||
109728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
10973fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 ||
10974fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png64 ||
10975fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
109768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
109778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10978b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
10979862a33cdfa342ec7df3a7c4b4b46def7c45712b3cristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
109802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1098116ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
109828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
109832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
109858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
109868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
1098716ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1098816ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,RedQuantum,ping_pixels,exception);
109892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
1099116ea139d53d867211d3bb0fa859a83de653f687ecristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
1099216ea139d53d867211d3bb0fa859a83de653f687ecristy                        quantum_info,GrayQuantum,ping_pixels,exception);
109938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
109942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
109958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
109968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1099716ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10998cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
1099916ea139d53d867211d3bb0fa859a83de653f687ecristy                      exception);
110002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
110028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
110048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
110052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
1100716ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1100816ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBAQuantum,ping_pixels,exception);
110092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
1101116ea139d53d867211d3bb0fa859a83de653f687ecristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
1101216ea139d53d867211d3bb0fa859a83de653f687ecristy                    quantum_info,RGBQuantum,ping_pixels,exception);
110132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110143b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
11015b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
110172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11018cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
11019b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
110208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
11023fd164d2bf84b111e304959af5698757d60e9b8aeglennrp            /* not ((image_depth > 8) ||
11024fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png24 || mng_info->write_png32 ||
11025fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                mng_info->write_png48 || mng_info->write_png64 ||
11026fd164d2bf84b111e304959af5698757d60e9b8aeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))
11027fd164d2bf84b111e304959af5698757d60e9b8aeglennrp             */
110288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
110298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
110308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
110318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
110328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
110338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
110352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
110378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
110388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
110392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
110418640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
110428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
110438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
110452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1104616ea139d53d867211d3bb0fa859a83de653f687ecristy                p=GetVirtualPixels(image,0,y,image->columns,1, exception);
110472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1104816ea139d53d867211d3bb0fa859a83de653f687ecristy                if (p == (const Quantum *) NULL)
110498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1105244757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
110534bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
110544bf89731a90c6e03598950223e19e7be7b95d630glennrp
1105516ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1105616ea139d53d867211d3bb0fa859a83de653f687ecristy                       quantum_info,GrayQuantum,ping_pixels,exception);
1105744757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
110582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
110608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
110618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
110628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
110642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1106516ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
11066cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
1106716ea139d53d867211d3bb0fa859a83de653f687ecristy                         exception);
110688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
110692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
110718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
1107216ea139d53d867211d3bb0fa859a83de653f687ecristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
1107316ea139d53d867211d3bb0fa859a83de653f687ecristy                      quantum_info,IndexQuantum,ping_pixels,exception);
110742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110755eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
110765eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
110775eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110781a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
110795eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
110805eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110815eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
110825eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
110835eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
110848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
11085cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
110868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
110878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
110882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
110898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
110908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
110918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
110928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
110938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
110948640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
110988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
11099b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
11100b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11105b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
111060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11108e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
111090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11111e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
111120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111165d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:bit-depth: %d",mng_info->write_png_depth);
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
111210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111255d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy            "    Defined png:color-type: %d",mng_info->write_png_colortype-1);
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
111270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
111300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
111333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11135a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11137823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
111383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1113926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1114026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1114126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1114226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1114326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1114426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
111452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1114616ea139d53d867211d3bb0fa859a83de653f687ecristy      value=GetImageProperty(image,property,exception);
11147a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11148e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      /* Don't write any "png:" or "jpeg:" properties; those are just for
11149e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       * "identify" or for passing through to another JPEG
11150e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp       */
11151e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp      if ((LocaleNCompare(property,"png:",4) != 0 &&
11152a3d5f0e19b5d325c69100fcd14fb174a581ee599glennrp           LocaleNCompare(property,"jpeg:",5) != 0) &&
11153e4d5fafd9fbdf0985a964fe9efee73d5d37ccd44glennrp
11154a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11155a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
11156a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
11157823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
11158a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
11159a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
11160a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
11161a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
11162a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1116326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
11164c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
11165c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
11166a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy
11167ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp#if PNG_LIBPNG_VER >= 10400
11168a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,
11169a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy                 (png_alloc_size_t) sizeof(png_text));
11170a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#else
11171a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy            text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
11172a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy#endif
11173c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
11174c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
11175c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
111762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11177c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
11178c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
111792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11180c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
11181c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
111822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11183c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1118426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
11185c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
11186c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
11187c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
11188c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1118926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
111902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11191c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
11192c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
11193c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11194c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
11195c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11196c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11197cbc9215c23fce410bf0bea825dee908c15271bb3glennrp                  "    keyword: '%s'",text[0].key);
11198c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
11199c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
11200c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
11201c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
11202c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1120326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1120426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1120526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
11209cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
112140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
112160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
112205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
112215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1123103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
112425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
112455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
112473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
112510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
112533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
112543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
112563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
11257edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
112580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
112613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
112633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
112643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112650997332e2c35a821b271d6e7473c01c10dc206adcristy  pixel_info=RelinquishVirtualMemory(pixel_info);
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1126716ea139d53d867211d3bb0fa859a83de653f687ecristy  if (ping_have_blob != MagickFalse)
1126816ea139d53d867211d3bb0fa859a83de653f687ecristy     (void) CloseBlob(image);
1126916ea139d53d867211d3bb0fa859a83de653f687ecristy
1127016ea139d53d867211d3bb0fa859a83de653f687ecristy  image_info=DestroyImageInfo(image_info);
1127116ea139d53d867211d3bb0fa859a83de653f687ecristy  image=DestroyImage(image);
1127216ea139d53d867211d3bb0fa859a83de653f687ecristy
11273b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
11274b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
11275b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
11276b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
1127716ea139d53d867211d3bb0fa859a83de653f687ecristy  (void) SetImageProperty(IMimage,"png:bit-depth-written",s,exception);
11278b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
112820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11283868fff35aea4233c40dca33989293cb5bc91601aglennrp#ifdef IMPNG_SETJMP_NOT_THREAD_SAFE
11284edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp  UnlockSemaphoreInfo(ping_semaphore);
11285edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp#endif
11286edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
11287edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp   /* }  for navigation to beginning of SETJMP-protected block. Revert to
11288edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    *    Throwing an Exception when an error occurs.
11289edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp    */
11290edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
11293edaa0389d5b58b8460dee2d1e585985ff0d80d31glennrp
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
113113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1131416ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1131516ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
113203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
113223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1132316ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1132416ea139d53d867211d3bb0fa859a83de653f687ecristy%
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
113283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
113303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
113315d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%  pseudo-formats which are subsets of png:
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113335a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
113345a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
113353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
113363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
113375a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
113385a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
11339e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
11340130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
11341130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
11342130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
11343e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
11344e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
11345e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
113465a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
113475a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
113495a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
113505a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
113515a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
113523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
113555a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
113565a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
113575a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
113585a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
113595a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
113603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
113623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
113640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
113655a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
113665a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
113673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11368fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG48:   A 16-bit per sample RGB PNG datastream is written.  The tRNS
11369fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               chunk can be present to convey binary transparency by naming
11370fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               one of the colors as transparent.  If the image has more
11371fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               than one transparent color, has semitransparent pixels, or
11372fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               has an opaque pixel with the same RGB components as the
11373fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparent color, an image is not written.
11374fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
11375fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%    o PNG64:   A 16-bit per sample RGBA PNG is written.  Partial
11376fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               transparency is permitted, i.e., the alpha sample for
11377fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               each pixel can have any value from 0 to 65535. The alpha
11378fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               channel is present even if the image is fully opaque.
11379fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%
113805830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%    o PNG00:   A PNG that inherits its colortype and bit-depth from the input
113815830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               image, if the input was a PNG, is written.  If these values
113825830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               cannot be found, then "PNG00" falls back to the regular "PNG"
113835830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%               format.
113845830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp%
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
11388bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
11389bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
11390bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
114013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
114043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
114063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
114073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11408fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               If the image cannot be written without loss with the
11409fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               requested bit-depth and color-type, a PNG file will not
11410fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               be written, a warning will be issued, and the encoder will
11411fd164d2bf84b111e304959af5698757d60e9b8aeglennrp%               return MagickFalse.
114125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
114165a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1141716ea139d53d867211d3bb0fa859a83de653f687ecristy%  or transparency limitations.
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
114203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
114243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
114273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
114293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
11432bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
11433bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
114343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
11438bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
114393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11440bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
114413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
114430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
11444d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
114450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
114460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
114470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
11448cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
114490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
11450d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
11451d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
114525d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy%      requested via the "-define png:bit-depth=N" option.
11453d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
11454d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
11455d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
11456d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
114570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
1146116ea139d53d867211d3bb0fa859a83de653f687ecristy  Image *image,ExceptionInfo *exception)
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1146421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1146521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1146621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
114713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
114733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
114765c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
114775c7cf4e469a4dad7e277783749155932252c52dfglennrp
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11486fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1149173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
114920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
114950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
11501a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
115053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
115083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
11509fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
11510fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
115113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11512092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:format");
115135a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value == (char *) NULL)
115145a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp    if (LocaleCompare(image_info->magick,"PNG00") == 0)
11515b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
115165a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp  if (value != (char *) NULL || LocaleCompare(image_info->magick,"PNG00") == 0)
11517b381a2618e8bb9e1e76299676711d0ec1063feabglennrp    {
11518f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11519f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp         "  Format=%s",value);
11520f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11521fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png8 = MagickFalse;
11522fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png24 = MagickFalse;
11523fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png32 = MagickFalse;
11524fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png48 = MagickFalse;
11525fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png64 = MagickFalse;
11526fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11527b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      if (LocaleCompare(value,"png8") == 0)
11528b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png8 = MagickTrue;
11529b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11530b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png24") == 0)
11531b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png24 = MagickTrue;
11532b381a2618e8bb9e1e76299676711d0ec1063feabglennrp
11533b381a2618e8bb9e1e76299676711d0ec1063feabglennrp      else if (LocaleCompare(value,"png32") == 0)
11534b381a2618e8bb9e1e76299676711d0ec1063feabglennrp        mng_info->write_png32 = MagickTrue;
11535fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11536fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png48") == 0)
11537fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png48 = MagickTrue;
11538fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11539fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else if (LocaleCompare(value,"png64") == 0)
11540fd164d2bf84b111e304959af5698757d60e9b8aeglennrp        mng_info->write_png64 = MagickTrue;
115415830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115425a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp      else if ((LocaleCompare(value,"png00") == 0) ||
115435a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp         LocaleCompare(image_info->magick,"PNG00") == 0)
115445830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        {
115453398b5b62521b49754d9391aae9e4511857bd63bglennrp          /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig. */
115463398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.bit-depth-orig",exception);
11547f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11548f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11549f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11550f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11551f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited bit depth=%s",value);
11552f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11553f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"1") == 0)
11554f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 1;
11555f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115565a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"2") == 0)
11557f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 2;
11558f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115595a4989dda1dc69f5b48487088bcc68b78fc4f322glennrp              else if (LocaleCompare(value,"4") == 0)
11560f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 4;
11561f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11562f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"8") == 0)
11563f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 8;
11564f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11565f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"16") == 0)
11566f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_depth = 16;
11567f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
11568f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
115693398b5b62521b49754d9391aae9e4511857bd63bglennrp          value=GetImageProperty(image,"png:IHDR.color-type-orig",exception);
11570f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11571f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp          if (value != (char *) NULL)
11572f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            {
11573f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11574f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                 "  png00 inherited color type=%s",value);
11575f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11576f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              if (LocaleCompare(value,"0") == 0)
11577f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 1;
11578f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11579f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"2") == 0)
11580f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 3;
11581f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11582f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"3") == 0)
11583f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 4;
11584f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11585f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"4") == 0)
11586f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 5;
11587f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp
11588f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp              else if (LocaleCompare(value,"6") == 0)
11589f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp                mng_info->write_png_colortype = 7;
11590f70c4d28c683ec8266f6a12ce6a7bf6c8a68b798glennrp            }
115915830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp        }
115925830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp    }
115935830fbc206b62351c31ade8fbe8cbaf259e7036eglennrp
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115969c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
115979c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
115989c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
115993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
116023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116039c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
116049c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116059c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
116060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116078a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      if (image->alpha_trait == BlendPixelTrait)
1160816ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorMatteType,exception);
116090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116109c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
1161116ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) SetImageType(image,TrueColorType,exception);
116120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1161316ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116189c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
116199c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
116209c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
1162147da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
116220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11623197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      (void) SetImageType(image,TrueColorMatteType,exception);
1162416ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SyncImage(image,exception);
116253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11627fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png48)
11628fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11629fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 2 */ 3;
11630fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11631fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
11632fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
116334dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      if (image->alpha_trait == BlendPixelTrait)
116344dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorMatteType,exception);
11635fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11636fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      else
116374dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp        (void) SetImageType(image,TrueColorType,exception);
11638fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
116394dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11640fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11641fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11642fd164d2bf84b111e304959af5698757d60e9b8aeglennrp  if (mng_info->write_png64)
11643fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    {
11644fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_colortype = /* 6 */  7;
11645fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      mng_info->write_png_depth = 16;
11646fd164d2bf84b111e304959af5698757d60e9b8aeglennrp      image->depth = 16;
1164747da46dca23c0c6f51670977d82dce24204c5693dirk      image->alpha_trait = BlendPixelTrait;
11648fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11649197c8e6d7a6d3658c44fa95f56c19f88f5d64390glennrp      (void) SetImageType(image,TrueColorMatteType,exception);
116504dda64fa7c4d4967629a7138cc7a9ce1db4b915eglennrp      (void) SyncImage(image,exception);
11651fd164d2bf84b111e304959af5698757d60e9b8aeglennrp    }
11652fd164d2bf84b111e304959af5698757d60e9b8aeglennrp
11653092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:bit-depth");
116548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
116553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
116589c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
116590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116619c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
116620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
116649c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
116650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
116679c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
116680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
116709c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
116710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11672bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1167316ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11674bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11675bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
11676bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11677bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
116783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
116799c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11680bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
116813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11683092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:color-type");
116840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
116863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
116883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
116899c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
116900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1169116ea139d53d867211d3bb0fa859a83de653f687ecristy      else if (LocaleCompare(value,"1") == 0)
1169216ea139d53d867211d3bb0fa859a83de653f687ecristy        mng_info->write_png_colortype = 2;
1169316ea139d53d867211d3bb0fa859a83de653f687ecristy
116943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
116959c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
116960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
116989c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
116990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
117019c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
117020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
117049c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
117050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11706bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
1170716ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
11708bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
11709bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
11710bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
11711bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
117123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
117139c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11714d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
117153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
117180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117190dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
117200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
117210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117225d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * Chunks can be listed for exclusion via a "png:exclude-chunk"
117230e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
117240e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
117250e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
117260e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
117270e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117280e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
117290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117305d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * A "png:include-chunk" define takes  priority over both the
117315d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy   * mng_info and the "png:exclude-chunk" define.  Like the
117320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
117330dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
117340dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
117350dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
11736aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * appear in the "include-chunk" list. Such defines appearing among
11737aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * the image options take priority over those found among the image
11738aa192b15c78ecafb5ee45ea185519ba2cf4e1f60glennrp   * artifacts.
117390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
117410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
117420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
117430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
117450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
117460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
117470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
117490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
117500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
117510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11752104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
117530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
117540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1175526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1175626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11757a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1175826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1175926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1176026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1176126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1176226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1176326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1176426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1176526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11766fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk  mng_info->ping_exclude_tIME=MagickFalse;
11767a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1176826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1176926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1177026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1177126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
117728d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
117738d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11774092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:preserve-colormap");
117758d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
117768b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:preserve-colormap");
117778d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
117788d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
117798d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
11780ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  mng_info->ping_preserve_iCCP=MagickFalse;
11781ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11782ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  value=GetImageOption(image_info,"png:preserve-iCCP");
11783ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value == NULL)
11784ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     value=GetImageArtifact(image,"png:preserve-iCCP");
11785ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  if (value != NULL)
11786ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp     mng_info->ping_preserve_iCCP=MagickTrue;
11787ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp
11788ecab7d7b7fc598881ff3c72240381caa5c444a56glennrp  /* These compression-level, compression-strategy, and compression-filter
117891868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
117901868258559ddf946fa73ef72dd43507b32623705glennrp   */
11791092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-level");
117921868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
117938b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-level");
117941868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
117951868258559ddf946fa73ef72dd43507b32623705glennrp  {
117961868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
117971868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
117981868258559ddf946fa73ef72dd43507b32623705glennrp       */
117991868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118001868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
118011868258559ddf946fa73ef72dd43507b32623705glennrp
118020ffb95c048e16be4f2a8d6aaa76de1dfd7775124glennrp      else if (LocaleCompare(value,"1") == 0)
118031868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
118041868258559ddf946fa73ef72dd43507b32623705glennrp
118051868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118061868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
118071868258559ddf946fa73ef72dd43507b32623705glennrp
118081868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118091868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
118101868258559ddf946fa73ef72dd43507b32623705glennrp
118111868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118121868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
118131868258559ddf946fa73ef72dd43507b32623705glennrp
118141868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118151868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
118161868258559ddf946fa73ef72dd43507b32623705glennrp
118171868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
118181868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
118191868258559ddf946fa73ef72dd43507b32623705glennrp
118201868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
118211868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
118221868258559ddf946fa73ef72dd43507b32623705glennrp
118231868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
118241868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
118251868258559ddf946fa73ef72dd43507b32623705glennrp
118261868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
118271868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
118281868258559ddf946fa73ef72dd43507b32623705glennrp
118291868258559ddf946fa73ef72dd43507b32623705glennrp      else
1183016ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118311868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118321868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
118331868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118341868258559ddf946fa73ef72dd43507b32623705glennrp    }
118351868258559ddf946fa73ef72dd43507b32623705glennrp
11836092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-strategy");
118371868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118388b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-strategy");
118391868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118401868258559ddf946fa73ef72dd43507b32623705glennrp  {
118411868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118421868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
118431868258559ddf946fa73ef72dd43507b32623705glennrp
118441868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
118451868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
118461868258559ddf946fa73ef72dd43507b32623705glennrp
118471868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118481868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
118491868258559ddf946fa73ef72dd43507b32623705glennrp
118501868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1185198c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
118521868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1185398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1185498c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1185598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118561868258559ddf946fa73ef72dd43507b32623705glennrp
118571868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1185898c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
118591868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1186098c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1186198c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1186298c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
118631868258559ddf946fa73ef72dd43507b32623705glennrp
118641868258559ddf946fa73ef72dd43507b32623705glennrp      else
1186516ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
118661868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
118671868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
118681868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
118691868258559ddf946fa73ef72dd43507b32623705glennrp    }
118701868258559ddf946fa73ef72dd43507b32623705glennrp
11871092ec8d083fedaedfb7792995e7ea42164553cffcristy  value=GetImageOption(image_info,"png:compression-filter");
118721868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
118738b206bac411969018dc3a6d395f525f1664af412cristy     value=GetImageArtifact(image,"png:compression-filter");
118741868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
118751868258559ddf946fa73ef72dd43507b32623705glennrp  {
118761868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
118771868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
118781868258559ddf946fa73ef72dd43507b32623705glennrp       *
118791868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
118801868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
118811868258559ddf946fa73ef72dd43507b32623705glennrp       */
118821868258559ddf946fa73ef72dd43507b32623705glennrp
118831868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
118841868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
118851868258559ddf946fa73ef72dd43507b32623705glennrp
11886b19b8125320afb5954bd73b82d00700e8ed9e984cristy      else if (LocaleCompare(value,"1") == 0)
118871868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
118881868258559ddf946fa73ef72dd43507b32623705glennrp
118891868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
118901868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
118911868258559ddf946fa73ef72dd43507b32623705glennrp
118921868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
118931868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
118941868258559ddf946fa73ef72dd43507b32623705glennrp
118951868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
118961868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
118971868258559ddf946fa73ef72dd43507b32623705glennrp
118981868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
118991868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
119001868258559ddf946fa73ef72dd43507b32623705glennrp
119011868258559ddf946fa73ef72dd43507b32623705glennrp      else
1190216ea139d53d867211d3bb0fa859a83de653f687ecristy        (void) ThrowMagickException(exception,
119031868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
119041868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
119051868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
119061a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  }
1190703812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119081a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  for (source=0; source<8; source++)
119095c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
119101a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    value = NULL;
11911acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
119122dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 0)
119132dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunks");
119142dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119152dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 1)
119162dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunks");
119172dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119182dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 2)
119192dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:exclude-chunk");
119202dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119212dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 3)
119222dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:exclude-chunk");
119232dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119242dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 4)
119252dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunks");
119262dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119272dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 5)
119282dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunks");
119292dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119302dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 6)
119312dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageOption(image_info,"png:include-chunk");
119322dd1906783a5ece58a6105b4f59239e28b13caddglennrp
119332dd1906783a5ece58a6105b4f59239e28b13caddglennrp    if (source == 7)
119342dd1906783a5ece58a6105b4f59239e28b13caddglennrp      value=GetImageArtifact(image,"png:include-chunk");
1193526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
119361a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (value == NULL)
119371a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp       continue;
119381a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp
119391a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (source < 4)
119401a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickTrue;
119411a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    else
119421a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      excluding = MagickFalse;
1194326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1194403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
119452cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
119461a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        if (source == 0 || source == 2)
119471a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119481a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:exclude-chunk=%s found in image options.\n", value);
119491a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 1 || source == 3)
119502cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119512cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
119521a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else if (source == 4 || source == 6)
119532cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119541a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image options.\n", value);
119551a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        else /* if (source == 5 || source == 7) */
119561a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119571a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
119582cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1195903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
119601a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp    if (IsOptionMember("all",value) != MagickFalse)
119611a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
119621a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_bKGD=excluding;
119631a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_cHRM=excluding;
119641a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_date=excluding;
119651a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_EXIF=excluding;
119661a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_gAMA=excluding;
119671a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_iCCP=excluding;
119681a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=excluding; */
119691a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_oFFs=excluding;
119701a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_pHYs=excluding;
119711a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_sRGB=excluding;
119721a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tEXt=excluding;
11973fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding;
119741a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_tRNS=excluding;
119751a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_vpAg=excluding;
119761a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zCCP=excluding;
119771a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        mng_info->ping_exclude_zTXt=excluding;
119781a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
11979280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp
11980689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("none",value) != MagickFalse)
119811a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      {
11982a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_bKGD=excluding != MagickFalse ? MagickFalse :
11983a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11984a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_cHRM=excluding != MagickFalse ? MagickFalse :
11985a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11986a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_date=excluding != MagickFalse ? MagickFalse :
11987a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11988a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_EXIF=excluding != MagickFalse ? MagickFalse :
11989a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11990a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_gAMA=excluding != MagickFalse ? MagickFalse :
11991a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11992a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_iCCP=excluding != MagickFalse ? MagickFalse :
11993a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
119941a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp        /* mng_info->ping_exclude_iTXt=!excluding; */
11995a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_oFFs=excluding != MagickFalse ? MagickFalse :
11996a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11997a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_pHYs=excluding != MagickFalse ? MagickFalse :
11998a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
11999a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_sRGB=excluding != MagickFalse ? MagickFalse :
12000a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12001a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tEXt=excluding != MagickFalse ? MagickFalse :
12002a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12003fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk        mng_info->ping_exclude_tIME=excluding != MagickFalse ? MagickFalse :
12004fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          MagickTrue;
12005a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_tRNS=excluding != MagickFalse ? MagickFalse :
12006a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12007a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_vpAg=excluding != MagickFalse ? MagickFalse :
12008a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12009a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zCCP=excluding != MagickFalse ? MagickFalse :
12010a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
12011a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy        mng_info->ping_exclude_zTXt=excluding != MagickFalse ? MagickFalse :
12012a20c8fe839f466073b171f5a6fd16fdf9a8bd0edcristy          MagickTrue;
120131a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      }
1201403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
12015689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("bkgd",value) != MagickFalse)
120161a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_bKGD=excluding;
120172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12018689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("chrm",value) != MagickFalse)
120191a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_cHRM=excluding;
12020a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
12021689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("date",value) != MagickFalse)
120221a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_date=excluding;
120232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12024689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("exif",value) != MagickFalse)
120251a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_EXIF=excluding;
120262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12027689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("gama",value) != MagickFalse)
120281a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_gAMA=excluding;
120292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12030689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("iccp",value) != MagickFalse)
120311a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iCCP=excluding;
120322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12033689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
12034689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("itxt",value) != MagickFalse)
120351a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_iTXt=excluding;
12036689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
120372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12038689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("offs",value) != MagickFalse)
120391a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_oFFs=excluding;
120402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12041689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("phys",value) != MagickFalse)
120421a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_pHYs=excluding;
120432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12044689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("srgb",value) != MagickFalse)
120451a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_sRGB=excluding;
120462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12047689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("text",value) != MagickFalse)
120481a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tEXt=excluding;
120492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12050fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (IsOptionMember("time",value) != MagickFalse)
12051fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      mng_info->ping_exclude_tIME=excluding;
12052fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk
12053689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("trns",value) != MagickFalse)
120541a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_tRNS=excluding;
12055a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
12056689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("vpag",value) != MagickFalse)
120571a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_vpAg=excluding;
120582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12059689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("zccp",value) != MagickFalse)
120601a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zCCP=excluding;
120612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
12062689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp    if (IsOptionMember("ztxt",value) != MagickFalse)
120631a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp      mng_info->ping_exclude_zTXt=excluding;
1206426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1206526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
120661a506acce0fc50a6bbb35b1c04e7e51c1f7129f3glennrp  if (logging != MagickFalse)
1206726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1206826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120695d6fc9c70199232d90da3ceaf6933100fe2c25d4cristy      "  Chunks to be excluded from the output png:");
1207026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1207126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1207326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1207426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1207526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
12076a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
12077a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12078a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1207926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1208026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1208226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1208326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1208526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1208626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1208726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
12088689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#if 0
1208926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1209026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
12092689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp#endif
12093689efa2792fc00b3418a812abcdc9bb76e5293b0glennrp
1209426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1209526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1209726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1209826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1209926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1210026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1210126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1210226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1210326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1210426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1210526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
12106fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk    if (mng_info->ping_exclude_tIME != MagickFalse)
12107fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12108fd6fd07e58e3d37313bec849313ac6e2b92e3957dirk          "    tIME");
12109a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
12110a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12111a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1211226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1211326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1211526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1211626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1211726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1211826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1211926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1212026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1212126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1212226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
12123b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
121243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1212516ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOnePNGImage(mng_info,image_info,image,exception);
121263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
121280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
121310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
121363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
1213916ea139d53d867211d3bb0fa859a83de653f687ecristy   const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
121413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
121423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
121433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
121453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1214803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
121573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
121583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
121613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
121623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
121633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1216659575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality,
121673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
121683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
12170fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
121713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
121743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
121753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
121773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
121788a46d827a124555f0c48fb2368ec1bba8e079ab6cristy     image_info->type==TrueColorMatteType || image->alpha_trait == BlendPixelTrait;
121793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121804b917593e694424be469d250448c05c878663812glennrp  jng_alpha_sample_depth = 0;
121814b917593e694424be469d250448c05c878663812glennrp
1218259575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality%1000;
1218359575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1218459575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jng_alpha_compression_method=image->compression==JPEGCompression? 8 : 0;
1218559575fa5c228308a41d7f5028390be2083aaaf6dglennrp
12186750105bf9b66a5a86aca655f78c493202bf8f5c2glennrp  jng_alpha_quality=image_info->quality == 0UL ? 75UL :
1218759575fa5c228308a41d7f5028390be2083aaaf6dglennrp      image_info->quality;
1218859575fa5c228308a41d7f5028390be2083aaaf6dglennrp
1218959575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (jng_alpha_quality >= 1000)
1219059575fa5c228308a41d7f5028390be2083aaaf6dglennrp    jng_alpha_quality /= 1000;
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12192d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp  length=0;
12193d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp
121948fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
121963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
121970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
121993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1220116ea139d53d867211d3bb0fa859a83de653f687ecristy          "  Creating jpeg_image_info for alpha.");
122020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
122040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
122063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
122110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1221216ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image=SeparateImage(image,AlphaChannel,exception);
122133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
122143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122168a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      jpeg_image->alpha_trait=UndefinedPixelTrait;
122178f77fdc7ab98b7b964922604fc7822d8b7fe8ec2glennrp      jpeg_image->quality=jng_alpha_quality;
1221816ea139d53d867211d3bb0fa859a83de653f687ecristy      jpeg_image_info->type=GrayscaleType;
1221916ea139d53d867211d3bb0fa859a83de653f687ecristy      (void) SetImageType(jpeg_image,GrayscaleType,exception);
122203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
122213b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
122223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
122233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1222459575fa5c228308a41d7f5028390be2083aaaf6dglennrp  else
1222559575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1222659575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_compression_method=0;
1222759575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_color_type=10;
1222859575fa5c228308a41d7f5028390be2083aaaf6dglennrp      jng_alpha_sample_depth=0;
1222959575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
122343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
122357fb2652ba366fc984d1dbb0c66560b91c57dab78cristy    TrueColorType && IsImageGray(image,exception))
122363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
122373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1223859575fa5c228308a41d7f5028390be2083aaaf6dglennrp  if (logging != MagickFalse)
1223959575fa5c228308a41d7f5028390be2083aaaf6dglennrp    {
1224059575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224159575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Quality           = %d",(int) jng_quality);
1224259575fa5c228308a41d7f5028390be2083aaaf6dglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224359575fa5c228308a41d7f5028390be2083aaaf6dglennrp          "    JNG Color Type        = %d",jng_color_type);
122448fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp        if (transparent != 0)
1224559575fa5c228308a41d7f5028390be2083aaaf6dglennrp          {
1224659575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224759575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Compression = %d",jng_alpha_compression_method);
1224859575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1224959575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Depth       = %d",jng_alpha_sample_depth);
1225059575fa5c228308a41d7f5028390be2083aaaf6dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1225159575fa5c228308a41d7f5028390be2083aaaf6dglennrp              "    JNG Alpha Quality     = %d",(int) jng_alpha_quality);
1225259575fa5c228308a41d7f5028390be2083aaaf6dglennrp          }
1225359575fa5c228308a41d7f5028390be2083aaaf6dglennrp    }
1225459575fa5c228308a41d7f5028390be2083aaaf6dglennrp
122558fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
122563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
122583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
122603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
122613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1226216ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale PNG blob */
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1226416ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
122683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
122703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12273cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          /* Exclude all ancillary chunks */
12274cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp          (void) SetImageArtifact(jpeg_image,"png:exclude-chunks","all");
12275cc5d45ba3d6a1494b0c655f29e95f8eeac659acbglennrp
122763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1227716ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
1228016ea139d53d867211d3bb0fa859a83de653f687ecristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written",exception);
122813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
122823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1228616ea139d53d867211d3bb0fa859a83de653f687ecristy          /* Encode alpha as a grayscale JPEG blob */
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1228916ea139d53d867211d3bb0fa859a83de653f687ecristy            exception);
122903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
122923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
122943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
122973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
1229816ea139d53d867211d3bb0fa859a83de653f687ecristy           exception);
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
123000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12303e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
12304e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
123103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
123143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1231603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
123174e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
123184e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
123203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
123273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
123283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
123293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
123313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12332f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
123330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12335f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
123360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
123390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
123420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
123450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
123480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
123510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
123540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
123570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
123603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
12363cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
123673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123698fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
123763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
123853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
12387bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
123883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1238903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
123923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
123933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
123973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
124093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1241003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
124110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
12413e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12414cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12415e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
124160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12418e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
12419cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
12420e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
124210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
124313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1243403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1243535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
124383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
124443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
124453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
124473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
124483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
124493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
124503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1245103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
124523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1245335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1245435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1245635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1245735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
124583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1245935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1246035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
124613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1246235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1246335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
124643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
124680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1246916ea139d53d867211d3bb0fa859a83de653f687ecristy  if (image->resolution.x && image->resolution.y && !mng_info->equal_physs)
124703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
124723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
124743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1247603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
124773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1247935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
1248016ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.x*100.0/2.54+0.5));
124810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1248235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
1248316ea139d53d867211d3bb0fa859a83de653f687ecristy            (image->resolution.y*100.0/2.54+0.5));
124840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
124893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1249235ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
1249316ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.x*100.0+0.5));
124940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1249535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
1249616ea139d53d867211d3bb0fa859a83de653f687ecristy                (image->resolution.y*100.0+0.5));
124970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
124993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1250316ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1250416ea139d53d867211d3bb0fa859a83de653f687ecristy              PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
125053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
125133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
125153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
125163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
125173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1251903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
12520bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
12521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
125223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
125243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
125293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1253003812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
125313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
125323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
125363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125398fe9159929faad07fb14f2bb0fac9c14d0fd4e20glennrp  if (transparent != 0)
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12543bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12546fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy          size_t
125473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
125483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
125503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12552e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
12553f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
12558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
125605389e5ad63c880fe6885e3b24c76acbdbf63bd61cristy            len=(size_t) (*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
125620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
125643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
12566fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image,len);
12567fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                LogPNGChunk(logging,mng_IDAT,len);
12568fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlob(image,len+4,p);
12569fa6de8c321ddfb1c035dcb0901b917b67461dbefcristy                (void) WriteBlobMSBULong(image, crc32(0,p,(uInt) len+4));
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
125753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12576e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
12577e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
125793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
125803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
125813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
125843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
125853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12587e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
12588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1259003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
125993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
126043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
126053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
126063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
126113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1261216ea139d53d867211d3bb0fa859a83de653f687ecristy  jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
126133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
126143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
126153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
126183b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
126203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
1262216ea139d53d867211d3bb0fa859a83de653f687ecristy    exception);
126233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12626e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
12627e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
126283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
126303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
126310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1263259575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image_info->quality=jng_quality;
1263359575fa5c228308a41d7f5028390be2083aaaf6dglennrp  jpeg_image->quality=jng_quality;
126343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
126360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
126400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1264116ea139d53d867211d3bb0fa859a83de653f687ecristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,exception);
126420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
126453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12646e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
12647e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
126483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12650e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
126513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
126553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1265603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
126573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
126593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
126643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12667cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
126683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
126713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1267203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
126753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
126773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
126783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
126790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
126903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
126933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
126963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
126983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
126993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
127003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1270116ea139d53d867211d3bb0fa859a83de653f687ecristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
1270216ea139d53d867211d3bb0fa859a83de653f687ecristy%        Image *image,ExceptionInfo *exception)
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1271016ea139d53d867211d3bb0fa859a83de653f687ecristy%    o exception: return any errors or warnings in this structure.
1271116ea139d53d867211d3bb0fa859a83de653f687ecristy%
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1271416ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
1271516ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1271821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1271903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
127203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
127293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
127303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
127323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12733fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
1273416ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
127363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
127373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1274273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
127433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
127533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1275416ea139d53d867211d3bb0fa859a83de653f687ecristy  status=WriteOneJNGImage(mng_info,image_info,image,exception);
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
127603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
127613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
127623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1276516ea139d53d867211d3bb0fa859a83de653f687ecristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
1276616ea139d53d867211d3bb0fa859a83de653f687ecristy  ExceptionInfo *exception)
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1277521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
127763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
127773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1277803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1277903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1278003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
127933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
128033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
128053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
128063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
128073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12808bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
128123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12815d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
128253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
128263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12829fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
1283016ea139d53d867211d3bb0fa859a83de653f687ecristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1283873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
128413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
128453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
128523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
128563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
128573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
128743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
128753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
128763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128782dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "  Checking input image(s)\n"
128792dd1906783a5ece58a6105b4f59239e28b13caddglennrp        "    Image_info depth: %.20g,    Type: %d",
128802dd1906783a5ece58a6105b4f59239e28b13caddglennrp        (double) image_info->depth, image_info->type);
128813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
128833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
128850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12887280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           "    Scene: %.20g\n,   Image depth: %.20g",
12888280283d1a79ab37cd5a59809848acaf2d6f7843aglennrp           (double) scene++, (double) p->depth);
128890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12890dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy        if (p->alpha_trait == BlendPixelTrait)
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
128930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
128970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
129010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
129050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12908e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
129090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
129130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
129253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
129263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
129273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
129283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
129313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
129323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
129333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
129343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
129353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
129363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
129373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
129383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
129393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
129423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
129433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
129603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
129623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
129633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
129643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
129653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
129663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
129673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
129713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
129753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
129760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
129793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
129800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
129830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12984dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy        if (next_image->alpha_trait == BlendPixelTrait)
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
129860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
12988dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy          if ((next_image->alpha_trait == BlendPixelTrait) ||
12989dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy               next_image->page.x || next_image->page.y ||
129903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
129913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
129930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
129960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
129980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
130013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
130020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
130063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
130088a46d827a124555f0c48fb2368ec1bba8e079ab6cristy        if (image->alpha_trait == BlendPixelTrait)
130093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
130100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
130123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130137fb2652ba366fc984d1dbb0c66560b91c57dab78cristy            if (IsImageGray(image,exception) == MagickFalse)
130143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
130153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
130163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
130173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
130183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
130193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
130223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
130233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
130243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
130253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
130263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
130273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
130283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
130293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
130300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
130323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
130330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
130353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
130363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
130370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
1303916ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.x != next_image->next->resolution.x) ||
1304016ea139d53d867211d3bb0fa859a83de653f687ecristy                (next_image->resolution.y != next_image->next->resolution.y))
130413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
130420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
130443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
130453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
130463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
130473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
130483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
130493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
130503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
130513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
130523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
130533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
130543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
130553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
130563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
130573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
130583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
130593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
130603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
130613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
130623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
130633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
130643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
130653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
130663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
130673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
130683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
130693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
130703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
130713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
130723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
130733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
130743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
130753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
130763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
130773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
130783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
130793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
130800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
130813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
130823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
130833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
130843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
130853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
130863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
130873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
130883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
130893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
130903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
130913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
130923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
130933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
130940261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
13095d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
13096d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
1309716ea139d53d867211d3bb0fa859a83de653f687ecristy                     (void) ThrowMagickException(exception,GetMagickModule(),
1309816ea139d53d867211d3bb0fa859a83de653f687ecristy                       CoderWarning,
13099d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
13100d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
13101d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
131023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
131033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
131053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
13107cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
13108cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
131093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
131103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
131110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
131133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
131140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
131163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
131170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
131193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
13120d0ee5a2a5576be4065e1e4d9dbdd97da0ade7a9bglennrp            (final_delay != 25) && (final_delay != 50) && (1UL*final_delay !=
131213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
131223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
131233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
131263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
131273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
131293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
131303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
131313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
131333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
131343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
131353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
131363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
131373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1313803812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
131394e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
131404e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
131413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
131423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
131433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
131443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
131453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
131463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
131510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
131543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
131600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
131633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
131673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
131693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
131720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
131753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
131783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
131793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
131803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
131810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
131823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
131833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
131843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
131853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
131863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
131873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
13188092ec8d083fedaedfb7792995e7ea42164553cffcristy     option=GetImageOption(image_info,"mng:need-cacheoff");
131893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
131903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
131913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
131923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
131933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
131953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
131963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
131973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
131983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
13199bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1320003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
132013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
132023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
132033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
132043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
132063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
132073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
132083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
132113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
132133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1321403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
132153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
132163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
132173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
132183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
132190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
132213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
132220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
132243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
132250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
132273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13229e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
13230e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
132310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
132333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13234e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
132350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
132373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13238e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
132393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
132413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
132423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
132443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
132453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
132463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
132473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
132483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
132503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
132513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
132523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
132533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1325403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
132550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
13257e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13258cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13259e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
132600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
13262e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
13263cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
13264cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
132650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
132673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
132683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
132693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
132700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
132713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
132723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
132733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
132743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
132773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
132793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1328003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1328135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
132823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
132833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
132843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
132853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
132863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
132873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
132883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
132893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
132903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
132923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
132933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
132943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
132953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1329603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
132973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1329835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1329935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
133003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1330135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1330235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
133033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1330435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1330535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
133063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1330735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1330835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
133093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
133103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
133113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
133123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
1331416ea139d53d867211d3bb0fa859a83de653f687ecristy     if (image->resolution.x && image->resolution.y && mng_info->equal_physs)
133153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
133183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
133203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1332103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
133220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
133243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1332535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
1332616ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.x*100.0/2.54+0.5));
133270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1332835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
1332916ea139d53d867211d3bb0fa859a83de653f687ecristy               (image->resolution.y*100.0/2.54+0.5));
133300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
133323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
133353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
133373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1333835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
1333916ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.x*100.0+0.5));
133400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1334135ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
1334216ea139d53d867211d3bb0fa859a83de653f687ecristy                   (image->resolution.y*100.0+0.5));
133430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
133453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
133473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
133483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1334916ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+4,(png_uint_32) (image->resolution.x+0.5));
1335016ea139d53d867211d3bb0fa859a83de653f687ecristy                 PNGLong(chunk+8,(png_uint_32) (image->resolution.y+0.5));
133513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
133523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
133533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
133553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
133563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
133583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
133593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
133603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
13361dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy     if (write_mng && ((image->alpha_trait == BlendPixelTrait) ||
13362dc2d327c3b86b0567bdcf9b4d04b5e4663864480cristy         image->page.x > 0 || image->page.y > 0 || (image->page.width &&
133633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
133643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
133653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
133663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
133673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
133683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1336903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
133703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
133713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
133723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
133733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
133743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
133753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
133763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
133773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
133793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
133803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
133813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1338203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
133833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
133843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
133853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
133863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
133873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
133893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
133903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
133913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
133923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
13393bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
133943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
133953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
133963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
133973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
133983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
133993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
134003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
134013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1340203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
134030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13404bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
134053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
1340616ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[4+i*3]=(unsigned char) (ScaleQuantumToChar(
1340716ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].red) & 0xff);
1340816ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[5+i*3]=(unsigned char) (ScaleQuantumToChar(
1340916ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].green) & 0xff);
1341016ea139d53d867211d3bb0fa859a83de653f687ecristy           chunk[6+i*3]=(unsigned char) (ScaleQuantumToChar(
1341116ea139d53d867211d3bb0fa859a83de653f687ecristy             image->colormap[i].blue) & 0xff);
134123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
134130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
134153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
134163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
134173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
134183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
134203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
134213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
134223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
134253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
134273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
134283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
134293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
134303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
134313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
134323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
134333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
134343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
134353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
134363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
134373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
134383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
134393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
134413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
134423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
134433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
134443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
134453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
134463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
134473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
134483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
134493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
134503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
13451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
134523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
134533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
134553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
134563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1345703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
134580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13459bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
134603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
134613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
134623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
134633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
134643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
134650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
134663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
134673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
134683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
134693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
134703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
134713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
134743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
134753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
134763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
134773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13478bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
134793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
134803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
134813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
134833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
134853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
134863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
134883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
134903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
134913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
134923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
134933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
134943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
134953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
134963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
134973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1349803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
134993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
135003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
135013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
135023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
135033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
135043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
135053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
135063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
135073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
135083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
135093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
135103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
135123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
135143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
135153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
135173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
135183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
135193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
135213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
135243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
135263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1352703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
135283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
135303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
135313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
135333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
135343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
135353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
135363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
135373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
135383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1353903812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
135403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
135413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
135423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
135433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
135443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
135453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
135463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
135473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
135483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
135493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
135503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
135514e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
135523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
135533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
135543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
135573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
135583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
135603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
135613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
135623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
135653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
135663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
135673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
1356816ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOneJNGImage(mng_info,write_info,image,exception);
135693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
135703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
135713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
135723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
135733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
135743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
135753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
135763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
135772f2e514554975d510c88df54de98c6cdc1080f1cglennrp
13578b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
135798d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
135802f2e514554975d510c88df54de98c6cdc1080f1cglennrp
135812f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
135822f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
135832f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
13584a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
135852f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
135862f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
135872f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
135882f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
135892f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
135902f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
135912f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
135922f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
13593a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
135942f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
135952f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
135962f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
135972f2e514554975d510c88df54de98c6cdc1080f1cglennrp
1359816ea139d53d867211d3bb0fa859a83de653f687ecristy       status=WriteOnePNGImage(mng_info,image_info,image,exception);
135993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
136003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
136013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
136033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
136043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
136053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
136063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
136073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
136083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
136093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
136113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
136123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
136130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
136153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
136160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
136180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
136203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
136213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
136223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
136233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
136243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
136253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
136263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
136273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1362803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
136293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
136303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
136313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
136323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
136333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
136343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
136353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
136363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
136370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
136393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
136400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
136423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13643d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1364439992b4dd9b12ef752d55b8e402c069698851f72glennrp
136453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
136463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136473bd393f9074299ed9f2f3d128e4985118077c2bdglennrp  (void) image;
136483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
136493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
136500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
136513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
136523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
136533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1365439992b4dd9b12ef752d55b8e402c069698851f72glennrp
136553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
136563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
136573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
136583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13659d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
136603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13661