aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Rumney2003-01-25 20:45:29 +0000
committerJason Rumney2003-01-25 20:45:29 +0000
commit839b19099404d6bc89563dd19208845df7a3e9cf (patch)
treeb8f294a96c3e6d1781ac3059af2fb0c5c9067b50
parent84e474169b1ef982669cad32fbd6284e05c0b146 (diff)
downloademacs-839b19099404d6bc89563dd19208845df7a3e9cf.tar.gz
emacs-839b19099404d6bc89563dd19208845df7a3e9cf.zip
(XPutPixel): Handle monochrome images; used for masks.
[HAVE_PNG]: Sync with xfns.c version. (png_load): Adjust colors for Windows. Use Windows bitmaps. Disable color table lookups. (DEF_IMGLIB_FN, LOAD_IMGLIB_FN): New macros. (init_png_functions): New function. (png_read_from_memory, png_load): Call png library functions through pointers determined at runtime. (QCloader, QCbounding_box, QCpt_width, QCpt_height): Declare. (init_external_image_libraries): New function. (init_xfns): Call it.
-rw-r--r--src/w32fns.c189
1 files changed, 139 insertions, 50 deletions
diff --git a/src/w32fns.c b/src/w32fns.c
index 1e54a07be72..4eeb08c4a53 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -57,6 +57,7 @@ Boston, MA 02111-1307, USA. */
57 57
58void syms_of_w32fns (); 58void syms_of_w32fns ();
59void globals_of_w32fns (); 59void globals_of_w32fns ();
60static void init_external_image_libraries ();
60 61
61extern void free_frame_menubar (); 62extern void free_frame_menubar ();
62extern void x_compute_fringe_widths P_ ((struct frame *, int)); 63extern void x_compute_fringe_widths P_ ((struct frame *, int));
@@ -9336,6 +9337,15 @@ forall_images_in_image_cache (f, fn)
9336 W32 support code 9337 W32 support code
9337 ***********************************************************************/ 9338 ***********************************************************************/
9338 9339
9340/* Macro for defining functions that will be loaded from image DLLs. */
9341#define DEF_IMGLIB_FN(func) FARPROC fn_##func
9342
9343/* Macro for loading those image functions from the library. */
9344#define LOAD_IMGLIB_FN(lib,func) { \
9345 fn_##func = (void *) GetProcAddress (lib, #func); \
9346 if (!fn_##func) return 0; \
9347 }
9348
9339static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, 9349static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
9340 XImage **, Pixmap *)); 9350 XImage **, Pixmap *));
9341static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int)); 9351static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int));
@@ -10843,7 +10853,7 @@ static void XPutPixel (ximg, x, y, color)
10843 *pixel = *pixel & ~(1 << x % 8); 10853 *pixel = *pixel & ~(1 << x % 8);
10844 } 10854 }
10845 else 10855 else
10846 image_error ("XPutPixel: palette image not supported.", NULL, Qnil); 10856 image_error ("XPutPixel: palette image not supported.", Qnil, Qnil);
10847} 10857}
10848 10858
10849/* Create IMG->pixmap from an array COLORS of XColor structures, whose 10859/* Create IMG->pixmap from an array COLORS of XColor structures, whose
@@ -11625,6 +11635,59 @@ static struct image_type png_type =
11625 NULL 11635 NULL
11626}; 11636};
11627 11637
11638/* PNG library details. */
11639
11640DEF_IMGLIB_FN (png_get_io_ptr);
11641DEF_IMGLIB_FN (png_check_sig);
11642DEF_IMGLIB_FN (png_create_read_struct);
11643DEF_IMGLIB_FN (png_create_info_struct);
11644DEF_IMGLIB_FN (png_destroy_read_struct);
11645DEF_IMGLIB_FN (png_set_read_fn);
11646DEF_IMGLIB_FN (png_init_io);
11647DEF_IMGLIB_FN (png_set_sig_bytes);
11648DEF_IMGLIB_FN (png_read_info);
11649DEF_IMGLIB_FN (png_get_IHDR);
11650DEF_IMGLIB_FN (png_get_valid);
11651DEF_IMGLIB_FN (png_set_strip_16);
11652DEF_IMGLIB_FN (png_set_expand);
11653DEF_IMGLIB_FN (png_set_gray_to_rgb);
11654DEF_IMGLIB_FN (png_set_background);
11655DEF_IMGLIB_FN (png_get_bKGD);
11656DEF_IMGLIB_FN (png_read_update_info);
11657DEF_IMGLIB_FN (png_get_channels);
11658DEF_IMGLIB_FN (png_get_rowbytes);
11659DEF_IMGLIB_FN (png_read_image);
11660DEF_IMGLIB_FN (png_read_end);
11661DEF_IMGLIB_FN (png_error);
11662
11663static int
11664init_png_functions (library)
11665 HMODULE library;
11666{
11667 LOAD_IMGLIB_FN (library, png_get_io_ptr);
11668 LOAD_IMGLIB_FN (library, png_check_sig);
11669 LOAD_IMGLIB_FN (library, png_create_read_struct);
11670 LOAD_IMGLIB_FN (library, png_create_info_struct);
11671 LOAD_IMGLIB_FN (library, png_destroy_read_struct);
11672 LOAD_IMGLIB_FN (library, png_set_read_fn);
11673 LOAD_IMGLIB_FN (library, png_init_io);
11674 LOAD_IMGLIB_FN (library, png_set_sig_bytes);
11675 LOAD_IMGLIB_FN (library, png_read_info);
11676 LOAD_IMGLIB_FN (library, png_get_IHDR);
11677 LOAD_IMGLIB_FN (library, png_get_valid);
11678 LOAD_IMGLIB_FN (library, png_set_strip_16);
11679 LOAD_IMGLIB_FN (library, png_set_expand);
11680 LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
11681 LOAD_IMGLIB_FN (library, png_set_background);
11682 LOAD_IMGLIB_FN (library, png_get_bKGD);
11683 LOAD_IMGLIB_FN (library, png_read_update_info);
11684 LOAD_IMGLIB_FN (library, png_get_channels);
11685 LOAD_IMGLIB_FN (library, png_get_rowbytes);
11686 LOAD_IMGLIB_FN (library, png_read_image);
11687 LOAD_IMGLIB_FN (library, png_read_end);
11688 LOAD_IMGLIB_FN (library, png_error);
11689 return 1;
11690}
11628 11691
11629/* Return non-zero if OBJECT is a valid PNG image specification. */ 11692/* Return non-zero if OBJECT is a valid PNG image specification. */
11630 11693
@@ -11687,10 +11750,10 @@ png_read_from_memory (png_ptr, data, length)
11687 png_size_t length; 11750 png_size_t length;
11688{ 11751{
11689 struct png_memory_storage *tbr 11752 struct png_memory_storage *tbr
11690 = (struct png_memory_storage *) png_get_io_ptr (png_ptr); 11753 = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
11691 11754
11692 if (length > tbr->len - tbr->index) 11755 if (length > tbr->len - tbr->index)
11693 png_error (png_ptr, "Read error"); 11756 fn_png_error (png_ptr, "Read error");
11694 11757
11695 bcopy (tbr->bytes + tbr->index, data, length); 11758 bcopy (tbr->bytes + tbr->index, data, length);
11696 tbr->index = tbr->index + length; 11759 tbr->index = tbr->index + length;
@@ -11752,7 +11815,7 @@ png_load (f, img)
11752 11815
11753 /* Check PNG signature. */ 11816 /* Check PNG signature. */
11754 if (fread (sig, 1, sizeof sig, fp) != sizeof sig 11817 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
11755 || !png_check_sig (sig, sizeof sig)) 11818 || !fn_png_check_sig (sig, sizeof sig))
11756 { 11819 {
11757 image_error ("Not a PNG file: `%s'", file, Qnil); 11820 image_error ("Not a PNG file: `%s'", file, Qnil);
11758 UNGCPRO; 11821 UNGCPRO;
@@ -11769,7 +11832,7 @@ png_load (f, img)
11769 11832
11770 /* Check PNG signature. */ 11833 /* Check PNG signature. */
11771 if (tbr.len < sizeof sig 11834 if (tbr.len < sizeof sig
11772 || !png_check_sig (tbr.bytes, sizeof sig)) 11835 || !fn_png_check_sig (tbr.bytes, sizeof sig))
11773 { 11836 {
11774 image_error ("Not a PNG image: `%s'", img->spec, Qnil); 11837 image_error ("Not a PNG image: `%s'", img->spec, Qnil);
11775 UNGCPRO; 11838 UNGCPRO;
@@ -11781,8 +11844,8 @@ png_load (f, img)
11781 } 11844 }
11782 11845
11783 /* Initialize read and info structs for PNG lib. */ 11846 /* Initialize read and info structs for PNG lib. */
11784 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, 11847 png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,
11785 my_png_error, my_png_warning); 11848 my_png_error, my_png_warning);
11786 if (!png_ptr) 11849 if (!png_ptr)
11787 { 11850 {
11788 if (fp) fclose (fp); 11851 if (fp) fclose (fp);
@@ -11790,19 +11853,19 @@ png_load (f, img)
11790 return 0; 11853 return 0;
11791 } 11854 }
11792 11855
11793 info_ptr = png_create_info_struct (png_ptr); 11856 info_ptr = fn_png_create_info_struct (png_ptr);
11794 if (!info_ptr) 11857 if (!info_ptr)
11795 { 11858 {
11796 png_destroy_read_struct (&png_ptr, NULL, NULL); 11859 fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
11797 if (fp) fclose (fp); 11860 if (fp) fclose (fp);
11798 UNGCPRO; 11861 UNGCPRO;
11799 return 0; 11862 return 0;
11800 } 11863 }
11801 11864
11802 end_info = png_create_info_struct (png_ptr); 11865 end_info = fn_png_create_info_struct (png_ptr);
11803 if (!end_info) 11866 if (!end_info)
11804 { 11867 {
11805 png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 11868 fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
11806 if (fp) fclose (fp); 11869 if (fp) fclose (fp);
11807 UNGCPRO; 11870 UNGCPRO;
11808 return 0; 11871 return 0;
@@ -11814,7 +11877,7 @@ png_load (f, img)
11814 { 11877 {
11815 error: 11878 error:
11816 if (png_ptr) 11879 if (png_ptr)
11817 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); 11880 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
11818 xfree (pixels); 11881 xfree (pixels);
11819 xfree (rows); 11882 xfree (rows);
11820 if (fp) fclose (fp); 11883 if (fp) fclose (fp);
@@ -11824,18 +11887,18 @@ png_load (f, img)
11824 11887
11825 /* Read image info. */ 11888 /* Read image info. */
11826 if (!NILP (specified_data)) 11889 if (!NILP (specified_data))
11827 png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); 11890 fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
11828 else 11891 else
11829 png_init_io (png_ptr, fp); 11892 fn_png_init_io (png_ptr, fp);
11830 11893
11831 png_set_sig_bytes (png_ptr, sizeof sig); 11894 fn_png_set_sig_bytes (png_ptr, sizeof sig);
11832 png_read_info (png_ptr, info_ptr); 11895 fn_png_read_info (png_ptr, info_ptr);
11833 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 11896 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
11834 &interlace_type, NULL, NULL); 11897 &interlace_type, NULL, NULL);
11835 11898
11836 /* If image contains simply transparency data, we prefer to 11899 /* If image contains simply transparency data, we prefer to
11837 construct a clipping mask. */ 11900 construct a clipping mask. */
11838 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) 11901 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
11839 transparent_p = 1; 11902 transparent_p = 1;
11840 else 11903 else
11841 transparent_p = 0; 11904 transparent_p = 0;
@@ -11846,16 +11909,16 @@ png_load (f, img)
11846 11909
11847 /* Strip more than 8 bits per channel. */ 11910 /* Strip more than 8 bits per channel. */
11848 if (bit_depth == 16) 11911 if (bit_depth == 16)
11849 png_set_strip_16 (png_ptr); 11912 fn_png_set_strip_16 (png_ptr);
11850 11913
11851 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel 11914 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
11852 if available. */ 11915 if available. */
11853 png_set_expand (png_ptr); 11916 fn_png_set_expand (png_ptr);
11854 11917
11855 /* Convert grayscale images to RGB. */ 11918 /* Convert grayscale images to RGB. */
11856 if (color_type == PNG_COLOR_TYPE_GRAY 11919 if (color_type == PNG_COLOR_TYPE_GRAY
11857 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 11920 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
11858 png_set_gray_to_rgb (png_ptr); 11921 fn_png_set_gray_to_rgb (png_ptr);
11859 11922
11860 screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2); 11923 screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
11861 11924
@@ -11897,15 +11960,15 @@ png_load (f, img)
11897 user_bg.green = 256 * GetGValue (color); 11960 user_bg.green = 256 * GetGValue (color);
11898 user_bg.blue = 256 * GetBValue (color); 11961 user_bg.blue = 256 * GetBValue (color);
11899 11962
11900 png_set_background (png_ptr, &user_bg, 11963 fn_png_set_background (png_ptr, &user_bg,
11901 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); 11964 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
11902 } 11965 }
11903 } 11966 }
11904 else if (png_get_bKGD (png_ptr, info_ptr, &image_bg)) 11967 else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg))
11905 /* Image contains a background color with which to 11968 /* Image contains a background color with which to
11906 combine the image. */ 11969 combine the image. */
11907 png_set_background (png_ptr, image_bg, 11970 fn_png_set_background (png_ptr, image_bg,
11908 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); 11971 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
11909 else 11972 else
11910 { 11973 {
11911 /* Image does not contain a background color with which 11974 /* Image does not contain a background color with which
@@ -11926,24 +11989,24 @@ png_load (f, img)
11926 frame_background.green = 256 * GetGValue (color); 11989 frame_background.green = 256 * GetGValue (color);
11927 frame_background.blue = 256 * GetBValue (color); 11990 frame_background.blue = 256 * GetBValue (color);
11928 11991
11929 png_set_background (png_ptr, &frame_background, 11992 fn_png_set_background (png_ptr, &frame_background,
11930 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); 11993 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
11931 } 11994 }
11932 } 11995 }
11933 11996
11934 /* Update info structure. */ 11997 /* Update info structure. */
11935 png_read_update_info (png_ptr, info_ptr); 11998 fn_png_read_update_info (png_ptr, info_ptr);
11936 11999
11937 /* Get number of channels. Valid values are 1 for grayscale images 12000 /* Get number of channels. Valid values are 1 for grayscale images
11938 and images with a palette, 2 for grayscale images with transparency 12001 and images with a palette, 2 for grayscale images with transparency
11939 information (alpha channel), 3 for RGB images, and 4 for RGB 12002 information (alpha channel), 3 for RGB images, and 4 for RGB
11940 images with alpha channel, i.e. RGBA. If conversions above were 12003 images with alpha channel, i.e. RGBA. If conversions above were
11941 sufficient we should only have 3 or 4 channels here. */ 12004 sufficient we should only have 3 or 4 channels here. */
11942 channels = png_get_channels (png_ptr, info_ptr); 12005 channels = fn_png_get_channels (png_ptr, info_ptr);
11943 xassert (channels == 3 || channels == 4); 12006 xassert (channels == 3 || channels == 4);
11944 12007
11945 /* Number of bytes needed for one row of the image. */ 12008 /* Number of bytes needed for one row of the image. */
11946 row_bytes = png_get_rowbytes (png_ptr, info_ptr); 12009 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
11947 12010
11948 /* Allocate memory for the image. */ 12011 /* Allocate memory for the image. */
11949 pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels); 12012 pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
@@ -11952,8 +12015,8 @@ png_load (f, img)
11952 rows[i] = pixels + i * row_bytes; 12015 rows[i] = pixels + i * row_bytes;
11953 12016
11954 /* Read the entire image. */ 12017 /* Read the entire image. */
11955 png_read_image (png_ptr, rows); 12018 fn_png_read_image (png_ptr, rows);
11956 png_read_end (png_ptr, info_ptr); 12019 fn_png_read_end (png_ptr, info_ptr);
11957 if (fp) 12020 if (fp)
11958 { 12021 {
11959 fclose (fp); 12022 fclose (fp);
@@ -12028,7 +12091,7 @@ png_load (f, img)
12028 overrode it. */ 12091 overrode it. */
12029 { 12092 {
12030 png_color_16 *bg; 12093 png_color_16 *bg;
12031 if (png_get_bKGD (png_ptr, info_ptr, &bg)) 12094 if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
12032 { 12095 {
12033#if 0 /* TODO: Color tables. */ 12096#if 0 /* TODO: Color tables. */
12034 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); 12097 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
@@ -12047,7 +12110,7 @@ png_load (f, img)
12047#endif 12110#endif
12048 12111
12049 /* Clean up. */ 12112 /* Clean up. */
12050 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); 12113 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
12051 xfree (rows); 12114 xfree (rows);
12052 xfree (pixels); 12115 xfree (pixels);
12053 12116
@@ -13122,6 +13185,10 @@ gif_load (f, img)
13122 13185
13123Lisp_Object Qpostscript; 13186Lisp_Object Qpostscript;
13124 13187
13188/* Keyword symbols. */
13189
13190Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
13191
13125#ifdef HAVE_GHOSTSCRIPT 13192#ifdef HAVE_GHOSTSCRIPT
13126static int gs_image_p P_ ((Lisp_Object object)); 13193static int gs_image_p P_ ((Lisp_Object object));
13127static int gs_load P_ ((struct frame *f, struct image *img)); 13194static int gs_load P_ ((struct frame *f, struct image *img));
@@ -15476,7 +15543,6 @@ versions of Windows) characters. */);
15476 staticpro (&QCrelief); 15543 staticpro (&QCrelief);
15477 Qpostscript = intern ("postscript"); 15544 Qpostscript = intern ("postscript");
15478 staticpro (&Qpostscript); 15545 staticpro (&Qpostscript);
15479#if 0 /* TODO: These need entries at top of file. */
15480 QCloader = intern (":loader"); 15546 QCloader = intern (":loader");
15481 staticpro (&QCloader); 15547 staticpro (&QCloader);
15482 QCbounding_box = intern (":bounding-box"); 15548 QCbounding_box = intern (":bounding-box");
@@ -15485,7 +15551,6 @@ versions of Windows) characters. */);
15485 staticpro (&QCpt_width); 15551 staticpro (&QCpt_width);
15486 QCpt_height = intern (":pt-height"); 15552 QCpt_height = intern (":pt-height");
15487 staticpro (&QCpt_height); 15553 staticpro (&QCpt_height);
15488#endif
15489 QCindex = intern (":index"); 15554 QCindex = intern (":index");
15490 staticpro (&QCindex); 15555 staticpro (&QCindex);
15491 Qpbm = intern ("pbm"); 15556 Qpbm = intern ("pbm");
@@ -15559,18 +15624,11 @@ void globals_of_w32fns ()
15559 track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent"); 15624 track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent");
15560} 15625}
15561 15626
15562 15627/* Initialize image types. Based on which libraries are available. */
15563void 15628static void
15564init_xfns () 15629init_external_image_libraries ()
15565{ 15630{
15566 image_types = NULL; 15631 HINSTANCE png_lib;
15567 Vimage_types = Qnil;
15568
15569 define_image_type (&pbm_type);
15570 define_image_type (&xbm_type);
15571#if 0 /* TODO : Image support for W32 */
15572 define_image_type (&gs_type);
15573#endif
15574 15632
15575#if HAVE_XPM 15633#if HAVE_XPM
15576 define_image_type (&xpm_type); 15634 define_image_type (&xpm_type);
@@ -15589,10 +15647,41 @@ init_xfns ()
15589#endif 15647#endif
15590 15648
15591#if HAVE_PNG 15649#if HAVE_PNG
15592 define_image_type (&png_type); 15650 /* Ensure zlib is loaded. Try debug version first. */
15651 if (!LoadLibrary ("zlibd.dll"))
15652 LoadLibrary ("zlib.dll");
15653
15654 /* Try loading libpng under probable names. */
15655 if ((png_lib = LoadLibrary ("libpng13d.dll"))
15656 || (png_lib = LoadLibrary ("libpng13.dll"))
15657 || (png_lib = LoadLibrary ("libpng12d.dll"))
15658 || (png_lib = LoadLibrary ("libpng12.dll"))
15659 || (png_lib = LoadLibrary ("libpng.dll")))
15660 {
15661 if (init_png_functions (png_lib))
15662 define_image_type (&png_type);
15663 }
15593#endif 15664#endif
15594} 15665}
15595 15666
15667void
15668init_xfns ()
15669{
15670 image_types = NULL;
15671 Vimage_types = Qnil;
15672
15673 define_image_type (&pbm_type);
15674 define_image_type (&xbm_type);
15675
15676#if 0 /* TODO : Ghostscript support for W32 */
15677 define_image_type (&gs_type);
15678#endif
15679
15680 /* Image types that rely on external libraries are loaded dynamically
15681 if the library is available. */
15682 init_external_image_libraries ();
15683}
15684
15596#undef abort 15685#undef abort
15597 15686
15598void 15687void