ImUtil.c revision 57f47464
1/*
2
3Copyright 1986, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include <X11/Xlibint.h>
31#include <X11/Xutil.h>
32#include <stdio.h>
33#include "ImUtil.h"
34
35static int _XDestroyImage(XImage *);
36static unsigned long _XGetPixel(XImage *, int, int);
37static unsigned long _XGetPixel1(XImage *, int, int);
38static unsigned long _XGetPixel8(XImage *, int, int);
39static unsigned long _XGetPixel16(XImage *, int, int);
40static unsigned long _XGetPixel32(XImage *, int, int);
41static int _XPutPixel(XImage *, int, int, unsigned long);
42static int _XPutPixel1(XImage *, int, int, unsigned long);
43static int _XPutPixel8(XImage *, int, int, unsigned long);
44static int _XPutPixel16(XImage *, int, int, unsigned long);
45static int _XPutPixel32(XImage *, int, int, unsigned long);
46static XImage *_XSubImage(XImage *, int, int, unsigned int, unsigned int);
47static int _XAddPixel(XImage *, long);
48
49static unsigned char const _lomask[0x09] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
50static unsigned char const _himask[0x09] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 };
51
52/* These two convenience routines return the scanline_pad and bits_per_pixel
53	associated with a specific depth of ZPixmap format image for a
54	display. */
55
56int
57_XGetScanlinePad(
58 Display *dpy,
59 int depth)
60 {
61 	register ScreenFormat *fmt = dpy->pixmap_format;
62 	register int i;
63
64 	for (i = dpy->nformats + 1; --i; ++fmt)
65 		if (fmt->depth == depth)
66 			return(fmt->scanline_pad);
67
68 	return(dpy->bitmap_pad);
69 }
70
71int
72_XGetBitsPerPixel(
73 Display *dpy,
74 int depth)
75 {
76 	register ScreenFormat *fmt = dpy->pixmap_format;
77 	register int i;
78
79 	for (i = dpy->nformats + 1; --i; ++fmt)
80 		if (fmt->depth == depth)
81 			return(fmt->bits_per_pixel);
82	if (depth <= 4)
83	    return 4;
84	if (depth <= 8)
85	    return 8;
86	if (depth <= 16)
87	    return 16;
88	return 32;
89 }
90
91
92/*
93 * This module provides rudimentary manipulation routines for image data
94 * structures.  The functions provided are:
95 *
96 *	XCreateImage	Creates a default XImage data structure
97 *	_XDestroyImage	Deletes an XImage data structure
98 *	_XGetPixel	Reads a pixel from an image data structure
99 *	_XGetPixel32	Reads a pixel from a 32-bit Z image data structure
100 *	_XGetPixel16	Reads a pixel from a 16-bit Z image data structure
101 *	_XGetPixel8	Reads a pixel from an 8-bit Z image data structure
102 *	_XGetPixel1	Reads a pixel from an 1-bit image data structure
103 *	_XPutPixel	Writes a pixel into an image data structure
104 *	_XPutPixel32	Writes a pixel into a 32-bit Z image data structure
105 *	_XPutPixel16	Writes a pixel into a 16-bit Z image data structure
106 *	_XPutPixel8	Writes a pixel into an 8-bit Z image data structure
107 *	_XPutPixel1	Writes a pixel into an 1-bit image data structure
108 *	_XSubImage	Clones a new (sub)image from an existing one
109 *	_XSetImage	Writes an image data pattern into another image
110 *	_XAddPixel	Adds a constant value to every pixel in an image
111 *
112 * The logic contained in these routines makes several assumptions about
113 * the image data structures, and at least for current implementations
114 * these assumptions are believed to be true.  They are:
115 *
116 *	For all formats, bits_per_pixel is less than or equal to 32.
117 *	For XY formats, bitmap_unit is always less than or equal to bitmap_pad.
118 *	For XY formats, bitmap_unit is 8, 16, or 32 bits.
119 *	For Z format, bits_per_pixel is 1, 4, 8, 16, 24, or 32 bits.
120 */
121static void _xynormalizeimagebits (
122    register unsigned char *bp,
123    register XImage *img)
124{
125	register unsigned char c;
126
127	if (img->byte_order != img->bitmap_bit_order) {
128	    switch (img->bitmap_unit) {
129
130		case 16:
131		    c = *bp;
132		    *bp = *(bp + 1);
133		    *(bp + 1) = c;
134		    break;
135
136		case 32:
137		    c = *(bp + 3);
138		    *(bp + 3) = *bp;
139		    *bp = c;
140		    c = *(bp + 2);
141		    *(bp + 2) = *(bp + 1);
142		    *(bp + 1) = c;
143		    break;
144	    }
145	}
146	if (img->bitmap_bit_order == MSBFirst)
147	    _XReverse_Bytes (bp, img->bitmap_unit >> 3);
148}
149
150static void _znormalizeimagebits (
151    register unsigned char *bp,
152    register XImage *img)
153{
154	register unsigned char c;
155	switch (img->bits_per_pixel) {
156
157	    case 4:
158		*bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
159		break;
160
161	    case 16:
162		c = *bp;
163		*bp = *(bp + 1);
164		*(bp + 1) = c;
165		break;
166
167	    case 24:
168		c = *(bp + 2);
169		*(bp + 2) = *bp;
170		*bp = c;
171		break;
172
173	    case 32:
174		c = *(bp + 3);
175		*(bp + 3) = *bp;
176		*bp = c;
177		c = *(bp + 2);
178		*(bp + 2) = *(bp + 1);
179		*(bp + 1) = c;
180		break;
181	}
182}
183
184static void _putbits(
185    register char *src,	/* address of source bit string */
186    int dstoffset,	/* bit offset into destination; range is 0-31 */
187    register int numbits,/* number of bits to copy to destination */
188    register char *dst)	/* address of destination bit string */
189{
190	register unsigned char chlo, chhi;
191	int hibits;
192	dst = dst + (dstoffset >> 3);
193	dstoffset = dstoffset & 7;
194	hibits = 8 - dstoffset;
195	chlo = *dst & _lomask[dstoffset];
196	for (;;) {
197	    chhi = (*src << dstoffset) & _himask[dstoffset];
198	    if (numbits <= hibits) {
199		chhi = chhi & _lomask[dstoffset + numbits];
200		*dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
201		break;
202	    }
203	    *dst = chhi | chlo;
204	    dst++;
205	    numbits = numbits - hibits;
206	    chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
207	    src++;
208	    if (numbits <= dstoffset) {
209		chlo = chlo & _lomask[numbits];
210		*dst = (*dst & _himask[numbits]) | chlo;
211		break;
212	    }
213	    numbits = numbits - dstoffset;
214	}
215}
216
217
218/*
219 * Macros
220 *
221 * The ROUNDUP macro rounds up a quantity to the specified boundary,
222 * then truncates to bytes.
223 *
224 * The XYNORMALIZE macro determines whether XY format data requires
225 * normalization and calls a routine to do so if needed. The logic in
226 * this module is designed for LSBFirst byte and bit order, so
227 * normalization is done as required to present the data in this order.
228 *
229 * The ZNORMALIZE macro performs byte and nibble order normalization if
230 * required for Z format data.
231 *
232 * The XYINDEX macro computes the index to the starting byte (char) boundary
233 * for a bitmap_unit containing a pixel with coordinates x and y for image
234 * data in XY format.
235 *
236 * The ZINDEX macro computes the index to the starting byte (char) boundary
237 * for a pixel with coordinates x and y for image data in ZPixmap format.
238 *
239 */
240
241#if defined(Lynx) && defined(ROUNDUP)
242#undef ROUNDUP
243#endif
244
245#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
246
247#define XYNORMALIZE(bp, img) \
248    if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
249	_xynormalizeimagebits((unsigned char *)(bp), img)
250
251#define ZNORMALIZE(bp, img) \
252    if (img->byte_order == MSBFirst) \
253	_znormalizeimagebits((unsigned char *)(bp), img)
254
255#define XYINDEX(x, y, img) \
256    ((y) * img->bytes_per_line) + \
257    (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
258
259#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
260    (((x) * img->bits_per_pixel) >> 3)
261
262/*
263 * This routine initializes the image object function pointers.  The
264 * intent is to provide native (i.e. fast) routines for native format images
265 * only using the generic (i.e. slow) routines when fast ones don't exist.
266 * However, with the current rather botched external interface, clients may
267 * have to mung image attributes after the image gets created, so the fast
268 * routines always have to check to make sure the optimization is still
269 * valid, and reinit the functions if not.
270 */
271void _XInitImageFuncPtrs (
272    register XImage *image)
273{
274	image->f.create_image = XCreateImage;
275	image->f.destroy_image = _XDestroyImage;
276	if ((image->format == ZPixmap) && (image->bits_per_pixel == 8)) {
277	    image->f.get_pixel = _XGetPixel8;
278	    image->f.put_pixel = _XPutPixel8;
279	} else if (((image->bits_per_pixel | image->depth) == 1) &&
280		   (image->byte_order == image->bitmap_bit_order)) {
281	    image->f.get_pixel = _XGetPixel1;
282	    image->f.put_pixel = _XPutPixel1;
283	} else if ((image->format == ZPixmap) &&
284		   (image->bits_per_pixel == 32)) {
285	    image->f.get_pixel = _XGetPixel32;
286	    image->f.put_pixel = _XPutPixel32;
287	} else if ((image->format == ZPixmap) &&
288		   (image->bits_per_pixel == 16)) {
289	    image->f.get_pixel = _XGetPixel16;
290	    image->f.put_pixel = _XPutPixel16;
291	} else {
292	    image->f.get_pixel = _XGetPixel;
293	    image->f.put_pixel = _XPutPixel;
294	}
295	image->f.sub_image = _XSubImage;
296/*	image->f.set_image = _XSetImage;*/
297	image->f.add_pixel = _XAddPixel;
298}
299
300/*
301 * CreateImage
302 *
303 * Allocates the memory necessary for an XImage data structure.
304 * Initializes the structure with "default" values and returns XImage.
305 *
306 */
307
308XImage *XCreateImage (
309    register Display *dpy,
310    register Visual *visual,
311    unsigned int depth,
312    int format,
313    int offset, /*How many pixels from the start of the data does the
314		picture to be transmitted start?*/
315
316    char *data,
317    unsigned int width,
318    unsigned int height,
319    int xpad,
320    int image_bytes_per_line)
321		/*How many bytes between a pixel on one line and the pixel with
322		  the same X coordinate on the next line? 0 means
323		  XCreateImage can calculate it.*/
324{
325	register XImage *image;
326	int bits_per_pixel = 1;
327	int min_bytes_per_line;
328
329	if (depth == 0 || depth > 32 ||
330	    (format != XYBitmap && format != XYPixmap && format != ZPixmap) ||
331	    (format == XYBitmap && depth != 1) ||
332	    (xpad != 8 && xpad != 16 && xpad != 32) ||
333	    offset < 0)
334	    return (XImage *) NULL;
335	if ((image = (XImage *) Xcalloc(1, (unsigned) sizeof(XImage))) == NULL)
336	    return (XImage *) NULL;
337
338	image->width = width;
339	image->height = height;
340	image->format = format;
341	image->byte_order = dpy->byte_order;
342	image->bitmap_unit = dpy->bitmap_unit;
343	image->bitmap_bit_order = dpy->bitmap_bit_order;
344	if (visual != NULL) {
345		image->red_mask = visual->red_mask;
346		image->green_mask = visual->green_mask;
347		image->blue_mask = visual->blue_mask;
348	}
349	else {
350		image->red_mask = image->green_mask = image->blue_mask = 0;
351	}
352	if (format == ZPixmap)
353	{
354	    bits_per_pixel = _XGetBitsPerPixel(dpy, (int) depth);
355	}
356
357	image->xoffset = offset;
358	image->bitmap_pad = xpad;
359	image->depth = depth;
360 	image->data = data;
361	/*
362	 * compute per line accelerator.
363	 */
364	{
365	if (format == ZPixmap)
366	    min_bytes_per_line =
367	       ROUNDUP((bits_per_pixel * width), image->bitmap_pad);
368	else
369	    min_bytes_per_line =
370	        ROUNDUP((width + offset), image->bitmap_pad);
371	}
372	if (image_bytes_per_line == 0) {
373	    image->bytes_per_line = min_bytes_per_line;
374	} else if (image_bytes_per_line < min_bytes_per_line) {
375	    Xfree(image);
376	    return NULL;
377	} else {
378	    image->bytes_per_line = image_bytes_per_line;
379	}
380
381	image->bits_per_pixel = bits_per_pixel;
382	image->obdata = NULL;
383	_XInitImageFuncPtrs (image);
384
385	return image;
386}
387
388Status XInitImage (XImage *image)
389{
390	int min_bytes_per_line;
391
392	if (image->depth == 0 || image->depth > 32 ||
393	    image->bits_per_pixel > 32 || image->bitmap_unit > 32 ||
394	    image->bits_per_pixel < 0 || image->bitmap_unit < 0 ||
395	    (image->format != XYBitmap &&
396	     image->format != XYPixmap &&
397	     image->format != ZPixmap) ||
398	    (image->format == XYBitmap && image->depth != 1) ||
399	    (image->bitmap_pad != 8 &&
400	     image->bitmap_pad != 16 &&
401	     image->bitmap_pad != 32) ||
402	    image->xoffset < 0)
403	    return 0;
404
405	/*
406	 * compute per line accelerator.
407	 */
408	if (image->format == ZPixmap)
409	    min_bytes_per_line =
410	       ROUNDUP((image->bits_per_pixel * image->width),
411		       image->bitmap_pad);
412	else
413	    min_bytes_per_line =
414	        ROUNDUP((image->width + image->xoffset), image->bitmap_pad);
415
416	if (image->bytes_per_line == 0) {
417	    image->bytes_per_line = min_bytes_per_line;
418	} else if (image->bytes_per_line < min_bytes_per_line) {
419	    return 0;
420	}
421
422	_XInitImageFuncPtrs (image);
423
424	return 1;
425}
426
427/*
428 * _DestroyImage
429 *
430 * Deallocates the memory associated with the ximage data structure.
431 * this version handles the case of the image data being malloc'd
432 * entirely by the library.
433 */
434
435static int _XDestroyImage (XImage *ximage)
436{
437	if (ximage->data != NULL) Xfree((char *)ximage->data);
438	if (ximage->obdata != NULL) Xfree((char *)ximage->obdata);
439	Xfree((char *)ximage);
440	return 1;
441}
442
443
444/*
445 * GetPixel
446 *
447 * Returns the specified pixel.  The X and Y coordinates are relative to
448 * the origin (upper left [0,0]) of the image.  The pixel value is returned
449 * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
450 * The algorithm used is:
451 *
452 *	copy the source bitmap_unit or Zpixel into temp
453 *	normalize temp if needed
454 *	extract the pixel bits into return value
455 *
456 */
457
458static unsigned long const low_bits_table[] = {
459    0x00000000, 0x00000001, 0x00000003, 0x00000007,
460    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
461    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
462    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
463    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
464    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
465    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
466    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
467    0xffffffff
468};
469
470static unsigned long _XGetPixel (
471    register XImage *ximage,
472    int x,
473    int y)
474
475{
476	unsigned long pixel, px;
477	register char *src;
478	register char *dst;
479	register int i, j;
480	int bits, nbytes;
481	long plane;
482
483	if ((ximage->bits_per_pixel | ximage->depth) == 1) {
484		src = &ximage->data[XYINDEX(x, y, ximage)];
485		dst = (char *)&pixel;
486		pixel = 0;
487		for (i = ximage->bitmap_unit >> 3; --i >= 0; ) *dst++ = *src++;
488		XYNORMALIZE(&pixel, ximage);
489          	bits = (x + ximage->xoffset) % ximage->bitmap_unit;
490		pixel = ((((char *)&pixel)[bits>>3])>>(bits&7)) & 1;
491	} else if (ximage->format == XYPixmap) {
492		pixel = 0;
493		plane = 0;
494		nbytes = ximage->bitmap_unit >> 3;
495		for (i = ximage->depth; --i >= 0; ) {
496		    src = &ximage->data[XYINDEX(x, y, ximage)+ plane];
497		    dst = (char *)&px;
498		    px = 0;
499		    for (j = nbytes; --j >= 0; ) *dst++ = *src++;
500		    XYNORMALIZE(&px, ximage);
501		    bits = (x + ximage->xoffset) % ximage->bitmap_unit;
502		    pixel = (pixel << 1) |
503			    (((((char *)&px)[bits>>3])>>(bits&7)) & 1);
504		    plane = plane + (ximage->bytes_per_line * ximage->height);
505		}
506	} else if (ximage->format == ZPixmap) {
507		src = &ximage->data[ZINDEX(x, y, ximage)];
508		dst = (char *)&px;
509		px = 0;
510		for (i = (ximage->bits_per_pixel + 7) >> 3; --i >= 0; )
511		    *dst++ = *src++;
512		ZNORMALIZE(&px, ximage);
513		pixel = 0;
514		for (i=sizeof(unsigned long); --i >= 0; )
515		    pixel = (pixel << 8) | ((unsigned char *)&px)[i];
516		if (ximage->bits_per_pixel == 4) {
517		    if (x & 1)
518			pixel >>= 4;
519		    else
520			pixel &= 0xf;
521		}
522	} else {
523		return 0; /* bad image */
524	}
525	if (ximage->bits_per_pixel == ximage->depth)
526	  return pixel;
527	else
528	  return (pixel & low_bits_table[ximage->depth]);
529}
530
531#ifndef WORD64
532static CARD32 const byteorderpixel = MSBFirst << 24;
533#endif
534
535static unsigned long _XGetPixel32 (
536    register XImage *ximage,
537    int x,
538    int y)
539{
540	register unsigned char *addr;
541	unsigned long pixel;
542
543	if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 32)) {
544	    addr = &((unsigned char *)ximage->data)
545			[y * ximage->bytes_per_line + (x << 2)];
546#ifndef WORD64
547	    if (*((const char *)&byteorderpixel) == ximage->byte_order)
548		pixel = *((CARD32 *)addr);
549	    else
550#endif
551	    if (ximage->byte_order == MSBFirst)
552		pixel = ((unsigned long)addr[0] << 24 |
553			 (unsigned long)addr[1] << 16 |
554			 (unsigned long)addr[2] << 8 |
555			 addr[3]);
556	    else
557		pixel = ((unsigned long)addr[3] << 24 |
558			 (unsigned long)addr[2] << 16 |
559			 (unsigned long)addr[1] << 8 |
560			 addr[0]);
561	    if (ximage->depth != 32)
562		pixel &= low_bits_table[ximage->depth];
563	    return pixel;
564	} else {
565	    _XInitImageFuncPtrs(ximage);
566	    return XGetPixel(ximage, x, y);
567	}
568}
569
570static unsigned long _XGetPixel16 (
571    register XImage *ximage,
572    int x,
573    int y)
574{
575	register unsigned char *addr;
576	unsigned long pixel;
577
578	if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 16)) {
579	    addr = &((unsigned char *)ximage->data)
580			[y * ximage->bytes_per_line + (x << 1)];
581	    if (ximage->byte_order == MSBFirst)
582		pixel = addr[0] << 8 | addr[1];
583	    else
584		pixel = addr[1] << 8 | addr[0];
585	    if (ximage->depth != 16)
586		pixel &= low_bits_table[ximage->depth];
587	    return pixel;
588	} else {
589	    _XInitImageFuncPtrs(ximage);
590	    return XGetPixel(ximage, x, y);
591	}
592}
593
594static unsigned long _XGetPixel8 (
595    register XImage *ximage,
596    int x,
597    int y)
598{
599	unsigned char pixel;
600
601	if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 8)) {
602	    pixel = ((unsigned char *)ximage->data)
603			[y * ximage->bytes_per_line + x];
604	    if (ximage->depth != 8)
605		pixel &= low_bits_table[ximage->depth];
606	    return pixel;
607	} else {
608	    _XInitImageFuncPtrs(ximage);
609	    return XGetPixel(ximage, x, y);
610	}
611}
612
613static unsigned long _XGetPixel1 (
614    register XImage *ximage,
615    int x,
616    int y)
617{
618	unsigned char bit;
619	int xoff, yoff;
620
621	if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
622	    (ximage->byte_order == ximage->bitmap_bit_order)) {
623	    xoff = x + ximage->xoffset;
624	    yoff = y * ximage->bytes_per_line + (xoff >> 3);
625	    xoff &= 7;
626	    if (ximage->bitmap_bit_order == MSBFirst)
627	        bit = 0x80 >> xoff;
628	    else
629		bit = 1 << xoff;
630	    return (ximage->data[yoff] & bit) ? 1 : 0;
631	} else {
632	    _XInitImageFuncPtrs(ximage);
633	    return XGetPixel(ximage, x, y);
634	}
635}
636
637/*
638 * PutPixel
639 *
640 * Overwrites the specified pixel.  The X and Y coordinates are relative to
641 * the origin (upper left [0,0]) of the image.  The input pixel value must be
642 * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
643 * The algorithm used is:
644 *
645 *	copy the destination bitmap_unit or Zpixel to temp
646 *	normalize temp if needed
647 *	copy the pixel bits into the temp
648 *	renormalize temp if needed
649 *	copy the temp back into the destination image data
650 *
651 */
652
653static int _XPutPixel (
654    register XImage *ximage,
655    int x,
656    int y,
657    unsigned long pixel)
658
659{
660	unsigned long px, npixel;
661	register char *src;
662	register char *dst;
663	register int i;
664	int j, nbytes;
665	long plane;
666
667	if (ximage->depth == 4)
668	    pixel &= 0xf;
669        npixel = pixel;
670	for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
671	    ((unsigned char *)&pixel)[i] = px;
672	if ((ximage->bits_per_pixel | ximage->depth) == 1) {
673		src = &ximage->data[XYINDEX(x, y, ximage)];
674		dst = (char *)&px;
675		px = 0;
676		nbytes = ximage->bitmap_unit >> 3;
677		for (i = nbytes; --i >= 0; ) *dst++ = *src++;
678		XYNORMALIZE(&px, ximage);
679		i = ((x + ximage->xoffset) % ximage->bitmap_unit);
680		_putbits ((char *)&pixel, i, 1, (char *)&px);
681		XYNORMALIZE(&px, ximage);
682		src = (char *) &px;
683		dst = &ximage->data[XYINDEX(x, y, ximage)];
684		for (i = nbytes; --i >= 0; ) *dst++ = *src++;
685	} else if (ximage->format == XYPixmap) {
686		plane = (ximage->bytes_per_line * ximage->height) *
687		    (ximage->depth - 1); /* do least signif plane 1st */
688		nbytes = ximage->bitmap_unit >> 3;
689		for (j = ximage->depth; --j >= 0; ) {
690		    src = &ximage->data[XYINDEX(x, y, ximage) + plane];
691		    dst = (char *) &px;
692		    px = 0;
693		    for (i = nbytes; --i >= 0; ) *dst++ = *src++;
694		    XYNORMALIZE(&px, ximage);
695		    i = ((x + ximage->xoffset) % ximage->bitmap_unit);
696		    _putbits ((char *)&pixel, i, 1, (char *)&px);
697		    XYNORMALIZE(&px, ximage);
698		    src = (char *)&px;
699		    dst = &ximage->data[XYINDEX(x, y, ximage) + plane];
700		    for (i = nbytes; --i >= 0; ) *dst++ = *src++;
701		    npixel = npixel >> 1;
702		    for (i=0, px=npixel; i<sizeof(unsigned long); i++, px>>=8)
703			((unsigned char *)&pixel)[i] = px;
704		    plane = plane - (ximage->bytes_per_line * ximage->height);
705		}
706	} else if (ximage->format == ZPixmap) {
707		src = &ximage->data[ZINDEX(x, y, ximage)];
708		dst = (char *)&px;
709		px = 0;
710		nbytes = (ximage->bits_per_pixel + 7) >> 3;
711		for (i = nbytes; --i >= 0; ) *dst++ = *src++;
712		ZNORMALIZE(&px, ximage);
713		_putbits ((char *)&pixel,
714			  (x * ximage->bits_per_pixel) & 7,
715			  ximage->bits_per_pixel, (char *)&px);
716		ZNORMALIZE(&px, ximage);
717		src = (char *)&px;
718		dst = &ximage->data[ZINDEX(x, y, ximage)];
719		for (i = nbytes; --i >= 0; ) *dst++ = *src++;
720	} else {
721		return 0; /* bad image */
722	}
723	return 1;
724}
725
726static int _XPutPixel32 (
727    register XImage *ximage,
728    int x,
729    int y,
730    unsigned long pixel)
731{
732	unsigned char *addr;
733
734	if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 32)) {
735	    addr = &((unsigned char *)ximage->data)
736			[y * ximage->bytes_per_line + (x << 2)];
737#ifndef WORD64
738	    if (*((const char *)&byteorderpixel) == ximage->byte_order)
739		*((CARD32 *)addr) = pixel;
740	    else
741#endif
742	    if (ximage->byte_order == MSBFirst) {
743		addr[0] = pixel >> 24;
744		addr[1] = pixel >> 16;
745		addr[2] = pixel >> 8;
746		addr[3] = pixel;
747	    } else {
748		addr[3] = pixel >> 24;
749		addr[2] = pixel >> 16;
750		addr[1] = pixel >> 8;
751		addr[0] = pixel;
752	    }
753	    return 1;
754	} else {
755	    _XInitImageFuncPtrs(ximage);
756	    return XPutPixel(ximage, x, y, pixel);
757	}
758}
759
760static int _XPutPixel16 (
761    register XImage *ximage,
762    int x,
763    int y,
764    unsigned long pixel)
765{
766	unsigned char *addr;
767
768	if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 16)) {
769	    addr = &((unsigned char *)ximage->data)
770			[y * ximage->bytes_per_line + (x << 1)];
771	    if (ximage->byte_order == MSBFirst) {
772		addr[0] = pixel >> 8;
773		addr[1] = pixel;
774	    } else {
775		addr[1] = pixel >> 8;
776		addr[0] = pixel;
777	    }
778	    return 1;
779	} else {
780	    _XInitImageFuncPtrs(ximage);
781	    return XPutPixel(ximage, x, y, pixel);
782	}
783}
784
785static int _XPutPixel8 (
786    register XImage *ximage,
787    int x,
788    int y,
789    unsigned long pixel)
790{
791	if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 8)) {
792	    ximage->data[y * ximage->bytes_per_line + x] = pixel;
793	    return 1;
794	} else {
795	    _XInitImageFuncPtrs(ximage);
796	    return XPutPixel(ximage, x, y, pixel);
797	}
798}
799
800static int _XPutPixel1 (
801    register XImage *ximage,
802    int x,
803    int y,
804    unsigned long pixel)
805{
806	unsigned char bit;
807	int xoff, yoff;
808
809	if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
810	    (ximage->byte_order == ximage->bitmap_bit_order)) {
811	    xoff = x + ximage->xoffset;
812	    yoff = y * ximage->bytes_per_line + (xoff >> 3);
813	    xoff &= 7;
814	    if (ximage->bitmap_bit_order == MSBFirst)
815		bit = 0x80 >> xoff;
816	    else
817		bit = 1 << xoff;
818	    if (pixel & 1)
819		ximage->data[yoff] |= bit;
820	    else
821		ximage->data[yoff] &= ~bit;
822	    return 1;
823	} else {
824	    _XInitImageFuncPtrs(ximage);
825	    return XPutPixel(ximage, x, y, pixel);
826	}
827}
828
829/*
830 * SubImage
831 *
832 * Creates a new image that is a subsection of an existing one.
833 * Allocates the memory necessary for the new XImage data structure.
834 * Pointer to new image is returned.  The algorithm used is repetitive
835 * calls to get and put pixel.
836 *
837 */
838
839static XImage *_XSubImage (
840    XImage *ximage,
841    register int x,	/* starting x coordinate in existing image */
842    register int y,	/* starting y coordinate in existing image */
843    unsigned int width,	/* width in pixels of new subimage */
844    unsigned int height)/* height in pixels of new subimage */
845
846{
847	register XImage *subimage;
848	int dsize;
849	register int row, col;
850	register unsigned long pixel;
851	char *data;
852
853	if ((subimage = (XImage *) Xcalloc (1, sizeof (XImage))) == NULL)
854	    return (XImage *) NULL;
855	subimage->width = width;
856	subimage->height = height;
857	subimage->xoffset = 0;
858	subimage->format = ximage->format;
859	subimage->byte_order = ximage->byte_order;
860	subimage->bitmap_unit = ximage->bitmap_unit;
861	subimage->bitmap_bit_order = ximage->bitmap_bit_order;
862	subimage->bitmap_pad = ximage->bitmap_pad;
863	subimage->bits_per_pixel = ximage->bits_per_pixel;
864	subimage->depth = ximage->depth;
865	/*
866	 * compute per line accelerator.
867	 */
868	if (subimage->format == ZPixmap)
869	    subimage->bytes_per_line =
870		ROUNDUP(subimage->bits_per_pixel * width,
871			subimage->bitmap_pad);
872	else
873	    subimage->bytes_per_line =
874		ROUNDUP(width, subimage->bitmap_pad);
875	subimage->obdata = NULL;
876	_XInitImageFuncPtrs (subimage);
877	dsize = subimage->bytes_per_line * height;
878	if (subimage->format == XYPixmap) dsize = dsize * subimage->depth;
879	if (((data = Xcalloc (1, (unsigned) dsize)) == NULL) && (dsize > 0)) {
880	    Xfree((char *) subimage);
881	    return (XImage *) NULL;
882	}
883	subimage->data = data;
884
885	/*
886	 * Test for cases where the new subimage is larger than the region
887	 * that we are copying from the existing data.  In those cases,
888	 * copy the area of the existing image, and allow the "uncovered"
889	 * area of new subimage to remain with zero filled pixels.
890	 */
891	if (height > ximage->height - y ) height = ximage->height - y;
892	if (width > ximage->width - x ) width = ximage->width - x;
893
894	for (row = y; row < (y + height); row++) {
895	    for (col = x; col < (x + width); col++) {
896		pixel = XGetPixel(ximage, col, row);
897		XPutPixel(subimage, (col - x), (row - y), pixel);
898	    }
899	}
900	return subimage;
901}
902
903
904/*
905 * SetImage
906 *
907 * Overwrites a section of one image with all of the data from another.
908 * If the two images are not of the same format (i.e. XYPixmap and ZPixmap),
909 * the image data is converted to the destination format.  The following
910 * restrictions apply:
911 *
912 *	1. The depths of the source and destination images must be equal.
913 *
914 *	2. If the height of the source image is too large to fit between
915 *	   the specified y starting point and the bottom of the image,
916 *	   then scanlines are truncated on the bottom.
917 *
918 *	3. If the width of the source image is too large to fit between
919 *	   the specified x starting point and the end of the scanline,
920 *	   then pixels are truncated on the right.
921 *
922 * The images need not have the same bitmap_bit_order, byte_order,
923 * bitmap_unit, bits_per_pixel, bitmap_pad, or xoffset.
924 *
925 */
926
927int _XSetImage(
928    XImage *srcimg,
929    register XImage *dstimg,
930    register int x,
931    register int y)
932{
933	register unsigned long pixel;
934	register int row, col;
935	int width, height, startrow, startcol;
936	if (x < 0) {
937	    startcol = -x;
938	    x = 0;
939	} else
940	    startcol = 0;
941	if (y < 0) {
942	    startrow = -y;
943	    y = 0;
944	} else
945	    startrow = 0;
946	width = dstimg->width - x;
947	if (srcimg->width < width)
948	    width = srcimg->width;
949	height = dstimg->height - y;
950	if (srcimg->height < height)
951	    height = srcimg->height;
952
953	/* this is slow, will do better later */
954	for (row = startrow; row < height; row++) {
955	    for (col = startcol; col < width; col++) {
956		pixel = XGetPixel(srcimg, col, row);
957		XPutPixel(dstimg, x + col, y + row, pixel);
958	    }
959	}
960	return 1;
961}
962
963/*
964 * AddPixel
965 *
966 * Adds a constant value to every pixel in a pixmap.
967 *
968 */
969
970static int
971_XAddPixel (
972    register XImage *ximage,
973    register long value)
974{
975	register int x;
976	register int y;
977
978	if (!value)
979	    return 0;
980	if ((ximage->bits_per_pixel | ximage->depth) == 1) {
981	    /* The only value that we can add here to an XYBitmap
982	     * is one.  Since 1 + value = ~value for one bit wide
983	     * data, we do this quickly by taking the ones complement
984	     * of the entire bitmap data (offset and pad included!).
985	     * Note that we don't need to be concerned with bit or
986	     * byte order at all.
987	     */
988	    register unsigned char *dp = (unsigned char *) ximage->data;
989	    x = ximage->bytes_per_line * ximage->height;
990	    while (--x >= 0) {
991		*dp = ~*dp;
992		dp++;
993	    }
994	} else if ((ximage->format == ZPixmap) &&
995		   (ximage->bits_per_pixel == 8)) {
996	    register unsigned char *dp = (unsigned char *) ximage->data;
997	    x = ximage->bytes_per_line * ximage->height;
998	    while (--x >= 0)
999		*dp++ += value;
1000#ifndef WORD64
1001	} else if ((ximage->format == ZPixmap) &&
1002		   (ximage->bits_per_pixel == 16) &&
1003		   (*((const char *)&byteorderpixel) == ximage->byte_order)) {
1004	    register unsigned short *dp = (unsigned short *) ximage->data;
1005	    x = (ximage->bytes_per_line >> 1) * ximage->height;
1006	    while (--x >= 0)
1007		*dp++ += value;
1008	} else if ((ximage->format == ZPixmap) &&
1009		   (ximage->bits_per_pixel == 32) &&
1010		   (*((const char *)&byteorderpixel) == ximage->byte_order)) {
1011	    register CARD32 *dp = (CARD32 *) ximage->data;
1012	    x = (ximage->bytes_per_line >> 2) * ximage->height;
1013	    while (--x >= 0)
1014		*dp++ += value;
1015#endif
1016	} else {
1017	    for (y = ximage->height; --y >= 0; ) {
1018		for (x = ximage->width; --x >= 0; ) {
1019		    register unsigned long pixel = XGetPixel(ximage, x, y);
1020		    pixel = pixel + value;
1021		    XPutPixel(ximage, x, y, pixel);
1022		}
1023	    }
1024	}
1025	return 0;
1026}
1027
1028