1: /*
2: * Interpress utility
3: *
4: * Written for Xerox Corporation by William LeFebvre
5: *
6: * 7-June-1984
7: *
8: * Copyright (c) 1984, 1985 Xerox Corp.
9: *
10: * HISTORY
11: * 13-Jan-86 lee at Xerox, WRC
12: * Changed a call to strmpn to strncmp.
13: *
14: * 01-Dec-85 lee at Xerox, WRC
15: * Linted
16: *
17: * 11-oct-85 ed flint don't worry about version # in Interpress header
18: * look only for 'Interpress/Xerox/'
19: *
20: * 23-may-85 ed flint fixed bug in print_string_from_file & print_string
21: * that would strip off high byte of ch in isprint
22: *
23: * 8-apr-85 ed flint add -d option to dump pixel arrays
24: * conditional compilation for vax-11c (vms)
25: */
26:
27: /*
28: * iptotext - convert an encoded interpress file into readable text
29: */
30:
31: #ifdef vax11c
32: # include stdio
33: # include setjmp
34: # include ctype
35: # include "iptokens.h"
36: # include "ipnames.h"
37: #else
38: # include <stdio.h>
39: # include <setjmp.h>
40: # include <ctype.h>
41: # include "iptokens.h"
42: # include "ipnames.h"
43: #endif
44:
45: int hlen;
46: jmp_buf next_file;
47: FILE *file;
48: FILE *output;
49:
50: int errno; /* imported value */
51:
52: char *op_name();
53: int dump_pixel= 0;
54:
55: main(argc, argv)
56:
57: int argc;
58: char *argv[];
59:
60: {
61: int arg;
62: int temp;
63: char *outputname;
64:
65: hlen = strlen(IP_Header);
66:
67: outputname= 0;
68:
69: /* look for options */
70: for ( arg= 1; arg < argc; arg++ )
71: {
72: if ( argv[arg][0] == '-' )
73: {
74: switch(argv[arg][1])
75: {
76: case('o'):
77: case('O'):
78: if ( strlen(argv[arg]) > 2 )
79: outputname= &(argv[arg][2]);
80: else
81: outputname= argv[++arg];
82: break;
83:
84: case('d'):
85: case('D'):
86: dump_pixel= 1;
87: break;
88:
89: default:
90: fprintf(stderr,"invalid option %s\n",argv[arg]);
91: break;
92: }
93: }
94: else
95: {
96: break;
97: }
98: }
99:
100: /* open the output file */
101: if ( outputname != 0 )
102: {
103: if ((output = fopen(outputname, "w")) == NULL)
104: {
105: /* save errno value */
106: temp = errno;
107: fputs("iptotext: ", stderr);
108: errno = temp;
109: perror(outputname);
110: exit(1);
111: }
112: }
113: else
114: {
115: /* default output -- use stdout */
116: output = stdout;
117: }
118:
119: if (argc == 1)
120: {
121: file = stdin;
122: do_file();
123: (void) putc('\n', output);
124: }
125:
126: /* make the begin- and end-block names be upper case */
127: op_names[OP_beginBlock] = "BEGIN";
128: op_names[OP_endBlock] = "END";
129:
130: for ( ; arg < argc; arg++) /* assume arg is index of first file name */
131: {
132: if ((file = fopen(argv[arg], "r")) == NULL)
133: {
134: perror(argv[arg]);
135: continue; /* on to the next file */
136: }
137:
138: /* print pretty banner */
139: fprintf(output, "(File: \"%s\")\n", argv[arg]);
140:
141: do_file();
142: (void) fclose(file);
143: (void) putc('\n', output);
144: }
145: }
146:
147: do_file()
148:
149: {
150: # define Buffsize 256
151: unsigned char buff[Buffsize];
152: unsigned char *ptr;
153: int val;
154: int len;
155: int byte; /* has to be "int" for stdio EOF detection */
156: /* stdio is a pile! */
157:
158: /* for error recovery */
159: if (setjmp(next_file) != 0)
160: {
161: return;
162: }
163:
164: /* get the header */
165: for (hlen = 0, ptr = buff; hlen < Buffsize; hlen++)
166: {
167: if ((*ptr++ = getnoeofc(file)) == ' ')
168: break;
169: }
170: *ptr = '\0';
171:
172: /* display the header */
173: fputs("Header: ", output);
174: print_string(buff);
175:
176: /* check the validity of the header */
177: if (strncmp(buff, IP_Header, 17) != 0)
178: {
179: fprintf(output, " (INVALID HEADER!)");
180: }
181: (void) putc('\n', output);
182:
183: /* main loop */
184: while ((byte = getc(file)) != EOF)
185: {
186: if ((byte & 0200) == 0)
187: {
188: /* a short number */
189: val = (byte << 8) + getnoeofc(file) - INTEGER_ZERO;
190: fprintf(output, "%d\n", val);
191: }
192: else
193: {
194: /* something else */
195: switch(byte >> 5)
196: {
197: case (SHORT_OP >> 5):
198: fprintf(output, "%s\n", op_name(byte & 037));
199: break;
200:
201: case (LONG_OP >> 5):
202: val = ((byte & 037) << 8) + getnoeofc(file);
203: fprintf(output, "%s%s\n", op_name(val),
204: val == OP_beginBlock || val == OP_endBlock ?
205: " (block)" : "");
206: break;
207:
208: case (SHORT_SEQUENCE >> 5):
209: len = getnoeofc(file);
210: fputs("> ", output);
211: do_sequence(byte & 037, len);
212: break;
213:
214: case (LONG_SEQUENCE >> 5):
215: len = getnoeofc(file) << 16;
216: len += (getnoeofc(file) << 8);
217: len += getnoeofc(file);
218: fputs(">>", output);
219: do_sequence(byte & 037, len);
220: break;
221: }
222: }
223: }
224: }
225:
226: do_sequence(type, length)
227:
228: int type;
229: int length;
230:
231: {
232: int val;
233: int val2;
234:
235: switch(type)
236: {
237: case sequenceAdaptivePixelVector:
238: fprintf(output, "Adaptive Pixel Vector: (%d words) [\n", length/2);
239: print_words_from_file(file, length);
240: fputs("]\n", file);
241: break;
242:
243: case :
244: fputs("Comment: ", output);
245: print_string_from_file(file, length);
246: (void) putc('\n', output);
247: break;
248:
249: case sequenceCompressedPixelVector:
250: fprintf(output, "Compressed Pixel Vector: (%d words) [\n", length/2);
251: print_words_from_file(file, length);
252: fputs("]\n", file);
253: break;
254:
255: case sequenceContinued:
256: fprintf(output, "Continuing last sequence: ");
257: break;
258:
259: case sequenceIdentifier:
260: fprintf(output, "Identifier: ");
261: iocopy(length);
262: fputs("\n", output);
263: break;
264:
265: case sequenceInsertFile:
266: fputs("Insert file: ", output);
267: print_string_from_file(file, length);
268: (void) putc('\n', output);
269: break;
270:
271: case sequenceInteger:
272: val = getint(length);
273: fprintf(output, "Integer: %d\n", val);
274: (void) putc('\n', output);
275: break;
276:
277: case sequenceLargeVector:
278: #ifdef notdef
279: val = getnoeofc(file);
280: fprintf(output, "Large Pixel Vector: (%d words of %d bytes) [\n"
281: (length - 1) / val, val);
282: #endif
283: break;
284:
285: case sequencePackedPixelVector:
286: fprintf(output, "Packed Pixel Vector: (%d words) [\n", length/2);
287: print_words_from_file(file, length);
288: fputs("]\n", output);
289: break;
290:
291: case sequenceRational:
292: length >>= 1;
293: val = getint(length);
294: val2 = getint(length);
295: fprintf(output, "Rational: %d/%d ", val, val2);
296: if (val2 != 0)
297: {
298: fprintf(output, "(%f)\n", (float)val / (float)val2);
299: }
300: else
301: {
302: fputs("(???)\n", output);
303: }
304: break;
305:
306: case sequenceString:
307: fputs("String: ", output);
308: print_string_from_file(file, length);
309: (void) putc('\n', output);
310: break;
311: }
312: }
313:
314: iocopy(length)
315:
316: int length;
317:
318: {
319: int byte;
320:
321: while(length-- > 0)
322: {
323: byte = getnoeofc(file);
324: (void) putc(byte, output);
325: }
326: }
327:
328: getint(length)
329:
330: int length;
331:
332: {
333: int val;
334:
335: val = getnoeofc(file);
336:
337: if ((val & 0x80) != 0) {
338: /* this is a negative number -- extend the sign */
339: val |= (-1 & ~(0xFF));
340: }
341:
342: while (--length > 0) {
343: val <<= 8;
344: val |= getnoeofc(file);
345: }
346:
347: return(val);
348: }
349:
350: char *op_name(op_code)
351:
352: int op_code;
353:
354: {
355: static char nbuff[10];
356:
357: if (op_names[op_code] == NULL)
358: {
359: (void) sprintf(nbuff, "--Unknown op: %d--", op_code);
360: return(nbuff);
361: }
362: else
363: {
364: return(op_names[op_code]);
365: }
366: }
367:
368: getnoeofc(file)
369:
370: FILE *file;
371:
372: {
373: int val;
374:
375: #ifdef vax11c
376: val= getc(file);
377: if ( feof(file) )
378: #else
379: if ((val = getc(file)) == EOF)
380: #endif
381: {
382: fprintf(output, "Unexpected EOF!");
383: longjmp(next_file, 1);
384: }
385: return(val);
386: }
387:
388: print_string_from_file(file, length)
389:
390: FILE *file;
391: int length;
392:
393: {
394: register int ch;
395: register int val;
396:
397: (void) putc('"', output);
398: for (val = 0; val < length; val++)
399: {
400: ch = getnoeofc(file);
401: if ( ((ch & 0x80) == 0) && (isprint(ch)) )
402: {
403: if (ch == '"' || ch == '\\')
404: {
405: (void) putc('\\', output);
406: }
407: (void) putc(ch, output);
408: }
409: else
410: {
411: fprintf(output, "\\%03o", ch);
412: }
413: }
414: (void) putc('"', output);
415: }
416:
417: print_string(string)
418:
419: unsigned char *string;
420:
421: {
422: register unsigned char *ptr;
423: register unsigned char ch;
424:
425: (void) putc('"', output);
426: ptr = string;
427: while ((ch = *ptr++) != '\0')
428: {
429: if ( ((ch & 0x80) == 0) && (isprint(ch)) )
430: {
431: if (ch == '"')
432: {
433: (void) putc('\\', output);
434: }
435: (void) putc(ch, output);
436: }
437: else
438: {
439: fprintf(output, "\\%03o", ch);
440: }
441: }
442: (void) putc('"', output);
443: }
444:
445: print_words_from_file(file, length)
446:
447: FILE *file;
448: int length;
449:
450: {
451: int val;
452: int cnt = 0;
453:
454: if ( dump_pixel == 1 )
455: {
456: while (length > 0)
457: {
458: val = getnoeofc(file) << 8;
459: val += getnoeofc(file);
460:
461: fprintf(output, "%04x ", val);
462: if (++cnt > 12)
463: {
464: (void) fputc('\n',output);
465: cnt = 0;
466: }
467:
468: length -= 2;
469: }
470: }
471: else
472: {
473: while ( length > 0 )
474: {
475: val= getnoeofc(file);
476: length--;
477: }
478: }
479: }