| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139 |
- // Copyright (C) 2023-2025 Artifex Software, Inc.
- //
- // This file is part of MuPDF.
- //
- // MuPDF is free software: you can redistribute it and/or modify it under the
- // terms of the GNU Affero General Public License as published by the Free
- // Software Foundation, either version 3 of the License, or (at your option)
- // any later version.
- //
- // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
- // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
- // details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
- //
- // Alternative licensing terms are available from the licensor.
- // For commercial licensing, see <https://www.artifex.com/> or contact
- // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
- // CA 94129, USA, for further information.
- /*
- * PDF auditing tool
- */
- #include "mupdf/fitz.h"
- #include "mupdf/pdf.h"
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #define SWITCH(x) switch ((intptr_t)(x))
- #define CASE(x) case ((intptr_t)(x))
- typedef enum
- {
- AUDIT_UNKNOWN = 0,
- AUDIT_THUMBNAILS,
- AUDIT_IMAGES,
- AUDIT_BOOKMARKS,
- AUDIT_PAGE_OBJECTS,
- AUDIT_CONTENT_STREAMS,
- AUDIT_FONTS,
- AUDIT_STRUCTURE_INFO,
- AUDIT_FORMS,
- AUDIT_LINK_ANNOTATIONS,
- AUDIT_COMMENTS,
- AUDIT_3DCONTENT,
- AUDIT_NAMED_DESTINATIONS,
- //AUDIT_DOCUMENT_OVERHEAD, // FIXME
- AUDIT_COLORSPACES,
- AUDIT_FORM_XOBJ,
- AUDIT_EXTGS,
- AUDIT_PIECE_INFORMATION,
- AUDIT_EMBEDDED_FILES,
- AUDIT_TRAILER,
- AUDIT_RESOURCES,
- AUDIT_OBJSTM,
- AUDIT_METADATA,
- AUDIT__MAX
- } audit_type_t;
- const char *audit_type[] =
- {
- "UNKNOWN",
- "THUMBNAILS",
- "IMAGES",
- "BOOKMARKS",
- "PAGE OBJECTS",
- "CONTENT_STREAMS",
- "FONTS",
- "STRUCTURE_INFO",
- "FORMS",
- "LINK_ANNOTATIONS",
- "COMMENTS",
- "3DCONTENT",
- "NAMED_DESTINATIONS",
- //"DOCUMENT_OVERHEAD",
- "COLORSPACES",
- "FORM_XOBJ",
- "EXTGS",
- "PIECE_INFORMATION",
- "EMBEDDED_FILES",
- "TRAILER",
- "RESOURCES",
- "OBJSTM",
- "METADATA"
- };
- typedef struct
- {
- audit_type_t type;
- int is_in_objstm;
- /* The number of bytes this object will take in the file, not including any actual stream content. */
- size_t textsize;
- /* The number of bytes of overhead "1 0 R\nendobj\n" plus "stream\nendstream\n" */
- size_t overhead;
- /* Uncompressed stream size */
- size_t len;
- /* Compressed stream size (not including 'stream\nendstream\n) */
- size_t stream_len;
- } obj_info_t;
- enum
- {
- OP_w = 0,
- OP_j,
- OP_J,
- OP_M,
- OP_d,
- OP_ri,
- OP_gs_OP,
- OP_gs_op,
- OP_gs_OPM,
- OP_gs_UseBlackPtComp,
- OP_i,
- OP_gs_begin,
- OP_gs_BM,
- OP_gs_CA,
- OP_gs_ca,
- OP_gs_SMask,
- OP_gs_end,
- OP_q,
- OP_cm,
- OP_m,
- OP_l,
- OP_c,
- OP_v,
- OP_y,
- OP_h,
- OP_re,
- OP_S,
- OP_s,
- OP_F,
- OP_f,
- OP_fstar,
- OP_B,
- OP_Bstar,
- OP_b,
- OP_bstar,
- OP_n,
- OP_W,
- OP_Wstar,
- OP_BT,
- OP_ET,
- OP_Q,
- OP_Tc,
- OP_Tw,
- OP_Tz,
- OP_TL,
- OP_Tf,
- OP_Tr,
- OP_Ts,
- OP_Td,
- OP_TD,
- OP_Tm,
- OP_Tstar,
- OP_TJ,
- OP_Tj,
- OP_squote,
- OP_dquote,
- OP_d0,
- OP_d1,
- OP_CS,
- OP_cs,
- OP_SC_pattern,
- OP_sc_pattern,
- OP_SC_shade,
- OP_sc_shade,
- OP_SC_color,
- OP_sc_color,
- OP_G,
- OP_g,
- OP_RG,
- OP_rg,
- OP_K,
- OP_k,
- OP_BI,
- OP_sh,
- OP_Do_image,
- OP_Do_form,
- OP_MP,
- OP_DP,
- OP_BMC,
- OP_BDC,
- OP_EMC,
- OP_BX,
- OP_EX,
- OP_END
- };
- const char *op_names[] =
- {
- "w",
- "j",
- "J",
- "M",
- "d",
- "ri",
- "gs_OP",
- "gs_op",
- "gs_OPM",
- "gs_UseBlackPtComp",
- "i",
- "gs_begin",
- "gs_BM",
- "gs_CA",
- "gs_ca",
- "gs_SMask",
- "gs_end",
- "q",
- "cm",
- "m",
- "l",
- "c",
- "v",
- "y",
- "h",
- "re",
- "S",
- "s",
- "F",
- "f",
- "fstar",
- "B",
- "Bstar",
- "b",
- "bstar",
- "n",
- "W",
- "Wstar",
- "BT",
- "ET",
- "Q",
- "Tc",
- "Tw",
- "Tz",
- "TL",
- "Tf",
- "Tr",
- "Ts",
- "Td",
- "TD",
- "Tm",
- "Tstar",
- "TJ",
- "Tj",
- "squote",
- "dquote",
- "d0",
- "d1",
- "CS",
- "cs",
- "SC_pattern",
- "sc_pattern",
- "SC_shade",
- "sc_shade",
- "SC_color",
- "sc_color",
- "G",
- "g",
- "RG",
- "rg",
- "K",
- "k",
- "BI",
- "sh",
- "Do_image",
- "Do_form",
- "MP",
- "DP",
- "BMC",
- "BDC",
- "EMC",
- "BX",
- "EX",
- };
- typedef struct
- {
- size_t len[OP_END];
- } op_usage_t;
- typedef struct
- {
- pdf_processor super;
- pdf_document *doc;
- int structparents;
- pdf_processor *mine;
- pdf_processor *chain;
- pdf_filter_options *global_options;
- op_usage_t *op_usage;
- fz_buffer *buffer;
- } pdf_opcount_processor;
- /* general graphics state */
- static void
- pdf_opcount_w(fz_context *ctx, pdf_processor *proc, float linewidth)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_w)
- p->mine->op_w(ctx, p->mine, linewidth);
- z = p->buffer->len - z;
- p->op_usage->len[OP_w] += z;
- }
- static void
- pdf_opcount_j(fz_context *ctx, pdf_processor *proc, int linejoin)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_j)
- p->mine->op_j(ctx, p->mine, linejoin);
- z = p->buffer->len - z;
- p->op_usage->len[OP_j] += z;
- }
- static void
- pdf_opcount_J(fz_context *ctx, pdf_processor *proc, int linecap)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_J)
- p->mine->op_J(ctx, p->mine, linecap);
- z = p->buffer->len - z;
- p->op_usage->len[OP_J] += z;
- }
- static void
- pdf_opcount_M(fz_context *ctx, pdf_processor *proc, float miterlimit)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_M)
- p->mine->op_M(ctx, p->mine, miterlimit);
- z = p->buffer->len - z;
- p->op_usage->len[OP_M] += z;
- }
- static void
- pdf_opcount_d(fz_context *ctx, pdf_processor *proc, pdf_obj *array, float phase)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_d)
- p->mine->op_d(ctx, p->mine, array, phase);
- z = p->buffer->len - z;
- p->op_usage->len[OP_d] += z;
- }
- static void
- pdf_opcount_ri(fz_context *ctx, pdf_processor *proc, const char *intent)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_ri)
- p->mine->op_ri(ctx, p->mine, intent);
- z = p->buffer->len - z;
- p->op_usage->len[OP_ri] += z;
- }
- static void
- pdf_opcount_gs_OP(fz_context *ctx, pdf_processor *proc, int b)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_OP)
- p->mine->op_gs_OP(ctx, p->mine, b);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_OP] += z;
- }
- static void
- pdf_opcount_gs_op(fz_context *ctx, pdf_processor *proc, int b)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_op)
- p->mine->op_gs_op(ctx, p->mine, b);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_op] += z;
- }
- static void
- pdf_opcount_gs_OPM(fz_context *ctx, pdf_processor *proc, int i)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_OPM)
- p->mine->op_gs_OPM(ctx, p->mine, i);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_OPM] += z;
- }
- static void
- pdf_opcount_gs_UseBlackPtComp(fz_context *ctx, pdf_processor *proc, pdf_obj *name)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_UseBlackPtComp)
- p->mine->op_gs_UseBlackPtComp(ctx, p->mine, name);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_UseBlackPtComp] += z;
- }
- static void
- pdf_opcount_i(fz_context *ctx, pdf_processor *proc, float flatness)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_i)
- p->mine->op_i(ctx, p->mine, flatness);
- z = p->buffer->len - z;
- p->op_usage->len[OP_i] += z;
- }
- static void
- pdf_opcount_gs_begin(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_begin)
- p->mine->op_gs_begin(ctx, p->mine, name, extgstate);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_begin] += z;
- }
- static void
- pdf_opcount_gs_BM(fz_context *ctx, pdf_processor *proc, const char *blendmode)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_BM)
- p->mine->op_gs_BM(ctx, p->mine, blendmode);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_BM] += z;
- }
- static void
- pdf_opcount_gs_CA(fz_context *ctx, pdf_processor *proc, float alpha)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_CA)
- p->mine->op_gs_CA(ctx, p->mine, alpha);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_CA] += z;
- }
- static void
- pdf_opcount_gs_ca(fz_context *ctx, pdf_processor *proc, float alpha)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_ca)
- p->mine->op_gs_ca(ctx, p->mine, alpha);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_ca] += z;
- }
- static void
- pdf_opcount_gs_SMask(fz_context *ctx, pdf_processor *proc, pdf_obj *smask, fz_colorspace *smask_cs, float *bc, int luminosity, pdf_obj *obj)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_SMask)
- p->mine->op_gs_SMask(ctx, p->mine, smask, smask_cs, bc, luminosity, obj);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_SMask] += z;
- }
- static void
- pdf_opcount_gs_end(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_gs_end)
- p->mine->op_gs_end(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_gs_end] += z;
- }
- /* special graphics state */
- static void
- pdf_opcount_q(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_q)
- p->mine->op_q(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_q] += z;
- }
- static void
- pdf_opcount_cm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_cm)
- p->mine->op_cm(ctx, p->mine, a, b, c, d, e, f);
- z = p->buffer->len - z;
- p->op_usage->len[OP_cm] += z;
- }
- /* path construction */
- static void
- pdf_opcount_m(fz_context *ctx, pdf_processor *proc, float x, float y)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_m)
- p->mine->op_m(ctx, p->mine, x, y);
- z = p->buffer->len - z;
- p->op_usage->len[OP_m] += z;
- }
- static void
- pdf_opcount_l(fz_context *ctx, pdf_processor *proc, float x, float y)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_l)
- p->mine->op_l(ctx, p->mine, x, y);
- z = p->buffer->len - z;
- p->op_usage->len[OP_l] += z;
- }
- static void
- pdf_opcount_c(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x2, float y2, float x3, float y3)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_c)
- p->mine->op_c(ctx, p->mine, x1, y1, x2, y2, x3, y3);
- z = p->buffer->len - z;
- p->op_usage->len[OP_c] += z;
- }
- static void
- pdf_opcount_v(fz_context *ctx, pdf_processor *proc, float x2, float y2, float x3, float y3)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_v)
- p->mine->op_v(ctx, p->mine, x2, y2, x3, y3);
- z = p->buffer->len - z;
- p->op_usage->len[OP_v] += z;
- }
- static void
- pdf_opcount_y(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x3, float y3)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_y)
- p->mine->op_y(ctx, p->mine, x1, y1, x3, y3);
- z = p->buffer->len - z;
- p->op_usage->len[OP_y] += z;
- }
- static void
- pdf_opcount_h(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_h)
- p->mine->op_h(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_h] += z;
- }
- static void
- pdf_opcount_re(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_re)
- p->mine->op_re(ctx, p->mine, x, y, w, h);
- z = p->buffer->len - z;
- p->op_usage->len[OP_re] += z;
- }
- /* path painting */
- static void
- pdf_opcount_S(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_S)
- p->mine->op_S(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_S] += z;
- }
- static void
- pdf_opcount_s(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_s)
- p->mine->op_s(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_s] += z;
- }
- static void
- pdf_opcount_F(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_F)
- p->mine->op_F(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_F] += z;
- }
- static void
- pdf_opcount_f(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_f)
- p->mine->op_f(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_f] += z;
- }
- static void
- pdf_opcount_fstar(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_fstar)
- p->mine->op_fstar(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_fstar] += z;
- }
- static void
- pdf_opcount_B(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_B)
- p->mine->op_B(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_B] += z;
- }
- static void
- pdf_opcount_Bstar(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Bstar)
- p->mine->op_Bstar(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Bstar] += z;
- }
- static void
- pdf_opcount_b(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_b)
- p->mine->op_b(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_b] += z;
- }
- static void
- pdf_opcount_bstar(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_bstar)
- p->mine->op_bstar(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_bstar] += z;
- }
- static void
- pdf_opcount_n(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_n)
- p->mine->op_n(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_n] += z;
- }
- /* clipping paths */
- static void
- pdf_opcount_W(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_W)
- p->mine->op_W(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_W] += z;
- }
- static void
- pdf_opcount_Wstar(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Wstar)
- p->mine->op_Wstar(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Wstar] += z;
- }
- /* text objects */
- static void
- pdf_opcount_BT(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_BT)
- p->mine->op_BT(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_BT] += z;
- }
- static void
- pdf_opcount_ET(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_ET)
- p->mine->op_ET(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_ET] += z;
- }
- static void
- pdf_opcount_Q(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Q)
- p->mine->op_Q(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Q] += z;
- }
- /* text state */
- static void
- pdf_opcount_Tc(fz_context *ctx, pdf_processor *proc, float charspace)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tc)
- p->mine->op_Tc(ctx, p->mine, charspace);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tc] += z;
- }
- static void
- pdf_opcount_Tw(fz_context *ctx, pdf_processor *proc, float wordspace)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tw)
- p->mine->op_Tw(ctx, p->mine, wordspace);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tw] += z;
- }
- static void
- pdf_opcount_Tz(fz_context *ctx, pdf_processor *proc, float scale)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tz)
- p->mine->op_Tz(ctx, p->mine, scale);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tz] += z;
- }
- static void
- pdf_opcount_TL(fz_context *ctx, pdf_processor *proc, float leading)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_TL)
- p->mine->op_TL(ctx, p->mine, leading);
- z = p->buffer->len - z;
- p->op_usage->len[OP_TL] += z;
- }
- static void
- pdf_opcount_Tf(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tf)
- p->mine->op_Tf(ctx, p->mine, name, font, size);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tf] += z;
- }
- static void
- pdf_opcount_Tr(fz_context *ctx, pdf_processor *proc, int render)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tr)
- p->mine->op_Tr(ctx, p->mine, render);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tr] += z;
- }
- static void
- pdf_opcount_Ts(fz_context *ctx, pdf_processor *proc, float rise)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Ts)
- p->mine->op_Ts(ctx, p->mine, rise);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Ts] += z;
- }
- /* text positioning */
- static void
- pdf_opcount_Td(fz_context *ctx, pdf_processor *proc, float tx, float ty)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Td)
- p->mine->op_Td(ctx, p->mine, tx, ty);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Td] += z;
- }
- static void
- pdf_opcount_TD(fz_context *ctx, pdf_processor *proc, float tx, float ty)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_TD)
- p->mine->op_TD(ctx, p->mine, tx, ty);
- z = p->buffer->len - z;
- p->op_usage->len[OP_TD] += z;
- }
- static void
- pdf_opcount_Tm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tm)
- p->mine->op_Tm(ctx, p->mine, a, b, c, d, e, f);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tm] += z;
- }
- static void
- pdf_opcount_Tstar(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tstar)
- p->mine->op_Tstar(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tstar] += z;
- }
- /* text showing */
- static void
- pdf_opcount_TJ(fz_context *ctx, pdf_processor *proc, pdf_obj *array)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_TJ)
- p->mine->op_TJ(ctx, p->mine, array);
- z = p->buffer->len - z;
- p->op_usage->len[OP_TJ] += z;
- }
- static void
- pdf_opcount_Tj(fz_context *ctx, pdf_processor *proc, char *str, size_t len)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Tj)
- p->mine->op_Tj(ctx, p->mine, str, len);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Tj] += z;
- }
- static void
- pdf_opcount_squote(fz_context *ctx, pdf_processor *proc, char *str, size_t len)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_squote)
- p->mine->op_squote(ctx, p->mine, str, len);
- z = p->buffer->len - z;
- p->op_usage->len[OP_squote] += z;
- }
- static void
- pdf_opcount_dquote(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *str, size_t len)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_dquote)
- p->mine->op_dquote(ctx, p->mine, aw, ac, str, len);
- z = p->buffer->len - z;
- p->op_usage->len[OP_dquote] += z;
- }
- /* type 3 fonts */
- static void
- pdf_opcount_d0(fz_context *ctx, pdf_processor *proc, float wx, float wy)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_d0)
- p->mine->op_d0(ctx, p->mine, wx, wy);
- z = p->buffer->len - z;
- p->op_usage->len[OP_d0] += z;
- }
- static void
- pdf_opcount_d1(fz_context *ctx, pdf_processor *proc, float wx, float wy, float llx, float lly, float urx, float ury)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_d1)
- p->mine->op_d1(ctx, p->mine, wx, wy, llx, lly, urx, ury);
- z = p->buffer->len - z;
- p->op_usage->len[OP_d1] += z;
- }
- /* color */
- static void
- pdf_opcount_CS(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor *)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_CS)
- p->mine->op_CS(ctx, p->mine, name, cs);
- z = p->buffer->len - z;
- p->op_usage->len[OP_CS] += z;
- }
- static void
- pdf_opcount_cs(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_cs)
- p->mine->op_cs(ctx, p->mine, name, cs);
- z = p->buffer->len - z;
- p->op_usage->len[OP_cs] += z;
- }
- static void
- pdf_opcount_SC_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_SC_pattern)
- p->mine->op_SC_pattern(ctx, p->mine, name, pat, n, color);
- z = p->buffer->len - z;
- p->op_usage->len[OP_SC_pattern] += z;
- }
- static void
- pdf_opcount_sc_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_sc_pattern)
- p->mine->op_sc_pattern(ctx, p->mine, name, pat, n, color);
- z = p->buffer->len - z;
- p->op_usage->len[OP_sc_pattern] += z;
- }
- static void
- pdf_opcount_SC_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_SC_shade)
- p->mine->op_SC_shade(ctx, p->mine, name, shade);
- z = p->buffer->len - z;
- p->op_usage->len[OP_SC_shade] += z;
- }
- static void
- pdf_opcount_sc_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_sc_shade)
- p->mine->op_sc_shade(ctx, p->mine, name, shade);
- z = p->buffer->len - z;
- p->op_usage->len[OP_sc_shade] += z;
- }
- static void
- pdf_opcount_SC_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_SC_color)
- p->mine->op_SC_color(ctx, p->mine, n, color);
- z = p->buffer->len - z;
- p->op_usage->len[OP_SC_color] += z;
- }
- static void
- pdf_opcount_sc_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_sc_color)
- p->mine->op_sc_color(ctx, p->mine, n, color);
- z = p->buffer->len - z;
- p->op_usage->len[OP_sc_color] += z;
- }
- static void
- pdf_opcount_G(fz_context *ctx, pdf_processor *proc, float g)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_G)
- p->mine->op_G(ctx, p->mine, g);
- z = p->buffer->len - z;
- p->op_usage->len[OP_G] += z;
- }
- static void
- pdf_opcount_g(fz_context *ctx, pdf_processor *proc, float g)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_g)
- p->mine->op_g(ctx, p->mine, g);
- z = p->buffer->len - z;
- p->op_usage->len[OP_g] += z;
- }
- static void
- pdf_opcount_RG(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_RG)
- p->mine->op_RG(ctx, p->mine, r, g, b);
- z = p->buffer->len - z;
- p->op_usage->len[OP_RG] += z;
- }
- static void
- pdf_opcount_rg(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_rg)
- p->mine->op_rg(ctx, p->mine, r, g, b);
- z = p->buffer->len - z;
- p->op_usage->len[OP_rg] += z;
- }
- static void
- pdf_opcount_K(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_K)
- p->mine->op_K(ctx, p->mine, c, m, y, k);
- z = p->buffer->len - z;
- p->op_usage->len[OP_K] += z;
- }
- static void
- pdf_opcount_k(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_k)
- p->mine->op_k(ctx, p->mine, c, m, y, k);
- z = p->buffer->len - z;
- p->op_usage->len[OP_k] += z;
- }
- /* shadings, images, xobjects */
- static void
- pdf_opcount_BI(fz_context *ctx, pdf_processor *proc, fz_image *image, const char *colorspace)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_BI)
- p->mine->op_BI(ctx, p->mine, image, colorspace);
- z = p->buffer->len - z;
- p->op_usage->len[OP_BI] += z;
- }
- static void
- pdf_opcount_sh(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_sh)
- p->mine->op_sh(ctx, p->mine, name, shade);
- z = p->buffer->len - z;
- p->op_usage->len[OP_sh] += z;
- }
- static void
- pdf_opcount_Do_image(fz_context *ctx, pdf_processor *proc, const char *name, fz_image *image)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Do_image)
- p->mine->op_Do_image(ctx, p->mine, name, image);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Do_image] += z;
- }
- static void
- pdf_opcount_Do_form(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *xobj)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_Do_form)
- p->mine->op_Do_form(ctx, p->mine, name, xobj);
- z = p->buffer->len - z;
- p->op_usage->len[OP_Do_form] += z;
- }
- /* marked content */
- static void
- pdf_opcount_MP(fz_context *ctx, pdf_processor *proc, const char *tag)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_MP)
- p->mine->op_MP(ctx, p->mine, tag);
- z = p->buffer->len - z;
- p->op_usage->len[OP_MP] += z;
- }
- static void
- pdf_opcount_DP(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_DP)
- p->mine->op_DP(ctx, p->mine, tag, raw, cooked);
- z = p->buffer->len - z;
- p->op_usage->len[OP_DP] += z;
- }
- static void
- pdf_opcount_BMC(fz_context *ctx, pdf_processor *proc, const char *tag)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_BMC)
- p->mine->op_BMC(ctx, p->mine, tag);
- z = p->buffer->len - z;
- p->op_usage->len[OP_BMC] += z;
- }
- static void
- pdf_opcount_BDC(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_BDC)
- p->mine->op_BDC(ctx, p->mine, tag, raw, cooked);
- z = p->buffer->len - z;
- p->op_usage->len[OP_BDC] += z;
- }
- static void
- pdf_opcount_EMC(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_EMC)
- p->mine->op_EMC(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_EMC] += z;
- }
- /* compatibility */
- static void
- pdf_opcount_BX(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_BX)
- p->mine->op_BX(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_BX] += z;
- }
- static void
- pdf_opcount_EX(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- size_t z = p->buffer->len;
- if (p->mine->op_EX)
- p->mine->op_EX(ctx, p->mine);
- z = p->buffer->len - z;
- p->op_usage->len[OP_EX] += z;
- }
- static void
- pdf_opcount_END(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- if (p->mine->op_END)
- p->mine->op_END(ctx, p->mine);
- }
- static void
- pdf_close_opcount_processor(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- pdf_close_processor(ctx, p->mine);
- pdf_close_processor(ctx, p->chain);
- }
- static void
- pdf_drop_opcount_processor(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- fz_drop_buffer(ctx, p->buffer);
- pdf_drop_processor(ctx, p->mine);
- }
- static void
- pdf_opcount_push_resources(fz_context *ctx, pdf_processor *proc, pdf_obj *res)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- pdf_processor_push_resources(ctx, p->mine, res);
- }
- static pdf_obj *
- pdf_opcount_pop_resources(fz_context *ctx, pdf_processor *proc)
- {
- pdf_opcount_processor *p = (pdf_opcount_processor*)proc;
- return pdf_processor_pop_resources(ctx, p->mine);
- }
- pdf_processor *
- pdf_new_opcount_filter(
- fz_context *ctx,
- pdf_document *doc,
- pdf_processor *chain,
- int struct_parents,
- fz_matrix transform,
- pdf_filter_options *global_options,
- void *options_)
- {
- pdf_opcount_processor *proc = pdf_new_processor(ctx, sizeof * proc);
- fz_try(ctx)
- {
- proc->buffer = fz_new_buffer(ctx, 1024);
- proc->mine = pdf_new_buffer_processor(ctx, proc->buffer, 0, 0);
- }
- fz_catch(ctx)
- fz_rethrow(ctx);
- proc->op_usage = (op_usage_t *)options_;
- proc->super.close_processor = pdf_close_opcount_processor;
- proc->super.drop_processor = pdf_drop_opcount_processor;
- proc->super.push_resources = pdf_opcount_push_resources;
- proc->super.pop_resources = pdf_opcount_pop_resources;
- /* general graphics state */
- proc->super.op_w = pdf_opcount_w;
- proc->super.op_j = pdf_opcount_j;
- proc->super.op_J = pdf_opcount_J;
- proc->super.op_M = pdf_opcount_M;
- proc->super.op_d = pdf_opcount_d;
- proc->super.op_ri = pdf_opcount_ri;
- proc->super.op_i = pdf_opcount_i;
- proc->super.op_gs_begin = pdf_opcount_gs_begin;
- proc->super.op_gs_end = pdf_opcount_gs_end;
- /* transparency graphics state */
- proc->super.op_gs_BM = pdf_opcount_gs_BM;
- proc->super.op_gs_CA = pdf_opcount_gs_CA;
- proc->super.op_gs_ca = pdf_opcount_gs_ca;
- proc->super.op_gs_SMask = pdf_opcount_gs_SMask;
- /* special graphics state */
- proc->super.op_q = pdf_opcount_q;
- proc->super.op_Q = pdf_opcount_Q;
- proc->super.op_cm = pdf_opcount_cm;
- /* path construction */
- proc->super.op_m = pdf_opcount_m;
- proc->super.op_l = pdf_opcount_l;
- proc->super.op_c = pdf_opcount_c;
- proc->super.op_v = pdf_opcount_v;
- proc->super.op_y = pdf_opcount_y;
- proc->super.op_h = pdf_opcount_h;
- proc->super.op_re = pdf_opcount_re;
- /* path painting */
- proc->super.op_S = pdf_opcount_S;
- proc->super.op_s = pdf_opcount_s;
- proc->super.op_F = pdf_opcount_F;
- proc->super.op_f = pdf_opcount_f;
- proc->super.op_fstar = pdf_opcount_fstar;
- proc->super.op_B = pdf_opcount_B;
- proc->super.op_Bstar = pdf_opcount_Bstar;
- proc->super.op_b = pdf_opcount_b;
- proc->super.op_bstar = pdf_opcount_bstar;
- proc->super.op_n = pdf_opcount_n;
- /* clipping paths */
- proc->super.op_W = pdf_opcount_W;
- proc->super.op_Wstar = pdf_opcount_Wstar;
- /* text objects */
- proc->super.op_BT = pdf_opcount_BT;
- proc->super.op_ET = pdf_opcount_ET;
- /* text state */
- proc->super.op_Tc = pdf_opcount_Tc;
- proc->super.op_Tw = pdf_opcount_Tw;
- proc->super.op_Tz = pdf_opcount_Tz;
- proc->super.op_TL = pdf_opcount_TL;
- proc->super.op_Tf = pdf_opcount_Tf;
- proc->super.op_Tr = pdf_opcount_Tr;
- proc->super.op_Ts = pdf_opcount_Ts;
- /* text positioning */
- proc->super.op_Td = pdf_opcount_Td;
- proc->super.op_TD = pdf_opcount_TD;
- proc->super.op_Tm = pdf_opcount_Tm;
- proc->super.op_Tstar = pdf_opcount_Tstar;
- /* text showing */
- proc->super.op_TJ = pdf_opcount_TJ;
- proc->super.op_Tj = pdf_opcount_Tj;
- proc->super.op_squote = pdf_opcount_squote;
- proc->super.op_dquote = pdf_opcount_dquote;
- /* type 3 fonts */
- proc->super.op_d0 = pdf_opcount_d0;
- proc->super.op_d1 = pdf_opcount_d1;
- /* color */
- proc->super.op_CS = pdf_opcount_CS;
- proc->super.op_cs = pdf_opcount_cs;
- proc->super.op_SC_color = pdf_opcount_SC_color;
- proc->super.op_sc_color = pdf_opcount_sc_color;
- proc->super.op_SC_pattern = pdf_opcount_SC_pattern;
- proc->super.op_sc_pattern = pdf_opcount_sc_pattern;
- proc->super.op_SC_shade = pdf_opcount_SC_shade;
- proc->super.op_sc_shade = pdf_opcount_sc_shade;
- proc->super.op_G = pdf_opcount_G;
- proc->super.op_g = pdf_opcount_g;
- proc->super.op_RG = pdf_opcount_RG;
- proc->super.op_rg = pdf_opcount_rg;
- proc->super.op_K = pdf_opcount_K;
- proc->super.op_k = pdf_opcount_k;
- /* shadings, images, xobjects */
- proc->super.op_BI = pdf_opcount_BI;
- proc->super.op_sh = pdf_opcount_sh;
- proc->super.op_Do_image = pdf_opcount_Do_image;
- proc->super.op_Do_form = pdf_opcount_Do_form;
- /* marked content */
- proc->super.op_MP = pdf_opcount_MP;
- proc->super.op_DP = pdf_opcount_DP;
- proc->super.op_BMC = pdf_opcount_BMC;
- proc->super.op_BDC = pdf_opcount_BDC;
- proc->super.op_EMC = pdf_opcount_EMC;
- /* compatibility */
- proc->super.op_BX = pdf_opcount_BX;
- proc->super.op_EX = pdf_opcount_EX;
- /* extgstate */
- proc->super.op_gs_OP = pdf_opcount_gs_OP;
- proc->super.op_gs_op = pdf_opcount_gs_op;
- proc->super.op_gs_OPM = pdf_opcount_gs_OPM;
- proc->super.op_gs_UseBlackPtComp = pdf_opcount_gs_UseBlackPtComp;
- proc->super.op_END = pdf_opcount_END;
- proc->global_options = global_options;
- proc->chain = chain;
- return (pdf_processor*)proc;
- }
- static void
- filter_page(fz_context *ctx, pdf_document *doc, op_usage_t *op_usage, int page_num)
- {
- pdf_page *page = pdf_load_page(ctx, doc, page_num);
- pdf_filter_options options = { 0 };
- pdf_filter_factory list[2] = { 0 };
- pdf_annot *annot;
- options.filters = list;
- options.recurse = 1;
- options.no_update = 1;
- list[0].filter = pdf_new_opcount_filter;
- list[0].options = op_usage;
- fz_try(ctx)
- {
- pdf_filter_page_contents(ctx, doc, page, &options);
- for (annot = pdf_first_annot(ctx, page); annot != NULL; annot = pdf_next_annot(ctx, annot))
- pdf_filter_annot_contents(ctx, doc, annot, &options);
- }
- fz_always(ctx)
- fz_drop_page(ctx, &page->super);
- fz_catch(ctx)
- fz_rethrow(ctx);
- }
- static void
- filter_page_streams(fz_context *ctx, pdf_document *pdf, op_usage_t *ou)
- {
- int i, n = pdf_count_pages(ctx, pdf);
- for (i= 0; i < n; i++)
- {
- filter_page(ctx, pdf, ou, i);
- }
- }
- static void
- filter_buffer(fz_context *ctx, obj_info_t *oi, fz_buffer *buf)
- {
- oi->len = buf->len;
- }
- static void
- filter_stream(fz_context *ctx, pdf_document *pdf, int i, obj_info_t *oi)
- {
- fz_buffer *buf = pdf_load_stream_number(ctx, pdf, i);
- fz_try(ctx)
- filter_buffer(ctx, oi, buf);
- fz_always(ctx)
- fz_drop_buffer(ctx, buf);
- fz_catch(ctx)
- fz_rethrow(ctx);
- }
- static void
- filter_obj(fz_context *ctx, obj_info_t *oi, pdf_obj *obj)
- {
- fz_buffer *buf = fz_new_buffer(ctx, 1024);
- fz_output *out = NULL;
- fz_var(out);
- fz_try(ctx)
- {
- out = fz_new_output_with_buffer(ctx, buf);
- pdf_print_obj(ctx, out, obj, 1, 0);
- fz_close_output(ctx, out);
- }
- fz_always(ctx)
- {
- fz_drop_output(ctx, out);
- if (buf)
- oi->textsize = buf->len;
- fz_drop_buffer(ctx, buf);
- }
- fz_catch(ctx)
- fz_rethrow(ctx);
- }
- typedef struct
- {
- int len;
- int max;
- struct {
- pdf_obj *obj;
- int pos;
- int state;
- } *stack;
- } walk_stack_t;
- static void
- walk(fz_context *ctx, walk_stack_t *ws, int n, obj_info_t *oi, pdf_obj *obj, audit_type_t type)
- {
- int num = 0;
- do
- {
- if (pdf_is_indirect(ctx, obj))
- {
- num = pdf_to_num(ctx, obj);
- if (num < 0 || num >= n)
- fz_throw(ctx, FZ_ERROR_GENERIC, "object outside of xref range");
- if (oi[num].type != AUDIT_UNKNOWN)
- goto visited;
- if (pdf_mark_obj(ctx, obj))
- {
- /* We've already visited this one! */
- goto visited;
- }
- }
- /* Push the object onto the stack. */
- if (ws->len == ws->max)
- {
- int newmax = ws->max * 2;
- if (newmax == 0)
- newmax = 32;
- ws->stack = fz_realloc(ctx, ws->stack, sizeof(ws->stack[0]) * newmax);
- ws->max = newmax;
- }
- /* If the object we are about to stack is a dict, then check to see if
- * we should be changing type because of it. */
- if (pdf_is_dict(ctx, obj))
- {
- pdf_obj *otype = pdf_dict_get(ctx, obj, PDF_NAME(Type));
- pdf_obj *subtype = pdf_dict_get(ctx, obj, PDF_NAME(Subtype));
- if (pdf_name_eq(ctx, otype, PDF_NAME(Annot)))
- {
- if (pdf_name_eq(ctx, subtype, PDF_NAME(Link)))
- type = AUDIT_LINK_ANNOTATIONS;
- else if (pdf_name_eq(ctx, subtype, PDF_NAME(Text)))
- type = AUDIT_COMMENTS;
- else if (pdf_name_eq(ctx, subtype, PDF_NAME(FreeText)))
- type = AUDIT_COMMENTS;
- else if (pdf_name_eq(ctx, subtype, PDF_NAME(Popup)))
- type = AUDIT_COMMENTS;
- else if (pdf_name_eq(ctx, subtype, PDF_NAME(3D)))
- type = AUDIT_3DCONTENT;
- else if (pdf_name_eq(ctx, subtype, PDF_NAME(PieceInfo)))
- type = AUDIT_PIECE_INFORMATION;
- }
- else if (pdf_name_eq(ctx, otype, PDF_NAME(Font)))
- type = AUDIT_FONTS;
- else if (pdf_name_eq(ctx, otype, PDF_NAME(FontDescriptor)))
- type = AUDIT_FONTS;
- else if (pdf_name_eq(ctx, otype, PDF_NAME(XObject)))
- {
- if (pdf_name_eq(ctx, subtype, PDF_NAME(Image)))
- type = AUDIT_IMAGES;
- else if (pdf_name_eq(ctx, subtype, PDF_NAME(Form)))
- type = AUDIT_FORM_XOBJ;
- }
- else if (pdf_name_eq(ctx, otype, PDF_NAME(Page)))
- type = AUDIT_PAGE_OBJECTS;
- else if (pdf_name_eq(ctx, otype, PDF_NAME(Pages)))
- type = AUDIT_PAGE_OBJECTS;
- else if (pdf_name_eq(ctx, otype, PDF_NAME(Metadata)))
- type = AUDIT_METADATA;
- }
- ws->stack[ws->len].obj = obj;
- ws->stack[ws->len].pos = 0;
- ws->stack[ws->len].state = type;
- ws->len++;
- /* So we have stepped successfully onto obj. */
- /* Record its type. */
- if (type != AUDIT_UNKNOWN)
- {
- num = pdf_obj_parent_num(ctx, obj);
- oi[num].type = type;
- }
- /* Step onwards to any children. */
- if (pdf_is_dict(ctx, obj))
- {
- pdf_obj *key;
- /* We've just stepped onto a dict. */
- step_next_dict_child:
- if (ws->stack[ws->len-1].pos == pdf_dict_len(ctx, obj))
- goto pop;
- key = pdf_dict_get_key(ctx, ws->stack[ws->len-1].obj, ws->stack[ws->len-1].pos);
- ws->stack[ws->len-1].pos++;
- if (pdf_name_eq(ctx, key, PDF_NAME(Parent)))
- goto step_next_dict_child;
- if (pdf_name_eq(ctx, key, PDF_NAME(Thumb)))
- type = AUDIT_THUMBNAILS;
- else if (pdf_name_eq(ctx, key, PDF_NAME(Outlines)))
- type = AUDIT_BOOKMARKS;
- else if (pdf_name_eq(ctx, key, PDF_NAME(Contents)))
- type = AUDIT_CONTENT_STREAMS;
- else if (pdf_name_eq(ctx, key, PDF_NAME(StructTreeRoot)))
- type = AUDIT_STRUCTURE_INFO;
- else if (pdf_name_eq(ctx, key, PDF_NAME(AcroForm)))
- type = AUDIT_FORMS;
- else if (pdf_name_eq(ctx, key, PDF_NAME(ColorSpace)))
- type = AUDIT_COLORSPACES;
- else if (pdf_name_eq(ctx, key, PDF_NAME(CS)))
- type = AUDIT_COLORSPACES;
- else if (pdf_name_eq(ctx, key, PDF_NAME(Dests)))
- type = AUDIT_NAMED_DESTINATIONS;
- else if (pdf_name_eq(ctx, key, PDF_NAME(ExtGState)))
- type = AUDIT_EXTGS;
- else if (pdf_name_eq(ctx, key, PDF_NAME(Resources)))
- type = AUDIT_RESOURCES;
- else if (pdf_name_eq(ctx, key, PDF_NAME(EmbeddedFile)))
- type = AUDIT_EMBEDDED_FILES;
- else if (pdf_name_eq(ctx, key, PDF_NAME(Metadata)))
- type = AUDIT_METADATA;
- /* OK. step onto the val. */
- obj = pdf_dict_get_val(ctx, ws->stack[ws->len-1].obj, ws->stack[ws->len-1].pos-1);
- continue;
- }
- else if (pdf_is_array(ctx, obj))
- {
- step_next_array_child:
- if (ws->stack[ws->len-1].pos == pdf_array_len(ctx, obj))
- goto pop;
- obj = pdf_array_get(ctx, ws->stack[ws->len-1].obj, ws->stack[ws->len-1].pos);
- ws->stack[ws->len-1].pos++;
- continue;
- }
- /* Nothing more to do with this object. Pop back up. */
- pop:
- if (pdf_is_indirect(ctx, obj))
- {
- pdf_unmark_obj(ctx, obj);
- }
- ws->len--;
- visited:
- if (ws->len > 0)
- {
- /* We should either have stepped up to a dict or an array. */
- obj = ws->stack[ws->len-1].obj;
- type = ws->stack[ws->len-1].state;
- num = pdf_obj_parent_num(ctx, obj);
- if (pdf_is_dict(ctx, obj))
- goto step_next_dict_child;
- else if (pdf_is_array(ctx, obj))
- goto step_next_array_child;
- else
- assert("Never happens" == NULL);
- }
- }
- while (ws->len > 0);
- }
- static void
- classify_by_walking(fz_context *ctx, pdf_document *doc, int n, obj_info_t *oi)
- {
- walk_stack_t ws = { 0 };
- fz_try(ctx)
- walk(ctx, &ws, n, oi, pdf_trailer(ctx, doc), AUDIT_TRAILER);
- fz_always(ctx)
- fz_free(ctx, ws.stack);
- fz_catch(ctx)
- fz_rethrow(ctx);
- }
- static void
- output_size(fz_context *ctx, fz_output *out, uint64_t file_size, const char *str, uint64_t size, uint64_t size2)
- {
- fz_write_printf(ctx, out, "<tr align=right><td align=left>%s<td>%,ld<td>%.2f%%<td>%,ld<td>%.2f%%</tr>\n", str, size, 100.0f * size/file_size, size2, 100.0f * size2/file_size);
- }
- static void
- filter_file(fz_context *ctx, fz_output *out, const char *filename)
- {
- pdf_document *pdf = NULL;
- int i, n;
- pdf_obj *obj = NULL;
- obj_info_t *oi = NULL;
- op_usage_t ou = { 0 };
- fz_var(pdf);
- fz_var(obj);
- fz_var(i);
- fz_var(oi);
- fz_try(ctx)
- {
- pdf = pdf_open_document(ctx, filename);
- n = pdf_xref_len(ctx, pdf);
- oi = fz_malloc_array(ctx, n, obj_info_t);
- memset(oi, 0, n * sizeof(obj_info_t));
- for (i = 1; i < n; i++)
- {
- fz_try(ctx)
- {
- for (; i <n; i++)
- {
- pdf_xref_entry *entry = pdf_cache_object(ctx, pdf, i);
- int is_in_objstm = entry->type == 'o';
- pdf_obj *type, *subtype;
- char text[128];
- if (entry->obj == NULL)
- continue;
- oi[i].is_in_objstm = is_in_objstm;
- if (!is_in_objstm)
- {
- sprintf(text, "%d 0 obj\nendobj\n", i);
- oi[i].overhead = strlen(text);
- }
- else
- {
- sprintf(text, "%d %zd ", i, (size_t)entry->ofs);
- oi[i].overhead = strlen(text);
- }
- type = pdf_dict_get(ctx, entry->obj, PDF_NAME(Type));
- SWITCH (type)
- {
- CASE(PDF_NAME(ObjStm)):
- oi[i].type = AUDIT_OBJSTM;
- break;
- }
- subtype = pdf_dict_get(ctx, entry->obj, PDF_NAME(Subtype));
- SWITCH (subtype)
- {
- CASE(PDF_NAME(Image)):
- oi[i].type = AUDIT_IMAGES;
- break;
- }
- filter_obj(ctx, &oi[i], entry->obj);
- if (pdf_obj_num_is_stream(ctx, pdf, i))
- {
- filter_stream(ctx, pdf, i, &oi[i]);
- oi[i].stream_len = pdf_dict_get_int64(ctx, entry->obj, PDF_NAME(Length));
- }
- pdf_drop_obj(ctx, obj);
- obj = NULL;
- }
- }
- fz_catch(ctx)
- {
- i++;
- /* Swallow error */
- }
- }
- /* Walk the doc structure. */
- classify_by_walking(ctx, pdf, n, oi);
- /* Filter the content streams to establish operator usage */
- filter_page_streams(ctx, pdf, &ou);
- fz_write_printf(ctx, out, "<html><title>PDF Audit: %s</title><body>\n", filename);
- fz_write_printf(ctx, out, "<H1>Input file: %s</H1>\n", filename);
- fz_write_printf(ctx, out, "<p>Total file size: %,zd bytes</p>", pdf->file_size);
- fz_write_printf(ctx, out, "<H3>Total file usage</H3>\n");
- /* Sum the results */
- {
- struct {
- size_t obj;
- size_t objstm;
- } counts[AUDIT__MAX] = { 0 };
- size_t total_obj = 0;
- size_t total_objstm = 0;
- size_t overhead = 0;
- size_t objstm_overhead = 0;
- size_t total_stream_uncomp = 0;
- size_t total_stream_comp = 0;
- for (i = 1; i < n; i++)
- {
- size_t z = oi[i].textsize + oi[i].overhead + oi[i].stream_len;
- total_stream_uncomp += oi[i].len;
- total_stream_comp += oi[i].stream_len;
- if (oi[i].is_in_objstm)
- {
- objstm_overhead += oi[i].overhead;
- total_objstm += oi[i].textsize;
- counts[oi[i].type].objstm += z;
- }
- else
- {
- overhead += oi[i].overhead;
- total_obj += oi[i].textsize;
- counts[oi[i].type].obj += z;
- }
- }
- fz_write_printf(ctx, out, "<table border=1><thead><th><th colspan=2>not in objstms<th colspan=2>in objstms</thead>\n");
- output_size(ctx, out, pdf->file_size, "object text", total_obj, total_objstm);
- output_size(ctx, out, pdf->file_size, "object overhead", overhead, objstm_overhead);
- fz_write_printf(ctx, out, "<thead><th><th colspan=2>uncompressed<th colspan=2>compressed</thead>\n");
- output_size(ctx, out, pdf->file_size, "streams", total_stream_uncomp, total_stream_comp);
- fz_write_printf(ctx, out, "</table>\n");
- fz_write_printf(ctx, out, "<p>NOTE: The uncompressed streams percentage figure is misleading,"
- " as it is the percentage of the complete file which typically includes compression.</p>\n");
- fz_write_printf(ctx, out, "<table border=1><thead><th><th colspan=2>not in objstms<th colspan=2>in objstms</thead>\n");
- fz_write_printf(ctx, out, "<H3>Classified file usage</H3>\n");
- for (i = 0; i < AUDIT__MAX; i++)
- {
- output_size(ctx, out, pdf->file_size, audit_type[i], counts[i].obj, counts[i].objstm);
- }
- fz_write_printf(ctx, out, "</table>\n");
- fz_write_printf(ctx, out, "<p>NOTE: The percentages are as percentages of the complete file. This again means that"
- " the percentages in the "in objstms" column are misleading as the objstms are"
- " typically compressed!</p>\n");
- }
- /* List some unknown objects. */
- {
- int count = 0;
- for (i = 1; i < n; i++)
- {
- if (oi[i].type != AUDIT_UNKNOWN || oi[i].textsize == 0)
- continue;
- if (count == 0)
- fz_write_printf(ctx, out, "<p>Some objects still unknown: e.g. ");
- fz_write_printf(ctx, out, "%d ", i);
- count++;
- if (count == 10)
- break;
- }
- if (count > 0)
- fz_write_printf(ctx, out, "</p>\n");
- }
- /* Write out the operator usage */
- fz_write_printf(ctx, out, "<H3>Operator usage within streams</H3>\n");
- {
- size_t total = 0;
- for (i = 0; i < OP_END; i++)
- total += ou.len[i];
- fz_write_printf(ctx, out, "<table border=1><thead><th>Op<th>bytes<th></thead>\n");
- for (i = 0; i < OP_END; i++)
- {
- fz_write_printf(ctx, out, "<tr align=right><td align=left>%s<td>%,zd<td>%.2f%%</tr>\n", op_names[i], ou.len[i], 100.f * ou.len[i] / total);
- }
- fz_write_printf(ctx, out, "</table>\n");
- fz_write_printf(ctx, out, "<p>NOTE: The percentages are of the operator stream content found.</p>\n");
- }
- }
- fz_always(ctx)
- {
- pdf_drop_obj(ctx, obj);
- pdf_drop_document(ctx, pdf);
- fz_free(ctx, oi);
- }
- fz_catch(ctx)
- fz_rethrow(ctx);
- }
- static int usage(void)
- {
- fprintf(stderr,
- "usage: mutool audit [options] input.pdf+\n"
- "\t-o -\toutput file\n"
- );
- return 1;
- }
- int pdfaudit_main(int argc, char **argv)
- {
- char *outfile = "-";
- int c;
- int errors = 0;
- int append = 0;
- fz_context *ctx;
- fz_output *out = NULL;
- const fz_getopt_long_options longopts[] =
- {
- { NULL, NULL, NULL }
- };
- while ((c = fz_getopt_long(argc, argv, "o:", longopts)) != -1)
- {
- switch (c)
- {
- case 'o': outfile = fz_optarg; break;
- case 0:
- {
- SWITCH(fz_optlong->opaque)
- {
- // Any future long options go here.
- default:
- case 0:
- assert(!"Never happens");
- break;
- break;
- }
- }
- default: return usage();
- }
- }
- if (argc - fz_optind < 1)
- return usage();
- ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
- if (!ctx)
- {
- fprintf(stderr, "cannot initialise context\n");
- exit(1);
- }
- #ifdef _WIN32
- fz_set_stddbg(ctx, fz_stdods(ctx));
- #endif
- fz_var(out);
- fz_try(ctx)
- {
- if (strcmp(outfile, "-") == 0)
- out = fz_stdout(ctx);
- else
- out = fz_new_output_with_path(ctx, outfile, append);
- while (fz_optind < argc)
- filter_file(ctx, out, argv[fz_optind++]);
- if (strcmp(outfile, "-") != 0)
- fz_close_output(ctx, out);
- }
- fz_always(ctx)
- if (strcmp(outfile, "-") != 0)
- fz_drop_output(ctx, out);
- fz_catch(ctx)
- {
- fz_report_error(ctx);
- errors++;
- }
- fz_drop_context(ctx);
- return errors != 0;
- }
|