diff options
| author | Paul Eggert | 2019-05-17 18:41:22 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-05-17 18:43:28 -0700 |
| commit | 41bf865329bbc2411203e9a90bc8dfd93ed5ef31 (patch) | |
| tree | 4424d4296328d277b3e653ac1e0f3a6bae67df40 /src/image.c | |
| parent | 4fbcecfaef8a3773b605c183c4da66cdabb39eef (diff) | |
| download | emacs-41bf865329bbc2411203e9a90bc8dfd93ed5ef31.tar.gz emacs-41bf865329bbc2411203e9a90bc8dfd93ed5ef31.zip | |
Clean up and simplify image-type setup
This also fixes an unlikely hang involving a circular image
description.
* src/dispextern.h (struct image.type): Now pointer-to-const.
* src/image.c (struct image_type.init) [!WINDOWSNT]: Omit.
(IMAGE_TYPE_INIT): New macro.
(image_types): Now a small array-of-const, not a pointer.
(CACHE_IMAGE_TYPE): Remove; the code’s simpler without it.
(ADD_IMAGE_TYPE): Remove this macro, replacing with ...
(add_image_type): ... this equivalent function. All uses changed.
(define_image_type): Remove. All uses removed.
(valid_image_p): Use FOR_EACH_TAIL_SAFE to avoid Emacs hanging
if the user creates a circular description of an image.
(xbm_type, xpm_type, pbm_type, png_type, jpeg_type, tiff_type)
(gif_type, imagemagick_type, svg_type, gs_type):
Remove; now done by image_types.
(init_imagemagick_functions): Remove decl of nonexistent function.
(gs_clear_image): Remove; all uses replaced by image_clear_image.
(initialize_image_type): New function, which captures a lot
of the previously-scattered WINDOWSNT ifdefs.
(lookup_image_type): Use it.
(reset_image_types): Remove. All uses removed.
(syms_of_image): Don’t worry about ignoring image_types for
pdumper, since it’s a constant now.
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 448 |
1 files changed, 87 insertions, 361 deletions
diff --git a/src/image.c b/src/image.c index 0779594989a..b82bf12aa5e 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -548,82 +548,29 @@ struct image_type | |||
| 548 | /* Free resources of image IMG which is used on frame F. */ | 548 | /* Free resources of image IMG which is used on frame F. */ |
| 549 | void (*free) (struct frame *f, struct image *img); | 549 | void (*free) (struct frame *f, struct image *img); |
| 550 | 550 | ||
| 551 | #ifdef WINDOWSNT | ||
| 551 | /* Initialization function (used for dynamic loading of image | 552 | /* Initialization function (used for dynamic loading of image |
| 552 | libraries on Windows), or NULL if none. */ | 553 | libraries on Windows), or NULL if none. */ |
| 553 | bool (*init) (void); | 554 | bool (*init) (void); |
| 554 | 555 | /* An initializer for the init field. */ | |
| 555 | /* Next in list of all supported image types. */ | 556 | # define IMAGE_TYPE_INIT(f) f |
| 556 | struct image_type *next; | 557 | #else |
| 558 | # define IMAGE_TYPE_INIT(f) | ||
| 559 | #endif | ||
| 557 | }; | 560 | }; |
| 558 | 561 | ||
| 559 | /* List of supported image types. Use define_image_type to add new | ||
| 560 | types. Use lookup_image_type to find a type for a given symbol. */ | ||
| 561 | |||
| 562 | static struct image_type *image_types; | ||
| 563 | |||
| 564 | /* Forward function prototypes. */ | 562 | /* Forward function prototypes. */ |
| 565 | 563 | ||
| 566 | static struct image_type *lookup_image_type (Lisp_Object); | 564 | static struct image_type const *lookup_image_type (Lisp_Object); |
| 567 | static void image_laplace (struct frame *, struct image *); | 565 | static void image_laplace (struct frame *, struct image *); |
| 568 | static void image_emboss (struct frame *, struct image *); | 566 | static void image_emboss (struct frame *, struct image *); |
| 569 | static void image_build_heuristic_mask (struct frame *, struct image *, | 567 | static void image_build_heuristic_mask (struct frame *, struct image *, |
| 570 | Lisp_Object); | 568 | Lisp_Object); |
| 571 | #ifdef WINDOWSNT | ||
| 572 | #define CACHE_IMAGE_TYPE(type, status) \ | ||
| 573 | do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) | ||
| 574 | #else | ||
| 575 | #define CACHE_IMAGE_TYPE(type, status) | ||
| 576 | #endif | ||
| 577 | |||
| 578 | #define ADD_IMAGE_TYPE(type) \ | ||
| 579 | do { Vimage_types = Fcons (type, Vimage_types); } while (0) | ||
| 580 | |||
| 581 | /* Define a new image type from TYPE. This adds a copy of TYPE to | ||
| 582 | image_types and caches the loading status of TYPE. */ | ||
| 583 | 569 | ||
| 584 | static struct image_type * | 570 | static void |
| 585 | define_image_type (struct image_type *type) | 571 | add_image_type (Lisp_Object type) |
| 586 | { | 572 | { |
| 587 | struct image_type *p = NULL; | 573 | Vimage_types = Fcons (type, Vimage_types); |
| 588 | int new_type = type->type; | ||
| 589 | bool type_valid = true; | ||
| 590 | |||
| 591 | block_input (); | ||
| 592 | |||
| 593 | for (p = image_types; p; p = p->next) | ||
| 594 | if (p->type == new_type) | ||
| 595 | goto done; | ||
| 596 | |||
| 597 | if (type->init) | ||
| 598 | { | ||
| 599 | #if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 600 | /* If we failed to load the library before, don't try again. */ | ||
| 601 | Lisp_Object tested = Fassq (builtin_lisp_symbol (new_type), | ||
| 602 | Vlibrary_cache); | ||
| 603 | if (CONSP (tested) && NILP (XCDR (tested))) | ||
| 604 | type_valid = false; | ||
| 605 | else | ||
| 606 | #endif | ||
| 607 | { | ||
| 608 | type_valid = type->init (); | ||
| 609 | CACHE_IMAGE_TYPE (builtin_lisp_symbol (new_type), | ||
| 610 | type_valid ? Qt : Qnil); | ||
| 611 | } | ||
| 612 | } | ||
| 613 | |||
| 614 | if (type_valid) | ||
| 615 | { | ||
| 616 | /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. | ||
| 617 | The initialized data segment is read-only. */ | ||
| 618 | p = xmalloc (sizeof *p); | ||
| 619 | *p = *type; | ||
| 620 | p->next = image_types; | ||
| 621 | image_types = p; | ||
| 622 | } | ||
| 623 | |||
| 624 | done: | ||
| 625 | unblock_input (); | ||
| 626 | return p; | ||
| 627 | } | 574 | } |
| 628 | 575 | ||
| 629 | 576 | ||
| @@ -637,29 +584,24 @@ define_image_type (struct image_type *type) | |||
| 637 | bool | 584 | bool |
| 638 | valid_image_p (Lisp_Object object) | 585 | valid_image_p (Lisp_Object object) |
| 639 | { | 586 | { |
| 640 | bool valid_p = 0; | ||
| 641 | |||
| 642 | if (IMAGEP (object)) | 587 | if (IMAGEP (object)) |
| 643 | { | 588 | { |
| 644 | Lisp_Object tem; | 589 | Lisp_Object tail = XCDR (object); |
| 645 | 590 | FOR_EACH_TAIL_SAFE (tail) | |
| 646 | for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem)) | 591 | if (EQ (XCAR (tail), QCtype)) |
| 647 | if (EQ (XCAR (tem), QCtype)) | ||
| 648 | { | 592 | { |
| 649 | tem = XCDR (tem); | 593 | tail = XCDR (tail); |
| 650 | if (CONSP (tem) && SYMBOLP (XCAR (tem))) | 594 | if (CONSP (tail)) |
| 651 | { | 595 | { |
| 652 | struct image_type *type; | 596 | struct image_type const *type = lookup_image_type (XCAR (tail)); |
| 653 | type = lookup_image_type (XCAR (tem)); | ||
| 654 | if (type) | 597 | if (type) |
| 655 | valid_p = type->valid_p (object); | 598 | return type->valid_p (object); |
| 656 | } | 599 | } |
| 657 | |||
| 658 | break; | 600 | break; |
| 659 | } | 601 | } |
| 660 | } | 602 | } |
| 661 | 603 | ||
| 662 | return valid_p; | 604 | return false; |
| 663 | } | 605 | } |
| 664 | 606 | ||
| 665 | 607 | ||
| @@ -2575,8 +2517,6 @@ slurp_file (int fd, ptrdiff_t *size) | |||
| 2575 | XBM images | 2517 | XBM images |
| 2576 | ***********************************************************************/ | 2518 | ***********************************************************************/ |
| 2577 | 2519 | ||
| 2578 | static bool xbm_load (struct frame *f, struct image *img); | ||
| 2579 | static bool xbm_image_p (Lisp_Object object); | ||
| 2580 | static bool xbm_file_p (Lisp_Object); | 2520 | static bool xbm_file_p (Lisp_Object); |
| 2581 | 2521 | ||
| 2582 | 2522 | ||
| @@ -2620,18 +2560,6 @@ static const struct image_keyword xbm_format[XBM_LAST] = | |||
| 2620 | {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} | 2560 | {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} |
| 2621 | }; | 2561 | }; |
| 2622 | 2562 | ||
| 2623 | /* Structure describing the image type XBM. */ | ||
| 2624 | |||
| 2625 | static struct image_type xbm_type = | ||
| 2626 | { | ||
| 2627 | SYMBOL_INDEX (Qxbm), | ||
| 2628 | xbm_image_p, | ||
| 2629 | xbm_load, | ||
| 2630 | image_clear_image, | ||
| 2631 | NULL, | ||
| 2632 | NULL | ||
| 2633 | }; | ||
| 2634 | |||
| 2635 | /* Tokens returned from xbm_scan. */ | 2563 | /* Tokens returned from xbm_scan. */ |
| 2636 | 2564 | ||
| 2637 | enum xbm_token | 2565 | enum xbm_token |
| @@ -3357,13 +3285,6 @@ xbm_load (struct frame *f, struct image *img) | |||
| 3357 | XPM images | 3285 | XPM images |
| 3358 | ***********************************************************************/ | 3286 | ***********************************************************************/ |
| 3359 | 3287 | ||
| 3360 | #if defined (HAVE_XPM) || defined (HAVE_NS) | ||
| 3361 | |||
| 3362 | static bool xpm_image_p (Lisp_Object object); | ||
| 3363 | static bool xpm_load (struct frame *f, struct image *img); | ||
| 3364 | |||
| 3365 | #endif /* HAVE_XPM || HAVE_NS */ | ||
| 3366 | |||
| 3367 | #ifdef HAVE_XPM | 3288 | #ifdef HAVE_XPM |
| 3368 | #ifdef HAVE_NTGUI | 3289 | #ifdef HAVE_NTGUI |
| 3369 | /* Indicate to xpm.h that we don't have Xlib. */ | 3290 | /* Indicate to xpm.h that we don't have Xlib. */ |
| @@ -3425,24 +3346,6 @@ static const struct image_keyword xpm_format[XPM_LAST] = | |||
| 3425 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 3346 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 3426 | }; | 3347 | }; |
| 3427 | 3348 | ||
| 3428 | #if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 3429 | static bool init_xpm_functions (void); | ||
| 3430 | #else | ||
| 3431 | #define init_xpm_functions NULL | ||
| 3432 | #endif | ||
| 3433 | |||
| 3434 | /* Structure describing the image type XPM. */ | ||
| 3435 | |||
| 3436 | static struct image_type xpm_type = | ||
| 3437 | { | ||
| 3438 | SYMBOL_INDEX (Qxpm), | ||
| 3439 | xpm_image_p, | ||
| 3440 | xpm_load, | ||
| 3441 | image_clear_image, | ||
| 3442 | init_xpm_functions, | ||
| 3443 | NULL | ||
| 3444 | }; | ||
| 3445 | |||
| 3446 | #ifdef HAVE_X_WINDOWS | 3349 | #ifdef HAVE_X_WINDOWS |
| 3447 | 3350 | ||
| 3448 | /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation | 3351 | /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation |
| @@ -5364,9 +5267,6 @@ image_build_heuristic_mask (struct frame *f, struct image *img, | |||
| 5364 | PBM (mono, gray, color) | 5267 | PBM (mono, gray, color) |
| 5365 | ***********************************************************************/ | 5268 | ***********************************************************************/ |
| 5366 | 5269 | ||
| 5367 | static bool pbm_image_p (Lisp_Object object); | ||
| 5368 | static bool pbm_load (struct frame *f, struct image *img); | ||
| 5369 | |||
| 5370 | /* Indices of image specification fields in gs_format, below. */ | 5270 | /* Indices of image specification fields in gs_format, below. */ |
| 5371 | 5271 | ||
| 5372 | enum pbm_keyword_index | 5272 | enum pbm_keyword_index |
| @@ -5403,19 +5303,6 @@ static const struct image_keyword pbm_format[PBM_LAST] = | |||
| 5403 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 5303 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 5404 | }; | 5304 | }; |
| 5405 | 5305 | ||
| 5406 | /* Structure describing the image type `pbm'. */ | ||
| 5407 | |||
| 5408 | static struct image_type pbm_type = | ||
| 5409 | { | ||
| 5410 | SYMBOL_INDEX (Qpbm), | ||
| 5411 | pbm_image_p, | ||
| 5412 | pbm_load, | ||
| 5413 | image_clear_image, | ||
| 5414 | NULL, | ||
| 5415 | NULL | ||
| 5416 | }; | ||
| 5417 | |||
| 5418 | |||
| 5419 | /* Return true if OBJECT is a valid PBM image specification. */ | 5306 | /* Return true if OBJECT is a valid PBM image specification. */ |
| 5420 | 5307 | ||
| 5421 | static bool | 5308 | static bool |
| @@ -5834,11 +5721,6 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5834 | 5721 | ||
| 5835 | #if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO) | 5722 | #if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO) |
| 5836 | 5723 | ||
| 5837 | /* Function prototypes. */ | ||
| 5838 | |||
| 5839 | static bool png_image_p (Lisp_Object object); | ||
| 5840 | static bool png_load (struct frame *f, struct image *img); | ||
| 5841 | |||
| 5842 | /* Indices of image specification fields in png_format, below. */ | 5724 | /* Indices of image specification fields in png_format, below. */ |
| 5843 | 5725 | ||
| 5844 | enum png_keyword_index | 5726 | enum png_keyword_index |
| @@ -5873,24 +5755,6 @@ static const struct image_keyword png_format[PNG_LAST] = | |||
| 5873 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 5755 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 5874 | }; | 5756 | }; |
| 5875 | 5757 | ||
| 5876 | #if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 5877 | static bool init_png_functions (void); | ||
| 5878 | #else | ||
| 5879 | #define init_png_functions NULL | ||
| 5880 | #endif | ||
| 5881 | |||
| 5882 | /* Structure describing the image type `png'. */ | ||
| 5883 | |||
| 5884 | static struct image_type png_type = | ||
| 5885 | { | ||
| 5886 | SYMBOL_INDEX (Qpng), | ||
| 5887 | png_image_p, | ||
| 5888 | png_load, | ||
| 5889 | image_clear_image, | ||
| 5890 | init_png_functions, | ||
| 5891 | NULL | ||
| 5892 | }; | ||
| 5893 | |||
| 5894 | /* Return true if OBJECT is a valid PNG image specification. */ | 5758 | /* Return true if OBJECT is a valid PNG image specification. */ |
| 5895 | 5759 | ||
| 5896 | static bool | 5760 | static bool |
| @@ -6518,9 +6382,6 @@ png_load (struct frame *f, struct image *img) | |||
| 6518 | 6382 | ||
| 6519 | #if defined (HAVE_JPEG) || defined (HAVE_NS) | 6383 | #if defined (HAVE_JPEG) || defined (HAVE_NS) |
| 6520 | 6384 | ||
| 6521 | static bool jpeg_image_p (Lisp_Object object); | ||
| 6522 | static bool jpeg_load (struct frame *f, struct image *img); | ||
| 6523 | |||
| 6524 | /* Indices of image specification fields in gs_format, below. */ | 6385 | /* Indices of image specification fields in gs_format, below. */ |
| 6525 | 6386 | ||
| 6526 | enum jpeg_keyword_index | 6387 | enum jpeg_keyword_index |
| @@ -6555,24 +6416,6 @@ static const struct image_keyword jpeg_format[JPEG_LAST] = | |||
| 6555 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 6416 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 6556 | }; | 6417 | }; |
| 6557 | 6418 | ||
| 6558 | #if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 6559 | static bool init_jpeg_functions (void); | ||
| 6560 | #else | ||
| 6561 | #define init_jpeg_functions NULL | ||
| 6562 | #endif | ||
| 6563 | |||
| 6564 | /* Structure describing the image type `jpeg'. */ | ||
| 6565 | |||
| 6566 | static struct image_type jpeg_type = | ||
| 6567 | { | ||
| 6568 | SYMBOL_INDEX (Qjpeg), | ||
| 6569 | jpeg_image_p, | ||
| 6570 | jpeg_load, | ||
| 6571 | image_clear_image, | ||
| 6572 | init_jpeg_functions, | ||
| 6573 | NULL | ||
| 6574 | }; | ||
| 6575 | |||
| 6576 | /* Return true if OBJECT is a valid JPEG image specification. */ | 6419 | /* Return true if OBJECT is a valid JPEG image specification. */ |
| 6577 | 6420 | ||
| 6578 | static bool | 6421 | static bool |
| @@ -7150,9 +6993,6 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 7150 | 6993 | ||
| 7151 | #if defined (HAVE_TIFF) || defined (HAVE_NS) | 6994 | #if defined (HAVE_TIFF) || defined (HAVE_NS) |
| 7152 | 6995 | ||
| 7153 | static bool tiff_image_p (Lisp_Object object); | ||
| 7154 | static bool tiff_load (struct frame *f, struct image *img); | ||
| 7155 | |||
| 7156 | /* Indices of image specification fields in tiff_format, below. */ | 6996 | /* Indices of image specification fields in tiff_format, below. */ |
| 7157 | 6997 | ||
| 7158 | enum tiff_keyword_index | 6998 | enum tiff_keyword_index |
| @@ -7189,24 +7029,6 @@ static const struct image_keyword tiff_format[TIFF_LAST] = | |||
| 7189 | {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0} | 7029 | {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0} |
| 7190 | }; | 7030 | }; |
| 7191 | 7031 | ||
| 7192 | #if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 7193 | static bool init_tiff_functions (void); | ||
| 7194 | #else | ||
| 7195 | #define init_tiff_functions NULL | ||
| 7196 | #endif | ||
| 7197 | |||
| 7198 | /* Structure describing the image type `tiff'. */ | ||
| 7199 | |||
| 7200 | static struct image_type tiff_type = | ||
| 7201 | { | ||
| 7202 | SYMBOL_INDEX (Qtiff), | ||
| 7203 | tiff_image_p, | ||
| 7204 | tiff_load, | ||
| 7205 | image_clear_image, | ||
| 7206 | init_tiff_functions, | ||
| 7207 | NULL | ||
| 7208 | }; | ||
| 7209 | |||
| 7210 | /* Return true if OBJECT is a valid TIFF image specification. */ | 7032 | /* Return true if OBJECT is a valid TIFF image specification. */ |
| 7211 | 7033 | ||
| 7212 | static bool | 7034 | static bool |
| @@ -7634,10 +7456,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 7634 | 7456 | ||
| 7635 | #if defined (HAVE_GIF) || defined (HAVE_NS) | 7457 | #if defined (HAVE_GIF) || defined (HAVE_NS) |
| 7636 | 7458 | ||
| 7637 | static bool gif_image_p (Lisp_Object object); | ||
| 7638 | static bool gif_load (struct frame *f, struct image *img); | ||
| 7639 | static void gif_clear_image (struct frame *f, struct image *img); | ||
| 7640 | |||
| 7641 | /* Indices of image specification fields in gif_format, below. */ | 7459 | /* Indices of image specification fields in gif_format, below. */ |
| 7642 | 7460 | ||
| 7643 | enum gif_keyword_index | 7461 | enum gif_keyword_index |
| @@ -7674,24 +7492,6 @@ static const struct image_keyword gif_format[GIF_LAST] = | |||
| 7674 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 7492 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 7675 | }; | 7493 | }; |
| 7676 | 7494 | ||
| 7677 | #if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 7678 | static bool init_gif_functions (void); | ||
| 7679 | #else | ||
| 7680 | #define init_gif_functions NULL | ||
| 7681 | #endif | ||
| 7682 | |||
| 7683 | /* Structure describing the image type `gif'. */ | ||
| 7684 | |||
| 7685 | static struct image_type gif_type = | ||
| 7686 | { | ||
| 7687 | SYMBOL_INDEX (Qgif), | ||
| 7688 | gif_image_p, | ||
| 7689 | gif_load, | ||
| 7690 | gif_clear_image, | ||
| 7691 | init_gif_functions, | ||
| 7692 | NULL | ||
| 7693 | }; | ||
| 7694 | |||
| 7695 | /* Free X resources of GIF image IMG which is used on frame F. */ | 7495 | /* Free X resources of GIF image IMG which is used on frame F. */ |
| 7696 | 7496 | ||
| 7697 | static void | 7497 | static void |
| @@ -8289,10 +8089,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 8289 | ImageMagick | 8089 | ImageMagick |
| 8290 | ***********************************************************************/ | 8090 | ***********************************************************************/ |
| 8291 | 8091 | ||
| 8292 | static bool imagemagick_image_p (Lisp_Object); | ||
| 8293 | static bool imagemagick_load (struct frame *, struct image *); | ||
| 8294 | static void imagemagick_clear_image (struct frame *, struct image *); | ||
| 8295 | |||
| 8296 | /* Indices of image specification fields in imagemagick_format. */ | 8092 | /* Indices of image specification fields in imagemagick_format. */ |
| 8297 | 8093 | ||
| 8298 | enum imagemagick_keyword_index | 8094 | enum imagemagick_keyword_index |
| @@ -8341,25 +8137,6 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = | |||
| 8341 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} | 8137 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} |
| 8342 | }; | 8138 | }; |
| 8343 | 8139 | ||
| 8344 | #if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 8345 | static bool init_imagemagick_functions (void); | ||
| 8346 | #else | ||
| 8347 | #define init_imagemagick_functions NULL | ||
| 8348 | #endif | ||
| 8349 | |||
| 8350 | /* Structure describing the image type for any image handled via | ||
| 8351 | ImageMagick. */ | ||
| 8352 | |||
| 8353 | static struct image_type imagemagick_type = | ||
| 8354 | { | ||
| 8355 | SYMBOL_INDEX (Qimagemagick), | ||
| 8356 | imagemagick_image_p, | ||
| 8357 | imagemagick_load, | ||
| 8358 | imagemagick_clear_image, | ||
| 8359 | init_imagemagick_functions, | ||
| 8360 | NULL | ||
| 8361 | }; | ||
| 8362 | |||
| 8363 | /* Free X resources of imagemagick image IMG which is used on frame F. */ | 8140 | /* Free X resources of imagemagick image IMG which is used on frame F. */ |
| 8364 | 8141 | ||
| 8365 | static void | 8142 | static void |
| @@ -9137,9 +8914,6 @@ and `imagemagick-types-inhibit'. */) | |||
| 9137 | 8914 | ||
| 9138 | /* Function prototypes. */ | 8915 | /* Function prototypes. */ |
| 9139 | 8916 | ||
| 9140 | static bool svg_image_p (Lisp_Object object); | ||
| 9141 | static bool svg_load (struct frame *f, struct image *img); | ||
| 9142 | |||
| 9143 | static bool svg_load_image (struct frame *, struct image *, | 8917 | static bool svg_load_image (struct frame *, struct image *, |
| 9144 | char *, ptrdiff_t, char *); | 8918 | char *, ptrdiff_t, char *); |
| 9145 | 8919 | ||
| @@ -9177,27 +8951,6 @@ static const struct image_keyword svg_format[SVG_LAST] = | |||
| 9177 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 8951 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 9178 | }; | 8952 | }; |
| 9179 | 8953 | ||
| 9180 | # if defined HAVE_NTGUI && defined WINDOWSNT | ||
| 9181 | static bool init_svg_functions (void); | ||
| 9182 | # else | ||
| 9183 | #define init_svg_functions NULL | ||
| 9184 | # endif | ||
| 9185 | |||
| 9186 | /* Structure describing the image type `svg'. Its the same type of | ||
| 9187 | structure defined for all image formats, handled by emacs image | ||
| 9188 | functions. See struct image_type in dispextern.h. */ | ||
| 9189 | |||
| 9190 | static struct image_type svg_type = | ||
| 9191 | { | ||
| 9192 | SYMBOL_INDEX (Qsvg), | ||
| 9193 | svg_image_p, | ||
| 9194 | svg_load, | ||
| 9195 | image_clear_image, | ||
| 9196 | init_svg_functions, | ||
| 9197 | NULL | ||
| 9198 | }; | ||
| 9199 | |||
| 9200 | |||
| 9201 | /* Return true if OBJECT is a valid SVG image specification. Do | 8954 | /* Return true if OBJECT is a valid SVG image specification. Do |
| 9202 | this by calling parse_image_spec and supplying the keywords that | 8955 | this by calling parse_image_spec and supplying the keywords that |
| 9203 | identify the SVG format. */ | 8956 | identify the SVG format. */ |
| @@ -9621,10 +9374,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9621 | 9374 | ||
| 9622 | #ifdef HAVE_GHOSTSCRIPT | 9375 | #ifdef HAVE_GHOSTSCRIPT |
| 9623 | 9376 | ||
| 9624 | static bool gs_image_p (Lisp_Object object); | ||
| 9625 | static bool gs_load (struct frame *f, struct image *img); | ||
| 9626 | static void gs_clear_image (struct frame *f, struct image *img); | ||
| 9627 | |||
| 9628 | /* Indices of image specification fields in gs_format, below. */ | 9377 | /* Indices of image specification fields in gs_format, below. */ |
| 9629 | 9378 | ||
| 9630 | enum gs_keyword_index | 9379 | enum gs_keyword_index |
| @@ -9665,28 +9414,6 @@ static const struct image_keyword gs_format[GS_LAST] = | |||
| 9665 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 9414 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 9666 | }; | 9415 | }; |
| 9667 | 9416 | ||
| 9668 | /* Structure describing the image type `ghostscript'. */ | ||
| 9669 | |||
| 9670 | static struct image_type gs_type = | ||
| 9671 | { | ||
| 9672 | SYMBOL_INDEX (Qpostscript), | ||
| 9673 | gs_image_p, | ||
| 9674 | gs_load, | ||
| 9675 | gs_clear_image, | ||
| 9676 | NULL, | ||
| 9677 | NULL | ||
| 9678 | }; | ||
| 9679 | |||
| 9680 | |||
| 9681 | /* Free X resources of Ghostscript image IMG which is used on frame F. */ | ||
| 9682 | |||
| 9683 | static void | ||
| 9684 | gs_clear_image (struct frame *f, struct image *img) | ||
| 9685 | { | ||
| 9686 | image_clear_image (f, img); | ||
| 9687 | } | ||
| 9688 | |||
| 9689 | |||
| 9690 | /* Return true if OBJECT is a valid Ghostscript image | 9417 | /* Return true if OBJECT is a valid Ghostscript image |
| 9691 | specification. */ | 9418 | specification. */ |
| 9692 | 9419 | ||
| @@ -9965,87 +9692,86 @@ the library file(s) specified by `dynamic-library-alist'. */) | |||
| 9965 | return lookup_image_type (type) ? Qt : Qnil; | 9692 | return lookup_image_type (type) ? Qt : Qnil; |
| 9966 | } | 9693 | } |
| 9967 | 9694 | ||
| 9968 | /* Look up image type TYPE, and return a pointer to its image_type | 9695 | static bool |
| 9969 | structure. Return 0 if TYPE is not a known image type. */ | 9696 | initialize_image_type (struct image_type const *type) |
| 9970 | |||
| 9971 | static struct image_type * | ||
| 9972 | lookup_image_type (Lisp_Object type) | ||
| 9973 | { | 9697 | { |
| 9974 | /* Types pbm and xbm are built-in and always available. */ | 9698 | #ifdef WINDOWSNT |
| 9975 | if (EQ (type, Qpbm)) | 9699 | bool (*init) (void) = type->init; |
| 9976 | return define_image_type (&pbm_type); | ||
| 9977 | |||
| 9978 | if (EQ (type, Qxbm)) | ||
| 9979 | return define_image_type (&xbm_type); | ||
| 9980 | 9700 | ||
| 9981 | #if defined (HAVE_XPM) || defined (HAVE_NS) | 9701 | if (init) |
| 9982 | if (EQ (type, Qxpm)) | 9702 | { |
| 9983 | return define_image_type (&xpm_type); | 9703 | /* If we failed to load the library before, don't try again. */ |
| 9704 | Lisp_Object typesym = builtin_lisp_symbol (type->type); | ||
| 9705 | Lisp_Object tested = Fassq (typesym, Vlibrary_cache); | ||
| 9706 | if (CONSP (tested) && NILP (XCDR (tested))) | ||
| 9707 | return false; | ||
| 9708 | bool type_valid = init (); | ||
| 9709 | Vlibrary_cache = Fcons (Fcons (typesym, type_valid ? Qt : Qnil), | ||
| 9710 | Vlibrary_cache); | ||
| 9711 | return type_valid; | ||
| 9712 | } | ||
| 9984 | #endif | 9713 | #endif |
| 9714 | return true; | ||
| 9715 | } | ||
| 9985 | 9716 | ||
| 9986 | #if defined (HAVE_JPEG) || defined (HAVE_NS) | 9717 | /* Array of supported image types. */ |
| 9987 | if (EQ (type, Qjpeg)) | ||
| 9988 | return define_image_type (&jpeg_type); | ||
| 9989 | #endif | ||
| 9990 | 9718 | ||
| 9991 | #if defined (HAVE_TIFF) || defined (HAVE_NS) | 9719 | static struct image_type const image_types[] = |
| 9992 | if (EQ (type, Qtiff)) | 9720 | { |
| 9993 | return define_image_type (&tiff_type); | 9721 | #ifdef HAVE_GHOSTSCRIPT |
| 9722 | { SYMBOL_INDEX (Qpostscript), gs_image_p, gs_load, image_clear_image }, | ||
| 9994 | #endif | 9723 | #endif |
| 9995 | 9724 | #ifdef HAVE_IMAGEMAGICK | |
| 9996 | #if defined (HAVE_GIF) || defined (HAVE_NS) | 9725 | { SYMBOL_INDEX (Qimagemagick), imagemagick_image_p, imagemagick_load, |
| 9997 | if (EQ (type, Qgif)) | 9726 | imagemagick_clear_image }, |
| 9998 | return define_image_type (&gif_type); | ||
| 9999 | #endif | 9727 | #endif |
| 10000 | 9728 | #ifdef HAVE_RSVG | |
| 10001 | #if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO) | 9729 | { SYMBOL_INDEX (Qsvg), svg_image_p, svg_load, image_clear_image, |
| 10002 | if (EQ (type, Qpng)) | 9730 | IMAGE_TYPE_INIT (init_svg_functions) }, |
| 10003 | return define_image_type (&png_type); | ||
| 10004 | #endif | 9731 | #endif |
| 10005 | 9732 | #if defined HAVE_PNG || defined HAVE_NS || defined USE_CAIRO | |
| 10006 | #if defined (HAVE_RSVG) | 9733 | { SYMBOL_INDEX (Qpng), png_image_p, png_load, image_clear_image, |
| 10007 | if (EQ (type, Qsvg)) | 9734 | IMAGE_TYPE_INIT (init_png_functions) }, |
| 10008 | return define_image_type (&svg_type); | ||
| 10009 | #endif | 9735 | #endif |
| 10010 | 9736 | #if defined HAVE_GIF || defined HAVE_NS | |
| 10011 | #if defined (HAVE_IMAGEMAGICK) | 9737 | { SYMBOL_INDEX (Qgif), gif_image_p, gif_load, gif_clear_image, |
| 10012 | if (EQ (type, Qimagemagick)) | 9738 | IMAGE_TYPE_INIT (init_gif_functions) }, |
| 10013 | return define_image_type (&imagemagick_type); | ||
| 10014 | #endif | 9739 | #endif |
| 10015 | 9740 | #if defined HAVE_TIFF || defined HAVE_NS | |
| 10016 | #ifdef HAVE_GHOSTSCRIPT | 9741 | { SYMBOL_INDEX (Qtiff), tiff_image_p, tiff_load, image_clear_image, |
| 10017 | if (EQ (type, Qpostscript)) | 9742 | IMAGE_TYPE_INIT (init_tiff_functions) }, |
| 10018 | return define_image_type (&gs_type); | ||
| 10019 | #endif | 9743 | #endif |
| 9744 | #if defined HAVE_JPEG || defined HAVE_NS | ||
| 9745 | { SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image, | ||
| 9746 | IMAGE_TYPE_INIT (init_jpeg_functions) }, | ||
| 9747 | #endif | ||
| 9748 | #if defined HAVE_XPM || defined HAVE_NS | ||
| 9749 | { SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image, | ||
| 9750 | IMAGE_TYPE_INIT (init_xpm_functions) }, | ||
| 9751 | #endif | ||
| 9752 | { SYMBOL_INDEX (Qxbm), xbm_image_p, xbm_load, image_clear_image }, | ||
| 9753 | { SYMBOL_INDEX (Qpbm), pbm_image_p, pbm_load, image_clear_image }, | ||
| 9754 | }; | ||
| 10020 | 9755 | ||
| 10021 | return NULL; | 9756 | /* Look up image type TYPE, and return a pointer to its image_type |
| 10022 | } | 9757 | structure. Return 0 if TYPE is not a known image type. */ |
| 10023 | |||
| 10024 | #if defined HAVE_UNEXEC && defined HAVE_WINDOW_SYSTEM | ||
| 10025 | |||
| 10026 | /* Reset image_types before dumping. | ||
| 10027 | Called from Fdump_emacs. */ | ||
| 10028 | 9758 | ||
| 10029 | void | 9759 | static struct image_type const * |
| 10030 | reset_image_types (void) | 9760 | lookup_image_type (Lisp_Object type) |
| 10031 | { | 9761 | { |
| 10032 | while (image_types) | 9762 | for (int i = 0; i < ARRAYELTS (image_types); i++) |
| 10033 | { | 9763 | { |
| 10034 | struct image_type *next = image_types->next; | 9764 | struct image_type const *r = &image_types[i]; |
| 10035 | xfree (image_types); | 9765 | if (EQ (type, builtin_lisp_symbol (r->type))) |
| 10036 | image_types = next; | 9766 | return initialize_image_type (r) ? r : NULL; |
| 10037 | } | 9767 | } |
| 9768 | return NULL; | ||
| 10038 | } | 9769 | } |
| 10039 | #endif | 9770 | |
| 10040 | 9771 | ||
| 10041 | void | 9772 | void |
| 10042 | syms_of_image (void) | 9773 | syms_of_image (void) |
| 10043 | { | 9774 | { |
| 10044 | /* Initialize this only once; it will be reset before dumping. */ | ||
| 10045 | /* The portable dumper will just leave it NULL, so no need to reset. */ | ||
| 10046 | image_types = NULL; | ||
| 10047 | PDUMPER_IGNORE (image_types); | ||
| 10048 | |||
| 10049 | /* Must be defined now because we're going to update it below, while | 9775 | /* Must be defined now because we're going to update it below, while |
| 10050 | defining the supported image types. */ | 9776 | defining the supported image types. */ |
| 10051 | DEFVAR_LISP ("image-types", Vimage_types, | 9777 | DEFVAR_LISP ("image-types", Vimage_types, |
| @@ -10096,7 +9822,7 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 10096 | DEFSYM (QCmax_width, ":max-width"); | 9822 | DEFSYM (QCmax_width, ":max-width"); |
| 10097 | DEFSYM (QCmax_height, ":max-height"); | 9823 | DEFSYM (QCmax_height, ":max-height"); |
| 10098 | #ifdef HAVE_GHOSTSCRIPT | 9824 | #ifdef HAVE_GHOSTSCRIPT |
| 10099 | ADD_IMAGE_TYPE (Qpostscript); | 9825 | add_image_type (Qpostscript); |
| 10100 | DEFSYM (QCloader, ":loader"); | 9826 | DEFSYM (QCloader, ":loader"); |
| 10101 | DEFSYM (QCpt_width, ":pt-width"); | 9827 | DEFSYM (QCpt_width, ":pt-width"); |
| 10102 | DEFSYM (QCpt_height, ":pt-height"); | 9828 | DEFSYM (QCpt_height, ":pt-height"); |
| @@ -10136,44 +9862,44 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 10136 | #endif | 9862 | #endif |
| 10137 | 9863 | ||
| 10138 | DEFSYM (Qpbm, "pbm"); | 9864 | DEFSYM (Qpbm, "pbm"); |
| 10139 | ADD_IMAGE_TYPE (Qpbm); | 9865 | add_image_type (Qpbm); |
| 10140 | 9866 | ||
| 10141 | DEFSYM (Qxbm, "xbm"); | 9867 | DEFSYM (Qxbm, "xbm"); |
| 10142 | ADD_IMAGE_TYPE (Qxbm); | 9868 | add_image_type (Qxbm); |
| 10143 | 9869 | ||
| 10144 | #if defined (HAVE_XPM) || defined (HAVE_NS) | 9870 | #if defined (HAVE_XPM) || defined (HAVE_NS) |
| 10145 | DEFSYM (Qxpm, "xpm"); | 9871 | DEFSYM (Qxpm, "xpm"); |
| 10146 | ADD_IMAGE_TYPE (Qxpm); | 9872 | add_image_type (Qxpm); |
| 10147 | #endif | 9873 | #endif |
| 10148 | 9874 | ||
| 10149 | #if defined (HAVE_JPEG) || defined (HAVE_NS) | 9875 | #if defined (HAVE_JPEG) || defined (HAVE_NS) |
| 10150 | DEFSYM (Qjpeg, "jpeg"); | 9876 | DEFSYM (Qjpeg, "jpeg"); |
| 10151 | ADD_IMAGE_TYPE (Qjpeg); | 9877 | add_image_type (Qjpeg); |
| 10152 | #endif | 9878 | #endif |
| 10153 | 9879 | ||
| 10154 | #if defined (HAVE_TIFF) || defined (HAVE_NS) | 9880 | #if defined (HAVE_TIFF) || defined (HAVE_NS) |
| 10155 | DEFSYM (Qtiff, "tiff"); | 9881 | DEFSYM (Qtiff, "tiff"); |
| 10156 | ADD_IMAGE_TYPE (Qtiff); | 9882 | add_image_type (Qtiff); |
| 10157 | #endif | 9883 | #endif |
| 10158 | 9884 | ||
| 10159 | #if defined (HAVE_GIF) || defined (HAVE_NS) | 9885 | #if defined (HAVE_GIF) || defined (HAVE_NS) |
| 10160 | DEFSYM (Qgif, "gif"); | 9886 | DEFSYM (Qgif, "gif"); |
| 10161 | ADD_IMAGE_TYPE (Qgif); | 9887 | add_image_type (Qgif); |
| 10162 | #endif | 9888 | #endif |
| 10163 | 9889 | ||
| 10164 | #if defined (HAVE_PNG) || defined (HAVE_NS) | 9890 | #if defined (HAVE_PNG) || defined (HAVE_NS) |
| 10165 | DEFSYM (Qpng, "png"); | 9891 | DEFSYM (Qpng, "png"); |
| 10166 | ADD_IMAGE_TYPE (Qpng); | 9892 | add_image_type (Qpng); |
| 10167 | #endif | 9893 | #endif |
| 10168 | 9894 | ||
| 10169 | #if defined (HAVE_IMAGEMAGICK) | 9895 | #if defined (HAVE_IMAGEMAGICK) |
| 10170 | DEFSYM (Qimagemagick, "imagemagick"); | 9896 | DEFSYM (Qimagemagick, "imagemagick"); |
| 10171 | ADD_IMAGE_TYPE (Qimagemagick); | 9897 | add_image_type (Qimagemagick); |
| 10172 | #endif | 9898 | #endif |
| 10173 | 9899 | ||
| 10174 | #if defined (HAVE_RSVG) | 9900 | #if defined (HAVE_RSVG) |
| 10175 | DEFSYM (Qsvg, "svg"); | 9901 | DEFSYM (Qsvg, "svg"); |
| 10176 | ADD_IMAGE_TYPE (Qsvg); | 9902 | add_image_type (Qsvg); |
| 10177 | #ifdef HAVE_NTGUI | 9903 | #ifdef HAVE_NTGUI |
| 10178 | /* Other libraries used directly by svg code. */ | 9904 | /* Other libraries used directly by svg code. */ |
| 10179 | DEFSYM (Qgdk_pixbuf, "gdk-pixbuf"); | 9905 | DEFSYM (Qgdk_pixbuf, "gdk-pixbuf"); |