Tizen 2.1 base
[framework/uifw/xorg/lib/libx11.git] / src / ImUtil.c
1 /*
2
3 Copyright 1986, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in 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
35 static int _XDestroyImage(XImage *);
36 static unsigned long _XGetPixel(XImage *, int, int);
37 static unsigned long _XGetPixel1(XImage *, int, int);
38 static unsigned long _XGetPixel8(XImage *, int, int);
39 static unsigned long _XGetPixel16(XImage *, int, int);
40 static unsigned long _XGetPixel32(XImage *, int, int);
41 static int _XPutPixel(XImage *, int, int, unsigned long);
42 static int _XPutPixel1(XImage *, int, int, unsigned long);
43 static int _XPutPixel8(XImage *, int, int, unsigned long);
44 static int _XPutPixel16(XImage *, int, int, unsigned long);
45 static int _XPutPixel32(XImage *, int, int, unsigned long);
46 static XImage *_XSubImage(XImage *, int, int, unsigned int, unsigned int);
47 static int _XAddPixel(XImage *, long);
48
49 static unsigned char const _lomask[0x09] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
50 static 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
56 int
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
71 int
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  */
121 static 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
150 static 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
184 static 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  */
271 void _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
308 XImage *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
388 Status 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
435 static 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
458 static 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
470 static 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
532 static CARD32 const byteorderpixel = MSBFirst << 24;
533 #endif
534
535 static 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
570 static 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
594 static 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
613 static 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
653 static 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
726 static 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
760 static 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
785 static 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
800 static 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
839 static 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
927 int _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
970 static 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