]>
Commit | Line | Data |
---|---|---|
95a0e1ee | 1 | /* |
58ec2a95 | 2 | * "$Id: pstops.c,v 1.8 1999/03/21 02:10:14 mike Exp $" |
95a0e1ee | 3 | * |
58ec2a95 | 4 | * PostScript filter for the Common UNIX Printing System (CUPS). |
95a0e1ee | 5 | * |
58ec2a95 | 6 | * Copyright 1993-1999 by Easy Software Products. |
95a0e1ee | 7 | * |
58ec2a95 | 8 | * These coded instructions, statements, and computer programs are the |
9 | * property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights are outlined in the file | |
11 | * "LICENSE.txt" which should have been included with this file. If this | |
12 | * file is missing or damaged please contact Easy Software Products | |
13 | * at: | |
95a0e1ee | 14 | * |
58ec2a95 | 15 | * Attn: CUPS Licensing Information |
16 | * Easy Software Products | |
17 | * 44141 Airport View Drive, Suite 204 | |
18 | * Hollywood, Maryland 20636-3111 USA | |
df37188e | 19 | * |
58ec2a95 | 20 | * Voice: (301) 373-9603 |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
418ea51f | 23 | * |
58ec2a95 | 24 | * Contents: |
95a0e1ee | 25 | * |
26 | */ | |
27 | ||
28 | /* | |
29 | * Include necessary headers... | |
30 | */ | |
31 | ||
32 | #include <stdio.h> | |
33 | #include <stdlib.h> | |
34 | #include <string.h> | |
35 | #include <errno.h> | |
36 | #include <ctype.h> | |
95a0e1ee | 37 | |
58ec2a95 | 38 | #if defined(WIN32) || defined(__EMX__) |
39 | # include <io.h> | |
40 | #else | |
41 | # include <unistd.h> | |
42 | #endif /* WIN32 || __EMX__ */ | |
43 | ||
44 | #include <cups/cups.h> | |
45 | #include <cups/language.h> | |
46 | #include <cups/string.h> | |
47 | ||
48 | ||
49 | /* | |
50 | * Constants... | |
51 | */ | |
95a0e1ee | 52 | |
53 | #define MAX_PAGES 10000 | |
58ec2a95 | 54 | |
55 | ||
56 | /* | |
57 | * Globals... | |
58 | */ | |
59 | ||
60 | int NumPages = 0; /* Number of pages in file */ | |
61 | size_t Pages[MAX_PAGES]; /* Offsets to each page */ | |
62 | char *PageRanges = NULL; /* Range of pages selected */ | |
63 | char *PageSet = NULL; /* All, Even, Odd pages */ | |
64 | int Reversed = 0, /* Reverse pages */ | |
65 | Flip = 0; /* Flip/mirror pages */ | |
66 | float Width = 612.0f, /* Total page width */ | |
67 | Height = 792.0f; /* Total page height */ | |
95a0e1ee | 68 | |
69 | ||
70 | /* | |
71 | * 'test_page()' - Test the given page number. Returns TRUE if the page | |
72 | * should be printed, false otherwise... | |
73 | */ | |
74 | ||
75 | int | |
76 | test_page(int number) | |
77 | { | |
78 | char *range; | |
79 | int lower, upper; | |
80 | ||
81 | ||
82 | if (((number & 1) && !PrintOddPages) || | |
83 | (!(number & 1) && !PrintEvenPages)) | |
84 | return (FALSE); | |
85 | ||
86 | if (PrintRange == NULL) | |
87 | return (TRUE); | |
88 | ||
89 | for (range = PrintRange; *range != '\0';) | |
90 | { | |
91 | if (*range == '-') | |
92 | lower = 0; | |
93 | else | |
94 | { | |
95 | lower = atoi(range); | |
96 | while (isdigit(*range) || *range == ' ') | |
97 | range ++; | |
98 | }; | |
99 | ||
100 | if (*range == '-') | |
101 | { | |
102 | range ++; | |
103 | if (*range == '\0') | |
104 | upper = MAX_PAGES; | |
105 | else | |
106 | upper = atoi(range); | |
107 | ||
108 | while (isdigit(*range) || *range == ' ') | |
109 | range ++; | |
110 | ||
111 | if (number >= lower && number <= upper) | |
112 | return (TRUE); | |
113 | }; | |
114 | ||
115 | if (number == lower) | |
116 | return (TRUE); | |
117 | ||
118 | if (*range != '\0') | |
119 | range ++; | |
120 | }; | |
121 | ||
122 | return (FALSE); | |
123 | } | |
124 | ||
125 | ||
126 | /* | |
127 | * 'copy_bytes()' - Copy bytes from the input file to stdout... | |
128 | */ | |
129 | ||
130 | void | |
131 | copy_bytes(FILE *fp, | |
df37188e | 132 | int length) |
95a0e1ee | 133 | { |
134 | char buffer[8192]; | |
df37188e | 135 | int nbytes, nleft; |
136 | int feature; | |
95a0e1ee | 137 | |
138 | ||
df37188e | 139 | feature = 0; |
140 | nleft = length; | |
95a0e1ee | 141 | |
df37188e | 142 | while (nleft > 0 || length == -1) |
143 | { | |
144 | if (fgets(buffer, sizeof(buffer), fp) == NULL) | |
95a0e1ee | 145 | return; |
146 | ||
df37188e | 147 | nbytes = strlen(buffer); |
148 | nleft -= nbytes; | |
149 | ||
150 | if (strncmp(buffer, "%%BeginFeature", 14) == 0) | |
151 | feature = 1; | |
152 | else if (strncmp(buffer, "%%EndFeature", 12) == 0 || | |
153 | strncmp(buffer, "%%EndSetup", 10) == 0) | |
154 | feature = 0; | |
155 | ||
156 | if (!feature) | |
157 | fputs(buffer, stdout); | |
95a0e1ee | 158 | }; |
159 | } | |
160 | ||
161 | ||
162 | /* | |
163 | * 'print_page()' - Print the specified page... | |
164 | */ | |
165 | ||
b9434065 | 166 | int |
95a0e1ee | 167 | print_page(FILE *fp, |
168 | int number) | |
169 | { | |
170 | if (number < 1 || number > PrintNumPages || !test_page(number)) | |
b9434065 | 171 | return (0); |
95a0e1ee | 172 | |
173 | if (Verbosity) | |
174 | fprintf(stderr, "psfilter: Printing page %d\n", number); | |
175 | ||
176 | number --; | |
177 | if (PrintPages[number] != ftell(fp)) | |
178 | fseek(fp, PrintPages[number], SEEK_SET); | |
179 | ||
180 | copy_bytes(fp, PrintPages[number + 1] - PrintPages[number]); | |
b9434065 | 181 | |
182 | return (1); | |
95a0e1ee | 183 | } |
184 | ||
185 | ||
186 | /* | |
187 | * 'scan_file()' - Scan a file for %%Page markers... | |
188 | */ | |
189 | ||
190 | #define PS_DOCUMENT 0 | |
191 | #define PS_FILE 1 | |
192 | #define PS_FONT 2 | |
193 | #define PS_RESOURCE 3 | |
194 | ||
195 | #define PS_MAX 1000 | |
196 | ||
df37188e | 197 | #define pushdoc(n) { if (doclevel < PS_MAX) { indent[doclevel] = '\t'; doclevel ++; docstack[doclevel] = (n); if (Verbosity) fprintf(stderr, "psfilter: pushdoc(%d), doclevel = %d\n", (n), doclevel); }; } |
198 | #define popdoc(n) { if (doclevel >= 0 && docstack[doclevel] == (n)) doclevel --; indent[doclevel] = '\0'; if (Verbosity) fprintf(stderr, "psfilter: popdoc(%d), doclevel = %d\n", (n), doclevel); } | |
95a0e1ee | 199 | |
200 | void | |
201 | scan_file(FILE *fp) | |
202 | { | |
203 | char line[8192]; | |
204 | int doclevel, /* Sub-document stack level */ | |
205 | docstack[PS_MAX + 1]; /* Stack contents... */ | |
df37188e | 206 | char indent[1024]; |
95a0e1ee | 207 | |
208 | ||
209 | PrintNumPages = 0; | |
210 | PrintPages[0] = 0; | |
211 | doclevel = -1; | |
df37188e | 212 | memset(indent, 0, sizeof(indent)); |
95a0e1ee | 213 | |
214 | rewind(fp); | |
215 | ||
216 | while (fgets(line, sizeof(line), fp) != NULL) | |
217 | { | |
218 | if (line[0] == '\r') | |
219 | strcpy(line, line + 1); /* Strip leading CR */ | |
220 | if (line[strlen(line) - 1] == '\n') | |
221 | line[strlen(line) - 1] = '\0'; /* Strip trailing LF */ | |
222 | if (line[strlen(line) - 1] == '\r') | |
223 | line[strlen(line) - 1] = '\0'; /* Strip trailing CR */ | |
224 | ||
225 | if (line[0] == '%' && line[1] == '%') | |
226 | { | |
227 | if (Verbosity) | |
df37188e | 228 | fprintf(stderr, "psfilter: Control line - %s%s\n", indent, line); |
95a0e1ee | 229 | |
230 | /* | |
df37188e | 231 | * Note that we check for colons and spaces after the BeginXXXX control |
95a0e1ee | 232 | * lines because Adobe's Acrobat product produces incorrect output! |
233 | */ | |
234 | ||
df37188e | 235 | if (strncmp(line, "%%BeginDocument:", 16) == 0 || |
236 | strncmp(line, "%%BeginDocument ", 16) == 0) | |
95a0e1ee | 237 | pushdoc(PS_DOCUMENT) |
df37188e | 238 | else if (strncmp(line, "%%BeginFont:", 12) == 0 || |
239 | strncmp(line, "%%BeginFont ", 12) == 0) | |
95a0e1ee | 240 | pushdoc(PS_FONT) |
df37188e | 241 | else if (strncmp(line, "%%BeginFile:", 12) == 0 || |
242 | strncmp(line, "%%BeginFile ", 12) == 0) | |
95a0e1ee | 243 | pushdoc(PS_FILE) |
df37188e | 244 | else if (strncmp(line, "%%BeginResource:", 16) == 0 || |
245 | strncmp(line, "%%BeginResource ", 16) == 0) | |
95a0e1ee | 246 | pushdoc(PS_RESOURCE) |
df37188e | 247 | else if (strcmp(line, "%%EndDocument") == 0) |
95a0e1ee | 248 | popdoc(PS_DOCUMENT) |
df37188e | 249 | else if (strcmp(line, "%%EndFont") == 0) |
95a0e1ee | 250 | popdoc(PS_FONT) |
df37188e | 251 | else if (strcmp(line, "%%EndFile") == 0) |
95a0e1ee | 252 | popdoc(PS_FILE) |
df37188e | 253 | else if (strcmp(line, "%%EndResource") == 0) |
95a0e1ee | 254 | popdoc(PS_RESOURCE) |
df37188e | 255 | else if (strncmp(line, "%%Page:", 7) == 0) |
95a0e1ee | 256 | { |
df37188e | 257 | if (doclevel < 0) |
258 | { | |
259 | if (Verbosity) | |
260 | fprintf(stderr, "psfilter: Page %d begins at offset %u\n", | |
261 | PrintNumPages + 2, PrintPages[PrintNumPages]); | |
262 | ||
263 | PrintNumPages ++; | |
264 | } | |
265 | else if (Verbosity) | |
266 | fprintf(stderr, "psfilter: embedded page %d begins at offset %u (doclevel = %d [%d])\n", | |
267 | PrintNumPages + 2, PrintPages[PrintNumPages], | |
268 | doclevel, docstack[doclevel]); | |
95a0e1ee | 269 | } |
270 | else if (strcmp(line, "%%Trailer") == 0 && doclevel < 0) | |
271 | break; | |
272 | else if (strcmp(line, "%%EOF") == 0) | |
273 | { | |
274 | doclevel --; | |
275 | if (doclevel < 0) | |
276 | doclevel = -1; | |
277 | }; | |
278 | }; | |
279 | ||
280 | PrintPages[PrintNumPages] = ftell(fp); | |
281 | }; | |
282 | ||
283 | rewind(fp); | |
284 | ||
285 | if (PrintNumPages == 0) | |
286 | { | |
287 | fputs("psfilter: Warning - this PostScript file does not conform to the DSC!\n", stderr); | |
288 | ||
289 | PrintPages[1] = PrintPages[0]; | |
290 | PrintPages[0] = 0; | |
291 | PrintNumPages = 1; | |
292 | } | |
293 | else if (Verbosity) | |
294 | fprintf(stderr, "psfilter: Saw %d pages total.\n", PrintNumPages); | |
295 | } | |
296 | ||
297 | ||
75639985 | 298 | /* |
299 | * 'make_transfer_function()' - Make a transfer function given a gamma, | |
300 | * brightness, and color profile values. | |
301 | */ | |
302 | ||
303 | void | |
304 | make_transfer_function(char *s, /* O - Transfer function string */ | |
305 | float ig, /* I - Image gamma */ | |
306 | float ib, /* I - Image brightness */ | |
307 | float pg, /* I - Profile gamma */ | |
308 | float pd) /* I - Profile ink density */ | |
309 | { | |
310 | if (ig == 0.0) | |
311 | ig = LutDefaultGamma(); | |
312 | ||
418ea51f | 313 | if ((ig == 1.0 || ig == 0.0) && |
314 | (ib == 1.0 || ib == 0.0) && | |
315 | (pg == 1.0 || pg == 0.0) && | |
316 | (pd == 1.0 || pd == 0.0)) | |
75639985 | 317 | { |
318 | s[0] = '\0'; | |
319 | return; | |
320 | }; | |
321 | ||
418ea51f | 322 | if (ig != 1.0 && ig != 0.0) |
323 | sprintf(s, "%.4f exp ", 1.0 / ig); | |
324 | else | |
325 | s[0] = '\0'; | |
75639985 | 326 | |
418ea51f | 327 | if (ib != 1.0 || ib != 0.0 || |
328 | pg != 1.0 || pg != 0.0 || | |
329 | pd != 1.0 || pd != 0.0) | |
330 | { | |
331 | strcat(s, "neg 1 add "); | |
75639985 | 332 | |
418ea51f | 333 | if (ib != 1.0 && ib != 0.0) |
334 | sprintf(s + strlen(s), "%.2f mul ", ib); | |
75639985 | 335 | |
418ea51f | 336 | if (pg != 1.0 && pg != 0.0) |
337 | sprintf(s + strlen(s), "%.4f exp ", 1.0 / pg); | |
75639985 | 338 | |
418ea51f | 339 | if (pd != 1.0 && pd != 0.0) |
340 | sprintf(s + strlen(s), "%.4f mul ", pd); | |
75639985 | 341 | |
418ea51f | 342 | strcat(s, "neg 1 add"); |
343 | }; | |
75639985 | 344 | } |
345 | ||
346 | ||
95a0e1ee | 347 | /* |
b9434065 | 348 | * 'print_header()' - Print the output header... |
95a0e1ee | 349 | */ |
350 | ||
351 | void | |
418ea51f | 352 | print_header(float gammaval[4], |
353 | int brightness[4]) | |
95a0e1ee | 354 | { |
75639985 | 355 | char cyan[255], |
356 | magenta[255], | |
357 | yellow[255], | |
358 | black[255]; | |
359 | ||
360 | ||
b9434065 | 361 | puts("%!PS-Adobe-3.0"); |
95a0e1ee | 362 | |
75639985 | 363 | puts("userdict begin"); |
f90763a7 | 364 | |
75639985 | 365 | make_transfer_function(black, gammaval[0], 100.0 / brightness[0], |
366 | ColorProfile[PD_PROFILE_KG], | |
367 | ColorProfile[PD_PROFILE_KD]); | |
f90763a7 | 368 | |
369 | if (PrintColor) | |
370 | { | |
75639985 | 371 | /* |
372 | * Color output... | |
373 | */ | |
374 | ||
375 | make_transfer_function(cyan, gammaval[1], 100.0 / brightness[1], | |
376 | ColorProfile[PD_PROFILE_BG], | |
377 | ColorProfile[PD_PROFILE_CD]); | |
378 | make_transfer_function(magenta, gammaval[2], 100.0 / brightness[2], | |
379 | ColorProfile[PD_PROFILE_BG], | |
380 | ColorProfile[PD_PROFILE_MD]); | |
381 | make_transfer_function(yellow, gammaval[3], 100.0 / brightness[3], | |
382 | ColorProfile[PD_PROFILE_BG], | |
383 | ColorProfile[PD_PROFILE_YD]); | |
384 | ||
385 | printf("{ %s } bind\n" | |
386 | "{ %s } bind\n" | |
387 | "{ %s } bind\n" | |
388 | "{ %s } bind\n" | |
389 | "setcolortransfer\n", | |
390 | cyan, magenta, yellow, black); | |
f90763a7 | 391 | } |
75639985 | 392 | else |
393 | { | |
394 | /* | |
395 | * B&W output... | |
396 | */ | |
397 | ||
398 | printf("{ %s } bind\n" | |
418ea51f | 399 | "settransfer\n", |
75639985 | 400 | black); |
401 | }; | |
402 | ||
403 | puts("end"); | |
b9434065 | 404 | } |
405 | ||
406 | ||
407 | /* | |
408 | * 'print_file()' - Print a file... | |
409 | */ | |
410 | ||
411 | void | |
412 | print_file(char *filename, | |
75639985 | 413 | float gammaval[4], |
414 | int brightness[4], | |
418ea51f | 415 | int nup, |
416 | int landscape) | |
b9434065 | 417 | { |
418 | FILE *fp; | |
419 | int number, | |
420 | endpage, | |
421 | dir, | |
422 | x, y; | |
423 | float w, l, | |
424 | tx, ty; | |
425 | long end; | |
426 | ||
427 | ||
428 | if ((fp = fopen(filename, "r")) == NULL) | |
429 | { | |
430 | fprintf(stderr, "psfilter: Unable to open file \'%s\' for reading - %s\n", | |
431 | filename, strerror(errno)); | |
432 | exit(1); | |
433 | }; | |
434 | ||
435 | scan_file(fp); | |
436 | ||
437 | print_header(gammaval, brightness); | |
f90763a7 | 438 | |
95a0e1ee | 439 | if (PrintReversed) |
f90763a7 | 440 | { |
441 | number = PrintNumPages; | |
442 | dir = -1; | |
443 | endpage = 0; | |
444 | } | |
95a0e1ee | 445 | else |
f90763a7 | 446 | { |
447 | number = 1; | |
448 | dir = 1; | |
449 | endpage = PrintNumPages + 1; | |
450 | }; | |
451 | ||
452 | switch (nup) | |
453 | { | |
454 | case 1 : | |
b9434065 | 455 | copy_bytes(fp, PrintPages[0]); |
456 | ||
f90763a7 | 457 | for (; number != endpage; number += dir) |
458 | { | |
459 | if (PrintFlip) | |
460 | printf("gsave\n" | |
461 | "%d 0 translate\n" | |
462 | "-1 1 scale\n", | |
463 | PrintWidth); | |
464 | ||
465 | print_page(fp, number); | |
466 | ||
467 | if (PrintFlip) | |
468 | puts("grestore\n"); | |
469 | }; | |
470 | break; | |
471 | ||
472 | case 2 : | |
418ea51f | 473 | if (landscape) |
474 | { | |
475 | w = (float)PrintLength; | |
f90763a7 | 476 | l = w * (float)PrintLength / (float)PrintWidth; |
418ea51f | 477 | if (l > ((float)PrintWidth * 0.5)) |
478 | { | |
479 | l = (float)PrintWidth * 0.5; | |
480 | w = l * (float)PrintWidth / (float)PrintLength; | |
481 | }; | |
f90763a7 | 482 | |
418ea51f | 483 | tx = (float)PrintWidth * 0.5 - l; |
484 | ty = ((float)PrintLength - w) * 0.5; | |
485 | } | |
486 | else | |
487 | { | |
488 | l = (float)PrintWidth; | |
489 | w = l * (float)PrintWidth / (float)PrintLength; | |
490 | if (w > ((float)PrintLength * 0.5)) | |
491 | { | |
492 | w = (float)PrintLength * 0.5; | |
493 | l = w * (float)PrintLength / (float)PrintWidth; | |
494 | }; | |
495 | ||
496 | tx = (float)PrintLength * 0.5 - w; | |
497 | ty = ((float)PrintWidth - l) * 0.5; | |
498 | } | |
f90763a7 | 499 | |
b9434065 | 500 | puts("userdict begin\n" |
501 | "/ESPshowpage /showpage load def\n" | |
502 | "/showpage { } def\n" | |
503 | "end"); | |
504 | ||
505 | copy_bytes(fp, PrintPages[0]); | |
f90763a7 | 506 | |
418ea51f | 507 | for (x = landscape; number != endpage;) |
f90763a7 | 508 | { |
b9434065 | 509 | puts("gsave"); |
510 | printf("%d 0.0 translate\n" | |
511 | "90 rotate\n", | |
512 | PrintWidth); | |
418ea51f | 513 | if (landscape) |
514 | printf("%f %f translate\n" | |
515 | "%f %f scale\n", | |
516 | ty, tx + l * x, | |
517 | w / (float)PrintWidth, l / (float)PrintLength); | |
518 | else | |
519 | printf("%f %f translate\n" | |
520 | "%f %f scale\n", | |
521 | tx + w * x, ty, | |
522 | w / (float)PrintWidth, l / (float)PrintLength); | |
f90763a7 | 523 | printf("newpath\n" |
524 | "0 0 moveto\n" | |
525 | "%d 0 lineto\n" | |
526 | "%d %d lineto\n" | |
527 | "0 %d lineto\n" | |
528 | "closepath clip newpath\n", | |
529 | PrintWidth, PrintWidth, PrintLength, PrintLength); | |
530 | if (PrintFlip) | |
531 | printf("%d 0 translate\n" | |
532 | "-1 1 scale\n", | |
533 | PrintWidth); | |
534 | ||
b9434065 | 535 | if (print_page(fp, number)) |
536 | { | |
537 | number += dir; | |
538 | x = 1 - x; | |
539 | }; | |
540 | ||
f90763a7 | 541 | puts("grestore"); |
b9434065 | 542 | |
418ea51f | 543 | if (x == landscape) |
f90763a7 | 544 | puts("ESPshowpage"); |
545 | }; | |
546 | ||
418ea51f | 547 | if (x != landscape) |
f90763a7 | 548 | puts("ESPshowpage"); |
549 | break; | |
550 | ||
551 | case 4 : | |
b9434065 | 552 | puts("userdict begin\n" |
553 | "/ESPshowpage /showpage load def\n" | |
554 | "/showpage { } def\n" | |
555 | "end"); | |
556 | ||
f90763a7 | 557 | |
558 | w = (float)PrintWidth * 0.5; | |
559 | l = (float)PrintLength * 0.5; | |
560 | ||
b9434065 | 561 | copy_bytes(fp, PrintPages[0]); |
562 | ||
563 | for (x = 0, y = 1; number != endpage;) | |
f90763a7 | 564 | { |
565 | printf("gsave\n" | |
566 | "%f %f translate\n" | |
567 | "0.5 0.5 scale\n", | |
568 | (float)x * w, (float)y * l); | |
569 | printf("newpath\n" | |
570 | "0 0 moveto\n" | |
571 | "%d 0 lineto\n" | |
572 | "%d %d lineto\n" | |
573 | "0 %d lineto\n" | |
574 | "closepath clip newpath\n", | |
575 | PrintWidth, PrintWidth, PrintLength, PrintLength); | |
576 | if (PrintFlip) | |
577 | printf("%d 0 translate\n" | |
578 | "-1 1 scale\n", | |
579 | PrintWidth); | |
580 | ||
b9434065 | 581 | if (print_page(fp, number)) |
582 | { | |
583 | number += dir; | |
584 | x = 1 - x; | |
585 | }; | |
586 | ||
f90763a7 | 587 | puts("grestore"); |
b9434065 | 588 | |
589 | if (x == 0) | |
f90763a7 | 590 | { |
591 | y = 1 - y; | |
592 | if (y == 1) | |
593 | puts("ESPshowpage"); | |
594 | }; | |
595 | }; | |
596 | ||
b9434065 | 597 | if (y != 1 || x != 1) |
f90763a7 | 598 | puts("ESPshowpage"); |
599 | break; | |
600 | }; | |
95a0e1ee | 601 | |
602 | fseek(fp, 0, SEEK_END); | |
603 | end = ftell(fp); | |
604 | fseek(fp, PrintPages[PrintNumPages], SEEK_SET); | |
605 | ||
606 | copy_bytes(fp, end - PrintPages[PrintNumPages]); | |
607 | ||
608 | fclose(fp); | |
609 | } | |
610 | ||
611 | ||
612 | void | |
613 | usage(void) | |
614 | { | |
615 | fputs("Usage: psfilter [-e] [-o] [-r] [-p<pages>] [-h] [-D] infile\n", stderr); | |
616 | exit(ERR_BAD_ARG); | |
617 | } | |
618 | ||
619 | ||
620 | /* | |
621 | * 'main()' - Main entry... | |
622 | */ | |
623 | ||
418ea51f | 624 | int |
95a0e1ee | 625 | main(int argc, |
626 | char *argv[]) | |
627 | { | |
b9434065 | 628 | int i, n, nfiles; |
f90763a7 | 629 | char *opt; |
630 | char tempfile[255]; | |
631 | FILE *temp; | |
632 | char buffer[8192]; | |
75639985 | 633 | float gammaval[4]; |
634 | int brightness[4]; | |
f90763a7 | 635 | int nup; |
418ea51f | 636 | int landscape; |
f90763a7 | 637 | PDInfoStruct *info; |
638 | PDSizeTableStruct *size; | |
639 | time_t modtime; | |
640 | ||
641 | ||
642 | gammaval[0] = 0.0; | |
643 | gammaval[1] = 0.0; | |
75639985 | 644 | gammaval[2] = 0.0; |
645 | gammaval[3] = 0.0; | |
f90763a7 | 646 | brightness[0] = 100; |
647 | brightness[1] = 100; | |
75639985 | 648 | brightness[2] = 100; |
649 | brightness[3] = 100; | |
f90763a7 | 650 | |
418ea51f | 651 | nup = 1; |
652 | landscape = 0; | |
95a0e1ee | 653 | |
654 | for (i = 1, nfiles = 0; i < argc; i ++) | |
655 | if (argv[i][0] == '-') | |
656 | for (opt = argv[i] + 1; *opt != '\0'; opt ++) | |
657 | switch (*opt) | |
658 | { | |
659 | default : | |
660 | case 'h' : /* Help */ | |
661 | usage(); | |
662 | break; | |
663 | ||
f90763a7 | 664 | case 'P' : /* Printer */ |
665 | i ++; | |
666 | if (i >= argc) | |
667 | usage(); | |
668 | ||
669 | PDLocalReadInfo(argv[i], &info, &modtime); | |
670 | size = PDFindPageSize(info, PD_SIZE_CURRENT); | |
671 | ||
672 | PrintColor = strncasecmp(info->printer_class, "Color", 5) == 0; | |
673 | PrintWidth = 72.0 * size->width; | |
674 | PrintLength = 72.0 * size->length; | |
75639985 | 675 | |
676 | memcpy(ColorProfile, info->active_status->color_profile, | |
677 | sizeof(ColorProfile)); | |
f90763a7 | 678 | break; |
679 | ||
418ea51f | 680 | case 'l' : /* Landscape printing... */ |
681 | landscape = 1; | |
682 | break; | |
683 | ||
f90763a7 | 684 | case '1' : /* 1-up printing... */ |
685 | nup = 1; | |
686 | break; | |
687 | case '2' : /* 2-up printing... */ | |
688 | nup = 2; | |
689 | break; | |
690 | case '4' : /* 4-up printing... */ | |
691 | nup = 4; | |
692 | break; | |
693 | ||
694 | case 'f' : /* Flip pages */ | |
695 | PrintFlip = 1; | |
696 | break; | |
697 | ||
95a0e1ee | 698 | case 'e' : /* Print even pages */ |
699 | PrintEvenPages = 1; | |
700 | PrintOddPages = 0; | |
701 | break; | |
702 | case 'o' : /* Print odd pages */ | |
703 | PrintEvenPages = 0; | |
704 | PrintOddPages = 1; | |
705 | break; | |
706 | case 'r' : /* Print pages reversed */ | |
707 | PrintReversed = 1; | |
708 | break; | |
709 | case 'p' : /* Print page range */ | |
710 | PrintRange = opt + 1; | |
711 | opt += strlen(opt) - 1; | |
712 | break; | |
713 | case 'D' : /* Debug ... */ | |
714 | Verbosity ++; | |
715 | break; | |
f90763a7 | 716 | |
717 | case 'g' : /* Gamma correction */ | |
718 | i ++; | |
719 | if (i < argc) | |
75639985 | 720 | switch (sscanf(argv[i], "%f,%f,%f,%f", gammaval + 0, |
721 | gammaval + 1, gammaval + 2, gammaval + 3)) | |
722 | { | |
723 | case 1 : | |
724 | gammaval[1] = gammaval[0]; | |
725 | case 2 : | |
726 | gammaval[2] = gammaval[1]; | |
727 | gammaval[3] = gammaval[1]; | |
728 | break; | |
729 | }; | |
f90763a7 | 730 | break; |
731 | ||
732 | case 'b' : /* Brightness */ | |
733 | i ++; | |
734 | if (i < argc) | |
75639985 | 735 | switch (sscanf(argv[i], "%d,%d,%d,%d", brightness + 0, |
736 | brightness + 1, brightness + 2, brightness + 3)) | |
737 | { | |
738 | case 1 : | |
739 | brightness[1] = brightness[0]; | |
740 | case 2 : | |
741 | brightness[2] = brightness[1]; | |
742 | brightness[3] = brightness[1]; | |
743 | break; | |
744 | }; | |
f90763a7 | 745 | break; |
75639985 | 746 | |
747 | case 'c' : /* Color profile */ | |
748 | i ++; | |
749 | if (i < argc) | |
750 | sscanf(argv[i], "%f,%f,%f,%f,%f,%f", | |
751 | ColorProfile + 0, | |
752 | ColorProfile + 1, | |
753 | ColorProfile + 2, | |
754 | ColorProfile + 3, | |
755 | ColorProfile + 4, | |
756 | ColorProfile + 5); | |
757 | break; | |
95a0e1ee | 758 | } |
759 | else | |
760 | { | |
418ea51f | 761 | if (landscape && nfiles == 0) |
762 | { | |
763 | n = PrintWidth; | |
764 | PrintWidth = PrintLength; | |
765 | PrintLength = n; | |
766 | }; | |
767 | ||
b9434065 | 768 | if (nup == 1 && PrintEvenPages && PrintOddPages && PrintRange == NULL && |
769 | !PrintReversed) | |
770 | { | |
771 | /* | |
772 | * Just cat the file to stdout - we don't need to to any processing. | |
773 | */ | |
774 | ||
775 | print_header(gammaval, brightness); | |
776 | ||
777 | if ((temp = fopen(argv[i], "r")) != NULL) | |
778 | { | |
df37188e | 779 | copy_bytes(temp, -1); |
b9434065 | 780 | fclose(temp); |
781 | }; | |
782 | } | |
783 | else | |
784 | { | |
785 | /* | |
786 | * Filter the file as necessary... | |
787 | */ | |
788 | ||
418ea51f | 789 | print_file(argv[i], gammaval, brightness, nup, landscape); |
b9434065 | 790 | }; |
791 | ||
95a0e1ee | 792 | nfiles ++; |
793 | }; | |
794 | ||
795 | if (nfiles == 0) | |
796 | { | |
418ea51f | 797 | if (landscape) |
798 | { | |
799 | n = PrintWidth; | |
800 | PrintWidth = PrintLength; | |
801 | PrintLength = n; | |
802 | }; | |
803 | ||
b9434065 | 804 | if (nup == 1 && PrintEvenPages && PrintOddPages && PrintRange == NULL && |
805 | !PrintReversed) | |
806 | { | |
807 | /* | |
808 | * Just cat stdin to stdout - we don't need to to any processing. | |
809 | */ | |
810 | ||
811 | print_header(gammaval, brightness); | |
95a0e1ee | 812 | |
df37188e | 813 | copy_bytes(stdin, -1); |
b9434065 | 814 | } |
815 | else | |
816 | { | |
817 | /* | |
818 | * Copy stdin to a temporary file and filter the temporary file. | |
819 | */ | |
820 | ||
821 | if ((temp = fopen(tmpnam(tempfile), "w")) == NULL) | |
822 | exit(ERR_DATA_BUFFER); | |
95a0e1ee | 823 | |
b9434065 | 824 | while (fgets(buffer, sizeof(buffer), stdin) != NULL) |
825 | fputs(buffer, temp); | |
826 | fclose(temp); | |
95a0e1ee | 827 | |
418ea51f | 828 | print_file(tempfile, gammaval, brightness, nup, landscape); |
95a0e1ee | 829 | |
b9434065 | 830 | unlink(tempfile); |
831 | }; | |
95a0e1ee | 832 | }; |
418ea51f | 833 | |
834 | return (NO_ERROR); | |
95a0e1ee | 835 | } |
836 | ||
837 | ||
838 | /* | |
58ec2a95 | 839 | * End of "$Id: pstops.c,v 1.8 1999/03/21 02:10:14 mike Exp $". |
95a0e1ee | 840 | */ |