Annotation of researchv9/X11/src/X.V11R1/lib/X/XPutImage.c, revision 1.1.1.1

1.1       root        1: #include "copyright.h"
                      2: 
                      3: /* $Header: XPutImage.c,v 11.34 87/09/11 15:46:16 rws Exp $ */
                      4: /* Copyright    Massachusetts Institute of Technology    1986  */
                      5: 
                      6: #include <stdio.h>
                      7: #include "Xlibint.h"
                      8: #include <errno.h>
                      9: 
                     10: 
                     11: #define ROUNDUP(nbytes, pad) (((((nbytes) - 1) + (pad)) / (pad)) * (pad))
                     12: 
                     13: /* XXX Note to who ever must maintain this code:
                     14: 
                     15: The helper routine "PutImageRequest" is unfinished and still has a few bugs.
                     16: Byte swapping is never required when
                     17:     (image->byte_order == image->bitmap_bit_order) &&
                     18:     (dpy->byte_order == dpy->bitmap_bit_order)
                     19: Someday we will write a treatise on the subject.  If you don't believe us, try it.
                     20: Note that all display hardware we know of works this way.
                     21: Note that in X10, shipping from a VAX to a SUN ended up byte-swapping twice (once
                     22: in dix and once in ddx).  Shipping from a SUN to a VAX byte-swapped once, but
                     23: that worked because bitmaps were described as shorts in VAX order, and thus when
                     24: compiled on a SUN resulted in the additional byte-swap.
                     25: 
                     26: Swapping in the other cases is probably worked out, but we don't have time to
                     27: make sure, and we don't have any machines that do things that way to test it on.
                     28: You probably need to swap halves within longs without swapping bytes within shorts
                     29: for some cases.
                     30: 
                     31: Also, if a client sends ZPixmap format images of 4 bits_per_pixel and nibble swapping
                     32: is required, this routine does not swap the 4 bit nibbles as it should.
                     33: 
                     34: XXX */
                     35: 
                     36: static PutImageRequest(dpy, d, gc, image, req_xoffset,req_yoffset, x, y, req_width,
                     37:                                                                req_height)
                     38:     register Display *dpy;
                     39:     Drawable d;
                     40:     GC gc;
                     41:     register XImage *image;
                     42:     int x, y;
                     43:     unsigned int req_width, req_height;
                     44:     int req_xoffset, req_yoffset;
                     45: {
                     46:        register xPutImageReq *req;
                     47:        int total_xoffset;
                     48: 
                     49:        FlushGC(dpy, gc);
                     50:        GetReq (PutImage, req);
                     51:        /*
                     52:         * first set up the standard stuff in the request
                     53:         */
                     54:        req->drawable = d;
                     55:        req->gc = gc->gid;
                     56:        req->dstX = x;
                     57:        req->dstY = y;
                     58:        req->width = req_width;
                     59:        req->height = req_height;
                     60:        req->format = image->format;
                     61:        req->depth = image->depth;
                     62:         total_xoffset = image->xoffset + req_xoffset;
                     63:        switch (image->format) {
                     64:              long length;
                     65:              int i;
                     66:              case XYBitmap:
                     67:                /*
                     68:                 * If the client side format matches the screen, we win!
                     69:                 */
                     70:                if ((dpy->bitmap_unit == image->bitmap_unit) 
                     71:                    &&(dpy->bitmap_pad == image->bitmap_pad)
                     72:                    &&(dpy->byte_order == image->byte_order)
                     73:                    &&(dpy->bitmap_bit_order == image->bitmap_bit_order)
                     74:                    &&(image->width == req_width)
                     75:                    &&(total_xoffset < dpy->bitmap_pad)
                     76:                    &&(req_yoffset == 0)) {
                     77:                      length = image->bytes_per_line * req_height;
                     78:                      req->length += length >> 2;
                     79:                      req->leftPad = total_xoffset;
                     80:                      _XSend (dpy, image->data, length);
                     81:                  }
                     82:                else {
                     83:                       long nbytes;
                     84:                       char *row_addr;
                     85:                       register char *p;
                     86:                       char* tempbuf;
                     87:                       /*
                     88:                        * compute length of image data; round up to next length
                     89:                        */
                     90:                       req->leftPad = total_xoffset%dpy->bitmap_pad;
                     91:                       nbytes = length = ROUNDUP(req_width + req->leftPad,
                     92:                                                 dpy->bitmap_pad) >> 3;
                     93:                       length *= req_height;
                     94:                       req->length += length >> 2;
                     95: 
                     96:                        /*Get space to put the image*/
                     97: 
                     98:                       tempbuf = p = _XAllocScratch (dpy, 
                     99:                                (unsigned long)(length));
                    100:                        
                    101:                       /*Figure out where to start*/
                    102: 
                    103:                       row_addr = (image->data)+
                    104:                              (image->bytes_per_line*req_yoffset) +
                    105:                              ((total_xoffset - req->leftPad)>>3);
                    106: 
                    107:                       /* Now copy the desired (sub)image into the buffer */
                    108: 
                    109:                       for (i = 0; i < req_height; 
                    110:                                i++, row_addr += image->bytes_per_line,p+=nbytes) {
                    111:                           bcopy (row_addr, p, (int)nbytes);
                    112:                           if (image->bitmap_bit_order
                    113:                             != dpy->bitmap_bit_order) _swapbits (
                    114:                                (unsigned char *)p, image->bytes_per_line);
                    115: #ifdef notdef
                    116:                           if ((image->byte_order != image->bitmap_bit_order) ||
                    117:                               (dpy->byte_order != dpy->bitmap_bit_order))
                    118:                           {
                    119:                             /* XXX swapping missing XXX */
                    120:                           }
                    121: #endif
                    122:                        }
                    123:                        _XSend(dpy,tempbuf,length);
                    124:               }
                    125:                  
                    126:                break;
                    127: 
                    128:              case XYPixmap:    /* not yet implemented */
                    129:                /*
                    130:                 * If the client side format matches the screen, we win!
                    131:                 */
                    132:                if ((dpy->bitmap_unit == image->bitmap_unit) 
                    133:                    &&(dpy->bitmap_pad == image->bitmap_pad)
                    134:                    &&(dpy->byte_order == image->byte_order)
                    135:                    &&(dpy->bitmap_bit_order == image->bitmap_bit_order)
                    136:                    &&(image->width == req_width)
                    137:                    &&(total_xoffset < dpy->bitmap_pad)
                    138:                    &&(req_yoffset == 0)) {
                    139:                      length = image->bytes_per_line * req_height * 
                    140:                                                                image->depth;
                    141:                      req->length += length >> 2;
                    142:                      req->leftPad = total_xoffset;
                    143:                      _XSend (dpy, image->data, length);
                    144:                  }
                    145:                else {
                    146:                       long nbytes;
                    147:                       char *row_addr;
                    148:                       register char *p;
                    149:                       char* tempbuf;
                    150:                       int bytes_per_plane,j;
                    151:                       /*
                    152:                        * compute length of image data; round up to next length
                    153:                        */
                    154:                       req->leftPad = total_xoffset%dpy->bitmap_pad;
                    155:                       nbytes = length = ROUNDUP(req_width + req->leftPad,
                    156:                                                 dpy->bitmap_pad) >> 3;
                    157:                       length *= req_height * image->depth;
                    158:                       req->length += length >> 2;
                    159:                       bytes_per_plane = image->bytes_per_line * image->height;
                    160: 
                    161:                        /*Get space to put the image*/
                    162: 
                    163:                       tempbuf = p = _XAllocScratch (dpy, 
                    164:                                (unsigned long)(length));
                    165: 
                    166:                       /* Loop on planes */
                    167:                        
                    168:                       for (j = 0; j < image->depth; j++) {
                    169: 
                    170:                           /*Figure out where to start in image structure*/
                    171: 
                    172:                           row_addr = (image->data)+
                    173:                                  (j * bytes_per_plane) +
                    174:                                  (image->bytes_per_line*req_yoffset) +
                    175:                                  ((total_xoffset - req->leftPad)>>3);
                    176: 
                    177:                           /* Now copy a plane of the desired (sub)image into the
                    178:                              buffer */
                    179: 
                    180:                           for (i = 0; i < req_height; 
                    181:                                    i++, row_addr += image->bytes_per_line,p+=nbytes) {
                    182:                               bcopy (row_addr, p, (int)nbytes);
                    183:                               if (image->bitmap_bit_order
                    184:                                 != dpy->bitmap_bit_order) _swapbits (
                    185:                                    (unsigned char *)p, nbytes);
                    186: #ifdef notdef
                    187:                               if ((image->byte_order != image->bitmap_bit_order) ||
                    188:                                   (dpy->byte_order != dpy->bitmap_bit_order))
                    189:                               {
                    190:                                 /* XXX swapping missing XXX */
                    191:                               }
                    192: #endif
                    193:                            }
                    194:                        }
                    195:                        _XSend(dpy,tempbuf,length);
                    196:               }
                    197:                  
                    198:                break;
                    199: 
                    200:              case ZPixmap:
                    201:                /*
                    202:                 * If the client side format matches the screen, we win!
                    203:                 */
                    204:                /* XXX is this right? */
                    205:                req->leftPad = 0;
                    206: 
                    207:                if ((dpy->byte_order == image->byte_order)
                    208:                   &&(dpy->bitmap_pad == image->bitmap_pad)) {
                    209:                    length = image->bytes_per_line * image->height;
                    210:                    req->length += length >> 2;
                    211:                    _XSend (dpy, image->data, length);
                    212:                  }
                    213:                else {
                    214:                    /*
                    215:                     * since we have no other way to go, we presume format
                    216:                     * of image matches format of drawable....  Sure makes
                    217:                     * things simpler.
                    218:                     */
                    219:                    long nbytes;
                    220:                    unsigned char *row = (unsigned char *) (image->data + req_yoffset * image->bytes_per_line);
                    221:                    unsigned char *tempbuf, *p;
                    222:                    int bit_xoffset, pseudoLeftPad, byte_xoffset;
                    223:                    int j;
                    224: 
                    225:                    nbytes = length = ROUNDUP(req_width * image->bits_per_pixel, dpy->bitmap_pad) >> 3;
                    226:     
                    227:                    tempbuf = p = (unsigned char *)_XAllocScratch(dpy, (unsigned long)nbytes * req_height);
                    228: 
                    229:                    length *= req_height;
                    230:                    req->length += length >> 2;
                    231: 
                    232:                    bit_xoffset = req_xoffset * image->bits_per_pixel;
                    233:                    pseudoLeftPad = bit_xoffset % 8;
                    234:                    byte_xoffset = bit_xoffset >> 3;
                    235: 
                    236:                    for (i = 0; i < req_height; 
                    237:                                    i++, row += image->bytes_per_line, p+=nbytes) {
                    238:                        /*
                    239:                         * Move the data somewhere we can reformat it.
                    240:                         */
                    241:                     
                    242: 
                    243:                    if (pseudoLeftPad != 0)
                    244:                    {
                    245:                        for ( j=0; j < nbytes; j++)
                    246:                        {
                    247:                            p[j] = (row[byte_xoffset + j] >> (pseudoLeftPad)) | (row[byte_xoffset + j + 1] << ( 8 - pseudoLeftPad));
                    248:                        }
                    249:                
                    250:                    }
                    251:                    else
                    252:                        bcopy (row + ((req_xoffset * image->bits_per_pixel) >> 3), p, (int)nbytes);
                    253:                        if (image->byte_order != dpy->byte_order) {
                    254:                          if(image->bits_per_pixel == 32) _swaplong(p, nbytes);
                    255:                          else if (image->bits_per_pixel == 24)
                    256:                              _swapthree (p, nbytes);
                    257:                          else if (image->bits_per_pixel == 16) 
                    258:                              _swapshort (p, nbytes);
                    259:                        }
                    260:                      }
                    261:                    _XSend(dpy, tempbuf, length);
                    262:                }
                    263:                break;
                    264:              default:  /* should never get here */
                    265:                (void) fputs ("unknown image type in XPutImage\n", stderr);
                    266:                exit(1);
                    267:                break;
                    268:        }
                    269: 
                    270:        SyncHandle();
                    271:        return;
                    272: }
                    273:        
                    274: 
                    275: char _reverse_byte[0x100] = {
                    276:        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
                    277:        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
                    278:        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
                    279:        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
                    280:        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
                    281:        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
                    282:        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
                    283:        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
                    284:        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
                    285:        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
                    286:        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
                    287:        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
                    288:        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
                    289:        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
                    290:        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
                    291:        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
                    292:        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
                    293:        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
                    294:        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
                    295:        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
                    296:        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
                    297:        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
                    298:        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
                    299:        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
                    300:        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
                    301:        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
                    302:        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
                    303:        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
                    304:        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
                    305:        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
                    306:        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
                    307:        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
                    308: };
                    309: 
                    310: 
                    311: _swapbits (b, n)
                    312:        register unsigned char *b;
                    313:        register long n;
                    314: {
                    315:        do {
                    316:                *b = _reverse_byte[*b];
                    317:                b++;
                    318:            } while (--n > 0);
                    319:        
                    320: }
                    321: 
                    322: _swapshort (bp, n)
                    323:      register char *bp;
                    324:      register long n;
                    325: {
                    326:        register char c;
                    327:        register char *ep = bp + n;
                    328:        do {
                    329:                c = *bp;
                    330:                *bp = *(bp + 1);
                    331:                bp++;
                    332:                *bp = c;
                    333:                bp++;
                    334:        }
                    335:        while (bp < ep);
                    336: }
                    337: 
                    338: _swaplong (bp, n)
                    339:      register char *bp;
                    340:      register long n;
                    341: {
                    342:        register char c;
                    343:        register char *ep = bp + n;
                    344:        register char *sp;
                    345:        do {
                    346:                sp = bp + 3;
                    347:                c = *sp;
                    348:                *sp = *bp;
                    349:                *bp++ = c;
                    350:                sp = bp + 1;
                    351:                c = *sp;
                    352:                *sp = *bp;
                    353:                *bp++ = c;
                    354:                bp += 2;
                    355:        }
                    356:        while (bp < ep);
                    357: }
                    358: 
                    359: _swapthree (bp, n)
                    360:      register char *bp;
                    361:      register long n;
                    362: {
                    363:        register char c;
                    364:        register char *ep = bp + n;
                    365:        do {
                    366:                c = *bp;
                    367:                *(bp + 2) = *bp;
                    368:                *bp = c;
                    369:                bp += 3;
                    370:        }
                    371:        while (bp < ep);
                    372: }
                    373: 
                    374: 
                    375: static int
                    376: BytesPerImageRow(dpy, image, req_width, req_xoffset)
                    377:     Display *dpy;
                    378:     XImage *image;
                    379:     unsigned int req_width;
                    380:     int req_xoffset;
                    381: {
                    382:     int total_offset = image->xoffset + req_xoffset;
                    383:     int left_pad = total_offset % dpy->bitmap_pad;
                    384:     int nbytes;
                    385: 
                    386:     switch (image->format) 
                    387:     {
                    388:        case XYBitmap:
                    389:             nbytes = ROUNDUP(req_width + left_pad, dpy->bitmap_pad) >> 3;
                    390:            break;
                    391: 
                    392:         case XYPixmap:
                    393:            nbytes = (ROUNDUP(req_width + left_pad, dpy->bitmap_pad) >> 3)
                    394:                * image->depth;
                    395:            break;
                    396:        case ZPixmap:
                    397:             nbytes = ROUNDUP(req_width * image->bits_per_pixel, 
                    398:                dpy->bitmap_pad) >> 3;
                    399:           break;
                    400:        default:        /* should never get here */
                    401:            (void) fputs ("unknown image type in XPutImage\n", stderr);
                    402:            exit(1);
                    403:            break;
                    404:     }
                    405:  
                    406:     return nbytes;
                    407: }
                    408:           
                    409: static void
                    410: PutSubImage (dpy, d, gc, image, req_xoffset,req_yoffset, x, y, req_width,
                    411:                                                                req_height)
                    412:     register Display *dpy;
                    413:     Drawable d;
                    414:     GC gc;
                    415:     register XImage *image;
                    416:     int x, y;
                    417:     unsigned int req_width, req_height;
                    418:     int req_xoffset, req_yoffset;
                    419: 
                    420: {
                    421:     int total_offset = image->xoffset + req_xoffset;
                    422:     int left_pad = total_offset % dpy->bitmap_pad;
                    423:     int BytesPerRowOfImage;
                    424:     int BytesInRequestAvailableForImage;
                    425:     int MaximumRequestSizeInBytes =
                    426:         (65536 < dpy->max_request_size) ? (65536 << 2)
                    427:         :( dpy->max_request_size << 2);
                    428: 
                    429:     if ((req_width == 0) || (req_height == 0)) return;
                    430:     
                    431:     BytesInRequestAvailableForImage = MaximumRequestSizeInBytes -
                    432:        sizeof(xPutImageReq);
                    433: 
                    434:     if (BytesInRequestAvailableForImage < (dpy->bitmap_pad >> 3))
                    435:     {
                    436:        /* This is a ridiculous case that should never happen, but just in
                    437:                case. */
                    438:                (void) fputs("Request size is simply too small to put image\n",
                    439:                        stderr);
                    440:                exit(1);
                    441:     }
                    442:   
                    443:     BytesPerRowOfImage = BytesPerImageRow(dpy, image, req_width, req_xoffset);
                    444: 
                    445:     if ((BytesPerRowOfImage * req_height) <= BytesInRequestAvailableForImage)
                    446:     {
                    447:         PutImageRequest(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, 
                    448:            req_width, req_height);
                    449:     }
                    450:     else
                    451:     {
                    452:        if (req_height > 1)
                    453:         {
                    454:            int SubImageHeight = BytesInRequestAvailableForImage /
                    455:                    BytesPerRowOfImage;
                    456: 
                    457:            if (SubImageHeight < 1) SubImageHeight = 1;
                    458: 
                    459:            PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, 
                    460:                req_width, SubImageHeight);
                    461: 
                    462:            PutSubImage(dpy, d, gc, image, req_xoffset, 
                    463:                req_yoffset + SubImageHeight, x, y + SubImageHeight, req_width,
                    464:                req_height - SubImageHeight);
                    465:        }
                    466:        else
                    467:        {
                    468:            int SubImageWidth = ((BytesInRequestAvailableForImage << 3) /
                    469:                dpy->bitmap_pad) * dpy->bitmap_pad - left_pad;
                    470: 
                    471:            PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, 
                    472:                SubImageWidth, req_height);
                    473: 
                    474:            PutSubImage(dpy, d, gc, image, req_xoffset + SubImageWidth, 
                    475:                req_yoffset, x + SubImageWidth, y, req_width - SubImageWidth, 
                    476:                req_height);
                    477:        }
                    478:     }
                    479:     return;
                    480: }
                    481: 
                    482: XPutImage (dpy, d, gc, image, req_xoffset,req_yoffset, x, y, req_width,
                    483:                                                                req_height)
                    484:     register Display *dpy;
                    485:     Drawable d;
                    486:     GC gc;
                    487:     register XImage *image;
                    488:     int x, y;
                    489:     unsigned int req_width, req_height;
                    490:     int req_xoffset, req_yoffset;
                    491: 
                    492: {
                    493:     /* Does the display need to be locked and the GC flushed here? */
                    494:     LockDisplay(dpy);
                    495:     if ((req_width == 0) || (req_height == 0)) return;
                    496: 
                    497:     PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width,
                    498:        req_height);
                    499: 
                    500:     /* Does the display need to be unlocked here? Are any status values
                    501:        returned? */
                    502:     UnlockDisplay(dpy);
                    503:     return;
                    504: }

unix.superglobalmegacorp.com

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