⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 literal.c

📁 早期freebsd实现
💻 C
字号:
/* *  Interpress utilities * *  Written for Xerox Corporation by William LeFebvre *  24-May-1984 * * Copyright (c) 1984, 1985, 1986 Xerox Corp. * * HISTORY * 15-Jul-86  Lee Moore (lee) at Xerox Webster Research Center *	Added AppendString1. * * 15-Jan-86  lee at Xerox, WRC *	Removed the rest of the Vax dependencies. * * 10-sep-85  lee moore *	Removed some dependencies on the Vax. *	Plenty more to be removed * * 29-apr-85  ed flint *	add conditional compilation for vax-11 c (vms) *//* *  Subroutines to help build interpress files: * *  literal interface level - these routines produce interpress output at *			      the token level. *//* *  NOTE:  Some of these "subroutines" are one-liners, so they are written *	   as macros for better efficiency. */# define Rational_max	1073741824# define ip_Buffsize	1024#ifndef vax11c# include <sys/param.h># include <math.h># include <stdio.h># include <ctype.h>#endif# include "iptokens.h"# include "literal.h"		/* macro definitions for some routines */# ifndef NULL# define NULL (char *)0# endif#ifdef vax11c# define NOFILE 20#endif# define   No	0# define   Yes	1static int  ip_fd = -1;			/* current Interpress file */static char ip_filebuff[ip_Buffsize];	/* file buffer */static char *ip_buffptr = NULL;		/* points in to ip_filebuff */static int  ip_bytecnt;			/* number of bytes in ip_filebuff */static char ip_files[NOFILE] = { 0 };	/* marks which files are ip files *//* *  Definitions for the primitives suggested in the Interpress standard *  (XSIS 048302).  The following primitives are defined with macros in *  "literal.h": * *	AppendComment *	AppendIdentifier *	AppendInsertFile *	AppendString *//* * Append a string but interpret the escape characters (different from * 	"AppendString"). * * Algorithum: copy the old string, substituting escaped characters. */AppendString1(string)char *string; {	char	*op,		*new,		*np;	int	i,		count;	extern char *malloc();	op = string;	new = malloc((unsigned) strlen(string));	np = new;	count = 0;	while (*op) {		if (*op == '\\') {			/* an escaped backslash? */			if (*++op == '\\') {				*np++ = *op++;				count++;			} else {				i = 0;				if (isascii(*op) && isdigit(*op))					i = *op++ - '0';				if (isascii(*op) && isdigit(*op))					i = (*op++ - '0') + i*8;				if (isascii(*op) && isdigit(*op))					i = (*op++ - '0') + i*8;				*np++ = (char) i;				count++;			}		} else {			*np++ = *op++;			count++;		}	}	append_Sequence(sequenceString, count, (unsigned char *) new);	free(new);}/* * append an Op Code to the end of the master */AppendOp(opcode)int opcode;{    if (opcode > SHORT_OP_LIMIT)    {	/* has to be coded as a long op */	append_n_byte_int((long)((LONG_OP << 8) | opcode), 2);    }    else    {	/* small enough to be a short op */	append_byte((unsigned char)(SHORT_OP | opcode));    }}AppendNumber(number)double number;{    long d;    double r;        if (number == (double)(d = (long)number))	AppendInteger(d);    else    {	d = 1;	while ((fabs(r = number * d) < Rational_max) &&	       (d < Rational_max) &&	       (r != (float)((int)(r))))	{	    d <<= 1;	}	AppendRational((long)r, d);    }}/* * note that although the routine is called AppendInteger, it is really * AppendLong.  This is because alot of code wants to use 32 bit numbers. * If you want to pass it a 16bit int on the Vax, that will work too. */AppendInteger(number)long number;{    if (number < INTEGER_MIN || number > INTEGER_MAX)    {	append_integer_sequence(number);    }    else    {	append_short_number((short) number);    }}AppendRational(value, divisor)long value, divisor;{    int len_value, len_divisor, len;    len_value = bytes_in_int(value);    len_divisor = bytes_in_int(divisor);    len = len_value > len_divisor ? len_value : len_divisor;    append_Sequence(sequenceRational, len << 1, (unsigned char *)NULL);    append_n_byte_int(value, len);    append_n_byte_int(divisor, len);}#ifdef notdefAppendIntegerVector(vector, num)int *vector;	/* ??? */int  number;{    }#endif/* * Append Packed Pixel Vector *	if the data pointer is null, then just append the header and leave it *	at that. */AppendPPVector(length, bitsPerPixel, pixelsPerScanLine, data)int length, bitsPerPixel, pixelsPerScanLine;unsigned char *data;{	int preambleSize = 2*sizeof(short);	/* two short ints */	append_Sequence(sequencePackedPixelVector, length + preambleSize,			(unsigned char *) 0);	append_n_byte_int((long) bitsPerPixel, 2);	append_n_byte_int((long) pixelsPerScanLine, 2);	if (data != NULL)		append_bytes(length, data);}/* * Append a Compressed Pixel Vector *	if the data pointer is null, then just append the header and leave it *	at that. */AppendCPVector(length, breakTable, nRange, pixelsPerScanLine, data)int length, breakTable, nRange, pixelsPerScanLine;unsigned char *data;{	int preambleSize = 6;	/* three short ints */	append_Sequence(sequenceCompressedPixelVector, length + preambleSize,			(unsigned char *) 0);	append_n_byte_int((long) breakTable, 2);	append_n_byte_int((long) nRange, 2);	append_n_byte_int((long) pixelsPerScanLine, 2);	if(data != NULL)		append_bytes(length, data);}/* *  The remainder of this file contains lower level primitives: *//* *  append_Sequence(type, length, buff) * *  Append a sequence descriptor and its data bytes.  The descriptor is of *  type "type" and length "length".  "Buff" points to the buffer containing *  the data.  If "Buff" is null, don't write any data. */append_Sequence(type, length, buff)int  type;int  length;unsigned char *buff;{# ifdef notnow    /* some day, we should make this check, but not today */    if ((length & 0x7f000000) != 0)    {	/* too big to fit in a long ... */    }# endif    /* check for use of an obsolete feature of this program */    if (length < 0)    {	fprintf(stderr, "negative sequence!\n");	abort();    }    if ((length & 0x7fffff00) != 0)    {	/* too big to fit in a short sequence */	append_byte((unsigned char) (LONG_SEQUENCE | type));	append_n_byte_int((long) length, 3);    }    else    {	append_byte((unsigned char) (SHORT_SEQUENCE | type));	append_byte((unsigned char) length);    }    /* tack on data, if any */    if (buff != NULL)        append_bytes(length, buff);}/* * append_integer_sequence(number) *	A special version of append_sequence that handles integers.  Integers *	must be treated differently because the natural representation of an *	integer for a particular machine maybe byte swapped relative to the *	Xerox standard. */append_integer_sequence(number)long number;{    int length = bytes_in_int(number);    append_byte((unsigned char) (SHORT_SEQUENCE | sequenceInteger));    append_byte((unsigned char) length);    append_n_byte_int(number, length);}/* * append_n_byte_int(number, length) *	Append N bytes of an integer to the interpress master. */append_n_byte_int(number, length)long number;int length;	/* measured in bytes */{    switch( length ) {	case 4:		append_byte((unsigned char) (number >> 24));	case 3:		append_byte((unsigned char) (number >> 16));	case 2:		append_byte((unsigned char) (number >>  8));	case 1:		append_byte((unsigned char) number);		break;	default:		fprintf(stderr, "append_n_byte_int: asked to append %d bytes\n", length);	}}	/* *  append_byte(value) - write out a byte */append_byte(value)unsigned char value;{    *ip_buffptr++ = value;    if (++ip_bytecnt == ip_Buffsize)    {	if( write(ip_fd, ip_filebuff, ip_Buffsize) != ip_Buffsize )		perror("iplib");	ip_bytecnt = 0;	ip_buffptr = ip_filebuff;    }}/* *  append_bytes(length, buff) - write the buffer of bytes pointed to by *				 "buff" with length "length". */append_bytes(length, buff)int length;unsigned char *buff;{    while (length-- > 0)    {	append_byte(*buff++);    }}/* this routine assumes two's complement notation. * this routine sometime over estimates the size of an integer. why?  * is it the sign bit that must be watched out for? */bytes_in_int(value)long value;{    int i;    long mask;    if (value < 0)    {	/* takes the same space as its one's complemented value */	value = ~value;    }    if (value == 0)    {	/* avoids infinite looping */	return(1);    }    for (i = 4, mask = 0xff800000; (value & mask) == 0; i--, mask >>= 8)	;    return(i);}/* *  ip_select(fd) - select file descriptor "fd" as the Interpress file for *		    later use by the i/o routines supplied in this library. */ip_select(fd)int fd;{    if (ip_fd != -1)    {	ip_flush();    }    /* set our idea of current file descriptor and initialize the buffer */    ip_fd = fd;    ip_buffptr = ip_filebuff;    ip_bytecnt = 0;    /* check for initialization */    if (!ip_files[fd])    {	/* not an Intepress or RES file -- initialize it */	append_bytes(strlen(IP_Header), (unsigned char *) IP_Header);	ip_files[fd] = Yes;    }}/* *  res_select(fd) - select file descriptor "fd" as the RES file for *		    later use by the i/o routines supplied in this library. */res_select(fd)int fd;{    if (ip_fd != -1)    {	ip_flush();    }    /* set our idea of current file descriptor and initialize the buffer */    ip_fd = fd;    ip_buffptr = ip_filebuff;    ip_bytecnt = 0;    /* check for initialization */    if (!ip_files[fd])    {	/* not an RES or Interpress file -- initialize it */	append_bytes(strlen(RES_Header), (unsigned char *) RES_Header);	ip_files[fd] = Yes;    }}/* *  ip_raw_select(fd) - same as ip_select, but no header is placed at the *			front of the file. */ip_raw_select(fd)int fd;{    /* trick ip_select into thinking that it is already initialized */    ip_files[fd] = Yes;    /* do a normal select */    ip_select(fd);}ip_close(){    if (ip_fd != -1)    {	ip_flush();	ip_files[ip_fd] = No;	(void) close(ip_fd);	ip_fd = -1;    }}ip_flush(){    /* flush the buffer */    if (ip_Buffsize - ip_bytecnt > 0)    {	if( write(ip_fd, ip_filebuff, ip_bytecnt) != ip_bytecnt )		perror("iplib");    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -