X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d6d164f6110a68a3acb816fd2ae7e55e71a18aef..3e71e4379ce7b53afe51ead4c94e6bb016bc6e7a:/src/image.c diff --git a/src/image.c b/src/image.c index e8418b840c..1770de7e8f 100644 --- a/src/image.c +++ b/src/image.c @@ -56,6 +56,11 @@ along with GNU Emacs. If not, see . */ #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 +85,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 */ @@ -223,6 +227,7 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi #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 +275,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; @@ -1142,7 +1147,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) @@ -2300,7 +2306,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 */ @@ -3158,16 +3164,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) @@ -3677,7 +3685,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 +3709,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 @@ -5894,13 +5902,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 +5929,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 +6024,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 +6673,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 +6687,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 +6750,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); @@ -7979,7 +7975,8 @@ gif_load (struct frame *f, struct image *img) { img->lisp_data = Fcons (make_number (ext->Function), - Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount), + Fcons (make_unibyte_string ((char *) ext->Bytes, + ext->ByteCount), img->lisp_data)); if (ext->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION && ext->ByteCount == 4) @@ -8076,15 +8073,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) { @@ -8135,6 +8142,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; } @@ -8549,6 +8563,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); @@ -9231,8 +9257,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); @@ -9258,82 +9284,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; @@ -9798,6 +9819,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");