Home | History | Annotate | Line # | Download | only in src
      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 <limits.h>
     34 #include "ImUtil.h"
     35 
     36 static int _XDestroyImage(XImage *);
     37 static unsigned long _XGetPixel(XImage *, int, int);
     38 static unsigned long _XGetPixel1(XImage *, int, int);
     39 static unsigned long _XGetPixel8(XImage *, int, int);
     40 static unsigned long _XGetPixel16(XImage *, int, int);
     41 static unsigned long _XGetPixel32(XImage *, int, int);
     42 static int _XPutPixel(XImage *, int, int, unsigned long);
     43 static int _XPutPixel1(XImage *, int, int, unsigned long);
     44 static int _XPutPixel8(XImage *, int, int, unsigned long);
     45 static int _XPutPixel16(XImage *, int, int, unsigned long);
     46 static int _XPutPixel32(XImage *, int, int, unsigned long);
     47 static XImage *_XSubImage(XImage *, int, int, unsigned int, unsigned int);
     48 static int _XAddPixel(XImage *, long);
     49 
     50 static unsigned char const _lomask[0x09] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
     51 static 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 
     57 int
     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 
     72 int
     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  */
    122 static 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 
    151 static 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 
    185 static 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  */
    268 void _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 
    305 XImage *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 
    394 Status 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 
    441 static 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 
    464 static 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 
    476 static 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 
    537 static CARD32 const byteorderpixel = MSBFirst << 24;
    538 
    539 static 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 
    571 static 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 
    595 static 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 
    614 static 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 
    654 static 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 
    727 static 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 
    758 static 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 
    783 static 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 
    798 static 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 
    837 static 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 
    925 int _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 
    968 static 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