/*
Include declarations.
*/
-#include "magick/studio.h"
-#include "magick/artifact.h"
-#include "magick/attribute.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/color.h"
-#include "magick/color-private.h"
-#include "magick/colormap.h"
-#include "magick/colorspace.h"
-#include "magick/constitute.h"
-#include "magick/enhance.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/geometry.h"
-#include "magick/histogram.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/layer.h"
-#include "magick/list.h"
-#include "magick/log.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/module.h"
-#include "magick/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/option.h"
-#include "magick/quantum-private.h"
-#include "magick/profile.h"
-#include "magick/property.h"
-#include "magick/resource_.h"
-#include "magick/semaphore.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/statistic.h"
-#include "magick/string_.h"
-#include "magick/string-private.h"
-#include "magick/transform.h"
-#include "magick/utility.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/artifact.h"
+#include "MagickCore/attribute.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/color.h"
+#include "MagickCore/color-private.h"
+#include "MagickCore/colormap.h"
+#include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
+#include "MagickCore/constitute.h"
+#include "MagickCore/enhance.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/geometry.h"
+#include "MagickCore/histogram.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/layer.h"
+#include "MagickCore/list.h"
+#include "MagickCore/log.h"
+#include "MagickCore/MagickCore.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/module.h"
+#include "MagickCore/monitor.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/option.h"
+#include "MagickCore/pixel.h"
+#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/profile.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/resource_.h"
+#include "MagickCore/semaphore.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/static.h"
+#include "MagickCore/statistic.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
+#include "MagickCore/transform.h"
+#include "MagickCore/utility.h"
#if defined(MAGICKCORE_PNG_DELEGATE)
/* Suppress libpng pedantic warnings that were added in
((color).blue == (target).blue))
#endif
-/* Convenience macros for copying RGB or RGB+opacity components
- * between a pixel and a PixelPacket.
+/* Macros for left-bit-replication to ensure that pixels
+ * and PixelPackets all have the image->depth, and for use
+ * in PNG8 quantization.
*/
-#define GetRGBOPixelComponents(pixel, packet) \
- (packet).red = GetRedPixelComponent((pixel)); \
- (packet).green = GetGreenPixelComponent((pixel)); \
- (packet).red = GetBluePixelComponent((pixel)); \
- (packet).opacity = GetOpacityPixelComponent((pixel)); \
-#define SetRGBOPixelComponents(pixel, packet) \
- SetRedPixelComponent((pixel),(packet).red); \
- SetGreenPixelComponent((pixel),(packet).green); \
- SetBluePixelComponent((pixel),(packet).blue); \
- SetOpacityPixelComponent((pixel),(packet).opacity); \
+/* LBR01: Replicate top bit */
+#define LBR01PacketRed(pixelpacket) \
+ (pixelpacket).red=(ScaleQuantumToChar((pixelpacket).red) < 0x10 ? \
+ 0 : QuantumRange);
-#define GetRGBPixelComponents(pixel, packet) \
- (packet).red = GetRedPixelComponent((pixel)); \
- (packet).green = GetGreenPixelComponent((pixel)); \
- (packet).red = GetBluePixelComponent((pixel));
+#define LBR01PacketGreen(pixelpacket) \
+ (pixelpacket).green=(ScaleQuantumToChar((pixelpacket).green) < 0x10 ? \
+ 0 : QuantumRange);
-#define SetRGBPixelComponents(pixel, packet) \
- SetRedPixelComponent((pixel),(packet).red); \
- SetGreenPixelComponent((pixel),(packet).green); \
- SetBluePixelComponent((pixel),(packet).blue);
+#define LBR01PacketBlue(pixelpacket) \
+ (pixelpacket).blue=(ScaleQuantumToChar((pixelpacket).blue) < 0x10 ? \
+ 0 : QuantumRange);
+
+#define LBR01PacketAlpha(pixelpacket) \
+ (pixelpacket).alpha=(ScaleQuantumToChar((pixelpacket).alpha) < 0x10 ? \
+ 0 : QuantumRange);
+
+#define LBR01PacketRGB(pixelpacket) \
+ { \
+ LBR01PacketRed((pixelpacket)); \
+ LBR01PacketGreen((pixelpacket)); \
+ LBR01PacketBlue((pixelpacket)); \
+ }
+
+#define LBR01PacketRGBO(pixelpacket) \
+ { \
+ LBR01PacketRGB((pixelpacket)); \
+ LBR01PacketAlpha((pixelpacket)); \
+ }
+
+#define LBR01PixelRed(pixel) \
+ (ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
+ 0 : QuantumRange);
+
+#define LBR01PixelGreen(pixel) \
+ (ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
+ 0 : QuantumRange);
+
+#define LBR01PixelBlue(pixel) \
+ (ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
+ 0 : QuantumRange);
+
+#define LBR01PixelAlpha(pixel) \
+ (ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) < 0x10 ? \
+ 0 : QuantumRange);
+
+#define LBR01PixelRGB(pixel) \
+ { \
+ LBR01PixelRed((pixel)); \
+ LBR01PixelGreen((pixel)); \
+ LBR01PixelBlue((pixel)); \
+ }
+
+#define LBR01PixelRGBA(pixel) \
+ { \
+ LBR01PixelRGB((pixel)); \
+ LBR01PixelAlpha((pixel)); \
+ }
+
+/* LBR02: Replicate top 2 bits */
+
+#define LBR02PacketRed(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xc0; \
+ (pixelpacket).red=ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
+ }
+#define LBR02PacketGreen(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xc0; \
+ (pixelpacket).green=ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
+ }
+#define LBR02PacketBlue(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xc0; \
+ (pixelpacket).blue=ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
+ }
+#define LBR02PacketAlpha(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
+ (pixelpacket).alpha=ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
+ }
+
+#define LBR02PacketRGB(pixelpacket) \
+ { \
+ LBR02PacketRed((pixelpacket)); \
+ LBR02PacketGreen((pixelpacket)); \
+ LBR02PacketBlue((pixelpacket)); \
+ }
+
+#define LBR02PacketRGBO(pixelpacket) \
+ { \
+ LBR02PacketRGB((pixelpacket)); \
+ LBR02PacketAlpha((pixelpacket)); \
+ }
+
+#define LBR02PixelRed(pixel) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
+ & 0xc0; \
+ SetPixelRed(image, ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
+ (pixel)); \
+ }
+#define LBR02PixelGreen(pixel) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
+ & 0xc0; \
+ SetPixelGreen(image, ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
+ (pixel)); \
+ }
+#define LBR02PixelBlue(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
+ SetPixelBlue(image, ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
+ (pixel)); \
+ }
+#define LBR02PixelAlpha(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
+ SetPixelAlpha(image, ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
+ (pixel) ); \
+ }
+
+#define LBR02PixelRGB(pixel) \
+ { \
+ LBR02PixelRed((pixel)); \
+ LBR02PixelGreen((pixel)); \
+ LBR02PixelBlue((pixel)); \
+ }
+
+#define LBR02PixelRGBA(pixel) \
+ { \
+ LBR02PixelRGB((pixel)); \
+ LBR02PixelAlpha((pixel)); \
+ }
+
+/* LBR03: Replicate top 3 bits (only used with opaque pixels during
+ PNG8 quantization) */
+
+#define LBR03PacketRed(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xe0; \
+ (pixelpacket).red=ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
+ }
+#define LBR03PacketGreen(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xe0; \
+ (pixelpacket).green=ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
+ }
+#define LBR03PacketBlue(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xe0; \
+ (pixelpacket).blue=ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
+ }
+
+#define LBR03PacketRGB(pixelpacket) \
+ { \
+ LBR03PacketRed((pixelpacket)); \
+ LBR03PacketGreen((pixelpacket)); \
+ LBR03PacketBlue((pixelpacket)); \
+ }
+
+#define LBR03PixelRed(pixel) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
+ & 0xe0; \
+ SetPixelRed(image, ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
+ }
+#define LBR03Green(pixel) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
+ & 0xe0; \
+ SetPixelGreen(image, ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
+ }
+#define LBR03Blue(pixel) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
+ & 0xe0; \
+ SetPixelBlue(image, ScaleCharToQuantum( \
+ (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
+ }
+
+#define LBR03RGB(pixel) \
+ { \
+ LBR03PixelRed((pixel)); \
+ LBR03Green((pixel)); \
+ LBR03Blue((pixel)); \
+ }
+
+/* LBR04: Replicate top 4 bits */
+
+#define LBR04PacketRed(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xf0; \
+ (pixelpacket).red=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
+ }
+#define LBR04PacketGreen(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xf0; \
+ (pixelpacket).green=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
+ }
+#define LBR04PacketBlue(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xf0; \
+ (pixelpacket).blue=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
+ }
+#define LBR04PacketAlpha(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
+ (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
+ }
+
+#define LBR04PacketRGB(pixelpacket) \
+ { \
+ LBR04PacketRed((pixelpacket)); \
+ LBR04PacketGreen((pixelpacket)); \
+ LBR04PacketBlue((pixelpacket)); \
+ }
+
+#define LBR04PacketRGBO(pixelpacket) \
+ { \
+ LBR04PacketRGB((pixelpacket)); \
+ LBR04PacketAlpha((pixelpacket)); \
+ }
+
+#define LBR04PixelRed(pixel) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
+ & 0xf0; \
+ SetPixelRed(image,\
+ ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
+ }
+#define LBR04PixelGreen(pixel) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
+ & 0xf0; \
+ SetPixelGreen(image,\
+ ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
+ }
+#define LBR04PixelBlue(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
+ SetPixelBlue(image,\
+ ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
+ }
+#define LBR04PixelAlpha(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
+ SetPixelAlpha(image,\
+ ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
+ }
+
+#define LBR04PixelRGB(pixel) \
+ { \
+ LBR04PixelRed((pixel)); \
+ LBR04PixelGreen((pixel)); \
+ LBR04PixelBlue((pixel)); \
+ }
+
+#define LBR04PixelRGBA(pixel) \
+ { \
+ LBR04PixelRGB((pixel)); \
+ LBR04PixelAlpha((pixel)); \
+ }
+
+
+/* LBR08: Replicate top 8 bits */
+
+#define LBR08PacketRed(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red); \
+ (pixelpacket).red=ScaleCharToQuantum((lbr_bits)); \
+ }
+#define LBR08PacketGreen(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green); \
+ (pixelpacket).green=ScaleCharToQuantum((lbr_bits)); \
+ }
+#define LBR08PacketBlue(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue); \
+ (pixelpacket).blue=ScaleCharToQuantum((lbr_bits)); \
+ }
+#define LBR08PacketAlpha(pixelpacket) \
+ { \
+ unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha); \
+ (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits)); \
+ }
+
+#define LBR08PacketRGB(pixelpacket) \
+ { \
+ LBR08PacketRed((pixelpacket)); \
+ LBR08PacketGreen((pixelpacket)); \
+ LBR08PacketBlue((pixelpacket)); \
+ }
+
+#define LBR08PacketRGBO(pixelpacket) \
+ { \
+ LBR08PacketRGB((pixelpacket)); \
+ LBR08PacketAlpha((pixelpacket)); \
+ }
+
+#define LBR08PixelRed(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelRed(image,(pixel))); \
+ SetPixelRed(image,\
+ ScaleCharToQuantum((lbr_bits)), (pixel)); \
+ }
+#define LBR08PixelGreen(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelGreen(image,(pixel))); \
+ SetPixelGreen(image,\
+ ScaleCharToQuantum((lbr_bits)), (pixel)); \
+ }
+#define LBR08PixelBlue(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelBlue(image,(pixel))); \
+ SetPixelBlue(image,\
+ ScaleCharToQuantum((lbr_bits)), (pixel)); \
+ }
+#define LBR08PixelAlpha(pixel) \
+ { \
+ unsigned char lbr_bits= \
+ ScaleQuantumToChar(GetPixelAlpha(image,(pixel))); \
+ SetPixelAlpha(image,\
+ ScaleCharToQuantum((lbr_bits)), (pixel)); \
+ }
+
+#define LBR08PixelRGB(pixel) \
+ { \
+ LBR08PixelRed((pixel)); \
+ LBR08PixelGreen((pixel)); \
+ LBR08PixelBlue((pixel)); \
+ }
+
+#define LBR08PixelRGBA(pixel) \
+ { \
+ LBR08PixelRGB((pixel)); \
+ LBR08PixelAlpha((pixel)); \
+ }
+
+
+/* LBR16: Replicate top 16 bits */
+
+#define LBR16PacketRed(pixelpacket) \
+ { \
+ unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).red); \
+ (pixelpacket).red=ScaleShortToQuantum((lbr_bits)); \
+ }
+#define LBR16PacketGreen(pixelpacket) \
+ { \
+ unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).green); \
+ (pixelpacket).green=ScaleShortToQuantum((lbr_bits)); \
+ }
+#define LBR16PacketBlue(pixelpacket) \
+ { \
+ unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).blue); \
+ (pixelpacket).blue=ScaleShortToQuantum((lbr_bits)); \
+ }
+#define LBR16PacketAlpha(pixelpacket) \
+ { \
+ unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).alpha); \
+ (pixelpacket).alpha=ScaleShortToQuantum((lbr_bits)); \
+ }
+
+#define LBR16PacketRGB(pixelpacket) \
+ { \
+ LBR16PacketRed((pixelpacket)); \
+ LBR16PacketGreen((pixelpacket)); \
+ LBR16PacketBlue((pixelpacket)); \
+ }
+
+#define LBR16PacketRGBO(pixelpacket) \
+ { \
+ LBR16PacketRGB((pixelpacket)); \
+ LBR16PacketAlpha((pixelpacket)); \
+ }
+
+#define LBR16PixelRed(pixel) \
+ { \
+ unsigned short lbr_bits= \
+ ScaleQuantumToShort(GetPixelRed(image,(pixel))); \
+ SetPixelRed(image,\
+ ScaleShortToQuantum((lbr_bits)),(pixel)); \
+ }
+#define LBR16PixelGreen(pixel) \
+ { \
+ unsigned short lbr_bits= \
+ ScaleQuantumToShort(GetPixelGreen(image,(pixel))); \
+ SetPixelGreen(image,\
+ ScaleShortToQuantum((lbr_bits)),(pixel)); \
+ }
+#define LBR16PixelBlue(pixel) \
+ { \
+ unsigned short lbr_bits= \
+ ScaleQuantumToShort(GetPixelBlue(image,(pixel))); \
+ SetPixelBlue(image,\
+ ScaleShortToQuantum((lbr_bits)),(pixel)); \
+ }
+#define LBR16PixelAlpha(pixel) \
+ { \
+ unsigned short lbr_bits= \
+ ScaleQuantumToShort(GetPixelAlpha(image,(pixel))); \
+ SetPixelAlpha(image,\
+ ScaleShortToQuantum((lbr_bits)),(pixel)); \
+ }
+
+#define LBR16PixelRGB(pixel) \
+ { \
+ LBR16PixelRed((pixel)); \
+ LBR16PixelGreen((pixel)); \
+ LBR16PixelBlue((pixel)); \
+ }
+
+#define LBR16PixelRGBA(pixel) \
+ { \
+ LBR16PixelRGB((pixel)); \
+ LBR16PixelAlpha((pixel)); \
+ }
/*
Establish thread safety.
write_mng,
write_png_colortype,
write_png_depth,
+ write_png_compression_level,
+ write_png_compression_strategy,
+ write_png_compression_filter,
write_png8,
write_png24,
write_png32;
Forward declarations.
*/
static MagickBooleanType
- WritePNGImage(const ImageInfo *,Image *);
+ WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
static MagickBooleanType
- WriteMNGImage(const ImageInfo *,Image *);
+ WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
#if defined(JNG_SUPPORTED)
static MagickBooleanType
- WriteJNGImage(const ImageInfo *,Image *);
+ WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
#endif
#if PNG_LIBPNG_VER > 10011
if (image->depth >= 16)
{
- const PixelPacket
+ const Quantum
*p;
ok_to_reduce=
{
p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ if (p == (const Quantum *) NULL)
{
ok_to_reduce = MagickFalse;
break;
for (x=(ssize_t) image->columns-1; x >= 0; x--)
{
ok_to_reduce=
- QuantumToCharToQuantumEqQuantum(GetRedPixelComponent(p)) &&
- QuantumToCharToQuantumEqQuantum(GetGreenPixelComponent(p)) &&
- QuantumToCharToQuantumEqQuantum(GetBluePixelComponent(p)) ?
+ QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
+ QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
+ QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
MagickTrue : MagickFalse;
if (ok_to_reduce == MagickFalse)
break;
- p++;
+ p+=GetPixelChannels(image);
}
if (x >= 0)
break;
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
-% Like IsGrayImage except does not change DirectClass to PseudoClass %
+% Like IsImageGray except does not change DirectClass to PseudoClass %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
static MagickBooleanType ImageIsGray(Image *image)
{
- register const PixelPacket
+ register const Quantum
*p;
register ssize_t
if (image->storage_class == PseudoClass)
{
for (i=0; i < (ssize_t) image->colors; i++)
- if (IsGray(image->colormap+i) == MagickFalse)
+ if (IsPixelPacketGray(image->colormap+i) == MagickFalse)
return(MagickFalse);
return(MagickTrue);
}
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ if (p == (const Quantum *) NULL)
return(MagickFalse);
for (x=(ssize_t) image->columns-1; x >= 0; x--)
{
- if (IsGray(p) == MagickFalse)
+ if (IsPixelGray(image,p) == MagickFalse)
return(MagickFalse);
- p++;
+ p+=GetPixelChannels(image);
}
}
return(MagickTrue);
% We will not attempt to read files containing the CgBI chunk.
% They are really Xcode files meant for display on the iPhone.
% These are not valid PNG files and it is impossible to recover
-% the orginal PNG from files that have been converted to Xcode-PNG,
+% the original PNG from files that have been converted to Xcode-PNG,
% since irretrievable loss of color data has occurred due to the
% use of premultiplied alpha.
*/
char
msg[MaxTextExtent];
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"Expected %.20g bytes; found %.20g bytes",(double) length,
(double) check);
png_warning(png_ptr,msg);
return(MagickFalse);
}
- profile=AcquireStringInfo(length);
+ profile=BlobToStringInfo((const void *) NULL,length);
if (profile == (StringInfo *) NULL)
{
double
file_gamma;
- LongPixelPacket
+ PixelLongPacket
transparent_color;
MagickBooleanType
register unsigned char
*p;
- register IndexPacket
- *indexes;
-
register ssize_t
i,
x;
- register PixelPacket
+ register Quantum
*q;
size_t
transparent_color.red=65537;
transparent_color.green=65537;
transparent_color.blue=65537;
- transparent_color.opacity=65537;
+ transparent_color.alpha=65537;
num_text = 0;
num_text_total = 0;
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Reading PNG iCCP chunk.");
- profile=AcquireStringInfo(profile_length);
+ profile=BlobToStringInfo(info,profile_length);
+ if (profile == (StringInfo *) NULL)
+ {
+ (void) ThrowMagickException(&image->exception,GetMagickModule(),
+ ResourceLimitError,"MemoryAllocationFailed","`%s'",
+ "unable to copy profile");
+ return((Image *) NULL);
+ }
SetStringInfoDatum(profile,(const unsigned char *) info);
(void) SetImageProfile(image,"icc",profile);
profile=DestroyStringInfo(profile);
image->background_color.blue=
ScaleShortToQuantum(ping_background->blue);
- image->background_color.opacity=OpaqueOpacity;
+ image->background_color.alpha=OpaqueAlpha;
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
transparent_color.red= scale_to_short*ping_trans_color->red;
transparent_color.green= scale_to_short*ping_trans_color->green;
transparent_color.blue= scale_to_short*ping_trans_color->blue;
- transparent_color.opacity= scale_to_short*ping_trans_color->gray;
+ transparent_color.alpha= scale_to_short*ping_trans_color->gray;
if (ping_color_type == PNG_COLOR_TYPE_GRAY)
{
" Raw tRNS graylevel is %d.",ping_trans_color->gray);
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " scaled graylevel is %d.",transparent_color.opacity);
+ " scaled graylevel is %d.",transparent_color.alpha);
}
- transparent_color.red=transparent_color.opacity;
- transparent_color.green=transparent_color.opacity;
- transparent_color.blue=transparent_color.opacity;
+ transparent_color.red=transparent_color.alpha;
+ transparent_color.green=transparent_color.alpha;
+ transparent_color.blue=transparent_color.alpha;
}
}
}
/*
Initialize image colormap.
*/
- if (AcquireImageColormap(image,image->colors) == MagickFalse)
+ if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
/* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
ping_interlace_method in value */
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"%d, %d",(int) ping_width, (int) ping_height);
(void) SetImageProperty(image,"PNG:IHDR.width,height ",msg);
- (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
+ (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
(void) SetImageProperty(image,"PNG:IHDR.bit_depth ",msg);
- (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_color_type);
+ (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_color_type);
(void) SetImageProperty(image,"PNG:IHDR.color_type ",msg);
- (void) FormatMagickString(msg,MaxTextExtent,"%d",
+ (void) FormatLocaleString(msg,MaxTextExtent,"%d",
(int) ping_interlace_method);
(void) SetImageProperty(image,"PNG:IHDR.interlace_method",msg);
}
png_read_row(ping,ping_pixels+row_offset,NULL);
q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
{
if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
- (GetOpacityPixelComponent(q) != OpaqueOpacity))
+ (GetPixelAlpha(image,q) != OpaqueAlpha))
{
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
}
if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
ping_color_type == PNG_COLOR_TYPE_GRAY) &&
- (ScaleQuantumToShort(GetRedPixelComponent(q))
- == transparent_color.red &&
- ScaleQuantumToShort(GetGreenPixelComponent(q))
- == transparent_color.green &&
- ScaleQuantumToShort(GetBluePixelComponent(q))
- == transparent_color.blue))
+ (ScaleQuantumToShort(GetPixelRed(image,q)) ==
+ transparent_color.red &&
+ ScaleQuantumToShort(GetPixelGreen(image,q)) ==
+ transparent_color.green &&
+ ScaleQuantumToShort(GetPixelBlue(image,q)) ==
+ transparent_color.blue))
{
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
found_transparent_pixel = MagickTrue;
break;
}
- q++;
+ q+=GetPixelChannels(image);
}
}
/*
Convert grayscale image to PseudoClass pixel packets.
*/
+ if (logging != MagickFalse)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Converting grayscale pixels to pixel packets");
+
image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
MagickTrue : MagickFalse;
png_read_row(ping,ping_pixels+row_offset,NULL);
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
- indexes=GetAuthenticIndexQueue(image);
p=ping_pixels+row_offset;
r=quantum_scanline;
for (x=(ssize_t) image->columns-1; x >= 0; x--)
{
*r++=*p++;
- /* In image.h, OpaqueOpacity is 0
- * TransparentOpacity is QuantumRange
- * In a PNG datastream, Opaque is QuantumRange
- * and Transparent is 0.
- */
- SetOpacityPixelComponent(q,
- ScaleCharToQuantum((unsigned char) (255-(*p++))));
- if (GetOpacityPixelComponent(q) != OpaqueOpacity)
+ SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) *p++),q);
+ if (GetPixelAlpha(image,q) != OpaqueAlpha)
found_transparent_pixel = MagickTrue;
- q++;
+ q+=GetPixelChannels(image);
}
else
{
for (x=(ssize_t) image->columns-1; x >= 0; x--)
{
-#if (MAGICKCORE_QUANTUM_DEPTH == 16)
+#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
size_t
quantum;
if (image->colors > 256)
- *r=((*p++) << 8);
+ quantum=((*p++) << 8);
else
- *r=0;
+ quantum=0;
- quantum=(*r);
quantum|=(*p++);
- *r=(Quantum) quantum;
+ *r=ScaleShortToQuantum(quantum);
r++;
if (ping_color_type == 4)
{
- quantum=((*p++) << 8);
- quantum|=(*p++);
- SetOpacityPixelComponent(q,(Quantum) (QuantumRange-quantum));
- if (GetOpacityPixelComponent(q) != OpaqueOpacity)
- found_transparent_pixel = MagickTrue;
- q++;
- }
-#else
-#if (MAGICKCORE_QUANTUM_DEPTH == 32)
- size_t
- quantum;
-
- if (image->colors > 256)
- *r=((*p++) << 8);
-
- else
- *r=0;
-
- quantum=(*r);
- quantum|=(*p++);
- *r=quantum;
- r++;
+ if (image->colors > 256)
+ quantum=((*p++) << 8);
+ else
+ quantum=0;
- if (ping_color_type == 4)
- {
- quantum=(*p << 8) | *(p+1);
- quantum*=65537L;
- SetOpacityPixelComponent(q,
- (Quantum) GetAlphaPixelComponent(q));
- if (GetOpacityPixelComponent(q) != OpaqueOpacity)
+ quantum|=(*p++);
+ SetPixelAlpha(image,ScaleShortToQuantum(quantum),q);
+ if (GetPixelAlpha(image,q) != OpaqueAlpha)
found_transparent_pixel = MagickTrue;
- p+=2;
- q++;
+ q+=GetPixelChannels(image);
}
#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
if (ping_color_type == 4)
{
- SetOpacityPixelComponent(q,(Quantum) (QuantumRange-(*p++)));
- if (GetOpacityPixelComponent(q) != OpaqueOpacity)
+ SetPixelAlpha(image,*p++,q);
+ if (GetPixelAlpha(image,q) != OpaqueAlpha)
found_transparent_pixel = MagickTrue;
p++;
- q++;
+ q+=GetPixelChannels(image);
}
-#endif
#endif
}
*/
r=quantum_scanline;
+ q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
+
+ if (q == (Quantum *) NULL)
+ break;
for (x=0; x < (ssize_t) image->columns; x++)
- SetIndexPixelComponent(indexes+x,*r++);
+ {
+ SetPixelIndex(image,*r++,q);
+ q+=GetPixelChannels(image);
+ }
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
{
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" No transparent pixel was found");
-
+
ping_color_type&=0x03;
}
}
{
for (x=0; x < ping_num_trans; x++)
{
- image->colormap[x].opacity =
- ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
+ image->colormap[x].alpha =
+ ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
}
}
for (x=0; x < (int) image->colors; x++)
{
if (ScaleQuantumToShort(image->colormap[x].red) ==
- transparent_color.opacity)
+ transparent_color.alpha)
{
- image->colormap[x].opacity = (Quantum) TransparentOpacity;
+ image->colormap[x].alpha = (Quantum) TransparentAlpha;
}
}
}
image->storage_class=storage_class;
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
- indexes=GetAuthenticIndexQueue(image);
/* Caution: on a Q8 build, this does not distinguish between
* 16-bit colors that differ only in the low byte
*/
for (x=(ssize_t) image->columns-1; x >= 0; x--)
{
- if (ScaleQuantumToShort(GetRedPixelComponent(q))
- == transparent_color.red &&
- ScaleQuantumToShort(GetGreenPixelComponent(q))
- == transparent_color.green &&
- ScaleQuantumToShort(GetBluePixelComponent(q))
- == transparent_color.blue)
+ if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
+ transparent_color.red &&
+ ScaleQuantumToShort(GetPixelGreen(image,q)) ==
+ transparent_color.green &&
+ ScaleQuantumToShort(GetPixelBlue(image,q)) ==
+ transparent_color.blue)
{
- SetOpacityPixelComponent(q,TransparentOpacity);
+ SetPixelAlpha(image,TransparentAlpha,q);
}
#if 0 /* I have not found a case where this is needed. */
else
{
- SetOpacityPixelComponent(q)=(Quantum) OpaqueOpacity;
+ SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
}
#endif
- q++;
+ q+=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
if (num_text_total != 0)
{
/* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"%d tEXt/zTXt/iTXt chunks were found", num_text_total);
(void) SetImageProperty(image,"PNG:text ",msg);
}
if (num_raw_profiles != 0)
{
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"%d were found", num_raw_profiles);
(void) SetImageProperty(image,"PNG:text-encoded profiles",msg);
}
if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
{
- (void) FormatMagickString(msg,MaxTextExtent,"%s",
+ (void) FormatLocaleString(msg,MaxTextExtent,"%s",
"chunk was found (see Chromaticity, above)");
(void) SetImageProperty(image,"PNG:cHRM ",msg);
}
if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
{
- (void) FormatMagickString(msg,MaxTextExtent,"%s",
+ (void) FormatLocaleString(msg,MaxTextExtent,"%s",
"chunk was found (see Background color, above)");
(void) SetImageProperty(image,"PNG:bKGD ",msg);
}
- (void) FormatMagickString(msg,MaxTextExtent,"%s",
+ (void) FormatLocaleString(msg,MaxTextExtent,"%s",
"chunk was found");
if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
#if defined(PNG_sRGB_SUPPORTED)
if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
{
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"intent=%d (See Rendering intent)",
(int) intent);
(void) SetImageProperty(image,"PNG:sRGB ",msg);
if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
{
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"gamma=%.8g (See Gamma, above)",
file_gamma);
(void) SetImageProperty(image,"PNG:gAMA ",msg);
#if defined(PNG_pHYs_SUPPORTED)
if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
{
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"x_res=%.10g, y_res=%.10g, units=%d",
(double) x_resolution,(double) y_resolution, unit_type);
(void) SetImageProperty(image,"PNG:pHYs ",msg);
#if defined(PNG_oFFs_SUPPORTED)
if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
{
- (void) FormatMagickString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
+ (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
(double) image->page.x,(double) image->page.y);
(void) SetImageProperty(image,"PNG:oFFs ",msg);
}
if ((image->page.width != 0 && image->page.width != image->columns) ||
(image->page.height != 0 && image->page.height != image->rows))
{
- (void) FormatMagickString(msg,MaxTextExtent,
+ (void) FormatLocaleString(msg,MaxTextExtent,
"width=%.20g, height=%.20g",
(double) image->page.width,(double) image->page.height);
(void) SetImageProperty(image,"PNG:vpAg ",msg);
ThrowReaderException(CorruptImageError,"CorruptImage");
}
-#if 0 /* This is probably redundant now */
- if (LocaleCompare(image_info->magick,"PNG8") == 0)
- {
- (void) SetImageType(image,PaletteType);
-
- if (image->matte != MagickFalse)
- {
- /* To do: Reduce to binary transparency */
- }
- }
-#endif
-
if (LocaleCompare(image_info->magick,"PNG24") == 0)
{
- (void) SetImageType(image,TrueColorType);
+ (void) SetImageType(image,TrueColorType,exception);
image->matte=MagickFalse;
}
if (LocaleCompare(image_info->magick,"PNG32") == 0)
- (void) SetImageType(image,TrueColorMatteType);
+ (void) SetImageType(image,TrueColorMatteType,exception);
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
jng_alpha_filter_method,
jng_alpha_interlace_method;
- register const PixelPacket
+ register const Quantum
*s;
register ssize_t
i,
x;
- register PixelPacket
+ register Quantum
*q;
register unsigned char
image=mng_info->image;
- if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
+ if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
{
/*
Allocate next image structure.
o close alpha_blob.
o copy intensity of secondary image into
- opacity samples of main image.
+ alpha samples of main image.
o destroy the secondary image.
*/
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Reading jng_image from color_blob.");
- (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
+ (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
color_image->filename);
color_image_info->ping=MagickFalse; /* To do: avoid this */
image->rows=jng_height;
image->columns=jng_width;
- length=image->columns*sizeof(PixelPacket);
for (y=0; y < (ssize_t) image->rows; y++)
{
s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
- (void) CopyMagickMemory(q,s,length);
+ for (x=(ssize_t) image->columns; x != 0; x--)
+ {
+ SetPixelRed(image,GetPixelRed(jng_image,s),q);
+ SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
+ SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
+ q+=GetPixelChannels(image);
+ s+=GetPixelChannels(jng_image);
+ }
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Reading opacity from alpha_blob.");
+ " Reading alpha from alpha_blob.");
- (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
+ (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
"%s",alpha_image->filename);
jng_image=ReadImage(alpha_image_info,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
s=GetVirtualPixels(jng_image,0,y,image->columns,1,
- &image->exception);
+ &image->exception);
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
if (image->matte != MagickFalse)
- for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
- SetOpacityPixelComponent(q,(Quantum) QuantumRange-
- GetRedPixelComponent(s));
+ for (x=(ssize_t) image->columns; x != 0; x--)
+ {
+ SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
+ q+=GetPixelChannels(image);
+ s+=GetPixelChannels(jng_image);
+ }
else
- for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
+ for (x=(ssize_t) image->columns; x != 0; x--)
{
- SetOpacityPixelComponent(q,(Quantum) QuantumRange-
- GetRedPixelComponent(s));
- if (GetOpacityPixelComponent(q) != OpaqueOpacity)
+ SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
+ if (GetPixelAlpha(image,q) != OpaqueAlpha)
image->matte=MagickTrue;
+ q+=GetPixelChannels(image);
+ s+=GetPixelChannels(jng_image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
if (mng_type != 3)
insert_layers=MagickTrue;
#endif
- if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
+ if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
{
/* Allocate next image structure. */
AcquireNextImage(image_info,image);
(mng_info->mng_height > 65535L))
ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
- (void) FormatMagickString(page_geometry,MaxTextExtent,
+ (void) FormatLocaleString(page_geometry,MaxTextExtent,
"%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
mng_info->mng_height);
mng_background_color.blue=
ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
- mng_background_color.opacity=OpaqueOpacity;
+ mng_background_color.alpha=OpaqueAlpha;
}
#ifdef MNG_OBJECT_BUFFERS
(subframe_width) && (subframe_height))
{
/* Allocate next image structure. */
- if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
+ if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
{
AcquireNextImage(image_info,image);
(image_height < mng_info->mng_height) ||
(mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
{
- if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
+ if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
{
/*
Allocate next image structure.
(subframe_width) && (subframe_height) && (simplicity == 0 ||
(simplicity & 0x08)))
{
- if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
+ if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
{
/*
Allocate next image structure.
#endif /* MNG_INSERT_LAYERS */
first_mng_object=MagickFalse;
- if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
+ if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
{
/*
Allocate next image structure.
int
yy;
+ Quantum
+ *next,
+ *prev;
+
+ png_uint_16
+ magn_methx,
+ magn_methy;
+
ssize_t
m,
y;
- register ssize_t
- x;
-
- register PixelPacket
+ register Quantum
*n,
*q;
- PixelPacket
- *next,
- *prev;
-
- png_uint_16
- magn_methx,
- magn_methy;
+ register ssize_t
+ x;
/* Allocate next image structure. */
for (x=(ssize_t) image->columns-1; x >= 0; x--)
{
- SetRedPixelComponent(q,ScaleQuantumToShort(
- GetRedPixelComponent(q));
- SetGreenPixelComponent(q,ScaleQuantumToShort(
- GetGreenPixelComponent(q));
- SetBluePixelComponent(q,ScaleQuantumToShort(
- GetBluePixelComponent(q));
- SetOpacityPixelComponent(q,ScaleQuantumToShort(
- GetOpacityPixelComponent(q));
- q++;
+ SetPixelRed(image,ScaleQuantumToShort(
+ GetPixelRed(image,q)),q);
+ SetPixelGreen(image,ScaleQuantumToShort(
+ GetPixelGreen(image,q)),q);
+ SetPixelBlue(image,ScaleQuantumToShort(
+ GetPixelBlue(image,q)),q);
+ SetPixelAlpha(image,ScaleQuantumToShort(
+ GetPixelAlpha(image,q)),q);
+ q+=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
else
{
- large_image->background_color.opacity=OpaqueOpacity;
+ large_image->background_color.alpha=OpaqueAlpha;
(void) SetImageBackgroundColor(large_image);
if (magn_methx == 4)
m=(ssize_t) mng_info->magn_mt;
yy=0;
length=(size_t) image->columns;
- next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
- prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
+ next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
+ prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
- if ((prev == (PixelPacket *) NULL) ||
- (next == (PixelPacket *) NULL))
+ if ((prev == (Quantum *) NULL) ||
+ (next == (Quantum *) NULL))
{
image=DestroyImageList(image);
MngInfoFreeStruct(mng_info,&have_mng_structure);
for (i=0; i < m; i++, yy++)
{
- /* To do: Rewrite using Get/Set***PixelComponent() */
- register PixelPacket
+ register Quantum
*pixels;
assert(yy < (ssize_t) large_image->rows);
if (magn_methy <= 1)
{
- *q=(*pixels); /* replicate previous */
+ /* replicate previous */
+ SetPixelRed(large_image,GetPixelRed(image,pixels),q);
+ SetPixelGreen(large_image,GetPixelGreen(image,
+ pixels),q);
+ SetPixelBlue(large_image,GetPixelBlue(image,
+ pixels),q);
+ SetPixelAlpha(large_image,GetPixelAlpha(image,
+ pixels),q);
}
else if (magn_methy == 2 || magn_methy == 4)
{
if (i == 0)
- *q=(*pixels);
+ {
+ SetPixelRed(large_image,GetPixelRed(image,
+ pixels),q);
+ SetPixelGreen(large_image,GetPixelGreen(image,
+ pixels),q);
+ SetPixelBlue(large_image,GetPixelBlue(image,
+ pixels),q);
+ SetPixelAlpha(large_image,GetPixelAlpha(image,
+ pixels),q);
+ }
else
{
/* Interpolate */
- (*q).red=(QM) (((ssize_t) (2*i*((*n).red
- -(*pixels).red)+m))/((ssize_t) (m*2))
- +(*pixels).red);
- (*q).green=(QM) (((ssize_t) (2*i*((*n).green
- -(*pixels).green)+m))/((ssize_t) (m*2))
- +(*pixels).green);
- (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
- -(*pixels).blue)+m))/((ssize_t) (m*2))
- +(*pixels).blue);
+ SetPixelRed(large_image,((QM) (((ssize_t)
+ (2*i*(GetPixelRed(image,n)
+ -GetPixelRed(image,pixels)+m))/
+ ((ssize_t) (m*2))
+ +GetPixelRed(image,pixels)))),q);
+ SetPixelGreen(large_image,((QM) (((ssize_t)
+ (2*i*(GetPixelGreen(image,n)
+ -GetPixelGreen(image,pixels)+m))/
+ ((ssize_t) (m*2))
+ +GetPixelGreen(image,pixels)))),q);
+ SetPixelBlue(large_image,((QM) (((ssize_t)
+ (2*i*(GetPixelBlue(image,n)
+ -GetPixelBlue(image,pixels)+m))/
+ ((ssize_t) (m*2))
+ +GetPixelBlue(image,pixels)))),q);
if (image->matte != MagickFalse)
- (*q).opacity=(QM) (((ssize_t)
- (2*i*((*n).opacity
- -(*pixels).opacity)+m))
- /((ssize_t) (m*2))+(*pixels).opacity);
+ SetPixelAlpha(large_image, ((QM) (((ssize_t)
+ (2*i*(GetPixelAlpha(image,n)
+ -GetPixelAlpha(image,pixels)+m))
+ /((ssize_t) (m*2))+
+ GetPixelAlpha(image,pixels)))),q);
}
if (magn_methy == 4)
{
/* Replicate nearest */
if (i <= ((m+1) << 1))
- (*q).opacity=(*pixels).opacity+0;
+ SetPixelAlpha(large_image,GetPixelAlpha(image,
+ pixels),q);
else
- (*q).opacity=(*n).opacity+0;
+ SetPixelAlpha(large_image,GetPixelAlpha(image,
+ n),q);
}
}
{
/* Replicate nearest */
if (i <= ((m+1) << 1))
- *q=(*pixels);
+ {
+ SetPixelRed(large_image,GetPixelRed(image,
+ pixels),q);
+ SetPixelGreen(large_image,GetPixelGreen(image,
+ pixels),q);
+ SetPixelBlue(large_image,GetPixelBlue(image,
+ pixels),q);
+ SetPixelAlpha(large_image,GetPixelAlpha(image,
+ pixels),q);
+ }
else
- *q=(*n);
+ {
+ SetPixelRed(large_image,GetPixelRed(image,n),q);
+ SetPixelGreen(large_image,GetPixelGreen(image,n),
+ q);
+ SetPixelBlue(large_image,GetPixelBlue(image,n),
+ q);
+ SetPixelAlpha(large_image,GetPixelAlpha(image,n),
+ q);
+ }
if (magn_methy == 5)
{
- (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
- -(*pixels).opacity)+m))/((ssize_t) (m*2))
- +(*pixels).opacity);
+ SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
+ (GetPixelAlpha(image,n)
+ -GetPixelAlpha(image,pixels))
+ +m))/((ssize_t) (m*2))
+ +GetPixelAlpha(image,pixels)),q);
}
}
- n++;
- q++;
- pixels++;
+ n+=GetPixelChannels(image);
+ q+=GetPixelChannels(large_image);
+ pixels+=GetPixelChannels(image);
} /* x */
if (SyncAuthenticPixels(large_image,exception) == 0)
} /* i */
} /* y */
- prev=(PixelPacket *) RelinquishMagickMemory(prev);
- next=(PixelPacket *) RelinquishMagickMemory(next);
+ prev=(Quantum *) RelinquishMagickMemory(prev);
+ next=(Quantum *) RelinquishMagickMemory(next);
length=image->columns;
for (y=0; y < (ssize_t) image->rows; y++)
{
- register PixelPacket
+ register Quantum
*pixels;
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
- /* To do: Rewrite using Get/Set***PixelComponent() */
- pixels=q+(image->columns-length);
- n=pixels+1;
+ pixels=q+(image->columns-length)*GetPixelChannels(image);
+ n=pixels+GetPixelChannels(image);
for (x=(ssize_t) (image->columns-length);
x < (ssize_t) image->columns; x++)
{
- /* To do: Rewrite using Get/Set***PixelComponent() */
+ /* To do: Rewrite using Get/Set***PixelChannel() */
if (x == (ssize_t) (image->columns-length))
m=(ssize_t) mng_info->magn_ml;
if (magn_methx <= 1)
{
/* replicate previous */
- /* To do: Rewrite using Get/Set***PixelComponent() */
- *q=(*pixels);
+ SetPixelRed(image,GetPixelRed(image,pixels),q);
+ SetPixelGreen(image,GetPixelGreen(image,pixels),q);
+ SetPixelBlue(image,GetPixelBlue(image,pixels),q);
+ SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
}
else if (magn_methx == 2 || magn_methx == 4)
{
if (i == 0)
- *q=(*pixels);
-
+ {
+ SetPixelRed(image,GetPixelRed(image,pixels),q);
+ SetPixelGreen(image,GetPixelGreen(image,pixels),q);
+ SetPixelBlue(image,GetPixelBlue(image,pixels),q);
+ SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
+ }
+
+ /* To do: Rewrite using Get/Set***PixelChannel() */
else
{
/* Interpolate */
- (*q).red=(QM) ((2*i*((*n).red
- -(*pixels).red)+m)
- /((ssize_t) (m*2))+(*pixels).red);
- (*q).green=(QM) ((2*i*((*n).green
- -(*pixels).green)
- +m)/((ssize_t) (m*2))+(*pixels).green);
- (*q).blue=(QM) ((2*i*((*n).blue
- -(*pixels).blue)+m)
- /((ssize_t) (m*2))+(*pixels).blue);
+ SetPixelRed(image,(QM) ((2*i*(
+ GetPixelRed(image,n)
+ -GetPixelRed(image,pixels))+m)
+ /((ssize_t) (m*2))+
+ GetPixelRed(image,pixels)),q);
+
+ SetPixelGreen(image,(QM) ((2*i*(
+ GetPixelGreen(image,n)
+ -GetPixelGreen(image,pixels))+m)
+ /((ssize_t) (m*2))+
+ GetPixelGreen(image,pixels)),q);
+
+ SetPixelBlue(image,(QM) ((2*i*(
+ GetPixelBlue(image,n)
+ -GetPixelBlue(image,pixels))+m)
+ /((ssize_t) (m*2))+
+ GetPixelBlue(image,pixels)),q);
if (image->matte != MagickFalse)
- (*q).opacity=(QM) ((2*i*((*n).opacity
- -(*pixels).opacity)+m)/((ssize_t) (m*2))
- +(*pixels).opacity);
+ SetPixelAlpha(image,(QM) ((2*i*(
+ GetPixelAlpha(image,n)
+ -GetPixelAlpha(image,pixels))+m)
+ /((ssize_t) (m*2))+
+ GetPixelAlpha(image,pixels)),q);
}
if (magn_methx == 4)
{
/* Replicate nearest */
if (i <= ((m+1) << 1))
- (*q).opacity=(*pixels).opacity+0;
+ {
+ SetPixelAlpha(image,
+ GetPixelAlpha(image,pixels)+0,q);
+ }
else
- (*q).opacity=(*n).opacity+0;
+ {
+ SetPixelAlpha(image,
+ GetPixelAlpha(image,n)+0,q);
+ }
}
}
{
/* Replicate nearest */
if (i <= ((m+1) << 1))
- *q=(*pixels);
+ {
+ SetPixelRed(image,GetPixelRed(image,pixels),q);
+ SetPixelGreen(image,GetPixelGreen(image,pixels),q);
+ SetPixelBlue(image,GetPixelBlue(image,pixels),q);
+ SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
+ }
else
- *q=(*n);
+ {
+ SetPixelRed(image,GetPixelRed(image,n),q);
+ SetPixelGreen(image,GetPixelGreen(image,n),q);
+ SetPixelBlue(image,GetPixelBlue(image,n),q);
+ SetPixelAlpha(image,GetPixelAlpha(image,n),q);
+ }
if (magn_methx == 5)
{
/* Interpolate */
- (*q).opacity=(QM) ((2*i*((*n).opacity
- -(*pixels).opacity)+m) /((ssize_t) (m*2))
- +(*pixels).opacity);
+ SetPixelAlpha(image,
+ (QM) ((2*i*( GetPixelAlpha(image,n)
+ -GetPixelAlpha(image,pixels))+m)/
+ ((ssize_t) (m*2))
+ +GetPixelAlpha(image,pixels)),q);
}
}
- q++;
+ q+=GetPixelChannels(image);
}
- n++;
- p++;
+ n+=GetPixelChannels(image);
+ p+=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
for (x=(ssize_t) image->columns-1; x >= 0; x--)
{
- SetRedPixelComponent(q,ScaleShortToQuantum(
- GetRedPixelComponent(q));
- SetGreenPixelComponent(q,ScaleShortToQuantum(
- GetGreenPixelComponent(q));
- SetBluePixelComponent(q,ScaleShortToQuantum(
- GetBluePixelComponent(q));
- SetOpacityPixelComponent(q,ScaleShortToQuantum(
- GetOpacityPixelComponent(q));
- q++;
+ SetPixelRed(image,ScaleShortToQuantum(
+ GetPixelRed(image,q)),q);
+ SetPixelGreen(image,ScaleShortToQuantum(
+ GetPixelGreen(image,q)),q);
+ SetPixelBlue(image,ScaleShortToQuantum(
+ GetPixelBlue(image,q)),q);
+ SetPixelAlpha(image,ScaleShortToQuantum(
+ GetPixelAlpha(image,q)),q);
+ q+=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" No images found. Inserting a background layer.");
- if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
+ if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
{
/*
Allocate next image structure.
%
% The format of the WriteMNGImage method is:
%
-% MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
+% MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
+% Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows.
%
%
% o image: The image.
%
+% o exception: return any errors or warnings in this structure.
%
% To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
% "To do" under ReadPNGImage):
allocated_length);
dp+=description_length;
*dp++='\n';
- (void) FormatMagickString(dp,allocated_length-
+ (void) FormatLocaleString(dp,allocated_length-
(png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
dp+=8;
/* Write one PNG image */
static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
- const ImageInfo *IMimage_info,Image *IMimage)
+ const ImageInfo *IMimage_info,Image *IMimage,ExceptionInfo *exception)
{
Image
*image;
ping_need_colortype_warning,
status,
+ tried_332,
tried_333,
tried_444;
ping_preserve_colormap = mng_info->ping_preserve_colormap;
ping_need_colortype_warning = MagickFalse;
+ /* Recognize the ICC sRGB profile and convert it to the sRGB chunk,
+ * i.e., eliminate the ICC profile and set image->rendering_intent.
+ * Note that this will not involve any changes to the actual pixels
+ * but merely passes information to applications that read the resulting
+ * PNG image.
+ */
+ if (ping_exclude_sRGB == MagickFalse)
+ {
+ char
+ *name;
+
+ const StringInfo
+ *profile;
+
+ ResetImageProfileIterator(image);
+ for (name=GetNextImageProfile(image); name != (const char *) NULL; )
+ {
+ profile=GetImageProfile(image,name);
+
+ if (profile != (StringInfo *) NULL)
+ {
+ if ((LocaleCompare(name,"ICC") == 0) ||
+ (LocaleCompare(name,"ICM") == 0))
+ {
+ unsigned char
+ *data;
+
+ png_uint_32
+ length;
+
+ length=(png_uint_32) GetStringInfoLength(profile);
+
+ if (length == 3144)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " got a 3144-byte ICC profile (potentially sRGB)");
+
+ data=GetStringInfoDatum(profile);
+
+ if (data[52]=='s' && data[53]=='R' &&
+ data[54]=='G' && data[55]=='B')
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " It is the HP-Microsoft sRGB)");
+ if (image->rendering_intent==UndefinedIntent);
+ image->rendering_intent=PerceptualIntent;
+ }
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " It is not sRGB (%c%c%c%c)",data[52],
+ data[53],data[54],data[55]);
+
+ }
+ else if (length == 3052)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " got a 3052-byte ICC profile (potentially sRGB)");
+
+ data=GetStringInfoDatum(profile);
+
+ if (data[336]=='s' && data[337]=='R' &&
+ data[338]=='G' && data[339]=='B')
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " It is the ICC no-black sRGB)");
+ if (image->rendering_intent==UndefinedIntent);
+ image->rendering_intent=PerceptualIntent;
+ }
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " It is not sRGB (%c%c%c%c)",data[52],
+ data[53],data[54],data[55]);
+
+ }
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " got a %lu-byte ICC profile",
+ (unsigned long) length);
+ }
+ }
+ name=GetNextImageProfile(image);
+ }
+ }
+
number_opaque = 0;
number_semitransparent = 0;
number_transparent = 0;
" storage_class=PseudoClass");
}
+ if (image->storage_class == PseudoClass &&
+ (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
+ (mng_info->write_png_colortype != 0 &&
+ mng_info->write_png_colortype != 4)))
+ {
+ (void) SyncImage(image);
+ image->storage_class = DirectClass;
+ }
+
if (ping_preserve_colormap == MagickFalse)
{
if (image->storage_class != PseudoClass && image->colormap != NULL)
image->colormap=NULL;
}
}
-
- if (image->colorspace != RGBColorspace)
+
+ if (IsRGBColorspace(image->colorspace) == MagickFalse)
(void) TransformImageColorspace(image,RGBColorspace);
/*
}
#endif
-#if 0 /* To do: Option to use the original colormap */
- if (ping_preserve_colormap != MagickFalse)
- {
- }
-#endif
-
-#if 0 /* To do: respect the -depth option */
+ /* Respect the -depth option */
if (image->depth < MAGICKCORE_QUANTUM_DEPTH)
{
- }
-#endif
+ register Quantum
+ *r;
- /* To do: set to next higher multiple of 8 */
- if (image->depth < 8)
- image->depth=8;
+ ExceptionInfo
+ *exception;
-#if (MAGICKCORE_QUANTUM_DEPTH > 16)
- /* PNG does not handle depths greater than 16 so reduce it even
- * if lossy
- */
- if (image->depth > 16)
- image->depth=16;
-#endif
+ exception=(&image->exception);
-#if (MAGICKCORE_QUANTUM_DEPTH > 8)
- if (image->depth == 16 && mng_info->write_png_depth != 16)
- if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
- image->depth = 8;
-#endif
+ if (image->depth > 8)
+ {
+#if MAGICKCORE_QUANTUM_DEPTH > 16
+ /* Scale to 16-bit */
+ LBR16PacketRGBO(image->background_color);
- /* Normally we run this just once, but in the case of writing PNG8
- * we reduce the transparency to binary and run again, then if there
- * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
- * RGBA palette and run again, and finally to a simple 3-3-2-1 RGBA
- * palette. The final reduction can only fail if there are still 256
- * colors present and one of them has both transparent and opaque instances.
- */
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ r=GetAuthenticPixels(image,0,y,image->columns,1,
+ exception);
- tried_333 = MagickFalse;
- tried_444 = MagickFalse;
+ if (r == (Quantum *) NULL)
+ break;
- for (j=0; j<5; j++)
- {
- /* BUILD_PALETTE
- *
- * Sometimes we get DirectClass images that have 256 colors or fewer.
- * This code will build a colormap.
- *
- * Also, sometimes we get PseudoClass images with an out-of-date
- * colormap. This code will replace the colormap with a new one.
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ LBR16PixelRGBA(r);
+ r++;
+ }
+
+ if (SyncAuthenticPixels(image,exception) == MagickFalse)
+ break;
+ }
+
+ if (image->storage_class == PseudoClass && image->colormap != NULL)
+ {
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ LBR16PacketRGBO(image->colormap[i]);
+ }
+ }
+#endif /* MAGICKCORE_QUANTUM_DEPTH > 16 */
+ }
+
+ else if (image->depth > 4)
+ {
+#if MAGICKCORE_QUANTUM_DEPTH > 8
+ /* Scale to 8-bit */
+ LBR08PacketRGBO(image->background_color);
+
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ r=GetAuthenticPixels(image,0,y,image->columns,1,
+ exception);
+
+ if (r == (Quantum *) NULL)
+ break;
+
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ LBR08PixelRGBA(r);
+ r++;
+ }
+
+ if (SyncAuthenticPixels(image,exception) == MagickFalse)
+ break;
+ }
+
+ if (image->storage_class == PseudoClass && image->colormap != NULL)
+ {
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ LBR08PacketRGBO(image->colormap[i]);
+ }
+ }
+#endif /* MAGICKCORE_QUANTUM_DEPTH > 8 */
+ }
+ else
+ if (image->depth > 2)
+ {
+ /* Scale to 4-bit */
+ LBR04PacketRGBO(image->background_color);
+
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ r=GetAuthenticPixels(image,0,y,image->columns,1,
+ exception);
+
+ if (r == (Quantum *) NULL)
+ break;
+
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ LBR04PixelRGBA(r);
+ r++;
+ }
+
+ if (SyncAuthenticPixels(image,exception) == MagickFalse)
+ break;
+ }
+
+ if (image->storage_class == PseudoClass && image->colormap != NULL)
+ {
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ LBR04PacketRGBO(image->colormap[i]);
+ }
+ }
+ }
+
+ else if (image->depth > 1)
+ {
+ /* Scale to 2-bit */
+ LBR02PacketRGBO(image->background_color);
+
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ r=GetAuthenticPixels(image,0,y,image->columns,1,
+ exception);
+
+ if (r == (Quantum *) NULL)
+ break;
+
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ LBR02PixelRGBA(r);
+ r++;
+ }
+
+ if (SyncAuthenticPixels(image,exception) == MagickFalse)
+ break;
+ }
+
+ if (image->storage_class == PseudoClass && image->colormap != NULL)
+ {
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ LBR02PacketRGBO(image->colormap[i]);
+ }
+ }
+ }
+ else
+ {
+ /* Scale to 1-bit */
+ LBR01PacketRGBO(image->background_color);
+
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ r=GetAuthenticPixels(image,0,y,image->columns,1,
+ exception);
+
+ if (r == (Quantum *) NULL)
+ break;
+
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ LBR01PixelRGBA(r);
+ r++;
+ }
+
+ if (SyncAuthenticPixels(image,exception) == MagickFalse)
+ break;
+ }
+
+ if (image->storage_class == PseudoClass && image->colormap != NULL)
+ {
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ LBR01PacketRGBO(image->colormap[i]);
+ }
+ }
+ }
+ }
+
+ /* To do: set to next higher multiple of 8 */
+ if (image->depth < 8)
+ image->depth=8;
+
+#if (MAGICKCORE_QUANTUM_DEPTH > 16)
+ /* PNG does not handle depths greater than 16 so reduce it even
+ * if lossy
+ */
+ if (image->depth > 8)
+ image->depth=16;
+#endif
+
+#if (MAGICKCORE_QUANTUM_DEPTH > 8)
+ if (image->depth == 16 && mng_info->write_png_depth != 16)
+ if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
+ image->depth = 8;
+#endif
+
+ /* Normally we run this just once, but in the case of writing PNG8
+ * we reduce the transparency to binary and run again, then if there
+ * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
+ * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
+ * palette. Then (To do) we take care of a final reduction that is only
+ * needed if there are still 256 colors present and one of them has both
+ * transparent and opaque instances.
+ */
+
+ tried_332 = MagickFalse;
+ tried_333 = MagickFalse;
+ tried_444 = MagickFalse;
+
+ for (j=0; j<6; j++)
+ {
+ /* BUILD_PALETTE
+ *
+ * Sometimes we get DirectClass images that have 256 colors or fewer.
+ * This code will build a colormap.
+ *
+ * Also, sometimes we get PseudoClass images with an out-of-date
+ * colormap. This code will replace the colormap with a new one.
* Sometimes we get PseudoClass images that have more than 256 colors.
* This code will delete the colormap and change the image to
* DirectClass.
*
- * If image->matte is MagickFalse, we ignore the opacity channel
+ * If image->matte is MagickFalse, we ignore the alpha channel
* even though it sometimes contains left-over non-opaque values.
*
* Also we gather some information (number of opaque, transparent,
semitransparent[260],
transparent[260];
- register IndexPacket
- *indexes;
+ register const Quantum
+ *s;
- register const PixelPacket
- *s,
- *q;
-
- register PixelPacket
+ register Quantum
+ *q,
*r;
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Original colormap:");
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " i (red,green,blue,opacity)");
+ " i (red,green,blue,alpha)");
for (i=0; i < 256; i++)
{
(int) image->colormap[i].red,
(int) image->colormap[i].green,
(int) image->colormap[i].blue,
- (int) image->colormap[i].opacity);
+ (int) image->colormap[i].alpha);
}
for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
(int) image->colormap[i].red,
(int) image->colormap[i].green,
(int) image->colormap[i].blue,
- (int) image->colormap[i].opacity);
+ (int) image->colormap[i].alpha);
}
}
}
{
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
if (image->matte == MagickFalse ||
- GetOpacityPixelComponent(q) == OpaqueOpacity)
+ GetPixelAlpha(image,q) == OpaqueAlpha)
{
if (number_opaque < 259)
{
if (number_opaque == 0)
{
- GetRGBPixelComponents(q, opaque[0]);
- opaque[0].opacity=OpaqueOpacity;
+ GetPixelPacket(image, q, opaque);
+ opaque[0].alpha=OpaqueAlpha;
number_opaque=1;
}
for (i=0; i< (ssize_t) number_opaque; i++)
{
- if (IsColorEqual(q, opaque+i))
+ if (IsPixelEquivalent(image,q, opaque+i))
break;
}
number_opaque < 259)
{
number_opaque++;
- GetRGBPixelComponents(q, opaque[i]);
- opaque[i].opacity=OpaqueOpacity;
+ GetPixelPacket(image, q, opaque+i);
+ opaque[i].alpha=OpaqueAlpha;
}
}
}
- else if (q->opacity == TransparentOpacity)
+ else if (GetPixelAlpha(image,q) == TransparentAlpha)
{
if (number_transparent < 259)
{
if (number_transparent == 0)
{
- GetRGBOPixelComponents(q, transparent[0]);
- ping_trans_color.red=
- (unsigned short) GetRedPixelComponent(q);
- ping_trans_color.green=
- (unsigned short) GetGreenPixelComponent(q);
- ping_trans_color.blue=
- (unsigned short) GetBluePixelComponent(q);
- ping_trans_color.gray=
- (unsigned short) GetRedPixelComponent(q);
+ GetPixelPacket(image, q, transparent);
+ ping_trans_color.red=(unsigned short)
+ GetPixelRed(image,q);
+ ping_trans_color.green=(unsigned short)
+ GetPixelGreen(image,q);
+ ping_trans_color.blue=(unsigned short)
+ GetPixelBlue(image,q);
+ ping_trans_color.gray=(unsigned short)
+ GetPixelRed(image,q);
number_transparent = 1;
}
for (i=0; i< (ssize_t) number_transparent; i++)
{
- if (IsColorEqual(q, transparent+i))
+ if (IsPixelEquivalent(image,q, transparent+i))
break;
}
number_transparent < 259)
{
number_transparent++;
- GetRGBOPixelComponents(q, transparent[i]);
+ GetPixelPacket(image,q,transparent+i);
}
}
}
{
if (number_semitransparent == 0)
{
- GetRGBOPixelComponents(q, semitransparent[0]);
+ GetPixelPacket(image,q,semitransparent);
number_semitransparent = 1;
}
for (i=0; i< (ssize_t) number_semitransparent; i++)
{
- if (IsColorEqual(q, semitransparent+i)
- && GetOpacityPixelComponent(q) ==
- semitransparent[i].opacity)
+ if (IsPixelEquivalent(image,q, semitransparent+i)
+ && GetPixelAlpha(image,q) ==
+ semitransparent[i].alpha)
break;
}
number_semitransparent < 259)
{
number_semitransparent++;
- GetRGBOPixelComponents(q, semitransparent[i]);
+ GetPixelPacket(image, q, semitransparent+i);
}
}
}
- q++;
+ q+=GetPixelChannels(image);
}
}
- if (ping_exclude_bKGD == MagickFalse)
+ if (mng_info->write_png8 == MagickFalse &&
+ ping_exclude_bKGD == MagickFalse)
{
/* Add the background color to the palette, if it
* isn't already there.
{
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
+ break;
+
+ s=q;
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
+ GetPixelRed(image,s) != GetPixelBlue(image,s))
+ {
+ ping_have_color=MagickTrue;
+ ping_have_non_bw=MagickTrue;
+ break;
+ }
+ s+=GetPixelChannels(image);
+ }
+
+ if (ping_have_color != MagickFalse)
break;
/* Worst case is black-and-white; we are looking at every
* pixel twice.
*/
- if (ping_have_color == MagickFalse)
- {
- s=q;
- for (x=0; x < (ssize_t) image->columns; x++)
- {
- if (GetRedPixelComponent(s) != GetGreenPixelComponent(s)
- || GetRedPixelComponent(s) != GetBluePixelComponent(s))
- {
- ping_have_color=MagickTrue;
- ping_have_non_bw=MagickTrue;
- break;
- }
- s++;
- }
- }
-
if (ping_have_non_bw == MagickFalse)
{
s=q;
for (x=0; x < (ssize_t) image->columns; x++)
{
- if (GetRedPixelComponent(s) != 0 &&
- GetRedPixelComponent(s) != QuantumRange)
+ if (GetPixelRed(image,s) != 0 &&
+ GetPixelRed(image,s) != QuantumRange)
{
ping_have_non_bw=MagickTrue;
+ break;
}
- s++;
+ s+=GetPixelChannels(image);
}
- }
+ }
}
- }
- }
+ }
+ }
if (image_colors < 257)
{
PixelPacket
colormap[260];
-
+
/*
* Initialize image colormap.
*/
ping_background.index +=
(number_transparent + number_semitransparent);
-
+
/* image_colors < 257; search the colormap instead of the pixels
* to get ping_have_color and ping_have_non_bw
*/
image->colors = image_colors;
- if (AcquireImageColormap(image,image_colors) ==
+ if (AcquireImageColormap(image,image_colors,exception) ==
MagickFalse)
ThrowWriterException(ResourceLimitError,
"MemoryAllocationFailed");
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" image->colors=%d (%d)",
(int) image->colors, image_colors);
-
+
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Update the pixel indexes");
}
q=GetAuthenticPixels(image,0,y,image->columns,1,
exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
- indexes=GetAuthenticIndexQueue(image);
-
+
for (x=0; x < (ssize_t) image->columns; x++)
{
for (i=0; i< (ssize_t) image_colors; i++)
{
if ((image->matte == MagickFalse ||
- image->colormap[i].opacity ==
- GetOpacityPixelComponent(q)) &&
- image->colormap[i].red ==
- GetRedPixelComponent(q) &&
- image->colormap[i].green ==
- GetGreenPixelComponent(q) &&
- image->colormap[i].blue ==
- GetBluePixelComponent(q))
+ image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
+ image->colormap[i].red == GetPixelRed(image,q) &&
+ image->colormap[i].green == GetPixelGreen(image,q) &&
+ image->colormap[i].blue == GetPixelBlue(image,q))
{
- SetIndexPixelComponent(indexes+x,i);
+ SetPixelIndex(image,i,q);
break;
}
}
- q++;
+ q+=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
if (image->colormap != NULL)
{
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " i (red,green,blue,opacity)");
+ " i (red,green,blue,alpha)");
for (i=0; i < (ssize_t) image->colors; i++)
{
(int) image->colormap[i].red,
(int) image->colormap[i].green,
(int) image->colormap[i].blue,
- (int) image->colormap[i].opacity);
+ (int) image->colormap[i].alpha);
}
}
}
break;
/* PNG8 can't have semitransparent colors so we threshold the
- * opacity to 0 or OpaqueOpacity
+ * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
+ * transparent color so if more than one is transparent we merge
+ * them into image->background_color.
*/
- if (number_semitransparent != 0)
+ if (number_semitransparent != 0 || number_transparent > 1)
{
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Thresholding the alpha channel to binary");
r=GetAuthenticPixels(image,0,y,image->columns,1,
exception);
- if (r == (PixelPacket *) NULL)
+ if (r == (Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- SetOpacityPixelComponent(r,
- (GetOpacityPixelComponent(r) > TransparentOpacity/2) ?
- TransparentOpacity : OpaqueOpacity);
- r++;
+ if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
+ {
+ SetPixelPacket(image,&image->background_color,r);
+ SetPixelAlpha(image,TransparentAlpha,r);
+ }
+ else
+ SetPixelAlpha(image,OpaqueAlpha,r);
+ r+=GetPixelChannels(image);
}
-
+
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
if (image_colors != 0 && image_colors <= 256 &&
image->colormap != NULL)
for (i=0; i<image_colors; i++)
- image->colormap[i].opacity =
- image->colormap[i].opacity > TransparentOpacity/2 ?
- TransparentOpacity : OpaqueOpacity;
+ image->colormap[i].alpha =
+ (image->colormap[i].alpha > TransparentAlpha/2 ?
+ TransparentAlpha : OpaqueAlpha);
}
continue;
}
tried_444 = MagickTrue;
- image->background_color.red=
- ScaleCharToQuantum(
- (ScaleQuantumToChar(image->background_color.red) & 0xf0) |
- (ScaleQuantumToChar(image->background_color.red) & 0xf0) >> 4);
- image->background_color.green=
- ScaleCharToQuantum(
- (ScaleQuantumToChar(image->background_color.green) & 0xf0) |
- (ScaleQuantumToChar(image->background_color.green) & 0xf0) >> 4);
- image->background_color.blue=
- ScaleCharToQuantum(
- (ScaleQuantumToChar(image->background_color.blue) & 0xf0) |
- (ScaleQuantumToChar(image->background_color.blue) & 0xf0) >> 4);
+ LBR04PacketRGB(image->background_color);
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
r=GetAuthenticPixels(image,0,y,image->columns,1,
exception);
- if (r == (PixelPacket *) NULL)
+ if (r == (Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- if (GetOpacityPixelComponent(r) == TransparentOpacity)
- {
- SetRGBPixelComponents(r,image->background_color);
- }
- else
- {
- SetRedPixelComponent(r,ScaleCharToQuantum(
- ScaleQuantumToChar(GetRedPixelComponent(r) & 0xf0) |
- ScaleQuantumToChar(GetRedPixelComponent(r) & 0xf0) >> 4));
- SetGreenPixelComponent(r,ScaleCharToQuantum(
- ScaleQuantumToChar(GetGreenPixelComponent(r) & 0xf0) |
- ScaleQuantumToChar(GetGreenPixelComponent(r) & 0xf0) >> 4));
- SetBluePixelComponent(r,ScaleCharToQuantum(
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xf0) |
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xf0) >> 4));
- }
+ if (GetPixelAlpha(image,r) == OpaqueAlpha)
+ LBR04PixelRGB(r);
r++;
}
-
+
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
}
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Quantizing the colormap to 4-4-4");
+
for (i=0; i<image_colors; i++)
{
- image->colormap[i].red=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->colormap[i].red) & 0xf0) |
- (ScaleQuantumToChar(image->colormap[i].red) & 0xf0) >> 4);
- image->colormap[i].green=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->colormap[i].green) & 0xf0) |
- (ScaleQuantumToChar(image->colormap[i].green) & 0xf0) >> 4);
- image->colormap[i].blue=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xf0) |
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xf0 >> 4));
+ LBR04PacketRGB(image->colormap[i]);
}
}
continue;
tried_333 = MagickTrue;
- image->background_color.red=
- ScaleCharToQuantum(
- (ScaleQuantumToChar(image->background_color.red) & 0xe0) |
- (ScaleQuantumToChar(image->background_color.red) & 0xe0) >> 3 |
- (ScaleQuantumToChar(image->background_color.red) & 0xc0) >> 6);
- image->background_color.green=
- ScaleCharToQuantum(
- (ScaleQuantumToChar(image->background_color.green) & 0xe0) |
- (ScaleQuantumToChar(image->background_color.green) & 0xe0) >> 3 |
- (ScaleQuantumToChar(image->background_color.green) & 0xc0) >> 6);
- image->background_color.blue=
- ScaleCharToQuantum(
- (ScaleQuantumToChar(image->background_color.blue) & 0xe0) |
- (ScaleQuantumToChar(image->background_color.blue) & 0xe0) >> 3 |
- (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 6);
+ LBR03PacketRGB(image->background_color);
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
r=GetAuthenticPixels(image,0,y,image->columns,1,
exception);
- if (r == (PixelPacket *) NULL)
+ if (r == (Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- if (GetOpacityPixelComponent(r) == TransparentOpacity)
- {
- SetRGBPixelComponents(r,image->background_color);
- }
- else
- {
- SetRedPixelComponent(r,ScaleCharToQuantum(
- ScaleQuantumToChar(GetRedPixelComponent(r) & 0xe0) |
- ScaleQuantumToChar(GetRedPixelComponent(r) & 0xe0) >> 3 |
- ScaleQuantumToChar(GetRedPixelComponent(r) & 0xc0) >> 6));
- SetGreenPixelComponent(r,ScaleCharToQuantum(
- ScaleQuantumToChar(GetGreenPixelComponent(r) & 0xe0) |
- ScaleQuantumToChar(GetGreenPixelComponent(r) & 0xe0) >> 3 |
- ScaleQuantumToChar(GetGreenPixelComponent(r) & 0xc0) >> 6));
- SetBluePixelComponent(r,ScaleCharToQuantum(
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xe0) |
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xe0) >> 3 |
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xc0) >> 6));
- }
+ if (GetPixelAlpha(image,r) == OpaqueAlpha)
+ LBR03RGB(r);
r++;
}
-
+
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
}
" Quantizing the colormap to 3-3-3-1");
for (i=0; i<image_colors; i++)
{
- image->colormap[i].red=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->colormap[i].red) & 0xe0) |
- (ScaleQuantumToChar(image->colormap[i].red) & 0xe0) >> 3 |
- (ScaleQuantumToChar(image->colormap[i].red) & 0xc0) >> 6);
- image->colormap[i].green=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->colormap[i].green) & 0xe0) |
- (ScaleQuantumToChar(image->colormap[i].green) & 0xe0) >> 3 |
- (ScaleQuantumToChar(image->colormap[i].green) & 0xc0) >> 6);
- image->colormap[i].blue=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xe0) |
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xe0) >> 3 |
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 6);
+ LBR03PacketRGB(image->colormap[i]);
}
}
continue;
}
- if (image_colors == 0 || image_colors > 256)
+ if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
{
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Quantizing the background color to 3-3-2");
+ tried_332 = MagickTrue;
+
/* Red and green were already done so we only quantize the blue
* channel
*/
- image->background_color.blue=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->background_color.blue) & 0xc0) |
- (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 2 |
- (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 4 |
- (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 6);
+ LBR02PacketBlue(image->background_color);
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
r=GetAuthenticPixels(image,0,y,image->columns,1,
exception);
- if (r == (PixelPacket *) NULL)
+ if (r == (Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- if (GetOpacityPixelComponent(r) == TransparentOpacity)
- {
- SetRGBPixelComponents(r,image->background_color);
- }
- else
- {
- SetBluePixelComponent(r,ScaleCharToQuantum(
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xc0) |
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xc0) >> 2 |
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xc0) >> 4 |
- ScaleQuantumToChar(GetBluePixelComponent(r) & 0xc0) >> 6));
- }
+ if (GetPixelAlpha(image,r) == OpaqueAlpha)
+ LBR02PixelBlue(r);
r++;
}
-
+
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
}
" Quantizing the colormap to 3-3-2-1");
for (i=0; i<image_colors; i++)
{
- image->colormap[i].blue=ScaleCharToQuantum(
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) |
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 2 |
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 4 |
- (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 6);
+ LBR02PacketBlue(image->colormap[i]);
}
}
continue;
}
break;
+
+ if (image_colors == 0 || image_colors > 256)
+ {
+ /* Take care of special case with 256 colors + 1 transparent
+ * color. We don't need to quantize to 2-3-2-1; we only need to
+ * eliminate one color, so we'll merge the two darkest red
+ * colors (0x49, 0, 0) -> (0x24, 0, 0).
+ */
+ if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
+ ScaleQuantumToChar(image->background_color.green) == 0x00 &&
+ ScaleQuantumToChar(image->background_color.blue) == 0x00)
+ {
+ image->background_color.red=ScaleCharToQuantum(0x24);
+ }
+
+ if (image->colormap == NULL)
+ {
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ r=GetAuthenticPixels(image,0,y,image->columns,1,
+ exception);
+
+ if (r == (Quantum *) NULL)
+ break;
+
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
+ ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
+ ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
+ GetPixelAlpha(image,r) == OpaqueAlpha)
+ {
+ SetPixelRed(image,ScaleCharToQuantum(0x24),r);
+ }
+ r+=GetPixelChannels(image);
+ }
+
+ if (SyncAuthenticPixels(image,exception) == MagickFalse)
+ break;
+
+ }
+ }
+
+ else
+ {
+ for (i=0; i<image_colors; i++)
+ {
+ if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
+ ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
+ ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(0x24);
+ }
+ }
+ }
+ }
}
/* END OF BUILD_PALETTE */
if (mng_info->ping_exclude_tRNS != MagickFalse &&
(number_transparent != 0 || number_semitransparent != 0))
{
- int colortype=mng_info->write_png_colortype;
+ unsigned int colortype=mng_info->write_png_colortype;
if (ping_have_color == MagickFalse)
mng_info->write_png_colortype = 5;
mng_info->write_png_colortype = 7;
if (colortype != 0 &&
- mng_info->write_png_colortype != (ssize_t) colortype)
+ mng_info->write_png_colortype != colortype)
ping_need_colortype_warning=MagickTrue;
}
ExceptionInfo
*exception;
- register const PixelPacket
+ register const Quantum
*q;
exception=(&image->exception);
{
q=GetVirtualPixels(image,0,y,image->columns,1, exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- if (q->opacity != TransparentOpacity &&
- (unsigned short) GetRedPixelComponent(q) ==
- ping_trans_color.red &&
- (unsigned short) GetGreenPixelComponent(q) ==
- ping_trans_color.green &&
- (unsigned short) GetBluePixelComponent(q) ==
- ping_trans_color.blue)
+ if (GetPixelAlpha(image,q) != TransparentAlpha &&
+ (unsigned short) GetPixelRed(image,q) ==
+ ping_trans_color.red &&
+ (unsigned short) GetPixelGreen(image,q) ==
+ ping_trans_color.green &&
+ (unsigned short) GetPixelBlue(image,q) ==
+ ping_trans_color.blue)
{
ping_have_cheap_transparency = MagickFalse;
break;
}
- q++;
+ q+=GetPixelChannels(image);
}
-
+
if (ping_have_cheap_transparency == MagickFalse)
break;
}
break;
}
}
-
+
if (logging != MagickFalse)
{
if (ping_have_cheap_transparency == MagickFalse)
}
} /* end of write_png8 */
- else if (mng_info->write_png24)
+ else if (mng_info->write_png24 || mng_info->write_png_colortype == 3)
{
image_matte=MagickFalse;
ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
}
- else if (mng_info->write_png32)
+ else if (mng_info->write_png32 || mng_info->write_png_colortype == 7)
{
image_matte=MagickTrue;
ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
else
{
unsigned int
- mask;
+ mask;
mask=0xffff;
(ScaleQuantumToShort(image->colormap[0].blue) & mask);
ping_trans_color.gray=(png_uint_16)
- (ScaleQuantumToShort(PixelIntensityToQuantum(
+ (ScaleQuantumToShort(GetPixelPacketIntensity(
image->colormap)) & mask);
ping_trans_color.index=(png_byte) 0;
image_depth=MAGICKCORE_QUANTUM_DEPTH;
if ((image_colors == 0) ||
- ((ssize_t) (image_colors-1) > MaxColormapSize))
+ ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
image_colors=(int) (one << image_depth);
if (image_depth > 8)
ping_bit_depth=1;
one=1;
- while ((one << ping_bit_depth) < number_colors)
+ while ((one << ping_bit_depth) < (size_t) number_colors)
ping_bit_depth <<= 1;
}
for (i=0; i < ping_num_trans; i++)
{
- ping_trans_alpha[i]= (png_byte) (255-
- ScaleQuantumToChar(image->colormap[i].opacity));
+ ping_trans_alpha[i]= (png_byte)
+ ScaleQuantumToChar(image->colormap[i].alpha);
}
}
}
{
ping_background.gray=(png_uint_16)
- (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
+ ((maxval/255.)*((GetPixelPacketIntensity(&image->background_color)))
+ +.5);
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
ping_have_bKGD = MagickTrue;
}
- ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
- ping_trans_color.gray));
+ if (logging != MagickFalse)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Scaling ping_trans_color.gray from %d",
+ (int)ping_trans_color.gray);
+
+ ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
+ ping_trans_color.gray)+.5);
+
+ if (logging != MagickFalse)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " to %d", (int)ping_trans_color.gray);
}
if (ping_exclude_bKGD == MagickFalse)
png_set_compression_mem_level(ping, 9);
+ /* Untangle the "-quality" setting:
+
+ Undefined is 0; the default is used.
+ Default is 75
+
+ 10's digit:
+
+ 0: Use Z_HUFFMAN_ONLY strategy with the
+ zlib default compression level
+
+ 1-9: the zlib compression level
+
+ 1's digit:
+
+ 0-4: the PNG filter method
+
+ 5: libpng adaptive filtering if compression level > 5
+ libpng filter type "none" if compression level <= 5
+ or if image is grayscale or palette
+
+ 6: libpng adaptive filtering
+
+ 7: "LOCO" filtering (intrapixel differing) if writing
+ a MNG, othewise "none". Did not work in IM-6.7.0-9
+ and earlier because of a missing "else".
+
+ 8: Z_RLE strategy, all filters
+ Unused prior to IM-6.7.0-10, was same as 6
+
+ 9: Z_RLE strategy, no PNG filters
+ Unused prior to IM-6.7.0-10, was same as 6
+
+ Note that using the -quality option, not all combinations of
+ PNG filter type, zlib compression level, and zlib compression
+ strategy are possible. This will be addressed soon in a
+ release that accomodates "-define PNG:compression-strategy", etc.
+
+ */
+
quality=image->quality == UndefinedCompressionQuality ? 75UL :
image->quality;
- if (quality > 9)
+ if (quality <= 9)
+ {
+ if (mng_info->write_png_compression_strategy == 0)
+ mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
+ }
+
+ else if (mng_info->write_png_compression_level == 0)
{
int
level;
level=(int) MagickMin((ssize_t) quality/10,9);
- if (logging != MagickFalse)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Compression level: %d",level);
-
- png_set_compression_level(ping,level);
+ mng_info->write_png_compression_level = level+1;
}
- else
+ if (mng_info->write_png_compression_strategy == 0)
{
- if (logging != MagickFalse)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Compression strategy: Z_HUFFMAN_ONLY");
-
- png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
+ if ((quality %10) == 8 || (quality %10) == 9)
+ mng_info->write_png_compression_strategy=Z_RLE;
}
- if (logging != MagickFalse)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Setting up filtering");
+ if (mng_info->write_png_compression_filter == 0)
+ mng_info->write_png_compression_filter=((int) quality % 10) + 1;
-#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
- /* This became available in libpng-1.0.9. Output must be a MNG. */
- if (mng_info->write_mng && ((quality % 10) == 7))
+ if (logging != MagickFalse)
{
- if (logging != MagickFalse)
+ if (mng_info->write_png_compression_level)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
-
- ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
- }
+ " Compression level: %d",
+ (int) mng_info->write_png_compression_level-1);
- else
- if (logging != MagickFalse)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Filter_type: 0");
-#endif
+ if (mng_info->write_png_compression_strategy)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression strategy: %d",
+ (int) mng_info->write_png_compression_strategy-1);
- {
- int
- base_filter;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up filtering");
- if ((quality % 10) > 5)
- base_filter=PNG_ALL_FILTERS;
+ if (mng_info->write_png_compression_filter == 6)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Base filter method: ADAPTIVE");
+ else if (mng_info->write_png_compression_filter == 0 ||
+ mng_info->write_png_compression_filter == 1)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Base filter method: NONE");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Base filter method: %d",
+ (int) mng_info->write_png_compression_filter-1);
+ }
- else
- if ((quality % 10) != 5)
- base_filter=(int) quality % 10;
+ if (mng_info->write_png_compression_level != 0)
+ png_set_compression_level(ping,mng_info->write_png_compression_level-1);
+ if (mng_info->write_png_compression_filter == 6)
+ {
+ if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
+ ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
+ (quality < 50))
+ png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
else
- if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
- ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
- (quality < 50))
- base_filter=PNG_NO_FILTERS;
-
- else
- base_filter=PNG_ALL_FILTERS;
+ png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
+ }
+ else if (mng_info->write_png_compression_filter == 7 ||
+ mng_info->write_png_compression_filter == 10)
+ png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
- if (logging != MagickFalse)
+ else if (mng_info->write_png_compression_filter == 8)
+ {
+#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
+ if (mng_info->write_mng)
{
- if (base_filter == PNG_ALL_FILTERS)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Base filter method: ADAPTIVE");
- else
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Base filter method: NONE");
+ if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
+ ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
+ ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
}
+#endif
+ png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
+ }
- png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
- }
+ else if (mng_info->write_png_compression_filter == 9)
+ png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
- if ((ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse) &&
- (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
+ else if (mng_info->write_png_compression_filter != 0)
+ png_set_filter(ping,PNG_FILTER_TYPE_BASE,
+ mng_info->write_png_compression_filter-1);
+
+ if (mng_info->write_png_compression_strategy != 0)
+ png_set_compression_strategy(ping,
+ mng_info->write_png_compression_strategy-1);
+
+ /* Only write the iCCP chunk if we are not writing the sRGB chunk. */
+ if (ping_exclude_sRGB != MagickFalse ||
+ (image->rendering_intent == UndefinedIntent))
+ {
+ if ((ping_exclude_tEXt == MagickFalse ||
+ ping_exclude_zTXt == MagickFalse) &&
+ (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
{
ResetImageProfileIterator(image);
for (name=GetNextImageProfile(image); name != (const char *) NULL; )
if (ping_exclude_iCCP == MagickFalse)
{
- png_set_iCCP(ping,ping_info,(const png_charp) name,0,
+ png_set_iCCP(ping,ping_info,(png_charp) name,0,
#if (PNG_LIBPNG_VER < 10500)
(png_charp) GetStringInfoDatum(profile),
#else
name=GetNextImageProfile(image);
}
+ }
}
#if defined(PNG_WRITE_sRGB_SUPPORTED)
(void) png_set_sRGB(ping,ping_info,(
Magick_RenderingIntent_to_PNG_RenderingIntent(
image->rendering_intent)));
-
- if (ping_exclude_gAMA == MagickFalse)
- png_set_gAMA(ping,ping_info,0.45455);
}
}
ping_have_non_bw == MagickFalse)
{
/* Palette, Bilevel, or Opaque Monochrome */
- register const PixelPacket
+ register const Quantum
*p;
quantum_info->depth=8;
p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ if (p == (const Quantum *) NULL)
break;
if (mng_info->IsPalette)
{
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,GrayQuantum,ping_pixels,&image->exception);
if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
mng_info->write_png_depth &&
else
{
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,RedQuantum,ping_pixels,&image->exception);
}
(ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
(mng_info->IsPalette) && ping_have_color == MagickFalse)
{
- register const PixelPacket
+ register const Quantum
*p;
for (pass=0; pass < num_passes; pass++)
{
p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ if (p == (const Quantum *) NULL)
break;
if (ping_color_type == PNG_COLOR_TYPE_GRAY)
{
if (mng_info->IsPalette)
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,GrayQuantum,ping_pixels,&image->exception);
else
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,RedQuantum,ping_pixels,&image->exception);
if (logging != MagickFalse && y == 0)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Writing GRAY_ALPHA PNG pixels (2)");
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,GrayAlphaQuantum,ping_pixels,&image->exception);
}
else
{
- register const PixelPacket
+ register const Quantum
*p;
for (pass=0; pass < num_passes; pass++)
p=GetVirtualPixels(image,0,y,image->columns,1,
&image->exception);
- if (p == (const PixelPacket *) NULL)
+ if (p == (const Quantum *) NULL)
break;
if (ping_color_type == PNG_COLOR_TYPE_GRAY)
{
if (image->storage_class == DirectClass)
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,RedQuantum,ping_pixels,&image->exception);
else
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,GrayQuantum,ping_pixels,&image->exception);
}
else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,GrayAlphaQuantum,ping_pixels,
&image->exception);
}
else if (image_matte != MagickFalse)
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,RGBAQuantum,ping_pixels,&image->exception);
else
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,RGBQuantum,ping_pixels,&image->exception);
if (logging != MagickFalse && y == 0)
p=GetVirtualPixels(image,0,y,image->columns,1,
&image->exception);
- if (p == (const PixelPacket *) NULL)
+ if (p == (const Quantum *) NULL)
break;
if (ping_color_type == PNG_COLOR_TYPE_GRAY)
{
quantum_info->depth=image->depth;
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,GrayQuantum,ping_pixels,&image->exception);
}
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Writing GRAY_ALPHA PNG pixels (4)");
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,GrayAlphaQuantum,ping_pixels,
&image->exception);
}
else
{
- (void) ExportQuantumPixels(image,(const CacheView *) NULL,
+ (void) ExportQuantumPixels(image,(CacheView *) NULL,
quantum_info,IndexQuantum,ping_pixels,&image->exception);
if (logging != MagickFalse && y <= 2)
%
% The format of the WritePNGImage method is:
%
-% MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
+% MagickBooleanType WritePNGImage(const ImageInfo *image_info,
+% Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o image: The image.
%
+% o exception: return any errors or warnings in this structure.
+%
% Returns MagickTrue on success, MagickFalse on failure.
%
% Communicating with the PNG encoder:
% transparent). If other values are present they will be
% 50%-thresholded to binary transparency. If more than 256
% colors are present, they will be quantized to the 4-4-4-1,
-% 3-3-3-1, or 3-3-2-1 palette.
+% 3-3-3-1, or 3-3-2-1 palette. The underlying RGB color
+% of any resulting fully-transparent pixels is changed to
+% the image's background color.
%
% If you want better quantization or dithering of the colors
% or alpha than that, you need to do it before calling the
% the user should make sure that ImageMagick has already reduced the
% image depth and number of colors and limit transparency to binary
% transparency prior to attempting to write the image with depth, color,
-% or transparency limitations.
-%
-% To do: Enforce the previous paragraph.
+% or transparency limitations.
%
% Note that another definition, "png:bit-depth-written" exists, but it
% is not intended for external use. It is only used internally by the
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
static MagickBooleanType WritePNGImage(const ImageInfo *image_info,
- Image *image)
+ Image *image,ExceptionInfo *exception)
{
MagickBooleanType
excluding,
image->depth = 8;
if (image->matte == MagickTrue)
- (void) SetImageType(image,TrueColorMatteType);
+ (void) SetImageType(image,TrueColorMatteType,exception);
else
- (void) SetImageType(image,TrueColorType);
+ (void) SetImageType(image,TrueColorType,exception);
(void) SyncImage(image);
}
image->depth = 8;
if (image->matte == MagickTrue)
- (void) SetImageType(image,TrueColorMatteType);
+ (void) SetImageType(image,TrueColorMatteType,exception);
else
- (void) SetImageType(image,TrueColorType);
+ (void) SetImageType(image,TrueColorType,exception);
(void) SyncImage(image);
}
* is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
*
* The -strip option causes StripImage() to set the png:include-chunk
- * artifact to "none,gama".
+ * artifact to "none,trns,gama".
*/
mng_info->ping_exclude_bKGD=MagickFalse;
if (value != NULL)
mng_info->ping_preserve_colormap=MagickTrue;
+ /* Thes compression-level, compression-strategy, and compression-filter
+ * defines take precedence over values from the -quality option.
+ */
+ value=GetImageArtifact(image,"png:compression-level");
+ if (value == NULL)
+ value=GetImageOption(image_info,"png:compression-level");
+ if (value != NULL)
+ {
+ /* We have to add 1 to everything because 0 is a valid input,
+ * and we want to use 0 (the default) to mean undefined.
+ */
+ if (LocaleCompare(value,"0") == 0)
+ mng_info->write_png_compression_level = 1;
+
+ if (LocaleCompare(value,"1") == 0)
+ mng_info->write_png_compression_level = 2;
+
+ else if (LocaleCompare(value,"2") == 0)
+ mng_info->write_png_compression_level = 3;
+
+ else if (LocaleCompare(value,"3") == 0)
+ mng_info->write_png_compression_level = 4;
+
+ else if (LocaleCompare(value,"4") == 0)
+ mng_info->write_png_compression_level = 5;
+
+ else if (LocaleCompare(value,"5") == 0)
+ mng_info->write_png_compression_level = 6;
+
+ else if (LocaleCompare(value,"6") == 0)
+ mng_info->write_png_compression_level = 7;
+
+ else if (LocaleCompare(value,"7") == 0)
+ mng_info->write_png_compression_level = 8;
+
+ else if (LocaleCompare(value,"8") == 0)
+ mng_info->write_png_compression_level = 9;
+
+ else if (LocaleCompare(value,"9") == 0)
+ mng_info->write_png_compression_level = 10;
+
+ else
+ (void) ThrowMagickException(&image->exception,
+ GetMagickModule(),CoderWarning,
+ "ignoring invalid defined png:compression-level",
+ "=%s",value);
+ }
+
+ value=GetImageArtifact(image,"png:compression-strategy");
+ if (value == NULL)
+ value=GetImageOption(image_info,"png:compression-strategy");
+ if (value != NULL)
+ {
+
+ if (LocaleCompare(value,"0") == 0)
+ mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
+
+ else if (LocaleCompare(value,"1") == 0)
+ mng_info->write_png_compression_strategy = Z_FILTERED+1;
+
+ else if (LocaleCompare(value,"2") == 0)
+ mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
+
+ else if (LocaleCompare(value,"3") == 0)
+#ifdef Z_RLE /* Z_RLE was added to zlib-1.2.0 */
+ mng_info->write_png_compression_strategy = Z_RLE+1;
+#else
+ mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
+#endif
+
+ else if (LocaleCompare(value,"4") == 0)
+#ifdef Z_FIXED /* Z_FIXED was added to zlib-1.2.2.2 */
+ mng_info->write_png_compression_strategy = Z_FIXED+1;
+#else
+ mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
+#endif
+
+ else
+ (void) ThrowMagickException(&image->exception,
+ GetMagickModule(),CoderWarning,
+ "ignoring invalid defined png:compression-strategy",
+ "=%s",value);
+ }
+
+ value=GetImageArtifact(image,"png:compression-filter");
+ if (value == NULL)
+ value=GetImageOption(image_info,"png:compression-filter");
+ if (value != NULL)
+ {
+
+ /* To do: combinations of filters allowed by libpng
+ * masks 0x08 through 0xf8
+ *
+ * Implement this as a comma-separated list of 0,1,2,3,4,5
+ * where 5 is a special case meaning PNG_ALL_FILTERS.
+ */
+
+ if (LocaleCompare(value,"0") == 0)
+ mng_info->write_png_compression_filter = 1;
+
+ if (LocaleCompare(value,"1") == 0)
+ mng_info->write_png_compression_filter = 2;
+
+ else if (LocaleCompare(value,"2") == 0)
+ mng_info->write_png_compression_filter = 3;
+
+ else if (LocaleCompare(value,"3") == 0)
+ mng_info->write_png_compression_filter = 4;
+
+ else if (LocaleCompare(value,"4") == 0)
+ mng_info->write_png_compression_filter = 5;
+
+ else if (LocaleCompare(value,"5") == 0)
+ mng_info->write_png_compression_filter = 6;
+
+ else
+ (void) ThrowMagickException(&image->exception,
+ GetMagickModule(),CoderWarning,
+ "ignoring invalid defined png:compression-filter",
+ "=%s",value);
+ }
+
excluding=MagickFalse;
for (source=0; source<1; source++)
mng_info->need_blob = MagickTrue;
- status=WriteOnePNGImage(mng_info,image_info,image);
+ status=WriteOnePNGImage(mng_info,image_info,image,exception);
MngInfoFreeStruct(mng_info,&have_mng_structure);
/* Write one JNG image */
static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
- const ImageInfo *image_info,Image *image)
+ const ImageInfo *image_info,Image *image,ExceptionInfo *exception)
{
Image
*jpeg_image;
if (transparent)
{
+ ChannelType
+ channel_mask;
+
jng_color_type=14;
/* Create JPEG blob, image, and image_info */
if (logging != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Creating jpeg_image_info for opacity.");
+ " Creating jpeg_image_info for alpha.");
jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
(void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
- status=SeparateImageChannel(jpeg_image,OpacityChannel);
- status=NegateImage(jpeg_image,MagickFalse);
+ channel_mask=SetPixelChannelMask(jpeg_image,AlphaChannel);
+ status=SeparateImage(jpeg_image);
+ (void) SetPixelChannelMap(jpeg_image,channel_mask);
jpeg_image->matte=MagickFalse;
if (jng_quality >= 1000)
jpeg_image_info->quality=jng_quality;
jpeg_image_info->type=GrayscaleType;
- (void) SetImageType(jpeg_image,GrayscaleType);
+ (void) SetImageType(jpeg_image,GrayscaleType,exception);
(void) AcquireUniqueFilename(jpeg_image->filename);
- (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
+ (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
"%s",jpeg_image->filename);
}
const char
*value;
- /* Encode opacity as a grayscale PNG blob */
+ /* Encode alpha as a grayscale PNG blob */
status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
&image->exception);
if (logging != MagickFalse)
}
else
{
- /* Encode opacity as a grayscale JPEG blob */
+ /* Encode alpha as a grayscale JPEG blob */
status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
&image->exception);
(void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
(void) AcquireUniqueFilename(jpeg_image->filename);
- (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
+ (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
jpeg_image->filename);
status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
%
% The format of the WriteJNGImage method is:
%
-% MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
+% MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
+% Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o image: The image.
%
+% o exception: return any errors or warnings in this structure.
+%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
-static MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
+ ExceptionInfo *exception)
{
MagickBooleanType
have_mng_structure,
(void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
- status=WriteOneJNGImage(mng_info,image_info,image);
+ status=WriteOneJNGImage(mng_info,image_info,image,exception);
(void) CloseBlob(image);
(void) CatchImageException(image);
}
#endif
-
-
-static MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
+ ExceptionInfo *exception)
{
const char
*option;
/* To do: specify the desired alpha compression method. */
write_info=CloneImageInfo(image_info);
write_info->compression=UndefinedCompression;
- status=WriteOneJNGImage(mng_info,write_info,image);
+ status=WriteOneJNGImage(mng_info,write_info,image,exception);
write_info=DestroyImageInfo(write_info);
}
else
mng_info->ping_exclude_zCCP=MagickTrue;
mng_info->ping_exclude_zTXt=MagickTrue;
- status=WriteOnePNGImage(mng_info,image_info,image);
+ status=WriteOnePNGImage(mng_info,image_info,image,exception);
}
if (status == MagickFalse)