57 |
|
|
58 |
void syms_of_w32fns (); |
void syms_of_w32fns (); |
59 |
void globals_of_w32fns (); |
void globals_of_w32fns (); |
60 |
|
static void init_external_image_libraries (); |
61 |
|
|
62 |
extern void free_frame_menubar (); |
extern void free_frame_menubar (); |
63 |
extern void x_compute_fringe_widths P_ ((struct frame *, int)); |
extern void x_compute_fringe_widths P_ ((struct frame *, int)); |
9337 |
W32 support code |
W32 support code |
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 |
|
|
9349 |
static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, |
static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, |
9350 |
XImage **, Pixmap *)); |
XImage **, Pixmap *)); |
9351 |
static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int)); |
static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int)); |
10853 |
*pixel = *pixel & ~(1 << x % 8); |
*pixel = *pixel & ~(1 << x % 8); |
10854 |
} |
} |
10855 |
else |
else |
10856 |
image_error ("XPutPixel: palette image not supported.", NULL, Qnil); |
image_error ("XPutPixel: palette image not supported.", Qnil, Qnil); |
10857 |
} |
} |
10858 |
|
|
10859 |
/* Create IMG->pixmap from an array COLORS of XColor structures, whose |
/* Create IMG->pixmap from an array COLORS of XColor structures, whose |
11635 |
NULL |
NULL |
11636 |
}; |
}; |
11637 |
|
|
11638 |
|
/* PNG library details. */ |
11639 |
|
|
11640 |
|
DEF_IMGLIB_FN (png_get_io_ptr); |
11641 |
|
DEF_IMGLIB_FN (png_check_sig); |
11642 |
|
DEF_IMGLIB_FN (png_create_read_struct); |
11643 |
|
DEF_IMGLIB_FN (png_create_info_struct); |
11644 |
|
DEF_IMGLIB_FN (png_destroy_read_struct); |
11645 |
|
DEF_IMGLIB_FN (png_set_read_fn); |
11646 |
|
DEF_IMGLIB_FN (png_init_io); |
11647 |
|
DEF_IMGLIB_FN (png_set_sig_bytes); |
11648 |
|
DEF_IMGLIB_FN (png_read_info); |
11649 |
|
DEF_IMGLIB_FN (png_get_IHDR); |
11650 |
|
DEF_IMGLIB_FN (png_get_valid); |
11651 |
|
DEF_IMGLIB_FN (png_set_strip_16); |
11652 |
|
DEF_IMGLIB_FN (png_set_expand); |
11653 |
|
DEF_IMGLIB_FN (png_set_gray_to_rgb); |
11654 |
|
DEF_IMGLIB_FN (png_set_background); |
11655 |
|
DEF_IMGLIB_FN (png_get_bKGD); |
11656 |
|
DEF_IMGLIB_FN (png_read_update_info); |
11657 |
|
DEF_IMGLIB_FN (png_get_channels); |
11658 |
|
DEF_IMGLIB_FN (png_get_rowbytes); |
11659 |
|
DEF_IMGLIB_FN (png_read_image); |
11660 |
|
DEF_IMGLIB_FN (png_read_end); |
11661 |
|
DEF_IMGLIB_FN (png_error); |
11662 |
|
|
11663 |
|
static int |
11664 |
|
init_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 |
|
} |
11691 |
|
|
11692 |
/* Return non-zero if OBJECT is a valid PNG image specification. */ |
/* Return non-zero if OBJECT is a valid PNG image specification. */ |
11693 |
|
|
11750 |
png_size_t length; |
png_size_t length; |
11751 |
{ |
{ |
11752 |
struct png_memory_storage *tbr |
struct png_memory_storage *tbr |
11753 |
= (struct png_memory_storage *) png_get_io_ptr (png_ptr); |
= (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr); |
11754 |
|
|
11755 |
if (length > tbr->len - tbr->index) |
if (length > tbr->len - tbr->index) |
11756 |
png_error (png_ptr, "Read error"); |
fn_png_error (png_ptr, "Read error"); |
11757 |
|
|
11758 |
bcopy (tbr->bytes + tbr->index, data, length); |
bcopy (tbr->bytes + tbr->index, data, length); |
11759 |
tbr->index = tbr->index + length; |
tbr->index = tbr->index + length; |
11815 |
|
|
11816 |
/* Check PNG signature. */ |
/* Check PNG signature. */ |
11817 |
if (fread (sig, 1, sizeof sig, fp) != sizeof sig |
if (fread (sig, 1, sizeof sig, fp) != sizeof sig |
11818 |
|| !png_check_sig (sig, sizeof sig)) |
|| !fn_png_check_sig (sig, sizeof sig)) |
11819 |
{ |
{ |
11820 |
image_error ("Not a PNG file: `%s'", file, Qnil); |
image_error ("Not a PNG file: `%s'", file, Qnil); |
11821 |
UNGCPRO; |
UNGCPRO; |
11832 |
|
|
11833 |
/* Check PNG signature. */ |
/* Check PNG signature. */ |
11834 |
if (tbr.len < sizeof sig |
if (tbr.len < sizeof sig |
11835 |
|| !png_check_sig (tbr.bytes, sizeof sig)) |
|| !fn_png_check_sig (tbr.bytes, sizeof sig)) |
11836 |
{ |
{ |
11837 |
image_error ("Not a PNG image: `%s'", img->spec, Qnil); |
image_error ("Not a PNG image: `%s'", img->spec, Qnil); |
11838 |
UNGCPRO; |
UNGCPRO; |
11844 |
} |
} |
11845 |
|
|
11846 |
/* Initialize read and info structs for PNG lib. */ |
/* Initialize read and info structs for PNG lib. */ |
11847 |
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, |
png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, |
11848 |
my_png_error, my_png_warning); |
my_png_error, my_png_warning); |
11849 |
if (!png_ptr) |
if (!png_ptr) |
11850 |
{ |
{ |
11851 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
11853 |
return 0; |
return 0; |
11854 |
} |
} |
11855 |
|
|
11856 |
info_ptr = png_create_info_struct (png_ptr); |
info_ptr = fn_png_create_info_struct (png_ptr); |
11857 |
if (!info_ptr) |
if (!info_ptr) |
11858 |
{ |
{ |
11859 |
png_destroy_read_struct (&png_ptr, NULL, NULL); |
fn_png_destroy_read_struct (&png_ptr, NULL, NULL); |
11860 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
11861 |
UNGCPRO; |
UNGCPRO; |
11862 |
return 0; |
return 0; |
11863 |
} |
} |
11864 |
|
|
11865 |
end_info = png_create_info_struct (png_ptr); |
end_info = fn_png_create_info_struct (png_ptr); |
11866 |
if (!end_info) |
if (!end_info) |
11867 |
{ |
{ |
11868 |
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); |
fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); |
11869 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
11870 |
UNGCPRO; |
UNGCPRO; |
11871 |
return 0; |
return 0; |
11877 |
{ |
{ |
11878 |
error: |
error: |
11879 |
if (png_ptr) |
if (png_ptr) |
11880 |
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
11881 |
xfree (pixels); |
xfree (pixels); |
11882 |
xfree (rows); |
xfree (rows); |
11883 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
11887 |
|
|
11888 |
/* Read image info. */ |
/* Read image info. */ |
11889 |
if (!NILP (specified_data)) |
if (!NILP (specified_data)) |
11890 |
png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); |
fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); |
11891 |
else |
else |
11892 |
png_init_io (png_ptr, fp); |
fn_png_init_io (png_ptr, fp); |
11893 |
|
|
11894 |
png_set_sig_bytes (png_ptr, sizeof sig); |
fn_png_set_sig_bytes (png_ptr, sizeof sig); |
11895 |
png_read_info (png_ptr, info_ptr); |
fn_png_read_info (png_ptr, info_ptr); |
11896 |
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, |
fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, |
11897 |
&interlace_type, NULL, NULL); |
&interlace_type, NULL, NULL); |
11898 |
|
|
11899 |
/* If image contains simply transparency data, we prefer to |
/* If image contains simply transparency data, we prefer to |
11900 |
construct a clipping mask. */ |
construct a clipping mask. */ |
11901 |
if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) |
if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) |
11902 |
transparent_p = 1; |
transparent_p = 1; |
11903 |
else |
else |
11904 |
transparent_p = 0; |
transparent_p = 0; |
11909 |
|
|
11910 |
/* Strip more than 8 bits per channel. */ |
/* Strip more than 8 bits per channel. */ |
11911 |
if (bit_depth == 16) |
if (bit_depth == 16) |
11912 |
png_set_strip_16 (png_ptr); |
fn_png_set_strip_16 (png_ptr); |
11913 |
|
|
11914 |
/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel |
/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel |
11915 |
if available. */ |
if available. */ |
11916 |
png_set_expand (png_ptr); |
fn_png_set_expand (png_ptr); |
11917 |
|
|
11918 |
/* Convert grayscale images to RGB. */ |
/* Convert grayscale images to RGB. */ |
11919 |
if (color_type == PNG_COLOR_TYPE_GRAY |
if (color_type == PNG_COLOR_TYPE_GRAY |
11920 |
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
11921 |
png_set_gray_to_rgb (png_ptr); |
fn_png_set_gray_to_rgb (png_ptr); |
11922 |
|
|
11923 |
screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2); |
screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2); |
11924 |
|
|
11960 |
user_bg.green = 256 * GetGValue (color); |
user_bg.green = 256 * GetGValue (color); |
11961 |
user_bg.blue = 256 * GetBValue (color); |
user_bg.blue = 256 * GetBValue (color); |
11962 |
|
|
11963 |
png_set_background (png_ptr, &user_bg, |
fn_png_set_background (png_ptr, &user_bg, |
11964 |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
11965 |
} |
} |
11966 |
} |
} |
11967 |
else if (png_get_bKGD (png_ptr, info_ptr, &image_bg)) |
else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg)) |
11968 |
/* Image contains a background color with which to |
/* Image contains a background color with which to |
11969 |
combine the image. */ |
combine the image. */ |
11970 |
png_set_background (png_ptr, image_bg, |
fn_png_set_background (png_ptr, image_bg, |
11971 |
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); |
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); |
11972 |
else |
else |
11973 |
{ |
{ |
11974 |
/* Image does not contain a background color with which |
/* Image does not contain a background color with which |
11989 |
frame_background.green = 256 * GetGValue (color); |
frame_background.green = 256 * GetGValue (color); |
11990 |
frame_background.blue = 256 * GetBValue (color); |
frame_background.blue = 256 * GetBValue (color); |
11991 |
|
|
11992 |
png_set_background (png_ptr, &frame_background, |
fn_png_set_background (png_ptr, &frame_background, |
11993 |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
11994 |
} |
} |
11995 |
} |
} |
11996 |
|
|
11997 |
/* Update info structure. */ |
/* Update info structure. */ |
11998 |
png_read_update_info (png_ptr, info_ptr); |
fn_png_read_update_info (png_ptr, info_ptr); |
11999 |
|
|
12000 |
/* Get number of channels. Valid values are 1 for grayscale images |
/* Get number of channels. Valid values are 1 for grayscale images |
12001 |
and images with a palette, 2 for grayscale images with transparency |
and images with a palette, 2 for grayscale images with transparency |
12002 |
information (alpha channel), 3 for RGB images, and 4 for RGB |
information (alpha channel), 3 for RGB images, and 4 for RGB |
12003 |
images with alpha channel, i.e. RGBA. If conversions above were |
images with alpha channel, i.e. RGBA. If conversions above were |
12004 |
sufficient we should only have 3 or 4 channels here. */ |
sufficient we should only have 3 or 4 channels here. */ |
12005 |
channels = png_get_channels (png_ptr, info_ptr); |
channels = fn_png_get_channels (png_ptr, info_ptr); |
12006 |
xassert (channels == 3 || channels == 4); |
xassert (channels == 3 || channels == 4); |
12007 |
|
|
12008 |
/* Number of bytes needed for one row of the image. */ |
/* Number of bytes needed for one row of the image. */ |
12009 |
row_bytes = png_get_rowbytes (png_ptr, info_ptr); |
row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr); |
12010 |
|
|
12011 |
/* Allocate memory for the image. */ |
/* Allocate memory for the image. */ |
12012 |
pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels); |
pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels); |
12015 |
rows[i] = pixels + i * row_bytes; |
rows[i] = pixels + i * row_bytes; |
12016 |
|
|
12017 |
/* Read the entire image. */ |
/* Read the entire image. */ |
12018 |
png_read_image (png_ptr, rows); |
fn_png_read_image (png_ptr, rows); |
12019 |
png_read_end (png_ptr, info_ptr); |
fn_png_read_end (png_ptr, info_ptr); |
12020 |
if (fp) |
if (fp) |
12021 |
{ |
{ |
12022 |
fclose (fp); |
fclose (fp); |
12091 |
overrode it. */ |
overrode it. */ |
12092 |
{ |
{ |
12093 |
png_color_16 *bg; |
png_color_16 *bg; |
12094 |
if (png_get_bKGD (png_ptr, info_ptr, &bg)) |
if (fn_png_get_bKGD (png_ptr, info_ptr, &bg)) |
12095 |
{ |
{ |
12096 |
#if 0 /* TODO: Color tables. */ |
#if 0 /* TODO: Color tables. */ |
12097 |
img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); |
img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); |
12110 |
#endif |
#endif |
12111 |
|
|
12112 |
/* Clean up. */ |
/* Clean up. */ |
12113 |
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
12114 |
xfree (rows); |
xfree (rows); |
12115 |
xfree (pixels); |
xfree (pixels); |
12116 |
|
|
13185 |
|
|
13186 |
Lisp_Object Qpostscript; |
Lisp_Object Qpostscript; |
13187 |
|
|
13188 |
|
/* Keyword symbols. */ |
13189 |
|
|
13190 |
|
Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; |
13191 |
|
|
13192 |
#ifdef HAVE_GHOSTSCRIPT |
#ifdef HAVE_GHOSTSCRIPT |
13193 |
static int gs_image_p P_ ((Lisp_Object object)); |
static int gs_image_p P_ ((Lisp_Object object)); |
13194 |
static int gs_load P_ ((struct frame *f, struct image *img)); |
static int gs_load P_ ((struct frame *f, struct image *img)); |
15543 |
staticpro (&QCrelief); |
staticpro (&QCrelief); |
15544 |
Qpostscript = intern ("postscript"); |
Qpostscript = intern ("postscript"); |
15545 |
staticpro (&Qpostscript); |
staticpro (&Qpostscript); |
|
#if 0 /* TODO: These need entries at top of file. */ |
|
15546 |
QCloader = intern (":loader"); |
QCloader = intern (":loader"); |
15547 |
staticpro (&QCloader); |
staticpro (&QCloader); |
15548 |
QCbounding_box = intern (":bounding-box"); |
QCbounding_box = intern (":bounding-box"); |
15551 |
staticpro (&QCpt_width); |
staticpro (&QCpt_width); |
15552 |
QCpt_height = intern (":pt-height"); |
QCpt_height = intern (":pt-height"); |
15553 |
staticpro (&QCpt_height); |
staticpro (&QCpt_height); |
|
#endif |
|
15554 |
QCindex = intern (":index"); |
QCindex = intern (":index"); |
15555 |
staticpro (&QCindex); |
staticpro (&QCindex); |
15556 |
Qpbm = intern ("pbm"); |
Qpbm = intern ("pbm"); |
15624 |
track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent"); |
track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent"); |
15625 |
} |
} |
15626 |
|
|
15627 |
|
/* Initialize image types. Based on which libraries are available. */ |
15628 |
void |
static void |
15629 |
init_xfns () |
init_external_image_libraries () |
15630 |
{ |
{ |
15631 |
image_types = NULL; |
HINSTANCE png_lib; |
|
Vimage_types = Qnil; |
|
|
|
|
|
define_image_type (&pbm_type); |
|
|
define_image_type (&xbm_type); |
|
|
#if 0 /* TODO : Image support for W32 */ |
|
|
define_image_type (&gs_type); |
|
|
#endif |
|
15632 |
|
|
15633 |
#if HAVE_XPM |
#if HAVE_XPM |
15634 |
define_image_type (&xpm_type); |
define_image_type (&xpm_type); |
15647 |
#endif |
#endif |
15648 |
|
|
15649 |
#if HAVE_PNG |
#if HAVE_PNG |
15650 |
define_image_type (&png_type); |
/* 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 |
|
} |
15664 |
#endif |
#endif |
15665 |
} |
} |
15666 |
|
|
15667 |
|
void |
15668 |
|
init_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 |
|
|
15685 |
#undef abort |
#undef abort |
15686 |
|
|
15687 |
void |
void |