Annotation of researchv9/X11/src/X.V11R1/lib/X/XImUtil.c, revision 1.1.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.