diff options
Diffstat (limited to 'src/image.c')
-rw-r--r-- | src/image.c | 496 |
1 files changed, 260 insertions, 236 deletions
diff --git a/src/image.c b/src/image.c index 6a62235673a..45010e7e2bc 100644 --- a/src/image.c +++ b/src/image.c @@ -30,10 +30,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #endif #include <setjmp.h> + #include <c-ctype.h> +#include <flexmember.h> #include "lisp.h" #include "frame.h" +#include "process.h" #include "window.h" #include "buffer.h" #include "dispextern.h" @@ -56,6 +59,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ +/* Work around GCC bug 54561. */ +#if GNUC_PREREQ (4, 3, 0) +# pragma GCC diagnostic ignored "-Wclobbered" +#endif + #ifdef HAVE_X_WINDOWS typedef struct x_bitmap_record Bitmap_Record; #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) @@ -80,7 +88,6 @@ typedef struct w32_bitmap_record Bitmap_Record; #define PIX_MASK_DRAW 1 #define x_defined_color w32_defined_color -#define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits) #endif /* HAVE_NTGUI */ @@ -91,11 +98,9 @@ typedef struct ns_bitmap_record Bitmap_Record; #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 -#define PIX_MASK_DRAW 1 #define x_defined_color(f, name, color_def, alloc) \ ns_defined_color (f, name, color_def, alloc, 0) -#define DefaultDepthOfScreen(screen) x_display_list->n_planes #endif /* HAVE_NS */ #if (defined HAVE_X_WINDOWS \ @@ -216,13 +221,14 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi #ifdef HAVE_X_WINDOWS Pixmap bitmap; - bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), bits, width, height); if (! bitmap) return -1; #endif /* HAVE_X_WINDOWS */ #ifdef HAVE_NTGUI + Lisp_Object frame UNINIT; /* The value is not used. */ Pixmap bitmap; bitmap = CreateBitmap (width, height, FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, @@ -270,11 +276,11 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi ptrdiff_t x_create_bitmap_from_file (struct frame *f, Lisp_Object file) { - Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); - #ifdef HAVE_NTGUI return -1; /* W32_TODO : bitmap support */ -#endif /* HAVE_NTGUI */ +#else + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); +#endif #ifdef HAVE_NS ptrdiff_t id; @@ -322,7 +328,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file) filename = SSDATA (found); - result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), filename, &width, &height, &bitmap, &xhot, &yhot); if (result != BitmapSuccess) return -1; @@ -788,7 +794,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, case IMAGE_FUNCTION_VALUE: value = indirect_function (value); - if (!NILP (Ffunctionp (value))) + if (FUNCTIONP (value)) break; return 0; @@ -1091,8 +1097,8 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice) static uint32_t xcolor_to_argb32 (XColor xc) { - return (0xff << 24) | ((xc.red / 256) << 16) - | ((xc.green / 256) << 8) | (xc.blue / 256); + return ((0xffu << 24) | ((xc.red / 256) << 16) + | ((xc.green / 256) << 8) | (xc.blue / 256)); } static uint32_t @@ -1142,7 +1148,8 @@ static RGB_PIXEL_COLOR four_corners_best (XImagePtr_or_DC ximg, int *corners, unsigned long width, unsigned long height) { - RGB_PIXEL_COLOR corner_pixels[4], best IF_LINT (= 0); + RGB_PIXEL_COLOR corner_pixels[4]; + RGB_PIXEL_COLOR best UNINIT; int i, best_count; if (corners && corners[BOT_CORNER] >= 0) @@ -1946,7 +1953,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, { #ifdef HAVE_X_WINDOWS Display *display = FRAME_X_DISPLAY (f); - Window window = FRAME_X_WINDOW (f); + Drawable drawable = FRAME_X_DRAWABLE (f); Screen *screen = FRAME_X_SCREEN (f); eassert (input_blocked_p ()); @@ -1975,7 +1982,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height); /* Allocate a pixmap of the same size. */ - *pixmap = XCreatePixmap (display, window, width, height, depth); + *pixmap = XCreatePixmap (display, drawable, width, height, depth); if (*pixmap == NO_PIXMAP) { x_destroy_x_image (*ximg); @@ -2300,7 +2307,7 @@ x_find_image_fd (Lisp_Object file, int *pfd) happens, e.g., under Auto Image File Mode.) 'openp' didn't open the file, so we should, because the caller expects that. */ - fd = emacs_open (SSDATA (file_found), O_RDONLY | O_BINARY, 0); + fd = emacs_open (SSDATA (file_found), O_RDONLY, 0); } } else /* fd < 0, but not -2 */ @@ -2325,12 +2332,12 @@ x_find_image_file (Lisp_Object file) occurred. FD is a file descriptor open for reading FILE. Set *SIZE to the size of the file. */ -static unsigned char * +static char * slurp_file (int fd, ptrdiff_t *size) { FILE *fp = fdopen (fd, "rb"); - unsigned char *buf = NULL; + char *buf = NULL; struct stat st; if (fp) @@ -2517,7 +2524,7 @@ xbm_image_p (Lisp_Object object) if (STRINGP (elt)) { if (SCHARS (elt) - < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR) + < (width + CHAR_BIT - 1) / CHAR_BIT) return 0; } else if (BOOL_VECTOR_P (elt)) @@ -2532,7 +2539,7 @@ xbm_image_p (Lisp_Object object) else if (STRINGP (data)) { if (SCHARS (data) - < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height) + < (width + CHAR_BIT - 1) / CHAR_BIT * height) return 0; } else if (BOOL_VECTOR_P (data)) @@ -2555,9 +2562,9 @@ xbm_image_p (Lisp_Object object) scanning a number, store its value in *IVAL. */ static int -xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) +xbm_scan (char **s, char *end, char *sval, int *ival) { - unsigned int c; + unsigned char c; loop: @@ -2609,7 +2616,7 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) if (*s < end) *s = *s - 1; *ival = value; - c = XBM_TK_NUMBER; + return XBM_TK_NUMBER; } else if (c_isalpha (c) || c == '_') { @@ -2620,7 +2627,7 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) *sval = 0; if (*s < end) *s = *s - 1; - c = XBM_TK_IDENT; + return XBM_TK_IDENT; } else if (c == '/' && **s == '*') { @@ -2736,7 +2743,7 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data, img->pixmap = (x_check_image_size (0, img->width, img->height) ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f), - FRAME_X_WINDOW (f), + FRAME_X_DRAWABLE (f), data, img->width, img->height, fg, bg, @@ -2757,11 +2764,11 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data, bitmap remains unread). */ static bool -xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end, +xbm_read_bitmap_data (struct frame *f, char *contents, char *end, int *width, int *height, char **data, bool inhibit_image_error) { - unsigned char *s = contents; + char *s = contents; char buffer[BUFSIZ]; bool padding_p = 0; bool v10 = 0; @@ -2918,8 +2925,7 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e successful. */ static bool -xbm_load_image (struct frame *f, struct image *img, unsigned char *contents, - unsigned char *end) +xbm_load_image (struct frame *f, struct image *img, char *contents, char *end) { bool rc; char *data; @@ -2979,8 +2985,8 @@ xbm_file_p (Lisp_Object data) { int w, h; return (STRINGP (data) - && xbm_read_bitmap_data (NULL, SDATA (data), - (SDATA (data) + SBYTES (data)), + && xbm_read_bitmap_data (NULL, SSDATA (data), + SSDATA (data) + SBYTES (data), &w, &h, NULL, 1)); } @@ -3009,7 +3015,7 @@ xbm_load (struct frame *f, struct image *img) } ptrdiff_t size; - unsigned char *contents = slurp_file (fd, &size); + char *contents = slurp_file (fd, &size); if (contents == NULL) { image_error ("Error loading XBM image `%s'", file); @@ -3070,9 +3076,8 @@ xbm_load (struct frame *f, struct image *img) } if (in_memory_file_p) - success_p = xbm_load_image (f, img, SDATA (data), - (SDATA (data) - + SBYTES (data))); + success_p = xbm_load_image (f, img, SSDATA (data), + SSDATA (data) + SBYTES (data)); else { USE_SAFE_ALLOCA; @@ -3081,7 +3086,7 @@ xbm_load (struct frame *f, struct image *img) { int i; char *p; - int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; + int nbytes = (img->width + CHAR_BIT - 1) / CHAR_BIT; SAFE_NALLOCA (bits, nbytes, img->height); p = bits; @@ -3105,7 +3110,7 @@ xbm_load (struct frame *f, struct image *img) int nbytes, i; /* Windows mono bitmaps are reversed compared with X. */ invertedBits = bits; - nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; + nbytes = (img->width + CHAR_BIT - 1) / CHAR_BIT; SAFE_NALLOCA (bits, nbytes, img->height); for (i = 0; i < nbytes; i++) bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]); @@ -3158,16 +3163,18 @@ static bool xpm_load (struct frame *f, struct image *img); #define XColor xpm_XColor #define XImage xpm_XImage #define Display xpm_Display -#define PIXEL_ALREADY_TYPEDEFED +#ifdef CYGWIN +#include "noX/xpm.h" +#else /* not CYGWIN */ #include "X11/xpm.h" +#endif /* not CYGWIN */ #undef FOR_MSW #undef XColor #undef XImage #undef Display -#undef PIXEL_ALREADY_TYPEDEFED -#else +#else /* not HAVE_NTGUI */ #include "X11/xpm.h" -#endif /* HAVE_NTGUI */ +#endif /* not HAVE_NTGUI */ #endif /* HAVE_XPM */ #if defined (HAVE_XPM) || defined (HAVE_NS) @@ -3339,7 +3346,7 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket) if (bucket < 0) bucket = xpm_color_bucket (color_name); - nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1; + nbytes = FLEXSIZEOF (struct xpm_cached_color, name, strlen (color_name) + 1); p = xmalloc (nbytes); strcpy (p->name, color_name); p->color = *color; @@ -3514,7 +3521,7 @@ x_create_bitmap_from_xpm_data (struct frame *f, const char **bits) xpm_init_color_cache (f, &attrs); #endif - rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), (char **) bits, &bitmap, &mask, &attrs); if (rc != XpmSuccess) { @@ -3677,7 +3684,7 @@ xpm_load (struct frame *f, struct image *img) #endif /* XpmReadFileToPixmap is not available in the Windows port of libxpm. But XpmReadFileToImage almost does what we want. */ - rc = XpmReadFileToImage (&hdc, SDATA (file), + rc = XpmReadFileToImage (&hdc, SSDATA (file), &xpm_image, &xpm_mask, &attrs); #else @@ -3701,7 +3708,7 @@ xpm_load (struct frame *f, struct image *img) #ifdef HAVE_NTGUI /* XpmCreatePixmapFromBuffer is not available in the Windows port of libxpm. But XpmCreateImageFromBuffer almost does what we want. */ - rc = XpmCreateImageFromBuffer (&hdc, SDATA (buffer), + rc = XpmCreateImageFromBuffer (&hdc, SSDATA (buffer), &xpm_image, &xpm_mask, &attrs); #else @@ -3720,10 +3727,10 @@ xpm_load (struct frame *f, struct image *img) { int width = img->ximg->width; int height = img->ximg->height; - unsigned char *data = (unsigned char *) xmalloc (width*height*4); + void *data = xmalloc (width * height * 4); int i; - uint32_t *od = (uint32_t *)data; - uint32_t *id = (uint32_t *)img->ximg->data; + uint32_t *od = data; + uint32_t *id = (uint32_t *) img->ximg->data; char *mid = img->mask_img ? img->mask_img->data : 0; uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f); @@ -3752,7 +3759,7 @@ xpm_load (struct frame *f, struct image *img) #ifdef HAVE_X_WINDOWS if (rc == XpmSuccess) { - img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), img->ximg->width, img->ximg->height, img->ximg->depth); if (img->pixmap == NO_PIXMAP) @@ -3762,7 +3769,7 @@ xpm_load (struct frame *f, struct image *img) } else if (img->mask_img) { - img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), img->mask_img->width, img->mask_img->height, img->mask_img->depth); @@ -3884,14 +3891,12 @@ xpm_load (struct frame *f, struct image *img) /* XPM support functions for NS where libxpm is not available. Only XPM version 3 (without any extensions) is supported. */ -static void xpm_put_color_table_v (Lisp_Object, const unsigned char *, +static void xpm_put_color_table_v (Lisp_Object, const char *, int, Lisp_Object); -static Lisp_Object xpm_get_color_table_v (Lisp_Object, - const unsigned char *, int); -static void xpm_put_color_table_h (Lisp_Object, const unsigned char *, +static Lisp_Object xpm_get_color_table_v (Lisp_Object, const char *, int); +static void xpm_put_color_table_h (Lisp_Object, const char *, int, Lisp_Object); -static Lisp_Object xpm_get_color_table_h (Lisp_Object, - const unsigned char *, int); +static Lisp_Object xpm_get_color_table_h (Lisp_Object, const char *, int); /* Tokens returned from xpm_scan. */ @@ -3910,12 +3915,9 @@ enum xpm_token length of the corresponding token, respectively. */ static int -xpm_scan (const unsigned char **s, - const unsigned char *end, - const unsigned char **beg, - ptrdiff_t *len) +xpm_scan (const char **s, const char *end, const char **beg, ptrdiff_t *len) { - int c; + unsigned char c; while (*s < end) { @@ -3978,12 +3980,9 @@ xpm_scan (const unsigned char **s, hash table is used. */ static Lisp_Object -xpm_make_color_table_v (void (**put_func) (Lisp_Object, - const unsigned char *, - int, +xpm_make_color_table_v (void (**put_func) (Lisp_Object, const char *, int, Lisp_Object), - Lisp_Object (**get_func) (Lisp_Object, - const unsigned char *, + Lisp_Object (**get_func) (Lisp_Object, const char *, int)) { *put_func = xpm_put_color_table_v; @@ -3993,28 +3992,27 @@ xpm_make_color_table_v (void (**put_func) (Lisp_Object, static void xpm_put_color_table_v (Lisp_Object color_table, - const unsigned char *chars_start, + const char *chars_start, int chars_len, Lisp_Object color) { - ASET (color_table, *chars_start, color); + unsigned char uc = *chars_start; + ASET (color_table, uc, color); } static Lisp_Object xpm_get_color_table_v (Lisp_Object color_table, - const unsigned char *chars_start, + const char *chars_start, int chars_len) { - return AREF (color_table, *chars_start); + unsigned char uc = *chars_start; + return AREF (color_table, uc); } static Lisp_Object -xpm_make_color_table_h (void (**put_func) (Lisp_Object, - const unsigned char *, - int, +xpm_make_color_table_h (void (**put_func) (Lisp_Object, const char *, int, Lisp_Object), - Lisp_Object (**get_func) (Lisp_Object, - const unsigned char *, + Lisp_Object (**get_func) (Lisp_Object, const char *, int)) { *put_func = xpm_put_color_table_h; @@ -4027,7 +4025,7 @@ xpm_make_color_table_h (void (**put_func) (Lisp_Object, static void xpm_put_color_table_h (Lisp_Object color_table, - const unsigned char *chars_start, + const char *chars_start, int chars_len, Lisp_Object color) { @@ -4041,7 +4039,7 @@ xpm_put_color_table_h (Lisp_Object color_table, static Lisp_Object xpm_get_color_table_h (Lisp_Object color_table, - const unsigned char *chars_start, + const char *chars_start, int chars_len) { struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); @@ -4075,20 +4073,22 @@ xpm_str_to_color_key (const char *s) static bool xpm_load_image (struct frame *f, struct image *img, - const unsigned char *contents, - const unsigned char *end) + const char *contents, + const char *end) { - const unsigned char *s = contents, *beg, *str; - unsigned char buffer[BUFSIZ]; + const char *s = contents, *beg, *str; + char buffer[BUFSIZ]; int width, height, x, y; int num_colors, chars_per_pixel; ptrdiff_t len; int LA1; - void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object); - Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int); + void (*put_color_table) (Lisp_Object, const char *, int, Lisp_Object); + Lisp_Object (*get_color_table) (Lisp_Object, const char *, int); Lisp_Object frame, color_symbols, color_table; int best_key; +#ifndef HAVE_NS bool have_mask = false; +#endif XImagePtr ximg = NULL, mask_img = NULL; #define match() \ @@ -4327,7 +4327,7 @@ xpm_load (struct frame *f, } ptrdiff_t size; - unsigned char *contents = slurp_file (fd, &size); + char *contents = slurp_file (fd, &size); if (contents == NULL) { image_error ("Error loading XPM image `%s'", file); @@ -4347,8 +4347,8 @@ xpm_load (struct frame *f, image_error ("Invalid image data `%s'", data); return 0; } - success_p = xpm_load_image (f, img, SDATA (data), - SDATA (data) + SBYTES (data)); + success_p = xpm_load_image (f, img, SSDATA (data), + SSDATA (data) + SBYTES (data)); } return success_p; @@ -5041,13 +5041,13 @@ static void x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) { XImagePtr_or_DC ximg; -#ifndef HAVE_NTGUI - XImagePtr mask_img; -#else +#ifdef HAVE_NTGUI HGDIOBJ prev; char *mask_img; int row_width; -#endif /* HAVE_NTGUI */ +#elif !defined HAVE_NS + XImagePtr mask_img; +#endif int x, y; bool use_img_background; unsigned long bg = 0; @@ -5222,20 +5222,22 @@ pbm_image_p (Lisp_Object object) end of input. */ static int -pbm_next_char (unsigned char **s, unsigned char *end) +pbm_next_char (char **s, char *end) { - int c = -1; - - while (*s < end && (c = *(*s)++, c == '#')) + while (*s < end) { - /* Skip to the next line break. */ - while (*s < end && (c = *(*s)++, c != '\n' && c != '\r')) - ; - - c = -1; + unsigned char c = *(*s)++; + if (c != '#') + return c; + while (*s < end) + { + c = *(*s)++; + if (c == '\n' || c == '\r') + break; + } } - return c; + return -1; } @@ -5244,7 +5246,7 @@ pbm_next_char (unsigned char **s, unsigned char *end) end of input. */ static int -pbm_scan_number (unsigned char **s, unsigned char *end) +pbm_scan_number (char **s, char *end) { int c = 0, val = -1; @@ -5274,12 +5276,9 @@ pbm_load (struct frame *f, struct image *img) int width, height, max_color_idx = 0; Lisp_Object specified_file; enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; - unsigned char *contents = NULL; - unsigned char *end, *p; -#ifdef USE_CAIRO - unsigned char *data = 0; - uint32_t *dataptr; -#else + char *contents = NULL; + char *end, *p; +#ifndef USE_CAIRO XImagePtr ximg; #endif @@ -5315,7 +5314,7 @@ pbm_load (struct frame *f, struct image *img) image_error ("Invalid image data `%s'", data); return 0; } - p = SDATA (data); + p = SSDATA (data); end = p + SBYTES (data); } @@ -5366,8 +5365,8 @@ pbm_load (struct frame *f, struct image *img) height = pbm_scan_number (&p, end); #ifdef USE_CAIRO - data = (unsigned char *) xmalloc (width * height * 4); - dataptr = (uint32_t *) data; + void *data = xmalloc (width * height * 4); + uint32_t *dataptr = data; #endif if (type != PBM_MONO) @@ -5396,7 +5395,8 @@ pbm_load (struct frame *f, struct image *img) if (type == PBM_MONO) { - int c = 0, g; + unsigned char c = 0; + int g; struct image_keyword fmt[PBM_LAST]; unsigned long fg = FRAME_FOREGROUND_PIXEL (f); unsigned long bg = FRAME_BACKGROUND_PIXEL (f); @@ -5541,7 +5541,7 @@ pbm_load (struct frame *f, struct image *img) r = (double) r * 255 / max_color_idx; g = (double) g * 255 / max_color_idx; b = (double) b * 255 / max_color_idx; - *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b; + *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b; #else /* RGB values are now in the range 0..max_color_idx. Scale this to the range 0..0xffff supported by X. */ @@ -5894,13 +5894,12 @@ struct png_load_context static bool png_load_body (struct frame *f, struct image *img, struct png_load_context *c) { - Lisp_Object specified_file; - Lisp_Object specified_data; + Lisp_Object specified_file, specified_data; + FILE *fp = NULL; int x, y; ptrdiff_t i; png_struct *png_ptr; png_info *info_ptr = NULL, *end_info = NULL; - FILE *fp = NULL; png_byte sig[8]; png_byte *pixels = NULL; png_byte **rows = NULL; @@ -5922,7 +5921,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) /* Find out what file to load. */ specified_file = image_spec_value (img->spec, QCfile, NULL); specified_data = image_spec_value (img->spec, QCdata, NULL); - IF_LINT (Lisp_Object volatile specified_data_volatile = specified_data); if (NILP (specified_data)) { @@ -6018,10 +6016,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) return 0; } - /* Silence a bogus diagnostic; see GCC bug 54561. */ - IF_LINT (fp = c->fp); - IF_LINT (specified_data = specified_data_volatile); - /* Read image info. */ if (!NILP (specified_data)) png_set_read_fn (png_ptr, &tbr, png_read_from_memory); @@ -6671,10 +6665,8 @@ static bool jpeg_load_body (struct frame *f, struct image *img, struct my_jpeg_error_mgr *mgr) { - Lisp_Object specified_file; - Lisp_Object specified_data; - /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */ - FILE * IF_LINT (volatile) fp = NULL; + Lisp_Object specified_file, specified_data; + FILE *volatile fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; unsigned long *colors; @@ -6687,7 +6679,6 @@ jpeg_load_body (struct frame *f, struct image *img, /* Open the JPEG file. */ specified_file = image_spec_value (img->spec, QCfile, NULL); specified_data = image_spec_value (img->spec, QCdata, NULL); - IF_LINT (Lisp_Object volatile specified_data_volatile = specified_data); if (NILP (specified_data)) { @@ -6751,9 +6742,6 @@ jpeg_load_body (struct frame *f, struct image *img, return 0; } - /* Silence a bogus diagnostic; see GCC bug 54561. */ - IF_LINT (specified_data = specified_data_volatile); - /* Create the JPEG decompression object. Let it read from fp. Read the JPEG image header. */ jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo); @@ -6848,7 +6836,7 @@ jpeg_load_body (struct frame *f, struct image *img, r = mgr->cinfo.colormap[ir][i]; g = mgr->cinfo.colormap[ig][i]; b = mgr->cinfo.colormap[ib][i]; - *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b; + *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b; } } @@ -7491,7 +7479,11 @@ gif_image_p (Lisp_Object object) /* avoid conflict with QuickdrawText.h */ # define DrawText gif_DrawText # include <gif_lib.h> -# undef DrawText +/* The bogus ifdef below, which is always true, is to avoid a compiler + warning about DrawText being unused. */ +# ifdef DrawText +# undef DrawText +# endif /* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI). */ # ifndef GIFLIB_MINOR @@ -7637,14 +7629,6 @@ gif_load (struct frame *f, struct image *img) EMACS_INT idx; int gif_err; -#ifdef USE_CAIRO - unsigned char *data = 0; -#else - unsigned long pixel_colors[256]; - unsigned long bgcolor = 0; - XImagePtr ximg; -#endif - if (NILP (specified_data)) { Lisp_Object file = x_find_image_file (specified_file); @@ -7775,24 +7759,26 @@ gif_load (struct frame *f, struct image *img) #ifdef USE_CAIRO /* xzalloc so data is zero => transparent */ - data = (unsigned char *) xzalloc (width * height * 4); + void *data = xzalloc (width * height * 4); + uint32_t *data32 = data; if (STRINGP (specified_bg)) { XColor color; if (x_defined_color (f, SSDATA (specified_bg), &color, 0)) { - uint32_t *dataptr = (uint32_t *)data; + uint32_t *dataptr = data32; int r = color.red/256; int g = color.green/256; int b = color.blue/256; for (y = 0; y < height; ++y) for (x = 0; x < width; ++x) - *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b; + *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b; } } #else /* Create the X image and pixmap. */ + XImagePtr ximg; if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) { gif_close (gif, NULL); @@ -7830,6 +7816,7 @@ gif_load (struct frame *f, struct image *img) init_color_table (); #ifndef USE_CAIRO + unsigned long bgcolor; if (STRINGP (specified_bg)) bgcolor = x_alloc_image_color (f, img, specified_bg, FRAME_BACKGROUND_PIXEL (f)); @@ -7883,7 +7870,7 @@ gif_load (struct frame *f, struct image *img) #ifndef USE_CAIRO /* Allocate subimage colors. */ - memset (pixel_colors, 0, sizeof pixel_colors); + unsigned long pixel_colors[256] = { 0, }; if (gif_color_map) for (i = 0; i < gif_color_map->ColorCount; ++i) @@ -7920,14 +7907,14 @@ gif_load (struct frame *f, struct image *img) { #ifdef USE_CAIRO uint32_t *dataptr = - ((uint32_t*)data + ((row + subimg_top) * subimg_width - + x + subimg_left)); + (data32 + ((row + subimg_top) * subimg_width + + x + subimg_left)); int r = gif_color_map->Colors[c].Red; int g = gif_color_map->Colors[c].Green; int b = gif_color_map->Colors[c].Blue; if (transparency_color_index != c) - *dataptr = (0xff << 24) | (r << 16) | (g << 8) | b; + *dataptr = (0xffu << 24) | (r << 16) | (g << 8) | b; #else XPutPixel (ximg, x + subimg_left, row + subimg_top, pixel_colors[c]); @@ -7946,13 +7933,13 @@ gif_load (struct frame *f, struct image *img) { #ifdef USE_CAIRO uint32_t *dataptr = - ((uint32_t*)data + ((y + subimg_top) * subimg_width - + x + subimg_left)); + (data32 + ((y + subimg_top) * subimg_width + + x + subimg_left)); int r = gif_color_map->Colors[c].Red; int g = gif_color_map->Colors[c].Green; int b = gif_color_map->Colors[c].Blue; if (transparency_color_index != c) - *dataptr = (0xff << 24) | (r << 16) | (g << 8) | b; + *dataptr = (0xffu << 24) | (r << 16) | (g << 8) | b; #else XPutPixel (ximg, x + subimg_left, y + subimg_top, pixel_colors[c]); @@ -8077,15 +8064,25 @@ compute_image_size (size_t width, size_t height, { Lisp_Object value; int desired_width, desired_height; + double scale = 1; + + value = image_spec_value (spec, QCscale, NULL); + if (NUMBERP (value)) + scale = extract_float (value); /* If width and/or height is set in the display spec assume we want to scale to those values. If either h or w is unspecified, the unspecified should be calculated from the specified to preserve aspect ratio. */ value = image_spec_value (spec, QCwidth, NULL); - desired_width = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1; + desired_width = NATNUMP (value) ? + min (XFASTINT (value) * scale, INT_MAX) : -1; value = image_spec_value (spec, QCheight, NULL); - desired_height = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1; + desired_height = NATNUMP (value) ? + min (XFASTINT (value) * scale, INT_MAX) : -1; + + width = width * scale; + height = height * scale; if (desired_width == -1) { @@ -8136,6 +8133,13 @@ compute_image_size (size_t width, size_t height, /* h known, calculate w. */ desired_width = scale_image_size (desired_height, height, width); + /* We have no width/height settings, so just apply the scale. */ + if (desired_width == -1 && desired_height == -1) + { + desired_width = width; + desired_height = height; + } + *d_width = desired_width; *d_height = desired_height; } @@ -8315,8 +8319,8 @@ static struct animation_cache * imagemagick_create_cache (char *signature) { struct animation_cache *cache - = xmalloc (offsetof (struct animation_cache, signature) - + strlen (signature) + 1); + = xmalloc (FLEXSIZEOF (struct animation_cache, signature, + strlen (signature) + 1)); cache->wand = 0; cache->index = 0; cache->next = 0; @@ -8519,7 +8523,6 @@ imagemagick_load_image (struct frame *f, struct image *img, EMACS_INT ino; int desired_width, desired_height; double rotation; - int pixelwidth; char hint_buffer[MaxTextExtent]; char *filename_hint = NULL; @@ -8538,6 +8541,14 @@ imagemagick_load_image (struct frame *f, struct image *img, status = MagickReadImage (image_wand, filename); else { + Lisp_Object lwidth = image_spec_value (img->spec, QCwidth, NULL); + Lisp_Object lheight = image_spec_value (img->spec, QCheight, NULL); + + if (NATNUMP (lwidth) && NATNUMP (lheight)) + { + MagickSetSize (image_wand, XFASTINT (lwidth), XFASTINT (lheight)); + MagickSetDepth (image_wand, 8); + } filename_hint = imagemagick_filename_hint (img->spec, hint_buffer); MagickSetFilename (image_wand, filename_hint); status = MagickReadImageBlob (image_wand, contents, size); @@ -8550,6 +8561,18 @@ imagemagick_load_image (struct frame *f, struct image *img, return 0; } +#ifdef HAVE_MAGICKAUTOORIENTIMAGE + /* If no :rotation is explicitly specified, apply the automatic + rotation from EXIF. */ + if (NILP (image_spec_value (img->spec, QCrotation, NULL))) + if (MagickAutoOrientImage (image_wand) == MagickFalse) + { + image_error ("Error applying automatic orientation in image `%s'", img->spec); + DestroyMagickWand (image_wand); + return 0; + } +#endif + if (ino < 0 || ino >= MagickGetNumberImages (image_wand)) { image_error ("Invalid image number `%s' in image `%s'", image, img->spec); @@ -8736,7 +8759,7 @@ imagemagick_load_image (struct frame *f, struct image *img, on rgb display. seems about 3 times as fast as pixel pushing(not carefully measured) */ - pixelwidth = CharPixel; /*??? TODO figure out*/ + int pixelwidth = CharPixel; /*??? TODO figure out*/ MagickExportImagePixels (image_wand, 0, 0, width, height, exportdepth, pixelwidth, ximg->data); } @@ -8920,7 +8943,7 @@ static bool svg_image_p (Lisp_Object object); static bool svg_load (struct frame *f, struct image *img); static bool svg_load_image (struct frame *, struct image *, - unsigned char *, ptrdiff_t, char *); + char *, ptrdiff_t, char *); /* Indices of image specification fields in svg_format, below. */ @@ -9009,10 +9032,13 @@ svg_image_p (Lisp_Object object) # ifdef WINDOWSNT +/* Restore the original definition of __MINGW_MAJOR_VERSION. */ # ifdef W32_SAVE_MINGW_VERSION # undef __MINGW_MAJOR_VERSION # define __MINGW_MAJOR_VERSION W32_SAVE_MINGW_VERSION -# undef W32_SAVE_MINGW_VERSION +# ifdef __MINGW_MAJOR_VERSION +# undef W32_SAVE_MINGW_VERSION +# endif # endif /* SVG library functions. */ @@ -9112,7 +9138,9 @@ init_svg_functions (void) # define gdk_pixbuf_get_width fn_gdk_pixbuf_get_width # define g_clear_error fn_g_clear_error # define g_object_unref fn_g_object_unref -# define g_type_init fn_g_type_init +# if ! GLIB_CHECK_VERSION (2, 36, 0) +# define g_type_init fn_g_type_init +# endif # define rsvg_handle_close fn_rsvg_handle_close # define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions # define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf @@ -9145,7 +9173,7 @@ svg_load (struct frame *f, struct image *img) /* Read the entire file into memory. */ ptrdiff_t size; - unsigned char *contents = slurp_file (fd, &size); + char *contents = slurp_file (fd, &size); if (contents == NULL) { image_error ("Error loading SVG image `%s'", file); @@ -9169,7 +9197,7 @@ svg_load (struct frame *f, struct image *img) return 0; } original_filename = BVAR (current_buffer, filename); - success_p = svg_load_image (f, img, SDATA (data), SBYTES (data), + success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data), (NILP (original_filename) ? NULL : SSDATA (original_filename))); } @@ -9177,19 +9205,16 @@ svg_load (struct frame *f, struct image *img) return success_p; } -/* svg_load_image is a helper function for svg_load, which does the - actual loading given contents and size, apart from frame and image - structures, passed from svg_load. +/* Load frame F and image IMG. CONTENTS contains the SVG XML data to + be parsed, SIZE is its size, and FILENAME is the name of the SVG + file being loaded. - Uses librsvg to do most of the image processing. + Use librsvg to do most of the image processing. - Returns true when successful. */ + Return true when successful. */ static bool -svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */ - struct image *img, /* Pointer to emacs image structure. */ - unsigned char *contents, /* String containing the SVG XML data to be parsed. */ - ptrdiff_t size, /* Size of data in bytes. */ - char *filename) /* Name of SVG file being loaded. */ +svg_load_image (struct frame *f, struct image *img, char *contents, + ptrdiff_t size, char *filename) { RsvgHandle *rsvg_handle; RsvgDimensionData dimension_data; @@ -9216,7 +9241,7 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * rsvg_handle_set_base_uri(rsvg_handle, filename); /* Parse the contents argument and fill in the rsvg_handle. */ - rsvg_handle_write (rsvg_handle, contents, size, &err); + rsvg_handle_write (rsvg_handle, (unsigned char *) contents, size, &err); if (err) goto rsvg_error; /* The parsing is complete, rsvg_handle is ready to used, close it @@ -9249,8 +9274,8 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * eassert (gdk_pixbuf_get_has_alpha (pixbuf)); eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); -#ifdef USE_CAIRO { +#ifdef USE_CAIRO unsigned char *data = (unsigned char *) xmalloc (width*height*4); uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f); @@ -9276,82 +9301,77 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * create_cairo_image_surface (img, data, width, height); g_object_unref (pixbuf); - } #else - /* Try to create a x pixmap to hold the svg pixmap. */ - XImagePtr ximg; - if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) - { - g_object_unref (pixbuf); - return 0; - } + /* Try to create a x pixmap to hold the svg pixmap. */ + XImagePtr ximg; + if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) + { + g_object_unref (pixbuf); + return 0; + } - init_color_table (); + init_color_table (); - /* Handle alpha channel by combining the image with a background - color. */ - XColor background; - Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); - if (!STRINGP (specified_bg) - || !x_defined_color (f, SSDATA (specified_bg), &background, 0)) - x_query_frame_background_color (f, &background); - - /* SVG pixmaps specify transparency in the last byte, so right - shift 8 bits to get rid of it, since emacs doesn't support - transparency. */ - background.red >>= 8; - background.green >>= 8; - background.blue >>= 8; - - /* This loop handles opacity values, since Emacs assumes - non-transparent images. Each pixel must be "flattened" by - calculating the resulting color, given the transparency of the - pixel, and the image background color. */ - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { - int red; - int green; - int blue; - int opacity; - - red = *pixels++; - green = *pixels++; - blue = *pixels++; - opacity = *pixels++; - - red = ((red * opacity) - + (background.red * ((1 << 8) - opacity))); - green = ((green * opacity) - + (background.green * ((1 << 8) - opacity))); - blue = ((blue * opacity) - + (background.blue * ((1 << 8) - opacity))); - - XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue)); - } + /* Handle alpha channel by combining the image with a background + color. */ + XColor background; + Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); + if (!STRINGP (specified_bg) + || !x_defined_color (f, SSDATA (specified_bg), &background, 0)) + x_query_frame_background_color (f, &background); + + /* SVG pixmaps specify transparency in the last byte, so right + shift 8 bits to get rid of it, since emacs doesn't support + transparency. */ + background.red >>= 8; + background.green >>= 8; + background.blue >>= 8; + + /* This loop handles opacity values, since Emacs assumes + non-transparent images. Each pixel must be "flattened" by + calculating the resulting color, given the transparency of the + pixel, and the image background color. */ + for (int y = 0; y < height; ++y) + { + for (int x = 0; x < width; ++x) + { + int red = *pixels++; + int green = *pixels++; + int blue = *pixels++; + int opacity = *pixels++; + + red = ((red * opacity) + + (background.red * ((1 << 8) - opacity))); + green = ((green * opacity) + + (background.green * ((1 << 8) - opacity))); + blue = ((blue * opacity) + + (background.blue * ((1 << 8) - opacity))); + + XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue)); + } - pixels += rowstride - 4 * width; - } + pixels += rowstride - 4 * width; + } #ifdef COLOR_TABLE_SUPPORT - /* Remember colors allocated for this image. */ - img->colors = colors_in_color_table (&img->ncolors); - free_color_table (); + /* Remember colors allocated for this image. */ + img->colors = colors_in_color_table (&img->ncolors); + free_color_table (); #endif /* COLOR_TABLE_SUPPORT */ - g_object_unref (pixbuf); + g_object_unref (pixbuf); - img->width = width; - img->height = height; + img->width = width; + img->height = height; - /* Maybe fill in the background field while we have ximg handy. - Casting avoids a GCC warning. */ - IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); + /* Maybe fill in the background field while we have ximg handy. + Casting avoids a GCC warning. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); - /* Put ximg into the image. */ - image_put_x_image (f, img, ximg, 0); + /* Put ximg into the image. */ + image_put_x_image (f, img, ximg, 0); #endif /* ! USE_CAIRO */ + } return 1; @@ -9525,7 +9545,7 @@ gs_load (struct frame *f, struct image *img) { /* Only W32 version did BLOCK_INPUT here. ++kfs */ block_input (); - img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), img->width, img->height, DefaultDepthOfScreen (FRAME_X_SCREEN (f))); unblock_input (); @@ -9541,7 +9561,7 @@ gs_load (struct frame *f, struct image *img) if successful. We do not record_unwind_protect here because other places in redisplay like calling window scroll functions don't either. Let the Lisp loader use `unwind-protect' instead. */ - printnum1 = FRAME_X_WINDOW (f); + printnum1 = FRAME_X_DRAWABLE (f); printnum2 = img->pixmap; window_and_pixmap_id = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2); @@ -9760,6 +9780,8 @@ lookup_image_type (Lisp_Object type) return NULL; } +#if !defined CANNOT_DUMP && defined HAVE_WINDOW_SYSTEM + /* Reset image_types before dumping. Called from Fdump_emacs. */ @@ -9773,6 +9795,7 @@ reset_image_types (void) image_types = next; } } +#endif void syms_of_image (void) @@ -9816,6 +9839,7 @@ non-numeric, there is no explicit limit on the size of images. */); DEFSYM (QCcrop, ":crop"); DEFSYM (QCrotation, ":rotation"); DEFSYM (QCmatrix, ":matrix"); + DEFSYM (QCscale, ":scale"); DEFSYM (QCcolor_adjustment, ":color-adjustment"); DEFSYM (QCmask, ":mask"); |