1: /* stack.c 2: * 3: * Copyright (c) 1984, 1985 Xerox Corp. 4: * 5: * This module manipulates the RES stack. 6: * 7: */ 8: 9: #include "stack.h" 10: 11: extern long filepos; 12: extern unsigned char **malloc(); 13: 14: /* Private procedures defined in this module. */ 15: extern unsigned char *makeitem(); 16: extern double readdouble(); 17: 18: struct item 19: { 20: int length; /* total byte length of this stack item. */ 21: struct item *next; /* next element on the stack. */ 22: int type; /* stack element type. */ 23: int subtype; /* subtype within this type. */ 24: }; 25: 26: struct number 27: { 28: int length; 29: struct item *next; 30: int type; 31: int subtype; 32: unsigned char nbytes; 33: unsigned char num[1]; 34: }; 35: 36: struct string 37: { 38: int length; 39: struct item *next; 40: int type; 41: int subtype; 42: char s[1]; 43: /* the string follows here, above char gives room for terminating null */ 44: }; 45: 46: struct vector 47: { 48: int length; 49: struct item *next; 50: int type; 51: int subtype; 52: int depth; 53: }; 54: 55: struct integers 56: { 57: int length; 58: struct item *next; 59: int type; 60: int subtype; 61: int bytesPerInteger; 62: long bytepos; 63: long bytelength; 64: }; 65: 66: 67: struct transformation 68: { 69: int length; 70: struct item *next; 71: int type; 72: int subtype; 73: double a; 74: double b; 75: double c; 76: double d; 77: double e; 78: double f; 79: }; 80: 81: static struct item *stack = (struct item *) 0; 82: 83: #define err0 "(%d) stack: pop called on an empty stack!\n" 84: #define err1 "(%d) stack: expecting type (%s, %s), got (%d, %d)!\n" 85: #define err2 "(%d) stack: should be 8 elements in pixelarray, got %d!\n" 86: 87: 88: /* 89: * Items on the stack. 90: * 91: */ 92: 93: stackempty() 94: { 95: return(stack == (struct item *) 0); 96: } 97: 98: unsigned char *pop(type, subtype) 99: int type, subtype; 100: { 101: unsigned char *ptr; 102: struct item *pitem; 103: 104: pitem = stack; 105: 106: if (pitem == (struct item *) 0) 107: error(err0, filepos); 108: 109: stack = pitem->next; 110: ptr = (unsigned char *) pitem; 111: checktype(ptr, type, subtype); 112: return (ptr); 113: } 114: 115: push(pitem) 116: struct item *pitem; 117: { 118: pitem->next = stack; 119: stack = pitem; 120: } 121: 122: unsigned char *duplicate(from) 123: unsigned char *from; 124: { 125: int n; 126: unsigned char *to; 127: to = makeitem(getlength(from), gettype(from), getsubtype(from)); 128: for (n=0; n < getlength(from); n++) to[n] = from[n]; 129: return (to); 130: } 131: 132: gettype(pitem) 133: struct item *pitem; 134: { 135: return(pitem->type); 136: } 137: 138: getsubtype(pitem) 139: struct item *pitem; 140: { 141: return(pitem->subtype); 142: } 143: 144: getlength(pitem) 145: struct item *pitem; 146: { 147: return(pitem->length); 148: } 149: 150: checktype(ptr, type, subtype) 151: unsigned char *ptr; 152: int type, subtype; 153: { 154: int intype, insubtype, problem; 155: char *typename, *subtypename; 156: intype = gettype(ptr); 157: insubtype = getsubtype(ptr); 158: problem = 0; 159: if (type) 160: { 161: if ((type & intype) == 0) problem = 1; 162: if ((subtype != 0) && ((subtype & insubtype) == 0)) problem = 1; 163: } 164: if (problem) 165: { 166: typename = gettypename(type); 167: subtypename = getsubtypename(subtype); 168: error(err1, filepos, typename, subtypename, intype, insubtype); 169: } 170: } 171: 172: char *gettypename(type) 173: int type; 174: { 175: switch (type) 176: { 177: case 0: return("undefined"); 178: case 1: return("number"); 179: case 2: return("string"); 180: case 4: return("vector"); 181: case 8: return("operator"); 182: case 16: return("color"); 183: case 32: return("pixelarray"); 184: case 64: return("transformation"); 185: case 128: return("integers"); 186: default: return("unknown"); 187: }; 188: } 189: 190: char *getsubtypename(subtype) 191: int subtype; 192: { 193: switch (subtype) 194: { 195: case 0: return("undefined"); 196: case 1: return("integer"); 197: case 2: return("rational"); 198: case 4: return("identifier"); 199: case 8: return("string"); 200: case 16: return("general"); 201: case 32: return("integers"); 202: case 64: return("samples"); 203: case 128: return("decompressop"); 204: case 256: return("colorop"); 205: case 512: return("colormodelop"); 206: case 1024: return("value"); 207: case 2048: return("name"); 208: case 4096: return("operator"); 209: default: return("unknown"); 210: }; 211: } 212: 213: 214: /* 215: * Numbers 216: * 217: */ 218: 219: unsigned char *makenumber(nbytes, array, subtype) 220: int nbytes; 221: unsigned char *array; 222: { 223: int n; 224: unsigned char *ptr; 225: struct number *pnumber; 226: ptr = makeitem(sizeof(struct number)+nbytes, type_number, subtype); 227: pnumber = (struct number *) ptr; 228: pnumber->nbytes = nbytes; 229: for (n=0; n < nbytes; n++) pnumber->num[n] = array[n]; 230: return(ptr); 231: } 232: 233: getnumlen(pnumber) 234: struct number *pnumber; 235: { 236: checktype(pnumber, type_number, 0); 237: return(pnumber->nbytes); 238: } 239: 240: unsigned char *getnumber(pnumber) 241: struct number *pnumber; 242: { 243: checktype(pnumber, type_number, 0); 244: return(pnumber->num); 245: } 246: 247: getint(ptr) 248: unsigned char *ptr; 249: { 250: int result; 251: result = getdouble(ptr); 252: return (result); 253: } 254: 255: double getdouble(pnumber) 256: struct number *pnumber; 257: { 258: int nbytes; 259: double result, numerator, denominator; 260: checktype(pnumber, type_number, subtype_integer | subtype_rational); 261: switch (getsubtype(pnumber)) 262: { 263: case subtype_integer: 264: result = readdouble(pnumber->nbytes, pnumber->num); 265: break; 266: case subtype_rational: 267: nbytes = pnumber->nbytes/2; 268: numerator = readdouble(nbytes, pnumber->num); 269: denominator = readdouble(nbytes, pnumber->num+nbytes); 270: result = numerator/denominator; 271: break; 272: } 273: return (result); 274: } 275: 276: double getnumerator(pnumber) 277: unsigned char *pnumber; 278: { 279: int nbytes; 280: double numerator; 281: checktype(pnumber, type_number, subtype_rational); 282: nbytes = getnumlen(pnumber)/2; 283: numerator = readdouble(nbytes, getnumber(pnumber)); 284: return (numerator); 285: } 286: 287: double getdenominator(pnumber) 288: unsigned char *pnumber; 289: { 290: int nbytes; 291: double denominator; 292: checktype(pnumber, type_number, subtype_rational); 293: nbytes = getnumlen(pnumber)/2; 294: denominator = readdouble(nbytes, getnumber(pnumber)+nbytes); 295: return (denominator); 296: } 297: 298: 299: /* 300: * Strings 301: * 302: */ 303: 304: unsigned char *makestring(string, subtype) 305: char *string; 306: int subtype; 307: { 308: unsigned char *ptr; 309: struct string *pstring; 310: ptr = makeitem(sizeof(struct string)+strlen(string), type_string, subtype); 311: pstring = (struct string *) ptr; 312: strcpy(pstring->s, string); 313: return(ptr); 314: } 315: 316: unsigned char *makeidentifier(ptr, prefix) 317: unsigned char *ptr; 318: char *prefix; 319: { 320: char *string; 321: int n, len, depth; 322: unsigned char *composite, **array; 323: depth = getdepth(ptr); 324: array = getvector(ptr); 325: len = strlen(prefix); 326: for (n=0; n < depth; n++) 327: { 328: string = getstring(array[n], subtype_identifier); 329: len += strlen(string)+1; /* add one for '/' character */ 330: } /* added one too many, gives extra space */ 331: string = (char *) malloc(len+1); /* add one for null character */ 332: strcpy(string, prefix); 333: for (n=0; n < depth; n++) 334: { 335: if (n) strcat(string, "/"); 336: strcat(string, getstring(array[n], subtype_identifier)); 337: } 338: free(array); 339: composite = makestring(string, subtype_identifier); 340: free(string); 341: return(composite); 342: } 343: 344: char *getstring(pstring, subtype) 345: struct string *pstring; 346: { 347: checktype(pstring, type_string, subtype); 348: return(pstring->s); 349: } 350: 351: 352: /* 353: * Vectors 354: * 355: */ 356: 357: unsigned char *makevector(array, type, subtype) 358: unsigned char **array; 359: int type, subtype; 360: { 361: int n, m, len, depth; 362: unsigned char *ptr, *to, *from; 363: struct vector *pvector; 364: len = sizeof(struct vector); 365: for (depth=0; array[depth] != (unsigned char *) 0; depth++) 366: len += getlength(array[depth]); 367: ptr = makeitem(len, type, subtype); 368: pvector = (struct vector *) ptr; 369: pvector->depth = depth; 370: to = ptr; 371: to += sizeof(struct vector); 372: for (n=0; n < depth; n++) 373: { 374: from = array[n]; 375: len = getlength(from); 376: for (m=0; m < len; m++) to[m] = from[m]; 377: to += len; 378: } 379: return(ptr); 380: } 381: 382: unsigned char **getvector(from) 383: unsigned char *from; 384: { 385: int n, m, depth, len; 386: unsigned char *to, **array; 387: depth = getdepth(from); 388: array = malloc((depth+1)*sizeof(unsigned char *)); 389: from += sizeof(struct vector); 390: for (n=0; n < depth; n++) 391: { 392: array[n] = from; 393: len = getlength(from); 394: from += len; 395: } 396: array[depth] = (unsigned char *) 0; /* null terminated list */ 397: return(array); 398: } 399: 400: getdepth(pvector) 401: struct vector *pvector; 402: { 403: return(pvector->depth); 404: } 405: 406: 407: 408: /* 409: * Operators 410: * 411: */ 412: 413: unsigned char *makeoperator(array, subtype) 414: unsigned char **array; 415: int subtype; 416: { 417: unsigned char *ptr; 418: ptr = makevector(array, type_operator, subtype); 419: return(ptr); 420: } 421: 422: unsigned char **getoperator(ptr) 423: unsigned char *ptr; 424: { 425: unsigned char **array; 426: array = getvector(ptr); 427: return(array); 428: } 429: 430: 431: 432: 433: /* 434: * Pixel array 435: * 436: */ 437: 438: 439: unsigned char *makepixelarray(array) 440: unsigned char **array; 441: { 442: int depth; 443: unsigned char *ptr; 444: for (depth=0; array[depth] != (unsigned char *) 0; depth++) ; 445: if (depth != 8) error(err2, filepos, depth); 446: ptr = makevector(array, type_pixelarray, 0); 447: return(ptr); 448: } 449: 450: unsigned char *makeselect(max, samples) 451: int max, samples; 452: { 453: int n, mask, depth; 454: unsigned char *ptr, **array, value; 455: array = malloc((max+1)*sizeof(unsigned char *)); 456: depth = 0; 457: for (n=0; n < max; n++) 458: { 459: value = n; 460: mask = 1 << n; 461: if (samples & mask) 462: { 463: array[depth] = makenumber(1, &value, subtype_integer); 464: depth++; 465: } 466: } 467: array[depth] = (unsigned char *) 0; /* null terminated list */ 468: ptr = makevector(array, type_vector, subtype_general); 469: for (n=0; n < depth; n++) free(array[n]); 470: free(array); 471: return(ptr); 472: } 473: 474: unsigned char **getpixelarray(from) 475: unsigned char *from; 476: { 477: if (getdepth(from) != 8) error(err2, filepos, getdepth(from)); 478: return(getvector(from)); 479: } 480: 481: 482: /* 483: * Transformations 484: * 485: */ 486: 487: unsigned char *maketransformation(a, b, c, d, e, f) 488: double a, b, c, d, e, f; 489: { 490: unsigned char *ptr; 491: struct transformation *ptransformation; 492: ptr = makeitem(sizeof(struct transformation), type_transformation, 0); 493: ptransformation = (struct transformation *) ptr; 494: ptransformation->a = a; 495: ptransformation->b = b; 496: ptransformation->c = c; 497: ptransformation->d = d; 498: ptransformation->e = e; 499: ptransformation->f = f; 500: return(ptr); 501: } 502: 503: double *gettransformation(ptransformation) 504: struct transformation *ptransformation; 505: { 506: double *array; 507: checktype(ptransformation, type_transformation, 0); 508: array = (double *) malloc(6*sizeof(double)); 509: array[0] = ptransformation->a; 510: array[1] = ptransformation->b; 511: array[2] = ptransformation->c; 512: array[3] = ptransformation->d; 513: array[4] = ptransformation->e; 514: array[5] = ptransformation->f; 515: return(array); 516: } 517: 518: 519: /* 520: * Integers 521: * 522: */ 523: 524: unsigned char *makeintegers(bytesPerInteger, bytepos, bytelength) 525: int bytesPerInteger; 526: long bytepos, bytelength; 527: { 528: unsigned char *ptr; 529: struct integers *pintegers; 530: ptr = makeitem(sizeof(struct integers), type_integers, 0); 531: pintegers = (struct integers *) ptr; 532: pintegers->bytesPerInteger = bytesPerInteger; 533: pintegers->bytepos = bytepos; 534: pintegers->bytelength = bytelength; 535: return(ptr); 536: } 537: 538: getbytesPerInteger(pintegers) 539: struct integers *pintegers; 540: { 541: checktype(pintegers, type_integers, 0); 542: return(pintegers->bytesPerInteger); 543: } 544: 545: long getbytepos(pintegers) 546: struct integers *pintegers; 547: { 548: checktype(pintegers, type_integers, 0); 549: return(pintegers->bytepos); 550: } 551: 552: long getbytelength(pintegers) 553: struct integers *pintegers; 554: { 555: checktype(pintegers, type_integers, 0); 556: return(pintegers->bytelength); 557: } 558: 559: 560: 561: /* 562: * Private procedures to this module. 563: * 564: */ 565: 566: static unsigned char *makeitem(length, type, subtype) 567: int length, type, subtype; 568: { 569: unsigned char *ptr; 570: struct item *pitem; 571: length = (length+sizeof(int)-1)/sizeof(int); 572: length *= sizeof(int); 573: ptr = (unsigned char *) malloc(length); 574: pitem = (struct item *) ptr; 575: pitem->length = length; 576: pitem->type = type; 577: pitem->subtype = subtype; 578: return(ptr); 579: } 580: 581: static double readdouble(nbytes, array) 582: int nbytes; 583: unsigned char *array; 584: { 585: int n, negative, temp; 586: double result; 587: negative = 0; 588: if (array[0] > 127) 589: { 590: negative = 1; 591: for (n=0; n < nbytes; n++) array[n] = ~array[n]; 592: } 593: result = 0; 594: for (n=0; n < nbytes; n++) 595: { 596: temp = array[n]; 597: result = 256.*result+(double)temp; 598: } 599: if (negative) result = -result-1; 600: return(result); 601: } 602: 603: 604: 605: /* Change Log 606: * 607: * K. Knox, 29-Mar-85 18:20:18, Created first version. 608: * K. Knox, 13-May-85 9:50:52, Fixed negative number bug in readdouble(). 609: * 610: * 611: * 612: */