|
|
1.1 root 1: /* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved. */
2: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T. */
3: /* The copyright notice does not imply actual or intended publication. */
4: /* AUTHORS: */
5: /* T. Thompson - ATT-BL HO - first versions */
6: /* Routines for generating PostScript from RLE. */
7: /* The routines at the bottom of this file, which */
8: /* do the actual conversion to postscript, were */
9: /* hacked out of 'sun2ps'. The original header */
10: /* giving credit to its authors is there. */
11:
12: /* The 'binary' version of the output is collected in a */
13: /* temporary file, which is then fed back to the routines */
14: /* that generate postscript in a run-length-encoded form. */
15: /* Ideally it should just convert the original run-length */
16: /* encoding directly, but the REAL bottleneck is the */
17: /* PostScript printer, of course. Printing an 800 by 800 */
18: /* pixel image takes 5 minutes. */
19:
20: #include <stdio.h>
21: #include <math.h>
22: #include <string.h>
23: #include "CPU.h"
24: #include "boole.h"
25: #include "limits.h" /* numeric extreme values */
26: #include "Units.h"
27: #include "Coord.h"
28: #include "pic.h"
29:
30: FILE *Fp, *tmpfile();
31: int Raswidth;
32: int Raslength;
33: int Rasbytes; /* bytes per row */
34: int Inv = 0;
35: int Aspect = 1; /* if non-zero, retain original aspect ratio */
36: int Land = 0; /* if non-zero, print in landscape mode */
37: char Revbyte[256];
38: /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */
39: char Revnib[16] = {
40: 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
41: };
42:
43: void
44: POST_start(h)
45: PIC_hdr *h;
46: {
47: int n, v;
48:
49: /* build a table of reversed bytes */
50: for ( n=0; n<256; n++ )
51: Revbyte[n] = Revnib[(n>>4)&0xf] | Revnib[n&0xf]<<4;
52:
53: h->bpl = (h->bpl+7)/8;
54: Rasbytes = h->bpl;
55: Raslength = h->bpl * h->bx.b.y;
56: Raswidth = h->bx.b.x;
57: postmain(1,NULL,Raswidth,h->bx.b.y);
58: #if CPU==SUN
59: Fp = tmpfile();
60: #else
61: Fp = fopen("tmp.postlib.0","rw");
62: #endif
63: }
64:
65: void
66: POST_end()
67: {
68: int c;
69: rewind(Fp);
70: (VOID) Encode(Raslength, Inv);
71: PrintPostScriptClosing();
72: fclose(Fp);
73: }
74:
75: /* write a full line of picture data, returning status: 1 OK, 0 EOF, -1 ERR */
76: int POST_wline(h,line)
77: PIC_hdr *h;
78: unsigned char *line;
79: { int stat;
80: if( (stat=fwrite(line,1,h->bpl,Fp)) == h->bpl) {
81: h->seek += h->bpl;
82: h->cy++;
83: return(1);
84: }
85: else { /* ERR */
86: err("write to fd%d stat%d",fileno(h->fp),stat);
87: if((stat>=0)&&(stat<h->bpl)) return(0 /*EOF*/);
88: else return(-1);
89: };
90: }
91:
92: /******************************************************************************
93: * *
94: * File: sun2ps.c *
95: * Author: Glenn Boysko *
96: * Organization: Case Western Reserve University *
97: * EMail: {decvax, sun}!mandrill!boysko *
98: * [email protected] *
99: * Created: Wed Mar 23 9:25pm *
100: * Contents: Sun Rasterfile to PostScript image (using a run-length *
101: * encoding scheme.) *
102: * *
103: * (Adapted from "postimage" filter by J. R. Bammi.) *
104: * *
105: * @(#)sun2ps.c 1.8
106: ******************************************************************************/
107:
108: /*
109: * Usage:
110: * sun2ps [-s sizex sizey] [-t transx transy] [-r rot] [-l] [-i] [-a] file ...
111: *
112: * -s sizex sizey = size of postscript image - default 7.5 x 10 inches.
113: * -t transx transy = translate image - default 0.5 0.5 inches
114: * -r rotate = rotate image - default 0 degress
115: * -l = landscape (overrides *all* settings.)
116: * -i = inverse image - default no inverse
117: * (Inverse enabled implies white on black.)
118: * -a = maintain correct aspect ratio - default none.
119: *
120: */
121:
122: /* Sun standard raster file format (as obtained by screendump(1)).
123: *
124: * Header (8 16-bit quantities)
125: * Color Map
126: * Image
127: *
128: */
129:
130: /* Header Format:
131: *
132: * ras_magic (int) Raster Magic number 0x59a66a95
133: * ras_width (int) Width of image in pixels.
134: * ras_height (int) Height of image in pixels.
135: * ras_depth (int) Bits per pixel. Either 1 or 8 bits.
136: * ras_length (int) Length of image in bytes.
137: * ras_type (int) Type of file. Assumed to be RT_STANDARD (1) if
138: * produced by a screendump command.
139: * ras_maptype (int) Type of color map.
140: * ras_maplength (int) Length of color map in bytes.
141: *
142: */
143:
144: /* Ras_maplength bytes of Color map data. */
145:
146: /* Ras_length bytes of Image data. */
147:
148: /* Buffer and Input Modes... */
149: #define LITERAL 0
150: #define COPY 1
151: #define IGNORE 2
152:
153: /* Transmission Variables. */
154: int BufCount;
155:
156: unsigned char Buffer[128],
157: CurrByte,
158: NextByte,
159: *BufferP = Buffer;
160:
161: /* Diagnostic Variables. */
162: int DiagNLongRuns = 0,
163: DiagMaxRunLength = 0,
164: DiagNumRuns = 0;
165: double DiagSumRunLength = 0;
166:
167: postmain(argc,argv,width,height)
168: int argc;
169: char **argv;
170: int width, height;
171: {
172: char *filename;
173: double sizex, sizey, transx, transy, rotate;
174:
175: extern double atof();
176:
177: filename = "STDIN";
178: sizex = 7.5;
179: sizey = 10.0;
180: transx = transy = 0.5;
181: rotate = 0.0;
182:
183: while(--argc > 0)
184: {
185: ++argv;
186: if((*argv)[0] == '-')
187: {
188: switch((*argv)[1])
189: {
190: case 'l':
191: case 'L':
192: Land = 1;
193: break;
194:
195: case 's':
196: case 'S':
197: sizex = atof(*++argv);
198: sizey = atof(*++argv);
199: argc -= 2;
200: break;
201:
202: case 't':
203: case 'T':
204: transx = atof(*++argv);
205: transy = atof(*++argv);
206: argc -= 2;
207: break;
208:
209: case 'r':
210: case 'R':
211: rotate = atof(*++argv);
212: argc--;
213: break;
214:
215: case 'I':
216: case 'i':
217: Inv = 1;
218: break;
219:
220: case 'A':
221: case 'a':
222: Aspect = 1;
223: break;
224:
225: default:
226: fprintf(stderr,"Illegal switch %c - ignored\n",
227: (*argv)[1]);
228: }
229: }
230: }
231: if (Land)
232: {
233: transx = 8.0;
234: transy = 0.5;
235: sizex = 10.0;
236: sizey = 7.5;
237: rotate = 90.0;
238: }
239: if (Aspect) {
240: if ((sizex / width) < (sizey / height)) {
241: sizey = sizex * (height * 1.0 / width);
242: }
243: else {
244: sizex = sizey * (width * 1.0 / height);
245: }
246: }
247: PrintPostScriptRoutines(height, width, 1 /*depth*/ ,
248: transx, transy, sizex, sizey, rotate);
249: }
250:
251: /******************************************************************************
252: * I/O Routines. *
253: ******************************************************************************/
254: int
255: gb() /* Get a byte from Fp. */
256: {
257: int byte;
258:
259: if (!feof(Fp))
260: byte = getc(Fp);
261: else
262: Error("Premature EOF.\n");
263: if (ferror(Fp))
264: Error("I/O Error.\n");
265: return(Revbyte[byte]);
266: }
267:
268: SendHex(Byte) /* Send a Hex char to Stdout. */
269: unsigned char Byte;
270: {
271: static int LineCount = 0;
272:
273: printf("%02x", 0xff & Byte);
274: if (++LineCount == Rasbytes)
275: {
276: putchar('\n');
277: LineCount = 0;
278: }
279: }
280:
281: int
282: SendBuffer(Inv) /* Send a buffer to Stdout. Return BytesSent. */
283: int Inv;
284: {
285: int i, BytesSent;
286:
287: if (BufferMode() == LITERAL)
288: {
289: SendHex( (unsigned char) 0xff & BufCount );
290: for (i = 0; i < BufCount+1; i++)
291: {
292: SendHex( (Inv) ? Buffer[i] : ~Buffer[i]);
293: }
294: BytesSent = BufCount+2;
295: }
296: else if (BufferMode() == COPY)
297: {
298: SendHex( (unsigned char) 0xff & (0x100 + BufCount) );
299: SendHex( (Inv) ? Buffer[0] : ~Buffer[0]);
300: BytesSent = 2;
301: DiagRecLRun(mag(BufCount)+1);
302: }
303: return(BytesSent);
304: }
305:
306: /******************************************************************************
307: * Utility Routines. *
308: ******************************************************************************/
309: int
310: mag(Byte) /* Magitude of a signed char. */
311: int Byte;
312: {
313: if (Byte & 0x80)
314: {
315: /* Signed */
316: Byte = ~(--Byte);
317: }
318: return( 0xff & Byte );
319: }
320:
321: /******************************************************************************
322: * Buffer Management Routines. *
323: ******************************************************************************/
324: int
325: InputMode()
326: {
327: if (CurrByte == NextByte)
328: return(COPY);
329: return(LITERAL);
330: }
331:
332: int
333: BufferMode()
334: {
335: if (BufCount >= 0 && BufCount <= 127)
336: return(LITERAL);
337: else if (BufCount >= -127 && BufCount <= -1)
338: return(COPY);
339: return(IGNORE);
340: }
341:
342: InitLitMode(NBytes, Inv)
343: int *NBytes, Inv;
344: {
345: BufferP = Buffer;
346: BufCount = -1;
347: ContLitMode(NBytes, Inv);
348: }
349:
350: ContLitMode(NBytes, Inv)
351: int *NBytes, Inv;
352: {
353: if (BufCount == 127)
354: {
355: SendBuffer(Inv);
356: BufferP = Buffer;
357: BufCount = -1;
358: }
359: *BufferP++ = CurrByte;
360: BufCount++;
361: CurrByte = NextByte;
362: NextByte = (unsigned char) gb();
363: (*NBytes)--;
364: }
365:
366: InitCopyMode(NBytes, Inv)
367: int *NBytes, Inv;
368: {
369: BufferP = Buffer;
370: *BufferP++ = CurrByte;
371: BufCount = -1;
372: CurrByte = (unsigned char) gb();
373: NextByte = (unsigned char) gb();
374: *NBytes -= 2;
375: }
376:
377: ContCopyMode(NBytes, Inv)
378: int *NBytes, Inv;
379: {
380: if (BufCount == -127)
381: {
382: SendBuffer(Inv);
383: InitCopyMode(NBytes, Inv);
384: DiagNLongRuns++;
385: }
386: BufCount--;
387: CurrByte = NextByte;
388: NextByte = gb();
389: (*NBytes)--;
390: }
391:
392: /******************************************************************************
393: * Encoding Algorithm. *
394: ******************************************************************************/
395: int
396: Encode(NBytes, Inv)
397: int NBytes, Inv;
398: {
399: int BytesSent = 0;
400:
401: /* Initialize Buffer, BufCount, NextByte, CurrByte */
402: CurrByte = (unsigned char) gb();
403: NextByte = (unsigned char) gb();
404: if (InputMode() == LITERAL)
405: {
406: InitLitMode(&NBytes, Inv);
407: }
408: else
409: {
410: InitCopyMode(&NBytes, Inv);
411: }
412: while (NBytes > 3)
413: {
414: switch(BufferMode())
415: {
416: case LITERAL:
417: if (InputMode() == COPY)
418: {
419: BytesSent += SendBuffer(Inv);
420: InitCopyMode(&NBytes, Inv);
421: }
422: else
423: {
424: ContLitMode(&NBytes, Inv);
425: }
426: break;
427: case COPY:
428: if (CurrByte == Buffer[0])
429: {
430: ContCopyMode(&NBytes, Inv);
431: }
432: else
433: {
434: BytesSent += SendBuffer(Inv);
435: if (InputMode() == COPY)
436: {
437: InitCopyMode(&NBytes, Inv);
438: }
439: else
440: {
441: InitLitMode(&NBytes, Inv);
442: }
443: }
444: break;
445: default:
446: Error("Bad Buffer Mode... Sorry\n");
447: break;
448: }
449: }
450: BytesSent += SendBuffer(Inv);
451: /* Send out rem'g 2-3 bytes in LITERAL mode. */
452: Buffer[0] = CurrByte;
453: Buffer[1] = NextByte;
454: if (NBytes == 3)
455: Buffer[2] = gb();
456: BufCount = NBytes-1;
457: BytesSent += SendBuffer(Inv);
458: return(BytesSent);
459: }
460:
461: /******************************************************************************
462: * Diagnostic Routines. *
463: ******************************************************************************/
464: DiagRecLRun(Rlength)
465: int Rlength;
466: {
467: #ifdef DIAGS
468: if (Rlength > DiagMaxRunLength)
469: DiagMaxRunLength = Rlength;
470: DiagSumRunLength += Rlength;
471: DiagNumRuns++;
472: #endif
473: }
474:
475: Diags()
476: {
477: #ifdef DIAGS
478: fprintf(stderr, "Longest Run (<= 128) = %d\n", DiagMaxRunLength);
479: fprintf(stderr, "Number of Runs over 128 = %d\n", DiagNLongRuns);
480: fprintf(stderr, "Average Run Length of %d. (%d Runs)\n",
481: (int) DiagSumRunLength / DiagNumRuns, DiagNumRuns);
482: #endif
483: }
484:
485: /******************************************************************************
486: * PostScript Output Routines. *
487: ******************************************************************************/
488: PrintPostScriptRoutines(ras_h, ras_w, ras_d, tx, ty, sx, sy, rot)
489: int ras_h, ras_w, ras_d;
490: double tx, ty, sx, sy, rot;
491: {
492: printf("%%!\n/inch {72 mul} def\n");
493: printf("/bpp %d def\n", ras_d);
494: printf("/scanlines %d def\n", ras_h);
495: printf("/scansize %d def\n", ras_w);
496: printf("/bitmapx\n{");
497: printf(" %d %d %d [%d 0 0 %d 0 %d] ", ras_w, ras_h, ras_d, ras_w,
498: -ras_h, ras_h);
499: printf("{currentfile readrlehexstring pop } image\n} def\n");
500: printf("gsave\n");
501: printf("%f inch %f inch translate\n",tx, ty);
502: printf("%f rotate\n", rot );
503: printf("%f inch %f inch scale\n", sx, sy);
504: printf("/readrlehexstring\t%% rle_file => decoded_string boolean\n");
505: printf("{\n\t/fileptr exch def\n\tfileptr 1 string readhexstring {");
506: printf("\n\t\t0 get dup 128 and 0 eq\n");
507: printf("\t\t{ 1 add /Buffer exch string def\n");
508: printf("\t\t\tfileptr Buffer readhexstring\n\t\t}\n\t\t{");
509: printf(" 256 exch sub /BufCount exch def\n");
510: printf("\t\t\t/Buffer BufCount 1 add string def\n");
511: printf("\t\t\t/RunInt fileptr 1 string readhexstring");
512: printf(" pop 0 get def\n");
513: printf("\t\t\t0 1 BufCount { RunInt Buffer 3 1 roll put } for\n");
514: printf("\t\t\tBuffer true\n\t\t} ifelse\n\t}\n\t{ false } ifelse\n");
515: printf("} def\n");
516: printf("/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f inch 0", sx);
517: printf(" lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n",
518: sx, sy, sy);
519: printf("\tclosepath\n} def\nclipathx clip\n");
520: printf("bitmapx\n");
521: }
522:
523: PrintPostScriptClosing()
524: {
525: printf("\ngrestore\n");
526: printf("showpage\n");
527: }
528:
529: /******************************************************************************
530: * Error Routine. *
531: ******************************************************************************/
532: Error(S1, S2, S3)
533: char *S1, *S2, *S3;
534: {
535: fprintf(stderr, S1, S2, S3);
536: exit(-1);
537: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.