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