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