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