diff --git a/Makefile.in b/Makefile.in index cc42a3c14b..b66b28f64a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -298,23 +298,24 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config/config.h -CONFIG_CLEAN_FILES = common.shi config/policy.xml config/configure.xml \ - config/delegates.xml config/ImageMagick.rdf \ - config/MagickCore.dox config/MagickWand.dox \ - config/Magick++.dox config/type-apple.xml \ - config/type-dejavu.xml config/type-ghostscript.xml \ - config/type-urw-base35.xml config/type-windows.xml \ - config/type.xml ImageMagick.spec Magick++/bin/Magick++-config \ - MagickCore/ImageMagick.pc Magick++/lib/Magick++.pc \ - MagickCore/MagickCore-config MagickCore/MagickCore.pc \ - MagickCore/version.h magick.sh PerlMagick/check.sh \ - PerlMagick/default/Magick.pm PerlMagick/Makefile.PL \ - PerlMagick/default/Makefile.PL PerlMagick/quantum/Makefile.PL \ - PerlMagick/quantum/quantum.pm PerlMagick/quantum/quantum.xs \ - PerlMagick/quantum/typemap utilities/animate.1 \ - utilities/compare.1 utilities/composite.1 utilities/conjure.1 \ - utilities/convert.1 utilities/display.1 utilities/identify.1 \ - utilities/ImageMagick.1 utilities/import.1 utilities/magick.1 \ +CONFIG_CLEAN_FILES = app-image/AppRun common.shi config/policy.xml \ + config/configure.xml config/delegates.xml \ + config/ImageMagick.rdf config/MagickCore.dox \ + config/MagickWand.dox config/Magick++.dox \ + config/type-apple.xml config/type-dejavu.xml \ + config/type-ghostscript.xml config/type-urw-base35.xml \ + config/type-windows.xml config/type.xml ImageMagick.spec \ + Magick++/bin/Magick++-config MagickCore/ImageMagick.pc \ + Magick++/lib/Magick++.pc MagickCore/MagickCore-config \ + MagickCore/MagickCore.pc MagickCore/version.h magick.sh \ + PerlMagick/check.sh PerlMagick/default/Magick.pm \ + PerlMagick/Makefile.PL PerlMagick/default/Makefile.PL \ + PerlMagick/quantum/Makefile.PL PerlMagick/quantum/quantum.pm \ + PerlMagick/quantum/quantum.xs PerlMagick/quantum/typemap \ + utilities/animate.1 utilities/compare.1 utilities/composite.1 \ + utilities/conjure.1 utilities/convert.1 utilities/display.1 \ + utilities/identify.1 utilities/ImageMagick.1 \ + utilities/import.1 utilities/magick.1 \ utilities/magick-script.1 utilities/mogrify.1 \ utilities/montage.1 utilities/stream.1 \ MagickWand/MagickWand-config MagickWand/MagickWand.pc @@ -3094,6 +3095,7 @@ am__DIST_COMMON = $(srcdir)/ImageMagick.spec.in \ $(top_srcdir)/PerlMagick/quantum/quantum.pm.in \ $(top_srcdir)/PerlMagick/quantum/quantum.xs.in \ $(top_srcdir)/PerlMagick/quantum/typemap.in \ + $(top_srcdir)/app-image/AppRun.in \ $(top_srcdir)/config/ImageMagick.rdf.in \ $(top_srcdir)/config/Magick++.dox.in \ $(top_srcdir)/config/MagickCore.dox.in \ @@ -6309,6 +6311,8 @@ $(top_srcdir)/config/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) distclean-hdr: -rm -f config/config.h config/stamp-h1 +app-image/AppRun: $(top_builddir)/config.status $(top_srcdir)/app-image/AppRun.in + cd $(top_builddir) && $(SHELL) ./config.status $@ common.shi: $(top_builddir)/config.status $(srcdir)/common.shi.in cd $(top_builddir) && $(SHELL) ./config.status $@ config/policy.xml: $(top_builddir)/config.status diff --git a/coders/jpeg.c b/coders/jpeg.c index b30f989768..d9ca87ce34 100644 --- a/coders/jpeg.c +++ b/coders/jpeg.c @@ -262,6 +262,14 @@ static MagickBooleanType IsJPEG(const unsigned char *magick,const size_t length) % */ +static inline int JPEGGetSample(const struct jpeg_decompress_struct *jpeg_info, + const JSAMPLE *p) +{ + if (jpeg_info->data_precision > 8) + return((int) (*(unsigned short *) p)); + return((int) (*(JSAMPLE *) p)); +} + static boolean FillInputBuffer(j_decompress_ptr compress_info) { SourceManager @@ -1086,9 +1094,6 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info, *volatile jpeg_pixels, *p; - JSAMPROW - scanline[1]; - MagickBooleanType status; @@ -1111,6 +1116,7 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info, jpeg_progress; size_t + bytes_per_pixel, max_memory_to_use, units; @@ -1403,8 +1409,9 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info, client_info=JPEGCleanup(jpeg_info,client_info); ThrowReaderException(CorruptImageError,"ImageTypeNotSupported"); } + bytes_per_pixel=(jpeg_info->data_precision+7)/8; memory_info=AcquireVirtualMemory((size_t) image->columns, - (size_t) jpeg_info->output_components*sizeof(*jpeg_pixels)); + (size_t) jpeg_info->output_components*bytes_per_pixel); if (memory_info == (MemoryInfo *) NULL) { client_info=JPEGCleanup(jpeg_info,client_info); @@ -1451,16 +1458,42 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info, image->colormap[i].alpha=(MagickRealType) OpaqueAlpha; } } - scanline[0]=(JSAMPROW) jpeg_pixels; for (y=0; y < (ssize_t) image->rows; y++) { - ssize_t - x; + JDIMENSION + number_scanlines = 0; Quantum *magick_restrict q; - if (jpeg_read_scanlines(jpeg_info,scanline,1) != 1) + ssize_t + x; + + switch (jpeg_info->data_precision) + { + case 16: + { +#if defined(MAGICKCORE_HAVE_JPEG16_READ_SCANLINES) + number_scanlines=jpeg16_read_scanlines(jpeg_info,(J16SAMPROW *) + &jpeg_pixels,1); + break; +#endif + } + case 12: + { +#if defined(MAGICKCORE_HAVE_JPEG12_READ_SCANLINES) + number_scanlines=jpeg12_read_scanlines(jpeg_info,(J12SAMPROW *) + &jpeg_pixels,1); + break; +#endif + } + default: + { + number_scanlines=jpeg_read_scanlines(jpeg_info,(JSAMPROW *) &jpeg_pixels,1); + break; + } + } + if (number_scanlines != 1) { (void) ThrowMagickException(exception,GetMagickModule(), CorruptImageWarning,"SkipToSyncByte","`%s'",image->filename); @@ -1470,95 +1503,59 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info, q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; - if (jpeg_info->data_precision > 8) - { - unsigned short - scale; - - scale=65535/(unsigned short) GetQuantumRange((size_t) + { + const unsigned int + scale = 65535U/(unsigned int) GetQuantumRange( jpeg_info->data_precision); - if (jpeg_info->output_components == 1) - for (x=0; x < (ssize_t) image->columns; x++) - { - ssize_t - pixel; - pixel=(ssize_t) (scale*GETJSAMPLE(*p)); - index=(Quantum) ConstrainColormapIndex(image,pixel,exception); - SetPixelIndex(image,index,q); - SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q); - p++; - q+=GetPixelChannels(image); - } - else - if (image->colorspace != CMYKColorspace) - for (x=0; x < (ssize_t) image->columns; x++) - { - SetPixelRed(image,ScaleShortToQuantum( - (unsigned short) (scale*GETJSAMPLE(*p++))),q); - SetPixelGreen(image,ScaleShortToQuantum( - (unsigned short) (scale*GETJSAMPLE(*p++))),q); - SetPixelBlue(image,ScaleShortToQuantum( - (unsigned short) (scale*GETJSAMPLE(*p++))),q); - SetPixelAlpha(image,OpaqueAlpha,q); - q+=GetPixelChannels(image); - } - else - for (x=0; x < (ssize_t) image->columns; x++) - { - SetPixelCyan(image,QuantumRange-ScaleShortToQuantum( - (unsigned short) (scale*GETJSAMPLE(*p++))),q); - SetPixelMagenta(image,QuantumRange-ScaleShortToQuantum( - (unsigned short) (scale*GETJSAMPLE(*p++))),q); - SetPixelYellow(image,QuantumRange-ScaleShortToQuantum( - (unsigned short) (scale*GETJSAMPLE(*p++))),q); - SetPixelBlack(image,QuantumRange-ScaleShortToQuantum( - (unsigned short) (scale*GETJSAMPLE(*p++))),q); - SetPixelAlpha(image,OpaqueAlpha,q); - q+=GetPixelChannels(image); - } - } - else if (jpeg_info->output_components == 1) for (x=0; x < (ssize_t) image->columns; x++) { ssize_t pixel; - pixel=(ssize_t) GETJSAMPLE(*p); + pixel=(ssize_t) (scale*JPEGGetSample(jpeg_info,p)); index=(Quantum) ConstrainColormapIndex(image,pixel,exception); SetPixelIndex(image,index,q); SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q); - p++; + p+=bytes_per_pixel; q+=GetPixelChannels(image); } else if (image->colorspace != CMYKColorspace) for (x=0; x < (ssize_t) image->columns; x++) { - SetPixelRed(image,ScaleCharToQuantum((unsigned char) - GETJSAMPLE(*p++)),q); - SetPixelGreen(image,ScaleCharToQuantum((unsigned char) - GETJSAMPLE(*p++)),q); - SetPixelBlue(image,ScaleCharToQuantum((unsigned char) - GETJSAMPLE(*p++)),q); + SetPixelRed(image,ScaleShortToQuantum((unsigned short) + (scale*JPEGGetSample(jpeg_info,p))),q); + p+=bytes_per_pixel; + SetPixelGreen(image,ScaleShortToQuantum((unsigned short) + (scale*JPEGGetSample(jpeg_info,p))),q); + p+=bytes_per_pixel; + SetPixelBlue(image,ScaleShortToQuantum((unsigned short) + (scale*JPEGGetSample(jpeg_info,p))),q); SetPixelAlpha(image,OpaqueAlpha,q); + p+=bytes_per_pixel; q+=GetPixelChannels(image); } else for (x=0; x < (ssize_t) image->columns; x++) { - 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); + SetPixelCyan(image,QuantumRange-ScaleShortToQuantum( + (unsigned short) (scale*JPEGGetSample(jpeg_info,p))),q); + p+=bytes_per_pixel; + SetPixelMagenta(image,QuantumRange-ScaleShortToQuantum( + (unsigned short) (scale*JPEGGetSample(jpeg_info,p))),q); + p+=bytes_per_pixel; + SetPixelYellow(image,QuantumRange-ScaleShortToQuantum( + (unsigned short) (scale*JPEGGetSample(jpeg_info,p))),q); + p+=bytes_per_pixel; + SetPixelBlack(image,QuantumRange-ScaleShortToQuantum( + (unsigned short) (scale*JPEGGetSample(jpeg_info,p))),q); SetPixelAlpha(image,OpaqueAlpha,q); + p+=bytes_per_pixel; q+=GetPixelChannels(image); } + } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, @@ -1703,8 +1700,7 @@ static Image *ReadJPEGImage(const ImageInfo *image_info, return(images); } #endif - - + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @@ -1839,8 +1835,7 @@ ModuleExport size_t RegisterJPEGImage(void) (void) RegisterMagickInfo(entry); return(MagickImageCoderSignature); } - - + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @@ -2355,6 +2350,14 @@ static char **SamplingFactorToList(const char *text) return(textlist); } +static inline void JPEGSetSample(const struct jpeg_compress_struct *jpeg_info, + const unsigned int scale,const Quantum pixel,JSAMPLE *q) +{ + if (jpeg_info->data_precision > 8) + (*(unsigned short *) q)=(ScaleQuantumToShort(pixel)/scale); + *q=(ScaleQuantumToChar(pixel)/scale); +} + static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, Image *myImage,struct jpeg_compress_struct *jpeg_info, ExceptionInfo *exception) @@ -2384,11 +2387,12 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, JPEGClientInfo *client_info = (JPEGClientInfo *) NULL; - JSAMPLE - *volatile jpeg_pixels; + JDIMENSION + number_scanlines = 0; - JSAMPROW - scanline[1]; + JSAMPLE + *volatile jpeg_pixels, + *q; MagickBooleanType status; @@ -2396,17 +2400,15 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, MemoryInfo *memory_info; - JSAMPLE - *q; - ssize_t + bytes_per_pixel, i, y; struct jpeg_error_mgr jpeg_error; - unsigned short + unsigned int scale; /* @@ -2471,6 +2473,15 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, jpeg_info->image_height=(unsigned int) image->rows; jpeg_info->input_components=3; jpeg_info->data_precision=8; +#if defined(C_LOSSLESS_SUPPORTED) + if (image_info->compression == LosslessJPEGCompression) + { + if (image->depth > 8) + jpeg_info->data_precision=12; + if (image->depth > 12) + jpeg_info->data_precision=16; + } +#endif jpeg_info->in_color_space=JCS_RGB; switch (image->colorspace) { @@ -2513,10 +2524,6 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, jpeg_set_defaults(jpeg_info); if (jpeg_info->in_color_space == JCS_CMYK) jpeg_set_colorspace(jpeg_info,JCS_YCCK); - if ((jpeg_info->data_precision != 12) && (image->depth <= 8)) - jpeg_info->data_precision=8; - else - jpeg_info->data_precision=BITS_IN_JSAMPLE; if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image resolution: %.20g,%.20g",image->resolution.x,image->resolution.y); @@ -2634,7 +2641,7 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, } else { -#if !defined(LIBJPEG_TURBO_VERSION_NUMBER) && defined(C_LOSSLESS_SUPPORTED) +#if defined(C_LOSSLESS_SUPPORTED) if (image->quality < 100) (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning, "LosslessToLossyJPEGConversion","`%s'",image->filename); @@ -2646,7 +2653,12 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, predictor=image->quality/100; /* range 1-7 */ point_transform=image->quality % 20; /* range 0-15 */ +#if defined(MAGICKCORE_HAVE_JPEG_SIMPLE_LOSSLESS) jpeg_simple_lossless(jpeg_info,predictor,point_transform); +#endif +#if defined(MAGICKCORE_HAVE_JPEG_ENABLE_LOSSLESS) + jpeg_enable_lossless(jpeg_info,predictor,point_transform); +#endif if (image->debug != MagickFalse) { (void) LogMagickEvent(CoderEvent,GetMagickModule(), @@ -2961,8 +2973,9 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, /* Convert MIFF to JPEG raster pixels. */ + bytes_per_pixel=(jpeg_info->data_precision+7)/8; memory_info=AcquireVirtualMemory((size_t) image->columns, - (size_t) (jpeg_info->input_components*(ssize_t) sizeof(*jpeg_pixels))); + (size_t) (jpeg_info->input_components*bytes_per_pixel)); if (memory_info == (MemoryInfo *) NULL) ThrowJPEGWriterException(ResourceLimitError,"MemoryAllocationFailed"); jpeg_pixels=(JSAMPLE *) GetVirtualMemoryBlob(memory_info); @@ -2977,102 +2990,65 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, jps_image=DestroyImage(jps_image); return(MagickFalse); } - scanline[0]=(JSAMPROW) jpeg_pixels; scale=0; if (GetQuantumRange((size_t) jpeg_info->data_precision) != 0) scale=65535/(unsigned short) GetQuantumRange((size_t) jpeg_info->data_precision); if (scale == 0) scale=1; - if (jpeg_info->data_precision <= 8) + if ((jpeg_info->in_color_space == JCS_RGB) || + (jpeg_info->in_color_space == JCS_YCbCr)) + for (y=0; y < (ssize_t) image->rows; y++) { - if ((jpeg_info->in_color_space == JCS_RGB) || - (jpeg_info->in_color_space == JCS_YCbCr)) - for (y=0; y < (ssize_t) image->rows; y++) + const Quantum + *p; + + ssize_t + x; + + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + q=jpeg_pixels; + for (x=0; x < (ssize_t) image->columns; x++) + { + JPEGSetSample(jpeg_info,scale,GetPixelRed(image,p),q); + q+=bytes_per_pixel; + JPEGSetSample(jpeg_info,scale,GetPixelGreen(image,p),q); + q+=bytes_per_pixel; + JPEGSetSample(jpeg_info,scale,GetPixelBlue(image,p),q); + q+=bytes_per_pixel; + p+=GetPixelChannels(image); + } + switch (jpeg_info->data_precision) + { + case 16: { - const Quantum - *p; - - ssize_t - x; - - p=GetVirtualPixels(image,0,y,image->columns,1,exception); - if (p == (const Quantum *) NULL) - break; - q=jpeg_pixels; - for (x=0; x < (ssize_t) image->columns; x++) - { - *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); - status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) - break; +#if defined(MAGICKCORE_HAVE_JPEG16_WRITE_SCANLINES) + number_scanlines=jpeg16_write_scanlines(jpeg_info,(J16SAMPROW *) + &jpeg_pixels,1); + break; +#endif } - else - if (jpeg_info->in_color_space == JCS_GRAYSCALE) - for (y=0; y < (ssize_t) image->rows; y++) - { - const Quantum - *p; - - ssize_t - x; - - p=GetVirtualPixels(image,0,y,image->columns,1,exception); - if (p == (const Quantum *) NULL) - break; - q=jpeg_pixels; - for (x=0; x < (ssize_t) image->columns; x++) - { - *q++=(JSAMPLE) ScaleQuantumToChar(ClampToQuantum(GetPixelLuma( - image,p))); - p+=GetPixelChannels(image); - } - (void) jpeg_write_scanlines(jpeg_info,scanline,1); - status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) - break; - } - else - for (y=0; y < (ssize_t) image->rows; y++) - { - const Quantum - *p; - - ssize_t - x; - - p=GetVirtualPixels(image,0,y,image->columns,1,exception); - if (p == (const Quantum *) NULL) - break; - q=jpeg_pixels; - for (x=0; x < (ssize_t) image->columns; x++) - { - /* - Convert DirectClass packets to contiguous CMYK scanlines. - */ - *q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange- - GetPixelCyan(image,p)))); - *q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange- - GetPixelMagenta(image,p)))); - *q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange- - GetPixelYellow(image,p)))); - *q++=(JSAMPLE) (ScaleQuantumToChar((Quantum) (QuantumRange- - GetPixelBlack(image,p)))); - p+=GetPixelChannels(image); - } - (void) jpeg_write_scanlines(jpeg_info,scanline,1); - status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) - break; - } + case 12: + { +#if defined(MAGICKCORE_HAVE_JPEG12_WRITE_SCANLINES) + number_scanlines=jpeg12_write_scanlines(jpeg_info,(J12SAMPROW *) + &jpeg_pixels,1); + break; +#endif + } + default: + { + number_scanlines=jpeg_write_scanlines(jpeg_info,(JSAMPROW *) + &jpeg_pixels,1); + break; + } + } + status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, + image->rows); + if (status == MagickFalse) + break; } else if (jpeg_info->in_color_space == JCS_GRAYSCALE) @@ -3090,79 +3066,104 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info, q=jpeg_pixels; for (x=0; x < (ssize_t) image->columns; x++) { - *q++=(JSAMPLE) (ScaleQuantumToShort(ClampToQuantum(GetPixelLuma(image, - p)))/scale); + JPEGSetSample(jpeg_info,scale,ClampToQuantum(GetPixelLuma(image,p)), + q); + q+=bytes_per_pixel; p+=GetPixelChannels(image); } - (void) jpeg_write_scanlines(jpeg_info,scanline,1); + switch (jpeg_info->data_precision) + { + case 16: + { +#if defined(MAGICKCORE_HAVE_JPEG16_WRITE_SCANLINES) + number_scanlines=jpeg16_write_scanlines(jpeg_info,(J16SAMPROW *) + &jpeg_pixels,1); + break; +#endif + } + case 12: + { +#if defined(MAGICKCORE_HAVE_JPEG12_WRITE_SCANLINES) + number_scanlines=jpeg12_write_scanlines(jpeg_info,(J12SAMPROW *) + &jpeg_pixels,1); + break; +#endif + } + default: + { + number_scanlines=jpeg_write_scanlines(jpeg_info,(JSAMPROW *) + &jpeg_pixels,1); + break; + } + } 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 < (ssize_t) image->rows; y++) + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum + *p; + + ssize_t + x; + + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + q=jpeg_pixels; + for (x=0; x < (ssize_t) image->columns; x++) { - const Quantum - *p; - - ssize_t - x; - - p=GetVirtualPixels(image,0,y,image->columns,1,exception); - if (p == (const Quantum *) NULL) - break; - q=jpeg_pixels; - for (x=0; x < (ssize_t) image->columns; x++) - { - *q++=(JSAMPLE) (ScaleQuantumToShort(GetPixelRed(image,p))/scale); - *q++=(JSAMPLE) (ScaleQuantumToShort(GetPixelGreen(image,p))/scale); - *q++=(JSAMPLE) (ScaleQuantumToShort(GetPixelBlue(image,p))/scale); - p+=GetPixelChannels(image); - } - (void) jpeg_write_scanlines(jpeg_info,scanline,1); - status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) - break; + /* + Convert DirectClass packets to contiguous CMYK scanlines. + */ + JPEGSetSample(jpeg_info,scale,(Quantum) ((QuantumRange- + GetPixelCyan(image,p))),q); + q+=bytes_per_pixel; + JPEGSetSample(jpeg_info,scale,(Quantum) ((QuantumRange- + GetPixelMagenta(image,p))),q); + q+=bytes_per_pixel; + JPEGSetSample(jpeg_info,scale,(Quantum) ((QuantumRange- + GetPixelYellow(image,p))),q); + q+=bytes_per_pixel; + JPEGSetSample(jpeg_info,scale,(Quantum) ((QuantumRange- + GetPixelBlack(image,p))),q); + q+=bytes_per_pixel; + p+=GetPixelChannels(image); } - else - for (y=0; y < (ssize_t) image->rows; y++) + switch (jpeg_info->data_precision) { - const Quantum - *p; - - ssize_t - x; - - p=GetVirtualPixels(image,0,y,image->columns,1,exception); - if (p == (const Quantum *) NULL) - break; - q=jpeg_pixels; - for (x=0; x < (ssize_t) image->columns; x++) + case 16: { - /* - Convert DirectClass packets to contiguous CMYK scanlines. - */ - *q++=(JSAMPLE) (ScaleQuantumToShort(QuantumRange-GetPixelRed( - image,p))/scale); - *q++=(JSAMPLE) (ScaleQuantumToShort(QuantumRange-GetPixelGreen( - image,p))/scale); - *q++=(JSAMPLE) (ScaleQuantumToShort(QuantumRange-GetPixelBlue( - image,p))/scale); - *q++=(JSAMPLE) (ScaleQuantumToShort(QuantumRange-GetPixelBlack( - image,p))/scale); - p+=GetPixelChannels(image); - } - (void) jpeg_write_scanlines(jpeg_info,scanline,1); - status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) +#if defined(MAGICKCORE_HAVE_JPEG16_WRITE_SCANLINES) + number_scanlines=jpeg16_write_scanlines(jpeg_info,(J16SAMPROW *) + &jpeg_pixels,1); break; +#endif + } + case 12: + { +#if defined(MAGICKCORE_HAVE_JPEG12_WRITE_SCANLINES) + number_scanlines=jpeg12_write_scanlines(jpeg_info,(J12SAMPROW *) + &jpeg_pixels,1); + break; +#endif + } + default: + { + number_scanlines=jpeg_write_scanlines(jpeg_info,(JSAMPROW *) + &jpeg_pixels,1); + break; + } } - if (y == (ssize_t) image->rows) + status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, + image->rows); + if (status == MagickFalse) + break; + } + if ((number_scanlines != 1) || (y == (ssize_t) image->rows)) jpeg_finish_compress(jpeg_info); /* Relinquish resources. diff --git a/config/config.h.in b/config/config.h.in index 75e798a70e..cfc2bd3f72 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -263,6 +263,24 @@ /* Define if you have jemalloc memory allocation library */ #undef HAVE_JEMALLOC +/* Define to 1 if you have the `jpeg12_read_scanlines' function. */ +#undef HAVE_JPEG12_READ_SCANLINES + +/* Define to 1 if you have the `jpeg12_write_scanlines' function. */ +#undef HAVE_JPEG12_WRITE_SCANLINES + +/* Define to 1 if you have the `jpeg16_read_scanlines' function. */ +#undef HAVE_JPEG16_READ_SCANLINES + +/* Define to 1 if you have the `jpeg16_write_scanlines' function. */ +#undef HAVE_JPEG16_WRITE_SCANLINES + +/* Define to 1 if you have the `jpeg_enable_lossless' function. */ +#undef HAVE_JPEG_ENABLE_LOSSLESS + +/* Define to 1 if you have the `jpeg_simple_lossless' function. */ +#undef HAVE_JPEG_SIMPLE_LOSSLESS + /* Define if you have the header file. */ #undef HAVE_LCMS2_H diff --git a/configure b/configure index 4e04cbdbff..d2fb17492b 100755 --- a/configure +++ b/configure @@ -5197,7 +5197,7 @@ MAGICK_PATCHLEVEL_VERSION=36 MAGICK_VERSION=7.1.1-36 -MAGICK_GIT_REVISION=4f6a11609:20240715 +MAGICK_GIT_REVISION=32591b858:20240720 # Substitute library versioning @@ -5231,7 +5231,7 @@ PACKAGE_LIB_VERSION=0x711 PACKAGE_LIB_VERSION_NUMBER=7,1,1,36 -PACKAGE_RELEASE_DATE=2024-07-15 +PACKAGE_RELEASE_DATE=2024-07-20 # Ensure that make can run correctly @@ -31970,6 +31970,43 @@ printf "%s\n" "#define JPEG_DELEGATE 1" >>confdefs.h printf "%s\n" "yes" >&6; } have_jpeg='yes' fi + ac_fn_c_check_func "$LINENO" "jpeg12_read_scanlines" "ac_cv_func_jpeg12_read_scanlines" +if test "x$ac_cv_func_jpeg12_read_scanlines" = xyes +then : + printf "%s\n" "#define HAVE_JPEG12_READ_SCANLINES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "jpeg12_write_scanlines" "ac_cv_func_jpeg12_write_scanlines" +if test "x$ac_cv_func_jpeg12_write_scanlines" = xyes +then : + printf "%s\n" "#define HAVE_JPEG12_WRITE_SCANLINES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "jpeg16_read_scanlines" "ac_cv_func_jpeg16_read_scanlines" +if test "x$ac_cv_func_jpeg16_read_scanlines" = xyes +then : + printf "%s\n" "#define HAVE_JPEG16_READ_SCANLINES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "jpeg16_write_scanlines" "ac_cv_func_jpeg16_write_scanlines" +if test "x$ac_cv_func_jpeg16_write_scanlines" = xyes +then : + printf "%s\n" "#define HAVE_JPEG16_WRITE_SCANLINES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "jpeg_enable_lossless" "ac_cv_func_jpeg_enable_lossless" +if test "x$ac_cv_func_jpeg_enable_lossless" = xyes +then : + printf "%s\n" "#define HAVE_JPEG_ENABLE_LOSSLESS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "jpeg_simple_lossless" "ac_cv_func_jpeg_simple_lossless" +if test "x$ac_cv_func_jpeg_simple_lossless" = xyes +then : + printf "%s\n" "#define HAVE_JPEG_SIMPLE_LOSSLESS 1" >>confdefs.h + +fi + else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } diff --git a/configure.ac b/configure.ac index fee0cd4372..0b855ed861 100644 --- a/configure.ac +++ b/configure.ac @@ -2476,6 +2476,7 @@ if test "$with_jpeg" != 'no'; then AC_MSG_RESULT([yes]) have_jpeg='yes' fi + AC_CHECK_FUNCS([jpeg12_read_scanlines jpeg12_write_scanlines jpeg16_read_scanlines jpeg16_write_scanlines jpeg_enable_lossless jpeg_simple_lossless]) else AC_MSG_RESULT([no]) fi