% July 1992 %
% %
% %
-% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
/*
Include declarations.
*/
-#include "magick/studio.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/color.h"
-#include "magick/colormap-private.h"
-#include "magick/color-private.h"
-#include "magick/colorspace.h"
-#include "magick/constitute.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/geometry.h"
-#include "magick/image.h"
-#include "magick/image-private.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/profile.h"
-#include "magick/property.h"
-#include "magick/quantum-private.h"
-#include "magick/resource_.h"
-#include "magick/splay-tree.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/string-private.h"
-#include "magick/utility.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/attribute.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/color.h"
+#include "MagickCore/colormap-private.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/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/geometry.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/log.h"
+#include "MagickCore/magick.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-accessor.h"
+#include "MagickCore/profile.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/resource_.h"
+#include "MagickCore/splay-tree.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
+#include "MagickCore/token.h"
+#include "MagickCore/utility.h"
+#include "MagickCore/xml-tree.h"
+#include "MagickCore/xml-tree-private.h"
#include <setjmp.h>
#if defined(MAGICKCORE_JPEG_DELEGATE)
#define JPEG_INTERNAL_OPTIONS
#if defined(__MINGW32__)
# define XMD_H 1 /* Avoid conflicting typedef for INT32 */
+typedef unsigned char boolean;
+#define HAVE_BOOLEAN
#endif
#undef HAVE_STDLIB_H
#include "jpeglib.h"
typedef struct _ErrorManager
{
+ ExceptionInfo
+ *exception;
+
Image
*image;
+ MagickBooleanType
+ finished;
+
jmp_buf
error_recovery;
} ErrorManager;
start_of_blob;
} SourceManager;
#endif
+
+typedef struct _QuantizationTable
+{
+ char
+ *slot,
+ *description;
+
+ size_t
+ width,
+ height;
+
+ double
+ divisor;
+
+ unsigned int
+ *levels;
+} QuantizationTable;
\f
/*
Forward declarations.
*/
#if defined(MAGICKCORE_JPEG_DELEGATE)
static MagickBooleanType
- WriteJPEGImage(const ImageInfo *,Image *);
+ WriteJPEGImage(const ImageInfo *,Image *,ExceptionInfo *);
#endif
\f
/*
%
*/
-static MagickBooleanType EmitMessage(j_common_ptr jpeg_info,int level)
-{
- char
- message[JMSG_LENGTH_MAX];
-
- ErrorManager
- *error_manager;
-
- Image
- *image;
-
- (jpeg_info->err->format_message)(jpeg_info,message);
- error_manager=(ErrorManager *) jpeg_info->client_data;
- image=error_manager->image;
- if (level < 0)
- {
- if ((jpeg_info->err->num_warnings == 0) ||
- (jpeg_info->err->trace_level >= 3))
- ThrowBinaryException(CorruptImageWarning,(char *) message,
- image->filename);
- jpeg_info->err->num_warnings++;
- }
- else
- if (jpeg_info->err->trace_level >= level)
- ThrowBinaryException(CoderError,(char *) message,image->filename);
- return(MagickTrue);
-}
-
static boolean FillInputBuffer(j_decompress_ptr cinfo)
{
SourceManager
*source;
source=(SourceManager *) cinfo->src;
- source->manager.bytes_in_buffer=(size_t)
- ReadBlob(source->image,MaxBufferExtent,source->buffer);
+ source->manager.bytes_in_buffer=(size_t) ReadBlob(source->image,
+ MaxBufferExtent,source->buffer);
if (source->manager.bytes_in_buffer == 0)
{
if (source->start_of_blob != 0)
static void JPEGErrorHandler(j_common_ptr jpeg_info)
{
+ char
+ message[JMSG_LENGTH_MAX];
+
ErrorManager
*error_manager;
- (void) EmitMessage(jpeg_info,0);
+ ExceptionInfo
+ *exception;
+
+ Image
+ *image;
+
+ *message='\0';
error_manager=(ErrorManager *) jpeg_info->client_data;
+ image=error_manager->image;
+ exception=error_manager->exception;
+ (jpeg_info->err->format_message)(jpeg_info,message);
+ if (image->debug != MagickFalse)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "[%s] JPEG Trace: \"%s\"",image->filename,message);
+ if (error_manager->finished != MagickFalse)
+ (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageWarning,
+ (char *) message,"`%s'",image->filename);
+ else
+ (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
+ (char *) message,"`%s'",image->filename);
longjmp(error_manager->error_recovery,1);
}
+static MagickBooleanType JPEGWarningHandler(j_common_ptr jpeg_info,int level)
+{
+#define JPEGExcessiveWarnings 1000
+
+ char
+ message[JMSG_LENGTH_MAX];
+
+ ErrorManager
+ *error_manager;
+
+ ExceptionInfo
+ *exception;
+
+ Image
+ *image;
+
+ *message='\0';
+ error_manager=(ErrorManager *) jpeg_info->client_data;
+ exception=error_manager->exception;
+ image=error_manager->image;
+ if (level < 0)
+ {
+ /*
+ Process warning message.
+ */
+ (jpeg_info->err->format_message)(jpeg_info,message);
+ if (jpeg_info->err->num_warnings++ > JPEGExcessiveWarnings)
+ JPEGErrorHandler(jpeg_info);
+ if ((jpeg_info->err->num_warnings == 0) ||
+ (jpeg_info->err->trace_level >= 3))
+ ThrowBinaryException(CorruptImageWarning,(char *) message,
+ image->filename);
+ }
+ else
+ if ((image->debug != MagickFalse) &&
+ (level >= jpeg_info->err->trace_level))
+ {
+ /*
+ Process trace message.
+ */
+ (jpeg_info->err->format_message)(jpeg_info,message);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "[%s] JPEG Trace: \"%s\"",image->filename,message);
+ }
+ return(MagickTrue);
+}
+
static boolean ReadComment(j_decompress_ptr jpeg_info)
{
char
ErrorManager
*error_manager;
+ ExceptionInfo
+ *exception;
+
Image
*image;
register char
*p;
- register long
+ register ssize_t
i;
size_t
Determine length of comment.
*/
error_manager=(ErrorManager *) jpeg_info->client_data;
+ exception=error_manager->exception;
image=error_manager->image;
- length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
+ length=(size_t) ((size_t) GetCharacter(jpeg_info) << 8);
length+=GetCharacter(jpeg_info);
length-=2;
if (length <= 0)
return(MagickTrue);
comment=(char *) NULL;
- if (~length >= MaxTextExtent)
+ if (~length >= (MaxTextExtent-1))
comment=(char *) AcquireQuantumMemory(length+MaxTextExtent,
sizeof(*comment));
if (comment == (char *) NULL)
/*
Read comment.
*/
- i=(long) length-1;
+ i=(ssize_t) length-1;
for (p=comment; i-- >= 0; p++)
*p=(char) GetCharacter(jpeg_info);
*p='\0';
- (void) SetImageProperty(image,"comment",comment);
+ (void) SetImageProperty(image,"comment",comment,exception);
comment=DestroyString(comment);
return(MagickTrue);
}
ErrorManager
*error_manager;
+ ExceptionInfo
+ *exception;
+
Image
*image;
MagickBooleanType
status;
- register long
+ register ssize_t
i;
register unsigned char
/*
Read color profile.
*/
- length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
+ length=(size_t) ((size_t) GetCharacter(jpeg_info) << 8);
length+=(size_t) GetCharacter(jpeg_info);
length-=2;
if (length <= 14)
/*
Not a ICC profile, return.
*/
- for (i=0; i < (long) (length-12); i++)
+ for (i=0; i < (ssize_t) (length-12); i++)
(void) GetCharacter(jpeg_info);
return(MagickTrue);
}
(void) GetCharacter(jpeg_info); /* markers */
length-=14;
error_manager=(ErrorManager *) jpeg_info->client_data;
+ exception=error_manager->exception;
image=error_manager->image;
- profile=AcquireStringInfo(length);
+ profile=BlobToStringInfo((const void *) NULL,length);
if (profile == (StringInfo *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
p=GetStringInfoDatum(profile);
- for (i=(long) GetStringInfoLength(profile)-1; i >= 0; i--)
+ for (i=(ssize_t) GetStringInfoLength(profile)-1; i >= 0; i--)
*p++=(unsigned char) GetCharacter(jpeg_info);
icc_profile=(StringInfo *) GetImageProfile(image,"icc");
if (icc_profile != (StringInfo *) NULL)
}
else
{
- status=SetImageProfile(image,"icc",profile);
+ status=SetImageProfile(image,"icc",profile,exception);
profile=DestroyStringInfo(profile);
if (status == MagickFalse)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
}
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Profile: ICC, %lu bytes",(unsigned long) length);
+ "Profile: ICC, %.20g bytes",(double) length);
return(MagickTrue);
}
ErrorManager
*error_manager;
+ ExceptionInfo
+ *exception;
+
Image
*image;
MagickBooleanType
status;
- register long
+ register ssize_t
i;
register unsigned char
/*
Determine length of binary data stored here.
*/
- length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
+ length=(size_t) ((size_t) GetCharacter(jpeg_info) << 8);
length+=(size_t) GetCharacter(jpeg_info);
length-=2;
if (length <= 14)
/*
Not a IPTC profile, return.
*/
- for (i=0; i < (long) length; i++)
+ for (i=0; i < (ssize_t) length; i++)
(void) GetCharacter(jpeg_info);
return(MagickTrue);
}
if (length == 0)
return(MagickTrue);
error_manager=(ErrorManager *) jpeg_info->client_data;
+ exception=error_manager->exception;
image=error_manager->image;
- profile=AcquireStringInfo(length);
+ profile=BlobToStringInfo((const void *) NULL,length);
if (profile == (StringInfo *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
p=GetStringInfoDatum(profile);
- for (i=(long) GetStringInfoLength(profile)-1; i >= 0; i--)
+ for (i=0; i < (ssize_t) GetStringInfoLength(profile); i++)
*p++=(unsigned char) GetCharacter(jpeg_info);
iptc_profile=(StringInfo *) GetImageProfile(image,"8bim");
if (iptc_profile != (StringInfo *) NULL)
}
else
{
- status=SetImageProfile(image,"8bim",profile);
+ status=SetImageProfile(image,"8bim",profile,exception);
profile=DestroyStringInfo(profile);
if (status == MagickFalse)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
}
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Profile: iptc, %lu bytes",(unsigned long) length);
+ "Profile: iptc, %.20g bytes",(double) length);
return(MagickTrue);
}
char
name[MaxTextExtent];
+ const StringInfo
+ *previous_profile;
+
ErrorManager
*error_manager;
+ ExceptionInfo
+ *exception;
+
Image
*image;
MagickBooleanType
status;
- register long
+ register ssize_t
i;
register unsigned char
/*
Read generic profile.
*/
- length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
+ length=(size_t) ((size_t) GetCharacter(jpeg_info) << 8);
length+=(size_t) GetCharacter(jpeg_info);
if (length <= 2)
return(MagickTrue);
length-=2;
marker=jpeg_info->unread_marker-JPEG_APP0;
- (void) FormatMagickString(name,MaxTextExtent,"APP%d",marker);
+ (void) FormatLocaleString(name,MaxTextExtent,"APP%d",marker);
error_manager=(ErrorManager *) jpeg_info->client_data;
+ exception=error_manager->exception;
image=error_manager->image;
- profile=AcquireStringInfo(length);
+ profile=BlobToStringInfo((const void *) NULL,length);
if (profile == (StringInfo *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
p=GetStringInfoDatum(profile);
- for (i=(long) GetStringInfoLength(profile)-1; i >= 0; i--)
+ for (i=0; i < (ssize_t) GetStringInfoLength(profile); i++)
*p++=(unsigned char) GetCharacter(jpeg_info);
if (marker == 1)
{
(void) CopyMagickString(name,"exif",MaxTextExtent);
if ((length > 5) && (LocaleNCompare((char *) p,"http:",5) == 0))
{
- long
+ ssize_t
j;
/*
Extract namespace from XMP profile.
*/
p=GetStringInfoDatum(profile);
- for (j=0; j < (long) GetStringInfoLength(profile); j++)
+ for (j=0; j < (ssize_t) GetStringInfoLength(profile); j++)
{
if (*p == '\0')
break;
p++;
}
- if (j < (long) GetStringInfoLength(profile))
+ if (j < (ssize_t) GetStringInfoLength(profile))
(void) DestroyStringInfo(SplitStringInfo(profile,(size_t) (j+1)));
(void) CopyMagickString(name,"xmp",MaxTextExtent);
}
}
- status=SetImageProfile(image,name,profile);
+ previous_profile=GetImageProfile(image,name);
+ if (previous_profile != (const StringInfo *) NULL)
+ {
+ size_t
+ length;
+
+ length=GetStringInfoLength(profile);
+ SetStringInfoLength(profile,GetStringInfoLength(profile)+
+ GetStringInfoLength(previous_profile));
+ (void) memmove(GetStringInfoDatum(profile)+
+ GetStringInfoLength(previous_profile),GetStringInfoDatum(profile),
+ length);
+ (void) memcpy(GetStringInfoDatum(profile),
+ GetStringInfoDatum(previous_profile),
+ GetStringInfoLength(previous_profile));
+ }
+ status=SetImageProfile(image,name,profile,exception);
profile=DestroyStringInfo(profile);
if (status == MagickFalse)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Profile: %s, %lu bytes",name,(unsigned long) length);
+ "Profile: %s, %.20g bytes",name,(double) length);
return(MagickTrue);
}
number_bytes-=(long) source->manager.bytes_in_buffer;
(void) FillInputBuffer(cinfo);
}
- source->manager.next_input_byte+=(size_t) number_bytes;
- source->manager.bytes_in_buffer-=(size_t) number_bytes;
+ source->manager.next_input_byte+=number_bytes;
+ source->manager.bytes_in_buffer-=number_bytes;
}
static void TerminateSource(j_decompress_ptr cinfo)
{
- cinfo=cinfo;
+ (void) cinfo;
}
static void JPEGSourceManager(j_decompress_ptr cinfo,Image *image)
else
#endif
{
- long
+ ssize_t
j,
qvalue,
sum;
- register long
+ register ssize_t
i;
/*
if ((jpeg_info->quant_tbl_ptrs[0] != NULL) &&
(jpeg_info->quant_tbl_ptrs[1] != NULL))
{
- long
+ ssize_t
hash[101] =
{
1020, 1015, 932, 848, 780, 735, 702, 679, 660, 645,
128, 0
};
- qvalue=(long) (jpeg_info->quant_tbl_ptrs[0]->quantval[2]+
+ qvalue=(ssize_t) (jpeg_info->quant_tbl_ptrs[0]->quantval[2]+
jpeg_info->quant_tbl_ptrs[0]->quantval[53]+
jpeg_info->quant_tbl_ptrs[1]->quantval[0]+
jpeg_info->quant_tbl_ptrs[1]->quantval[DCTSIZE2-1]);
if ((qvalue < hash[i]) && (sum < sums[i]))
continue;
if (((qvalue <= hash[i]) && (sum <= sums[i])) || (i >= 50))
- image->quality=(unsigned long) i+1;
+ image->quality=(size_t) i+1;
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Quality: %ld (%s)",i+1,(qvalue <= hash[i]) &&
+ "Quality: %.20g (%s)",(double) i+1,(qvalue <= hash[i]) &&
(sum <= sums[i]) ? "exact" : "approximate");
break;
}
else
if (jpeg_info->quant_tbl_ptrs[0] != NULL)
{
- long
+ ssize_t
hash[101] =
{
510, 505, 422, 380, 355, 338, 326, 318, 311, 305,
64, 0
};
- qvalue=(long) (jpeg_info->quant_tbl_ptrs[0]->quantval[2]+
+ qvalue=(ssize_t) (jpeg_info->quant_tbl_ptrs[0]->quantval[2]+
jpeg_info->quant_tbl_ptrs[0]->quantval[53]);
for (i=0; i < 100; i++)
{
if ((qvalue < hash[i]) && (sum < sums[i]))
continue;
if (((qvalue <= hash[i]) && (sum <= sums[i])) || (i >= 50))
- image->quality=(unsigned long) i+1;
+ image->quality=(size_t) i+1;
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Quality: %ld (%s)",i+1,(qvalue <= hash[i]) &&
+ "Quality: %.20g (%s)",(double) i+1,(qvalue <= hash[i]) &&
(sum <= sums[i]) ? "exact" : "approximate");
break;
}
}
}
-static void JPEGSetImageSamplingFactor(struct jpeg_decompress_struct *jpeg_info, Image *image)
+static void JPEGSetImageSamplingFactor(struct jpeg_decompress_struct *jpeg_info, Image *image,ExceptionInfo *exception)
{
char
sampling_factor[MaxTextExtent];
case JCS_CMYK:
{
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"Colorspace: CMYK");
- (void) FormatMagickString(sampling_factor,MaxTextExtent,
+ (void) FormatLocaleString(sampling_factor,MaxTextExtent,
"%dx%d,%dx%d,%dx%d,%dx%d",jpeg_info->comp_info[0].h_samp_factor,
jpeg_info->comp_info[0].v_samp_factor,
jpeg_info->comp_info[1].h_samp_factor,
{
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
"Colorspace: GRAYSCALE");
- (void) FormatMagickString(sampling_factor,MaxTextExtent,"%dx%d",
+ (void) FormatLocaleString(sampling_factor,MaxTextExtent,"%dx%d",
jpeg_info->comp_info[0].h_samp_factor,
jpeg_info->comp_info[0].v_samp_factor);
break;
case JCS_RGB:
{
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"Colorspace: RGB");
- (void) FormatMagickString(sampling_factor,MaxTextExtent,
+ (void) FormatLocaleString(sampling_factor,MaxTextExtent,
"%dx%d,%dx%d,%dx%d",jpeg_info->comp_info[0].h_samp_factor,
jpeg_info->comp_info[0].v_samp_factor,
jpeg_info->comp_info[1].h_samp_factor,
{
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"Colorspace: %d",
jpeg_info->out_color_space);
- (void) FormatMagickString(sampling_factor,MaxTextExtent,
+ (void) FormatLocaleString(sampling_factor,MaxTextExtent,
"%dx%d,%dx%d,%dx%d,%dx%d",jpeg_info->comp_info[0].h_samp_factor,
jpeg_info->comp_info[0].v_samp_factor,
jpeg_info->comp_info[1].h_samp_factor,
break;
}
}
- (void) SetImageProperty(image,"jpeg:sampling-factor",sampling_factor);
+ (void) SetImageProperty(image,"jpeg:sampling-factor",sampling_factor,
+ exception);
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"Sampling Factors: %s",
sampling_factor);
}
Image
*image;
- IndexPacket
- index;
-
- long
- y;
-
JSAMPLE
*jpeg_pixels;
MagickSizeType
number_pixels;
- register long
+ Quantum
+ index;
+
+ register ssize_t
i;
struct jpeg_decompress_struct
register JSAMPLE
*p;
- unsigned long
+ size_t
precision,
units;
+ ssize_t
+ y;
+
/*
Open image file.
*/
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
debug=IsEventLogging();
- image=AcquireImage(image_info);
+ (void) debug;
+ image=AcquireImage(image_info,exception);
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
if (status == MagickFalse)
{
/*
Initialize JPEG parameters.
*/
+ (void) ResetMagickMemory(&error_manager,0,sizeof(error_manager));
(void) ResetMagickMemory(&jpeg_info,0,sizeof(jpeg_info));
(void) ResetMagickMemory(&jpeg_error,0,sizeof(jpeg_error));
jpeg_info.err=jpeg_std_error(&jpeg_error);
- jpeg_info.err->emit_message=(void (*)(j_common_ptr,int)) EmitMessage;
+ jpeg_info.err->emit_message=(void (*)(j_common_ptr,int)) JPEGWarningHandler;
jpeg_info.err->error_exit=(void (*)(j_common_ptr)) JPEGErrorHandler;
jpeg_pixels=(JSAMPLE *) NULL;
+ error_manager.exception=exception;
error_manager.image=image;
if (setjmp(error_manager.error_recovery) != 0)
{
number_pixels=(MagickSizeType) image->columns*image->rows;
if (number_pixels != 0)
return(GetFirstImageInList(image));
- InheritException(exception,&image->exception);
return(DestroyImage(image));
}
jpeg_info.client_data=(void *) &error_manager;
for (i=1; i < 16; i++)
if ((i != 2) && (i != 13) && (i != 14))
jpeg_set_marker_processor(&jpeg_info,(int) (JPEG_APP0+i),ReadProfile);
- i=jpeg_read_header(&jpeg_info,MagickTrue);
+ i=(ssize_t) jpeg_read_header(&jpeg_info,MagickTrue);
if ((image_info->colorspace == YCbCrColorspace) ||
(image_info->colorspace == Rec601YCbCrColorspace) ||
(image_info->colorspace == Rec709YCbCrColorspace))
if ((jpeg_info.saw_JFIF_marker != 0) && (jpeg_info.X_density != 1) &&
(jpeg_info.Y_density != 1))
{
- image->x_resolution=(double) jpeg_info.X_density;
- image->y_resolution=(double) jpeg_info.Y_density;
- units=(unsigned long) jpeg_info.density_unit;
+ image->resolution.x=(double) jpeg_info.X_density;
+ image->resolution.y=(double) jpeg_info.Y_density;
+ units=(size_t) jpeg_info.density_unit;
}
if (units == 1)
image->units=PixelsPerInchResolution;
jpeg_info.scale_denom=(unsigned int) scale_factor;
jpeg_calc_output_dimensions(&jpeg_info);
if (image->debug != MagickFalse)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Scale factor: %ld",
- (long) scale_factor);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Scale factor: %.20g",(double) scale_factor);
}
- precision=(unsigned long) jpeg_info.data_precision;
+ precision=(size_t) jpeg_info.data_precision;
#if (JPEG_LIB_VERSION >= 61) && defined(D_PROGRESSIVE_SUPPORTED)
#if defined(D_LOSSLESS_SUPPORTED)
image->interlace=jpeg_info.process == JPROC_PROGRESSIVE ?
image->compression=JPEGCompression;
image->interlace=JPEGInterlace;
#endif
- if ((image_info->colors > 8) && (image_info->colors <= 256))
+ option=GetImageOption(image_info,"jpeg:colors");
+ if (option != (const char *) NULL)
{
/*
- Let the JPEG library quantize for us.
+ Let the JPEG library quantize the image.
*/
jpeg_info.quantize_colors=MagickTrue;
- jpeg_info.desired_number_of_colors=(int) image_info->colors;
+ jpeg_info.desired_number_of_colors=(int) StringToUnsignedLong(option);
}
option=GetImageOption(image_info,"jpeg:block-smoothing");
- if (option != (const char *) NULL)
- {
- jpeg_info.do_block_smoothing=MagickFalse;
- if (IsMagickTrue(option) != MagickFalse)
- jpeg_info.do_block_smoothing=MagickTrue;
- }
+ jpeg_info.do_block_smoothing=IsStringTrue(option);
+ jpeg_info.dct_method=JDCT_FLOAT;
option=GetImageOption(image_info,"jpeg:dct-method");
if (option != (const char *) NULL)
switch (*option)
}
}
option=GetImageOption(image_info,"jpeg:fancy-upsampling");
- if (option != (const char *) NULL)
- {
- jpeg_info.do_fancy_upsampling=MagickFalse;
- if (IsMagickTrue(option) != MagickFalse)
- jpeg_info.do_fancy_upsampling=MagickTrue;
- }
+ jpeg_info.do_fancy_upsampling=IsStringTrue(option);
(void) jpeg_start_decompress(&jpeg_info);
image->columns=jpeg_info.output_width;
image->rows=jpeg_info.output_height;
- image->depth=(unsigned long) jpeg_info.data_precision;
+ image->depth=(size_t) jpeg_info.data_precision;
if (jpeg_info.out_color_space == JCS_YCbCr)
image->colorspace=YCbCrColorspace;
if (jpeg_info.out_color_space == JCS_CMYK)
image->colorspace=CMYKColorspace;
- if ((image_info->colors != 0) && (image_info->colors <= 256))
- if (AcquireImageColormap(image,image_info->colors) == MagickFalse)
+ option=GetImageOption(image_info,"jpeg:colors");
+ if (option != (const char *) NULL)
+ if (AcquireImageColormap(image,StringToUnsignedLong(option),exception)
+ == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
if ((jpeg_info.output_components == 1) &&
(jpeg_info.quantize_colors == MagickFalse))
{
- unsigned long
+ size_t
colors;
- colors=(unsigned long) GetQuantumRange(image->depth)+1;
- if (AcquireImageColormap(image,colors) == MagickFalse)
+ colors=(size_t) GetQuantumRange(image->depth)+1;
+ if (AcquireImageColormap(image,colors,exception) == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
if (image->debug != MagickFalse)
(int) jpeg_info.output_width,(int) jpeg_info.output_height);
}
JPEGSetImageQuality(&jpeg_info,image);
- JPEGSetImageSamplingFactor(&jpeg_info,image);
- (void) FormatMagickString(value,MaxTextExtent,"%ld",(long)
+ JPEGSetImageSamplingFactor(&jpeg_info,image,exception);
+ (void) FormatLocaleString(value,MaxTextExtent,"%.20g",(double)
jpeg_info.out_color_space);
- (void) SetImageProperty(image,"jpeg:colorspace",value);
+ (void) SetImageProperty(image,"jpeg:colorspace",value,exception);
if (image_info->ping != MagickFalse)
{
jpeg_destroy_decompress(&jpeg_info);
}
if (jpeg_info.quantize_colors != MagickFalse)
{
- image->colors=(unsigned long) jpeg_info.actual_number_of_colors;
+ image->colors=(size_t) jpeg_info.actual_number_of_colors;
if (jpeg_info.out_color_space == JCS_GRAYSCALE)
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < (ssize_t) image->colors; i++)
{
- image->colormap[i].red=ScaleCharToQuantum(jpeg_info.colormap[0][i]);
+ image->colormap[i].red=(double) ScaleCharToQuantum(
+ jpeg_info.colormap[0][i]);
image->colormap[i].green=image->colormap[i].red;
image->colormap[i].blue=image->colormap[i].red;
- image->colormap[i].opacity=OpaqueOpacity;
+ image->colormap[i].alpha=OpaqueAlpha;
}
else
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < (ssize_t) image->colors; i++)
{
- image->colormap[i].red=ScaleCharToQuantum(jpeg_info.colormap[0][i]);
- image->colormap[i].green=ScaleCharToQuantum(jpeg_info.colormap[1][i]);
- image->colormap[i].blue=ScaleCharToQuantum(jpeg_info.colormap[2][i]);
- image->colormap[i].opacity=OpaqueOpacity;
+ image->colormap[i].red=(double) ScaleCharToQuantum(
+ jpeg_info.colormap[0][i]);
+ image->colormap[i].green=(double) ScaleCharToQuantum(
+ jpeg_info.colormap[1][i]);
+ image->colormap[i].blue=(double) ScaleCharToQuantum(
+ jpeg_info.colormap[2][i]);
+ image->colormap[i].alpha=OpaqueAlpha;
}
}
scanline[0]=(JSAMPROW) jpeg_pixels;
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- register IndexPacket
- *restrict indexes;
-
- register long
+ register ssize_t
x;
- register PixelPacket
+ register Quantum
*restrict q;
if (jpeg_read_scanlines(&jpeg_info,scanline,1) != 1)
}
p=jpeg_pixels;
q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
- indexes=GetAuthenticIndexQueue(image);
if (jpeg_info.data_precision > 8)
{
if (jpeg_info.output_components == 1)
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- unsigned long
+ size_t
pixel;
if (precision != 16)
- pixel=(unsigned long) GETJSAMPLE(*p);
+ pixel=(size_t) GETJSAMPLE(*p);
else
- pixel=(unsigned long) ((GETJSAMPLE(*p) ^ 0x80) << 4);
- index=ConstrainColormapIndex(image,pixel);
- indexes[x]=index;
- *q++=image->colormap[(int) index];
+ pixel=(size_t) ((GETJSAMPLE(*p) ^ 0x80) << 4);
+ index=ConstrainColormapIndex(image,pixel,exception);
+ SetPixelIndex(image,index,q);
+ SetPixelInfoPixel(image,image->colormap+(ssize_t) index,q);
p++;
+ q+=GetPixelChannels(image);
}
else
if (image->colorspace != CMYKColorspace)
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- q->red=ScaleShortToQuantum((unsigned char)
- (GETJSAMPLE(*p++) << 4));
- q->green=ScaleShortToQuantum((unsigned char)
- (GETJSAMPLE(*p++) << 4));
- q->blue=ScaleShortToQuantum((unsigned char)
- (GETJSAMPLE(*p++) << 4));
- SetOpacityPixelComponent(q,OpaqueOpacity);
- q++;
+ SetPixelRed(image,ScaleShortToQuantum((unsigned char)
+ (GETJSAMPLE(*p++) << 4)),q);
+ SetPixelGreen(image,ScaleShortToQuantum((unsigned char)
+ (GETJSAMPLE(*p++) << 4)),q);
+ SetPixelBlue(image,ScaleShortToQuantum((unsigned char)
+ (GETJSAMPLE(*p++) << 4)),q);
+ SetPixelAlpha(image,OpaqueAlpha,q);
+ q+=GetPixelChannels(image);
}
else
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- q->red=(Quantum) QuantumRange-ScaleShortToQuantum((unsigned char)
- (GETJSAMPLE(*p++) << 4));
- q->green=(Quantum) QuantumRange-ScaleShortToQuantum(
- (unsigned char) (GETJSAMPLE(*p++) << 4));
- q->blue=(Quantum) QuantumRange-ScaleShortToQuantum((unsigned char)
- (GETJSAMPLE(*p++) << 4));
- SetOpacityPixelComponent(q,OpaqueOpacity);
- indexes[x]=(IndexPacket) QuantumRange-ScaleShortToQuantum(
- (unsigned char) (GETJSAMPLE(*p++) << 4));
- q++;
+ SetPixelCyan(image,QuantumRange-ScaleShortToQuantum(
+ (unsigned char) (GETJSAMPLE(*p++) << 4)),q);
+ SetPixelMagenta(image,QuantumRange-ScaleShortToQuantum(
+ (unsigned char) (GETJSAMPLE(*p++) << 4)),q);
+ SetPixelYellow(image,QuantumRange-ScaleShortToQuantum(
+ (unsigned char) (GETJSAMPLE(*p++) << 4)),q);
+ SetPixelBlack(image,QuantumRange-ScaleShortToQuantum(
+ (unsigned char) (GETJSAMPLE(*p++) << 4)),q);
+ SetPixelAlpha(image,OpaqueAlpha,q);
+ q+=GetPixelChannels(image);
}
}
else
if (jpeg_info.output_components == 1)
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- index=ConstrainColormapIndex(image,(unsigned long) GETJSAMPLE(*p));
- indexes[x]=(IndexPacket) index;
- *q++=image->colormap[(int) index];
+ index=ConstrainColormapIndex(image,(size_t) GETJSAMPLE(*p),exception);
+ SetPixelIndex(image,index,q);
+ SetPixelInfoPixel(image,image->colormap+(ssize_t) index,q);
p++;
+ q+=GetPixelChannels(image);
}
else
if (image->colorspace != CMYKColorspace)
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- q->red=ScaleCharToQuantum((unsigned char) GETJSAMPLE(*p++));
- q->green=ScaleCharToQuantum((unsigned char) GETJSAMPLE(*p++));
- q->blue=ScaleCharToQuantum((unsigned char) GETJSAMPLE(*p++));
- SetOpacityPixelComponent(q,OpaqueOpacity);
- q++;
+ SetPixelRed(image,ScaleCharToQuantum((unsigned char)
+ GETJSAMPLE(*p++)),q);
+ SetPixelGreen(image,ScaleCharToQuantum((unsigned char)
+ GETJSAMPLE(*p++)),q);
+ SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
+ GETJSAMPLE(*p++)),q);
+ SetPixelAlpha(image,OpaqueAlpha,q);
+ q+=GetPixelChannels(image);
}
else
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- q->red=(Quantum) QuantumRange-ScaleCharToQuantum((unsigned char)
- GETJSAMPLE(*p++));
- q->green=(Quantum) QuantumRange-ScaleCharToQuantum((unsigned char)
- GETJSAMPLE(*p++));
- q->blue=(Quantum) QuantumRange-ScaleCharToQuantum((unsigned char)
- GETJSAMPLE(*p++));
- SetOpacityPixelComponent(q,OpaqueOpacity);
- indexes[x]=(IndexPacket) QuantumRange-ScaleCharToQuantum(
- (unsigned char) GETJSAMPLE(*p++));
- q++;
+ SetPixelCyan(image,QuantumRange-ScaleCharToQuantum(
+ (unsigned char) GETJSAMPLE(*p++)),q);
+ SetPixelMagenta(image,QuantumRange-ScaleCharToQuantum(
+ (unsigned char) GETJSAMPLE(*p++)),q);
+ SetPixelYellow(image,QuantumRange-ScaleCharToQuantum(
+ (unsigned char) GETJSAMPLE(*p++)),q);
+ SetPixelBlack(image,QuantumRange-ScaleCharToQuantum(
+ (unsigned char) GETJSAMPLE(*p++)),q);
+ SetPixelAlpha(image,OpaqueAlpha,q);
+ q+=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
- if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
- break;
+ status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
+ image->rows);
+ if (status == MagickFalse)
+ {
+ jpeg_abort_decompress(&jpeg_info);
+ break;
+ }
}
+ if (status != MagickFalse)
+ {
+ error_manager.finished=MagickTrue;
+ if (setjmp(error_manager.error_recovery) == 0)
+ (void) jpeg_finish_decompress(&jpeg_info);
+ }
/*
Free jpeg resources.
*/
- (void) jpeg_finish_decompress(&jpeg_info);
jpeg_destroy_decompress(&jpeg_info);
jpeg_pixels=(unsigned char *) RelinquishMagickMemory(jpeg_pixels);
(void) CloseBlob(image);
%
% The format of the RegisterJPEGImage method is:
%
-% unsigned long RegisterJPEGImage(void)
+% size_t RegisterJPEGImage(void)
%
*/
-ModuleExport unsigned long RegisterJPEGImage(void)
+ModuleExport size_t RegisterJPEGImage(void)
{
char
version[MaxTextExtent];
*version='\0';
#if defined(JPEG_LIB_VERSION)
- (void) FormatMagickString(version,MaxTextExtent,"%d",JPEG_LIB_VERSION);
+ (void) FormatLocaleString(version,MaxTextExtent,"%d",JPEG_LIB_VERSION);
#endif
entry=SetMagickInfo("JPEG");
entry->thread_support=NoThreadSupport;
%
% The format of the WriteJPEGImage method is:
%
-% MagickBooleanType WriteJPEGImage(const ImageInfo *image_info,Image *image)
+% MagickBooleanType WriteJPEGImage(const ImageInfo *image_info,
+% Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o jpeg_image: The image.
%
+% o exception: return any errors or warnings in this structure.
%
*/
+static QuantizationTable *DestroyQuantizationTable(QuantizationTable *table)
+{
+ assert(table != (QuantizationTable *) NULL);
+ if (table->slot != (char *) NULL)
+ table->slot=DestroyString(table->slot);
+ if (table->description != (char *) NULL)
+ table->description=DestroyString(table->description);
+ if (table->levels != (unsigned int *) NULL)
+ table->levels=(unsigned int *) RelinquishMagickMemory(table->levels);
+ table=(QuantizationTable *) RelinquishMagickMemory(table);
+ return(table);
+}
+
static boolean EmptyOutputBuffer(j_compress_ptr cinfo)
{
DestinationManager
return(TRUE);
}
+static QuantizationTable *GetQuantizationTable(const char *filename,
+ const char *slot,ExceptionInfo *exception)
+{
+ char
+ *p,
+ *xml;
+
+ const char
+ *attribute,
+ *content;
+
+ double
+ value;
+
+ register ssize_t
+ i;
+
+ ssize_t
+ j;
+
+ QuantizationTable
+ *table;
+
+ size_t
+ length;
+
+ XMLTreeInfo
+ *description,
+ *levels,
+ *quantization_tables,
+ *table_iterator;
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Loading quantization tables \"%s\" ...",filename);
+ table=(QuantizationTable *) NULL;
+ xml=FileToString(filename,~0,exception);
+ if (xml == (char *) NULL)
+ return(table);
+ quantization_tables=NewXMLTree(xml,exception);
+ if (quantization_tables == (XMLTreeInfo *) NULL)
+ {
+ xml=DestroyString(xml);
+ return(table);
+ }
+ for (table_iterator=GetXMLTreeChild(quantization_tables,"table");
+ table_iterator != (XMLTreeInfo *) NULL;
+ table_iterator=GetNextXMLTreeTag(table_iterator))
+ {
+ attribute=GetXMLTreeAttribute(table_iterator,"slot");
+ if ((attribute != (char *) NULL) && (LocaleCompare(slot,attribute) == 0))
+ break;
+ attribute=GetXMLTreeAttribute(table_iterator,"alias");
+ if ((attribute != (char *) NULL) && (LocaleCompare(slot,attribute) == 0))
+ break;
+ }
+ if (table_iterator == (XMLTreeInfo *) NULL)
+ {
+ xml=DestroyString(xml);
+ return(table);
+ }
+ description=GetXMLTreeChild(table_iterator,"description");
+ if (description == (XMLTreeInfo *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingElement", "<description>, slot \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ levels=GetXMLTreeChild(table_iterator,"levels");
+ if (levels == (XMLTreeInfo *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingElement", "<levels>, slot \"%s\"", slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table=(QuantizationTable *) AcquireMagickMemory(sizeof(*table));
+ if (table == (QuantizationTable *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,
+ "UnableToAcquireQuantizationTable");
+ table->slot=(char *) NULL;
+ table->description=(char *) NULL;
+ table->levels=(unsigned int *) NULL;
+ attribute=GetXMLTreeAttribute(table_iterator,"slot");
+ if (attribute != (char *) NULL)
+ table->slot=ConstantString(attribute);
+ content=GetXMLTreeContent(description);
+ if (content != (char *) NULL)
+ table->description=ConstantString(content);
+ attribute=GetXMLTreeAttribute(levels,"width");
+ if (attribute == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingAttribute", "<levels width>, slot \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table->width=StringToUnsignedLong(attribute);
+ if (table->width == 0)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidAttribute", "<levels width>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ attribute=GetXMLTreeAttribute(levels,"height");
+ if (attribute == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingAttribute", "<levels height>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table->height=StringToUnsignedLong(attribute);
+ if (table->height == 0)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidAttribute", "<levels height>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ attribute=GetXMLTreeAttribute(levels,"divisor");
+ if (attribute == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingAttribute", "<levels divisor>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ table->divisor=InterpretLocaleValue(attribute,(char **) NULL);
+ if (table->divisor == 0.0)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidAttribute", "<levels divisor>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ content=GetXMLTreeContent(levels);
+ if (content == (char *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlMissingContent", "<levels>, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ length=(size_t) table->width*table->height;
+ if (length < 64)
+ length=64;
+ table->levels=(unsigned int *) AcquireQuantumMemory(length,
+ sizeof(*table->levels));
+ if (table->levels == (unsigned int *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,
+ "UnableToAcquireQuantizationTable");
+ for (i=0; i < (ssize_t) (table->width*table->height); i++)
+ {
+ table->levels[i]=(unsigned int) (InterpretLocaleValue(content,&p)/
+ table->divisor+0.5);
+ while (isspace((int) ((unsigned char) *p)) != 0)
+ p++;
+ if (*p == ',')
+ p++;
+ content=p;
+ }
+ value=InterpretLocaleValue(content,&p);
+ (void) value;
+ if (p != content)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "XmlInvalidContent", "<level> too many values, table \"%s\"",slot);
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ table=DestroyQuantizationTable(table);
+ xml=DestroyString(xml);
+ return(table);
+ }
+ for (j=i; j < 64; j++)
+ table->levels[j]=table->levels[j-1];
+ quantization_tables=DestroyXMLTree(quantization_tables);
+ xml=DestroyString(xml);
+ return(table);
+}
+
static void InitializeDestination(j_compress_ptr cinfo)
{
DestinationManager
MagickBooleanType
iptc;
- register long
+ register ssize_t
i;
size_t
- length;
+ length,
+ tag_length;
StringInfo
*custom_profile;
- unsigned long
- tag_length;
-
/*
Save image profile as a APP marker.
*/
ResetImageProfileIterator(image);
for (name=GetNextImageProfile(image); name != (const char *) NULL; )
{
+ register unsigned char
+ *p;
+
profile=GetImageProfile(image,name);
+ p=GetStringInfoDatum(custom_profile);
if (LocaleCompare(name,"EXIF") == 0)
- for (i=0; i < (long) GetStringInfoLength(profile); i+=65533L)
+ for (i=0; i < (ssize_t) GetStringInfoLength(profile); i+=65533L)
{
length=MagickMin(GetStringInfoLength(profile)-i,65533L);
jpeg_write_marker(jpeg_info,XML_MARKER,GetStringInfoDatum(profile)+i,
tag_length=14;
p=GetStringInfoDatum(custom_profile);
(void) CopyMagickMemory(p,ICC_PROFILE,tag_length);
- for (i=0; i < (long) GetStringInfoLength(profile); i+=65519L)
+ for (i=0; i < (ssize_t) GetStringInfoLength(profile); i+=65519L)
{
length=MagickMin(GetStringInfoLength(profile)-i,65519L);
- p=GetStringInfoDatum(custom_profile);
p[12]=(unsigned char) ((i/65519L)+1);
p[13]=(unsigned char) (GetStringInfoLength(profile)/65519L+1);
(void) CopyMagickMemory(p+tag_length,GetStringInfoDatum(profile)+i,
if (((LocaleCompare(name,"IPTC") == 0) ||
(LocaleCompare(name,"8BIM") == 0)) && (iptc == MagickFalse))
{
- register unsigned char
- *p;
-
- unsigned long
+ size_t
roundup;
iptc=MagickTrue;
- p=GetStringInfoDatum(custom_profile);
- if (LocaleNCompare((char *) GetStringInfoDatum(profile),"8BIM",4) == 0)
- {
- (void) CopyMagickMemory(p,"Photoshop 3.0\0",14);
- tag_length=14;
- }
- else
- {
- (void) CopyMagickMemory(p,"Photoshop 3.0\08BIM\04\04\0\0\0\0",24);
- p[13]=0x00;
- p[24]=(unsigned char) (GetStringInfoLength(profile) >> 8);
- p[25]=(unsigned char) (GetStringInfoLength(profile) & 0xff);
- tag_length=26;
- }
- for (i=0; i < (long) GetStringInfoLength(profile); i+=65500L)
+ for (i=0; i < (ssize_t) GetStringInfoLength(profile); i+=65500L)
{
length=MagickMin(GetStringInfoLength(profile)-i,65500L);
- roundup=(unsigned long) (length & 0x01);
- (void) CopyMagickMemory(p+tag_length,GetStringInfoDatum(profile)+i,
- length);
+ roundup=(size_t) (length & 0x01);
+ if (LocaleNCompare((char *) GetStringInfoDatum(profile),"8BIM",4) == 0)
+ {
+ (void) memcpy(p,"Photoshop 3.0 ",14);
+ tag_length=14;
+ }
+ else
+ {
+ (void) CopyMagickMemory(p,"Photoshop 3.0 8BIM\04\04\0\0\0\0",24);
+ tag_length=26;
+ p[24]=(unsigned char) (length >> 8);
+ p[25]=(unsigned char) (length & 0xff);
+ }
+ p[13]=0x00;
+ (void) memcpy(p+tag_length,GetStringInfoDatum(profile)+i,length);
if (roundup != 0)
p[length+tag_length]='\0';
jpeg_write_marker(jpeg_info,IPTC_MARKER,GetStringInfoDatum(
/*
Add namespace to XMP profile.
*/
- xmp_profile=StringToStringInfo("http://ns.adobe.com/xap/1.0/");
+ xmp_profile=StringToStringInfo("http://ns.adobe.com/xap/1.0/ ");
ConcatenateStringInfo(xmp_profile,profile);
GetStringInfoDatum(xmp_profile)[28]='\0';
- for (i=0; i < (long) GetStringInfoLength(xmp_profile); i+=65533L)
+ for (i=0; i < (ssize_t) GetStringInfoLength(xmp_profile); i+=65533L)
{
length=MagickMin(GetStringInfoLength(xmp_profile)-i,65533L);
jpeg_write_marker(jpeg_info,XML_MARKER,
}
xmp_profile=DestroyStringInfo(xmp_profile);
}
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s profile: %lu bytes",
- name,(unsigned long) GetStringInfoLength(profile));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%s profile: %.20g bytes",name,(double) GetStringInfoLength(profile));
name=GetNextImageProfile(image);
}
custom_profile=DestroyStringInfo(custom_profile);
register const char
*p;
- register long
+ register ssize_t
i;
- unsigned long
+ size_t
lines;
if (text == (char *) NULL)
if (textlist == (char **) NULL)
ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
p=text;
- for (i=0; i < (long) lines; i++)
+ for (i=0; i < (ssize_t) lines; i++)
{
for (q=(char *) p; *q != '\0'; q++)
if (*q == ',')
}
static MagickBooleanType WriteJPEGImage(const ImageInfo *image_info,
- Image *image)
+ Image *image,ExceptionInfo *exception)
{
const char
*option,
ErrorManager
error_manager;
+ int
+ quality;
+
JSAMPLE
*jpeg_pixels;
JSAMPROW
scanline[1];
- long
- y;
-
MagickBooleanType
status;
register JSAMPLE
*q;
- register long
+ register ssize_t
i;
+ ssize_t
+ y;
+
struct jpeg_compress_struct
jpeg_info;
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
/*
Initialize JPEG parameters.
*/
+ (void) ResetMagickMemory(&error_manager,0,sizeof(error_manager));
(void) ResetMagickMemory(&jpeg_info,0,sizeof(jpeg_info));
(void) ResetMagickMemory(&jpeg_error,0,sizeof(jpeg_error));
jpeg_info.client_data=(void *) image;
jpeg_info.err=jpeg_std_error(&jpeg_error);
- jpeg_info.err->emit_message=(void (*)(j_common_ptr,int)) EmitMessage;
+ jpeg_info.err->emit_message=(void (*)(j_common_ptr,int)) JPEGWarningHandler;
jpeg_info.err->error_exit=(void (*)(j_common_ptr)) JPEGErrorHandler;
+ error_manager.exception=exception;
error_manager.image=image;
jpeg_pixels=(JSAMPLE *) NULL;
if (setjmp(error_manager.error_recovery) != 0)
}
default:
{
- if (image->colorspace != RGBColorspace)
- (void) TransformImageColorspace(image,RGBColorspace);
+ if (IsRGBColorspace(image->colorspace) == MagickFalse)
+ (void) TransformImageColorspace(image,sRGBColorspace,exception);
break;
}
}
if ((image_info->type != TrueColorType) &&
- (IsGrayImage(image,&image->exception) != MagickFalse))
+ (IsImageGray(image,exception) != MagickFalse))
{
jpeg_info.input_components=1;
jpeg_info.in_color_space=JCS_GRAYSCALE;
jpeg_info.density_unit=(UINT8) 1;
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Image resolution: %ld,%ld",(long) (image->x_resolution+0.5),
- (long) (image->y_resolution+0.5));
- if ((image->x_resolution != 0.0) && (image->y_resolution != 0.0))
+ "Image resolution: %.20g,%.20g",floor(image->resolution.x+0.5),
+ floor(image->resolution.y+0.5));
+ if ((image->resolution.x != 0.0) && (image->resolution.y != 0.0))
{
/*
Set image resolution.
*/
jpeg_info.write_JFIF_header=MagickTrue;
- jpeg_info.X_density=(UINT16) image->x_resolution;
- jpeg_info.Y_density=(UINT16) image->y_resolution;
+ jpeg_info.X_density=(UINT16) floor(image->resolution.x+0.5);
+ jpeg_info.Y_density=(UINT16) floor(image->resolution.y+0.5);
if (image->units == PixelsPerInchResolution)
jpeg_info.density_unit=(UINT8) 1;
if (image->units == PixelsPerCentimeterResolution)
jpeg_info.density_unit=(UINT8) 2;
}
+ jpeg_info.dct_method=JDCT_FLOAT;
option=GetImageOption(image_info,"jpeg:dct-method");
if (option != (const char *) NULL)
switch (*option)
}
option=GetImageOption(image_info,"jpeg:optimize-coding");
if (option != (const char *) NULL)
- {
- jpeg_info.optimize_coding=MagickFalse;
- if (IsMagickTrue(option) != MagickFalse)
- jpeg_info.optimize_coding=MagickTrue;
- }
+ jpeg_info.optimize_coding=IsStringTrue(option);
else
{
MagickSizeType
Perform optimization only if available memory resources permit it.
*/
status=AcquireMagickResource(MemoryResource,length);
- if (status != MagickFalse)
- jpeg_info.optimize_coding=MagickTrue;
RelinquishMagickResource(MemoryResource,length);
+ jpeg_info.optimize_coding=status;
}
}
#if (JPEG_LIB_VERSION >= 61) && defined(C_PROGRESSIVE_SUPPORTED)
*jpeg_info;
jpeg_info=CloneImageInfo(image_info);
- jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
+ jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
if (jpeg_image != (Image *) NULL)
{
MagickSizeType
Search for compression quality that does not exceed image extent.
*/
jpeg_info->quality=0;
- extent=(MagickSizeType) SiPrefixToDouble(option,100.0);
+ extent=(MagickSizeType) SiPrefixToDoubleInterval(option,100.0);
(void) DeleteImageOption(jpeg_info,"jpeg:extent");
(void) AcquireUniqueFilename(jpeg_image->filename);
maximum=101;
for (minimum=0; minimum != maximum; )
{
jpeg_image->quality=minimum+(maximum-minimum)/2;
- status=WriteJPEGImage(jpeg_info,jpeg_image);
+ status=WriteJPEGImage(jpeg_info,jpeg_image,exception);
if (GetBlobSize(jpeg_image) <= extent)
minimum=jpeg_image->quality+1;
else
}
jpeg_info=DestroyImageInfo(jpeg_info);
}
+ quality=92;
if ((image_info->compression != LosslessJPEGCompression) &&
(image->quality <= 100))
{
- if (image->quality == UndefinedCompressionQuality)
- jpeg_set_quality(&jpeg_info,92,MagickTrue);
- else
- jpeg_set_quality(&jpeg_info,(int) image->quality,MagickTrue);
+ if (image->quality != UndefinedCompressionQuality)
+ quality=(int) image->quality;
if (image->debug != MagickFalse)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Quality: %lu",
- image->quality);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Quality: %.20g",
+ (double) image->quality);
}
else
{
#if !defined(C_LOSSLESS_SUPPORTED)
- jpeg_set_quality(&jpeg_info,100,MagickTrue);
+ quality=100;
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"Quality: 100");
#else
if (image->quality < 100)
- (void) ThrowMagickException(&image->exception,GetMagickModule(),
- CoderWarning,"LosslessToLossyJPEGConversion",image->filename);
+ (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
+ "LosslessToLossyJPEGConversion",image->filename);
else
{
int
}
#endif
}
+ jpeg_set_quality(&jpeg_info,quality,MagickTrue);
sampling_factor=(const char *) NULL;
- value=GetImageProperty(image,"jpeg:sampling-factor");
+ value=GetImageProperty(image,"jpeg:sampling-factor",exception);
if (value != (char *) NULL)
{
sampling_factor=value;
jpeg_info.comp_info[i].h_samp_factor=1;
jpeg_info.comp_info[i].v_samp_factor=1;
}
+ option=GetImageOption(image_info,"jpeg:q-table");
+ if (option != (const char *) NULL)
+ {
+ QuantizationTable
+ *table;
+
+ /*
+ Custom quantization tables.
+ */
+ table=GetQuantizationTable(option,"0",exception);
+ if (table != (QuantizationTable *) NULL)
+ {
+ jpeg_add_quant_table(&jpeg_info,0,table->levels,jpeg_quality_scaling(
+ quality),0);
+ table=DestroyQuantizationTable(table);
+ }
+ table=GetQuantizationTable(option,"1",exception);
+ if (table != (QuantizationTable *) NULL)
+ {
+ jpeg_add_quant_table(&jpeg_info,1,table->levels,jpeg_quality_scaling(
+ quality),0);
+ table=DestroyQuantizationTable(table);
+ }
+ table=GetQuantizationTable(option,"2",exception);
+ if (table != (QuantizationTable *) NULL)
+ {
+ jpeg_add_quant_table(&jpeg_info,2,table->levels,jpeg_quality_scaling(
+ quality),0);
+ table=DestroyQuantizationTable(table);
+ }
+ table=GetQuantizationTable(option,"3",exception);
+ if (table != (QuantizationTable *) NULL)
+ {
+ jpeg_add_quant_table(&jpeg_info,3,table->levels,jpeg_quality_scaling(
+ quality),0);
+ table=DestroyQuantizationTable(table);
+ }
+ }
jpeg_start_compress(&jpeg_info,MagickTrue);
if (image->debug != MagickFalse)
{
else
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
"Storage class: DirectClass");
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Depth: %lu",
- image->depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Depth: %.20g",
+ (double) image->depth);
if (image->colors != 0)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Number of colors: %lu",image->colors);
+ "Number of colors: %.20g",(double) image->colors);
else
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
"Number of colors: unspecified");
/*
Write JPEG profiles.
*/
- value=GetImageProperty(image,"comment");
+ value=GetImageProperty(image,"comment",exception);
if (value != (char *) NULL)
- for (i=0; i < (long) strlen(value); i+=65533L)
+ for (i=0; i < (ssize_t) strlen(value); i+=65533L)
jpeg_write_marker(&jpeg_info,JPEG_COM,(unsigned char *) value+i,
(unsigned int) MagickMin((size_t) strlen(value+i),65533L));
if (image->profiles != (void *) NULL)
{
if ((jpeg_info.in_color_space == JCS_RGB) ||
(jpeg_info.in_color_space == JCS_YCbCr))
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- register const PixelPacket
+ register const Quantum
*p;
- register long
+ register ssize_t
x;
- p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
break;
q=jpeg_pixels;
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- *q++=(JSAMPLE) ScaleQuantumToChar(GetRedPixelComponent(p));
- *q++=(JSAMPLE) ScaleQuantumToChar(GetGreenPixelComponent(p));
- *q++=(JSAMPLE) ScaleQuantumToChar(GetBluePixelComponent(p));
- p++;
+ *q++=(JSAMPLE) ScaleQuantumToChar(GetPixelRed(image,p));
+ *q++=(JSAMPLE) ScaleQuantumToChar(GetPixelGreen(image,p));
+ *q++=(JSAMPLE) ScaleQuantumToChar(GetPixelBlue(image,p));
+ p+=GetPixelChannels(image);
}
(void) jpeg_write_scanlines(&jpeg_info,scanline,1);
- if (SetImageProgress(image,SaveImageTag,y,image->rows) == MagickFalse)
+ status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+ image->rows);
+ if (status == MagickFalse)
break;
}
else
if (jpeg_info.in_color_space == JCS_GRAYSCALE)
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- register const PixelPacket
+ register const Quantum
*p;
- register long
+ register ssize_t
x;
- p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
break;
q=jpeg_pixels;
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- *q++=(JSAMPLE) ScaleQuantumToChar(PixelIntensityToQuantum(p));
- p++;
+ *q++=(JSAMPLE) ScaleQuantumToChar(GetPixelIntensity(image,p));
+ p+=GetPixelChannels(image);
}
(void) jpeg_write_scanlines(&jpeg_info,scanline,1);
- if (SetImageProgress(image,SaveImageTag,y,image->rows) == MagickFalse)
+ status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+ image->rows);
+ if (status == MagickFalse)
break;
}
else
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- register const IndexPacket
- *indexes;
-
- register const PixelPacket
+ register const Quantum
*p;
- register long
+ register ssize_t
x;
- p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
break;
q=jpeg_pixels;
- indexes=GetVirtualIndexQueue(image);
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
/*
Convert DirectClass packets to contiguous CMYK scanlines.
*/
*q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange-
- GetRedPixelComponent(p))));
+ GetPixelRed(image,p))));
*q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange-
- GetGreenPixelComponent(p))));
+ GetPixelGreen(image,p))));
*q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange-
- GetBluePixelComponent(p))));
+ GetPixelBlue(image,p))));
*q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange-
- indexes[x])));
- p++;
+ GetPixelBlack(image,p))));
+ p+=GetPixelChannels(image);
}
(void) jpeg_write_scanlines(&jpeg_info,scanline,1);
- if (SetImageProgress(image,SaveImageTag,y,image->rows) == MagickFalse)
+ status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+ image->rows);
+ if (status == MagickFalse)
break;
}
}
else
if (jpeg_info.in_color_space == JCS_GRAYSCALE)
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- register const PixelPacket
+ register const Quantum
*p;
- register long
+ register ssize_t
x;
- p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
break;
q=jpeg_pixels;
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- *q++=(JSAMPLE) (ScaleQuantumToShort(PixelIntensityToQuantum(p)) >>
- 4);
- p++;
+ *q++=(JSAMPLE) (ScaleQuantumToShort(GetPixelIntensity(image,p)) >> 4);
+ p+=GetPixelChannels(image);
}
(void) jpeg_write_scanlines(&jpeg_info,scanline,1);
- if (SetImageProgress(image,SaveImageTag,y,image->rows) == MagickFalse)
+ status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+ image->rows);
+ if (status == MagickFalse)
break;
}
else
if ((jpeg_info.in_color_space == JCS_RGB) ||
(jpeg_info.in_color_space == JCS_YCbCr))
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- register const PixelPacket
+ register const Quantum
*p;
- register long
+ register ssize_t
x;
- p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
break;
q=jpeg_pixels;
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
- *q++=(JSAMPLE) (ScaleQuantumToShort(GetRedPixelComponent(p)) >>
- 4);
- *q++=(JSAMPLE) (ScaleQuantumToShort(GetGreenPixelComponent(p)) >>
- 4);
- *q++=(JSAMPLE) (ScaleQuantumToShort(GetBluePixelComponent(p)) >>
- 4);
- p++;
+ *q++=(JSAMPLE) (ScaleQuantumToShort(GetPixelRed(image,p)) >> 4);
+ *q++=(JSAMPLE) (ScaleQuantumToShort(GetPixelGreen(image,p)) >> 4);
+ *q++=(JSAMPLE) (ScaleQuantumToShort(GetPixelBlue(image,p)) >> 4);
+ p+=GetPixelChannels(image);
}
(void) jpeg_write_scanlines(&jpeg_info,scanline,1);
- status=SetImageProgress(image,SaveImageTag,y,image->rows);
+ status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+ image->rows);
if (status == MagickFalse)
break;
}
else
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- register const IndexPacket
- *indexes;
-
- register const PixelPacket
+ register const Quantum
*p;
- register long
+ register ssize_t
x;
- p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
break;
q=jpeg_pixels;
- indexes=GetVirtualIndexQueue(image);
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
/*
Convert DirectClass packets to contiguous CMYK scanlines.
*/
*q++=(JSAMPLE) (4095-(ScaleQuantumToShort(
- GetRedPixelComponent(p)) >> 4));
+ GetPixelRed(image,p)) >> 4));
*q++=(JSAMPLE) (4095-(ScaleQuantumToShort(
- GetGreenPixelComponent(p)) >> 4));
+ GetPixelGreen(image,p)) >> 4));
*q++=(JSAMPLE) (4095-(ScaleQuantumToShort(
- GetBluePixelComponent(p)) >> 4));
- *q++=(JSAMPLE) (4095-(ScaleQuantumToShort(indexes[x]) >> 4));
- p++;
+ GetPixelBlue(image,p)) >> 4));
+ *q++=(JSAMPLE) (4095-(ScaleQuantumToShort(
+ GetPixelBlack(image,p)) >> 4));
+ p+=GetPixelChannels(image);
}
(void) jpeg_write_scanlines(&jpeg_info,scanline,1);
- status=SetImageProgress(image,SaveImageTag,y,image->rows);
+ status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+ image->rows);
if (status == MagickFalse)
break;
}
- if (y == (long) image->rows)
+ if (y == (ssize_t) image->rows)
jpeg_finish_compress(&jpeg_info);
/*
Relinquish resources.