aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/obm/ObmW/HTMLimages.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/x11iraf/obm/ObmW/HTMLimages.c')
-rw-r--r--vendor/x11iraf/obm/ObmW/HTMLimages.c891
1 files changed, 891 insertions, 0 deletions
diff --git a/vendor/x11iraf/obm/ObmW/HTMLimages.c b/vendor/x11iraf/obm/ObmW/HTMLimages.c
new file mode 100644
index 00000000..fe33a6ee
--- /dev/null
+++ b/vendor/x11iraf/obm/ObmW/HTMLimages.c
@@ -0,0 +1,891 @@
+/****************************************************************************
+ * NCSA Mosaic for the X Window System *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * mosaic@ncsa.uiuc.edu *
+ * *
+ * Copyright (C) 1993, Board of Trustees of the University of Illinois *
+ * *
+ * NCSA Mosaic software, both binary and source (hereafter, Software) is *
+ * copyrighted by The Board of Trustees of the University of Illinois *
+ * (UI), and ownership remains with the UI. *
+ * *
+ * The UI grants you (hereafter, Licensee) a license to use the Software *
+ * for academic, research and internal business purposes only, without a *
+ * fee. Licensee may distribute the binary and source code (if released) *
+ * to third parties provided that the copyright notice and this statement *
+ * appears on all copies and that no charge is associated with such *
+ * copies. *
+ * *
+ * Licensee may make derivative works. However, if Licensee distributes *
+ * any derivative work based on or derived from the Software, then *
+ * Licensee will (1) notify NCSA regarding its distribution of the *
+ * derivative work, and (2) clearly notify users that such derivative *
+ * work is a modified version and not the original NCSA Mosaic *
+ * distributed by the UI. *
+ * *
+ * Any Licensee wishing to make commercial use of the Software should *
+ * contact the UI, c/o NCSA, to negotiate an appropriate license for such *
+ * commercial use. Commercial use includes (1) integration of all or *
+ * part of the source code into a product for sale or license by or on *
+ * behalf of Licensee to third parties, or (2) distribution of the binary *
+ * code or source code to third parties that need it to utilize a *
+ * commercial product sold or licensed by or on behalf of Licensee. *
+ * *
+ * UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR *
+ * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED *
+ * WARRANTY. THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE *
+ * USERS OF THIS SOFTWARE. *
+ * *
+ * By using or copying this Software, Licensee agrees to abide by the *
+ * copyright law and all other applicable laws of the U.S. including, but *
+ * not limited to, export control laws, and the terms of this license. *
+ * UI shall have the right to terminate this license immediately by *
+ * written notice upon Licensee's breach of, or non-compliance with, any *
+ * of its terms. Licensee may be held legally responsible for any *
+ * copyright infringement that is caused or encouraged by Licensee's *
+ * failure to abide by the terms of this license. *
+ * *
+ * Comments and questions are welcome and can be sent to *
+ * mosaic-x@ncsa.uiuc.edu. *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+#include "HTMLP.h"
+#include "bitmaps/NoImage.xbm"
+#include "bitmaps/DelayedImage.xbm"
+#include "bitmaps/AnchoredImage.xbm"
+
+
+#define IMAGE_BORDER 2
+
+
+ImageInfo no_image;
+ImageInfo delayed_image;
+ImageInfo anchored_image;
+
+static int allocation_index[256];
+
+
+/*
+ * Free all the colors in the default colormap that we have allocated so far.
+ */
+void
+FreeColors(dsp, colormap)
+ Display *dsp;
+ Colormap colormap;
+{
+ int i, j;
+ unsigned long pix;
+
+ for (i=0; i<256; i++)
+ {
+ if (allocation_index[i])
+ {
+ pix = (unsigned long)i;
+ /*
+ * Because X is stupid, we have to Free the color
+ * once for each time we've allocated it.
+ */
+ for (j=0; j<allocation_index[i]; j++)
+ {
+ XFreeColors(dsp, colormap, &pix, 1, 0L);
+ }
+ }
+ allocation_index[i] = 0;
+ }
+}
+
+
+/*
+ * Free up all the pixmaps allocated for this document.
+ */
+void
+FreeImages(hw)
+ HTMLWidget hw;
+{
+ struct ele_rec *eptr;
+
+ eptr = hw->html.formatted_elements;
+ while (eptr != NULL)
+ {
+ if ((eptr->type == E_IMAGE)&&(eptr->pic_data != NULL))
+ {
+ /*
+ * Don't free the no_image default image
+ */
+ if ((eptr->pic_data->image != (Pixmap)NULL)&&
+ (eptr->pic_data->image != delayed_image.image)&&
+ (eptr->pic_data->image != anchored_image.image)&&
+ (eptr->pic_data->image != no_image.image))
+ {
+ /*
+ * Don't free internal images
+ */
+ if ((eptr->edata != NULL)&&
+ (strncmp(eptr->edata, INTERNAL_IMAGE,
+ strlen(INTERNAL_IMAGE)) == 0))
+ {
+ }
+ else
+ {
+ XFreePixmap(XtDisplay(hw),
+ eptr->pic_data->image);
+ eptr->pic_data->image = (Pixmap)NULL;
+ }
+ }
+ }
+ eptr = eptr->next;
+ }
+}
+
+
+/*
+ * Find the closest color by allocating it, or picking an already allocated
+ * color
+ */
+void
+FindColor(dsp, colormap, colr)
+ Display *dsp;
+ Colormap colormap;
+ XColor *colr;
+{
+ int i, match;
+#ifdef MORE_ACCURATE
+ double rd, gd, bd, dist, mindist;
+#else
+ int rd, gd, bd, dist, mindist;
+#endif /* MORE_ACCURATE */
+ int cindx;
+static XColor def_colrs[256];
+static int have_colors = 0;
+ int NumCells;
+
+ match = XAllocColor(dsp, colormap, colr);
+ if (match == 0)
+ {
+ NumCells = DisplayCells(dsp, DefaultScreen(dsp));
+ if (!have_colors)
+ {
+ for (i=0; i<NumCells; i++)
+ {
+ def_colrs[i].pixel = i;
+ }
+ XQueryColors(dsp, colormap, def_colrs, NumCells);
+ have_colors = 1;
+ }
+#ifdef MORE_ACCURATE
+ mindist = 196608.0; /* 256.0 * 256.0 * 3.0 */
+ cindx = colr->pixel;
+ for (i=0; i<NumCells; i++)
+ {
+ rd = (def_colrs[i].red - colr->red) / 256.0;
+ gd = (def_colrs[i].green - colr->green) / 256.0;
+ bd = (def_colrs[i].blue - colr->blue) / 256.0;
+ dist = (rd * rd) +
+ (gd * gd) +
+ (bd * bd);
+ if (dist < mindist)
+ {
+ mindist = dist;
+ cindx = def_colrs[i].pixel;
+ if (dist == 0.0)
+ {
+ break;
+ }
+ }
+ }
+#else
+ mindist = 196608; /* 256 * 256 * 3 */
+ cindx = colr->pixel;
+ for (i=0; i<NumCells; i++)
+ {
+ rd = ((int)(def_colrs[i].red >> 8) -
+ (int)(colr->red >> 8));
+ gd = ((int)(def_colrs[i].green >> 8) -
+ (int)(colr->green >> 8));
+ bd = ((int)(def_colrs[i].blue >> 8) -
+ (int)(colr->blue >> 8));
+ dist = (rd * rd) +
+ (gd * gd) +
+ (bd * bd);
+ if (dist < mindist)
+ {
+ mindist = dist;
+ cindx = def_colrs[i].pixel;
+ if (dist == 0)
+ {
+ break;
+ }
+ }
+ }
+#endif /* MORE_ACCURATE */
+ colr->pixel = cindx;
+ colr->red = def_colrs[cindx].red;
+ colr->green = def_colrs[cindx].green;
+ colr->blue = def_colrs[cindx].blue;
+ }
+ else
+ {
+ /*
+ * Keep a count of how many times we have allocated the
+ * same color, so we can properly free them later.
+ */
+ allocation_index[colr->pixel]++;
+
+ /*
+ * If this is a new color, we've actually changed the default
+ * colormap, and may have to re-query it later.
+ */
+ if (allocation_index[colr->pixel] == 1)
+ {
+ have_colors = 0;
+ }
+ }
+}
+
+
+static int
+highbit(ul)
+unsigned long ul;
+{
+ /*
+ * returns position of highest set bit in 'ul' as an integer (0-31),
+ * or -1 if none.
+ */
+
+ int i;
+ for (i=31; ((ul&0x80000000) == 0) && i>=0; i--, ul<<=1);
+ return i;
+}
+
+
+/*
+ * Make am image of appropriate depth for display from image data.
+ */
+XImage *
+MakeImage(dsp, data, width, height, depth, img_info)
+ Display *dsp;
+ unsigned char *data;
+ int width, height;
+ int depth;
+ ImageInfo *img_info;
+{
+ int linepad, shiftnum;
+ int shiftstart, shiftstop, shiftinc;
+ int bytesperline;
+ int temp;
+ int w, h;
+ XImage *newimage;
+ unsigned char *bit_data, *bitp, *datap;
+ Visual *theVisual;
+ int bmap_order;
+ unsigned long c;
+ int rshift, gshift, bshift;
+
+ switch(depth)
+ {
+ case 6:
+ case 8:
+ bit_data = (unsigned char *)malloc(width * height);
+ bcopy(data, bit_data, (width * height));
+ bytesperline = width;
+ newimage = XCreateImage(dsp,
+ DefaultVisual(dsp, DefaultScreen(dsp)),
+ depth, ZPixmap, 0, (char *)bit_data,
+ width, height, 8, bytesperline);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ if (BitmapBitOrder(dsp) == LSBFirst)
+ {
+ shiftstart = 0;
+ shiftstop = 8;
+ shiftinc = depth;
+ }
+ else
+ {
+ shiftstart = 8 - depth;
+ shiftstop = -depth;
+ shiftinc = -depth;
+ }
+ linepad = 8 - (width % 8);
+ bit_data = (unsigned char *)malloc(((width + linepad) * height)
+ + 1);
+ bitp = bit_data;
+ datap = data;
+ *bitp = 0;
+ shiftnum = shiftstart;
+ for (h=0; h<height; h++)
+ {
+ for (w=0; w<width; w++)
+ {
+ temp = *datap++ << shiftnum;
+ *bitp = *bitp | temp;
+ shiftnum = shiftnum + shiftinc;
+ if (shiftnum == shiftstop)
+ {
+ shiftnum = shiftstart;
+ bitp++;
+ *bitp = 0;
+ }
+ }
+ for (w=0; w<linepad; w++)
+ {
+ shiftnum = shiftnum + shiftinc;
+ if (shiftnum == shiftstop)
+ {
+ shiftnum = shiftstart;
+ bitp++;
+ *bitp = 0;
+ }
+ }
+ }
+ bytesperline = (width + linepad) * depth / 8;
+ newimage = XCreateImage(dsp,
+ DefaultVisual(dsp, DefaultScreen(dsp)),
+ depth, ZPixmap, 0, (char *)bit_data,
+ (width + linepad), height, 8, bytesperline);
+ break;
+ /*
+ * WARNING: This depth 16 code is donated code for 16 but
+ * TrueColor displays. I have no access to such displays, so I
+ * can't really test it.
+ * Donated by - andrew@icarus.demon.co.uk
+ */
+ case 16:
+ bit_data = (unsigned char *)malloc(width * height * 2);
+ bitp = bit_data;
+ datap = data;
+ for (w = (width * height); w > 0; w--)
+ {
+ temp = (((img_info->reds[(int)*datap] >> 1)& 0x7c00) |
+ ((img_info->greens[(int)*datap] >> 6)& 0x03e0) |
+ ((img_info->blues[(int)*datap] >> 11)& 0x001f));
+
+ if (BitmapBitOrder(dsp) == MSBFirst)
+ {
+ *bitp++ = (temp >> 8) & 0xff;
+ *bitp++ = temp & 0xff;
+ }
+ else
+ {
+ *bitp++ = temp & 0xff;
+ *bitp++ = (temp >> 8) & 0xff;
+ }
+
+ datap++;
+ }
+
+ newimage = XCreateImage(dsp,
+ DefaultVisual(dsp, DefaultScreen(dsp)),
+ depth, ZPixmap, 0, (char *)bit_data,
+ width, height, 16, 0);
+ break;
+ case 24:
+ bit_data = (unsigned char *)malloc(width * height * 4);
+
+ theVisual = DefaultVisual(dsp, DefaultScreen(dsp));
+ rshift = highbit(theVisual->red_mask) - 7;
+ gshift = highbit(theVisual->green_mask) - 7;
+ bshift = highbit(theVisual->blue_mask) - 7;
+ bmap_order = BitmapBitOrder(dsp);
+
+ bitp = bit_data;
+ datap = data;
+ for (w = (width * height); w > 0; w--)
+ {
+ c =
+ (((img_info->reds[(int)*datap] >> 8) & 0xff) << rshift) |
+ (((img_info->greens[(int)*datap] >> 8) & 0xff) << gshift) |
+ (((img_info->blues[(int)*datap] >> 8) & 0xff) << bshift);
+
+ datap++;
+
+ if (bmap_order == MSBFirst)
+ {
+ *bitp++ = (unsigned char)((c >> 24) & 0xff);
+ *bitp++ = (unsigned char)((c >> 16) & 0xff);
+ *bitp++ = (unsigned char)((c >> 8) & 0xff);
+ *bitp++ = (unsigned char)(c & 0xff);
+ }
+ else
+ {
+ *bitp++ = (unsigned char)(c & 0xff);
+ *bitp++ = (unsigned char)((c >> 8) & 0xff);
+ *bitp++ = (unsigned char)((c >> 16) & 0xff);
+ *bitp++ = (unsigned char)((c >> 24) & 0xff);
+ }
+ }
+
+ newimage = XCreateImage(dsp,
+ DefaultVisual(dsp, DefaultScreen(dsp)),
+ depth, ZPixmap, 0, (char *)bit_data,
+ width, height, 32, 0);
+ break;
+ default:
+ fprintf(stderr, "Don't know how to format image for display of depth %d\n", depth);
+ return(NULL);
+ }
+
+ return(newimage);
+}
+
+
+int
+AnchoredHeight(hw)
+ HTMLWidget hw;
+{
+ return((int)(AnchoredImage_height + IMAGE_BORDER));
+}
+
+
+char *
+IsMapForm(hw)
+ HTMLWidget hw;
+{
+ char *str;
+
+ str = (char *)malloc(strlen("ISMAP Form") + 1);
+ if (str != NULL)
+ {
+ strcpy(str, "ISMAP Form");
+ }
+ return(str);
+}
+
+
+int
+IsIsMapForm(hw, href)
+ HTMLWidget hw;
+ char *href;
+{
+ if ((href != NULL)&&(strcmp(href, "ISMAP Form") == 0))
+ {
+ return(1);
+ }
+ else
+ {
+ return(0);
+ }
+}
+
+
+char *
+DelayedHRef(hw)
+ HTMLWidget hw;
+{
+ char *str;
+
+ str = (char *)malloc(strlen("Delayed Image") + 1);
+ if (str != NULL)
+ {
+ strcpy(str, "Delayed Image");
+ }
+ return(str);
+}
+
+
+int
+IsDelayedHRef(hw, href)
+ HTMLWidget hw;
+ char *href;
+{
+ if ((href != NULL)&&(strcmp(href, "Delayed Image") == 0))
+ {
+ return(1);
+ }
+ else
+ {
+ return(0);
+ }
+}
+
+
+Pixmap
+DelayedImage(hw, anchored)
+ HTMLWidget hw;
+ Boolean anchored;
+{
+ if (delayed_image.image == (Pixmap)NULL)
+ {
+ delayed_image.image = XCreatePixmapFromBitmapData(
+ XtDisplay(hw->html.view),
+ XtWindow(hw->html.view), DelayedImage_bits,
+ DelayedImage_width, DelayedImage_height,
+/*
+ * Without motif we use our own foreground resource instead of
+ * using the manager's
+ */
+#ifdef MOTIF
+ hw->manager.foreground,
+#else
+ hw->html.foreground,
+#endif /* MOTIF */
+ hw->core.background_pixel,
+ DefaultDepthOfScreen(XtScreen(hw)));
+ }
+
+ if ((anchored == True)&&(anchored_image.image == (Pixmap)NULL))
+ {
+ Pixmap pix;
+
+ anchored_image.image = XCreatePixmapFromBitmapData(
+ XtDisplay(hw->html.view),
+ XtWindow(hw->html.view), AnchoredImage_bits,
+ AnchoredImage_width, AnchoredImage_height,
+/*
+ * Without motif we use our own foreground resource instead of
+ * using the manager's
+ */
+#ifdef MOTIF
+ hw->manager.foreground,
+#else
+ hw->html.foreground,
+#endif /* MOTIF */
+ hw->core.background_pixel,
+ DefaultDepthOfScreen(XtScreen(hw)));
+ pix = XCreatePixmap(
+ XtDisplay(hw->html.view),
+ XtWindow(hw->html.view),
+ DelayedImage_width,
+ (DelayedImage_height + AnchoredImage_height +
+ IMAGE_BORDER),
+ DefaultDepthOfScreen(XtScreen(hw)));
+ XSetForeground(XtDisplay(hw), hw->html.drawGC,
+ hw->core.background_pixel);
+ XFillRectangle(XtDisplay(hw->html.view), pix,
+ hw->html.drawGC, 0, 0,
+ DelayedImage_width,
+ (DelayedImage_height + AnchoredImage_height +
+ IMAGE_BORDER));
+ XCopyArea(XtDisplay(hw->html.view),
+ anchored_image.image, pix, hw->html.drawGC,
+ 0, 0, AnchoredImage_width, AnchoredImage_height,
+ 0, 0);
+ XCopyArea(XtDisplay(hw->html.view),
+ delayed_image.image, pix, hw->html.drawGC,
+ 0, 0, DelayedImage_width, DelayedImage_height,
+ 0, (AnchoredImage_height + IMAGE_BORDER));
+ XFreePixmap(XtDisplay(hw->html.view), anchored_image.image);
+ anchored_image.image = pix;
+
+ return(anchored_image.image);
+ }
+
+ return(delayed_image.image);
+}
+
+
+ImageInfo *
+DelayedImageData(hw, anchored)
+ HTMLWidget hw;
+ Boolean anchored;
+{
+ delayed_image.delayed = 1;
+ delayed_image.internal = 0;
+ delayed_image.fetched = 0;
+ delayed_image.width = DelayedImage_width;
+ delayed_image.height = DelayedImage_height;
+ delayed_image.num_colors = 0;
+ delayed_image.reds = NULL;
+ delayed_image.greens = NULL;
+ delayed_image.blues = NULL;
+ delayed_image.image_data = NULL;
+ delayed_image.image = (Pixmap)NULL;
+
+ if (anchored == True)
+ {
+ anchored_image.delayed = 0;
+ anchored_image.internal = 0;
+ anchored_image.fetched = 0;
+ anchored_image.width = DelayedImage_width;
+ anchored_image.height = DelayedImage_height +
+ AnchoredImage_height + IMAGE_BORDER;
+ anchored_image.num_colors = 0;
+ anchored_image.reds = NULL;
+ anchored_image.greens = NULL;
+ anchored_image.blues = NULL;
+ anchored_image.image_data = NULL;
+ anchored_image.image = (Pixmap)NULL;
+
+ return(&anchored_image);
+ }
+
+ return(&delayed_image);
+}
+
+
+Pixmap
+NoImage(hw)
+ HTMLWidget hw;
+{
+ if (no_image.image == (Pixmap)NULL)
+ {
+ no_image.image = XCreatePixmapFromBitmapData(
+ XtDisplay(hw->html.view),
+ XtWindow(hw->html.view), NoImage_bits,
+ NoImage_width, NoImage_height,
+/*
+ * Without motif we use our own foreground resource instead of
+ * using the manager's
+ */
+#ifdef MOTIF
+ hw->manager.foreground,
+#else
+ hw->html.foreground,
+#endif /* MOTIF */
+ hw->core.background_pixel,
+ DefaultDepthOfScreen(XtScreen(hw)));
+ }
+ return(no_image.image);
+}
+
+
+ImageInfo *
+NoImageData(hw)
+ HTMLWidget hw;
+{
+ no_image.delayed = 0;
+ no_image.internal = 0;
+ no_image.fetched = 0;
+ no_image.width = NoImage_width;
+ no_image.height = NoImage_height;
+ no_image.num_colors = 0;
+ no_image.reds = NULL;
+ no_image.greens = NULL;
+ no_image.blues = NULL;
+ no_image.image_data = NULL;
+ no_image.image = (Pixmap)NULL;
+
+ return(&no_image);
+}
+
+
+Pixmap
+InfoToImage(hw, img_info)
+ HTMLWidget hw;
+ ImageInfo *img_info;
+{
+ int i, size;
+ int delta, not_right_col, not_last_row;
+ Pixmap Img;
+ XImage *tmpimage;
+ XColor tmpcolr;
+ int *Mapping;
+ unsigned char *tmpdata;
+ unsigned char *ptr;
+ unsigned char *ptr2;
+ int Vclass;
+ XVisualInfo vinfo, *vptr;
+ Boolean need_to_dither;
+ unsigned long black_pixel;
+ unsigned long white_pixel;
+
+ /* find the visual class. */
+ vinfo.visualid = XVisualIDFromVisual(DefaultVisual(XtDisplay(hw),
+ DefaultScreen(XtDisplay(hw))));
+ vptr = XGetVisualInfo(XtDisplay(hw), VisualIDMask, &vinfo, &i);
+ Vclass = vptr->class;
+ if (vptr->depth == 1)
+ {
+ need_to_dither = True;
+ black_pixel = BlackPixel(XtDisplay(hw),
+ DefaultScreen(XtDisplay(hw)));
+ white_pixel = WhitePixel(XtDisplay(hw),
+ DefaultScreen(XtDisplay(hw)));
+ }
+ else
+ {
+ need_to_dither = False;
+ }
+ XFree((char *)vptr);
+
+ Mapping = (int *)malloc(img_info->num_colors * sizeof(int));
+
+ for (i=0; i < img_info->num_colors; i++)
+ {
+ tmpcolr.red = img_info->reds[i];
+ tmpcolr.green = img_info->greens[i];
+ tmpcolr.blue = img_info->blues[i];
+ tmpcolr.flags = DoRed|DoGreen|DoBlue;
+ if ((Vclass == TrueColor) || (Vclass == DirectColor))
+ {
+ Mapping[i] = i;
+ }
+ else if (need_to_dither == True)
+ {
+ Mapping[i] = (int)((tmpcolr.red>>5)*11 +
+ (tmpcolr.green>>5)*16 +
+ (tmpcolr.blue>>5)*5) / (65504/64);
+ }
+ else
+ {
+ FindColor(XtDisplay(hw),
+ DefaultColormapOfScreen(XtScreen(hw)),
+ &tmpcolr);
+ Mapping[i] = tmpcolr.pixel;
+ }
+ }
+
+ /*
+ * Special case: For 2 color non-black&white images, instead
+ * of 2 dither patterns, we will always drop them to be
+ * black on white.
+ */
+ if ((need_to_dither == True)&&(img_info->num_colors == 2))
+ {
+ if (Mapping[0] < Mapping[1])
+ {
+ Mapping[0] = 0;
+ Mapping[1] = 64;
+ }
+ else
+ {
+ Mapping[0] = 64;
+ Mapping[1] = 0;
+ }
+ }
+
+ size = img_info->width * img_info->height;
+ if (size == 0)
+ {
+ tmpdata = NULL;
+ }
+ else
+ {
+ tmpdata = (unsigned char *)malloc(size);
+ }
+ if (tmpdata == NULL)
+ {
+ tmpimage = NULL;
+ Img = (Pixmap)NULL;
+ }
+ else
+ {
+ ptr = img_info->image_data;
+ ptr2 = tmpdata;
+
+ if (need_to_dither == True)
+ {
+ int cx, cy;
+
+ for (ptr2 = tmpdata, ptr = img_info->image_data;
+ ptr2 < tmpdata+(size-1); ptr2++, ptr++)
+ {
+ *ptr2 = Mapping[(int)*ptr];
+ }
+
+ ptr2 = tmpdata;
+ for (cy=0; cy < img_info->height; cy++)
+ {
+ for (cx=0; cx < img_info->width; cx++)
+ {
+ /*
+ * Assume high numbers are
+ * really negative.
+ */
+ if (*ptr2 > 128)
+ {
+ *ptr2 = 0;
+ }
+ if (*ptr2 > 64)
+ {
+ *ptr2 = 64;
+ }
+
+ /*
+ * Traditional Floyd-Steinberg
+ */
+ if (*ptr2 < 32)
+ {
+ delta = *ptr2;
+ *ptr2 = black_pixel;
+ }
+ else
+ {
+ delta = *ptr2 - 64;
+ *ptr2 = white_pixel;
+ }
+ if (not_right_col =
+ (cx < (img_info->width-1)))
+ {
+ *(ptr2+1) += delta*7 >> 4;
+ }
+
+ if (not_last_row =
+ (cy < (img_info->height-1)))
+ {
+ (*(ptr2+img_info->width)) +=
+ delta*5 >> 4;
+ }
+
+ if (not_right_col && not_last_row)
+ {
+ (*(ptr2+img_info->width+1)) +=
+ delta >> 4;
+ }
+
+ if (cx && not_last_row)
+ {
+ (*(ptr2+img_info->width-1)) +=
+ delta*3 >> 4;
+ }
+ ptr2++;
+ }
+ }
+ } /* end if (need_to_dither==True) */
+ else
+ {
+
+ for (i=0; i < size; i++)
+ {
+ *ptr2++ = (unsigned char)Mapping[(int)*ptr];
+ ptr++;
+ }
+ }
+
+ tmpimage = MakeImage(XtDisplay(hw), tmpdata,
+ img_info->width, img_info->height,
+ DefaultDepthOfScreen(XtScreen(hw)), img_info);
+
+ /* Caught by Purify; should be OK. */
+ free (tmpdata);
+
+ Img = XCreatePixmap(XtDisplay(hw->html.view),
+ XtWindow(hw->html.view),
+ img_info->width, img_info->height,
+ DefaultDepthOfScreen(XtScreen(hw)));
+ }
+
+ if ((tmpimage == NULL)||(Img == (Pixmap)NULL))
+ {
+ if (tmpimage != NULL)
+ {
+ XDestroyImage(tmpimage);
+ }
+ if (Img != (Pixmap)NULL)
+ {
+ XFreePixmap(XtDisplay(hw), Img);
+ }
+ img_info->width = NoImage_width;
+ img_info->height = NoImage_height;
+ Img = NoImage(hw);
+ }
+ else
+ {
+ XPutImage(XtDisplay(hw), Img, hw->html.drawGC, tmpimage, 0, 0,
+ 0, 0, img_info->width, img_info->height);
+ XDestroyImage(tmpimage);
+ }
+
+ /* Caught by Purify; should be OK. */
+ free((char *)Mapping);
+
+ return(Img);
+}
+