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