123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240 |
- /* Copyright (C) 2000, 2001, Ghostgum Software Pty Ltd. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
- distributor accepts any responsibility for the consequences of using it, or
- for whether it serves any particular purpose or works at all, unless he or
- she says so in writing. Refer to the Aladdin Free Public License (the
- "License") for full details.
-
- Every copy of AFPL Ghostscript must include a copy of the License, normally
- in a plain ASCII text file named PUBLIC. The License grants you the right
- to copy, modify and redistribute AFPL Ghostscript, but only under certain
- conditions described in the License. Among other things, the License
- requires that the copyright notice and this notice be preserved on all
- copies.
- */
- /*$Id: dscparse.c,v 1.7 2001/08/01 09:03:40 ghostgum Exp $ */
- /*
- * This is a DSC parser, based on the DSC 3.0 spec,
- * with a few DSC 2.1 additions for page size.
- *
- * Current limitations:
- * %%+ may be used after any comment in the comment or trailer,
- * but is currently only supported by
- * %%DocumentMedia
- *
- * DSC 2.1 additions (discontinued in DSC 3.0):
- * %%DocumentPaperColors:
- * %%DocumentPaperForms:
- * %%DocumentPaperSizes:
- * %%DocumentPaperWeights:
- * %%PaperColor: (ignored)
- * %%PaperForm: (ignored)
- * %%PaperSize:
- * %%PaperWeight: (ignored)
- *
- * Other additions for defaults or page section
- % %%ViewingOrientation: xx xy yx yy
- */
- #include <stdio.h> /* for sprintf(), not file I/O */
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #define MAXSTR 256
- #include "dscparse.h"
- /* Macros for comparing string literals
- * For maximum speed, the length of the second macro argument is
- * computed at compile time.
- * THE SECOND MACRO ARGUMENT MUST BE A STRING LITERAL.
- */
- #define COMPARE(p,str) (strncmp((const char *)(p), (str), sizeof(str)-1)==0)
- #define IS_DSC(line, str) (COMPARE((line), (str)))
- /* Macros for comparing the first one or two characters */
- #define IS_WHITE(ch) (((ch)==' ') || ((ch)=='\t'))
- #define IS_EOL(ch) (((ch)=='\r') || ((ch)=='\n'))
- #define IS_WHITE_OR_EOL(ch) (IS_WHITE(ch) || IS_EOL(ch))
- #define IS_BLANK(str) (IS_EOL(str[0]))
- #define NOT_DSC_LINE(str) (((str)[0]!='%') || ((str)[1]!='%'))
- /* Macros for document offset to start and end of line */
- #define DSC_START(dsc) ((dsc)->data_offset + (dsc)->data_index - (dsc)->line_length)
- #define DSC_END(dsc) ((dsc)->data_offset + (dsc)->data_index)
- /* dsc_scan_SECTION() functions return one of
- * CDSC_ERROR, CDSC_OK, CDSC_NOTDSC
- * or one of the following
- */
- /* The line should be passed on to the next section parser. */
- #define CDSC_PROPAGATE 10
- /* If document is DOS EPS and we haven't read 30 bytes, ask for more. */
- #define CDSC_NEEDMORE 11
- /* local prototypes */
- dsc_private void * dsc_memalloc(P2(CDSC *dsc, size_t size));
- dsc_private void dsc_memfree(P2(CDSC*dsc, void *ptr));
- dsc_private CDSC * dsc_init2(P1(CDSC *dsc));
- dsc_private void dsc_reset(P1(CDSC *dsc));
- dsc_private void dsc_section_join(P3(unsigned long begin, unsigned long *pend, unsigned long **pplast));
- dsc_private int dsc_read_line(P1(CDSC *dsc));
- dsc_private int dsc_read_doseps(P1(CDSC *dsc));
- dsc_private char * dsc_alloc_string(P3(CDSC *dsc, const char *str, int len));
- dsc_private char * dsc_add_line(P3(CDSC *dsc, const char *line, unsigned int len));
- dsc_private char * dsc_copy_string(P5(char *str, unsigned int slen,
- char *line, unsigned int len, unsigned int *offset));
- dsc_private GSDWORD dsc_get_dword(P1(const unsigned char *buf));
- dsc_private GSWORD dsc_get_word(P1(const unsigned char *buf));
- dsc_private int dsc_get_int(P3(const char *line, unsigned int len, unsigned int *offset));
- dsc_private float dsc_get_real(P3(const char *line, unsigned int len,
- unsigned int *offset));
- dsc_private int dsc_stricmp(P2(const char *s, const char *t));
- dsc_private void dsc_unknown(P1(CDSC *dsc));
- dsc_private int dsc_parse_pages(P1(CDSC *dsc));
- dsc_private int dsc_parse_bounding_box(P3(CDSC *dsc, CDSCBBOX** pbbox, int offset));
- dsc_private int dsc_parse_orientation(P3(CDSC *dsc, unsigned int *porientation,
- int offset));
- dsc_private int dsc_parse_order(P1(CDSC *dsc));
- dsc_private int dsc_parse_media(P2(CDSC *dsc, const CDSCMEDIA **page_media));
- dsc_private int dsc_parse_document_media(P1(CDSC *dsc));
- dsc_private int dsc_parse_viewing_orientation(P2(CDSC *dsc, CDSCCTM **pctm));
- dsc_private int dsc_parse_page(P1(CDSC *dsc));
- dsc_private void dsc_save_line(P1(CDSC *dsc));
- dsc_private int dsc_scan_type(P1(CDSC *dsc));
- dsc_private int dsc_scan_comments(P1(CDSC *dsc));
- dsc_private int dsc_scan_preview(P1(CDSC *dsc));
- dsc_private int dsc_scan_defaults(P1(CDSC *dsc));
- dsc_private int dsc_scan_prolog(P1(CDSC *dsc));
- dsc_private int dsc_scan_setup(P1(CDSC *dsc));
- dsc_private int dsc_scan_page(P1(CDSC *dsc));
- dsc_private int dsc_scan_trailer(P1(CDSC *dsc));
- dsc_private int dsc_error(P4(CDSC *dsc, unsigned int explanation,
- char *line, unsigned int line_len));
- /* DSC error reporting */
- dsc_private const int dsc_severity[] = {
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_BBOX */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_EARLY_TRAILER */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_EARLY_EOF */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGE_IN_TRAILER */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGE_ORDINAL */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_PAGES_WRONG */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_EPS_NO_BBOX */
- CDSC_ERROR_ERROR, /* CDSC_MESSAGE_EPS_PAGES */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_NO_MEDIA */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_ATEND */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_DUP_COMMENT */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_DUP_TRAILER */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_BEGIN_END */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_BAD_SECTION */
- CDSC_ERROR_INFORM, /* CDSC_MESSAGE_LONG_LINE */
- CDSC_ERROR_WARN, /* CDSC_MESSAGE_INCORRECT_USAGE */
- 0
- };
- #define DSC_MAX_ERROR ((sizeof(dsc_severity) / sizeof(int))-2)
- const CDSCMEDIA dsc_known_media[CDSC_KNOWN_MEDIA] = {
- /* These sizes taken from Ghostscript gs_statd.ps */
- {"11x17", 792, 1224, 0, NULL, NULL},
- {"A3", 842, 1190, 0, NULL, NULL},
- {"A4", 595, 842, 0, NULL, NULL},
- {"A5", 421, 595, 0, NULL, NULL},
- {"B4", 709, 1002, 0, NULL, NULL}, /* ISO, but not Adobe standard */
- {"B5", 501, 709, 0, NULL, NULL}, /* ISO, but not Adobe standard */
- {"Ledger", 1224, 792, 0, NULL, NULL},
- {"Legal", 612, 1008, 0, NULL, NULL},
- {"Letter", 612, 792, 0, NULL, NULL},
- {"Note", 612, 792, 0, NULL, NULL},
- {NULL, 0, 0, 0, NULL, NULL}
- };
- /* parser state */
- enum CDSC_SCAN_SECTION {
- scan_none = 0,
- scan_comments = 1,
- scan_pre_preview = 2,
- scan_preview = 3,
- scan_pre_defaults = 4,
- scan_defaults = 5,
- scan_pre_prolog = 6,
- scan_prolog = 7,
- scan_pre_setup = 8,
- scan_setup = 9,
- scan_pre_pages = 10,
- scan_pages = 11,
- scan_pre_trailer = 12,
- scan_trailer = 13,
- scan_eof = 14
- };
- static const char * const dsc_scan_section_name[15] = {
- "Type", "Comments",
- "pre-Preview", "Preview",
- "pre-Defaults", "Defaults",
- "pre-Prolog", "Prolog",
- "pre-Setup", "Setup",
- "pre-Page", "Page",
- "pre-Trailer", "Trailer",
- "EOF"
- };
- /******************************************************************/
- /* Public functions */
- /******************************************************************/
- /* constructor */
- CDSC *
- dsc_init(void *caller_data)
- {
- CDSC *dsc = (CDSC *)malloc(sizeof(CDSC));
- if (dsc == NULL)
- return NULL;
- memset(dsc, 0, sizeof(CDSC));
- dsc->caller_data = caller_data;
- return dsc_init2(dsc);
- }
- /* constructor, with caller supplied memalloc */
- CDSC *
- dsc_init_with_alloc(
- void *caller_data,
- void *(*memalloc)(size_t size, void *closure_data),
- void (*memfree)(void *ptr, void *closure_data),
- void *closure_data)
- {
- CDSC *dsc = (CDSC *)memalloc(sizeof(CDSC), closure_data);
- if (dsc == NULL)
- return NULL;
- memset(dsc, 0, sizeof(CDSC));
- dsc->caller_data = caller_data;
- dsc->memalloc = memalloc;
- dsc->memfree = memfree;
- dsc->mem_closure_data = closure_data;
-
- return dsc_init2(dsc);
- }
- /* destructor */
- void
- dsc_free(CDSC *dsc)
- {
- if (dsc == NULL)
- return;
- dsc_reset(dsc);
- dsc_memfree(dsc, dsc);
- }
- /* Tell DSC parser how long document will be, to allow ignoring
- * of early %%Trailer and %%EOF. This is optional.
- */
- void
- dsc_set_length(CDSC *dsc, unsigned long len)
- {
- dsc->file_length = len;
- }
- /* Process a buffer containing DSC comments and PostScript */
- /* Return value is < 0 for error, >=0 for OK.
- * CDSC_ERROR
- * CDSC_OK
- * CDSC_NOTDSC (DSC will be ignored)
- * other values indicate the last DSC comment read
- */
- int
- dsc_scan_data(CDSC *dsc, const char *data, int length)
- {
- int bytes_read;
- int code = 0;
- if (dsc == NULL)
- return CDSC_ERROR;
- if (dsc->id == CDSC_NOTDSC)
- return CDSC_NOTDSC;
- dsc->id = CDSC_OK;
- if (dsc->eof)
- return CDSC_OK; /* ignore */
- if (length == 0) {
- /* EOF, so process what remains */
- dsc->eof = TRUE;
- }
- do {
- if (dsc->id == CDSC_NOTDSC)
- break;
- if (length != 0) {
- /* move existing data if needed */
- if (dsc->data_length > CDSC_DATA_LENGTH/2) {
- memmove(dsc->data, dsc->data + dsc->data_index,
- dsc->data_length - dsc->data_index);
- dsc->data_offset += dsc->data_index;
- dsc->data_length -= dsc->data_index;
- dsc->data_index = 0;
- }
- /* append to buffer */
- bytes_read = min(length, (int)(CDSC_DATA_LENGTH - dsc->data_length));
- memcpy(dsc->data + dsc->data_length, data, bytes_read);
- dsc->data_length += bytes_read;
- data += bytes_read;
- length -= bytes_read;
- }
- if (dsc->scan_section == scan_none) {
- code = dsc_scan_type(dsc);
- if (code == CDSC_NEEDMORE) {
- /* need more characters before we can identify type */
- code = CDSC_OK;
- break;
- }
- dsc->id = code;
- }
- if (code == CDSC_NOTDSC) {
- dsc->id = CDSC_NOTDSC;
- break;
- }
- while ((code = dsc_read_line(dsc)) > 0) {
- if (dsc->id == CDSC_NOTDSC)
- break;
- if (dsc->doseps_end &&
- (dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
- /* have read past end of DOS EPS PostScript section */
- return CDSC_OK; /* ignore */
- }
- if (dsc->eof)
- return CDSC_OK;
- if (dsc->skip_document)
- continue; /* embedded document */
- if (dsc->skip_lines)
- continue; /* embedded lines */
- if (IS_DSC(dsc->line, "%%BeginData:"))
- continue;
- if (IS_DSC(dsc->line, "%%BeginBinary:"))
- continue;
- if (IS_DSC(dsc->line, "%%EndDocument"))
- continue;
- if (IS_DSC(dsc->line, "%%EndData"))
- continue;
- if (IS_DSC(dsc->line, "%%EndBinary"))
- continue;
- do {
- switch (dsc->scan_section) {
- case scan_comments:
- code = dsc_scan_comments(dsc);
- break;
- case scan_pre_preview:
- case scan_preview:
- code = dsc_scan_preview(dsc);
- break;
- case scan_pre_defaults:
- case scan_defaults:
- code = dsc_scan_defaults(dsc);
- break;
- case scan_pre_prolog:
- case scan_prolog:
- code = dsc_scan_prolog(dsc);
- break;
- case scan_pre_setup:
- case scan_setup:
- code = dsc_scan_setup(dsc);
- break;
- case scan_pre_pages:
- case scan_pages:
- code = dsc_scan_page(dsc);
- break;
- case scan_pre_trailer:
- case scan_trailer:
- code = dsc_scan_trailer(dsc);
- break;
- case scan_eof:
- code = CDSC_OK;
- break;
- default:
- /* invalid state */
- code = CDSC_ERROR;
- }
- /* repeat if line is start of next section */
- } while (code == CDSC_PROPAGATE);
- /* if DOS EPS header not complete, ask for more */
- if (code == CDSC_NEEDMORE) {
- code = CDSC_OK;
- break;
- }
- if (code == CDSC_NOTDSC) {
- dsc->id = CDSC_NOTDSC;
- break;
- }
- }
- } while (length != 0);
- return (code < 0) ? code : dsc->id;
- }
- /* Tidy up from incorrect DSC comments */
- int
- dsc_fixup(CDSC *dsc)
- {
- unsigned int i;
- char buf[32];
- unsigned long *last;
- if (dsc->id == CDSC_NOTDSC)
- return 0;
- /* flush last partial line */
- dsc_scan_data(dsc, NULL, 0);
- /* Fix DSC error: code between %%EndSetup and %%Page */
- if (dsc->page_count && (dsc->page[0].begin != dsc->endsetup)
- && (dsc->endsetup != dsc->beginsetup)) {
- dsc->endsetup = dsc->page[0].begin;
- dsc_debug_print(dsc, "Warning: code included between setup and first page\n");
- }
- /* Last page contained a false trailer, */
- /* so extend last page to start of trailer */
- if (dsc->page_count && (dsc->begintrailer != 0) &&
- (dsc->page[dsc->page_count-1].end != dsc->begintrailer)) {
- dsc_debug_print(dsc, "Ignoring earlier misplaced trailer\n");
- dsc_debug_print(dsc, "and extending last page to start of trailer\n");
- dsc->page[dsc->page_count-1].end = dsc->begintrailer;
- }
- /*
- * Join up all sections.
- * There might be extra code between them, or we might have
- * missed including the \n which followed \r.
- */
- last = &dsc->endcomments;
- dsc_section_join(dsc->beginpreview, &dsc->endpreview, &last);
- dsc_section_join(dsc->begindefaults, &dsc->enddefaults, &last);
- dsc_section_join(dsc->beginprolog, &dsc->endprolog, &last);
- dsc_section_join(dsc->beginsetup, &dsc->endsetup, &last);
- for (i=0; i<dsc->page_count; i++)
- dsc_section_join(dsc->page[i].begin, &dsc->page[i].end, &last);
- if (dsc->begintrailer)
- *last = dsc->begintrailer;
-
- if ((dsc->page_pages == 0) && (dsc->page_count == 1)) {
- /* don't flag an error if %%Pages absent but one %%Page found */
- /* adjust incorrect page count */
- dsc->page_pages = dsc->page_count;
- }
- /* Warnings and Errors that we can now identify */
- if ((dsc->page_count != dsc->page_pages)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_PAGES_WRONG, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* adjust incorrect page count */
- dsc->page_pages = dsc->page_count;
- break;
- case CDSC_RESPONSE_CANCEL:
- break;;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if (dsc->epsf && (dsc->bbox == (CDSCBBOX *)NULL)) {
- /* EPS files MUST include a BoundingBox */
- int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_NO_BBOX, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* Assume that it is EPS */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* Is NOT an EPS file */
- dsc->epsf = FALSE;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if (dsc->epsf && ((dsc->page_count > 1) || (dsc->page_pages > 1))) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_EPS_PAGES, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* Is an EPS file */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* Is NOT an EPS file */
- dsc->epsf = FALSE;
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((dsc->media_count == 1) && (dsc->page_media == NULL)) {
- /* if one only media was specified, and default page media */
- /* was not specified, assume that default is the only media. */
- dsc->page_media = dsc->media[0];
- }
- if ((dsc->media_count != 0) && (dsc->page_media == NULL)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_NO_MEDIA, NULL, 0);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* default media is first listed */
- dsc->page_media = dsc->media[0];
- break;
- case CDSC_RESPONSE_CANCEL:
- /* No default media */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- /* make sure all pages have a label */
- for (i=0; i<dsc->page_count; i++) {
- if (strlen(dsc->page[i].label) == 0) {
- sprintf(buf, "%d", i+1);
- if ((dsc->page[i].label = dsc_alloc_string(dsc, buf, strlen(buf)))
- == (char *)NULL)
- return CDSC_ERROR; /* no memory */
- }
- }
- return CDSC_OK;
- }
- /* Install a function to be used for displaying messages about
- * DSC errors and warnings, and to request advice from user.
- * Installing an error function is optional.
- */
- void
- dsc_set_error_function(CDSC *dsc,
- int (*fn)(P5(void *caller_data, CDSC *dsc,
- unsigned int explanation, const char *line, unsigned int line_len)))
- {
- dsc->dsc_error_fn = fn;
- }
- /* Install a function for printing debug messages */
- /* This is optional */
- void
- dsc_set_debug_function(CDSC *dsc,
- void (*debug_fn)(P2(void *caller_data, const char *str)))
- {
- dsc->debug_print_fn = debug_fn;
- }
- /* Doesn't need to be public for PostScript documents */
- /* Made public so GSview can add pages when processing PDF files */
- int
- dsc_add_page(CDSC *dsc, int ordinal, char *label)
- {
- dsc->page[dsc->page_count].begin = 0;
- dsc->page[dsc->page_count].end = 0;
- dsc->page[dsc->page_count].label =
- dsc_alloc_string(dsc, label, strlen(label)+1);
- dsc->page[dsc->page_count].ordinal = ordinal;
- dsc->page[dsc->page_count].media = NULL;
- dsc->page[dsc->page_count].bbox = NULL;
- dsc->page[dsc->page_count].viewing_orientation = NULL;
- dsc->page_count++;
- if (dsc->page_count >= dsc->page_chunk_length) {
- CDSCPAGE *new_page = (CDSCPAGE *)dsc_memalloc(dsc,
- (CDSC_PAGE_CHUNK+dsc->page_count) * sizeof(CDSCPAGE));
- if (new_page == NULL)
- return CDSC_ERROR; /* out of memory */
- memcpy(new_page, dsc->page,
- dsc->page_count * sizeof(CDSCPAGE));
- dsc_memfree(dsc, dsc->page);
- dsc->page= new_page;
- dsc->page_chunk_length = CDSC_PAGE_CHUNK+dsc->page_count;
- }
- return CDSC_OK;
- }
- /* Doesn't need to be public for PostScript documents */
- /* Made public so GSview can store PDF MediaBox */
- int
- dsc_add_media(CDSC *dsc, CDSCMEDIA *media)
- {
- CDSCMEDIA **newmedia_array;
- CDSCMEDIA *newmedia;
- /* extend media array */
- newmedia_array = (CDSCMEDIA **)dsc_memalloc(dsc,
- (dsc->media_count + 1) * sizeof(CDSCMEDIA *));
- if (newmedia_array == NULL)
- return CDSC_ERROR; /* out of memory */
- if (dsc->media != NULL) {
- memcpy(newmedia_array, dsc->media,
- dsc->media_count * sizeof(CDSCMEDIA *));
- dsc_memfree(dsc, dsc->media);
- }
- dsc->media = newmedia_array;
- /* allocate new media */
- newmedia = dsc->media[dsc->media_count] =
- (CDSCMEDIA *)dsc_memalloc(dsc, sizeof(CDSCMEDIA));
- if (newmedia == NULL)
- return CDSC_ERROR; /* out of memory */
- newmedia->name = NULL;
- newmedia->width = 595.0;
- newmedia->height = 842.0;
- newmedia->weight = 80.0;
- newmedia->colour = NULL;
- newmedia->type = NULL;
- newmedia->mediabox = NULL;
- dsc->media_count++;
- if (media->name) {
- newmedia->name = dsc_alloc_string(dsc, media->name,
- strlen(media->name));
- if (newmedia->name == NULL)
- return CDSC_ERROR; /* no memory */
- }
- newmedia->width = media->width;
- newmedia->height = media->height;
- newmedia->weight = media->weight;
- if (media->colour) {
- newmedia->colour = dsc_alloc_string(dsc, media->colour,
- strlen(media->colour));
- if (newmedia->colour == NULL)
- return CDSC_ERROR; /* no memory */
- }
- if (media->type) {
- newmedia->type = dsc_alloc_string(dsc, media->type,
- strlen(media->type));
- if (newmedia->type == NULL)
- return CDSC_ERROR; /* no memory */
- }
- newmedia->mediabox = NULL;
- if (media->mediabox) {
- newmedia->mediabox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (newmedia->mediabox == NULL)
- return CDSC_ERROR; /* no memory */
- *newmedia->mediabox = *media->mediabox;
- }
- return CDSC_OK;
- }
- /* Doesn't need to be public for PostScript documents */
- /* Made public so GSview can store PDF CropBox */
- int
- dsc_set_page_bbox(CDSC *dsc, unsigned int page_number,
- int llx, int lly, int urx, int ury)
- {
- CDSCBBOX *bbox;
- if (page_number >= dsc->page_count)
- return CDSC_ERROR;
- bbox = dsc->page[page_number].bbox;
- if (bbox == NULL)
- dsc->page[page_number].bbox = bbox =
- (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (bbox == NULL)
- return CDSC_ERROR;
- bbox->llx = llx;
- bbox->lly = lly;
- bbox->urx = urx;
- bbox->ury = ury;
- return CDSC_OK;
- }
- /******************************************************************/
- /* Private functions below here. */
- /******************************************************************/
- dsc_private void *
- dsc_memalloc(CDSC *dsc, size_t size)
- {
- if (dsc->memalloc)
- return dsc->memalloc(size, dsc->mem_closure_data);
- return malloc(size);
- }
- dsc_private void
- dsc_memfree(CDSC*dsc, void *ptr)
- {
- if (dsc->memfree)
- dsc->memfree(ptr, dsc->mem_closure_data);
- else
- free(ptr);
- }
- /* private constructor */
- dsc_private CDSC *
- dsc_init2(CDSC *dsc)
- {
- dsc_reset(dsc);
- dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
- if (dsc->string_head == NULL) {
- dsc_free(dsc);
- return NULL; /* no memory */
- }
- dsc->string = dsc->string_head;
- dsc->string->next = NULL;
- dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
- if (dsc->string->data == NULL) {
- dsc_free(dsc);
- return NULL; /* no memory */
- }
- dsc->string->index = 0;
- dsc->string->length = CDSC_STRING_CHUNK;
-
- dsc->page = (CDSCPAGE *)dsc_memalloc(dsc, CDSC_PAGE_CHUNK * sizeof(CDSCPAGE));
- if (dsc->page == NULL) {
- dsc_free(dsc);
- return NULL; /* no memory */
- }
- dsc->page_chunk_length = CDSC_PAGE_CHUNK;
- dsc->page_count = 0;
-
- dsc->line = NULL;
- dsc->data_length = 0;
- dsc->data_index = dsc->data_length;
- return dsc;
- }
- dsc_private void
- dsc_reset(CDSC *dsc)
- {
- unsigned int i;
- /* Clear public members */
- dsc->id = CDSC_OK;
- dsc->dsc = FALSE;
- dsc->ctrld = FALSE;
- dsc->pjl = FALSE;
- dsc->epsf = FALSE;
- dsc->pdf = FALSE;
- dsc->epsf = FALSE;
- dsc->preview = CDSC_NOPREVIEW;
- dsc->language_level = 0;
- dsc->document_data = CDSC_DATA_UNKNOWN;
- dsc->dsc_version = NULL;
- dsc->begincomments = 0;
- dsc->endcomments = 0;
- dsc->beginpreview = 0;
- dsc->endpreview = 0;
- dsc->begindefaults = 0;
- dsc->enddefaults = 0;
- dsc->beginprolog = 0;
- dsc->endprolog = 0;
- dsc->beginsetup = 0;
- dsc->endsetup = 0;
- dsc->begintrailer = 0;
- dsc->endtrailer = 0;
-
- for (i=0; i<dsc->page_count; i++) {
- /* page media is pointer to an element of media or dsc_known_media */
- /* do not free it. */
- if (dsc->page[i].bbox)
- dsc_memfree(dsc, dsc->page[i].bbox);
- if (dsc->page[i].viewing_orientation)
- dsc_memfree(dsc, dsc->page[i].viewing_orientation);
- }
- if (dsc->page)
- dsc_memfree(dsc, dsc->page);
- dsc->page = NULL;
-
- dsc->page_chunk_length = 0;
- dsc->page_count = 0;
- dsc->page_pages = 0;
- dsc->page_order = CDSC_ORDER_UNKNOWN;
- dsc->page_orientation = CDSC_ORIENT_UNKNOWN;
- if (dsc->viewing_orientation)
- dsc_memfree(dsc, dsc->viewing_orientation);
- dsc->viewing_orientation = NULL;
-
- /* page_media is pointer to an element of media or dsc_known_media */
- /* do not free it. */
- dsc->page_media = NULL;
- if (dsc->media) {
- for (i=0; i<dsc->media_count; i++) {
- if (dsc->media[i]) {
- if (dsc->media[i]->mediabox)
- dsc_memfree(dsc, dsc->media[i]->mediabox);
- dsc_memfree(dsc, dsc->media[i]);
- }
- }
- dsc_memfree(dsc, dsc->media);
- }
- dsc->media = NULL;
- dsc->media_count = 0;
- if (dsc->bbox)
- dsc_memfree(dsc, dsc->bbox);
- dsc->bbox = NULL;
- if (dsc->page_bbox)
- dsc_memfree(dsc, dsc->page_bbox);
- dsc->page_bbox = NULL;
- if (dsc->doseps)
- dsc_memfree(dsc, dsc->doseps);
- dsc->doseps = NULL;
-
- dsc->doseps_end = 0;
- dsc->dsc_title = NULL;
- dsc->dsc_creator = NULL;
- dsc->dsc_date = NULL;
- dsc->dsc_for = NULL;
-
- dsc->file_length = 0;
- dsc->severity = dsc_severity;
- dsc->max_error = DSC_MAX_ERROR;
-
- /* Clear private members */
- dsc->skip_pjl = 0;
- dsc->scan_section = scan_none;
- dsc->skip_bytes = 0;
- dsc->skip_document = 0;
- dsc->skip_bytes = 0;
- dsc->skip_lines = 0;
- dsc->begin_font_count = 0;
- dsc->begin_feature_count = 0;
- dsc->begin_resource_count = 0;
- dsc->begin_procset_count = 0;
- dsc->string = dsc->string_head;
- while (dsc->string != (CDSCSTRING *)NULL) {
- if (dsc->string->data)
- dsc_memfree(dsc, dsc->string->data);
- dsc->string_head = dsc->string;
- dsc->string = dsc->string->next;
- dsc_memfree(dsc, dsc->string_head);
- }
- dsc->string_head = NULL;
- dsc->string = NULL;
-
- dsc->data_length = 0;
- dsc->data_index = 0;
- dsc->data_offset = 0;
- dsc->eof = 0;
-
- dsc->line = 0;
- dsc->line_length = 0;
- dsc->eol = 0;
- dsc->last_cr = FALSE;
- dsc->line_count = 1;
- dsc->long_line = FALSE;
- }
- /*
- * Join up all sections.
- * There might be extra code between them, or we might have
- * missed including the \n which followed \r.
- * begin is the start of this section
- * pend is a pointer to the end of this section
- * pplast is a pointer to a pointer of the end of the previous section
- */
- dsc_private void
- dsc_section_join(unsigned long begin, unsigned long *pend, unsigned long **pplast)
- {
- if (begin)
- **pplast = begin;
- if (*pend > begin)
- *pplast = pend;
- }
- /* return value is 0 if no line available, or length of line */
- dsc_private int
- dsc_read_line(CDSC *dsc)
- {
- char *p, *last;
- dsc->line = NULL;
- if (dsc->eof) {
- /* return all that remains, even if line incomplete */
- dsc->line = dsc->data + dsc->data_index;
- dsc->line_length = dsc->data_length - dsc->data_index;
- dsc->data_index = dsc->data_length;
- return dsc->line_length;
- }
- /* ignore embedded bytes */
- if (dsc->skip_bytes) {
- int cnt = min(dsc->skip_bytes,
- (int)(dsc->data_length - dsc->data_index));
- dsc->skip_bytes -= cnt;
- dsc->data_index += cnt;
- if (dsc->skip_bytes != 0)
- return 0;
- }
- do {
- dsc->line = dsc->data + dsc->data_index;
- last = dsc->data + dsc->data_length;
- if (dsc->data_index == dsc->data_length) {
- dsc->line_length = 0;
- return 0;
- }
- if (dsc->eol) {
- /* if previous line was complete, increment line count */
- dsc->line_count++;
- if (dsc->skip_lines)
- dsc->skip_lines--;
- }
-
- /* skip over \n which followed \r */
- if (dsc->last_cr && dsc->line[0] == '\n') {
- dsc->data_index++;
- dsc->line++;
- }
- dsc->last_cr = FALSE;
- /* look for EOL */
- dsc->eol = FALSE;
- for (p = dsc->line; p < last; p++) {
- if (*p == '\r') {
- p++;
- if ((p<last) && (*p == '\n'))
- p++; /* include line feed also */
- else
- dsc->last_cr = TRUE; /* we might need to skip \n */
- dsc->eol = TRUE; /* dsc->line is a complete line */
- break;
- }
- if (*p == '\n') {
- p++;
- dsc->eol = TRUE; /* dsc->line is a complete line */
- break;
- }
- if (*p == '\032') { /* MS-DOS Ctrl+Z */
- dsc->eol = TRUE;
- }
- }
- if (dsc->eol == FALSE) {
- /* we haven't got a complete line yet */
- if (dsc->data_length - dsc->data_index < sizeof(dsc->data)/2) {
- /* buffer is less than half full, ask for some more */
- dsc->line_length = 0;
- return 0;
- }
- }
- dsc->data_index += dsc->line_length = (p - dsc->line);
- } while (dsc->skip_lines && dsc->line_length);
- if (dsc->line_length == 0)
- return 0;
-
- if ((dsc->line[0]=='%') && (dsc->line[1]=='%')) {
- /* handle recursive %%BeginDocument */
- if ((dsc->skip_document) && dsc->line_length &&
- COMPARE(dsc->line, "%%EndDocument")) {
- dsc->skip_document--;
- }
- /* handle embedded lines or binary data */
- if (COMPARE(dsc->line, "%%BeginData:")) {
- /* %%BeginData: <numberof>[ <type> [ <bytesorlines> ] ]
- * <numberof> ::= <uint> (Lines or physical bytes)
- * <type> ::= Hex | Binary | ASCII (Type of data)
- * <bytesorlines> ::= Bytes | Lines (Read in bytes or lines)
- */
- char begindata[MAXSTR+1];
- int cnt;
- const char *numberof, *bytesorlines;
- memcpy(begindata, dsc->line, dsc->line_length);
- begindata[dsc->line_length] = '\0';
- numberof = strtok(begindata+12, " \r\n");
- strtok(NULL, " \r\n"); /* dump type */
- bytesorlines = strtok(NULL, " \r\n");
- if (bytesorlines == NULL)
- bytesorlines = "Bytes";
-
- if ( (numberof == NULL) || (bytesorlines == NULL) ) {
- /* invalid usage of %%BeginData */
- /* ignore that we ever saw it */
- int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE,
- dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return 0;
- }
- }
- else {
- cnt = atoi(numberof);
- if (cnt) {
- if (bytesorlines && (dsc_stricmp(bytesorlines, "Lines")==0)) {
- /* skip cnt lines */
- if (dsc->skip_lines == 0) {
- /* we are not already skipping lines */
- dsc->skip_lines = cnt+1;
- }
- }
- else {
- /* byte count doesn't includes \n or \r\n */
- /* or \r of %%BeginData: */
- /* skip cnt bytes */
- if (dsc->skip_bytes == 0) {
- /* we are not already skipping lines */
- dsc->skip_bytes = cnt;
- }
- }
- }
- }
- }
- else if (COMPARE(dsc->line, "%%BeginBinary:")) {
- /* byte count doesn't includes \n or \r\n or \r of %%BeginBinary:*/
- unsigned long cnt = atoi(dsc->line + 14);
- if (dsc->skip_bytes == 0) {
- /* we are not already skipping lines */
- dsc->skip_bytes = cnt;
- }
- }
- }
-
- if ((dsc->line[0]=='%') && (dsc->line[1]=='%') &&
- COMPARE(dsc->line, "%%BeginDocument:") ) {
- /* Skip over embedded document, recursively */
- dsc->skip_document++;
- }
- if (!dsc->eol && !dsc->long_line &&
- (dsc->data_length - dsc->data_index)>DSC_LINE_LENGTH) {
- dsc_error(dsc, CDSC_MESSAGE_LONG_LINE, dsc->line, dsc->line_length);
- dsc->long_line = TRUE;
- }
-
- return dsc->line_length;
- }
- /* Save last DSC line, for use with %%+ */
- dsc_private void
- dsc_save_line(CDSC *dsc)
- {
- int len = min(sizeof(dsc->last_line), dsc->line_length);
- memcpy(dsc->last_line, dsc->line, len);
- }
- /* display unknown DSC line */
- dsc_private void
- dsc_unknown(CDSC *dsc)
- {
- if (dsc->debug_print_fn) {
- char line[DSC_LINE_LENGTH];
- unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length);
- sprintf(line, "Unknown in %s section at line %d:\n ",
- dsc_scan_section_name[dsc->scan_section], dsc->line_count);
- dsc_debug_print(dsc, line);
- strncpy(line, dsc->line, length);
- line[length] = '\0';
- dsc_debug_print(dsc, line);
- }
- }
- GSBOOL
- dsc_is_section(char *line)
- {
- if ( !((line[0]=='%') && (line[1]=='%')) )
- return FALSE;
- if (IS_DSC(line, "%%BeginPreview"))
- return TRUE;
- if (IS_DSC(line, "%%BeginDefaults"))
- return TRUE;
- if (IS_DSC(line, "%%BeginProlog"))
- return TRUE;
- if (IS_DSC(line, "%%BeginSetup"))
- return TRUE;
- if (IS_DSC(line, "%%Page:"))
- return TRUE;
- if (IS_DSC(line, "%%Trailer"))
- return TRUE;
- if (IS_DSC(line, "%%EOF"))
- return TRUE;
- return FALSE;
- }
- dsc_private GSDWORD
- dsc_get_dword(const unsigned char *buf)
- {
- GSDWORD dw;
- dw = (GSDWORD)buf[0];
- dw += ((GSDWORD)buf[1])<<8;
- dw += ((GSDWORD)buf[2])<<16;
- dw += ((GSDWORD)buf[3])<<24;
- return dw;
- }
- dsc_private GSWORD
- dsc_get_word(const unsigned char *buf)
- {
- GSWORD w;
- w = (GSWORD)buf[0];
- w |= (GSWORD)(buf[1]<<8);
- return w;
- }
- dsc_private int
- dsc_read_doseps(CDSC *dsc)
- {
- unsigned char *line = (unsigned char *)dsc->line;
- if ((dsc->doseps = (CDSCDOSEPS *)dsc_memalloc(dsc, sizeof(CDSCDOSEPS))) == NULL)
- return CDSC_ERROR; /* no memory */
-
- dsc->doseps->ps_begin = dsc_get_dword(line+4);
- dsc->doseps->ps_length = dsc_get_dword(line+8);
- dsc->doseps->wmf_begin = dsc_get_dword(line+12);
- dsc->doseps->wmf_length = dsc_get_dword(line+16);
- dsc->doseps->tiff_begin = dsc_get_dword(line+20);
- dsc->doseps->tiff_length = dsc_get_dword(line+24);
- dsc->doseps->checksum = dsc_get_word(line+28);
-
- dsc->doseps_end = dsc->doseps->ps_begin + dsc->doseps->ps_length;
- /* move data_index backwards to byte after doseps header */
- dsc->data_index -= dsc->line_length - 30;
- /* we haven't read a line of PostScript code yet */
- dsc->line_count = 0;
- /* skip from current position to start of PostScript section */
- dsc->skip_bytes = dsc->doseps->ps_begin - 30;
- if (dsc->doseps->tiff_begin)
- dsc->preview = CDSC_TIFF;
- if (dsc->doseps->wmf_begin)
- dsc->preview = CDSC_WMF;
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_pages(CDSC *dsc)
- {
- int ip, io;
- unsigned int i;
- char *p;
- int n;
- if ((dsc->page_pages != 0) && (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((dsc->page_pages != 0) && (dsc->scan_section == scan_trailer)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break; /* use duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- n = IS_DSC(dsc->line, "%%+") ? 3 : 8;
- while (IS_WHITE(dsc->line[n]))
- n++;
- p = dsc->line + n;
- if (COMPARE(p, "atend")) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* assume (atend) */
- /* we should mark it as deferred */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- else if (COMPARE(p, "(atend)")) {
- /* do nothing */
- /* we should mark it as deferred */
- }
- else {
- ip = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- n+=i;
- dsc->page_pages = ip;
- io = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- /* DSC 2 uses extra integer to indicate page order */
- /* DSC 3 uses %%PageOrder: */
- if (dsc->page_order == CDSC_ORDER_UNKNOWN)
- switch (io) {
- case -1:
- dsc->page_order = CDSC_DESCEND;
- break;
- case 0:
- dsc->page_order = CDSC_SPECIAL;
- break;
- case 1:
- dsc->page_order = CDSC_ASCEND;
- break;
- }
- }
- }
- else {
- int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_bounding_box(CDSC *dsc, CDSCBBOX** pbbox, int offset)
- {
- unsigned int i, n;
- int llx, lly, urx, ury;
- float fllx, flly, furx, fury;
- char *p;
- /* Process first %%BoundingBox: in comments, and last in trailer */
- if ((*pbbox != NULL) && (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((*pbbox != NULL) && (dsc->scan_section == scan_pages)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((*pbbox != NULL) && (dsc->scan_section == scan_trailer)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break; /* use duplicate comments in trailer */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if (*pbbox != NULL) {
- dsc_memfree(dsc, *pbbox);
- *pbbox = NULL;
- }
- /* should only process first %%BoundingBox: */
- while (IS_WHITE(dsc->line[offset]))
- offset++;
- p = dsc->line + offset;
-
- if (COMPARE(p, "atend")) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* assume (atend) */
- /* we should mark it as deferred */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- else if (COMPARE(p, "(atend)")) {
- /* do nothing */
- /* we should mark it as deferred */
- }
- else {
- /* llx = */ lly = urx = ury = 0;
- n = offset;
- llx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- lly = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- urx = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- ury = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (*pbbox == NULL)
- return CDSC_ERROR; /* no memory */
- (*pbbox)->llx = llx;
- (*pbbox)->lly = lly;
- (*pbbox)->urx = urx;
- (*pbbox)->ury = ury;
- }
- else {
- int rc = dsc_error(dsc, CDSC_MESSAGE_BBOX, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* fllx = */ flly = furx = fury = 0.0;
- n = offset;
- n += i;
- fllx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- flly = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- furx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- fury = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- *pbbox = (CDSCBBOX *)dsc_memalloc(dsc, sizeof(CDSCBBOX));
- if (*pbbox == NULL)
- return CDSC_ERROR; /* no memory */
- (*pbbox)->llx = (int)fllx;
- (*pbbox)->lly = (int)flly;
- (*pbbox)->urx = (int)(furx+0.999);
- (*pbbox)->ury = (int)(fury+0.999);
- }
- return CDSC_OK;
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_orientation(CDSC *dsc, unsigned int *porientation, int offset)
- {
- char *p;
- if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) &&
- (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((dsc->page_orientation != CDSC_ORIENT_UNKNOWN) &&
- (dsc->scan_section == scan_trailer)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break; /* use duplicate comments in header; */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- p = dsc->line + offset;
- while (IS_WHITE(*p))
- p++;
- if (COMPARE(p, "atend")) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* assume (atend) */
- /* we should mark it as deferred */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- else if (COMPARE(p, "(atend)")) {
- /* do nothing */
- /* we should mark it as deferred */
- }
- else if (COMPARE(p, "Portrait")) {
- *porientation = CDSC_PORTRAIT;
- }
- else if (COMPARE(p, "Landscape")) {
- *porientation = CDSC_LANDSCAPE;
- }
- else {
- dsc_unknown(dsc);
- }
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_order(CDSC *dsc)
- {
- char *p;
- if ((dsc->page_order != CDSC_ORDER_UNKNOWN) &&
- (dsc->scan_section == scan_comments)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_COMMENT, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- return CDSC_OK; /* ignore duplicate comments in header */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- if ((dsc->page_order != CDSC_ORDER_UNKNOWN) &&
- (dsc->scan_section == scan_trailer)) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- case CDSC_RESPONSE_CANCEL:
- break; /* use duplicate comments in trailer */
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- p = dsc->line + (IS_DSC(dsc->line, "%%+") ? 3 : 13);
- while (IS_WHITE(*p))
- p++;
- if (COMPARE(p, "atend")) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* assume (atend) */
- /* we should mark it as deferred */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* ignore it */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- else if (COMPARE(p, "(atend)")) {
- /* do nothing */
- /* we should mark it as deferred */
- }
- else if (COMPARE(p, "Ascend")) {
- dsc->page_order = CDSC_ASCEND;
- }
- else if (COMPARE(p, "Descend")) {
- dsc->page_order = CDSC_DESCEND;
- }
- else if (COMPARE(p, "Special")) {
- dsc->page_order = CDSC_SPECIAL;
- }
- else {
- dsc_unknown(dsc);
- }
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media)
- {
- char media_name[MAXSTR];
- int n = IS_DSC(dsc->line, "%%+") ? 3 : 12; /* %%PageMedia: */
- unsigned int i;
- if (dsc_copy_string(media_name, sizeof(media_name)-1,
- dsc->line+n, dsc->line_length-n, NULL)) {
- for (i=0; i<dsc->media_count; i++) {
- if (dsc->media[i]->name &&
- (dsc_stricmp(media_name, dsc->media[i]->name) == 0)) {
- *page_media = dsc->media[i];
- return CDSC_OK;
- }
- }
- }
- dsc_unknown(dsc);
-
- return CDSC_OK;
- }
- dsc_private int
- dsc_parse_document_media(CDSC *dsc)
- {
- unsigned int i, n;
- CDSCMEDIA lmedia;
- GSBOOL blank_line;
- if (IS_DSC(dsc->line, "%%DocumentMedia:"))
- n = 16;
- else if (IS_DSC(dsc->line, "%%+"))
- n = 3;
- else
- return CDSC_ERROR; /* error */
- /* check for blank remainder of line */
- blank_line = TRUE;
- for (i=n; i<dsc->line_length; i++) {
- if (!IS_WHITE_OR_EOL(dsc->line[i])) {
- blank_line = FALSE;
- break;
- }
- }
- if (!blank_line) {
- char name[MAXSTR];
- char colour[MAXSTR];
- char type[MAXSTR];
- lmedia.name = lmedia.colour = lmedia.type = (char *)NULL;
- lmedia.width = lmedia.height = lmedia.weight = 0;
- lmedia.mediabox = (CDSCBBOX *)NULL;
- lmedia.name = dsc_copy_string(name, sizeof(name),
- dsc->line+n, dsc->line_length-n, &i);
- n+=i;
- if (i)
- lmedia.width = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n+=i;
- if (i)
- lmedia.height = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n+=i;
- if (i)
- lmedia.weight = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n+=i;
- if (i)
- lmedia.colour = dsc_copy_string(colour, sizeof(colour),
- dsc->line+n, dsc->line_length-n, &i);
- n+=i;
- if (i)
- lmedia.type = dsc_copy_string(type, sizeof(type),
- dsc->line+n, dsc->line_length-n, &i);
- if (i==0)
- dsc_unknown(dsc); /* we didn't get all fields */
- else {
- if (dsc_add_media(dsc, &lmedia))
- return CDSC_ERROR; /* out of memory */
- }
- }
- return CDSC_OK;
- }
- /* viewing orientation is believed to be the first four elements of
- * a CTM matrix
- */
- dsc_private int
- dsc_parse_viewing_orientation(CDSC *dsc, CDSCCTM **pctm)
- {
- CDSCCTM ctm;
- unsigned int i, n;
- if (*pctm != NULL) {
- dsc_memfree(dsc, *pctm);
- *pctm = NULL;
- }
- n = IS_DSC(dsc->line, "%%+") ? 3 : 21; /* %%ViewingOrientation: */
- while (IS_WHITE(dsc->line[n]))
- n++;
- /* ctm.xx = */ ctm.xy = ctm.yx = ctm.yy = 0.0;
- ctm.xx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- ctm.xy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- ctm.yx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- n += i;
- if (i)
- ctm.yy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- if (i==0) {
- dsc_unknown(dsc); /* we didn't get all fields */
- }
- else {
- *pctm = (CDSCCTM *)dsc_memalloc(dsc, sizeof(CDSCCTM));
- if (*pctm == NULL)
- return CDSC_ERROR; /* no memory */
- **pctm = ctm;
- }
- return CDSC_OK;
- }
-
- /* This is called before dsc_read_line(), since we may
- * need to skip a binary header which contains a new line
- * character
- */
- dsc_private int
- dsc_scan_type(CDSC *dsc)
- {
- unsigned char *p;
- unsigned char *line = (unsigned char *)(dsc->data + dsc->data_index);
- int length = dsc->data_length - dsc->data_index;
- /* Types that should be known:
- * DSC
- * EPSF
- * PJL + any of above
- * ^D + any of above
- * DOS EPS
- * PDF
- * non-DSC
- */
- /* First process any non PostScript headers */
- /* At this stage we do not have a complete line */
- if (length == 0)
- return CDSC_NEEDMORE;
- if (dsc->skip_pjl) {
- /* skip until first PostScript comment */
- while (length >= 2) {
- while (length && !IS_EOL(line[0])) {
- /* skip until EOL character */
- line++;
- dsc->data_index++;
- length--;
- }
- while ((length >= 2) && IS_EOL(line[0]) && IS_EOL(line[1])) {
- /* skip until EOL followed by non-EOL */
- line++;
- dsc->data_index++;
- length--;
- }
- if (length < 2)
- return CDSC_NEEDMORE;
- if (IS_EOL(line[0]) && line[1]=='%') {
- line++;
- dsc->data_index++;
- length--;
- dsc->skip_pjl = FALSE;
- break;
- }
- else {
- /* line++; */
- dsc->data_index++;
- /* length--; */
- return CDSC_NEEDMORE;
- }
- }
- if (dsc->skip_pjl)
- return CDSC_NEEDMORE;
- }
- if (length == 0)
- return CDSC_NEEDMORE;
- if (line[0] == '\004') {
- line++;
- dsc->data_index++;
- length--;
- dsc->ctrld = TRUE;
- }
- if (line[0] == '\033') {
- /* possibly PJL */
- if (length < 9)
- return CDSC_NEEDMORE;
- if (COMPARE(line, "\033%-12345X")) {
- dsc->skip_pjl = TRUE; /* skip until first PostScript comment */
- dsc->pjl = TRUE;
- dsc->data_index += 9;
- return dsc_scan_type(dsc);
- }
- }
- if ((line[0]==0xc5) && (length < 4))
- return CDSC_NEEDMORE;
- if ((line[0]==0xc5) && (line[1]==0xd0) &&
- (line[2]==0xd3) && (line[3]==0xc6) ) {
- /* id is "EPSF" with bit 7 set */
- /* read DOS EPS header, then ignore all bytes until the PS section */
- if (length < 30)
- return CDSC_NEEDMORE;
- dsc->line = (char *)line;
- if (dsc_read_doseps(dsc))
- return CDSC_ERROR;
- }
- else {
- if (length < 2)
- return CDSC_NEEDMORE;
- if ((line[0] == '%') && (line[1] == 'P')) {
- if (length < 5)
- return CDSC_NEEDMORE;
- if (COMPARE(line, "%PDF-")) {
- dsc->pdf = TRUE;
- dsc->scan_section = scan_comments;
- return CDSC_OK;
- }
- }
- }
- /* Finally process PostScript headers */
- if (dsc_read_line(dsc) <= 0)
- return CDSC_NEEDMORE;
-
- dsc->dsc_version = dsc_add_line(dsc, dsc->line, dsc->line_length);
- if (COMPARE(dsc->line, "%!PS-Adobe")) {
- dsc->dsc = TRUE;
- dsc->begincomments = DSC_START(dsc);
- if (dsc->dsc_version == NULL)
- return CDSC_ERROR; /* no memory */
- p = (unsigned char *)dsc->line + 14;
- while (IS_WHITE(*p))
- p++;
- if (COMPARE(p, "EPSF-"))
- dsc->epsf = TRUE;
- dsc->scan_section = scan_comments;
- return CDSC_PSADOBE;
- }
- if (COMPARE(dsc->line, "%!")) {
- dsc->scan_section = scan_comments;
- return CDSC_NOTDSC;
- }
- dsc->scan_section = scan_comments;
- return CDSC_NOTDSC; /* unrecognised */
- }
- dsc_private int
- dsc_scan_comments(CDSC *dsc)
- {
- /* Comments section ends at */
- /* %%EndComments */
- /* another section */
- /* line that does not start with %% */
- /* Save a few important lines */
- char *line = dsc->line;
- GSBOOL continued = FALSE;
- dsc->id = CDSC_OK;
- if (IS_DSC(line, "%%EndComments")) {
- dsc->id = CDSC_ENDCOMMENTS;
- dsc->endcomments = DSC_END(dsc);
- dsc->scan_section = scan_pre_preview;
- return CDSC_OK;
- }
- else if (IS_DSC(line, "%%BeginComments")) {
- /* ignore because we are in this section */
- dsc->id = CDSC_BEGINCOMMENTS;
- }
- else if (dsc_is_section(line)) {
- dsc->endcomments = DSC_START(dsc);
- dsc->scan_section = scan_pre_preview;
- return CDSC_PROPAGATE;
- }
- else if (line[0] == '%' && IS_WHITE_OR_EOL(line[1])) {
- dsc->endcomments = DSC_START(dsc);
- dsc->scan_section = scan_pre_preview;
- return CDSC_PROPAGATE;
- }
- else if (line[0] != '%') {
- dsc->id = CDSC_OK;
- dsc->endcomments = DSC_START(dsc);
- dsc->scan_section = scan_pre_preview;
- return CDSC_PROPAGATE;
- }
- else if (IS_DSC(line, "%%Begin")) {
- dsc->endcomments = DSC_START(dsc);
- dsc->scan_section = scan_pre_preview;
- return CDSC_PROPAGATE;
- }
- /* Handle continuation lines.
- * To simply processing, we assume that contination lines
- * will only occur if repeat parameters are allowed and that
- * a complete set of these parameters appears on each line.
- * This is more restrictive than the DSC specification, but
- * is valid for the DSC comments understood by this parser
- * for all documents that we have seen.
- */
- if (IS_DSC(line, "%%+")) {
- line = dsc->last_line;
- continued = TRUE;
- }
- else
- dsc_save_line(dsc);
- if (IS_DSC(line, "%%Pages:")) {
- dsc->id = CDSC_PAGES;
- if (dsc_parse_pages(dsc) != 0)
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%Creator:")) {
- dsc->id = CDSC_CREATOR;
- dsc->dsc_creator = dsc_add_line(dsc, dsc->line+10, dsc->line_length-10);
- if (dsc->dsc_creator==NULL)
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%CreationDate:")) {
- dsc->id = CDSC_CREATIONDATE;
- dsc->dsc_date = dsc_add_line(dsc, dsc->line+15, dsc->line_length-15);
- if (dsc->dsc_date==NULL)
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%Title:")) {
- dsc->id = CDSC_TITLE;
- dsc->dsc_title = dsc_add_line(dsc, dsc->line+8, dsc->line_length-8);
- if (dsc->dsc_title==NULL)
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%For:")) {
- dsc->id = CDSC_FOR;
- dsc->dsc_for = dsc_add_line(dsc, dsc->line+6, dsc->line_length-6);
- if (dsc->dsc_for==NULL)
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%LanguageLevel:")) {
- unsigned int n = continued ? 3 : 16;
- unsigned int i;
- int ll;
- dsc->id = CDSC_LANGUAGELEVEL;
- ll = dsc_get_int(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- if ( (ll==1) || (ll==2) || (ll==3) )
- dsc->language_level = ll;
- else {
- dsc_unknown(dsc);
- }
- }
- else
- dsc_unknown(dsc);
- }
- else if (IS_DSC(line, "%%BoundingBox:")) {
- dsc->id = CDSC_BOUNDINGBOX;
- if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%Orientation:")) {
- dsc->id = CDSC_ORIENTATION;
- if (dsc_parse_orientation(dsc, &(dsc->page_orientation),
- continued ? 3 : 14))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%PageOrder:")) {
- dsc->id = CDSC_PAGEORDER;
- if (dsc_parse_order(dsc))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%DocumentMedia:")) {
- dsc->id = CDSC_DOCUMENTMEDIA;
- if (dsc_parse_document_media(dsc))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%DocumentPaperSizes:")) {
- /* DSC 2.1 */
- unsigned int n = continued ? 3 : 21;
- unsigned int count = 0;
- unsigned int i = 1;
- char name[MAXSTR];
- char *p;
- dsc->id = CDSC_DOCUMENTPAPERSIZES;
- while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
- p = dsc_copy_string(name, sizeof(name)-1,
- dsc->line+n, dsc->line_length-n, &i);
- if (i && p) {
- const CDSCMEDIA *m = dsc_known_media;
- if (count >= dsc->media_count) {
- /* set some default values */
- CDSCMEDIA lmedia;
- lmedia.name = p;
- lmedia.width = 595.0;
- lmedia.height = 842.0;
- lmedia.weight = 80.0;
- lmedia.colour = NULL;
- lmedia.type = NULL;
- lmedia.mediabox = NULL;
- if (dsc_add_media(dsc, &lmedia))
- return CDSC_ERROR;
- }
- else
- dsc->media[count]->name =
- dsc_alloc_string(dsc, p, strlen(p));
- /* find in list of known media */
- while (m && m->name) {
- if (dsc_stricmp(p, m->name)==0) {
- dsc->media[count]->width = m->width;
- dsc->media[count]->height = m->height;
- break;
- }
- m++;
- }
- }
- n+=i;
- count++;
- }
- }
- else if (IS_DSC(line, "%%DocumentPaperForms:")) {
- /* DSC 2.1 */
- unsigned int n = continued ? 3 : 21;
- unsigned int count = 0;
- unsigned int i = 1;
- char type[MAXSTR];
- char *p;
- dsc->id = CDSC_DOCUMENTPAPERFORMS;
- while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
- p = dsc_copy_string(type, sizeof(type)-1,
- dsc->line+n, dsc->line_length-n, &i);
- if (i && p) {
- if (count >= dsc->media_count) {
- /* set some default values */
- CDSCMEDIA lmedia;
- lmedia.name = NULL;
- lmedia.width = 595.0;
- lmedia.height = 842.0;
- lmedia.weight = 80.0;
- lmedia.colour = NULL;
- lmedia.type = p;
- lmedia.mediabox = NULL;
- if (dsc_add_media(dsc, &lmedia))
- return CDSC_ERROR;
- }
- else
- dsc->media[count]->type =
- dsc_alloc_string(dsc, p, strlen(p));
- }
- n+=i;
- count++;
- }
- }
- else if (IS_DSC(line, "%%DocumentPaperColors:")) {
- /* DSC 2.1 */
- unsigned int n = continued ? 3 : 22;
- unsigned int count = 0;
- unsigned int i = 1;
- char colour[MAXSTR];
- char *p;
- dsc->id = CDSC_DOCUMENTPAPERCOLORS;
- while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
- p = dsc_copy_string(colour, sizeof(colour)-1,
- dsc->line+n, dsc->line_length-n, &i);
- if (i && p) {
- if (count >= dsc->media_count) {
- /* set some default values */
- CDSCMEDIA lmedia;
- lmedia.name = NULL;
- lmedia.width = 595.0;
- lmedia.height = 842.0;
- lmedia.weight = 80.0;
- lmedia.colour = p;
- lmedia.type = NULL;
- lmedia.mediabox = NULL;
- if (dsc_add_media(dsc, &lmedia))
- return CDSC_ERROR;
- }
- else
- dsc->media[count]->colour =
- dsc_alloc_string(dsc, p, strlen(p));
- }
- n+=i;
- count++;
- }
- }
- else if (IS_DSC(line, "%%DocumentPaperWeights:")) {
- /* DSC 2.1 */
- unsigned int n = continued ? 3 : 23;
- unsigned int count = 0;
- unsigned int i = 1;
- float w;
- dsc->id = CDSC_DOCUMENTPAPERWEIGHTS;
- while (i && (dsc->line[n]!='\r') && (dsc->line[n]!='\n')) {
- w = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
- if (i) {
- if (count >= dsc->media_count) {
- /* set some default values */
- CDSCMEDIA lmedia;
- lmedia.name = NULL;
- lmedia.width = 595.0;
- lmedia.height = 842.0;
- lmedia.weight = w;
- lmedia.colour = NULL;
- lmedia.type = NULL;
- lmedia.mediabox = NULL;
- if (dsc_add_media(dsc, &lmedia))
- return CDSC_ERROR;
- }
- else
- dsc->media[count]->weight = w;
- }
- n+=i;
- count++;
- }
- }
- else if (IS_DSC(line, "%%DocumentData:")) {
- unsigned int n = continued ? 3 : 15;
- char *p = dsc->line + n;
- while (IS_WHITE(*p))
- p++;
- dsc->id = CDSC_DOCUMENTDATA;
- if (COMPARE(p, "Clean7Bit"))
- dsc->document_data = CDSC_CLEAN7BIT;
- else if (COMPARE(p, "Clean8Bit"))
- dsc->document_data = CDSC_CLEAN8BIT;
- else if (COMPARE(p, "Binary"))
- dsc->document_data = CDSC_BINARY;
- else
- dsc_unknown(dsc);
- }
- else if (IS_DSC(line, "%%Requirements:")) {
- dsc->id = CDSC_REQUIREMENTS;
- /* ignore */
- }
- else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
- dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
- /* ignore */
- }
- else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
- dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
- /* ignore */
- }
- else if (dsc->line[0] == '%' && IS_WHITE_OR_EOL(dsc->line[1])) {
- dsc->id = CDSC_OK;
- /* ignore */
- }
- else {
- dsc->id = CDSC_UNKNOWNDSC;
- dsc_unknown(dsc);
- }
- dsc->endcomments = DSC_END(dsc);
- return CDSC_OK;
- }
- dsc_private int
- dsc_scan_preview(CDSC *dsc)
- {
- /* Preview section ends at */
- /* %%EndPreview */
- /* another section */
- /* Preview section must start with %%BeginPreview */
- char *line = dsc->line;
- dsc->id = CDSC_OK;
- if (dsc->scan_section == scan_pre_preview) {
- if (IS_BLANK(line))
- return CDSC_OK; /* ignore blank lines before preview */
- else if (IS_DSC(line, "%%BeginPreview")) {
- dsc->id = CDSC_BEGINPREVIEW;
- dsc->beginpreview = DSC_START(dsc);
- dsc->endpreview = DSC_END(dsc);
- dsc->scan_section = scan_preview;
- /* Don't mark the preview as EPSI if a DOS EPS header is present */
- if (dsc->preview == CDSC_NOPREVIEW)
- dsc->preview = CDSC_EPSI;
- return CDSC_OK;
- }
- else {
- dsc->scan_section = scan_pre_defaults;
- return CDSC_PROPAGATE;
- }
- }
- if (IS_DSC(line, "%%BeginPreview")) {
- /* ignore because we are in this section */
- }
- else if (dsc_is_section(line)) {
- dsc->endpreview = DSC_START(dsc);
- dsc->scan_section = scan_pre_defaults;
- return CDSC_PROPAGATE;
- }
- else if (IS_DSC(line, "%%EndPreview")) {
- dsc->id = CDSC_ENDPREVIEW;
- dsc->endpreview = DSC_END(dsc);
- dsc->scan_section = scan_pre_defaults;
- return CDSC_OK;
- }
- else if (line[0] == '%' && line[1] != '%') {
- /* Ordinary comments are OK */
- }
- else {
- dsc->id = CDSC_UNKNOWNDSC;
- /* DSC comments should not occur in preview */
- dsc_unknown(dsc);
- }
- dsc->endpreview = DSC_END(dsc);
- return CDSC_OK;
- }
- dsc_private int
- dsc_scan_defaults(CDSC *dsc)
- {
- /* Defaults section ends at */
- /* %%EndDefaults */
- /* another section */
- /* Defaults section must start with %%BeginDefaults */
- char *line = dsc->line;
- dsc->id = CDSC_OK;
- if (dsc->scan_section == scan_pre_defaults) {
- if (IS_BLANK(line))
- return CDSC_OK; /* ignore blank lines before defaults */
- else if (IS_DSC(line, "%%BeginDefaults")) {
- dsc->id = CDSC_BEGINDEFAULTS;
- dsc->begindefaults = DSC_START(dsc);
- dsc->enddefaults = DSC_END(dsc);
- dsc->scan_section = scan_defaults;
- return CDSC_OK;
- }
- else {
- dsc->scan_section = scan_pre_prolog;
- return CDSC_PROPAGATE;
- }
- }
- if (NOT_DSC_LINE(line)) {
- /* ignore */
- }
- else if (IS_DSC(line, "%%BeginPreview")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginDefaults")) {
- /* ignore because we are in this section */
- }
- else if (dsc_is_section(line)) {
- dsc->enddefaults = DSC_START(dsc);
- dsc->scan_section = scan_pre_prolog;
- return CDSC_PROPAGATE;
- }
- else if (IS_DSC(line, "%%EndDefaults")) {
- dsc->id = CDSC_ENDDEFAULTS;
- dsc->enddefaults = DSC_END(dsc);
- dsc->scan_section = scan_pre_prolog;
- return CDSC_OK;
- }
- else if (IS_DSC(line, "%%PageMedia:")) {
- dsc->id = CDSC_PAGEMEDIA;
- dsc_parse_media(dsc, &dsc->page_media);
- }
- else if (IS_DSC(line, "%%PageOrientation:")) {
- dsc->id = CDSC_PAGEORIENTATION;
- /* This can override %%Orientation: */
- if (dsc_parse_orientation(dsc, &(dsc->page_orientation), 18))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%PageBoundingBox:")) {
- dsc->id = CDSC_PAGEBOUNDINGBOX;
- if (dsc_parse_bounding_box(dsc, &(dsc->page_bbox), 18))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%ViewingOrientation:")) {
- dsc->id = CDSC_VIEWINGORIENTATION;
- if (dsc_parse_viewing_orientation(dsc, &dsc->viewing_orientation))
- return CDSC_ERROR;
- }
- else {
- dsc->id = CDSC_UNKNOWNDSC;
- /* All other DSC comments are unknown, but not an error */
- dsc_unknown(dsc);
- }
- dsc->enddefaults = DSC_END(dsc);
- return CDSC_OK;
- }
- /* CDSC_RESPONSE_OK and CDSC_RESPONSE_CANCEL mean ignore the
- * mismatch (default) */
- dsc_private int
- dsc_check_match_prompt(CDSC *dsc, const char *str, int count)
- {
- if (count != 0) {
- char buf[MAXSTR+MAXSTR];
- if (dsc->line_length < (unsigned int)(sizeof(buf)/2-1)) {
- strncpy(buf, dsc->line, dsc->line_length);
- buf[dsc->line_length] = '\0';
- }
- sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str);
- return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, strlen(buf));
- }
- return CDSC_RESPONSE_CANCEL;
- }
- dsc_private int
- dsc_check_match_type(CDSC *dsc, const char *str, int count)
- {
- if (dsc_check_match_prompt(dsc, str, count) == CDSC_RESPONSE_IGNORE_ALL)
- return CDSC_NOTDSC;
- return CDSC_OK;
- }
- /* complain if Begin/End blocks didn't match */
- /* return non-zero if we should ignore all DSC */
- dsc_private int
- dsc_check_match(CDSC *dsc)
- {
- int rc = 0;
- const char *font = "Font";
- const char *feature = "Feature";
- const char *resource = "Resource";
- const char *procset = "ProcSet";
- if (!rc)
- rc = dsc_check_match_type(dsc, font, dsc->begin_font_count);
- if (!rc)
- rc = dsc_check_match_type(dsc, feature, dsc->begin_feature_count);
- if (!rc)
- rc = dsc_check_match_type(dsc, resource, dsc->begin_resource_count);
- if (!rc)
- rc = dsc_check_match_type(dsc, procset, dsc->begin_procset_count);
- dsc->begin_font_count = 0;
- dsc->begin_feature_count = 0;
- dsc->begin_resource_count = 0;
- dsc->begin_procset_count = 0;
- return rc;
- }
- dsc_private int
- dsc_scan_prolog(CDSC *dsc)
- {
- /* Prolog section ends at */
- /* %%EndProlog */
- /* another section */
- /* Prolog section may start with %%BeginProlog or non-dsc line */
- char *line = dsc->line;
- dsc->id = CDSC_OK;
- if (dsc->scan_section == scan_pre_prolog) {
- if (dsc_is_section(line) && (!IS_DSC(line, "%%BeginProlog"))) {
- dsc->scan_section = scan_pre_setup;
- return CDSC_PROPAGATE;
- }
- dsc->id = CDSC_BEGINPROLOG;
- dsc->beginprolog = DSC_START(dsc);
- dsc->endprolog = DSC_END(dsc);
- dsc->scan_section = scan_prolog;
- if (IS_DSC(line, "%%BeginProlog"))
- return CDSC_OK;
- }
-
- if (NOT_DSC_LINE(line)) {
- /* ignore */
- }
- else if (IS_DSC(line, "%%BeginPreview")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginDefaults")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginProlog")) {
- /* ignore because we are in this section */
- }
- else if (dsc_is_section(line)) {
- dsc->endprolog = DSC_START(dsc);
- dsc->scan_section = scan_pre_setup;
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_PROPAGATE;
- }
- else if (IS_DSC(line, "%%EndProlog")) {
- dsc->id = CDSC_ENDPROLOG;
- dsc->endprolog = DSC_END(dsc);
- dsc->scan_section = scan_pre_setup;
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_OK;
- }
- else if (IS_DSC(line, "%%BeginFont:")) {
- dsc->id = CDSC_BEGINFONT;
- /* ignore Begin/EndFont, apart form making sure */
- /* that they are matched. */
- dsc->begin_font_count++;
- }
- else if (IS_DSC(line, "%%EndFont")) {
- dsc->id = CDSC_ENDFONT;
- dsc->begin_font_count--;
- }
- else if (IS_DSC(line, "%%BeginFeature:")) {
- dsc->id = CDSC_BEGINFEATURE;
- /* ignore Begin/EndFeature, apart form making sure */
- /* that they are matched. */
- dsc->begin_feature_count++;
- }
- else if (IS_DSC(line, "%%EndFeature")) {
- dsc->id = CDSC_ENDFEATURE;
- dsc->begin_feature_count--;
- }
- else if (IS_DSC(line, "%%BeginResource:")) {
- dsc->id = CDSC_BEGINRESOURCE;
- /* ignore Begin/EndResource, apart form making sure */
- /* that they are matched. */
- dsc->begin_resource_count++;
- }
- else if (IS_DSC(line, "%%EndResource")) {
- dsc->id = CDSC_ENDRESOURCE;
- dsc->begin_resource_count--;
- }
- else if (IS_DSC(line, "%%BeginProcSet:")) {
- dsc->id = CDSC_BEGINPROCSET;
- /* ignore Begin/EndProcSet, apart form making sure */
- /* that they are matched. */
- dsc->begin_procset_count++;
- }
- else if (IS_DSC(line, "%%EndProcSet")) {
- dsc->id = CDSC_ENDPROCSET;
- dsc->begin_procset_count--;
- }
- else {
- /* All other DSC comments are unknown, but not an error */
- dsc->id = CDSC_UNKNOWNDSC;
- dsc_unknown(dsc);
- }
- dsc->endprolog = DSC_END(dsc);
- return CDSC_OK;
- }
- dsc_private int
- dsc_scan_setup(CDSC *dsc)
- {
- /* Setup section ends at */
- /* %%EndSetup */
- /* another section */
- /* Setup section must start with %%BeginSetup */
- char *line = dsc->line;
- dsc->id = CDSC_OK;
- if (dsc->scan_section == scan_pre_setup) {
- if (IS_BLANK(line))
- return CDSC_OK; /* ignore blank lines before setup */
- else if (IS_DSC(line, "%%BeginSetup")) {
- dsc->id = CDSC_BEGINSETUP;
- dsc->beginsetup = DSC_START(dsc);
- dsc->endsetup = DSC_END(dsc);
- dsc->scan_section = scan_setup;
- return CDSC_OK;
- }
- else {
- dsc->scan_section = scan_pre_pages;
- return CDSC_PROPAGATE;
- }
- }
- if (NOT_DSC_LINE(line)) {
- /* ignore */
- }
- else if (IS_DSC(line, "%%BeginPreview")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginDefaults")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginProlog")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginSetup")) {
- /* ignore because we are in this section */
- }
- else if (dsc_is_section(line)) {
- dsc->endsetup = DSC_START(dsc);
- dsc->scan_section = scan_pre_pages;
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_PROPAGATE;
- }
- else if (IS_DSC(line, "%%EndSetup")) {
- dsc->id = CDSC_ENDSETUP;
- dsc->endsetup = DSC_END(dsc);
- dsc->scan_section = scan_pre_pages;
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_OK;
- }
- else if (IS_DSC(line, "%%BeginFeature:")) {
- dsc->id = CDSC_BEGINFEATURE;
- /* ignore Begin/EndFeature, apart form making sure */
- /* that they are matched. */
- dsc->begin_feature_count++;
- }
- else if (IS_DSC(line, "%%EndFeature")) {
- dsc->id = CDSC_ENDFEATURE;
- dsc->begin_feature_count--;
- }
- else if (IS_DSC(line, "%%Feature:")) {
- dsc->id = CDSC_FEATURE;
- /* ignore */
- }
- else if (IS_DSC(line, "%%BeginResource:")) {
- dsc->id = CDSC_BEGINRESOURCE;
- /* ignore Begin/EndResource, apart form making sure */
- /* that they are matched. */
- dsc->begin_resource_count++;
- }
- else if (IS_DSC(line, "%%EndResource")) {
- dsc->id = CDSC_ENDRESOURCE;
- dsc->begin_resource_count--;
- }
- else if (IS_DSC(line, "%%PaperColor:")) {
- dsc->id = CDSC_PAPERCOLOR;
- /* ignore */
- }
- else if (IS_DSC(line, "%%PaperForm:")) {
- dsc->id = CDSC_PAPERFORM;
- /* ignore */
- }
- else if (IS_DSC(line, "%%PaperWeight:")) {
- dsc->id = CDSC_PAPERWEIGHT;
- /* ignore */
- }
- else if (IS_DSC(line, "%%PaperSize:")) {
- /* DSC 2.1 */
- GSBOOL found_media = FALSE;
- int i;
- int n = 12;
- char buf[MAXSTR];
- buf[0] = '\0';
- dsc->id = CDSC_PAPERSIZE;
- dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n, dsc->line_length-n,
- NULL);
- for (i=0; i<(int)dsc->media_count; i++) {
- if (dsc->media[i] && dsc->media[i]->name &&
- (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
- dsc->page_media = dsc->media[i];
- found_media = TRUE;
- break;
- }
- }
- if (!found_media) {
- /* It didn't match %%DocumentPaperSizes: */
- /* Try our known media */
- const CDSCMEDIA *m = dsc_known_media;
- while (m->name) {
- if (dsc_stricmp(buf, m->name)==0) {
- dsc->page_media = m;
- break;
- }
- m++;
- }
- if (m->name == NULL)
- dsc_unknown(dsc);
- }
- }
- else {
- /* All other DSC comments are unknown, but not an error */
- dsc->id = CDSC_UNKNOWNDSC;
- dsc_unknown(dsc);
- }
- dsc->endsetup = DSC_END(dsc);
- return CDSC_OK;
- }
- dsc_private int
- dsc_scan_page(CDSC *dsc)
- {
- /* Page section ends at */
- /* %%Page */
- /* %%Trailer */
- /* %%EOF */
- char *line = dsc->line;
- dsc->id = CDSC_OK;
- if (dsc->scan_section == scan_pre_pages) {
- if (IS_DSC(line, "%%Page:")) {
- dsc->scan_section = scan_pages;
- /* fall through */
- }
- else {
- /* %%Page: didn't follow %%EndSetup
- * Keep reading until reach %%Page or %%Trailer
- * and add it to previous section.
- */
- unsigned long *last;
- if (dsc->endsetup != 0)
- last = &dsc->endsetup;
- else if (dsc->endprolog != 0)
- last = &dsc->endprolog;
- else if (dsc->enddefaults != 0)
- last = &dsc->enddefaults;
- else if (dsc->endpreview != 0)
- last = &dsc->endpreview;
- else if (dsc->endcomments != 0)
- last = &dsc->endcomments;
- else
- last = &dsc->begincomments;
- *last = DSC_START(dsc);
- if (IS_DSC(line, "%%Trailer") || IS_DSC(line, "%%EOF")) {
- dsc->scan_section = scan_pre_trailer;
- return CDSC_PROPAGATE;
- }
- return CDSC_OK;
- }
- }
- if (NOT_DSC_LINE(line)) {
- /* ignore */
- }
- else if (IS_DSC(line, "%%Page:")) {
- dsc->id = CDSC_PAGE;
- if (dsc->page_count) {
- dsc->page[dsc->page_count-1].end = DSC_START(dsc);
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- }
- if (dsc_parse_page(dsc) != 0)
- return CDSC_ERROR;
- return CDSC_OK;
- }
- else if (IS_DSC(line, "%%BeginPreview")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginDefaults")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginProlog")) {
- /* ignore because we have already processed this section */
- }
- else if (IS_DSC(line, "%%BeginSetup")) {
- /* ignore because we have already processed this section */
- }
- else if (dsc_is_section(line)) {
- if (IS_DSC(line, "%%Trailer")) {
- dsc->page[dsc->page_count-1].end = DSC_START(dsc);
- if (dsc->file_length) {
- if ((!dsc->doseps &&
- ((DSC_END(dsc) + 32768) < dsc->file_length)) ||
- ((dsc->doseps) &&
- ((DSC_END(dsc) + 32768) < dsc->doseps_end))) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_TRAILER,
- dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* ignore early trailer */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* this is the trailer */
- dsc->scan_section = scan_pre_trailer;
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_PROPAGATE;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- else {
- dsc->scan_section = scan_pre_trailer;
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_PROPAGATE;
- }
- }
- else if (IS_DSC(line, "%%EOF")) {
- dsc->page[dsc->page_count-1].end = DSC_START(dsc);
- if (dsc->file_length) {
- if ((DSC_END(dsc)+100 < dsc->file_length) ||
- (dsc->doseps && (DSC_END(dsc) + 100 < dsc->doseps_end))) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_EARLY_EOF,
- dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* %%EOF is wrong, ignore it */
- break;
- case CDSC_RESPONSE_CANCEL:
- /* %%EOF is correct */
- dsc->scan_section = scan_eof;
- dsc->eof = TRUE;
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_PROPAGATE;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- }
- else {
- /* ignore it */
- if (dsc_check_match(dsc))
- return CDSC_NOTDSC;
- return CDSC_OK;
- }
- }
- else {
- /* Section comment, probably from a badly */
- /* encapsulated EPS file. */
- int rc = dsc_error(dsc, CDSC_MESSAGE_BAD_SECTION,
- dsc->line, dsc->line_length);
- if (rc == CDSC_RESPONSE_IGNORE_ALL)
- return CDSC_NOTDSC;
- }
- }
- else if (IS_DSC(line, "%%PageTrailer")) {
- dsc->id = CDSC_PAGETRAILER;
- /* ignore */
- }
- else if (IS_DSC(line, "%%BeginPageSetup")) {
- dsc->id = CDSC_BEGINPAGESETUP;
- /* ignore */
- }
- else if (IS_DSC(line, "%%EndPageSetup")) {
- dsc->id = CDSC_ENDPAGESETUP;
- /* ignore */
- }
- else if (IS_DSC(line, "%%PageMedia:")) {
- dsc->id = CDSC_PAGEMEDIA;
- dsc_parse_media(dsc, &(dsc->page[dsc->page_count-1].media));
- }
- else if (IS_DSC(line, "%%PaperColor:")) {
- dsc->id = CDSC_PAPERCOLOR;
- /* ignore */
- }
- else if (IS_DSC(line, "%%PaperForm:")) {
- dsc->id = CDSC_PAPERFORM;
- /* ignore */
- }
- else if (IS_DSC(line, "%%PaperWeight:")) {
- dsc->id = CDSC_PAPERWEIGHT;
- /* ignore */
- }
- else if (IS_DSC(line, "%%PaperSize:")) {
- /* DSC 2.1 */
- GSBOOL found_media = FALSE;
- int i;
- int n = 12;
- char buf[MAXSTR];
- buf[0] = '\0';
- dsc_copy_string(buf, sizeof(buf)-1, dsc->line+n,
- dsc->line_length-n, NULL);
- for (i=0; i<(int)dsc->media_count; i++) {
- if (dsc->media[i] && dsc->media[i]->name &&
- (dsc_stricmp(buf, dsc->media[i]->name)==0)) {
- dsc->page_media = dsc->media[i];
- found_media = TRUE;
- break;
- }
- }
- if (!found_media) {
- /* It didn't match %%DocumentPaperSizes: */
- /* Try our known media */
- const CDSCMEDIA *m = dsc_known_media;
- while (m->name) {
- if (dsc_stricmp(buf, m->name)==0) {
- dsc->page[dsc->page_count-1].media = m;
- break;
- }
- m++;
- }
- if (m->name == NULL)
- dsc_unknown(dsc);
- }
- }
- else if (IS_DSC(line, "%%PageOrientation:")) {
- dsc->id = CDSC_PAGEORIENTATION;
- if (dsc_parse_orientation(dsc,
- &(dsc->page[dsc->page_count-1].orientation) ,18))
- return CDSC_NOTDSC;
- }
- else if (IS_DSC(line, "%%PageBoundingBox:")) {
- dsc->id = CDSC_PAGEBOUNDINGBOX;
- if (dsc_parse_bounding_box(dsc, &dsc->page[dsc->page_count-1].bbox, 18))
- return CDSC_NOTDSC;
- }
- else if (IS_DSC(line, "%%ViewingOrientation:")) {
- dsc->id = CDSC_VIEWINGORIENTATION;
- if (dsc_parse_viewing_orientation(dsc,
- &dsc->page[dsc->page_count-1].viewing_orientation))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%BeginFont:")) {
- dsc->id = CDSC_BEGINFONT;
- /* ignore Begin/EndFont, apart form making sure */
- /* that they are matched. */
- dsc->begin_font_count++;
- }
- else if (IS_DSC(line, "%%EndFont")) {
- dsc->id = CDSC_BEGINFONT;
- dsc->begin_font_count--;
- }
- else if (IS_DSC(line, "%%BeginFeature:")) {
- dsc->id = CDSC_BEGINFEATURE;
- /* ignore Begin/EndFeature, apart form making sure */
- /* that they are matched. */
- dsc->begin_feature_count++;
- }
- else if (IS_DSC(line, "%%EndFeature")) {
- dsc->id = CDSC_ENDFEATURE;
- dsc->begin_feature_count--;
- }
- else if (IS_DSC(line, "%%BeginResource:")) {
- dsc->id = CDSC_BEGINRESOURCE;
- /* ignore Begin/EndResource, apart form making sure */
- /* that they are matched. */
- dsc->begin_resource_count++;
- }
- else if (IS_DSC(line, "%%EndResource")) {
- dsc->id = CDSC_ENDRESOURCE;
- dsc->begin_resource_count--;
- }
- else if (IS_DSC(line, "%%BeginProcSet:")) {
- dsc->id = CDSC_BEGINPROCSET;
- /* ignore Begin/EndProcSet, apart form making sure */
- /* that they are matched. */
- dsc->begin_procset_count++;
- }
- else if (IS_DSC(line, "%%EndProcSet")) {
- dsc->id = CDSC_ENDPROCSET;
- dsc->begin_procset_count--;
- }
- else if (IS_DSC(line, "%%IncludeFont:")) {
- dsc->id = CDSC_INCLUDEFONT;
- /* ignore */
- }
- else {
- /* All other DSC comments are unknown, but not an error */
- dsc->id = CDSC_UNKNOWNDSC;
- dsc_unknown(dsc);
- }
- dsc->page[dsc->page_count-1].end = DSC_END(dsc);
- return CDSC_OK;
- }
- /* Valid Trailer comments are
- * %%Trailer
- * %%EOF
- * or the following deferred with (atend)
- * %%BoundingBox:
- * %%DocumentCustomColors:
- * %%DocumentFiles:
- * %%DocumentFonts:
- * %%DocumentNeededFiles:
- * %%DocumentNeededFonts:
- * %%DocumentNeededProcSets:
- * %%DocumentNeededResources:
- * %%DocumentProcSets:
- * %%DocumentProcessColors:
- * %%DocumentSuppliedFiles:
- * %%DocumentSuppliedFonts:
- * %%DocumentSuppliedProcSets:
- * %%DocumentSuppliedResources:
- * %%Orientation:
- * %%Pages:
- * %%PageOrder:
- *
- * Our supported subset is
- * %%Trailer
- * %%EOF
- * %%BoundingBox:
- * %%Orientation:
- * %%Pages:
- * %%PageOrder:
- * In addition to these, we support
- * %%DocumentMedia:
- *
- * A %%PageTrailer can have the following:
- * %%PageBoundingBox:
- * %%PageCustomColors:
- * %%PageFiles:
- * %%PageFonts:
- * %%PageOrientation:
- * %%PageProcessColors:
- * %%PageResources:
- */
- dsc_private int
- dsc_scan_trailer(CDSC *dsc)
- {
- /* Trailer section start at */
- /* %%Trailer */
- /* and ends at */
- /* %%EOF */
- char *line = dsc->line;
- GSBOOL continued = FALSE;
- dsc->id = CDSC_OK;
- if (dsc->scan_section == scan_pre_trailer) {
- if (IS_DSC(line, "%%Trailer")) {
- dsc->id = CDSC_TRAILER;
- dsc->begintrailer = DSC_START(dsc);
- dsc->endtrailer = DSC_END(dsc);
- dsc->scan_section = scan_trailer;
- return CDSC_OK;
- }
- else if (IS_DSC(line, "%%EOF")) {
- dsc->id = CDSC_EOF;
- dsc->begintrailer = DSC_START(dsc);
- dsc->endtrailer = DSC_END(dsc);
- dsc->scan_section = scan_trailer;
- /* Continue, in case we found %%EOF in an embedded document */
- return CDSC_OK;
- }
- else {
- /* %%Page: didn't follow %%EndSetup
- * Keep reading until reach %%Page or %%Trailer
- * and add it to setup section
- */
- /* append to previous section */
- if (dsc->beginsetup)
- dsc->endsetup = DSC_END(dsc);
- else if (dsc->beginprolog)
- dsc->endprolog = DSC_END(dsc);
- else {
- /* horribly confused */
- }
- return CDSC_OK;
- }
- }
- /* Handle continuation lines.
- * See comment above about our restrictive processing of
- * continuation lines
- */
- if (IS_DSC(line, "%%+")) {
- line = dsc->last_line;
- continued = TRUE;
- }
- else
- dsc_save_line(dsc);
- if (NOT_DSC_LINE(line)) {
- /* ignore */
- }
- else if (IS_DSC(dsc->line, "%%EOF")) {
- /* Keep scanning, in case we have a false trailer */
- dsc->id = CDSC_EOF;
- }
- else if (IS_DSC(dsc->line, "%%Trailer")) {
- /* Cope with no pages with code after setup and before trailer. */
- /* Last trailer is the correct one. */
- dsc->id = CDSC_TRAILER;
- dsc->begintrailer = DSC_START(dsc);
- }
- else if (IS_DSC(line, "%%Pages:")) {
- dsc->id = CDSC_PAGES;
- if (dsc_parse_pages(dsc) != 0)
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%BoundingBox:")) {
- dsc->id = CDSC_BOUNDINGBOX;
- if (dsc_parse_bounding_box(dsc, &(dsc->bbox), continued ? 3 : 14))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%Orientation:")) {
- dsc->id = CDSC_ORIENTATION;
- if (dsc_parse_orientation(dsc, &(dsc->page_orientation), continued ? 3 : 14))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%PageOrder:")) {
- dsc->id = CDSC_PAGEORDER;
- if (dsc_parse_order(dsc))
- return CDSC_ERROR;
- }
- else if (IS_DSC(line, "%%DocumentMedia:")) {
- dsc->id = CDSC_DOCUMENTMEDIA;
- if (dsc_parse_document_media(dsc))
- return CDSC_ERROR;
- }
- else if (IS_DSC(dsc->line, "%%Page:")) {
- /* This should not occur in the trailer, but we might see
- * this if a document has been incorrectly embedded.
- */
- int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_IN_TRAILER,
- dsc->line, dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* Assume that we are really in the previous */
- /* page, not the trailer */
- dsc->scan_section = scan_pre_pages;
- if (dsc->page_count)
- dsc->page[dsc->page_count-1].end = DSC_START(dsc);
- return CDSC_PROPAGATE; /* try again */
- case CDSC_RESPONSE_CANCEL:
- /* ignore pages in trailer */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- else if (IS_DSC(line, "%%DocumentNeededFonts:")) {
- dsc->id = CDSC_DOCUMENTNEEDEDFONTS;
- /* ignore */
- }
- else if (IS_DSC(line, "%%DocumentSuppliedFonts:")) {
- dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
- /* ignore */
- }
- else {
- /* All other DSC comments are unknown, but not an error */
- dsc->id = CDSC_UNKNOWNDSC;
- dsc_unknown(dsc);
- }
- dsc->endtrailer = DSC_END(dsc);
- return CDSC_OK;
- }
- dsc_private char *
- dsc_alloc_string(CDSC *dsc, const char *str, int len)
- {
- char *p;
- if (dsc->string_head == NULL) {
- dsc->string_head = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
- if (dsc->string_head == NULL)
- return NULL; /* no memory */
- dsc->string = dsc->string_head;
- dsc->string->next = NULL;
- dsc->string->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
- if (dsc->string->data == NULL) {
- dsc_reset(dsc);
- return NULL; /* no memory */
- }
- dsc->string->index = 0;
- dsc->string->length = CDSC_STRING_CHUNK;
- }
- if ( dsc->string->index + len + 1 > dsc->string->length) {
- /* allocate another string block */
- CDSCSTRING *newstring = (CDSCSTRING *)dsc_memalloc(dsc, sizeof(CDSCSTRING));
- if (newstring == NULL) {
- dsc_debug_print(dsc, "Out of memory\n");
- return NULL;
- }
- newstring->next = NULL;
- newstring->length = 0;
- newstring->index = 0;
- newstring->data = (char *)dsc_memalloc(dsc, CDSC_STRING_CHUNK);
- if (newstring->data == NULL) {
- dsc_memfree(dsc, newstring);
- dsc_debug_print(dsc, "Out of memory\n");
- return NULL; /* no memory */
- }
- newstring->length = CDSC_STRING_CHUNK;
- dsc->string->next = newstring;
- dsc->string = newstring;
- }
- if ( dsc->string->index + len + 1 > dsc->string->length)
- return NULL; /* failed */
- p = dsc->string->data + dsc->string->index;
- memcpy(p, str, len);
- *(p+len) = '\0';
- dsc->string->index += len + 1;
- return p;
- }
- /* store line, ignoring leading spaces */
- dsc_private char *
- dsc_add_line(CDSC *dsc, const char *line, unsigned int len)
- {
- char *newline;
- unsigned int i;
- while (len && (IS_WHITE(*line))) {
- len--;
- line++;
- }
- newline = dsc_alloc_string(dsc, line, len);
- if (newline == NULL)
- return NULL;
- for (i=0; i<len; i++) {
- if (newline[i] == '\r') {
- newline[i]='\0';
- break;
- }
- if (newline[i] == '\n') {
- newline[i]='\0';
- break;
- }
- }
- return newline;
- }
- /* Copy string on line to new allocated string str */
- /* String is always null terminated */
- /* String is no longer than len */
- /* Return pointer to string */
- /* Store number of used characters from line */
- /* Don't copy enclosing () */
- dsc_private char *
- dsc_copy_string(char *str, unsigned int slen, char *line,
- unsigned int len, unsigned int *offset)
- {
- int quoted = FALSE;
- int instring=0;
- unsigned int newlength = 0;
- unsigned int i = 0;
- unsigned char ch;
- if (len > slen)
- len = slen-1;
- while ( (i<len) && IS_WHITE(line[i]))
- i++; /* skip leading spaces */
- if (line[i]=='(') {
- quoted = TRUE;
- instring++;
- i++; /* don't copy outside () */
- }
- while (i < len) {
- str[newlength] = ch = line[i];
- i++;
- if (quoted) {
- if (ch == '(')
- instring++;
- if (ch == ')')
- instring--;
- if (instring==0)
- break;
- }
- else if (ch == ' ')
- break;
- if (ch == '\r')
- break;
- if (ch == '\n')
- break;
- else if ( (ch == '\\') && (i+1 < len) ) {
- ch = line[i];
- if ((ch >= '0') && (ch <= '9')) {
- /* octal coded character */
- int j = 3;
- ch = 0;
- while (j && (i < len) && line[i]>='0' && line[i]<='7') {
- ch = (unsigned char)((ch<<3) + (line[i]-'0'));
- i++;
- j--;
- }
- str[newlength] = ch;
- }
- else if (ch == '(') {
- str[newlength] = ch;
- i++;
- }
- else if (ch == ')') {
- str[newlength] = ch;
- i++;
- }
- else if (ch == 'b') {
- str[newlength] = '\b';
- i++;
- }
- else if (ch == 'f') {
- str[newlength] = '\b';
- i++;
- }
- else if (ch == 'n') {
- str[newlength] = '\n';
- i++;
- }
- else if (ch == 'r') {
- str[newlength] = '\r';
- i++;
- }
- else if (ch == 't') {
- str[newlength] = '\t';
- i++;
- }
- else if (ch == '\\') {
- str[newlength] = '\\';
- i++;
- }
- }
- newlength++;
- }
- str[newlength] = '\0';
- if (offset != (unsigned int *)NULL)
- *offset = i;
- return str;
- }
- dsc_private int
- dsc_get_int(const char *line, unsigned int len, unsigned int *offset)
- {
- char newline[MAXSTR];
- int newlength = 0;
- unsigned int i = 0;
- unsigned char ch;
- len = min(len, sizeof(newline)-1);
- while ((i<len) && IS_WHITE(line[i]))
- i++; /* skip leading spaces */
- while (i < len) {
- newline[newlength] = ch = line[i];
- if (!(isdigit(ch) || (ch=='-') || (ch=='+')))
- break; /* not part of an integer number */
- i++;
- newlength++;
- }
- while ((i<len) && IS_WHITE(line[i]))
- i++; /* skip trailing spaces */
- newline[newlength] = '\0';
- if (offset != (unsigned int *)NULL)
- *offset = i;
- return atoi(newline);
- }
- dsc_private float
- dsc_get_real(const char *line, unsigned int len, unsigned int *offset)
- {
- char newline[MAXSTR];
- int newlength = 0;
- unsigned int i = 0;
- unsigned char ch;
- len = min(len, sizeof(newline)-1);
- while ((i<len) && IS_WHITE(line[i]))
- i++; /* skip leading spaces */
- while (i < len) {
- newline[newlength] = ch = line[i];
- if (!(isdigit(ch) || (ch=='.') || (ch=='-') || (ch=='+')
- || (ch=='e') || (ch=='E')))
- break; /* not part of a real number */
- i++;
- newlength++;
- }
- while ((i<len) && IS_WHITE(line[i]))
- i++; /* skip trailing spaces */
- newline[newlength] = '\0';
- if (offset != (unsigned int *)NULL)
- *offset = i;
- return (float)atof(newline);
- }
- dsc_private int
- dsc_stricmp(const char *s, const char *t)
- {
- while (toupper(*s) == toupper(*t)) {
- if (*s == '\0')
- return 0;
- s++;
- t++;
- }
- return (toupper(*s) - toupper(*t));
- }
- dsc_private int
- dsc_parse_page(CDSC *dsc)
- {
- char *p;
- unsigned int i;
- char page_label[MAXSTR];
- char *pl;
- int page_ordinal;
- int page_number;
- p = dsc->line + 7;
- pl = dsc_copy_string(page_label, sizeof(page_label), p, dsc->line_length-7, &i);
- if (pl == NULL)
- return CDSC_ERROR;
- p += i;
- page_ordinal = atoi(p);
- if ( (page_ordinal == 0) || (strlen(page_label) == 0) ||
- (dsc->page_count &&
- (page_ordinal != dsc->page[dsc->page_count-1].ordinal+1)) ) {
- int rc = dsc_error(dsc, CDSC_MESSAGE_PAGE_ORDINAL, dsc->line,
- dsc->line_length);
- switch (rc) {
- case CDSC_RESPONSE_OK:
- /* ignore this page */
- return CDSC_OK;
- case CDSC_RESPONSE_CANCEL:
- /* accept the page */
- break;
- case CDSC_RESPONSE_IGNORE_ALL:
- return CDSC_NOTDSC;
- }
- }
- page_number = dsc->page_count;
- dsc_add_page(dsc, page_ordinal, page_label);
- dsc->page[page_number].begin = DSC_START(dsc);
- dsc->page[page_number].end = DSC_START(dsc);
- if (dsc->page[page_number].label == NULL)
- return CDSC_ERROR; /* no memory */
-
- return CDSC_OK;
- }
- /* DSC error reporting */
- void
- dsc_debug_print(CDSC *dsc, const char *str)
- {
- if (dsc->debug_print_fn)
- dsc->debug_print_fn(dsc->caller_data, str);
- }
- /* Display a message about a problem with the DSC comments.
- *
- * explanation = an index to to a multiline explanation in dsc_message[]
- * line = pointer to the offending DSC line (if any)
- * return code =
- * CDSC_RESPONSE_OK DSC was wrong, make a guess about what
- * was really meant.
- * CDSC_RESPONSE_CANCEL Assume DSC was correct, ignore if it
- * is misplaced.
- * CDSC_RESPONSE_IGNORE_ALL Ignore all DSC.
- */
- /* Silent operation. Don't display errors. */
- dsc_private int
- dsc_error(CDSC *dsc, unsigned int explanation,
- char *line, unsigned int line_len)
- {
- /* if error function provided, use it */
- if (dsc->dsc_error_fn)
- return dsc->dsc_error_fn(dsc->caller_data, dsc,
- explanation, line, line_len);
- /* treat DSC as being correct */
- return CDSC_RESPONSE_CANCEL;
- }
|