Annotation of 43BSDTahoe/new/dipress/src/lib/libip/literal.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Interpress utilities
                      3:  *
                      4:  *  Written for Xerox Corporation by William LeFebvre
                      5:  *  24-May-1984
                      6:  *
                      7:  * Copyright (c) 1984, 1985, 1986 Xerox Corp.
                      8:  *
                      9:  * HISTORY
                     10:  * 15-Jul-86  Lee Moore (lee) at Xerox Webster Research Center
                     11:  *     Added AppendString1.
                     12:  *
                     13:  * 15-Jan-86  lee at Xerox, WRC
                     14:  *     Removed the rest of the Vax dependencies.
                     15:  *
                     16:  * 10-sep-85  lee moore
                     17:  *     Removed some dependencies on the Vax.
                     18:  *     Plenty more to be removed
                     19:  *
                     20:  * 29-apr-85  ed flint
                     21:  *     add conditional compilation for vax-11 c (vms)
                     22:  */
                     23: 
                     24: /*
                     25:  *  Subroutines to help build interpress files:
                     26:  *
                     27:  *  literal interface level - these routines produce interpress output at
                     28:  *                           the token level.
                     29:  */
                     30: 
                     31: /*
                     32:  *  NOTE:  Some of these "subroutines" are one-liners, so they are written
                     33:  *        as macros for better efficiency.
                     34:  */
                     35: 
                     36: # define Rational_max  1073741824
                     37: # define ip_Buffsize   1024
                     38: 
                     39: #ifndef vax11c
                     40: # include <sys/param.h>
                     41: # include <math.h>
                     42: # include <stdio.h>
                     43: # include <ctype.h>
                     44: #endif
                     45: 
                     46: # include "iptokens.h"
                     47: # include "literal.h"          /* macro definitions for some routines */
                     48: 
                     49: # ifndef NULL
                     50: # define NULL (char *)0
                     51: # endif
                     52: 
                     53: #ifdef vax11c
                     54: # define NOFILE 20
                     55: #endif
                     56: 
                     57: # define   No  0
                     58: # define   Yes 1
                     59: 
                     60: static int  ip_fd = -1;                        /* current Interpress file */
                     61: static char ip_filebuff[ip_Buffsize];  /* file buffer */
                     62: static char *ip_buffptr = NULL;                /* points in to ip_filebuff */
                     63: static int  ip_bytecnt;                        /* number of bytes in ip_filebuff */
                     64: static char ip_files[NOFILE] = { 0 };  /* marks which files are ip files */
                     65: 
                     66: /*
                     67:  *  Definitions for the primitives suggested in the Interpress standard
                     68:  *  (XSIS 048302).  The following primitives are defined with macros in
                     69:  *  "literal.h":
                     70:  *
                     71:  *     AppendComment
                     72:  *     AppendIdentifier
                     73:  *     AppendInsertFile
                     74:  *     AppendString
                     75:  */
                     76: 
                     77: 
                     78: /*
                     79:  * Append a string but interpret the escape characters (different from
                     80:  *     "AppendString").
                     81:  *
                     82:  * Algorithum: copy the old string, substituting escaped characters.
                     83:  */
                     84: 
                     85: AppendString1(string)
                     86: 
                     87: char *string; {
                     88:        char    *op,
                     89:                *new,
                     90:                *np;
                     91:        int     i,
                     92:                count;
                     93:        extern char *malloc();
                     94: 
                     95:        op = string;
                     96:        new = malloc((unsigned) strlen(string));
                     97:        np = new;
                     98:        count = 0;
                     99: 
                    100:        while (*op) {
                    101:                if (*op == '\\') {
                    102:                        /* an escaped backslash? */
                    103:                        if (*++op == '\\') {
                    104:                                *np++ = *op++;
                    105:                                count++;
                    106:                        } else {
                    107:                                i = 0;
                    108:                                if (isascii(*op) && isdigit(*op))
                    109:                                        i = *op++ - '0';
                    110:                                if (isascii(*op) && isdigit(*op))
                    111:                                        i = (*op++ - '0') + i*8;
                    112:                                if (isascii(*op) && isdigit(*op))
                    113:                                        i = (*op++ - '0') + i*8;
                    114:                                *np++ = (char) i;
                    115:                                count++;
                    116:                        }
                    117:                } else {
                    118:                        *np++ = *op++;
                    119:                        count++;
                    120:                }
                    121:        }
                    122: 
                    123:        append_Sequence(sequenceString, count, (unsigned char *) new);
                    124:        free(new);
                    125: }
                    126: 
                    127: 
                    128: /*
                    129:  * append an Op Code to the end of the master
                    130:  */
                    131: 
                    132: AppendOp(opcode)
                    133: 
                    134: int opcode;
                    135: 
                    136: {
                    137:     if (opcode > SHORT_OP_LIMIT)
                    138:     {
                    139:        /* has to be coded as a long op */
                    140:        append_n_byte_int((long)((LONG_OP << 8) | opcode), 2);
                    141:     }
                    142:     else
                    143:     {
                    144:        /* small enough to be a short op */
                    145:        append_byte((unsigned char)(SHORT_OP | opcode));
                    146:     }
                    147: }
                    148: 
                    149: 
                    150: AppendNumber(number)
                    151: 
                    152: double number;
                    153: 
                    154: {
                    155:     long d;
                    156:     double r;
                    157:     
                    158:     if (number == (double)(d = (long)number))
                    159:        AppendInteger(d);
                    160:     else
                    161:     {
                    162:        d = 1;
                    163:        while ((fabs(r = number * d) < Rational_max) &&
                    164:               (d < Rational_max) &&
                    165:               (r != (float)((int)(r))))
                    166:        {
                    167:            d <<= 1;
                    168:        }
                    169:        AppendRational((long)r, d);
                    170:     }
                    171: }
                    172: 
                    173: 
                    174: /*
                    175:  * note that although the routine is called AppendInteger, it is really
                    176:  * AppendLong.  This is because alot of code wants to use 32 bit numbers.
                    177:  * If you want to pass it a 16bit int on the Vax, that will work too.
                    178:  */
                    179: 
                    180: AppendInteger(number)
                    181: 
                    182: long number;
                    183: 
                    184: {
                    185:     if (number < INTEGER_MIN || number > INTEGER_MAX)
                    186:     {
                    187:        append_integer_sequence(number);
                    188:     }
                    189:     else
                    190:     {
                    191:        append_short_number((short) number);
                    192:     }
                    193: }
                    194: 
                    195: AppendRational(value, divisor)
                    196: 
                    197: long value, divisor;
                    198: 
                    199: {
                    200:     int len_value, len_divisor, len;
                    201: 
                    202:     len_value = bytes_in_int(value);
                    203:     len_divisor = bytes_in_int(divisor);
                    204: 
                    205:     len = len_value > len_divisor ? len_value : len_divisor;
                    206:     append_Sequence(sequenceRational, len << 1, (unsigned char *)NULL);
                    207:     append_n_byte_int(value, len);
                    208:     append_n_byte_int(divisor, len);
                    209: }
                    210: 
                    211: #ifdef notdef
                    212: AppendIntegerVector(vector, num)
                    213: 
                    214: int *vector;   /* ??? */
                    215: int  number;
                    216: 
                    217: {
                    218:     
                    219: }
                    220: #endif
                    221: 
                    222: 
                    223: /*
                    224:  * Append Packed Pixel Vector
                    225:  *     if the data pointer is null, then just append the header and leave it
                    226:  *     at that.
                    227:  */
                    228: 
                    229: AppendPPVector(length, bitsPerPixel, pixelsPerScanLine, data)
                    230: int length, bitsPerPixel, pixelsPerScanLine;
                    231: unsigned char *data;
                    232: {
                    233:        int preambleSize = 2*sizeof(short);     /* two short ints */
                    234: 
                    235:        append_Sequence(sequencePackedPixelVector, length + preambleSize,
                    236:                        (unsigned char *) 0);
                    237:        append_n_byte_int((long) bitsPerPixel, 2);
                    238:        append_n_byte_int((long) pixelsPerScanLine, 2);
                    239: 
                    240:        if (data != NULL)
                    241:                append_bytes(length, data);
                    242: }
                    243: 
                    244: /*
                    245:  * Append a Compressed Pixel Vector
                    246:  *     if the data pointer is null, then just append the header and leave it
                    247:  *     at that.
                    248:  */
                    249: AppendCPVector(length, breakTable, nRange, pixelsPerScanLine, data)
                    250: int length, breakTable, nRange, pixelsPerScanLine;
                    251: unsigned char *data;
                    252: {
                    253:        int preambleSize = 6;   /* three short ints */
                    254: 
                    255:        append_Sequence(sequenceCompressedPixelVector, length + preambleSize,
                    256:                        (unsigned char *) 0);
                    257:        append_n_byte_int((long) breakTable, 2);
                    258:        append_n_byte_int((long) nRange, 2);
                    259:        append_n_byte_int((long) pixelsPerScanLine, 2);
                    260: 
                    261:        if(data != NULL)
                    262:                append_bytes(length, data);
                    263: }
                    264: 
                    265: 
                    266: /*
                    267:  *  The remainder of this file contains lower level primitives:
                    268:  */
                    269: 
                    270: /*
                    271:  *  append_Sequence(type, length, buff)
                    272:  *
                    273:  *  Append a sequence descriptor and its data bytes.  The descriptor is of
                    274:  *  type "type" and length "length".  "Buff" points to the buffer containing
                    275:  *  the data.  If "Buff" is null, don't write any data.
                    276:  */
                    277: 
                    278: append_Sequence(type, length, buff)
                    279: 
                    280: int  type;
                    281: int  length;
                    282: unsigned char *buff;
                    283: 
                    284: {
                    285: # ifdef notnow
                    286:     /* some day, we should make this check, but not today */
                    287:     if ((length & 0x7f000000) != 0)
                    288:     {
                    289:        /* too big to fit in a long ... */
                    290:     }
                    291: # endif
                    292: 
                    293:     /* check for use of an obsolete feature of this program */
                    294:     if (length < 0)
                    295:     {
                    296:        fprintf(stderr, "negative sequence!\n");
                    297:        abort();
                    298:     }
                    299: 
                    300:     if ((length & 0x7fffff00) != 0)
                    301:     {
                    302:        /* too big to fit in a short sequence */
                    303:        append_byte((unsigned char) (LONG_SEQUENCE | type));
                    304:        append_n_byte_int((long) length, 3);
                    305:     }
                    306:     else
                    307:     {
                    308:        append_byte((unsigned char) (SHORT_SEQUENCE | type));
                    309:        append_byte((unsigned char) length);
                    310:     }
                    311: 
                    312:     /* tack on data, if any */
                    313:     if (buff != NULL)
                    314:         append_bytes(length, buff);
                    315: }
                    316: 
                    317: 
                    318: /*
                    319:  * append_integer_sequence(number)
                    320:  *     A special version of append_sequence that handles integers.  Integers
                    321:  *     must be treated differently because the natural representation of an
                    322:  *     integer for a particular machine maybe byte swapped relative to the
                    323:  *     Xerox standard.
                    324:  */
                    325: append_integer_sequence(number)
                    326: 
                    327: long number;
                    328: 
                    329: {
                    330:     int length = bytes_in_int(number);
                    331: 
                    332:     append_byte((unsigned char) (SHORT_SEQUENCE | sequenceInteger));
                    333:     append_byte((unsigned char) length);
                    334:     append_n_byte_int(number, length);
                    335: }
                    336: 
                    337: /*
                    338:  * append_n_byte_int(number, length)
                    339:  *     Append N bytes of an integer to the interpress master.
                    340:  */
                    341: 
                    342: append_n_byte_int(number, length)
                    343: 
                    344: long number;
                    345: int length;    /* measured in bytes */
                    346: 
                    347: {
                    348:     switch( length ) {
                    349:        case 4:
                    350:                append_byte((unsigned char) (number >> 24));
                    351:        case 3:
                    352:                append_byte((unsigned char) (number >> 16));
                    353:        case 2:
                    354:                append_byte((unsigned char) (number >>  8));
                    355:        case 1:
                    356:                append_byte((unsigned char) number);
                    357:                break;
                    358:        default:
                    359:                fprintf(stderr, "append_n_byte_int: asked to append %d bytes\n", length);
                    360:        }
                    361: }
                    362:        
                    363: 
                    364: /*
                    365:  *  append_byte(value) - write out a byte
                    366:  */
                    367: 
                    368: append_byte(value)
                    369: 
                    370: unsigned char value;
                    371: 
                    372: {
                    373:     *ip_buffptr++ = value;
                    374:     if (++ip_bytecnt == ip_Buffsize)
                    375:     {
                    376:        if( write(ip_fd, ip_filebuff, ip_Buffsize) != ip_Buffsize )
                    377:                perror("iplib");
                    378: 
                    379:        ip_bytecnt = 0;
                    380:        ip_buffptr = ip_filebuff;
                    381:     }
                    382: }
                    383: 
                    384: /*
                    385:  *  append_bytes(length, buff) - write the buffer of bytes pointed to by
                    386:  *                              "buff" with length "length".
                    387:  */
                    388: 
                    389: append_bytes(length, buff)
                    390: 
                    391: int length;
                    392: unsigned char *buff;
                    393: 
                    394: {
                    395:     while (length-- > 0)
                    396:     {
                    397:        append_byte(*buff++);
                    398:     }
                    399: }
                    400: 
                    401: 
                    402: /* this routine assumes two's complement notation.
                    403:  * this routine sometime over estimates the size of an integer. why? 
                    404:  * is it the sign bit that must be watched out for?
                    405:  */
                    406: 
                    407: bytes_in_int(value)
                    408: 
                    409: long value;
                    410: 
                    411: {
                    412:     int i;
                    413:     long mask;
                    414: 
                    415:     if (value < 0)
                    416:     {
                    417:        /* takes the same space as its one's complemented value */
                    418:        value = ~value;
                    419:     }
                    420:     if (value == 0)
                    421:     {
                    422:        /* avoids infinite looping */
                    423:        return(1);
                    424:     }
                    425:     for (i = 4, mask = 0xff800000; (value & mask) == 0; i--, mask >>= 8)
                    426:        ;
                    427:     return(i);
                    428: }
                    429: 
                    430: /*
                    431:  *  ip_select(fd) - select file descriptor "fd" as the Interpress file for
                    432:  *                 later use by the i/o routines supplied in this library.
                    433:  */
                    434: 
                    435: ip_select(fd)
                    436: 
                    437: int fd;
                    438: 
                    439: {
                    440:     if (ip_fd != -1)
                    441:     {
                    442:        ip_flush();
                    443:     }
                    444: 
                    445:     /* set our idea of current file descriptor and initialize the buffer */
                    446:     ip_fd = fd;
                    447:     ip_buffptr = ip_filebuff;
                    448:     ip_bytecnt = 0;
                    449: 
                    450:     /* check for initialization */
                    451:     if (!ip_files[fd])
                    452:     {
                    453:        /* not an Intepress or RES file -- initialize it */
                    454:        append_bytes(strlen(IP_Header), (unsigned char *) IP_Header);
                    455:        ip_files[fd] = Yes;
                    456:     }
                    457: }
                    458: 
                    459: 
                    460: /*
                    461:  *  res_select(fd) - select file descriptor "fd" as the RES file for
                    462:  *                 later use by the i/o routines supplied in this library.
                    463:  */
                    464: 
                    465: res_select(fd)
                    466: 
                    467: int fd;
                    468: 
                    469: {
                    470:     if (ip_fd != -1)
                    471:     {
                    472:        ip_flush();
                    473:     }
                    474: 
                    475:     /* set our idea of current file descriptor and initialize the buffer */
                    476:     ip_fd = fd;
                    477:     ip_buffptr = ip_filebuff;
                    478:     ip_bytecnt = 0;
                    479: 
                    480:     /* check for initialization */
                    481:     if (!ip_files[fd])
                    482:     {
                    483:        /* not an RES or Interpress file -- initialize it */
                    484:        append_bytes(strlen(RES_Header), (unsigned char *) RES_Header);
                    485:        ip_files[fd] = Yes;
                    486:     }
                    487: }
                    488: 
                    489: /*
                    490:  *  ip_raw_select(fd) - same as ip_select, but no header is placed at the
                    491:  *                     front of the file.
                    492:  */
                    493: 
                    494: ip_raw_select(fd)
                    495: 
                    496: int fd;
                    497: 
                    498: {
                    499:     /* trick ip_select into thinking that it is already initialized */
                    500:     ip_files[fd] = Yes;
                    501: 
                    502:     /* do a normal select */
                    503:     ip_select(fd);
                    504: }
                    505: 
                    506: ip_close()
                    507: 
                    508: {
                    509:     if (ip_fd != -1)
                    510:     {
                    511:        ip_flush();
                    512:        ip_files[ip_fd] = No;
                    513:        (void) close(ip_fd);
                    514:        ip_fd = -1;
                    515:     }
                    516: }
                    517: 
                    518: ip_flush()
                    519: 
                    520: {
                    521:     /* flush the buffer */
                    522:     if (ip_Buffsize - ip_bytecnt > 0)
                    523:     {
                    524:        if( write(ip_fd, ip_filebuff, ip_bytecnt) != ip_bytecnt )
                    525:                perror("iplib");
                    526:     }
                    527: }

unix.superglobalmegacorp.com

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