static fz_error * parseTTCs(char *path) { fz_error *err = nil; int byteread; fz_stream *file = nil; FONT_COLLECTION fontcollectioin; ULONG i; err = fz_openrfile(&file, path); if(err) goto cleanup; SAFE_FZ_READ(file, &fontcollectioin, sizeof(FONT_COLLECTION)); if(memcmp(fontcollectioin.Tag,"ttcf",sizeof(fontcollectioin.Tag)) == 0) { fontcollectioin.Version = SWAPLONG(fontcollectioin.Version); fontcollectioin.NumFonts = SWAPLONG(fontcollectioin.NumFonts); if( fontcollectioin.Version == TTC_VERSION1 || fontcollectioin.Version == TTC_VERSION2 ) { ULONG *offsettable = fz_malloc(sizeof(ULONG)*fontcollectioin.NumFonts); if(offsettable == nil) { err = fz_outofmem; goto cleanup; } SAFE_FZ_READ(file, offsettable, sizeof(ULONG)*fontcollectioin.NumFonts); for(i = 0; i < fontcollectioin.NumFonts; ++i) { offsettable[i] = SWAPLONG(offsettable[i]); parseTTF(file,offsettable[i],i,path); } fz_free(offsettable); } else { err = fz_throw("fonterror : invalid version"); goto cleanup; } } else { err = fz_throw("fonterror: wrong format"); goto cleanup; } cleanup: if(file) fz_dropstream(file); return err; }
static fz_error * parseTTFs(char *path) { fz_error *err = nil; fz_stream *file = nil; err = fz_openrfile(&file, path); if(err) goto cleanup; err = parseTTF(file,0,0,path); if(err) goto cleanup; cleanup: if(file) fz_dropstream(file); return err; }
int main(int argc, char **argv) { pdf_cmap *cmap; fz_error error; fz_stream *fi; FILE *fo; char name[256]; char *realname; int i, k; if (argc < 3) { fprintf(stderr, "usage: cmapdump output.c lots of cmap files\n"); return 1; } fo = fopen(argv[1], "wb"); if (!fo) { fprintf(stderr, "cmapdump: could not open output file\n"); return 1; } fprintf(fo, "#include \"fitz.h\"\n"); fprintf(fo, "#include \"mupdf.h\"\n"); fprintf(fo, "\n"); for (i = 2; i < argc; i++) { realname = strrchr(argv[i], '/'); if (!realname) realname = strrchr(argv[i], '\\'); if (realname) realname ++; else realname = argv[i]; if (strlen(realname) > (sizeof name - 1)) { fprintf(stderr, "cmapdump: file name too long\n"); return 1; } strcpy(name, realname); clean(name); error = fz_openrfile(&fi, argv[i]); if (error) { fz_catch(error, "cmapdump: could not open input file %s\n", argv[i]); return 1; } error = pdf_parsecmap(&cmap, fi); if (error) { fz_catch(error, "cmapdump: could not parse input cmap %s\n", argv[i]); return 1; } fprintf(fo, "/*\n * %s\n */\n\n", cmap->cmapname); fprintf(fo, "static const pdf_range pdf_cmap_%s_ranges[] =\n{\n", name); if (cmap->rlen == 0) { fprintf(fo, " /* dummy entry for non-c99 compilers */\n"); fprintf(fo, " { 0x0, 0x0, PDF_CMAP_RANGE, 0 }\n"); } for (k = 0; k < cmap->rlen; k++) { fprintf(fo, " { 0x%04x, 0x%04x, %s %d },\n", cmap->ranges[k].low, cmap->ranges[k].high, flagtoname(cmap->ranges[k].flag), cmap->ranges[k].offset); } fprintf(fo, "};\n\n"); if (cmap->tlen == 0) { fprintf(fo, "static const unsigned short pdf_cmap_%s_table[1] = { 0 };\n\n", name); } else { fprintf(fo, "static const unsigned short pdf_cmap_%s_table[%d] =\n{", name, cmap->tlen); for (k = 0; k < cmap->tlen; k++) { if (k % 8 == 0) fprintf(fo, "\n "); fprintf(fo, "%d, ", cmap->table[k]); } fprintf(fo, "\n};\n\n"); } fprintf(fo, "pdf_cmap pdf_cmap_%s =\n", name); fprintf(fo, "{\n"); fprintf(fo, " -1, "); fprintf(fo, "\"%s\", ", cmap->cmapname); fprintf(fo, "\"%s\", nil, ", cmap->usecmapname); fprintf(fo, "%d,\n", cmap->wmode); fprintf(fo, " %d, /* codespace table */\n", cmap->ncspace); fprintf(fo, " {\n"); if (cmap->ncspace == 0) { fprintf(fo, " /* dummy entry for non-c99 compilers */\n"); fprintf(fo, " { 0, 0x0, 0x0 },\n"); } for (k = 0; k < cmap->ncspace; k++) { fprintf(fo, "\t{ %d, 0x%04x, 0x%04x },\n", cmap->cspace[k].n, cmap->cspace[k].low, cmap->cspace[k].high); } fprintf(fo, " },\n"); fprintf(fo, " %d, %d, (pdf_range*) pdf_cmap_%s_ranges,\n", cmap->rlen, cmap->rlen, name); fprintf(fo, " %d, %d, (unsigned short*) pdf_cmap_%s_table,\n", cmap->tlen, cmap->tlen, name); fprintf(fo, "};\n\n"); fz_dropstream(fi); } return 0; }
fz_error pdf_loadxref(pdf_xref *xref, char *filename) { fz_error error; fz_obj *size; int i; char buf[65536]; /* yeowch! */ pdf_logxref("loadxref '%s' %p\n", filename, xref); error = fz_openrfile(&xref->file, filename); if (error) { return fz_rethrow(error, "cannot open file: '%s'", filename); } error = loadversion(xref); if (error) { error = fz_rethrow(error, "cannot read version marker"); goto cleanup; } error = readstartxref(xref); if (error) { error = fz_rethrow(error, "cannot read startxref"); goto cleanup; } error = readtrailer(xref, buf, sizeof buf); if (error) { error = fz_rethrow(error, "cannot read trailer"); goto cleanup; } size = fz_dictgets(xref->trailer, "Size"); if (!size) { error = fz_throw("trailer missing Size entry"); goto cleanup; } pdf_logxref(" size %d at 0x%x\n", fz_toint(size), xref->startxref); assert(xref->table == nil); xref->len = fz_toint(size); xref->cap = xref->len + 1; /* for hack to allow broken pdf generators with off-by-one errors */ xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry)); for (i = 0; i < xref->cap; i++) { xref->table[i].ofs = 0; xref->table[i].gen = 0; xref->table[i].stmofs = 0; xref->table[i].obj = nil; xref->table[i].type = 0; } error = readxrefsections(xref, xref->startxref, buf, sizeof buf); if (error) { error = fz_rethrow(error, "cannot read xref"); goto cleanup; } /* broken pdfs where first object is not free */ if (xref->table[0].type != 'f') { fz_warn("first object in xref is not free"); xref->table[0].type = 'f'; } /* broken pdfs where freed objects have offset and gen set to 0 but still exits */ for (i = 0; i < xref->len; i++) if (xref->table[i].type == 'n' && xref->table[i].ofs == 0 && xref->table[i].gen == 0 && xref->table[i].obj == nil) { fz_warn("object (%d %d R) has invalid offset, assumed missing", i, xref->table[i].gen); xref->table[i].type = 'f'; } return fz_okay; cleanup: fz_dropstream(xref->file); xref->file = nil; free(xref->table); xref->table = nil; return error; }