From 1a95b2df898d21ae8e8a7db6bc868171bfafc07c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 25 May 2018 16:02:25 +0100 Subject: [PATCH] fix tga header read When you ping() an image with imagemagick to get the header, some format loaders (eg. TGA) don't set all the fields. In this case, image->colormap was not set and that made GetImageChannelDepth() crash. Work around this, at least in this case, by allocating a colourmap ourselves if none is set. see https://github.com/jcupitt/libvips/issues/980 --- configure.ac | 11 +++++++++++ libvips/foreign/magick.c | 16 ++++++++++++++++ libvips/foreign/magick.h | 1 + libvips/foreign/magick2vips.c | 11 +++++++++++ 4 files changed, 39 insertions(+) diff --git a/configure.ac b/configure.ac index bfdeb908..d2306a4c 100644 --- a/configure.ac +++ b/configure.ac @@ -704,6 +704,17 @@ if test x"$magick6" = x"yes"; then LIBS="$save_LIBS" fi +if test x"$magick6" = x"yes"; then + # more recent magick6s have AcquireImageColormap rather than + # AllocateImageColormap groan + save_LIBS="$LIBS" + LIBS="$LIBS $MAGICK_LIBS" + AC_CHECK_FUNCS(AcquireImageColormap, + AC_DEFINE(HAVE_ACQUIREIMAGECOLORMAP,1, + [define if your magick has AcquireImageColormap.])) + LIBS="$save_LIBS" +fi + if test x"$magick6" = x"yes"; then # more recent magick6s have SetImageExtent save_LIBS="$LIBS" diff --git a/libvips/foreign/magick.c b/libvips/foreign/magick.c index 6e3fe4ac..04b3d24b 100644 --- a/libvips/foreign/magick.c +++ b/libvips/foreign/magick.c @@ -52,6 +52,12 @@ magick_acquire_image( const ImageInfo *image_info, ExceptionInfo *exception ) return( AcquireImage( image_info, exception ) ); } +void +magick_acquire_image_colormap( Image *image, int colors ) +{ + AcquireImageColormap( image, colors ) +} + void magick_acquire_next_image( const ImageInfo *image_info, Image *image, ExceptionInfo *exception ) @@ -107,6 +113,16 @@ magick_acquire_image( const ImageInfo *image_info, ExceptionInfo *exception ) #endif } +void +magick_acquire_image_colormap( Image *image, int colors ) +{ +#ifdef HAVE_ACQUIREIMAGECOLORMAP + AcquireImageColormap( image, colors ); +#else /*!HAVE_ACQUIREIMAGECOLORMAP*/ + AllocateImageColormap( image, colors ); +#endif /*HAVE_ACQUIREIMAGECOLORMAP*/ +} + void magick_acquire_next_image( const ImageInfo *image_info, Image *image, ExceptionInfo *exception ) diff --git a/libvips/foreign/magick.h b/libvips/foreign/magick.h index 1d7539f5..241f6d5f 100644 --- a/libvips/foreign/magick.h +++ b/libvips/foreign/magick.h @@ -44,6 +44,7 @@ Image *magick_acquire_image( const ImageInfo *image_info, ExceptionInfo *exception ); +void magick_acquire_image_colormap( Image *image, int colors ); void magick_acquire_next_image( const ImageInfo *image_info, Image *image, ExceptionInfo *exception ); int magick_set_image_size( Image *image, diff --git a/libvips/foreign/magick2vips.c b/libvips/foreign/magick2vips.c index 74497a48..0aba999c 100644 --- a/libvips/foreign/magick2vips.c +++ b/libvips/foreign/magick2vips.c @@ -57,6 +57,8 @@ * - try using GetImageChannelDepth() instead of ->depth * 24/4/18 * - add format hint + * 25/5/18 + * - acquire an image colormap if none set */ /* @@ -327,6 +329,15 @@ parse_header( Read *read ) if( (im->Bands = get_bands( image )) < 0 ) return( -1 ); + /* Some ImageMagick loaders (eg. TGA) fail to set the ->colormap + * field on Ping. GetImageChannelDepth() needs this and + * will crash if it's not set. + * + * If there's no colormap, set an empty one. + */ + if( !image->colormap ) + magick_acquire_image_colormap( image, image->colors ); + /* Depth can be 'fractional'. * * You'd think we should use