aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorChong Yidong2012-09-22 22:10:24 +0800
committerChong Yidong2012-09-22 22:10:24 +0800
commitbb4d86b40c61443608280df3d0668d44845177a5 (patch)
tree421c8ddc18fd1f329b1906cea10f6cb60d389b37 /src/image.c
parent287d74553b1116a8e3e97e399e231c0423429aca (diff)
downloademacs-bb4d86b40c61443608280df3d0668d44845177a5.tar.gz
emacs-bb4d86b40c61443608280df3d0668d44845177a5.zip
Refactor image-type loading.
* src/dispextern.h (struct image_type): Add new slot, storing a type initialization function. * src/image.c (define_image_type): Call the image initializer function if it is defined. Arguments and return value changed. (valid_image_p, make_image): Callers changed. (xbm_type, xpm_type, pbm_type, png_type, jpeg_type, tiff_type) (gif_type, imagemagick_type, svg_type, gs_type): Add initialization functions. (Finit_image_library): Call lookup_image_type. (CHECK_LIB_AVAILABLE): Macro deleted. (lookup_image_type): Call define_image_type here, rather than via Finit_image_library, and without using CHECK_LIB_AVAILABLE. (syms_of_image): Move define_image_type calls for xbm_type and pbm_type to lookup_image_type.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c217
1 files changed, 133 insertions, 84 deletions
diff --git a/src/image.c b/src/image.c
index 8d690df8abb..0060d0d4148 100644
--- a/src/image.c
+++ b/src/image.c
@@ -561,8 +561,8 @@ static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
561 561
562/* Function prototypes. */ 562/* Function prototypes. */
563 563
564static Lisp_Object define_image_type (struct image_type *type, int loaded); 564static struct image_type *define_image_type (struct image_type *, Lisp_Object);
565static struct image_type *lookup_image_type (Lisp_Object symbol); 565static struct image_type *lookup_image_type (Lisp_Object, Lisp_Object);
566static void image_error (const char *format, Lisp_Object, Lisp_Object); 566static void image_error (const char *format, Lisp_Object, Lisp_Object);
567static void x_laplace (struct frame *, struct image *); 567static void x_laplace (struct frame *, struct image *);
568static void x_emboss (struct frame *, struct image *); 568static void x_emboss (struct frame *, struct image *);
@@ -579,54 +579,54 @@ static int x_build_heuristic_mask (struct frame *, struct image *,
579 do { Vimage_types = Fcons (type, Vimage_types); } while (0) 579 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
580 580
581/* Define a new image type from TYPE. This adds a copy of TYPE to 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. */ 582 image_types and caches the loading status of TYPE.
583 583
584static Lisp_Object 584 LIBRARIES is an alist associating dynamic libraries to external
585define_image_type (struct image_type *type, int loaded) 585 files implementing them, which is passed to the image library
586 initialization function if necessary. A nil value defaults to
587 Vdynamic_library_alist. */
588
589static struct image_type *
590define_image_type (struct image_type *type, Lisp_Object libraries)
586{ 591{
587 Lisp_Object success; 592 struct image_type *p = NULL;
593 Lisp_Object target_type = *type->type;
594 int type_valid = 1;
588 595
589 if (!loaded) 596 BLOCK_INPUT;
590 success = Qnil; 597
591 else 598 for (p = image_types; p; p = p->next)
599 if (EQ (*p->type, target_type))
600 goto done;
601
602 if (type->init)
592 { 603 {
593 struct image_type *p; 604#ifdef HAVE_NTGUI
594 Lisp_Object target_type = *(type->type); 605 /* If we failed to load the library before, don't try again. */
595 for (p = image_types; p; p = p->next) 606 Lisp_Object tested = Fassq (target_type, Vlibrary_cache);
596 if (EQ (*(p->type), target_type)) 607 if (CONSP (tested) && NILP (XCDR (tested)))
597 return Qt; 608 type_valid = 0;
609 else
610#endif
611 {
612 type_valid = type->init (libraries);
613 CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil);
614 }
615 }
598 616
617 if (type_valid)
618 {
599 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. 619 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
600 The initialized data segment is read-only. */ 620 The initialized data segment is read-only. */
601 p = xmalloc (sizeof *p); 621 p = xmalloc (sizeof *p);
602 *p = *type; 622 *p = *type;
603 p->next = image_types; 623 p->next = image_types;
604 image_types = p; 624 image_types = p;
605 success = Qt;
606 } 625 }
607 626
608 CACHE_IMAGE_TYPE (*type->type, success); 627 done:
609 return success; 628 UNBLOCK_INPUT;
610} 629 return p;
611
612
613/* Look up image type SYMBOL, and return a pointer to its image_type
614 structure. Value is null if SYMBOL is not a known image type. */
615
616static inline struct image_type *
617lookup_image_type (Lisp_Object symbol)
618{
619 struct image_type *type;
620
621 /* We must initialize the image-type if it hasn't been already. */
622 if (NILP (Finit_image_library (symbol, Vdynamic_library_alist)))
623 return 0; /* unimplemented */
624
625 for (type = image_types; type; type = type->next)
626 if (EQ (symbol, *type->type))
627 break;
628
629 return type;
630} 630}
631 631
632 632
@@ -653,7 +653,7 @@ valid_image_p (Lisp_Object object)
653 if (CONSP (tem) && SYMBOLP (XCAR (tem))) 653 if (CONSP (tem) && SYMBOLP (XCAR (tem)))
654 { 654 {
655 struct image_type *type; 655 struct image_type *type;
656 type = lookup_image_type (XCAR (tem)); 656 type = lookup_image_type (XCAR (tem), Qnil);
657 if (type) 657 if (type)
658 valid_p = type->valid_p (object); 658 valid_p = type->valid_p (object);
659 } 659 }
@@ -986,7 +986,7 @@ make_image (Lisp_Object spec, EMACS_UINT hash)
986 986
987 eassert (valid_image_p (spec)); 987 eassert (valid_image_p (spec));
988 img->dependencies = NILP (file) ? Qnil : list1 (file); 988 img->dependencies = NILP (file) ? Qnil : list1 (file);
989 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); 989 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL), Qnil);
990 eassert (img->type != NULL); 990 eassert (img->type != NULL);
991 img->spec = spec; 991 img->spec = spec;
992 img->lisp_data = Qnil; 992 img->lisp_data = Qnil;
@@ -2262,6 +2262,7 @@ static struct image_type xbm_type =
2262 xbm_image_p, 2262 xbm_image_p,
2263 xbm_load, 2263 xbm_load,
2264 x_clear_image, 2264 x_clear_image,
2265 NULL,
2265 NULL 2266 NULL
2266}; 2267};
2267 2268
@@ -3051,6 +3052,12 @@ static const struct image_keyword xpm_format[XPM_LAST] =
3051 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 3052 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
3052}; 3053};
3053 3054
3055#ifdef HAVE_NTGUI
3056static int init_xpm_functions (Lisp_Object);
3057#else
3058#define init_xpm_functions NULL
3059#endif
3060
3054/* Structure describing the image type XPM. */ 3061/* Structure describing the image type XPM. */
3055 3062
3056static struct image_type xpm_type = 3063static struct image_type xpm_type =
@@ -3059,6 +3066,7 @@ static struct image_type xpm_type =
3059 xpm_image_p, 3066 xpm_image_p,
3060 xpm_load, 3067 xpm_load,
3061 x_clear_image, 3068 x_clear_image,
3069 init_xpm_functions,
3062 NULL 3070 NULL
3063}; 3071};
3064 3072
@@ -4981,6 +4989,7 @@ static struct image_type pbm_type =
4981 pbm_image_p, 4989 pbm_image_p,
4982 pbm_load, 4990 pbm_load,
4983 x_clear_image, 4991 x_clear_image,
4992 NULL,
4984 NULL 4993 NULL
4985}; 4994};
4986 4995
@@ -5387,6 +5396,12 @@ static const struct image_keyword png_format[PNG_LAST] =
5387 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 5396 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5388}; 5397};
5389 5398
5399#ifdef HAVE_NTGUI
5400static int init_png_functions (Lisp_Object);
5401#else
5402#define init_png_functions NULL
5403#endif
5404
5390/* Structure describing the image type `png'. */ 5405/* Structure describing the image type `png'. */
5391 5406
5392static struct image_type png_type = 5407static struct image_type png_type =
@@ -5395,6 +5410,7 @@ static struct image_type png_type =
5395 png_image_p, 5410 png_image_p,
5396 png_load, 5411 png_load,
5397 x_clear_image, 5412 x_clear_image,
5413 init_png_functions,
5398 NULL 5414 NULL
5399}; 5415};
5400 5416
@@ -6039,6 +6055,12 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
6039 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 6055 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6040}; 6056};
6041 6057
6058#ifdef HAVE_NTGUI
6059static int init_jpeg_functions (Lisp_Object);
6060#else
6061#define init_jpeg_functions NULL
6062#endif
6063
6042/* Structure describing the image type `jpeg'. */ 6064/* Structure describing the image type `jpeg'. */
6043 6065
6044static struct image_type jpeg_type = 6066static struct image_type jpeg_type =
@@ -6047,6 +6069,7 @@ static struct image_type jpeg_type =
6047 jpeg_image_p, 6069 jpeg_image_p,
6048 jpeg_load, 6070 jpeg_load,
6049 x_clear_image, 6071 x_clear_image,
6072 init_jpeg_functions,
6050 NULL 6073 NULL
6051}; 6074};
6052 6075
@@ -6624,6 +6647,12 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
6624 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0} 6647 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
6625}; 6648};
6626 6649
6650#ifdef HAVE_NTGUI
6651static int init_tiff_functions (Lisp_Object);
6652#else
6653#define init_tiff_functions NULL
6654#endif
6655
6627/* Structure describing the image type `tiff'. */ 6656/* Structure describing the image type `tiff'. */
6628 6657
6629static struct image_type tiff_type = 6658static struct image_type tiff_type =
@@ -6632,6 +6661,7 @@ static struct image_type tiff_type =
6632 tiff_image_p, 6661 tiff_image_p,
6633 tiff_load, 6662 tiff_load,
6634 x_clear_image, 6663 x_clear_image,
6664 init_tiff_functions,
6635 NULL 6665 NULL
6636}; 6666};
6637 6667
@@ -7072,6 +7102,12 @@ static const struct image_keyword gif_format[GIF_LAST] =
7072 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 7102 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7073}; 7103};
7074 7104
7105#ifdef HAVE_NTGUI
7106static int init_gif_functions (Lisp_Object);
7107#else
7108#define init_gif_functions NULL
7109#endif
7110
7075/* Structure describing the image type `gif'. */ 7111/* Structure describing the image type `gif'. */
7076 7112
7077static struct image_type gif_type = 7113static struct image_type gif_type =
@@ -7080,6 +7116,7 @@ static struct image_type gif_type =
7080 gif_image_p, 7116 gif_image_p,
7081 gif_load, 7117 gif_load,
7082 gif_clear_image, 7118 gif_clear_image,
7119 init_gif_functions,
7083 NULL 7120 NULL
7084}; 7121};
7085 7122
@@ -7562,6 +7599,12 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7562 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 7599 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7563 }; 7600 };
7564 7601
7602#ifdef HAVE_NTGUI
7603static int init_imagemagick_functions (Lisp_Object);
7604#else
7605#define init_imagemagick_functions NULL
7606#endif
7607
7565/* Structure describing the image type for any image handled via 7608/* Structure describing the image type for any image handled via
7566 ImageMagick. */ 7609 ImageMagick. */
7567 7610
@@ -7571,6 +7614,7 @@ static struct image_type imagemagick_type =
7571 imagemagick_image_p, 7614 imagemagick_image_p,
7572 imagemagick_load, 7615 imagemagick_load,
7573 imagemagick_clear_image, 7616 imagemagick_clear_image,
7617 init_imagemagick_functions,
7574 NULL 7618 NULL
7575 }; 7619 };
7576 7620
@@ -8109,22 +8153,23 @@ static const struct image_keyword svg_format[SVG_LAST] =
8109 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 8153 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8110}; 8154};
8111 8155
8156#ifdef HAVE_NTGUI
8157static int init_svg_functions (Lisp_Object);
8158#else
8159#define init_svg_functions NULL
8160#endif
8161
8112/* Structure describing the image type `svg'. Its the same type of 8162/* Structure describing the image type `svg'. Its the same type of
8113 structure defined for all image formats, handled by emacs image 8163 structure defined for all image formats, handled by emacs image
8114 functions. See struct image_type in dispextern.h. */ 8164 functions. See struct image_type in dispextern.h. */
8115 8165
8116static struct image_type svg_type = 8166static struct image_type svg_type =
8117{ 8167{
8118 /* An identifier showing that this is an image structure for the SVG format. */
8119 &Qsvg, 8168 &Qsvg,
8120 /* Handle to a function that can be used to identify a SVG file. */
8121 svg_image_p, 8169 svg_image_p,
8122 /* Handle to function used to load a SVG file. */
8123 svg_load, 8170 svg_load,
8124 /* Handle to function to free sresources for SVG. */
8125 x_clear_image, 8171 x_clear_image,
8126 /* An internal field to link to the next image type in a list of 8172 init_svg_functions,
8127 image types, will be filled in when registering the format. */
8128 NULL 8173 NULL
8129}; 8174};
8130 8175
@@ -8504,6 +8549,12 @@ static const struct image_keyword gs_format[GS_LAST] =
8504 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 8549 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8505}; 8550};
8506 8551
8552#ifdef HAVE_NTGUI
8553static int init_gs_functions (Lisp_Object);
8554#else
8555#define init_gs_functions NULL
8556#endif
8557
8507/* Structure describing the image type `ghostscript'. */ 8558/* Structure describing the image type `ghostscript'. */
8508 8559
8509static struct image_type gs_type = 8560static struct image_type gs_type =
@@ -8512,6 +8563,7 @@ static struct image_type gs_type =
8512 gs_image_p, 8563 gs_image_p,
8513 gs_load, 8564 gs_load,
8514 gs_clear_image, 8565 gs_clear_image,
8566 init_gs_functions,
8515 NULL 8567 NULL
8516}; 8568};
8517 8569
@@ -8774,16 +8826,6 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8774 Initialization 8826 Initialization
8775 ***********************************************************************/ 8827 ***********************************************************************/
8776 8828
8777#ifdef HAVE_NTGUI
8778/* Image types that rely on external libraries are loaded dynamically
8779 if the library is available. */
8780#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8781 define_image_type (image_type, init_lib_fn (libraries))
8782#else
8783#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8784 define_image_type (image_type, 1)
8785#endif /* HAVE_NTGUI */
8786
8787DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0, 8829DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
8788 doc: /* Initialize image library implementing image type TYPE. 8830 doc: /* Initialize image library implementing image type TYPE.
8789Return non-nil if TYPE is a supported image type. 8831Return non-nil if TYPE is a supported image type.
@@ -8793,61 +8835,71 @@ Libraries to load are specified in alist LIBRARIES (usually, the value
8793of `dynamic-library-alist', which see). */) 8835of `dynamic-library-alist', which see). */)
8794 (Lisp_Object type, Lisp_Object libraries) 8836 (Lisp_Object type, Lisp_Object libraries)
8795{ 8837{
8796#ifdef HAVE_NTGUI 8838 return lookup_image_type (type, libraries) ? Qt : Qnil;
8797 /* Don't try to reload the library. */ 8839}
8798 Lisp_Object tested = Fassq (type, Vlibrary_cache); 8840
8799 if (CONSP (tested)) 8841/* Look up image type TYPE, and return a pointer to its image_type
8800 return XCDR (tested); 8842 structure. Return 0 if TYPE is not a known image type.
8801#endif 8843
8844 LIBRARIES is an alist associating dynamic libraries to external
8845 files implementing them, which is passed to the image library
8846 initialization function if necessary. A nil value defaults to
8847 Vdynamic_library_alist. */
8848
8849static struct image_type *
8850lookup_image_type (Lisp_Object type, Lisp_Object libraries)
8851{
8852 if (NILP (libraries))
8853 libraries = Vdynamic_library_alist;
8802 8854
8803 /* Types pbm and xbm are built-in and always available. */ 8855 /* Types pbm and xbm are built-in and always available. */
8804 if (EQ (type, Qpbm) || EQ (type, Qxbm)) 8856 if (EQ (type, Qpbm))
8805 return Qt; 8857 return define_image_type (&pbm_type, libraries);
8858
8859 if (EQ (type, Qxbm))
8860 return define_image_type (&xbm_type, libraries);
8806 8861
8807#if defined (HAVE_XPM) || defined (HAVE_NS) 8862#if defined (HAVE_XPM) || defined (HAVE_NS)
8808 if (EQ (type, Qxpm)) 8863 if (EQ (type, Qxpm))
8809 return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries); 8864 return define_image_type (&xpm_type, libraries);
8810#endif 8865#endif
8811 8866
8812#if defined (HAVE_JPEG) || defined (HAVE_NS) 8867#if defined (HAVE_JPEG) || defined (HAVE_NS)
8813 if (EQ (type, Qjpeg)) 8868 if (EQ (type, Qjpeg))
8814 return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries); 8869 return define_image_type (&jpeg_type, libraries);
8815#endif 8870#endif
8816 8871
8817#if defined (HAVE_TIFF) || defined (HAVE_NS) 8872#if defined (HAVE_TIFF) || defined (HAVE_NS)
8818 if (EQ (type, Qtiff)) 8873 if (EQ (type, Qtiff))
8819 return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries); 8874 return define_image_type (&tiff_type, libraries);
8820#endif 8875#endif
8821 8876
8822#if defined (HAVE_GIF) || defined (HAVE_NS) 8877#if defined (HAVE_GIF) || defined (HAVE_NS)
8823 if (EQ (type, Qgif)) 8878 if (EQ (type, Qgif))
8824 return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries); 8879 return define_image_type (&gif_type, libraries);
8825#endif 8880#endif
8826 8881
8827#if defined (HAVE_PNG) || defined (HAVE_NS) 8882#if defined (HAVE_PNG) || defined (HAVE_NS)
8828 if (EQ (type, Qpng)) 8883 if (EQ (type, Qpng))
8829 return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries); 8884 return define_image_type (&png_type, libraries);
8830#endif 8885#endif
8831 8886
8832#if defined (HAVE_RSVG) 8887#if defined (HAVE_RSVG)
8833 if (EQ (type, Qsvg)) 8888 if (EQ (type, Qsvg))
8834 return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); 8889 return define_image_type (&svg_type, libraries);
8835#endif 8890#endif
8836 8891
8837#if defined (HAVE_IMAGEMAGICK) 8892#if defined (HAVE_IMAGEMAGICK)
8838 if (EQ (type, Qimagemagick)) 8893 if (EQ (type, Qimagemagick))
8839 return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, 8894 return define_image_type (&imagemagick_type, libraries);
8840 libraries);
8841#endif 8895#endif
8842 8896
8843#ifdef HAVE_GHOSTSCRIPT 8897#ifdef HAVE_GHOSTSCRIPT
8844 if (EQ (type, Qpostscript)) 8898 if (EQ (type, Qpostscript))
8845 return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); 8899 return define_image_type (&gs_type, libraries);
8846#endif 8900#endif
8847 8901
8848 /* If the type is not recognized, avoid testing it ever again. */ 8902 return NULL;
8849 CACHE_IMAGE_TYPE (type, Qnil);
8850 return Qnil;
8851} 8903}
8852 8904
8853void 8905void
@@ -8878,15 +8930,6 @@ as a ratio to the frame height and width. If the value is
8878non-numeric, there is no explicit limit on the size of images. */); 8930non-numeric, there is no explicit limit on the size of images. */);
8879 Vmax_image_size = make_float (MAX_IMAGE_SIZE); 8931 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
8880 8932
8881 DEFSYM (Qpbm, "pbm");
8882 ADD_IMAGE_TYPE (Qpbm);
8883
8884 DEFSYM (Qxbm, "xbm");
8885 ADD_IMAGE_TYPE (Qxbm);
8886
8887 define_image_type (&xbm_type, 1);
8888 define_image_type (&pbm_type, 1);
8889
8890 DEFSYM (Qcount, "count"); 8933 DEFSYM (Qcount, "count");
8891 DEFSYM (Qextension_data, "extension-data"); 8934 DEFSYM (Qextension_data, "extension-data");
8892 DEFSYM (Qdelay, "delay"); 8935 DEFSYM (Qdelay, "delay");
@@ -8930,6 +8973,12 @@ non-numeric, there is no explicit limit on the size of images. */);
8930 ); 8973 );
8931#endif 8974#endif
8932 8975
8976 DEFSYM (Qpbm, "pbm");
8977 ADD_IMAGE_TYPE (Qpbm);
8978
8979 DEFSYM (Qxbm, "xbm");
8980 ADD_IMAGE_TYPE (Qxbm);
8981
8933#if defined (HAVE_XPM) || defined (HAVE_NS) 8982#if defined (HAVE_XPM) || defined (HAVE_NS)
8934 DEFSYM (Qxpm, "xpm"); 8983 DEFSYM (Qxpm, "xpm");
8935 ADD_IMAGE_TYPE (Qxpm); 8984 ADD_IMAGE_TYPE (Qxpm);