diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2008-08-05 13:03:15 +0200 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@gnome.org> | 2008-08-05 13:03:15 +0200 |
commit | c17c602cf494ee2b280f3e2ea09346a08000d61d (patch) | |
tree | c8b1635c4400a6dfdb7ddc38c556616b6e2bfb86 | |
parent | 0196965f9c09e0b3bbfff847c3aed16b59be959f (diff) |
Support DOS EPS files in order to ignore the preview stuff
Based on changes made by Russell Lang for GSview.
Fixes bug #16810
-rw-r--r-- | libspectre/ps.c | 166 | ||||
-rw-r--r-- | libspectre/ps.h | 16 |
2 files changed, 153 insertions, 29 deletions
diff --git a/libspectre/ps.c b/libspectre/ps.c index bee2db9..a2c1a34 100644 --- a/libspectre/ps.c +++ b/libspectre/ps.c @@ -53,6 +53,12 @@ * ###jp### 04/96 * */ + +/* modified by Russell Lang, rjl@aladdin.com to use with GSview + * 1995-01-11 + * supports DOS EPS files (binary header) + */ + #define USE_ACROREAD_WORKAROUND #include <stdlib.h> @@ -182,16 +188,22 @@ typedef struct FileDataStruct_ { static FileData ps_io_init PT((FILE *)); static void ps_io_exit PT((FileData)); +static void ps_io_rewind PT((FileData)); static char *ps_io_fgetchars PT((FileData, int)); static int ps_io_fseek PT((FileData, int)); static int ps_io_ftell PT((FileData)); -static char *readline PT((FileData, char **, long *, unsigned int *)); +static char *readline PT((FileData, unsigned long, char **, long *, unsigned int *)); static char *gettextline PT((char *)); static char *ps_gettext PT((char *,char **)); static int blank PT((char *)); static char *pscopyuntil PT((FileData,FILE *,long,long,char *)); +/* DOS EPS header reading */ +static unsigned long ps_read_doseps PT((FileData, DOSEPS *)); +static PS_DWORD reorder_dword PT((PS_DWORD)); +static PS_WORD reorder_word PT((PS_WORD)); + static char *skipped_line = "% ps_io_fgetchars: skipped line"; static char *empty_string = ""; @@ -345,6 +357,8 @@ psscan(const char *filename, int scanstyle) char *next_char; /* 1st char after text returned by ps_gettext() */ char *cp; ConstMedia dmp; + unsigned long enddoseps; /* zero of not DOS EPS, otherwise position of end of ps section */ + DOSEPS doseps; FileData fd; int respect_eof; /* Derived from the scanstyle argument. If set to 0 EOF comments will be ignored, @@ -378,7 +392,10 @@ psscan(const char *filename, int scanstyle) } fd = ps_io_init(file); - if (!readline(fd,&line, &position, &line_len)) { + + /* rjl: check for DOS EPS files and almost DSC files that start with ^D */ + enddoseps = ps_read_doseps (fd, &doseps); + if (!readline(fd, enddoseps, &line, &position, &line_len)) { fprintf(stderr, "Warning: empty file.\n"); ENDMESSAGE(psscan) ps_io_exit(fd); @@ -391,7 +408,7 @@ psscan(const char *filename, int scanstyle) * follows, this seems to be a real pjl file. */ if(iscomment(line, "\033%-12345X@PJL")) { /* read until first DSC comment */ - while(readline(fd, &line, &position, &line_len) && (line[0] != '%')) ; + while(readline(fd, enddoseps, &line, &position, &line_len) && (line[0] != '%')) ; if(line[0] != '%') { fprintf(stderr, "psscan error: input files seems to be a PJL file.\n"); ENDMESSAGE(psscan) @@ -453,9 +470,14 @@ psscan(const char *filename, int scanstyle) doc->default_page_orientation = NONE; doc->orientation = NONE; } + + if (enddoseps) { /* rjl: add doseps header */ + doc->doseps = (DOSEPS *) malloc(sizeof(DOSEPS)); + *(doc->doseps) = doseps; + } preread = 0; - while (preread || readline(fd, &line, &position, &line_len)) { + while (preread || readline(fd, enddoseps, &line, &position, &line_len)) { if (!preread) section_len += line_len; preread = 0; if (line[0] != '%' || @@ -587,7 +609,7 @@ psscan(const char *filename, int scanstyle) PS_free(doc->media[0].name); } preread=1; - while (readline(fd, &line, &position, &line_len) && + while (readline(fd, enddoseps, &line, &position, &line_len) && DSCcomment(line) && iscomment(line+2, "+")) { section_len += line_len; doc->media = (Media) @@ -675,7 +697,7 @@ psscan(const char *filename, int scanstyle) PS_free(doc->media[doc->nummedia].name); } preread=1; - while (readline(fd, &line, &position, &line_len) && + while (readline(fd, enddoseps, &line, &position, &line_len) && DSCcomment(line) && iscomment(line+2, "+")) { section_len += line_len; next_char = line + length("%%+"); @@ -713,7 +735,7 @@ psscan(const char *filename, int scanstyle) } if (DSCcomment(line) && iscomment(line+2, "EndComments")) { - readline(fd, &line, &position, &line_len); + readline(fd, enddoseps, &line, &position, &line_len); section_len += line_len; } doc->endheader = position; @@ -723,19 +745,19 @@ psscan(const char *filename, int scanstyle) beginsection = position; section_len = line_len; - while (blank(line) && readline(fd, &line, &position, &line_len)) { + while (blank(line) && readline(fd, enddoseps, &line, &position, &line_len)) { section_len += line_len; } if (doc->epsf && DSCcomment(line) && iscomment(line+2, "BeginPreview")) { doc->beginpreview = beginsection; beginsection = 0; - while (readline(fd, &line, &position, &line_len) && + while (readline(fd, enddoseps, &line, &position, &line_len) && !(DSCcomment(line) && iscomment(line+2, "EndPreview"))) { section_len += line_len; } section_len += line_len; - readline(fd, &line, &position, &line_len); + readline(fd, enddoseps, &line, &position, &line_len); section_len += line_len; doc->endpreview = position; doc->lenpreview = section_len - line_len; @@ -747,14 +769,14 @@ psscan(const char *filename, int scanstyle) beginsection = position; section_len = line_len; } - while (blank(line) && readline(fd, &line, &position, &line_len)) { + while (blank(line) && readline(fd, enddoseps, &line, &position, &line_len)) { section_len += line_len; } if (DSCcomment(line) && iscomment(line+2, "BeginDefaults")) { doc->begindefaults = beginsection; beginsection = 0; - while (readline(fd, &line, &position, &line_len) && + while (readline(fd, enddoseps, &line, &position, &line_len) && !(DSCcomment(line) && iscomment(line+2, "EndDefaults"))) { section_len += line_len; if (!DSCcomment(line)) { @@ -812,7 +834,7 @@ psscan(const char *filename, int scanstyle) } } section_len += line_len; - readline(fd, &line, &position, &line_len); + readline(fd, enddoseps, &line, &position, &line_len); section_len += line_len; doc->enddefaults = position; doc->lendefaults = section_len - line_len; @@ -824,7 +846,7 @@ psscan(const char *filename, int scanstyle) beginsection = position; section_len = line_len; } - while (blank(line) && readline(fd, &line, &position, &line_len)) { + while (blank(line) && readline(fd, enddoseps, &line, &position, &line_len)) { section_len += line_len; } @@ -838,7 +860,7 @@ psscan(const char *filename, int scanstyle) preread = 1; while ((preread || - readline(fd, &line, &position, &line_len)) && + readline(fd, enddoseps, &line, &position, &line_len)) && !(DSCcomment(line) && (iscomment(line+2, "EndProlog") || iscomment(line+2, "BeginSetup") || @@ -850,7 +872,7 @@ psscan(const char *filename, int scanstyle) } section_len += line_len; if (DSCcomment(line) && iscomment(line+2, "EndProlog")) { - readline(fd, &line, &position, &line_len); + readline(fd, enddoseps, &line, &position, &line_len); section_len += line_len; } doc->endprolog = position; @@ -863,7 +885,7 @@ psscan(const char *filename, int scanstyle) beginsection = position; section_len = line_len; } - while (blank(line) && readline(fd, &line, &position, &line_len)) { + while (blank(line) && readline(fd, enddoseps, &line, &position, &line_len)) { section_len += line_len; } @@ -875,7 +897,7 @@ psscan(const char *filename, int scanstyle) beginsection = 0; preread = 1; while ((preread || - readline(fd, &line, &position, &line_len)) && + readline(fd, enddoseps, &line, &position, &line_len)) && !(DSCcomment(line) && (iscomment(line+2, "EndSetup") || iscomment(line+2, "Page:") || @@ -943,7 +965,7 @@ psscan(const char *filename, int scanstyle) } section_len += line_len; if (DSCcomment(line) && iscomment(line+2, "EndSetup")) { - readline(fd, &line, &position, &line_len); + readline(fd, enddoseps, &line, &position, &line_len); section_len += line_len; } doc->endsetup = position; @@ -976,7 +998,7 @@ psscan(const char *filename, int scanstyle) (iscomment(line+2, "Page:") || iscomment(line+2, "Trailer") || (respect_eof && iscomment(line+2, "EOF"))))) && - (readline(fd, &line, &position, &line_len))) { + (readline(fd, enddoseps, &line, &position, &line_len))) { section_len += line_len; doc->lensetup = section_len - line_len; doc->endsetup = position; @@ -990,7 +1012,7 @@ psscan(const char *filename, int scanstyle) beginsection = position; section_len = line_len; } - while (blank(line) && readline(fd, &line, &position, &line_len)) { + while (blank(line) && readline(fd, enddoseps, &line, &position, &line_len)) { section_len += line_len; } @@ -1031,7 +1053,7 @@ newpage: section_len = line_len; } continuepage: - while (readline(fd, &line, &position, &line_len) && + while (readline(fd, enddoseps, &line, &position, &line_len) && !(DSCcomment(line) && (iscomment(line+2, "Page:") || iscomment(line+2, "Trailer") || @@ -1134,7 +1156,7 @@ continuepage: preread = 1; while ((preread || - readline(fd, &line, &position, &line_len)) && + readline(fd, enddoseps, &line, &position, &line_len)) && !(respect_eof && DSCcomment(line) && iscomment(line+2, "EOF"))) { if (!preread) section_len += line_len; preread = 0; @@ -1225,7 +1247,7 @@ continuepage: } section_len += line_len; if (DSCcomment(line) && iscomment(line+2, "EOF")) { - readline(fd, &line, &position, &line_len); + readline(fd, enddoseps, &line, &position, &line_len); section_len += line_len; } doc->endtrailer = position; @@ -1235,7 +1257,7 @@ continuepage: section_len = line_len; preread = 1; while (preread || - readline(fd, &line, &position, &line_len)) { + readline(fd, enddoseps, &line, &position, &line_len)) { if (!preread) section_len += line_len; preread = 0; if (DSCcomment(line) && iscomment(line+2, "Page:")) { @@ -1296,6 +1318,7 @@ psfree(struct document *doc) if (doc->pages) PS_free(doc->pages); if (doc->media) PS_free(doc->media); if (doc->languagelevel) PS_free(doc->languagelevel); + if (doc->doseps) free(doc->doseps); /* rjl: */ PS_free(doc); } ENDMESSAGE(psfree) @@ -1500,11 +1523,33 @@ static FileData ps_io_init(file) FD_BUF_SIZE = (2*LINE_CHUNK_SIZE)+1; FD_BUF = PS_XtMalloc(FD_BUF_SIZE); FD_BUF[0] = '\0'; + ENDMESSAGE(ps_io_init) + return(fd); } /*----------------------------------------------------------*/ +/* ps_io_rewind */ +/*----------------------------------------------------------*/ + +static void +ps_io_rewind(fd) + FileData fd; +{ + rewind(FD_FILE); + FD_FILEPOS = ftell(FD_FILE); + FD_BUF[0] = '\0'; + FD_BUF_END = 0; + FD_BUF_SIZE = 0; + FD_LINE_BEGIN = 0; + FD_LINE_END = 0; + FD_LINE_LEN = 0; + FD_LINE_TERMCHAR = '\0'; + FD_STATUS = FD_STATUS_OKAY; +} + +/*----------------------------------------------------------*/ /* ps_io_exit */ /*----------------------------------------------------------*/ @@ -1715,8 +1760,9 @@ static char * ps_io_fgetchars(fd,num) */ /*----------------------------------------------------------*/ -static char * readline (fd, lineP, positionP, line_lenP) +static char * readline (fd, enddoseps, lineP, positionP, line_lenP) FileData fd; + unsigned long enddoseps; char **lineP; long *positionP; unsigned int *line_lenP; @@ -1729,6 +1775,11 @@ static char * readline (fd, lineP, positionP, line_lenP) BEGINMESSAGE(readline) if (positionP) *positionP = FD_FILEPOS; + if (positionP && enddoseps) { + if (*positionP >= enddoseps) + return NULL; /* don't read any more, we have reached end of dos eps section */ + } + line = ps_io_fgetchars(fd,-1); if (!line) { INFMESSAGE(could not get line) @@ -1747,7 +1798,7 @@ static char * readline (fd, lineP, positionP, line_lenP) #define IS_END(comment) \ (iscomment(line+5,(comment))) #define SKIP_WHILE(cond) \ - while (readline(fd, &line, NULL, &nbytes) && (cond)) *line_lenP += nbytes;\ + while (readline(fd, enddoseps, &line, NULL, &nbytes) && (cond)) *line_lenP += nbytes; \ skipped=1; #define SKIP_UNTIL_1(comment) { \ INFMESSAGE(skipping until comment) \ @@ -1774,14 +1825,14 @@ static char * readline (fd, lineP, positionP, line_lenP) printf("skipping starts here: %s\n",line); SKIP_UNTIL_1("EOF") *line_lenP += nbytes; - readline(fd, &line, NULL, &nbytes); + readline(fd, enddoseps, &line, NULL, &nbytes); printf("skipping ends here: %s\n",line); } } else #endif if ((line[0] == '%') && - positionP && *positionP > 0 && + positionP && *positionP > enddoseps && (!iscomment(line, "%!PS-AdobeFont") && (iscomment(line,"%!PS") || iscomment(line, "\004%!PS")))) { nesting_level=1; line = ps_io_fgetchars(fd,-1); @@ -2171,6 +2222,63 @@ pscopydoc(dest_file,src_filename,d,pagelist) } #undef length +/* rjl: routines to handle reading DOS EPS files */ +static unsigned long dsc_arch = 0x00000001; + +/* change byte order if architecture is big-endian */ +static PS_DWORD +reorder_dword(val) + PS_DWORD val; +{ + if (*((char *)(&dsc_arch))) + return val; /* little endian machine */ + else + return ((val&0xff) << 24) | ((val&0xff00) << 8) + | ((val&0xff0000L) >> 8) | ((val>>24)&0xff); +} + +/* change byte order if architecture is big-endian */ +static PS_WORD +reorder_word(val) + PS_WORD val; +{ + if (*((char *)(&dsc_arch))) + return val; /* little endian machine */ + else + return (PS_WORD) ((PS_WORD)(val&0xff) << 8) | (PS_WORD)((val&0xff00) >> 8); +} + +/* DOS EPS header reading */ +static unsigned long +ps_read_doseps(fd,doseps) + FileData fd; + DOSEPS *doseps; +{ + fread(doseps->id, 1, 4, FD_FILE); + if (! ((doseps->id[0]==0xc5) && (doseps->id[1]==0xd0) + && (doseps->id[2]==0xd3) && (doseps->id[3]==0xc6)) ) { + /* id is "EPSF" with bit 7 set */ + ps_io_rewind(fd); + return 0; /* OK */ + } + fread(&doseps->ps_begin, 4, 1, FD_FILE); /* PS offset */ + doseps->ps_begin = (unsigned long)reorder_dword(doseps->ps_begin); + fread(&doseps->ps_length, 4, 1, FD_FILE); /* PS length */ + doseps->ps_length = (unsigned long)reorder_dword(doseps->ps_length); + fread(&doseps->mf_begin, 4, 1, FD_FILE); /* Metafile offset */ + doseps->mf_begin = (unsigned long)reorder_dword(doseps->mf_begin); + fread(&doseps->mf_length, 4, 1, FD_FILE); /* Metafile length */ + doseps->mf_length = (unsigned long)reorder_dword(doseps->mf_length); + fread(&doseps->tiff_begin, 4, 1, FD_FILE); /* TIFF offset */ + doseps->tiff_begin = (unsigned long)reorder_dword(doseps->tiff_begin); + fread(&doseps->tiff_length, 4, 1, FD_FILE); /* TIFF length */ + doseps->tiff_length = (unsigned long)reorder_dword(doseps->tiff_length); + fread(&doseps->checksum, 2, 1, FD_FILE); + doseps->checksum = (unsigned short)reorder_word(doseps->checksum); + ps_io_fseek(fd, doseps->ps_begin); /* seek to PS section */ + + return doseps->ps_begin + doseps->ps_length; +} /* From Evince */ #define DEFAULT_PAGE_SIZE 1 diff --git a/libspectre/ps.h b/libspectre/ps.h index ba6c55d..3d18399 100644 --- a/libspectre/ps.h +++ b/libspectre/ps.h @@ -68,6 +68,21 @@ enum {ATEND = -1, NONE = 0, PORTRAIT, LANDSCAPE, ASCEND, DESCEND, SPECIAL}; #define PSLINELENGTH 257 /* 255 characters + 1 newline + 1 NULL */ +/* rjl: DOS binary EPS header */ +#define PS_DWORD unsigned long/* must be 32 bits unsigned */ +#define PS_WORD unsigned short/* must be 16 bits unsigned */ +typedef struct tagDOSEPS { + unsigned char id[4]; + PS_DWORD ps_begin; + PS_DWORD ps_length; + PS_DWORD mf_begin; + PS_DWORD mf_length; + PS_DWORD tiff_begin; + PS_DWORD tiff_length; + PS_WORD checksum; +} DOSEPS; + + /*############################################## media ##############################################*/ @@ -114,6 +129,7 @@ typedef struct document { unsigned int nummedia; struct documentmedia *media; ConstMedia default_page_media; + DOSEPS *doseps; unsigned int numpages; struct page *pages; } *Document; |