|
|
1.1 ! root 1: #include "copyright.h" ! 2: ! 3: /* $Header: XImUtil.c,v 11.17 87/09/01 14:53:59 toddb Exp $ */ ! 4: /* Copyright Massachusetts Institute of Technology 1986 */ ! 5: ! 6: #include "Xlibint.h" ! 7: #include "Xutil.h" ! 8: #include <stdio.h> ! 9: ! 10: extern char _reverse_byte[0x100]; /* found in XPutImage */ ! 11: static char _lomask[0x09] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; ! 12: static char _himask[0x09] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 }; ! 13: ! 14: /* These two convenience routines return the scanline_pad and bits_per_pixel ! 15: associated with a specific depth of ZPixmap format image for a ! 16: display. */ ! 17: ! 18: _XGetScanlinePad(dpy, depth) ! 19: Display *dpy; ! 20: int depth; ! 21: { ! 22: register ScreenFormat *fmt = dpy->pixmap_format; ! 23: register int i; ! 24: ! 25: for (i = dpy->nformats + 1; --i; ++fmt) ! 26: if (fmt->depth == depth) ! 27: return(fmt->scanline_pad); ! 28: ! 29: return(dpy->bitmap_pad); ! 30: } ! 31: ! 32: _XGetBitsPerPixel(dpy, depth) ! 33: Display *dpy; ! 34: int depth; ! 35: { ! 36: register ScreenFormat *fmt = dpy->pixmap_format; ! 37: register int i; ! 38: ! 39: for (i = dpy->nformats + 1; --i; ++fmt) ! 40: if (fmt->depth == depth) ! 41: return(fmt->bits_per_pixel); ! 42: ! 43: return(depth); ! 44: } ! 45: ! 46: ! 47: /* ! 48: * This module provides rudimentary manipulation routines for image data ! 49: * structures. The functions provided are: ! 50: * ! 51: * XCreateImage Creates a default XImage data structure ! 52: * _XDestroyImage Deletes an XImage data structure ! 53: * _XGetPixel Reads a pixel from an image data structure ! 54: * _XPutPixel Writes a pixel into an image data structure ! 55: * _XSubImage Clones a new (sub)image from an existing one ! 56: * _XSetImage Writes an image data pattern into another image ! 57: * _XAddPixel Adds a constant value to every pixel in an image ! 58: * ! 59: * The logic contained in these routines makes several assumptions about ! 60: * the image data structures, and at least for current implementations ! 61: * these assumptions are believed to be true. They are: ! 62: * ! 63: * For all formats, bits_per_pixel is less than or equal to 32. ! 64: * For XY formats, bitmap_unit is 8, 16, 24, or 32 bits. ! 65: * For Z format, bits_per_pixel is 4, 8, 12, 16, 20, 24, 28 or 32 bits. ! 66: */ ! 67: static _normalizeimagebits (bpt, nb, byteorder, unitsize, bitorder) ! 68: unsigned char *bpt; /* beginning pointer to image bits */ ! 69: long nb; /* number of bytes to normalize */ ! 70: int byteorder; /* swap bytes if byteorder == MSBFirst */ ! 71: int unitsize; /* size of the bitmap_unit or Zpixel */ ! 72: int bitorder; /* swap bits if bitorder == MSBFirst */ ! 73: { ! 74: if (byteorder == MSBFirst) { ! 75: register char c; ! 76: register unsigned char *bp = bpt; ! 77: register unsigned char *ep = bpt + nb; ! 78: register unsigned char *sp; ! 79: switch (unitsize) { ! 80: ! 81: case 4: ! 82: do { /* swap nibble */ ! 83: *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); ! 84: bp++; ! 85: } ! 86: while (bp < ep); ! 87: break; ! 88: ! 89: case 16: ! 90: do { /* swap short */ ! 91: c = *bp; ! 92: *bp = *(bp + 1); ! 93: bp++; ! 94: *bp = c; ! 95: bp++; ! 96: } ! 97: while (bp < ep); ! 98: break; ! 99: ! 100: case 24: ! 101: do { /* swap three */ ! 102: c = *(bp + 2); ! 103: *(bp + 2) = *bp; ! 104: *bp = c; ! 105: bp += 3; ! 106: } ! 107: while (bp < ep); ! 108: break; ! 109: ! 110: case 32: ! 111: do { /* swap long */ ! 112: sp = bp + 3; ! 113: c = *sp; ! 114: *sp = *bp; ! 115: *bp++ = c; ! 116: sp = bp + 1; ! 117: c = *sp; ! 118: *sp = *bp; ! 119: *bp++ = c; ! 120: bp += 2; ! 121: } ! 122: while (bp < ep); ! 123: break; ! 124: } ! 125: } ! 126: if (bitorder == MSBFirst) { ! 127: do { ! 128: *bpt = _reverse_byte[*bpt]; ! 129: bpt++; ! 130: } ! 131: while (--nb > 0); ! 132: } ! 133: } ! 134: ! 135: static _putbits (src, dstoffset, numbits, dst) ! 136: register char *src; /* address of source bit string */ ! 137: long dstoffset; /* bit offset into destination; range is 0-31 */ ! 138: register int numbits;/* number of bits to copy to destination */ ! 139: register char *dst; /* address of destination bit string */ ! 140: { ! 141: register unsigned char chlo, chhi; ! 142: int hibits; ! 143: dst = dst + (dstoffset >> 3); ! 144: dstoffset = dstoffset % 8; ! 145: hibits = 8 - dstoffset; ! 146: chlo = *dst & _lomask[dstoffset]; ! 147: for (;;) { ! 148: chhi = (*src << dstoffset) & _himask[dstoffset]; ! 149: if (numbits <= hibits) { ! 150: chhi = chhi & _lomask[dstoffset + numbits]; ! 151: *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; ! 152: break; ! 153: } ! 154: *dst = chhi | chlo; ! 155: dst++; ! 156: numbits = numbits - hibits; ! 157: chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; ! 158: src++; ! 159: if (numbits <= dstoffset) { ! 160: chlo = chlo & _lomask[numbits]; ! 161: *dst = (*dst & _himask[numbits]) | chlo; ! 162: break; ! 163: } ! 164: numbits = numbits - dstoffset; ! 165: } ! 166: } ! 167: ! 168: ! 169: /* ! 170: * Macros ! 171: * ! 172: * The ROUNDUP macro rounds up a quantity to the specified boundary. ! 173: * ! 174: * The XYNORMALIZE macro determines whether XY format data requires ! 175: * normalization and calls a routine to do so if needed. The logic in ! 176: * this module is designed for LSBFirst byte and bit order, so ! 177: * normalization is done as required to present the data in this order. ! 178: * ! 179: * The ZNORMALIZE macro performs byte and nibble order normalization if ! 180: * required for Z format data. ! 181: * ! 182: * The XYINDEX macro computes the index to the starting byte (char) boundary ! 183: * for a bitmap_unit containing a pixel with coordinates x and y for image ! 184: * data in XY format. ! 185: * ! 186: * The ZINDEX macro computes the index to the starting byte (char) boundary ! 187: * for a pixel with coordinates x and y for image data in ZPixmap format. ! 188: * ! 189: */ ! 190: ! 191: #define ROUNDUP(nbytes, pad) (((((nbytes) - 1) + (pad)) / (pad)) * (pad)) ! 192: ! 193: #define XYNORMALIZE(bp, nbytes, img) \ ! 194: if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \ ! 195: _normalizeimagebits((unsigned char *)(bp), (nbytes), img->byte_order, img->bitmap_unit, \ ! 196: img->bitmap_bit_order) ! 197: ! 198: #define ZNORMALIZE(bp, nbytes, img) \ ! 199: if (img->byte_order == MSBFirst) \ ! 200: _normalizeimagebits((unsigned char *)(bp), (nbytes), MSBFirst, img->bits_per_pixel, \ ! 201: LSBFirst) ! 202: ! 203: #define XYINDEX(x, y, img) \ ! 204: ((y) * img->bytes_per_line) + \ ! 205: (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3) ! 206: ! 207: #define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \ ! 208: (((x) * img->bits_per_pixel) >> 3) ! 209: ! 210: ! 211: /* ! 212: * CreateImage ! 213: * ! 214: * Allocates the memory necessary for an XImage data structure. ! 215: * Initializes the structure with "default" values and returns XImage. ! 216: * ! 217: */ ! 218: ! 219: XImage *XCreateImage (dpy, visual, depth, format, offset, data, width, height, ! 220: xpad, image_bytes_per_line) ! 221: register Display *dpy; ! 222: register Visual *visual; ! 223: unsigned int depth; ! 224: int format; ! 225: int offset; /*How many pixels from the start of the data does the ! 226: picture to be transmitted start?*/ ! 227: ! 228: char *data; ! 229: unsigned int width; ! 230: unsigned int height; ! 231: int xpad; ! 232: int image_bytes_per_line; ! 233: /*How many bytes between a pixel on one line and the pixel with ! 234: the same X coordinate on the next line? 0 means ! 235: XCreateImage can calculate it.*/ ! 236: { ! 237: register XImage *image; ! 238: int bits_per_pixel = 1; ! 239: int byte_offset; ! 240: image = (XImage *) Xcalloc (1, (unsigned) sizeof (XImage)); ! 241: image->width = width; ! 242: image->height = height; ! 243: image->format = format; ! 244: image->byte_order = dpy->byte_order; ! 245: image->bitmap_unit = dpy->bitmap_unit; ! 246: image->bitmap_bit_order = dpy->bitmap_bit_order; ! 247: if (visual != NULL) { ! 248: image->red_mask = visual->red_mask; ! 249: image->green_mask = visual->green_mask; ! 250: image->blue_mask = visual->blue_mask; ! 251: } ! 252: else { ! 253: image->red_mask = image->green_mask = image->blue_mask = 0; ! 254: } ! 255: if (format == ZPixmap) ! 256: { ! 257: bits_per_pixel = _XGetBitsPerPixel(dpy, depth); ! 258: } ! 259: ! 260: image->xoffset = offset; ! 261: image->bitmap_pad = xpad; ! 262: image->depth = depth; ! 263: image->data = data; ! 264: /* ! 265: * compute per line accelerator. ! 266: */ ! 267: if (image_bytes_per_line == 0) ! 268: { ! 269: if (format == ZPixmap) ! 270: image->bytes_per_line = ! 271: ROUNDUP((bits_per_pixel * width), image->bitmap_pad) >> 3; ! 272: else ! 273: image->bytes_per_line = ! 274: ROUNDUP((width + offset), image->bitmap_pad) >> 3; ! 275: } ! 276: else image->bytes_per_line = image_bytes_per_line; ! 277: ! 278: image->bits_per_pixel = bits_per_pixel; ! 279: image->obdata = NULL; ! 280: _XInitImageFuncPtrs (image); ! 281: ! 282: return image; ! 283: ! 284: } ! 285: ! 286: ! 287: /* ! 288: * _DestroyImage ! 289: * ! 290: * Deallocates the memory associated with the ximage data structure. ! 291: * this version handles the case of the image data being malloc'd ! 292: * entirely by the library. ! 293: */ ! 294: ! 295: int _XDestroyImage (ximage) ! 296: XImage *ximage; ! 297: ! 298: { ! 299: Xfree((char *)ximage->data); ! 300: if (ximage->obdata != NULL) Xfree((char *)ximage->obdata); ! 301: Xfree((char *)ximage); ! 302: return 1; ! 303: } ! 304: ! 305: ! 306: /* ! 307: * GetPixel ! 308: * ! 309: * Returns the specified pixel. The X and Y coordinates are relative to ! 310: * the origin (upper left [0,0]) of the image. The pixel value is returned ! 311: * in normalized format, i.e. the LSB of the long is the LSB of the pixel. ! 312: * The algorithm used is: ! 313: * ! 314: * copy the source bitmap_unit or Zpixel into temp ! 315: * normalize temp if needed ! 316: * extract the pixel bits into return value ! 317: * ! 318: */ ! 319: ! 320: unsigned long _XGetPixel (ximage, x, y) ! 321: register XImage *ximage; ! 322: int x; ! 323: int y; ! 324: ! 325: { ! 326: unsigned long pixel, px; ! 327: register char *src; ! 328: register char *dst; ! 329: register long i, j; ! 330: int plane; ! 331: long nbytes; ! 332: switch (ximage->format) { ! 333: ! 334: case XYBitmap: ! 335: src = &ximage->data[XYINDEX(x, y, ximage)]; ! 336: dst = (char *)&pixel; ! 337: pixel = 0; ! 338: nbytes = ximage->bitmap_unit >> 3; ! 339: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 340: XYNORMALIZE(&pixel, nbytes, ximage); ! 341: pixel = pixel >> ((x + ximage->xoffset) % ximage->bitmap_unit); ! 342: pixel = pixel & 1; ! 343: break; ! 344: ! 345: case XYPixmap: ! 346: pixel = 0; ! 347: plane = 0; ! 348: nbytes = ximage->bitmap_unit >> 3; ! 349: for (i=0; i < ximage->depth; i++) { ! 350: src = &ximage->data[XYINDEX(x, y, ximage)+ plane]; ! 351: dst = (char *)&px; ! 352: px = 0; ! 353: for (j=0; j < nbytes; j++) *dst++ = *src++; ! 354: XYNORMALIZE(&px, nbytes, ximage); ! 355: px = px >> ((x + ximage->xoffset) % ximage->bitmap_unit); ! 356: px = px & 1; ! 357: pixel = (pixel << 1) | px; ! 358: plane = plane + (ximage->bytes_per_line * ximage->height); ! 359: } ! 360: break; ! 361: ! 362: case ZPixmap: ! 363: src = &ximage->data[ZINDEX(x, y, ximage)]; ! 364: dst = (char *)&pixel; ! 365: pixel = 0; ! 366: nbytes = ROUNDUP(ximage->bits_per_pixel, 8) >> 3; ! 367: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 368: ZNORMALIZE(&pixel, nbytes, ximage); ! 369: pixel = pixel >> ((x * ximage->bits_per_pixel) % 8); ! 370: break; ! 371: ! 372: default: /* should never get here */ ! 373: _XReportBadImage("format", ximage->format, "_XGetPixel"); ! 374: break; ! 375: } ! 376: return pixel; ! 377: } ! 378: ! 379: ! 380: /* ! 381: * PutPixel ! 382: * ! 383: * Overwrites the specified pixel. The X and Y coordinates are relative to ! 384: * the origin (upper left [0,0]) of the image. The input pixel value must be ! 385: * in normalized format, i.e. the LSB of the long is the LSB of the pixel. ! 386: * The algorithm used is: ! 387: * ! 388: * copy the destination bitmap_unit or Zpixel to temp ! 389: * normalize temp if needed ! 390: * copy the pixel bits into the temp ! 391: * renormalize temp if needed ! 392: * copy the temp back into the destination image data ! 393: * ! 394: */ ! 395: ! 396: int _XPutPixel (ximage, x, y, pixel) ! 397: register XImage *ximage; ! 398: int x; ! 399: int y; ! 400: unsigned long pixel; ! 401: ! 402: { ! 403: unsigned long px; ! 404: register char *src; ! 405: register char *dst; ! 406: register long i; ! 407: int plane, j; ! 408: register long nbytes; ! 409: ! 410: switch (ximage->format) { ! 411: ! 412: case XYBitmap: ! 413: src = &ximage->data[XYINDEX(x, y, ximage)]; ! 414: dst = (char *)&px; ! 415: px = 0; ! 416: nbytes = ximage->bitmap_unit >> 3; ! 417: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 418: XYNORMALIZE(&px, nbytes, ximage); ! 419: i = ((x + ximage->xoffset) % ximage->bitmap_unit); ! 420: _putbits ((char *)&pixel, i, 1, (char *)&px); ! 421: XYNORMALIZE(&px, nbytes, ximage); ! 422: src = (char *) &px; ! 423: dst = &ximage->data[XYINDEX(x, y, ximage)]; ! 424: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 425: break; ! 426: ! 427: case XYPixmap: ! 428: plane = (ximage->bytes_per_line * ximage->height) * ! 429: (ximage->depth - 1); /* do least signif plane 1st */ ! 430: nbytes = ximage->bitmap_unit >> 3; ! 431: for (j=0; j < ximage->depth; j++) { ! 432: src = &ximage->data[XYINDEX(x, y, ximage) + plane]; ! 433: dst = (char *) &px; ! 434: px = 0; ! 435: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 436: XYNORMALIZE(&px, nbytes, ximage); ! 437: i = ((x + ximage->xoffset) % ximage->bitmap_unit); ! 438: _putbits ((char *)&pixel, i, 1, (char *)&px); ! 439: XYNORMALIZE(&px, nbytes, ximage); ! 440: src = (char *)&px; ! 441: dst = &ximage->data[XYINDEX(x, y, ximage) + plane]; ! 442: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 443: pixel = pixel >> 1; ! 444: plane = plane - (ximage->bytes_per_line * ximage->height); ! 445: } ! 446: break; ! 447: ! 448: case ZPixmap: ! 449: src = &ximage->data[ZINDEX(x, y, ximage)]; ! 450: dst = (char *)&px; ! 451: px = 0; ! 452: nbytes = ROUNDUP(ximage->bits_per_pixel, 8) >> 3; ! 453: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 454: ZNORMALIZE(&px, nbytes, ximage); ! 455: _putbits ((char *)&pixel, ! 456: (long) (x * ximage->bits_per_pixel) % 8, ! 457: ximage->bits_per_pixel, (char *)&px); ! 458: ZNORMALIZE(&px, nbytes, ximage); ! 459: src = (char *)&px; ! 460: dst = &ximage->data[ZINDEX(x, y, ximage)]; ! 461: for (i=0; i < nbytes; i++) *dst++ = *src++; ! 462: break; ! 463: ! 464: default: /* should never get here */ ! 465: _XReportBadImage("format", ximage->format, "_XPutPixel"); ! 466: break; ! 467: } ! 468: return 1; ! 469: } ! 470: ! 471: ! 472: /* ! 473: * SubImage ! 474: * ! 475: * Creates a new image that is a subsection of an existing one. ! 476: * Allocates the memory necessary for the new XImage data structure. ! 477: * Pointer to new image is returned. The algorithm used is repetitive ! 478: * calls to get and put pixel. ! 479: * ! 480: */ ! 481: ! 482: XImage *_XSubImage (ximage, x, y, width, height) ! 483: XImage *ximage; ! 484: register int x; /* starting x coordinate in existing image */ ! 485: register int y; /* starting y coordinate in existing image */ ! 486: int width; /* width in pixels of new subimage */ ! 487: int height; /* height in pixels of new subimage */ ! 488: ! 489: { ! 490: register XImage *subimage; ! 491: int dsize; ! 492: register int row, col; ! 493: register unsigned long pixel; ! 494: char *data; ! 495: subimage = (XImage *) Xcalloc (1, sizeof (XImage)); ! 496: subimage->width = width; ! 497: subimage->height = height; ! 498: subimage->xoffset = 0; ! 499: subimage->format = ximage->format; ! 500: subimage->byte_order = ximage->byte_order; ! 501: subimage->bitmap_unit = ximage->bitmap_unit; ! 502: subimage->bitmap_bit_order = ximage->bitmap_bit_order; ! 503: subimage->bitmap_pad = ximage->bitmap_pad; ! 504: subimage->bits_per_pixel = ximage->bits_per_pixel; ! 505: subimage->depth = ximage->depth; ! 506: /* ! 507: * compute per line accelarator. ! 508: */ ! 509: if (subimage->format == ZPixmap) ! 510: subimage->bytes_per_line = ! 511: ROUNDUP(((subimage->bits_per_pixel * width) >> 3), ! 512: subimage->bitmap_pad >> 3); ! 513: else ! 514: subimage->bytes_per_line = ! 515: ROUNDUP((width >> 3), subimage->bitmap_pad >> 3); ! 516: subimage->obdata = NULL; ! 517: _XInitImageFuncPtrs (subimage); ! 518: dsize = subimage->bytes_per_line * height; ! 519: if (subimage->format == XYPixmap) dsize = dsize * subimage->depth; ! 520: data = Xcalloc (1, (unsigned) dsize); ! 521: subimage->data = data; ! 522: ! 523: /* ! 524: * Test for cases where the new subimage is larger than the region ! 525: * that we are copying from the existing data. In those cases, ! 526: * copy the area of the existing image, and allow the "uncovered" ! 527: * area of new subimage to remain with zero filled pixels. ! 528: */ ! 529: if (height > ximage->height - y ) height = ximage->height - y; ! 530: if (width > ximage->width - x ) width = ximage->width - x; ! 531: ! 532: for (row = y; row < (y + height); row++) { ! 533: for (col = x; col < (x + width); col++) { ! 534: pixel = XGetPixel(ximage, col, row); ! 535: XPutPixel(subimage, (col - x), (row - y), pixel); ! 536: } ! 537: } ! 538: return subimage; ! 539: } ! 540: ! 541: ! 542: /* ! 543: * SetImage ! 544: * ! 545: * Overwrites a section of one image with all of the data from another. ! 546: * If the two images are not of the same format (i.e. XYPixmap and ZPixmap), ! 547: * the image data is converted to the destination format. The following ! 548: * restrictions apply: ! 549: * ! 550: * 1. The depths of the source and destination images must be equal. ! 551: * ! 552: * 2. If the height of the source image is too large to fit between ! 553: * the specified x starting point and the bottom of the image, ! 554: * then scanlines are truncated on the bottom. ! 555: * ! 556: * 3. If the width of the source image is too large to fit between ! 557: * the specified y starting point and the end of the scanline, ! 558: * then pixels are truncated on the right. ! 559: * ! 560: * The images need not have the same bitmap_bit_order, byte_order, ! 561: * bitmap_unit, bits_per_pixel, bitmap_pad, or xoffset. ! 562: * ! 563: */ ! 564: ! 565: int _XSetImage (srcimg, dstimg, x, y) ! 566: XImage *srcimg; ! 567: register XImage *dstimg; ! 568: register int x; ! 569: register int y; ! 570: ! 571: { ! 572: register unsigned long pixel; ! 573: register int row, col; ! 574: if (srcimg->depth != dstimg->depth) ! 575: _XReportBadImage ("depth", dstimg->depth, "_XSetImage"); ! 576: ! 577: /* this is slow, will do better later */ ! 578: for (row = y; row < dstimg->height; row++) { ! 579: for (col = x; col < dstimg->width; col++) { ! 580: pixel = XGetPixel(srcimg, col - x, row - y); ! 581: XPutPixel(dstimg, col, row, pixel); ! 582: } ! 583: } ! 584: return 1; ! 585: } ! 586: ! 587: ! 588: /* ! 589: * AddPixel ! 590: * ! 591: * Adds a constant value to every pixel in a pixmap. ! 592: * ! 593: */ ! 594: ! 595: int _XAddPixel (ximage, value) ! 596: register XImage *ximage; ! 597: int value; ! 598: ! 599: { ! 600: unsigned long pixel; ! 601: register unsigned char *dp, *src, *dst, *tmp; ! 602: register int x; ! 603: int y; ! 604: long nbytes, i; ! 605: if (value != 0) { ! 606: switch(ximage->format) { ! 607: ! 608: case XYBitmap: ! 609: /* The only value that we can add here to an XYBitmap ! 610: * is one. Since 1 + value = ~value for one bit wide ! 611: * data, we do this quickly by taking the ones complement ! 612: * of the entire bitmap data (offset and pad included!). ! 613: * Note that we don't need to be concerned with bit or ! 614: * byte order at all. ! 615: */ ! 616: dp = (unsigned char *) &ximage->data[0]; ! 617: y = ximage->bytes_per_line * ximage->height; ! 618: for (x=0; x < y; x++) { ! 619: *dp = ~(*dp); ! 620: dp++; ! 621: } ! 622: break; ! 623: ! 624: case XYPixmap: ! 625: /* this is slow, may do better later */ ! 626: for (y = 0; y < ximage->height; y++) { ! 627: for (x = 0; x < ximage->width; x++) { ! 628: pixel = XGetPixel(ximage, x, y); ! 629: pixel = pixel + value; ! 630: XPutPixel(ximage, x, y, pixel); ! 631: } ! 632: } ! 633: break; ! 634: ! 635: case ZPixmap: ! 636: /* If the bits_per_pixel makes the alignment occur on even ! 637: * byte boundaries, perform the addition by stepping thru ! 638: * the data one pixel at a time. Otherwise, do it the slow ! 639: * way by calling get and put pixel. ! 640: */ ! 641: if ((ximage->bits_per_pixel % 8) == 0) { ! 642: nbytes = ROUNDUP(ximage->bits_per_pixel, 8) >> 3; ! 643: for (y = 0; y < ximage->height; y++) { ! 644: src = (unsigned char *) &ximage->data[ZINDEX(0, y, ximage)]; ! 645: dst = src; ! 646: for (x = 0; x < ximage->width; x++) { ! 647: pixel = 0; ! 648: tmp = (unsigned char *)&pixel; ! 649: for (i = 0; i < nbytes; i++) *tmp++ = *src++; ! 650: ZNORMALIZE(&pixel, nbytes, ximage); ! 651: pixel = pixel + value; ! 652: ZNORMALIZE(&pixel, nbytes, ximage); ! 653: tmp = (unsigned char *)&pixel; ! 654: for (i = 0; i < nbytes; i++) *dst++ = *tmp++; ! 655: } ! 656: } ! 657: break; ! 658: } ! 659: else for (y = 0; y < ximage->height; y++) { ! 660: for (x = 0; x < ximage->width; x++) { ! 661: pixel = XGetPixel(ximage, x, y); ! 662: pixel = pixel + value; ! 663: XPutPixel(ximage, x, y, pixel); ! 664: } ! 665: } ! 666: break; ! 667: ! 668: default: /* should never get here */ ! 669: _XReportBadImage("format", ximage->format, "_XAddPixel"); ! 670: break; ! 671: } ! 672: } ! 673: return 1; ! 674: } ! 675: ! 676: /* ! 677: * This routine initializes the image object function pointers. The ! 678: * intent is to provide native (i.e. fast) routines for native format images ! 679: * only using the generic (i.e. slow) routines when fast ones don't exist. ! 680: * For now, just insert the generic routines. ! 681: */ ! 682: _XInitImageFuncPtrs (image) ! 683: register XImage *image; ! 684: { ! 685: image->f.create_image = XCreateImage; ! 686: image->f.destroy_image = _XDestroyImage; ! 687: image->f.get_pixel = _XGetPixel; ! 688: image->f.put_pixel = _XPutPixel; ! 689: image->f.sub_image = _XSubImage; ! 690: /* image->f.set_image = _XSetImage;*/ ! 691: image->f.add_pixel = _XAddPixel; ! 692: } ! 693: ! 694: void exit(); ! 695: int _XReportBadImage (errtype, error, routine) ! 696: char errtype[]; ! 697: int error; ! 698: char routine[]; ! 699: { ! 700: (void) fprintf(stderr, "Bad image %s: %d found in routine: %s\n", ! 701: errtype, error, routine ); ! 702: exit(1); ! 703: } ! 704: ! 705: ! 706: #ifdef notdef ! 707: _getbits (src, srcoffset, numbits, dst) ! 708: register char *src; /* address of source bit string */ ! 709: int srcoffset; /* bit offset into source; range is 0-31 */ ! 710: register int numbits; /* number of bits to copy to destination */ ! 711: register char *dst; /* address of destination bit string */ ! 712: { ! 713: register unsigned char chlo, chhi; ! 714: int lobits; ! 715: src = src + (srcoffset >> 3); ! 716: srcoffset = srcoffset % 8; ! 717: lobits = 8 - srcoffset; ! 718: for (;;) { ! 719: chlo = (unsigned char) (*src & _himask[srcoffset]) >> srcoffset; ! 720: src++; ! 721: if (numbits <= lobits) { ! 722: chlo = chlo & _lomask[numbits]; ! 723: *dst = (*dst & _himask[numbits]) | chlo; ! 724: break; ! 725: } ! 726: numbits = numbits - lobits; ! 727: chhi = *src & _lomask[srcoffset]; ! 728: if (numbits <= srcoffset) { ! 729: chhi = (chhi & _lomask[numbits]) << lobits; ! 730: *dst = (*dst & _himask[lobits + numbits]) | chlo | chhi; ! 731: break; ! 732: } ! 733: chhi = chhi << lobits; ! 734: *(dst++) = chhi | chlo; ! 735: numbits = numbits - srcoffset; ! 736: } ! 737: } ! 738: #endif ! 739:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.