/* * peps.c - Pnm or Png from EPS - v2.0 * * by G. Adam Stanislav * * Started: 24-Jun-2001 * Updated: 25-Jan-2005 * * Copyright 2001, 2005 G. Adam Stanislav. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ /* * This program converts EPS (encapsulated PostScript) files to * either PGM (portable graymap) or PPM (portable pixmap) files. * * It requires that gs (GhostScript) be installed and available * on the path. * * Options allow to use anti-aliasing setting of 1 (none), 2 (some), * or 4 (much) for the text and the graphics. The text anti-aliasing * is set by using the -t1, -t2, or -t4 options; the graphic * anti-aliasing with the -g1, -g2, and -g4 options. -t4 and -g4 are * the default. * * Secondly, options allow you to choose the resolution of the image * in pixels per inch (these are gs units, I would rather use metric * units, but gs uses inches). The default is 100 ppi. You can change * it with the -r switch, e.g., -r144 will increase the resolution. * * If you need a different vertical and horizontal resolution, use * -v and -h instead, e.g., -v1200 -h600. This may be necessary with * certain printers. * * All output is sent to stdout (directly by gs), from where it can * be piped or redirected. The idea is to use it with image format * converters. Both, PGM and PPM, are text files, so they can grow * huge. However, using this format is the only way to get gs to * use anti-aliasing, at least as of this writing (24-Jun-2001). * * NEW IN VERSION 2.0 * * As the more recent versions of GhostScript can produce anti-aliased * PNG images directly, there no longer is a need to use pnmtopng. * * An X version called xpeps is made conditionally for the use * with x11 output devices. * * The -b switch overrides the bounding box. * * The -c and -C switches print a content type to stdout. * * The -d switch prints the defaults peps was compiled with. * * The -e switch is used by xpeps to determine after how many * seconds the image should evaporate. The -E switch does the same but * prints its PID to allow the use of kill. * * The -f switch chooses any output bitmap type supported * by Ghostscript. * * The -h switch without parameters, now prints usage to stdout * and exits 0. As before, with a parameter it selects horizontal * resolution. * * The -i switch was added to allow for the use of stdin. This * also is the default. * * The -l switch is a combination of the -t and -g switches. * * The -m switch produces grayscale PNG images. * * The -M switch defines the default MIME list to parse. * * The -n switch produces pnm images. This was the default in 1.0, * which had no switch for it. In 2.0, color PNG is the default * unless compiled with PNDEFAULT defined as a non-zero value. * * The -p switch now produces color PNG images (in 1.0 the -p switch called * pnmtopng which determined whether an image was grayscale or color). * * The -q switch sets the height of the output in pixels without * affecting the width. The -Q also sets the height but changes * the width to keep the height/width ratio of the image. * * The -S switch restores the security setting turned off by -s. * * The -u switch tells peps to read the peps.mime file in the home * directory of the user specified by the switch. * * Using the -v switch not followed by a number will now print the * version to stdout and exit 0. As before, the -v switch followed * by a number selects vertical resolution. * * The -w switch sets the width of the output in pixels without * affecting the height. The -W also sets the width but changes * the height to keep the height/width ratio of the image. * * An input file whose name starts with a dash ('-') can be specified * on the command line preceded by an extra dash. So, a file named * - would be entered as -- or even - - on the command line. */ #include #include #include #include #define VERSION "2.0" #ifdef X #define PEPS "xpeps" #else #define PEPS "peps" #endif #ifndef GSPATH #define GSPATH "gs" #endif #ifndef GZPATH #define GZPATH "gzip" #endif #ifndef GZIP #define GZIP 3 #endif #ifndef ETC #define ETC "/etc" #endif #ifndef HRES #ifdef RESOLUTION #define HRES (RESOLUTION) #else #define HRES (100) #endif #endif #ifndef VRES #ifdef RESOLUTION #define VRES (RESOLUTION) #else #define VRES (100) #endif #endif #ifndef HAE #define HAE "HTTP_ACCEPT_ENCODING" #endif #ifndef PNMDEFAULT #define PNMDEFAULT 0 #endif #ifdef X #ifndef EVAPORATIONDELAY #define EVAPORATIONDELAY (((unsigned)(-1))>>1) #else #if (EVAPORATIONDELAY) == 0 #undef EVAPORATIONDELAY #define EVAPORATIONDELAY (((unsigned)(-1))>>1) #endif #endif #endif #define FLAGWIDTH 1 #define FLAGHEIGHT 2 #ifdef X #ifndef XGRAY #define XGRAY "x11gray4" #endif #ifndef XCOLOR #define XCOLOR "x11" #endif #else typedef struct MIMES { char *format; char *mime; } MIMES; MIMES const mimes[] = { { "bmp16", "bmp" }, { "bmp16m", "bmp" }, { "bmp256", "bmp" }, { "bmp32b", "bmp" }, { "bmpgray", "bmp" }, { "bmpmono", "bmp" }, { "cgm8", "cgm" }, { "cgm24", "cgm" }, { "cgmmono", "cgm" }, { "faxg3", "g3fax" }, { "jpeg", "jpeg" }, { "jpeggray", "jpeg" }, { "miff24", "x-miff" }, { "pbm", "x-portable-bitmap" }, { "pbmraw", "x-portable-bitmap" }, { "pcx16", "x-pcx" }, { "pcx24b", "x-pcx" }, { "pcx256", "x-pcx" }, { "pcxcmyk", "x-pcx" }, { "pcxgray", "x-pcx" }, { "pcxmono", "x-pcx" }, { "pgm", "x-portable-graymap" }, { "png16", "png" }, { "png16m", "png" }, { "png256", "png" }, { "pngalpha", "png" }, { "pnggray", "png" }, { "pnm", "x-portable-anymap" }, { "ppm", "x-portable-pixmap" }, { "tiff12nc", "tiff" }, { "tiff24nc", "tiff" }, { "tiffcrle", "tiff" }, { "tiffg3", "tiff" }, { "tiffg32d", "tiff" }, { "tiffg4", "tiff" }, { "tifflzw", "tiff" }, { "tiffpack", "tiff" } }; #define MIMECOUNT (sizeof(mimes)/sizeof(MIMES)) #endif char gsargs[] = GSPATH " " "-q " "-dBATCH " "-dGraphicsAlphaBits=%i " "-dTextAlphaBits=%i " "-r%ix%i " "-g%ix%i " "-dNOPAUSE " "%s" "-sDEVICE=%s" " -sOutputFile=- " "-" #ifndef X "\0 | " GZPATH #endif ; char *input = NULL; #ifdef X unsigned int naptime = 0; int printpid = 0; char *format = XCOLOR; #else char *output = NULL; char *mimelist = NULL; char *user = NULL; #if (PNMDEFAULT) char *format = "pnm"; #else char *format = "png16m"; #endif // PNMDEFAULT int cgi = 0; unsigned int gzip = GZIP; #endif // X int usestdin = 1; int mime = 0; int bbox = 0; int flags = 0; int hres = HRES; int vres = VRES; int gab = 4; int tab = 4; int x = 0; int y = 0; int dx = 0; int dy = 0; int dX = 0; int dY = 0; int width = -1; int height = -1; int bwidth = -1; int bheight = -1; int angle = 0; char safer[] = "-dSAFER "; char buffer[1024]; int version(void) { printf(PEPS " v." VERSION "\n"); return 0; } int bug(int b) { fprintf(stderr, PEPS ": Fatal error %u (programmer was tired)\n", b); return b; } int defaults(void) { printf( "On this system, " PEPS " v." VERSION " was compiled for these defaults:\n\n" "\tHorizontal resolution = %u dpi,\n" "\tVertical resolution = %u dpi,\n" "\tGhostscript path = " GSPATH ",\n" #ifdef X "\tColor output device = " XCOLOR ",\n" "\tGrayscale device = " XGRAY ",\n" "\tEvaporation delay = %u seconds.\n" #else "\tgzip path = " GZPATH ",\n" "\tSystem MIME list = " ETC "/peps.mime,\n" #if PNMDEFAULT "\tOutput format = pnm,\n" #else "\tOutput format = PNG (16 million colors),\n" #endif #if GZIP == 0 "\tgzip compression OFF.\n" #elif GZIP == 1 "\tgzip compression ON whenever the output goes to stdout.\n" #elif GZIP == 2 "\tgzip compression ON when:\n\n" "\t\t1. CGI use is specified with -c, and\n" "\t\t2. " HAE " lists gzip, and\n" "\t\t3. the output format is not PNG,\n\n" "\tgzip compression OFF otherwise.\n" #else "\tgzip compression ON when:\n\n" "\t\t1. CGI use is specified with -c, and\n" "\t\t2. " HAE " lists gzip,\n\n" "\tgzip compression OFF otherwise.\n" #endif #endif // X "\nYou can override all defaults with command line switches.\n" "To see them, type:\n\n" "\t" PEPS " -h\n", HRES, VRES #ifdef X , EVAPORATIONDELAY #endif ); return 0; } int usage(int where) { fprintf(where ? stdout : stderr, "Usage: " PEPS " [option ...] [file]\n" "\t-g\t-t" "\t-r\t-h\n" "\t-v\t-a" "\t-x

\t-X

\n" "\t-y

\t-Y

" "\t-w\t-W\n" "\t-q\t-Q" "\t-z\t-Z\n" "\t-u " "\t-M \n" "\t-b \n" "\t-s (turns off gs safety)\n" #ifdef X "\t-e|E (evaporation delay)\n" "\t-p (output in color, this is the default)\n" "\t-m (output in grayscale)\n" "\t-n (ignored by " PEPS ")\n" "\t-f (ignored by " PEPS ")\n" "\t-o (ignored by " PEPS ")\n" "\t-c (ignored by " PEPS ")\n" "\t-C (ignored by " PEPS ", which just quits)\n" #else "\t-e|E (ignored by " PEPS ")\n" #if PNMDEFAULT "\t-p (output in color PNG format, default is pnm)\n" "\t-m (output in monochrome PNG format, default is pnm)\n" "\t-n (output in pnm format, overrides -m, this is the default)\n" #else "\t-p (output in color PNG format, this is the default)\n" "\t-m (output in monochrome PNG format, default is color PNG)\n" "\t-n (output in pnm format, the default is PNG)\n" #endif "\t-f (output in a different format)\n" "\t-o (output to a file, default is stdout)\n" "\t-c (print HTTP content type, ignored if -o)\n" "\t-C (print HTTP content type and exit)\n" #endif // X "\t-i (use stdin, this is the default)\n" "\t-d (show defaults)\n\n" "\t = 1 | 2 | 4\n" "\t = resolution in ppi\n" "\t = width in pixels\n" "\t = height in pixels\n" "\t = angle in degrees\n" "\t

= offset in points\n" "\t = left edge of bounding box\n" "\t = bottom edge of bounding box\n" "\t = right edge of bounding box\n" "\t = top edge of bounding box\n\n" "See http://" PEPS ".redprince.net for details.\n"); return !where; } int invalid(FILE *eps) { if (!usestdin) { fprintf(stderr, PEPS ": %s is not a valid EPS file.\n", input); if (eps) fclose(eps); } else fprintf(stderr, PEPS ": Missing EPS header.\n"); return 4; } int parse (FILE *eps) { register char *charptr; while (!feof(eps)) { fgets(buffer, 1024, eps); if (!strncmp(buffer, "%%BoundingBox:", 14)) { charptr = buffer + 14; while (*charptr <= ' ') { if (!*charptr) break; charptr++; } if (((*charptr == '-') && (isdigit(charptr[1]))) || isdigit(*charptr)) { x = -atoi(charptr); while (*charptr > ' ') charptr++; while (*charptr <= ' ') { if (!*charptr) break; charptr++; } if (((*charptr == '-') && (isdigit(charptr[1]))) || isdigit(*charptr)) { y = -atoi(charptr); while (*charptr > ' ') charptr++; while (*charptr <= ' ') { if (!*charptr) break; charptr++; } if (((*charptr == '-') && (isdigit(charptr[1]))) || isdigit(*charptr)) { width = atoi(charptr) + x; while (*charptr > ' ') charptr++; while (*charptr <= ' ') { if (!*charptr) break; charptr++; } if (((*charptr == '-') && (isdigit(charptr[1]))) || isdigit(*charptr)) { height = atoi(charptr) + y; if ((width > 0) && (height > 0)) return 0; } } } } } } return 1; } #ifndef X int outputmime(char *mimelist) { char *charptr; char *mimeptr; register int i; FILE *m; if (m = fopen(mimelist, "r")) while (fgets(buffer, 1024, m) != NULL) { // Strip leading blanks charptr = buffer; while (*charptr && (*charptr <= ' ')) charptr++; if ((*charptr == '#') || (!*charptr)) continue; if (!strncmp(format, charptr, i = strlen(format)) && (charptr[i] <= ' ')) for (mimeptr = charptr+i; *mimeptr; mimeptr++) { if (*mimeptr <= ' ') continue; // Strip any comment for (charptr = mimeptr; *charptr; charptr++) if (*charptr == '#') { *charptr = '\0'; break; } // Strip any trailing blanks while ((*charptr <= ' ') && (charptr >= mimeptr)) { *charptr = '\0'; charptr--; } if (*mimeptr) { fclose(m); printf("%s\n", mimeptr); return 1; } else break; } } if (m) fclose(m); return 0; } int printusermime(void) { struct passwd *pwd; if (!user) user = getenv("PEPSUSER"); pwd = user ? getpwnam(user) : getpwuid(geteuid()); if (pwd && pwd->pw_dir) { sprintf(buffer, "%s/peps.mime", pwd->pw_dir); return outputmime(buffer); } else return 0; } int printmime(int newline) { int i = 0; // So it != MIMECOUNT if we do not go in the for loop if (!format || !*format) return 23; printf("Content-Type: "); if (!outputmime(mimelist) && !printusermime() && !outputmime(ETC "/peps.mime")) for (; i < MIMECOUNT; i++) { if (strcmp(format, mimes[i].format) == 0) { printf("image/%s\n", mimes[i].mime); break; } } if (i == MIMECOUNT) printf("image/x-%s\n", format); if (newline) { if (gzip) printf("Content-Encoding: gzip\n\n"); else fputc('\n', stdout); } fflush(stdout); return 0; } #endif // X int blackhole(void) { fprintf(stderr, PEPS ": Image absorbed by a black hole.\n"); return 13; } int main(int argc, char *argv[]) { register int i, c; register char *charptr; FILE *gs, *eps; double tempdouble; for (i = 1; i < argc; i++) { charptr = argv[i]; if (*charptr == '-') { charptr++; switch (*charptr) { default: return usage(0); case '\0': charptr = argv[++i]; if (!charptr || (*charptr != '-')) return usage(0); // fall through case '-': input = charptr; usestdin = 0; break; case 'C': if (charptr[1] != '\0') return usage(0); else mime = 1; break; case 'E': charptr++; if (!*charptr && argv[i+1] && isdigit(*argv[i+1])) charptr = argv[++i]; #ifdef X naptime = (charptr && isdigit(*charptr)) ? strtoul(charptr, NULL, 0) : EVAPORATIONDELAY; printpid = 1; #endif break; case 'M': charptr++; if (!*charptr) charptr = argv[++i]; if (!charptr) return usage(0); #ifndef X mimelist = *charptr ? charptr : NULL; #endif break; case 'Q': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && isdigit(*charptr)) bheight = atoi(charptr); else return usage(0); flags |= FLAGWIDTH | FLAGHEIGHT; bwidth = -1; break; case 'S': if (charptr[1] == '\0') safer[0] = '-'; else return usage(0); break; case 'W': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && isdigit(*charptr)) bwidth = atoi(charptr); else return usage(0); flags |= FLAGWIDTH | FLAGHEIGHT; bheight = -1; break; case 'X': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && (isdigit(*charptr) || ((*charptr == '-') && isdigit(charptr[1])))) dX = atoi(charptr); else return usage(0); break; case 'Y': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && (isdigit(*charptr) || ((*charptr == '-') && isdigit(charptr[1])))) dY = atoi(charptr); else return usage(0); break; case 'Z': if (charptr[1]) return usage(0); #ifndef X gzip = 0; #endif break; case 'a': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && (isdigit(*charptr) || ((*charptr == '-') && isdigit(charptr[1])))) angle = atoi(charptr); else return usage(0); break; case 'b': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && (((*charptr == '-') && isdigit(charptr[1])) || isdigit(*charptr))) x = -atoi(charptr); else return usage(0); charptr = argv[++i]; if (charptr && (((*charptr == '-') && isdigit(charptr[1])) || isdigit(*charptr))) y = -atoi(charptr); else return usage(0); charptr = argv[++i]; if (charptr && (((*charptr == '-') && isdigit(charptr[1])) || isdigit(*charptr))) width = atoi(charptr) + x; else return usage(0); charptr = argv[++i]; if (charptr && (((*charptr == '-') && isdigit(charptr[1])) || isdigit(*charptr))) height = atoi(charptr) + y; else return usage(0); bbox = 1; break; case 'c': if (charptr[1] != '\0') return usage(0); #ifndef X else cgi = 1; #endif break; case 'd': if (!charptr[1]) return defaults(); else return usage(0); break; case 'e': charptr++; if (!*charptr && argv[i+1] && isdigit(*argv[i+1])) charptr = argv[++i]; #ifdef X naptime = (charptr && isdigit(*charptr)) ? strtoul(charptr, NULL, 0) : EVAPORATIONDELAY; printpid = 0; #endif break; case 'f': charptr++; if (!*charptr) charptr = argv[++i]; // A valid Ghostscript device name starts with a letter. // The rest of it can consist of letters, digits // and underscores. if (!charptr || !isalpha(*charptr)) return usage(0); #ifndef X format = charptr; #endif for (charptr++; *charptr; charptr++) if (!isalnum(*charptr) && (*charptr != '_')) return usage(0); break; case 'g': charptr++; if (!*charptr) charptr = argv[++i]; if (!charptr || charptr[1]) return usage(0); switch (*charptr) { case '1': gab = 1; break; case '2': gab = 2; break; case '4': gab = 4; break; default: return usage(0); } break; case 'h': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && isdigit(*charptr)) hres = atoi(charptr); else return usage(1); flags &= ~FLAGWIDTH; bwidth = -1; if (bheight < 0) flags &= ~FLAGHEIGHT; break; case 'i': if (charptr[1] == '\0') { usestdin = 1; input = NULL; } else return usage(0); break; case 'l': charptr++; if (!*charptr) charptr = argv[++i]; if (!charptr || charptr[1]) return usage(0); switch (*charptr) { case '1': gab = 1; tab = 1; break; case '2': gab = 2; tab = 2; break; case '4': gab = 4; tab = 4; break; default: return usage(0); } break; case 'm': if (charptr[1] == '\0') #ifdef X format = XGRAY; #else format = "pnggray"; #endif else return usage(0); break; case 'n': if (charptr[1] != '\0') return usage(0); #ifndef X else format = "pnm"; #endif break; case 'o': charptr++; if (!*charptr) charptr = argv[++i]; if (!charptr) return usage(0); #ifndef X output = charptr; #endif break; case 'p': if (charptr[1] == '\0') #ifdef X format = XCOLOR; #else format = "png16m"; #endif else return usage(0); break; case 'q': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && isdigit(*charptr)) bheight = atoi(charptr); else return usage(0); flags |= FLAGHEIGHT; break; case 'r': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && isdigit(*charptr)) hres = vres = atoi(charptr); else return usage(0); flags &= ~(FLAGWIDTH | FLAGHEIGHT); bwidth = -1; bheight = -1; break; case 's': if (charptr[1] == '\0') safer[0] = '\0'; else return usage(0); break; case 't': charptr++; if (!*charptr) charptr = argv[++i]; if (!charptr || charptr[1]) return usage(0); switch (*charptr) { case '1': tab = 1; break; case '2': tab = 2; break; case '4': tab = 4; break; default: return usage(0); } break; case 'u': charptr++; if (!*charptr) charptr = argv[++i]; if (!charptr) return usage(0); #ifndef X else user = charptr; #endif break; case 'v': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && isdigit(*charptr)) vres = atoi(charptr); else return version(); flags &= ~FLAGHEIGHT; bheight = -1; if (bwidth < 0) flags &= ~FLAGWIDTH; break; case 'w': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && isdigit(*charptr)) bwidth = atoi(charptr); else return usage(0); flags |= FLAGWIDTH; break; case 'x': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && (isdigit(*charptr) || ((*charptr == '-') && isdigit(charptr[1])))) dx = atoi(charptr); else return usage(0); break; case 'y': charptr++; if (!*charptr) charptr = argv[++i]; if (charptr && (isdigit(*charptr) || ((*charptr == '-') && isdigit(charptr[1])))) dy = atoi(charptr); else return usage(0); break; case 'z': if (charptr[1]) return usage(0); #ifndef X gzip = 1; #endif break; } } else { input = charptr; usestdin = 0; } } if (mime) #ifdef X return 0; #else return printmime(0); #endif if ((!hres) || (!vres)) { fprintf(stderr, PEPS ": Resolution cannot be 0.\n"); return usage(0); } if (!format) return bug(17); if (usestdin) { eps = stdin; #ifdef X if (!naptime) naptime = EVAPORATIONDELAY; #endif } else if (!input) return usage(0); else if ((eps = fopen(input, "r")) == NULL) { perror(input); return 3; } #ifndef X if (output && *output) { cgi = 0; gzip = 0; if (freopen(output, "w", stdout) == NULL) { perror(output); if (eps != stdin) fclose(eps); return 7; } } /* * How we interpret the gzip value: * * gzip == 0, do not compress * gzip == 1, do compress * gzip > 1 and cgi == 0, do not compress * otherwise * gzip == 2 and the output format is PNG, do not compress * otherwise do compress * * Of course, it all depends on how we compile peps. * * Additionally, if gzip > 1, we only compress if the * browser has indicated it accepts gzip encoding * by listing it in HTTP_ACCEPT_ENCODING. */ #if GZIP == 2 if ((!cgi && (gzip == 2)) || ((gzip == 2) && !strncmp(format, "png", 3))) gzip = 0; #elif GZIP > 2 if (!cgi && (gzip == GZIP)) gzip = 0; #endif #if GZIP > 1 if ( (gzip == GZIP) && !((charptr = getenv(HAE)) && strstr(charptr, "gzip")) ) gzip = 0; #endif if (gzip) gsargs[strlen(gsargs)] = ' '; #endif // X /* Parse input file */ if (!bbox) { fgets(buffer, 1024, eps); if (*buffer == '#') fgets(buffer, 1024, eps); if ((strncmp(buffer, "%!PS-Adobe-", 11)) || parse(eps)) return invalid(eps); if (!usestdin) rewind(eps); } x += dx; y += dy; width += dx + dX; height += dy + dY; if ((width <= 0) || (height <= 0)) return blackhole(); if (flags & FLAGWIDTH) { if (flags & FLAGHEIGHT) { if (bheight < 0) { if (bwidth <= 0) return blackhole(); // Set the resolution to make sure the output // is bwidth pixels wide. tempdouble = (double)bwidth / (double)width; hres = vres = (int)(72.0 * tempdouble + 0.5); bheight = (int)(tempdouble * (double)height + 0.5); } else if (bwidth < 0) { // Set the resolution to make the output // bheight pixels wide. tempdouble = (double)bheight / (double)height; hres = vres = (int)(72.0 * tempdouble + 0.5); bwidth = (int)(tempdouble * (double)width + 0.5); } else { // Set the horizontal resolution so the output is bwidth // pixels wide, and the vertical resolution so it is // bheight pixels high. hres = (int)(((72.0 * (double)bwidth) / (double)width) + 0.5); vres = (int)(((72.0 * (double)bheight) / (double)height) + 0.5); } } else { if (bwidth < 0) return blackhole(); // Set the horizontal resolution to make the output bwidth // pixels wide. hres = (int)(((72.0 * (double)bwidth) / (double)width) + 0.5); //Set the bitmap height according to the vertical resolution. bheight = (int)(((double)vres * (double)height / 72.0) + 0.5); } } else if (flags & FLAGHEIGHT) { if (bheight < 0) return blackhole(); // Set the vertical resolution so the output is bheight pixels high. vres = (int)(((72.0 * (double)bheight) / (double)height) + 0.5); // Set the bitmap width according to horizontal resolution bwidth = (int)(((double)hres * (double)width / 72.0) + 0.5); } else { bwidth = (int)(((double)hres * (double)width / 72.0) + 0.5); bheight = (int)(((double)vres * (double)height / 72.0) + 0.5); } if ((bwidth <= 0) || (bheight <= 0) || (hres <= 0) || (vres <= 0)) return blackhole(); sprintf(buffer, gsargs, gab, tab, hres, vres, bwidth, bheight, safer, format); #ifdef X if (naptime) switch (i = fork()) { case 0: case -1: break; default: if (printpid) printf("pid = %i\n", i); return 0; } #endif if ((gs = popen(buffer, "w")) == NULL) { perror(PEPS " (gs)"); return 5; } #ifndef X if (cgi) printmime(1); #endif fprintf(gs, "%%!PS-Adobe-3.0\n" "%%%%BoundingBox: 0 0 %i %i\n" "%%%%Creator: " PEPS "-" VERSION "\n" "%%%%EndComments\n" "%%%%BeginProlog\n" "/BeginEPSF {\n" "/peps_state save def\n" "/dict_count countdictstack def\n" "/op_count count 1 sub def\n" "userdict begin\n" "/showpage { } def\n" "0 setgray 0 setlinecap\n" "1 setlinewidth 0 setlinejoin\n" "10 setmiterlimit [ ] 0 setdash newpath\n" "/languagelevel where\n" "{pop languagelevel\n" "1 ne\n" "{false setstrokeadjust false setoverprint\n" "} if } if } bind def\n\n" "/EndEPSF {\n" "count op_count sub {pop} repeat\n" "countdictstack dict_count sub {end} repeat\n" "peps_state restore\n" "} bind def\n" "%%%%EndProlog\n" "%%%%BeginSetup\n" "%%%%EndSetup\n" "%%%%Page: 1 1\n" "%%%%BeginPageSetup\n" "%%%%EndPageSetup\n" "BeginEPSF\n" "%i %i 2 div add %i %i 2 div add translate\n" "%i rotate\n" "%i 2 div %i 2 div translate\n" "%%%%BeginDocument: %s\n", width, height, x, width, y, height, angle, -width, -height, usestdin ? "stdin" : input ); // PostScript does not follow the Unix convention // Of using the '#' for comments. However, peps will // assume that if the FIRST line of input starts with // it, it is a shell script. In that case we will // not pass the first line to gs. // // If the bounding box was not passsed on the command line // and the input comes from stdin, we have already removed // the first line. So, we only check for it if that is // not the case. if (bbox || !usestdin) { c = fgetc(eps); if (c == '#') { while (c != '\n') c = fgetc(eps); } else if (c != EOF) fputc(c, gs); } while ((c = fgetc(eps)) != EOF) fputc(c, gs); if (eps != stdin) fclose(eps); fprintf(gs, "%%%%EndDocument\n" "EndEPSF\n" #ifndef X "showpage\n" "%%%%EOF\n" "quit\n" #endif ); #ifdef X fflush(gs); if (naptime) sleep(naptime); else { printf("Press ENTER to quit " PEPS ". "); fgetc(stdin); } fprintf(gs, "showpage\n" "%%%%EOF\n" "quit\n"); #endif return pclose(gs); }