/* Copyright (C) 2001-2005 Peter Selinger. This file is part of psdim. It is free software and it is covered by the GNU general public license. See the file COPYING for details. */ /* $Id: psdim.c,v 1.3 2005/03/31 03:20:13 selinger Exp $ */ #include #include #include #include #include "config.h" #include "main.h" #include "psdim.h" /* x1list[n] is the index of the leftmost bit in the binary representation of n. x2list[n] is the index of the rightmost bit. */ int x1list[] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; int x2list[] = { 0, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 3, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 2, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 3, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 1, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 3, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 2, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 3, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, 4, 8, 7, 8, 6, 8, 7, 8, 5, 8, 7, 8, 6, 8, 7, 8, }; char *strcat_safe(char *dest, const char *src) { dest = realloc(dest, strlen(dest)+strlen(src)+1); if (dest) { strcat(dest, src); } return dest; } /* skip whitespace and comments, then read a non-negative decimal number from a stream. Return -1 on EOF. Tolerate other errors (skip bad characters). Also read the immediately following character, or to the end of the line if next character is a comment character. */ int readnum(FILE *f) { int c; int acc; /* skip whitespace and comments */ while (1) { c = fgetc(f); if (c=='#') { while (1) { c = fgetc(f); if (c=='\n' || c==EOF) break; } } if (c==EOF) return -1; if (c>='0' && c<='9') break; } /* first digit is already in c */ acc = c-'0'; while (1) { c = fgetc(f); if (c=='#') { while (1) { c = fgetc(f); if (c=='\n' || c==EOF) break; } } if (c<'0' || c>'9') break; acc *= 10; acc += c-'0'; } return acc; } /* read zero or more portable bitmaps from GS and figure out the dimension of their printed area. This information is collected for all pages modulo n, e.g., if n=2, the info is summarized separately for even and odd pages. Return 0 on error, else -1 with merrno set. */ int psdim(char *infile, int n, bbox_t *bboxes) { FILE *f; char *cmd; int magic[2]; int y, i, j, b, p, c; int w, h; /* width, height in pixels */ int bpr; /* bytes per row */ int x1, x2; cmd = strdup(""GS" -q -dNOPAUSE -sDEVICE=pbmraw -g1008x1008 -sOutputFile=- "); if (infile) { cmd = strcat_safe(cmd, "-- "); cmd = strcat_safe(cmd, infile); } else { cmd = strcat_safe(cmd, "-"); } f = popen(cmd, "r"); free(cmd); if (!f) { merrno = ME_GSNOTFOUND; return -1; } for (j=0; j=0; y--) { for (i=0; ibboxes[j].y1) { bboxes[j].y1 = y; } if (ybboxes[j].x1) { x1 = x1list[b] + i*8; x2 = x2list[b] + i*8 - 1; if (x1bboxes[j].x1) bboxes[j].x1 = x2; } } } if (!info.quiet) { c += fprintf(stderr, "[%d] ", p); if (c >= 75) { fprintf(stderr, "\n"); c = 0; } } j = (j+1) % n; p++; } /* while(1) */ eof_error: pclose(f); if (!info.quiet && c!=0) { fprintf(stderr, "\n"); } merrno = ME_EOF; return -1; format_error: pclose(f); if (!info.quiet && c!=0) { fprintf(stderr, "\n"); } merrno = ME_POSTSCRIPT; return -1; eof: if (!info.quiet && c!=0) { fprintf(stderr, "\n"); } /* note: we now ignore the return value of pclose, as this was sometimes -1 (with errno=ECHILD) although everything worked fine. */ pclose(f); return 0; } /* like psdim, except use colored bitmaps. Return 0 on error, else -1 with merrno set. NOTE: this calculates the right dimensions; however, pstops does not work well on colored backgrounds due to stupid cropping. */ int psdim_color(char *infile, int n, bbox_t *bboxes) { FILE *f; char *cmd; int magic[2]; int y, x, i, j, b, p, c; int maxval, bpp; int w, h; /* width, height in pixels */ int ink, first; unsigned char pix[6]; cmd = strdup(""GS" -q -dNOPAUSE -sDEVICE=ppmraw -g1008x1008 -sOutputFile=- "); if (infile) { cmd = strcat_safe(cmd, "-- "); cmd = strcat_safe(cmd, infile); } else { cmd = strcat_safe(cmd, "-"); } f = popen(cmd, "r"); free(cmd); if (!f) { merrno = ME_GSNOTFOUND; return -1; } for (j=0; j=65536) goto format_error; bpp = (maxval >= 256) ? 6 : 3; /* bytes per pixel */ /* read P6 format */ first = 1; for (y=h-1; y>=0; y--) { for (x=0; xbboxes[j].y1) { bboxes[j].y1 = y; } if (ybboxes[j].x1) { bboxes[j].x1 = x; } if (x= 75) { fprintf(stderr, "\n"); c = 0; } } j = (j+1) % n; p++; } /* while(1) */ eof_error: pclose(f); if (!info.quiet && c!=0) { fprintf(stderr, "\n"); } merrno = ME_EOF; return -1; format_error: pclose(f); if (!info.quiet && c!=0) { fprintf(stderr, "\n"); } merrno = ME_POSTSCRIPT; return -1; eof: if (!info.quiet && c!=0) { fprintf(stderr, "\n"); } pclose(f); return 0; }