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