static void check_type_by_header(image_dict * idict) { int i; FILE *file = NULL; char header[MAX_HEADER]; char prefix[LEN_PDF_MEMSTREAM+1]; if (idict == NULL) return; if (img_type(idict) != IMG_TYPE_NONE) return; /*tex Here we read the and also check for a memstream object. */ if (!img_filepath(idict) || !FOPEN_RBIN_MODE) { normal_error("pdf backend","reading image file failed"); } file = fopen(img_filepath(idict), FOPEN_RBIN_MODE); if (file == NULL) { /*tex We check the prefix of img_filepath(idict). */ for (i = 0; (unsigned) i < LEN_PDF_MEMSTREAM; i++) { prefix[i] = (char) (img_filepath(idict)[i]); } prefix[LEN_PDF_MEMSTREAM]='\0'; if (strncmp(prefix, HEADER_PDF_MEMSTREAM, LEN_PDF_MEMSTREAM) == 0) { img_type(idict) = IMG_TYPE_PDFMEMSTREAM; return; } else { formatted_error("pdf backend","reading image file '%s' failed",img_filepath(idict)); } } /*tex Do we have a valid file but perhaps unsupported? */ for (i = 0; (unsigned) i < MAX_HEADER; i++) { header[i] = (char) xgetc(file); if (feof(file)) { normal_error("pdf backend","reading image file failed"); } } xfclose(file, img_filepath(idict)); /*tex Further tests: */ if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0) img_type(idict) = IMG_TYPE_JPG; else if (strncmp(header + 4, HEADER_JP2, sizeof(HEADER_JP2) - 1) == 0) img_type(idict) = IMG_TYPE_JP2; else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0) img_type(idict) = IMG_TYPE_PNG; else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0) img_type(idict) = IMG_TYPE_JBIG2; else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0) img_type(idict) = IMG_TYPE_PDF; }
void write_img(PDF pdf, image_dict * idict) { if (img_state(idict) < DICT_WRITTEN) { report_start_file(filetype_image, img_filepath(idict)); switch (img_type(idict)) { case IMG_TYPE_PNG: write_png(pdf, idict); break; case IMG_TYPE_JPG: write_jpg(pdf, idict); break; case IMG_TYPE_JP2: write_jp2(pdf, idict); break; case IMG_TYPE_JBIG2: write_jbig2(pdf, idict); break; case IMG_TYPE_PDFMEMSTREAM: case IMG_TYPE_PDF: write_epdf(pdf, idict,(int) pdf_suppress_optional_info); break; case IMG_TYPE_PDFSTREAM: write_pdfstream(pdf, idict); break; default: normal_error("pdf backend","internal error: writing unknown image type"); } report_stop_file(filetype_image); if (img_type(idict) == IMG_TYPE_PNG) { write_additional_png_objects(pdf); } } if (img_state(idict) < DICT_WRITTEN) img_state(idict) = DICT_WRITTEN; }
void check_pdfstream_dict(image_dict * idict) { if (!img_is_bbox(idict) && !img_nobbox(idict)) { normal_error("pdf backend","image.stream: no bbox given"); } if (img_state(idict) < DICT_FILESCANNED) { img_state(idict) = DICT_FILESCANNED; } }
static USHORT find_empty_slot(struct tt_glyphs *g) { USHORT gid; for (gid = 0; gid < NUM_GLYPH_LIMIT; gid++) { if (!(g->used_slot[gid / 8] & (1 << (7 - (gid % 8))))) break; } if (gid == NUM_GLYPH_LIMIT) normal_error("ttf","no empty glyph slot available."); return gid; }
static void set_textmatrix(PDF pdf, scaledpos pos) { boolean move; pdfstructure *p = pdf->pstruct; if (!is_textmode(p)) normal_error("pdf backend","text mode expected in set_textmatrix"); move = calc_pdfpos(p, pos); if (p->need_tm || move) { print_pdf_matrix(pdf, p->tm); pdf_puts(pdf, " Tm "); /*tex |Tm| replaces */ p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; p->pdf.v.m = p->pdf_bt_pos.v.m + p->tm[5].m; p->need_tm = false; } p->tm0_cur.m = p->tm[0].m; }
USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid) { if (g->used_slot[new_gid / 8] & (1 << (7 - (new_gid % 8)))) { formatted_warning("ttf","slot %u already used", new_gid); } else { if (g->num_glyphs + 1 >= NUM_GLYPH_LIMIT) normal_error("ttf","too many glyphs"); if (g->num_glyphs >= g->max_glyphs) { g->max_glyphs = (USHORT) (g->max_glyphs + GLYPH_ARRAY_ALLOC_SIZE); g->gd = RENEW(g->gd, g->max_glyphs, struct tt_glyph_desc); } g->gd[g->num_glyphs].gid = new_gid; g->gd[g->num_glyphs].ogid = gid; g->gd[g->num_glyphs].length = 0; g->gd[g->num_glyphs].data = NULL; g->used_slot[new_gid / 8] = (unsigned char) (g->used_slot[new_gid / 8] | (1 << (7 - (new_gid % 8)))); g->num_glyphs++; }
void free_image_dict(image_dict * p) { if (ini_version) { /*tex The image may be \.{\\dump}ed to a format. */ return; } /*tex Called from limglib.c. */ switch (img_type(p)) { case IMG_TYPE_PDFMEMSTREAM: case IMG_TYPE_PDF: flush_pdf_info(p); break; case IMG_TYPE_PNG: flush_png_info(p); break; case IMG_TYPE_JPG: flush_jpg_info(p); break; case IMG_TYPE_JP2: flush_jp2_info(p); break; case IMG_TYPE_JBIG2: flush_jbig2_info(p); break; case IMG_TYPE_PDFSTREAM: if (img_pdfstream_ptr(p) != NULL) { xfree(img_pdfstream_stream(p)); xfree(img_pdfstream_ptr(p)); } break; case IMG_TYPE_NONE: break; default: normal_error("pdf backend","unknown image type"); } free_dict_strings(p); xfree(p); }
static image_dict *read_image(char *file_name, int page_num, char *page_name, int colorspace, int page_box, char *user_password, char *owner_password, char *visible_filename) { image *a = new_image(); image_dict *idict = img_dict(a) = new_image_dict(); static_pdf->ximage_count++; img_objnum(idict) = pdf_create_obj(static_pdf, obj_type_ximage, static_pdf->ximage_count); img_index(idict) = static_pdf->ximage_count; set_obj_data_ptr(static_pdf, img_objnum(idict), img_index(idict)); idict_to_array(idict); img_colorspace(idict) = colorspace; img_pagenum(idict) = page_num; img_pagename(idict) = page_name; img_userpassword(idict) = user_password; img_ownerpassword(idict) = owner_password; img_visiblefilename(idict) = visible_filename; if (file_name == NULL) { normal_error("pdf backend","no image filename given"); } cur_file_name = file_name; img_filename(idict) = file_name; img_pagebox(idict) = page_box; read_img(idict); return idict; }
static void do_extension_pdf(int immediate) { int i; if(scan_keyword("literal")){ new_whatsit(pdf_literal_node); if(scan_keyword("direct")) set_pdf_literal_mode(tail,direct_always); else if(scan_keyword("page")) set_pdf_literal_mode(tail,direct_page); else set_pdf_literal_mode(tail,set_origin); scan_toks(false,true); set_pdf_literal_type(tail,normal); set_pdf_literal_data(tail,def_ref); }else if(scan_keyword("dest")){ scan_pdfdest(static_pdf); }else if(scan_keyword("annot")){ scan_annot(static_pdf); }else if(scan_keyword("save")){ new_whatsit(pdf_save_node); }else if(scan_keyword("restore")){ new_whatsit(pdf_restore_node); }else if(scan_keyword("setmatrix")){ new_whatsit(pdf_setmatrix_node); scan_toks(false,true); set_pdf_setmatrix_data(tail,def_ref); }else if(scan_keyword("obj")){ scan_obj(static_pdf); if(immediate){ if(obj_data_ptr(static_pdf,pdf_last_obj)==0) normal_error("pdf backend","\\pdfextension obj 'reserveobjnum' cannot be used with \\immediate"); pdf_write_obj(static_pdf,pdf_last_obj); } }else if(scan_keyword("refobj")){ scan_refobj(static_pdf); }else if(scan_keyword("colorstack")){ scan_int(); if(cur_val>=colorstackused()){ print_err("Unknown color stack number "); print_int(cur_val); help3 ("Allocate and initialize a color stack with \\pdfextension colorstackinit.", "I'll use default color stack 0 here.", "Proceed, with fingers crossed."); error(); cur_val= 0; } if(cur_val<0){ print_err("Invalid negative color stack number"); help2("I'll use default color stack 0 here.", "Proceed, with fingers crossed."); error(); cur_val= 0; } if(scan_keyword("set")) i= colorstack_set; else if(scan_keyword("push")) i= colorstack_push; else if(scan_keyword("pop")) i= colorstack_pop; else if(scan_keyword("current")) i= colorstack_current; else i= -1; if(i>=0){ new_whatsit(pdf_colorstack_node); set_pdf_colorstack_stack(tail,cur_val); set_pdf_colorstack_cmd(tail,i); set_pdf_colorstack_data(tail,null); if(i<=colorstack_data){ scan_toks(false,true); set_pdf_colorstack_data(tail,def_ref); } }else{ print_err("Color stack action is missing"); help3("The expected actions for \\pdfextension colorstack:", " set, push, pop, current", "I'll ignore the color stack command."); error(); } }else if(scan_keyword("startlink")){ scan_startlink(static_pdf); }else if(scan_keyword("endlink")){ if(abs(mode)==vmode) normal_error("pdf backend","\\pdfextension endlink cannot be used in vertical mode"); new_whatsit(pdf_end_link_node); }else if(scan_keyword("startthread")){ new_annot_whatsit(pdf_start_thread_node); scan_thread_id(); }else if(scan_keyword("endthread")){ new_whatsit(pdf_end_thread_node); }else if(scan_keyword("thread")){ new_annot_whatsit(pdf_thread_node); scan_thread_id(); }else if(scan_keyword("outline")){ scan_pdfoutline(static_pdf); }else if(scan_keyword("glyphtounicode")){ glyph_to_unicode(); }else if(scan_keyword("catalog")){ scan_pdfcatalog(static_pdf); }else if(scan_keyword("fontattr")){ scan_font_ident(); i= cur_val; if(i==null_font) normal_error("pdf backend","invalid font identifier"); scan_toks(false,true); set_pdf_font_attr(i,tokens_to_string(def_ref)); if(str_length(pdf_font_attr(i))==0){ flush_str((str_ptr-1)); set_pdf_font_attr(i,0); } }else if(scan_keyword("mapfile")){ scan_toks(false,true); pdfmapfile(def_ref); delete_token_ref(def_ref); }else if(scan_keyword("mapline")){ scan_toks(false,true); pdfmapline(def_ref); delete_token_ref(def_ref); }else if(scan_keyword("includechars")){ pdf_include_chars(static_pdf); }else if(scan_keyword("info")){ scan_toks(false,true); pdf_info_toks= concat_tokens(pdf_info_toks,def_ref); }else if(scan_keyword("names")){ scan_toks(false,true); pdf_names_toks= concat_tokens(pdf_names_toks,def_ref); }else if(scan_keyword("trailer")){ scan_toks(false,true); pdf_trailer_toks= concat_tokens(pdf_trailer_toks,def_ref); }else{ tex_error("unexpected use of \\pdfextension",null); } }
scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform) { /*tex size and resolution of image */ int x, y, xr, yr, tmp; /*tex natural size corresponding to image resolution */ scaled_whd nat; int default_res; nat.dp = 0; nat.wd = 0; nat.ht = 0; if (img_nobbox(idict)) { if (img_is_bbox(idict)) { x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; img_xorig(idict) = img_bbox(idict)[0]; img_yorig(idict) = img_bbox(idict)[1]; nat.wd = x; nat.ht = y; } else { normal_error("pdf backend","use boundingbox to pass dimensions"); } } else { if ((img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) { /*tex dimensions from image.bbox */ x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; img_xorig(idict) = img_bbox(idict)[0]; img_yorig(idict) = img_bbox(idict)[1]; } else { /*tex dimensions, resolutions from image file */ x = img_xsize(idict); y = img_ysize(idict); } xr = img_xres(idict); yr = img_yres(idict); if (x <= 0 || y <= 0 || xr < 0 || yr < 0) normal_error("pdf backend","invalid image dimensions"); if (xr > 65535 || yr > 65535) { xr = 0; yr = 0; normal_warning("pdf backend","too large image resolution ignored"); } if (((transform - img_rotation(idict)) & 1) == 1) { tmp = x; x = y; y = tmp; tmp = xr; xr = yr; yr = tmp; } /*tex always for images */ if (img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM || img_type(idict) == IMG_TYPE_PDFSTREAM) { nat.wd = x; nat.ht = y; } else { default_res = fix_int(pdf_image_resolution, 0, 65535); if (default_res > 0 && (xr == 0 || yr == 0)) { xr = default_res; yr = default_res; } if (xr > 0 && yr > 0) { nat.wd = ext_xn_over_d(one_hundred_inch, x, 100 * xr); nat.ht = ext_xn_over_d(one_hundred_inch, y, 100 * yr); } else { nat.wd = ext_xn_over_d(one_hundred_inch, x, 7200); nat.ht = ext_xn_over_d(one_hundred_inch, y, 7200); } } } return tex_scale(nat, alt_rule); }
void scan_pdfximage(PDF pdf) { scaled_whd alt_rule; image_dict *idict; int transform = 0, page = 1, pagebox, colorspace = 0; char *named = NULL, *attr = NULL, *file_name = NULL, *user = NULL, *owner = NULL, *visible = NULL; alt_rule = scan_alt_rule(); if (scan_keyword("attr")) { scan_toks(false, true); attr = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); } if (scan_keyword("named")) { scan_toks(false, true); if (0) { named = tokenlist_to_cstring(def_ref, true, NULL); page = 0; } else { normal_warning("pdf backend","named pages are not supported, using page 1"); page = 1; } delete_token_ref(def_ref); } else if (scan_keyword("page")) { scan_int(); page = cur_val; } if (scan_keyword("userpassword")) { scan_toks(false, true); user = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); } if (scan_keyword("ownerpassword")) { scan_toks(false, true); owner = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); } if (scan_keyword("visiblefilename")) { scan_toks(false, true); visible = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); } if (scan_keyword("colorspace")) { scan_int(); colorspace = cur_val; } pagebox = scan_pdf_box_spec(); if (pagebox == PDF_BOX_SPEC_NONE) { pagebox = pdf_pagebox; if (pagebox == PDF_BOX_SPEC_NONE) pagebox = PDF_BOX_SPEC_CROP; } scan_toks(false, true); file_name = tokenlist_to_cstring(def_ref, true, NULL); if (file_name == NULL) { normal_error("pdf backend","no image filename given"); } delete_token_ref(def_ref); idict = read_image(file_name, page, named, colorspace, pagebox, user, owner, visible); img_attr(idict) = attr; img_dimen(idict) = alt_rule; img_transform(idict) = transform; last_saved_image_index = img_objnum(idict); last_saved_image_pages = img_totalpages(idict); }
void read_img(image_dict * idict) { char *filepath = NULL; int callback_id; if (img_filename(idict) == NULL) { normal_error("pdf backend","image file name missing"); } callback_id = callback_defined(find_image_file_callback); if (img_filepath(idict) == NULL) { if (callback_id > 0) { /*tex We always callback, also for a mem stream. */ if (run_callback(callback_id, "S->S", img_filename(idict),&filepath)) { if (filepath && (strlen(filepath) > 0)) { img_filepath(idict) = strdup(filepath); } } } if (img_filepath(idict) == NULL && (strstr(img_filename(idict),"data:application/pdf,") != NULL)) { /*tex We need to check here for a pdf memstream. */ img_filepath(idict) = strdup(img_filename(idict)); } else if (callback_id == 0) { /*tex Otherwise we use kpse but only when we don't callback. */ img_filepath(idict) = kpse_find_file(img_filename(idict), kpse_tex_format, true); } if (img_filepath(idict) == NULL) { /*tex In any case we need a name. */ formatted_error("pdf backend","cannot find image file '%s'", img_filename(idict)); } } recorder_record_input(img_filepath(idict)); /*tex A few type checks. */ check_type_by_header(idict); check_type_by_extension(idict); /*tex Now we're ready to read the image. */ switch (img_type(idict)) { case IMG_TYPE_PDFMEMSTREAM: case IMG_TYPE_PDF: read_pdf_info(idict); break; case IMG_TYPE_PNG: read_png_info(idict); break; case IMG_TYPE_JPG: read_jpg_info(idict); break; case IMG_TYPE_JP2: read_jp2_info(idict); break; case IMG_TYPE_JBIG2: read_jbig2_info(idict); break; default: img_type(idict) = IMG_TYPE_NONE; if (pdf_ignore_unknown_images) { normal_warning("pdf backend","internal error: ignoring unknown image type"); } else { normal_error("pdf backend","internal error: unknown image type"); } break; } cur_file_name = NULL; if (img_type(idict) == IMG_TYPE_NONE) { img_state(idict) = DICT_NEW; } else if (img_state(idict) < DICT_FILESCANNED) { img_state(idict) = DICT_FILESCANNED; } }
inline static int run_put_next(lua_State * L) { int n = lua_gettop(L); int m = 0; int i = 0; halfword h = null; halfword t = null; halfword x = null; lua_token *p ; if (n == 0) { /* we accept a single nil argument */ return 0; } lua_get_metatablelua(luatex_token); m = lua_gettop(L); if (lua_type(L,1) == LUA_TTABLE) { if (n>1) { normal_error("token lib","only one table permitted in put_next"); } else { for (i = 1;; i++) { lua_rawgeti(L, 1, i); /* table mt token */ if (lua_type(L,-1) == LUA_TNIL) { break; } else { p = lua_touserdata(L, -1); if (p == NULL) { normal_error("token lib","lua <token> expected in put_next (1)"); } else if (!lua_getmetatable(L, -1)) { /* table mt token mt */ normal_error("token lib","lua <token> expected in put_next (2)"); } else if (!lua_rawequal(L, m, -1)) { normal_error("token lib","lua <token> expected in put_next (3)"); } else { fast_get_avail(x) ; token_info(x) = token_info(p->token); if (h == null) { h = x; } else { token_link(t) = x; } t = x; } lua_pop(L, 1); } } } } else { for (i = 1; i <= n; i++) { p = lua_touserdata(L,i); if (p == NULL) { normal_error("token lib","lua <token> expected in put_next (4)"); } else if (!lua_getmetatable(L, i)) { /* table mt token mt */ normal_error("token lib","lua <token> expected in put_next (5)"); } else if (!lua_rawequal(L, m, -1)) { normal_error("token lib","lua <token> expected in put_next (6)"); } else { fast_get_avail(x) ; token_info(x) = token_info(p->token); if (h == null) { h = x; } else { token_link(t) = x; } t = x; } lua_pop(L, 1); } } if (h == null) { /* can't happen */ } else { begin_token_list(h,0); } lua_settop(L,n); return 0; }