X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/18ab493650d648ab8dca651ea2698861f926e895..d562d7a44cf4abe2ea23ee6fc2982a1e41bc27fb:/src/image.c diff --git a/src/image.c b/src/image.c index d2a71637fe..db201d5a83 100644 --- a/src/image.c +++ b/src/image.c @@ -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 @@ -216,15 +217,6 @@ x_allocate_bitmap_record (FRAME_PTR f) Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); ptrdiff_t i; - if (dpyinfo->bitmaps == NULL) - { - dpyinfo->bitmaps - = (Bitmap_Record *) xmalloc (10 * sizeof (Bitmap_Record)); - dpyinfo->bitmaps_size = 10; - dpyinfo->bitmaps_last = 1; - return 1; - } - if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size) return ++dpyinfo->bitmaps_last; @@ -232,14 +224,9 @@ x_allocate_bitmap_record (FRAME_PTR f) if (dpyinfo->bitmaps[i].refcount == 0) return i + 1; - if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2 - < dpyinfo->bitmaps_size) - memory_full (SIZE_MAX); - dpyinfo->bitmaps - = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps, - (dpyinfo->bitmaps_size - * (2 * sizeof (Bitmap_Record)))); - dpyinfo->bitmaps_size *= 2; + dpyinfo->bitmaps = + xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size, + 10, -1, sizeof *dpyinfo->bitmaps); return ++dpyinfo->bitmaps_last; } @@ -705,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, @@ -812,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; @@ -1055,9 +1042,13 @@ check_image_size (struct frame *f, int width, int height) && height <= XINT (Vmax_image_size)); else if (FLOATP (Vmax_image_size)) { - xassert (f); - w = FRAME_PIXEL_WIDTH (f); - h = FRAME_PIXEL_HEIGHT (f); + if (f != NULL) + { + w = FRAME_PIXEL_WIDTH (f); + h = FRAME_PIXEL_HEIGHT (f); + } + else + w = h = 1024; /* Arbitrary size for unknown frame. */ return (width <= XFLOAT_DATA (Vmax_image_size) * w && height <= XFLOAT_DATA (Vmax_image_size) * h); } @@ -1115,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 @@ -1832,14 +1823,7 @@ cache_image (struct frame *f, struct image *img) /* If no free slot found, maybe enlarge c->images. */ if (i == c->used && c->used == c->size) - { - if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size) - memory_full (SIZE_MAX); - c->images = - (struct image **) xrealloc (c->images, - c->size * (2 * sizeof *c->images)); - c->size *= 2; - } + c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images); /* Add IMG to c->images, and assign IMG an id. */ c->images[i] = img; @@ -2273,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}, @@ -3068,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}, @@ -3586,11 +3570,7 @@ xpm_load (struct frame *f, struct image *img) #endif /* HAVE_NTGUI */ /* Remember allocated colors. */ - if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors - < attrs.nalloc_pixels) - memory_full (SIZE_MAX); - img->colors = (unsigned long *) xmalloc (img->ncolors - * sizeof *img->colors); + img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors); img->ncolors = attrs.nalloc_pixels; for (i = 0; i < attrs.nalloc_pixels; ++i) { @@ -5001,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}, @@ -5416,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}, @@ -5565,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 @@ -5986,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 */ @@ -6036,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}, @@ -6135,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 @@ -6586,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}, @@ -7023,7 +7003,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}, @@ -7168,7 +7148,6 @@ gif_load (struct frame *f, struct image *img) ColorMapObject *gif_color_map; unsigned long pixel_colors[256]; GifFileType *gif; - int image_height, image_width; gif_memory_source memsrc; Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); @@ -7245,19 +7224,15 @@ gif_load (struct frame *f, struct image *img) } } - img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top; - img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left; - image_height = gif->SavedImages[idx].ImageDesc.Height; - img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height; - image_width = gif->SavedImages[idx].ImageDesc.Width; - img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width; + width = img->width = gif->SWidth; + height = img->height = gif->SHeight; - width = img->width = max (gif->SWidth, - max (gif->Image.Left + gif->Image.Width, - img->corners[RIGHT_CORNER])); - height = img->height = max (gif->SHeight, - max (gif->Image.Top + gif->Image.Height, - img->corners[BOT_CORNER])); + 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] + 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)) { @@ -7312,6 +7287,10 @@ gif_load (struct frame *f, struct image *img) unsigned char *raster = (unsigned char *) subimage->RasterBits; int transparency_color_index = -1; int disposal = 0; + int subimg_width = subimage->ImageDesc.Width; + int subimg_height = subimage->ImageDesc.Height; + int subimg_top = subimage->ImageDesc.Top; + int subimg_left = subimage->ImageDesc.Left; /* Find the Graphic Control Extension block for this sub-image. Extract the disposal method and transparency color. */ @@ -7335,6 +7314,13 @@ gif_load (struct frame *f, struct image *img) if (j == 0) disposal = 2; + /* For disposal == 0, the spec says "No disposal specified. The + decoder is not required to take any action." In practice, it + seems we need to treat this like "keep in place", see e.g. + http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */ + if (disposal == 0) + disposal = 1; + /* Allocate subimage colors. */ memset (pixel_colors, 0, sizeof pixel_colors); gif_color_map = subimage->ImageDesc.ColorMap; @@ -7362,34 +7348,34 @@ gif_load (struct frame *f, struct image *img) int row, pass; for (y = 0, row = interlace_start[0], pass = 0; - y < image_height; + y < subimg_height; y++, row += interlace_increment[pass]) { - if (row >= image_height) + if (row >= subimg_height) { row = interlace_start[++pass]; - while (row >= image_height) + while (row >= subimg_height) row = interlace_start[++pass]; } - for (x = 0; x < image_width; x++) + for (x = 0; x < subimg_width; x++) { - int c = raster[y * image_width + x]; + int c = raster[y * subimg_width + x]; if (transparency_color_index != c || disposal != 1) - XPutPixel (ximg, x + img->corners[LEFT_CORNER], - row + img->corners[TOP_CORNER], pixel_colors[c]); + XPutPixel (ximg, x + subimg_left, row + subimg_top, + pixel_colors[c]); } } } else { - for (y = 0; y < image_height; ++y) - for (x = 0; x < image_width; ++x) + for (y = 0; y < subimg_height; ++y) + for (x = 0; x < subimg_width; ++x) { - int c = raster[y * image_width + x]; + int c = raster[y * subimg_width + x]; if (transparency_color_index != c || disposal != 1) - XPutPixel (ximg, x + img->corners[LEFT_CORNER], - y + img->corners[TOP_CORNER], pixel_colors[c]); + XPutPixel (ximg, x + subimg_left, y + subimg_top, + pixel_colors[c]); } } } @@ -7504,7 +7490,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}, @@ -7639,7 +7625,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)), @@ -7664,7 +7650,7 @@ 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 { @@ -7785,7 +7771,7 @@ 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; } @@ -7839,7 +7825,7 @@ 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; } @@ -8027,7 +8013,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}, @@ -8422,7 +8408,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},