Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/src/glyphs-x.c Mon Aug 13 10:09:36 2007 +0200 +++ b/src/glyphs-x.c Mon Aug 13 10:10:02 2007 +0200 @@ -60,6 +60,8 @@ #include <magick/magick.h> /*#include <image.h>*/ #include <assert.h> + +#define OLDCOMPAT /* allow lisp code using the old names to still function */ #endif #define LISP_DEVICE_TO_X_SCREEN(dev) \ @@ -85,6 +87,17 @@ #ifdef HAVE_IMAGEMAGICK DEFINE_IMAGE_INSTANTIATOR_FORMAT (imagick); Lisp_Object Qimagick; + +#ifdef OLDCOMPAT /* old compatibility */ +DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff); +DEFINE_IMAGE_INSTANTIATOR_FORMAT (png); +DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif); +DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg); +Lisp_Object Qtiff; +Lisp_Object Qpng; +Lisp_Object Qgif; +Lisp_Object Qjpeg; +#endif #endif DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); @@ -1680,8 +1693,8 @@ struct imagick_unwind_data { - /* FIXME - what goes here...*/ Display *dpy; + Colormap cmap; FILE *instream; Image *image; XImage *ximage; @@ -1707,15 +1720,18 @@ DestroyImage(data->image); } - if (data->ximage) - { - if (data->ximage->data) - { + if (data->ximage) { + if (data->ximage->data) { xfree (data->ximage->data); data->ximage->data = NULL; } XDestroyImage (data->ximage); } + + if (data->npixels > 0) { + XFreeColors(data->dpy, data->cmap, data->pixels, data->npixels, 0L); + xfree (data->pixels); + } return Qnil; } @@ -1725,166 +1741,185 @@ Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - Display *dpy; - Screen *scr; - Visual *visual; - Dimension depth; - struct imagick_unwind_data unwind; - int speccount = specpdl_depth (); - ImageInfo image_info; - - /* ImageMagick variables */ - - /* Basic error checking */ - if (!DEVICE_X_P (XDEVICE (device))) - signal_simple_error ("Not an X device", device); - - dpy = DEVICE_X_DISPLAY (XDEVICE (device)); - scr = DefaultScreenOfDisplay (dpy); - depth = DEVICE_X_DEPTH (XDEVICE (device)); - visual = DEVICE_X_VISUAL (XDEVICE (device)); - - /* Set up the unwind */ - memset (&unwind, 0, sizeof (unwind)); - unwind.dpy = dpy; - record_unwind_protect(imagick_instantiate_unwind,make_opaque_ptr(&unwind)); - - /* Write out to a temp file - not sure if ImageMagick supports the - ** notion of an abstrat 'data source' right now. - */ - { - Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); - - assert (!NILP (data)); - - write_lisp_string_to_temp_file (data, unwind.tempfile); - unwind.tempfile_needs_to_be_removed = 1; - - if ((unwind.instream = fopen (unwind.tempfile, "rb")) == NULL) - report_file_error ("Opening ImageMagick temp file", - list1 (build_string (unwind.tempfile))); - } - - /* Initialize structures and read in the image */ - GetImageInfo(&image_info); - strcpy(image_info.filename,unwind.tempfile); - unwind.image = ReadImage(&image_info); - if (unwind.image == (Image *) NULL) { - signal_simple_error ("Unable to read image.",instantiator); - } + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); + Display *dpy; + Screen *scr; + Visual *visual; + Colormap cmap; + Dimension depth; + struct imagick_unwind_data unwind; + int speccount = specpdl_depth (); + ImageInfo image_info; + + /* ImageMagick variables */ + + /* Basic error checking */ + if (!DEVICE_X_P (XDEVICE (device))) + signal_simple_error ("Not an X device", device); + + dpy = DEVICE_X_DISPLAY (XDEVICE (device)); + scr = DefaultScreenOfDisplay (dpy); + depth = DEVICE_X_DEPTH (XDEVICE (device)); + visual = DEVICE_X_VISUAL (XDEVICE (device)); + cmap = DEVICE_X_COLORMAP (XDEVICE(device)); + + /* Set up the unwind */ + memset (&unwind, 0, sizeof (unwind)); + unwind.dpy = dpy; + unwind.cmap = cmap; + record_unwind_protect(imagick_instantiate_unwind,make_opaque_ptr(&unwind)); + + /* Write out to a temp file - not sure if ImageMagick supports the + ** notion of an abstract 'data source' right now. + ** JH: It doesn't as of 3.9.3 + */ + { + Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); + + assert (!NILP (data)); + + write_lisp_string_to_temp_file (data, unwind.tempfile); + unwind.tempfile_needs_to_be_removed = 1; + + if ((unwind.instream = fopen (unwind.tempfile, "rb")) == NULL) + report_file_error ("Opening ImageMagick temp file", + list1 (build_string (unwind.tempfile))); + } + + /* Initialize structures and read in the image */ + GetImageInfo(&image_info); + strcpy(image_info.filename,unwind.tempfile); + unwind.image = ReadImage(&image_info); + + if (unwind.image == (Image *) NULL) { + signal_simple_error ("Unable to read image.",instantiator); + } #if 1 - DescribeImage(unwind.image,stderr,1); + /* + * For now, force dithering everything, and deal with all images as if they + * were PseudoClass images + */ + if (unwind.image->class != PseudoClass) { + QuantizeInfo quantize_info; + GetQuantizeInfo(&quantize_info); + quantize_info.number_colors=256; + quantize_info.tree_depth=8; + quantize_info.dither=True; + quantize_info.colorspace=RGBColorspace; + QuantizeImage(&quantize_info, unwind.image); + SyncImage(unwind.image); + /* #### It would probably be a good idea to sort the colormap by popularity, + * so that in case we run out of entries in the map, it will likely be on + * the less used colors + */ + } else { + CompressColormap(unwind.image); + SyncImage(unwind.image); + } + +#endif + +#if 0 + DescribeImage(unwind.image,stderr,1); #endif - unwind.ximage = XCreateImage(dpy, visual, depth, - (depth == 1) ? XYPixmap : ZPixmap, - 0, 0, - unwind.image->columns, - unwind.image->rows, - XBitmapPad(dpy), 0); - - if (!unwind.ximage) { - signal_simple_error("Unable to allocate XImage structure", - instantiator); - } - - unwind.ximage->data = (char *) xmalloc(unwind.ximage->bytes_per_line * - unwind.ximage->height * - unwind.ximage->depth); - - if (unwind.ximage->data == (char *)NULL) { - signal_simple_error("Unable to allocate pixel information", - instantiator); - } - - /* Need to pull the data from the 'Image' structure in - ** unwind.image and convert it to an 'XImage' in unwind.ximage - ** - ** FIXME IM FUCKED - ** - ** WMP 10/30/97 - */ - + unwind.ximage = XCreateImage(dpy, visual, depth, + (depth == 1) ? XYPixmap : ZPixmap, + 0, 0, + unwind.image->columns, + unwind.image->rows, + XBitmapPad(dpy), 0); + + if (!unwind.ximage) { + signal_simple_error("Unable to allocate XImage structure", + instantiator); + } + + unwind.ximage->data = (char *) xmalloc(unwind.ximage->bytes_per_line * + unwind.ximage->height); + + if (unwind.ximage->data == (char *)NULL) { + signal_simple_error("Unable to allocate XImage data information", + instantiator); + } + + + /* + ** First pull out all of the colors used, and create a lookup for them + */ + + if (unwind.image->class == PseudoClass) { + int i; + + unwind.npixels = unwind.image->colors; + unwind.pixels = xmalloc(unwind.npixels * sizeof(unsigned long)); + for (i = 0; i < unwind.npixels; i++) { + XColor color; + /* ImageMagic uses 8bit values for colors, whilst X expects 16bits */ + color.red = unwind.image->colormap[i].red << 8; + color.green = unwind.image->colormap[i].green << 8; + color.blue = unwind.image->colormap[i].blue << 8; + color.flags = DoRed | DoGreen | DoBlue; + allocate_nearest_color (dpy, cmap, visual, &color); + unwind.pixels[i] = color.pixel; + } + } + + /* + ** Need to pull the data from the 'Image' structure in + ** unwind.image and convert it to an 'XImage' in unwind.ximage + */ + { + int i,j,x,b; + unsigned int bytes_per_pixel, scanline_pad; + unsigned long pixval; + unsigned char *q; + RunlengthPacket *p; + + q = (unsigned char *) unwind.ximage->data; + x = 0; + p = unwind.image->pixels; + scanline_pad = unwind.ximage->bytes_per_line - + ((unwind.ximage->width * unwind.ximage->bits_per_pixel) >> 3); + + /* Convert to multi-byte color-mapped X image. */ + bytes_per_pixel=unwind.ximage->bits_per_pixel >> 3; + + for (i=0; i < unwind.image->packets; i++) { + if (unwind.image->class == PseudoClass) + pixval = unwind.pixels[p->index]; + else { - int i,j,x; - unsigned int bytes_per_pixel, scanline_pad; - unsigned char *q; - RunlengthPacket *p; - XColor color; - - unwind.npixels = unwind.image->total_colors; - unwind.pixels = xmalloc(unwind.npixels * sizeof(unsigned long)); - q = (unsigned char *) unwind.ximage->data; - x = 0; - memset(unwind.pixels,0,unwind.npixels * sizeof(unsigned long)); - p = unwind.image->pixels; - scanline_pad = unwind.ximage->bytes_per_line - - ((unwind.ximage->width * unwind.ximage->bits_per_pixel) >> 3); - - /* Convert to multi-byte color-mapped X image. */ - bytes_per_pixel=unwind.ximage->bits_per_pixel >> 3; - -#if 1 - for (i=0; i < unwind.image->packets; i++) - { - color.red = p->red; - color.green = p->green; - color.blue = p->blue; - color.flags = DoRed | DoGreen | DoBlue; - allocate_nearest_color (dpy, DefaultColormapOfScreen (scr), visual, &color); - unwind.pixels[i] = color.pixel; - - for (j=0; j <= ((int) p->length); j++) - { - *q++=(unsigned char) color.pixel; - x++; - if (x == unwind.ximage->width) - { - x=0; - q+=scanline_pad; - } - } - p++; - } -#else - for (i=0; i < unwind.image->packets; i++) - { - pixel = unwind.pixels[p->index]; - for (k=0; k < bytes_per_pixel; k++) - { - channel[k]=(unsigned char) pixel; - pixel>>=8; - } - for (j=0; j <= ((int) p->length); j++) - { - for (k=0; k < bytes_per_pixel; k++) - *q++=channel[k]; - x++; - if (x == unwind.ximage->width) - { - x=0; - q+=scanline_pad; - } - } - p++; - } -#endif + /* ### NOW what? */ + pixval = 0; + } + + for (j=0; j <= ((int) p->length); j++) { + for (b=0; b < bytes_per_pixel; b++) + *q++=(unsigned char) (pixval >> (8*b)); + x++; + if (x == unwind.ximage->width) { + x=0; + q+=scanline_pad; } - - init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, - unwind.pixels, unwind.npixels, - instantiator); - - /* And we are done! - ** Now that we've succeeded, we don't want the pixels - ** freed right now. They're kept around in the image instance - ** structure until it's destroyed. - */ - unwind.npixels = 0; - unbind_to (speccount, Qnil); + } + p++; + } + } + + init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, + unwind.pixels, unwind.npixels, + instantiator); + + /* And we are done! + ** Now that we've succeeded, we don't want the pixels + ** freed right now. They're kept around in the image instance + ** structure until it's destroyed. + */ + unwind.npixels = 0; + unbind_to (speccount, Qnil); } #endif /* HAVE_IMAGEMAGICK */ @@ -2804,6 +2839,45 @@ IIFORMAT_VALID_KEYWORD (imagick, Q_data, check_valid_string); IIFORMAT_VALID_KEYWORD (imagick, Q_file, check_valid_string); + +#ifdef OLDCOMPAT /* old graphics compatibility */ +#define IIFORMAT_USES_METHOD(format, source, m) \ + (format##_image_instantiator_methods->m##_method = source##_##m) + + INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff"); + IIFORMAT_USES_METHOD (tiff, imagick, validate); + IIFORMAT_USES_METHOD (tiff, imagick, normalize); + IIFORMAT_USES_METHOD (tiff, imagick, possible_dest_types); + IIFORMAT_USES_METHOD (tiff, imagick, instantiate); + IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string); + IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string); + + INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png"); + IIFORMAT_USES_METHOD (png, imagick, validate); + IIFORMAT_USES_METHOD (png, imagick, normalize); + IIFORMAT_USES_METHOD (png, imagick, possible_dest_types); + IIFORMAT_USES_METHOD (png, imagick, instantiate); + IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string); + IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string); + + INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif"); + IIFORMAT_USES_METHOD (gif, imagick, validate); + IIFORMAT_USES_METHOD (gif, imagick, normalize); + IIFORMAT_USES_METHOD (gif, imagick, possible_dest_types); + IIFORMAT_USES_METHOD (gif, imagick, instantiate); + IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string); + IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string); + + INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg"); + IIFORMAT_USES_METHOD (jpeg, imagick, validate); + IIFORMAT_USES_METHOD (jpeg, imagick, normalize); + IIFORMAT_USES_METHOD (jpeg, imagick, possible_dest_types); + IIFORMAT_USES_METHOD (jpeg, imagick, instantiate); + IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string); + IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string); + +#endif /* old compat */ + #endif #ifdef HAVE_XPM @@ -2868,6 +2942,13 @@ #ifdef HAVE_IMAGEMAGICK Fprovide (Qimagick); + +#ifdef OLDCOMPAT + Fprovide (Qtiff); + Fprovide (Qpng); + Fprovide (Qgif); + Fprovide (Qjpeg); +#endif #endif #ifdef HAVE_XFACE