comparison src/glyphs-x.c @ 221:6c0ae1f9357f r20-4b9

Import from CVS: tag r20-4b9
author cvs
date Mon, 13 Aug 2007 10:10:02 +0200
parents 262b8bb4a523
children 2c611d1463a6
comparison
equal deleted inserted replaced
220:04f4bca7b601 221:6c0ae1f9357f
58 58
59 #ifdef HAVE_IMAGEMAGICK 59 #ifdef HAVE_IMAGEMAGICK
60 #include <magick/magick.h> 60 #include <magick/magick.h>
61 /*#include <image.h>*/ 61 /*#include <image.h>*/
62 #include <assert.h> 62 #include <assert.h>
63
64 #define OLDCOMPAT /* allow lisp code using the old names to still function */
63 #endif 65 #endif
64 66
65 #define LISP_DEVICE_TO_X_SCREEN(dev) \ 67 #define LISP_DEVICE_TO_X_SCREEN(dev) \
66 XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev))) 68 XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev)))
67 69
83 #endif 85 #endif
84 86
85 #ifdef HAVE_IMAGEMAGICK 87 #ifdef HAVE_IMAGEMAGICK
86 DEFINE_IMAGE_INSTANTIATOR_FORMAT (imagick); 88 DEFINE_IMAGE_INSTANTIATOR_FORMAT (imagick);
87 Lisp_Object Qimagick; 89 Lisp_Object Qimagick;
90
91 #ifdef OLDCOMPAT /* old compatibility */
92 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
93 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png);
94 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif);
95 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
96 Lisp_Object Qtiff;
97 Lisp_Object Qpng;
98 Lisp_Object Qgif;
99 Lisp_Object Qjpeg;
100 #endif
88 #endif 101 #endif
89 102
90 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); 103 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font);
91 Lisp_Object Qcursor_font; 104 Lisp_Object Qcursor_font;
92 105
1678 return IMAGE_COLOR_PIXMAP_MASK; 1691 return IMAGE_COLOR_PIXMAP_MASK;
1679 } 1692 }
1680 1693
1681 struct imagick_unwind_data 1694 struct imagick_unwind_data
1682 { 1695 {
1683 /* FIXME - what goes here...*/
1684 Display *dpy; 1696 Display *dpy;
1697 Colormap cmap;
1685 FILE *instream; 1698 FILE *instream;
1686 Image *image; 1699 Image *image;
1687 XImage *ximage; 1700 XImage *ximage;
1688 unsigned long *pixels; 1701 unsigned long *pixels;
1689 unsigned long npixels; 1702 unsigned long npixels;
1705 1718
1706 if (data->image) { 1719 if (data->image) {
1707 DestroyImage(data->image); 1720 DestroyImage(data->image);
1708 } 1721 }
1709 1722
1710 if (data->ximage) 1723 if (data->ximage) {
1711 { 1724 if (data->ximage->data) {
1712 if (data->ximage->data)
1713 {
1714 xfree (data->ximage->data); 1725 xfree (data->ximage->data);
1715 data->ximage->data = NULL; 1726 data->ximage->data = NULL;
1716 } 1727 }
1717 XDestroyImage (data->ximage); 1728 XDestroyImage (data->ximage);
1718 } 1729 }
1730
1731 if (data->npixels > 0) {
1732 XFreeColors(data->dpy, data->cmap, data->pixels, data->npixels, 0L);
1733 xfree (data->pixels);
1734 }
1719 1735
1720 return Qnil; 1736 return Qnil;
1721 } 1737 }
1722 1738
1723 static void 1739 static void
1724 imagick_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 1740 imagick_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1725 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 1741 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1726 int dest_mask, Lisp_Object domain) 1742 int dest_mask, Lisp_Object domain)
1727 { 1743 {
1728 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 1744 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1729 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); 1745 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1730 Display *dpy; 1746 Display *dpy;
1731 Screen *scr; 1747 Screen *scr;
1732 Visual *visual; 1748 Visual *visual;
1733 Dimension depth; 1749 Colormap cmap;
1734 struct imagick_unwind_data unwind; 1750 Dimension depth;
1735 int speccount = specpdl_depth (); 1751 struct imagick_unwind_data unwind;
1736 ImageInfo image_info; 1752 int speccount = specpdl_depth ();
1737 1753 ImageInfo image_info;
1738 /* ImageMagick variables */ 1754
1739 1755 /* ImageMagick variables */
1740 /* Basic error checking */ 1756
1741 if (!DEVICE_X_P (XDEVICE (device))) 1757 /* Basic error checking */
1742 signal_simple_error ("Not an X device", device); 1758 if (!DEVICE_X_P (XDEVICE (device)))
1743 1759 signal_simple_error ("Not an X device", device);
1744 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); 1760
1745 scr = DefaultScreenOfDisplay (dpy); 1761 dpy = DEVICE_X_DISPLAY (XDEVICE (device));
1746 depth = DEVICE_X_DEPTH (XDEVICE (device)); 1762 scr = DefaultScreenOfDisplay (dpy);
1747 visual = DEVICE_X_VISUAL (XDEVICE (device)); 1763 depth = DEVICE_X_DEPTH (XDEVICE (device));
1748 1764 visual = DEVICE_X_VISUAL (XDEVICE (device));
1749 /* Set up the unwind */ 1765 cmap = DEVICE_X_COLORMAP (XDEVICE(device));
1750 memset (&unwind, 0, sizeof (unwind)); 1766
1751 unwind.dpy = dpy; 1767 /* Set up the unwind */
1752 record_unwind_protect(imagick_instantiate_unwind,make_opaque_ptr(&unwind)); 1768 memset (&unwind, 0, sizeof (unwind));
1753 1769 unwind.dpy = dpy;
1754 /* Write out to a temp file - not sure if ImageMagick supports the 1770 unwind.cmap = cmap;
1755 ** notion of an abstrat 'data source' right now. 1771 record_unwind_protect(imagick_instantiate_unwind,make_opaque_ptr(&unwind));
1756 */ 1772
1773 /* Write out to a temp file - not sure if ImageMagick supports the
1774 ** notion of an abstract 'data source' right now.
1775 ** JH: It doesn't as of 3.9.3
1776 */
1777 {
1778 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1779
1780 assert (!NILP (data));
1781
1782 write_lisp_string_to_temp_file (data, unwind.tempfile);
1783 unwind.tempfile_needs_to_be_removed = 1;
1784
1785 if ((unwind.instream = fopen (unwind.tempfile, "rb")) == NULL)
1786 report_file_error ("Opening ImageMagick temp file",
1787 list1 (build_string (unwind.tempfile)));
1788 }
1789
1790 /* Initialize structures and read in the image */
1791 GetImageInfo(&image_info);
1792 strcpy(image_info.filename,unwind.tempfile);
1793 unwind.image = ReadImage(&image_info);
1794
1795 if (unwind.image == (Image *) NULL) {
1796 signal_simple_error ("Unable to read image.",instantiator);
1797 }
1798
1799 #if 1
1800 /*
1801 * For now, force dithering everything, and deal with all images as if they
1802 * were PseudoClass images
1803 */
1804 if (unwind.image->class != PseudoClass) {
1805 QuantizeInfo quantize_info;
1806 GetQuantizeInfo(&quantize_info);
1807 quantize_info.number_colors=256;
1808 quantize_info.tree_depth=8;
1809 quantize_info.dither=True;
1810 quantize_info.colorspace=RGBColorspace;
1811 QuantizeImage(&quantize_info, unwind.image);
1812 SyncImage(unwind.image);
1813 /* #### It would probably be a good idea to sort the colormap by popularity,
1814 * so that in case we run out of entries in the map, it will likely be on
1815 * the less used colors
1816 */
1817 } else {
1818 CompressColormap(unwind.image);
1819 SyncImage(unwind.image);
1820 }
1821
1822 #endif
1823
1824 #if 0
1825 DescribeImage(unwind.image,stderr,1);
1826 #endif
1827
1828 unwind.ximage = XCreateImage(dpy, visual, depth,
1829 (depth == 1) ? XYPixmap : ZPixmap,
1830 0, 0,
1831 unwind.image->columns,
1832 unwind.image->rows,
1833 XBitmapPad(dpy), 0);
1834
1835 if (!unwind.ximage) {
1836 signal_simple_error("Unable to allocate XImage structure",
1837 instantiator);
1838 }
1839
1840 unwind.ximage->data = (char *) xmalloc(unwind.ximage->bytes_per_line *
1841 unwind.ximage->height);
1842
1843 if (unwind.ximage->data == (char *)NULL) {
1844 signal_simple_error("Unable to allocate XImage data information",
1845 instantiator);
1846 }
1847
1848
1849 /*
1850 ** First pull out all of the colors used, and create a lookup for them
1851 */
1852
1853 if (unwind.image->class == PseudoClass) {
1854 int i;
1855
1856 unwind.npixels = unwind.image->colors;
1857 unwind.pixels = xmalloc(unwind.npixels * sizeof(unsigned long));
1858 for (i = 0; i < unwind.npixels; i++) {
1859 XColor color;
1860 /* ImageMagic uses 8bit values for colors, whilst X expects 16bits */
1861 color.red = unwind.image->colormap[i].red << 8;
1862 color.green = unwind.image->colormap[i].green << 8;
1863 color.blue = unwind.image->colormap[i].blue << 8;
1864 color.flags = DoRed | DoGreen | DoBlue;
1865 allocate_nearest_color (dpy, cmap, visual, &color);
1866 unwind.pixels[i] = color.pixel;
1867 }
1868 }
1869
1870 /*
1871 ** Need to pull the data from the 'Image' structure in
1872 ** unwind.image and convert it to an 'XImage' in unwind.ximage
1873 */
1874 {
1875 int i,j,x,b;
1876 unsigned int bytes_per_pixel, scanline_pad;
1877 unsigned long pixval;
1878 unsigned char *q;
1879 RunlengthPacket *p;
1880
1881 q = (unsigned char *) unwind.ximage->data;
1882 x = 0;
1883 p = unwind.image->pixels;
1884 scanline_pad = unwind.ximage->bytes_per_line -
1885 ((unwind.ximage->width * unwind.ximage->bits_per_pixel) >> 3);
1886
1887 /* Convert to multi-byte color-mapped X image. */
1888 bytes_per_pixel=unwind.ximage->bits_per_pixel >> 3;
1889
1890 for (i=0; i < unwind.image->packets; i++) {
1891 if (unwind.image->class == PseudoClass)
1892 pixval = unwind.pixels[p->index];
1893 else
1757 { 1894 {
1758 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); 1895 /* ### NOW what? */
1759 1896 pixval = 0;
1760 assert (!NILP (data));
1761
1762 write_lisp_string_to_temp_file (data, unwind.tempfile);
1763 unwind.tempfile_needs_to_be_removed = 1;
1764
1765 if ((unwind.instream = fopen (unwind.tempfile, "rb")) == NULL)
1766 report_file_error ("Opening ImageMagick temp file",
1767 list1 (build_string (unwind.tempfile)));
1768 } 1897 }
1769 1898
1770 /* Initialize structures and read in the image */ 1899 for (j=0; j <= ((int) p->length); j++) {
1771 GetImageInfo(&image_info); 1900 for (b=0; b < bytes_per_pixel; b++)
1772 strcpy(image_info.filename,unwind.tempfile); 1901 *q++=(unsigned char) (pixval >> (8*b));
1773 unwind.image = ReadImage(&image_info); 1902 x++;
1774 if (unwind.image == (Image *) NULL) { 1903 if (x == unwind.ximage->width) {
1775 signal_simple_error ("Unable to read image.",instantiator); 1904 x=0;
1905 q+=scanline_pad;
1776 } 1906 }
1777 1907 }
1778 #if 1 1908 p++;
1779 DescribeImage(unwind.image,stderr,1); 1909 }
1780 #endif 1910 }
1781 1911
1782 unwind.ximage = XCreateImage(dpy, visual, depth, 1912 init_image_instance_from_x_image (ii, unwind.ximage, dest_mask,
1783 (depth == 1) ? XYPixmap : ZPixmap, 1913 unwind.pixels, unwind.npixels,
1784 0, 0, 1914 instantiator);
1785 unwind.image->columns, 1915
1786 unwind.image->rows, 1916 /* And we are done!
1787 XBitmapPad(dpy), 0); 1917 ** Now that we've succeeded, we don't want the pixels
1788 1918 ** freed right now. They're kept around in the image instance
1789 if (!unwind.ximage) { 1919 ** structure until it's destroyed.
1790 signal_simple_error("Unable to allocate XImage structure", 1920 */
1791 instantiator); 1921 unwind.npixels = 0;
1792 } 1922 unbind_to (speccount, Qnil);
1793
1794 unwind.ximage->data = (char *) xmalloc(unwind.ximage->bytes_per_line *
1795 unwind.ximage->height *
1796 unwind.ximage->depth);
1797
1798 if (unwind.ximage->data == (char *)NULL) {
1799 signal_simple_error("Unable to allocate pixel information",
1800 instantiator);
1801 }
1802
1803 /* Need to pull the data from the 'Image' structure in
1804 ** unwind.image and convert it to an 'XImage' in unwind.ximage
1805 **
1806 ** FIXME IM FUCKED
1807 **
1808 ** WMP 10/30/97
1809 */
1810
1811 {
1812 int i,j,x;
1813 unsigned int bytes_per_pixel, scanline_pad;
1814 unsigned char *q;
1815 RunlengthPacket *p;
1816 XColor color;
1817
1818 unwind.npixels = unwind.image->total_colors;
1819 unwind.pixels = xmalloc(unwind.npixels * sizeof(unsigned long));
1820 q = (unsigned char *) unwind.ximage->data;
1821 x = 0;
1822 memset(unwind.pixels,0,unwind.npixels * sizeof(unsigned long));
1823 p = unwind.image->pixels;
1824 scanline_pad = unwind.ximage->bytes_per_line -
1825 ((unwind.ximage->width * unwind.ximage->bits_per_pixel) >> 3);
1826
1827 /* Convert to multi-byte color-mapped X image. */
1828 bytes_per_pixel=unwind.ximage->bits_per_pixel >> 3;
1829
1830 #if 1
1831 for (i=0; i < unwind.image->packets; i++)
1832 {
1833 color.red = p->red;
1834 color.green = p->green;
1835 color.blue = p->blue;
1836 color.flags = DoRed | DoGreen | DoBlue;
1837 allocate_nearest_color (dpy, DefaultColormapOfScreen (scr), visual, &color);
1838 unwind.pixels[i] = color.pixel;
1839
1840 for (j=0; j <= ((int) p->length); j++)
1841 {
1842 *q++=(unsigned char) color.pixel;
1843 x++;
1844 if (x == unwind.ximage->width)
1845 {
1846 x=0;
1847 q+=scanline_pad;
1848 }
1849 }
1850 p++;
1851 }
1852 #else
1853 for (i=0; i < unwind.image->packets; i++)
1854 {
1855 pixel = unwind.pixels[p->index];
1856 for (k=0; k < bytes_per_pixel; k++)
1857 {
1858 channel[k]=(unsigned char) pixel;
1859 pixel>>=8;
1860 }
1861 for (j=0; j <= ((int) p->length); j++)
1862 {
1863 for (k=0; k < bytes_per_pixel; k++)
1864 *q++=channel[k];
1865 x++;
1866 if (x == unwind.ximage->width)
1867 {
1868 x=0;
1869 q+=scanline_pad;
1870 }
1871 }
1872 p++;
1873 }
1874 #endif
1875 }
1876
1877 init_image_instance_from_x_image (ii, unwind.ximage, dest_mask,
1878 unwind.pixels, unwind.npixels,
1879 instantiator);
1880
1881 /* And we are done!
1882 ** Now that we've succeeded, we don't want the pixels
1883 ** freed right now. They're kept around in the image instance
1884 ** structure until it's destroyed.
1885 */
1886 unwind.npixels = 0;
1887 unbind_to (speccount, Qnil);
1888 } 1923 }
1889 1924
1890 #endif /* HAVE_IMAGEMAGICK */ 1925 #endif /* HAVE_IMAGEMAGICK */
1891 1926
1892 1927
2802 IIFORMAT_HAS_METHOD (imagick, possible_dest_types); 2837 IIFORMAT_HAS_METHOD (imagick, possible_dest_types);
2803 IIFORMAT_HAS_METHOD (imagick, instantiate); 2838 IIFORMAT_HAS_METHOD (imagick, instantiate);
2804 2839
2805 IIFORMAT_VALID_KEYWORD (imagick, Q_data, check_valid_string); 2840 IIFORMAT_VALID_KEYWORD (imagick, Q_data, check_valid_string);
2806 IIFORMAT_VALID_KEYWORD (imagick, Q_file, check_valid_string); 2841 IIFORMAT_VALID_KEYWORD (imagick, Q_file, check_valid_string);
2842
2843 #ifdef OLDCOMPAT /* old graphics compatibility */
2844 #define IIFORMAT_USES_METHOD(format, source, m) \
2845 (format##_image_instantiator_methods->m##_method = source##_##m)
2846
2847 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff");
2848 IIFORMAT_USES_METHOD (tiff, imagick, validate);
2849 IIFORMAT_USES_METHOD (tiff, imagick, normalize);
2850 IIFORMAT_USES_METHOD (tiff, imagick, possible_dest_types);
2851 IIFORMAT_USES_METHOD (tiff, imagick, instantiate);
2852 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string);
2853 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string);
2854
2855 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png");
2856 IIFORMAT_USES_METHOD (png, imagick, validate);
2857 IIFORMAT_USES_METHOD (png, imagick, normalize);
2858 IIFORMAT_USES_METHOD (png, imagick, possible_dest_types);
2859 IIFORMAT_USES_METHOD (png, imagick, instantiate);
2860 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string);
2861 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string);
2862
2863 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif");
2864 IIFORMAT_USES_METHOD (gif, imagick, validate);
2865 IIFORMAT_USES_METHOD (gif, imagick, normalize);
2866 IIFORMAT_USES_METHOD (gif, imagick, possible_dest_types);
2867 IIFORMAT_USES_METHOD (gif, imagick, instantiate);
2868 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string);
2869 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string);
2870
2871 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg");
2872 IIFORMAT_USES_METHOD (jpeg, imagick, validate);
2873 IIFORMAT_USES_METHOD (jpeg, imagick, normalize);
2874 IIFORMAT_USES_METHOD (jpeg, imagick, possible_dest_types);
2875 IIFORMAT_USES_METHOD (jpeg, imagick, instantiate);
2876 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string);
2877 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string);
2878
2879 #endif /* old compat */
2880
2807 #endif 2881 #endif
2808 2882
2809 #ifdef HAVE_XPM 2883 #ifdef HAVE_XPM
2810 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xpm, "xpm"); 2884 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xpm, "xpm");
2811 2885
2866 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */ 2940 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */
2867 #endif 2941 #endif
2868 2942
2869 #ifdef HAVE_IMAGEMAGICK 2943 #ifdef HAVE_IMAGEMAGICK
2870 Fprovide (Qimagick); 2944 Fprovide (Qimagick);
2945
2946 #ifdef OLDCOMPAT
2947 Fprovide (Qtiff);
2948 Fprovide (Qpng);
2949 Fprovide (Qgif);
2950 Fprovide (Qjpeg);
2951 #endif
2871 #endif 2952 #endif
2872 2953
2873 #ifdef HAVE_XFACE 2954 #ifdef HAVE_XFACE
2874 Fprovide (Qxface); 2955 Fprovide (Qxface);
2875 #endif 2956 #endif