Annotation of researchv9/X11/src/X.V11R1/lib/X/XImUtil.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.