X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a974cdce9b9121158e623a3fab6ad731ff5d48ec..44b0225ed09cfbc6cee7ed53c630988c342df806:/src/image.c diff --git a/src/image.c b/src/image.c index d0d28bea58..f4def3e681 100644 --- a/src/image.c +++ b/src/image.c @@ -1,5 +1,5 @@ /* Functions for image support on window system. - Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc. + Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -56,7 +56,7 @@ along with GNU Emacs. If not, see . */ #define COLOR_TABLE_SUPPORT 1 typedef struct x_bitmap_record Bitmap_Record; -#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y) +#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) #define NO_PIXMAP None #define RGB_PIXEL_COLOR unsigned long @@ -74,7 +74,7 @@ typedef struct x_bitmap_record Bitmap_Record; #undef COLOR_TABLE_SUPPORT typedef struct w32_bitmap_record Bitmap_Record; -#define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y) +#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y) #define NO_PIXMAP 0 #define RGB_PIXEL_COLOR COLORREF @@ -106,7 +106,7 @@ Lisp_Object Qlibpng_version; typedef struct ns_bitmap_record Bitmap_Record; -#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y) +#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) #define NO_PIXMAP 0 #define RGB_PIXEL_COLOR unsigned long @@ -115,7 +115,7 @@ typedef struct ns_bitmap_record Bitmap_Record; #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 -#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual +#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO (f)->visual #define x_defined_color(f, name, color_def, alloc) \ ns_defined_color (f, name, color_def, alloc, 0) #define FRAME_X_SCREEN(f) 0 @@ -196,7 +196,8 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id) int x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) { - return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; + /* HAVE_NTGUI needs the explicit cast here. */ + return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; } #endif @@ -691,7 +692,7 @@ enum image_value_type IMAGE_STRING_OR_NIL_VALUE, IMAGE_SYMBOL_VALUE, IMAGE_POSITIVE_INTEGER_VALUE, - IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, + IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, IMAGE_NON_NEGATIVE_INTEGER_VALUE, IMAGE_ASCENT_VALUE, IMAGE_INTEGER_VALUE, @@ -798,12 +799,12 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, return 0; break; - case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR: - if (RANGED_INTEGERP (1, value, INT_MAX)) + case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR: + if (RANGED_INTEGERP (0, value, INT_MAX)) break; if (CONSP (value) - && RANGED_INTEGERP (1, XCAR (value), INT_MAX) - && RANGED_INTEGERP (1, XCDR (value), INT_MAX)) + && RANGED_INTEGERP (0, XCAR (value), INT_MAX) + && RANGED_INTEGERP (0, XCDR (value), INT_MAX)) break; return 0; @@ -1105,8 +1106,8 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice) because a typical font is `top-heavy' (due to the presence uppercase letters), so the image placement should err towards being top-heavy too. It also just generally looks better. */ - ascent = (height + FONT_BASE(face->font) - - FONT_DESCENT(face->font) + 1) / 2; + ascent = (height + FONT_BASE (face->font) + - FONT_DESCENT (face->font) + 1) / 2; #endif /* HAVE_NTGUI */ } else @@ -2014,7 +2015,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, /* Bitmaps with a depth less than 16 need a palette. */ /* BITMAPINFO structure already contains the first RGBQUAD. */ if (depth < 16) - palette_colors = 1 << depth - 1; + palette_colors = 1 << (depth - 1); *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD)); @@ -2256,7 +2257,7 @@ static const struct image_keyword xbm_format[XBM_LAST] = {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -3051,7 +3052,7 @@ static const struct image_keyword xpm_format[XPM_LAST] = {":file", IMAGE_STRING_VALUE, 0}, {":data", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -4980,7 +4981,7 @@ static const struct image_keyword pbm_format[PBM_LAST] = {":file", IMAGE_STRING_VALUE, 0}, {":data", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -5395,7 +5396,7 @@ static const struct image_keyword png_format[PNG_LAST] = {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -5544,7 +5545,7 @@ init_png_functions (Lisp_Object libraries) /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */ #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1)) #define PNG_JMPBUF(ptr) \ - (*fn_png_set_longjmp_fn((ptr), longjmp, sizeof (jmp_buf))) + (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf))) #endif /* Error and warning handlers installed when the PNG library @@ -5965,9 +5966,9 @@ png_load (struct frame *f, struct image *img) static int png_load (struct frame *f, struct image *img) { - return ns_load_image(f, img, - image_spec_value (img->spec, QCfile, NULL), - image_spec_value (img->spec, QCdata, NULL)); + return ns_load_image (f, img, + image_spec_value (img->spec, QCfile, NULL), + image_spec_value (img->spec, QCdata, NULL)); } #endif /* HAVE_NS */ @@ -6015,7 +6016,7 @@ static const struct image_keyword jpeg_format[JPEG_LAST] = {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -6114,7 +6115,7 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired) #else -#define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a) +#define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress (a) #define fn_jpeg_start_decompress jpeg_start_decompress #define fn_jpeg_finish_decompress jpeg_finish_decompress #define fn_jpeg_destroy_decompress jpeg_destroy_decompress @@ -6565,7 +6566,7 @@ static const struct image_keyword tiff_format[TIFF_LAST] = {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -6744,10 +6745,20 @@ tiff_size_of_memory (thandle_t data) return ((tiff_memory_source *) data)->len; } +/* GCC 3.x on x86 Windows targets has a bug that triggers an internal + compiler error compiling tiff_handler, see Bugzilla bug #17406 + (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring + this function as external works around that problem. */ +#if defined (__MINGW32__) && __GNUC__ == 3 +# define MINGW_STATIC +#else +# define MINGW_STATIC static +#endif -static void tiff_handler (const char *, const char *, const char *, va_list) +MINGW_STATIC void +tiff_handler (const char *, const char *, const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (3, 0); -static void +MINGW_STATIC void tiff_handler (const char *log_format, const char *title, const char *format, va_list ap) { @@ -6761,6 +6772,7 @@ tiff_handler (const char *log_format, const char *title, add_to_log (log_format, build_string (title), make_string (buf, max (0, min (len, sizeof buf - 1)))); } +#undef MINGW_STATIC static void tiff_error_handler (const char *, const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (2, 0); @@ -7002,7 +7014,7 @@ static const struct image_keyword gif_format[GIF_LAST] = {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -7228,8 +7240,10 @@ gif_load (struct frame *f, struct image *img) img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top; img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left; - img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + height; - img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + width; + img->corners[BOT_CORNER] + = img->corners[TOP_CORNER] + gif->SavedImages[0].ImageDesc.Height; + img->corners[RIGHT_CORNER] + = img->corners[LEFT_CORNER] + gif->SavedImages[0].ImageDesc.Width; if (!check_image_size (f, width, height)) { @@ -7487,7 +7501,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -7538,7 +7552,7 @@ imagemagick_image_p (Lisp_Object object) } /* The GIF library also defines DrawRectangle, but its never used in Emacs. - Therefore rename the function so it doesnt collide with ImageMagick. */ + Therefore rename the function so it doesn't collide with ImageMagick. */ #define DrawRectangle DrawRectangleGif #include @@ -7550,6 +7564,22 @@ extern WandExport void PixelGetMagickColor (const PixelWand *, MagickPixelPacket *); #endif +/* Log ImageMagick error message. + Useful when a ImageMagick function returns the status `MagickFalse'. */ + +static void +imagemagick_error (MagickWand *wand) +{ + char *description; + ExceptionType severity; + + description = MagickGetException (wand, &severity); + image_error ("ImageMagick error: %s", + make_string (description, strlen (description)), + Qnil); + description = (char *) MagickRelinquishMemory (description); +} + /* Helper function for imagemagick_load, which does the actual loading given contents and size, apart from frame and image structures, passed from imagemagick_load. Uses librimagemagick to do most of @@ -7604,7 +7634,8 @@ imagemagick_load_image (struct frame *f, struct image *img, image = image_spec_value (img->spec, QCindex, NULL); ino = INTEGERP (image) ? XFASTINT (image) : 0; ping_wand = NewMagickWand (); - MagickSetResolution (ping_wand, 2, 2); + /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */ + if (filename != NULL) { status = MagickPingImage (ping_wand, filename); @@ -7614,6 +7645,13 @@ imagemagick_load_image (struct frame *f, struct image *img, status = MagickPingImageBlob (ping_wand, contents, size); } + if (status == MagickFalse) + { + imagemagick_error (ping_wand); + DestroyMagickWand (ping_wand); + return 0; + } + if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand))) { image_error ("Invalid image number `%s' in image `%s'", @@ -7622,7 +7660,7 @@ imagemagick_load_image (struct frame *f, struct image *img, return 0; } - if (MagickGetNumberImages(ping_wand) > 1) + if (MagickGetNumberImages (ping_wand) > 1) img->lisp_data = Fcons (Qcount, Fcons (make_number (MagickGetNumberImages (ping_wand)), @@ -7647,13 +7685,16 @@ imagemagick_load_image (struct frame *f, struct image *img, if (im_image == NULL) goto imagemagick_no_wand; image_wand = NewMagickWandFromImage (im_image); - DestroyImage(im_image); + DestroyImage (im_image); } else { image_wand = NewMagickWand (); if (MagickReadImageBlob (image_wand, contents, size) == MagickFalse) - goto imagemagick_error; + { + imagemagick_error (image_wand); + goto imagemagick_error; + } } /* If width and/or height is set in the display spec assume we want @@ -7681,6 +7722,7 @@ imagemagick_load_image (struct frame *f, struct image *img, if (status == MagickFalse) { image_error ("Imagemagick scale failed", Qnil, Qnil); + imagemagick_error (image_wand); goto imagemagick_error; } } @@ -7735,12 +7777,13 @@ imagemagick_load_image (struct frame *f, struct image *img, if (status == MagickFalse) { image_error ("Imagemagick image rotate failed", Qnil, Qnil); + imagemagick_error (image_wand); goto imagemagick_error; } } /* Finally we are done manipulating the image. Figure out the - resulting width/height and transfer ownerwship to Emacs. */ + resulting width/height and transfer ownership to Emacs. */ height = MagickGetImageHeight (image_wand); width = MagickGetImageWidth (image_wand); @@ -7768,11 +7811,11 @@ imagemagick_load_image (struct frame *f, struct image *img, #ifdef COLOR_TABLE_SUPPORT free_color_table (); #endif - image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); + image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil); goto imagemagick_error; } - /* Copy imagegmagick image to x with primitive yet robust pixel + /* Copy imagemagick image to x with primitive yet robust pixel pusher loop. This has been tested a lot with many different images. */ @@ -7810,7 +7853,7 @@ imagemagick_load_image (struct frame *f, struct image *img, if (imagemagick_rendermethod == 1) { - /* Magicexportimage is normaly faster than pixelpushing. This + /* Magicexportimage is normally faster than pixelpushing. This method is also well tested. Some aspects of this method are ad-hoc and needs to be more researched. */ int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/ @@ -7822,12 +7865,12 @@ imagemagick_load_image (struct frame *f, struct image *img, #ifdef COLOR_TABLE_SUPPORT free_color_table (); #endif - image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); + image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil); goto imagemagick_error; } - /* Oddly, the below code doesnt seem to work:*/ + /* Oddly, the below code doesn't seem to work:*/ /* switch(ximg->bitmap_unit){ */ /* case 8: */ /* pixelwidth=CharPixel; */ @@ -7856,7 +7899,7 @@ imagemagick_load_image (struct frame *f, struct image *img, /*&(img->pixmap));*/ ximg->data); #else - image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!", + image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!", Qnil, Qnil); #endif } @@ -7959,7 +8002,7 @@ recognize as images, such as C. See `imagemagick-types-inhibit'. */) Qimagemagicktype = intern (imtypes[i]); typelist = Fcons (Qimagemagicktype, typelist); } - return typelist; + return Fnreverse (typelist); } #endif /* defined (HAVE_IMAGEMAGICK) */ @@ -8010,7 +8053,7 @@ static const struct image_keyword svg_format[SVG_LAST] = {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -8405,7 +8448,7 @@ static const struct image_keyword gs_format[GS_LAST] = {":loader", IMAGE_FUNCTION_VALUE, 0}, {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, {":ascent", IMAGE_ASCENT_VALUE, 0}, - {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, + {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, @@ -8767,7 +8810,7 @@ syms_of_image (void) operation on GNU/Linux of calling dump-emacs after loading some images. */ image_types = NULL; - /* Must be defined now becase we're going to update it below, while + /* Must be defined now because we're going to update it below, while defining the supported image types. */ DEFVAR_LISP ("image-types", Vimage_types, doc: /* List of potentially supported image types.