From 5ff1d6955496b3cf9a35042c9ac35db43bc336b1 Mon Sep 17 00:00:00 2001 From: Thomas Deutschmann Date: Tue, 30 Mar 2021 10:59:39 +0200 Subject: Import Ghostscript 9.54 Signed-off-by: Thomas Deutschmann --- Makefile.in | 43 +- Resource/CIDFont/ArtifexBullet | Bin 2659 -> 2664 bytes Resource/CMap/Identity-UTF16-H | 2 +- Resource/ColorSpace/DefaultCMYK | 2 +- Resource/ColorSpace/DefaultGray | 2 +- Resource/ColorSpace/DefaultRGB | 2 +- Resource/ColorSpace/TrivialCMYK | 2 +- Resource/ColorSpace/sGray | 2 +- Resource/ColorSpace/sRGB | 2 +- Resource/Decoding/FCO_Dingbats | 2 +- Resource/Decoding/FCO_Symbol | 2 +- Resource/Decoding/FCO_Unicode | 2 +- Resource/Decoding/FCO_Wingdings | 2 +- Resource/Decoding/Latin1 | 2 +- Resource/Decoding/StandardEncoding | 2 +- Resource/Decoding/Unicode | 2 +- Resource/Encoding/CEEncoding | 2 +- Resource/Encoding/ExpertEncoding | 2 +- Resource/Encoding/ExpertSubsetEncoding | 2 +- Resource/Encoding/NotDefEncoding | 2 +- Resource/Encoding/Wingdings | 2 +- Resource/IdiomSet/PPI_CUtils | 24 + Resource/Init/FCOfontmap-PCLPS2 | 2 +- Resource/Init/Fontmap.GS | 2 +- Resource/Init/gs_agl.ps | 2 +- Resource/Init/gs_btokn.ps | 2 +- Resource/Init/gs_cff.ps | 2 +- Resource/Init/gs_cidcm.ps | 2 +- Resource/Init/gs_ciddc.ps | 2 +- Resource/Init/gs_cidfm.ps | 2 +- Resource/Init/gs_cidfn.ps | 2 +- Resource/Init/gs_cidtt.ps | 2 +- Resource/Init/gs_cmap.ps | 2 +- Resource/Init/gs_cspace.ps | 2 +- Resource/Init/gs_dbt_e.ps | 2 +- Resource/Init/gs_diskn.ps | 2 +- Resource/Init/gs_dps1.ps | 2 +- Resource/Init/gs_dps2.ps | 2 +- Resource/Init/gs_dscp.ps | 2 +- Resource/Init/gs_epsf.ps | 76 +- Resource/Init/gs_fapi.ps | 2 +- Resource/Init/gs_fntem.ps | 2 +- Resource/Init/gs_fonts.ps | 2 +- Resource/Init/gs_frsd.ps | 24 +- Resource/Init/gs_icc.ps | 2 +- Resource/Init/gs_il1_e.ps | 2 +- Resource/Init/gs_img.ps | 2 +- Resource/Init/gs_init.ps | 15 +- Resource/Init/gs_lev2.ps | 2 +- Resource/Init/gs_ll3.ps | 2 +- Resource/Init/gs_mex_e.ps | 2 +- Resource/Init/gs_mgl_e.ps | 2 +- Resource/Init/gs_mro_e.ps | 2 +- Resource/Init/gs_pdf_e.ps | 2 +- Resource/Init/gs_pdfwr.ps | 15 +- Resource/Init/gs_res.ps | 2 +- Resource/Init/gs_resmp.ps | 2 +- Resource/Init/gs_setpd.ps | 2 +- Resource/Init/gs_statd.ps | 2 +- Resource/Init/gs_std_e.ps | 2 +- Resource/Init/gs_sym_e.ps | 2 +- Resource/Init/gs_trap.ps | 2 +- Resource/Init/gs_ttf.ps | 22 +- Resource/Init/gs_typ32.ps | 2 +- Resource/Init/gs_typ42.ps | 2 +- Resource/Init/gs_type1.ps | 2 +- Resource/Init/gs_wan_e.ps | 2 +- Resource/Init/pdf_base.ps | 62 +- Resource/Init/pdf_draw.ps | 120 +- Resource/Init/pdf_font.ps | 23 +- Resource/Init/pdf_main.ps | 520 +- Resource/Init/pdf_ops.ps | 101 +- Resource/Init/pdf_rbld.ps | 31 +- Resource/Init/pdf_sec.ps | 34 +- Resource/SubstCID/CNS1-WMode | 2 +- Resource/SubstCID/GB1-WMode | 2 +- Resource/SubstCID/Japan1-WMode | 2 +- Resource/SubstCID/Korea1-WMode | 2 +- arch/arch_autoconf.h.in | 2 +- arch/windows-arm-msvc.h | 2 +- arch/windows-x64-msvc.h | 2 +- arch/windows-x86-msvc.h | 2 +- base/all-arch.mak | 6 +- base/assert_.h | 2 +- base/bench.c | 2 +- base/bobbin.c | 4 +- base/bobbin.h | 2 +- base/cal.mak | 4 +- base/claptrap-impl.h | 2 +- base/claptrap-init.c | 2 +- base/claptrap-planar.c | 2 +- base/claptrap.c | 2 +- base/claptrap.h | 2 +- base/ctype_.h | 2 +- base/dirent_.h | 2 +- base/dos_.h | 2 +- base/echogs.c | 2 +- base/errno_.h | 2 +- base/ets.c | 6 +- base/ets.h | 4 +- base/ets_tm.h | 2 +- base/expat.mak | 6 +- base/fapi_bs.mak | 6 +- base/fapi_ft.c | 55 +- base/fapibstm.c | 4 +- base/fapiufst.c | 16 +- base/fcntl_.h | 2 +- base/freetype.mak | 10 +- base/gconf.c | 2 +- base/gconf.h | 2 +- base/gdbflags.h | 2 +- base/gdebug.h | 2 +- base/gdevabuf.c | 2 +- base/gdevbbox.c | 10 +- base/gdevbbox.h | 2 +- base/gdevdbit.c | 52 +- base/gdevdcrd.c | 2 +- base/gdevdcrd.h | 2 +- base/gdevddrw.c | 2 +- base/gdevddrw.h | 2 +- base/gdevdevn.c | 2 +- base/gdevdevn.h | 2 +- base/gdevdevnprn.h | 2 +- base/gdevdflt.c | 12 +- base/gdevdgbr.c | 2 +- base/gdevdrop.c | 2 +- base/gdevdsha.c | 12 +- base/gdevemap.c | 2 +- base/gdevepo.c | 68 +- base/gdevepo.h | 2 +- base/gdevflp.c | 19 +- base/gdevflp.h | 2 +- base/gdevhit.c | 2 +- base/gdevkrnlsclass.c | 45 +- base/gdevkrnlsclass.h | 5 +- base/gdevm1.c | 2 +- base/gdevm16.c | 2 +- base/gdevm2.c | 2 +- base/gdevm24.c | 2 +- base/gdevm32.c | 2 +- base/gdevm4.c | 2 +- base/gdevm40.c | 2 +- base/gdevm48.c | 2 +- base/gdevm56.c | 2 +- base/gdevm64.c | 2 +- base/gdevm8.c | 2 +- base/gdevmem.c | 16 +- base/gdevmem.h | 2 +- base/gdevmpla.c | 2 +- base/gdevmpla.h | 2 +- base/gdevmplt.c | 2 +- base/gdevmplt.h | 2 +- base/gdevmr1.c | 4 +- base/gdevmr2n.c | 2 +- base/gdevmr8n.c | 3 +- base/gdevmrop.h | 2 +- base/gdevmrun.c | 19 +- base/gdevmrun.h | 2 +- base/gdevmx.c | 2 +- base/gdevnfwd.c | 13 +- base/gdevnup.c | 593 + base/gdevnup.h | 48 + base/gdevoflt.c | 2 +- base/gdevoflt.h | 2 +- base/gdevp14.c | 1662 +- base/gdevp14.h | 10 +- base/gdevpccm.c | 2 +- base/gdevpccm.h | 2 +- base/gdevpipe.c | 2 +- base/gdevplnx.c | 2 +- base/gdevplnx.h | 2 +- base/gdevppla.c | 3 +- base/gdevppla.h | 2 +- base/gdevprn.c | 266 +- base/gdevprn.h | 6 +- base/gdevpxat.h | 2 +- base/gdevpxen.h | 2 +- base/gdevpxop.h | 2 +- base/gdevrops.c | 2 +- base/gdevsclass.c | 370 +- base/gdevsclass.h | 2 +- base/gdevvec.c | 2 +- base/gdevvec.h | 2 +- base/gen_ordered.c | 297 +- base/gen_ordered.h | 14 +- base/genarch.c | 2 +- base/genconf.c | 2 +- base/gendev.c | 2 +- base/genht.c | 2 +- base/gp.h | 2 +- base/gp_dosfe.c | 2 +- base/gp_dosfs.c | 2 +- base/gp_dvx.c | 2 +- base/gp_getnv.c | 2 +- base/gp_mktmp.c | 2 +- base/gp_msdll.c | 2 +- base/gp_msdos.c | 2 +- base/gp_mshdl.c | 2 +- base/gp_mslib.c | 2 +- base/gp_mspol.c | 2 +- base/gp_msprn.c | 2 +- base/gp_mswin.c | 2 +- base/gp_mswin.h | 2 +- base/gp_nsync.c | 2 +- base/gp_ntfs.c | 3 +- base/gp_nxpsprn.c | 2 +- base/gp_os2.c | 2 +- base/gp_os2.h | 2 +- base/gp_os2fs.c | 2 +- base/gp_os2pr.c | 2 +- base/gp_os9.c | 2 +- base/gp_paper.c | 2 +- base/gp_psync.c | 4 +- base/gp_stdia.c | 2 +- base/gp_stdin.c | 2 +- base/gp_strdl.c | 4 +- base/gp_unifn.c | 2 +- base/gp_unifs.c | 4 +- base/gp_unix.c | 2 +- base/gp_upapr.c | 2 +- base/gp_vms.c | 2 +- base/gp_wgetv.c | 2 +- base/gp_win32.c | 24 +- base/gp_winfs.c | 2 +- base/gp_winfs2.c | 2 +- base/gp_wpapr.c | 2 +- base/gp_wsync.c | 2 +- base/gp_wutf8.c | 2 +- base/gp_wxpsprn.cpp | 2 +- base/gpcheck.h | 2 +- base/gpgetenv.h | 2 +- base/gpmisc.c | 10 +- base/gpmisc.h | 2 +- base/gpsync.h | 2 +- base/gs.mak | 2 +- base/gs_dll_call.h | 2 +- base/gs_mgl_e.h | 2 +- base/gs_mro_e.h | 2 +- base/gsalloc.c | 8 +- base/gsalloc.h | 2 +- base/gsargs.c | 2 +- base/gsargs.h | 2 +- base/gsbitcom.c | 2 +- base/gsbitmap.h | 2 +- base/gsbitops.c | 2 +- base/gsbitops.h | 2 +- base/gsbittab.c | 2 +- base/gsbittab.h | 2 +- base/gsccode.h | 6 +- base/gsccolor.h | 4 +- base/gscdef.c | 2 +- base/gscdefs.h | 4 +- base/gscdevn.c | 2 +- base/gscdevn.h | 2 +- base/gscedata.c | 3888 ++-- base/gscedata.h | 2 +- base/gscencs.c | 2 +- base/gscencs.h | 2 +- base/gschar.c | 4 +- base/gschar.h | 2 +- base/gschar0.c | 2 +- base/gscicach.c | 30 +- base/gscicach.h | 2 +- base/gscie.c | 2 +- base/gscie.h | 2 +- base/gsciemap.c | 2 +- base/gscindex.h | 2 +- base/gsclipsr.c | 2 +- base/gsclipsr.h | 2 +- base/gscms.h | 20 +- base/gscolor.c | 2 +- base/gscolor.h | 2 +- base/gscolor1.c | 2 +- base/gscolor1.h | 2 +- base/gscolor2.c | 4 +- base/gscolor2.h | 2 +- base/gscolor3.c | 2 +- base/gscolor3.h | 2 +- base/gscompt.h | 2 +- base/gscoord.c | 2 +- base/gscoord.h | 2 +- base/gscparam.c | 2 +- base/gscpixel.c | 2 +- base/gscpixel.h | 2 +- base/gscpm.h | 2 +- base/gscrd.c | 2 +- base/gscrd.h | 2 +- base/gscrdp.c | 2 +- base/gscrdp.h | 2 +- base/gscrypt1.c | 2 +- base/gscrypt1.h | 2 +- base/gscscie.c | 2 +- base/gscsel.h | 2 +- base/gscsepr.c | 2 +- base/gscsepr.h | 2 +- base/gscspace.c | 32 +- base/gscspace.h | 6 +- base/gscssub.c | 2 +- base/gscssub.h | 2 +- base/gsdcolor.h | 2 +- base/gsdevice.c | 45 +- base/gsdevice.h | 2 +- base/gsdevmem.c | 2 +- base/gsdll.h | 2 +- base/gsdllwin.h | 2 +- base/gsdparam.c | 238 +- base/gsdps1.c | 11 +- base/gsdsrc.c | 2 +- base/gsdsrc.h | 2 +- base/gsequivc.c | 21 +- base/gsequivc.h | 4 +- base/gserrors.h | 2 +- base/gsexit.h | 2 +- base/gsfcid.c | 6 +- base/gsfcid2.c | 2 +- base/gsfcmap.c | 15 +- base/gsfcmap.h | 4 +- base/gsfcmap1.c | 2 +- base/gsflip.c | 2 +- base/gsflip.h | 2 +- base/gsfname.c | 2 +- base/gsfname.h | 2 +- base/gsfont.c | 2 +- base/gsfont.h | 2 +- base/gsfont0.c | 2 +- base/gsfont0c.c | 2 +- base/gsform1.h | 2 +- base/gsftopts.h | 2 +- base/gsfunc.c | 2 +- base/gsfunc.h | 2 +- base/gsfunc0.c | 2 +- base/gsfunc0.h | 2 +- base/gsfunc3.c | 2 +- base/gsfunc3.h | 2 +- base/gsfunc4.c | 26 +- base/gsfunc4.h | 2 +- base/gsgc.h | 2 +- base/gsgcache.c | 2 +- base/gsgcache.h | 2 +- base/gsgdata.c | 2 +- base/gsgdata.h | 2 +- base/gsgstate.c | 12 +- base/gsgstate.h | 2 +- base/gshsb.c | 2 +- base/gshsb.h | 2 +- base/gsht.c | 56 +- base/gsht.h | 2 +- base/gsht1.c | 13 +- base/gsht1.h | 2 +- base/gshtscr.c | 2 +- base/gshtx.c | 2 +- base/gshtx.h | 2 +- base/gsicc.c | 2 +- base/gsicc.h | 2 +- base/gsicc_blacktext.c | 108 + base/gsicc_blacktext.h | 34 + base/gsicc_cache.c | 43 +- base/gsicc_cache.h | 7 +- base/gsicc_cms.h | 2 +- base/gsicc_create.c | 59 +- base/gsicc_create.h | 4 +- base/gsicc_lcms2.c | 21 +- base/gsicc_lcms2mt.c | 35 +- base/gsicc_manage.c | 10 +- base/gsicc_manage.h | 4 +- base/gsicc_monitorcm.c | 2 +- base/gsicc_nocm.c | 2 +- base/gsicc_profilecache.c | 2 +- base/gsicc_profilecache.h | 2 +- base/gsicc_replacecm.c | 2 +- base/gsimage.c | 13 +- base/gsimage.h | 2 +- base/gsimpath.c | 2 +- base/gsinit.c | 2 +- base/gsio.h | 2 +- base/gsiodev.c | 2 +- base/gsiodevs.c | 2 +- base/gsiodisk.c | 8 +- base/gsioram.c | 2 +- base/gsiorom.c | 2 +- base/gsiorom.h | 2 +- base/gsipar3x.h | 2 +- base/gsiparam.h | 2 +- base/gsiparm3.h | 2 +- base/gsiparm4.h | 2 +- base/gsjconf.h | 2 +- base/gsjmorec.h | 2 +- base/gslib.c | 2 +- base/gslib.h | 2 +- base/gslibctx.c | 45 +- base/gslibctx.h | 2 +- base/gsline.c | 2 +- base/gsline.h | 2 +- base/gslparam.h | 2 +- base/gsmalloc.c | 12 +- base/gsmalloc.h | 2 +- base/gsmatrix.c | 2 +- base/gsmatrix.h | 4 +- base/gsmchunk.c | 28 +- base/gsmchunk.h | 2 +- base/gsmd5.c | 2 +- base/gsmd5.h | 2 +- base/gsmdebug.h | 2 +- base/gsmemory.c | 6 +- base/gsmemory.h | 2 +- base/gsmemraw.h | 2 +- base/gsmemret.c | 2 +- base/gsmemret.h | 2 +- base/gsmisc.c | 8 +- base/gsnamecl.c | 2 +- base/gsnamecl.h | 2 +- base/gsncdummy.c | 2 +- base/gsncdummy.h | 2 +- base/gsnogc.c | 2 +- base/gsnogc.h | 2 +- base/gsnotify.c | 2 +- base/gsnotify.h | 2 +- base/gsovrc.c | 21 +- base/gsovrc.h | 2 +- base/gspaint.c | 12 +- base/gspaint.h | 2 +- base/gsparam.c | 18 +- base/gsparam.h | 6 +- base/gsparam2.c | 2 +- base/gsparaml.c | 30 +- base/gsparams.c | 2 +- base/gsparams.h | 2 +- base/gsparamx.c | 2 +- base/gsparamx.h | 2 +- base/gspath.c | 4 +- base/gspath.h | 2 +- base/gspath1.c | 2 +- base/gspath2.h | 2 +- base/gspcolor.c | 2 +- base/gspcolor.h | 2 +- base/gspenum.h | 2 +- base/gspmdrv.c | 2 +- base/gspmdrv.h | 2 +- base/gspmdrv.rc | 4 +- base/gsptype1.c | 393 +- base/gsptype1.h | 2 +- base/gsptype2.c | 2 +- base/gsptype2.h | 2 +- base/gsrect.h | 2 +- base/gsrefct.h | 2 +- base/gsromfs0.c | 2 +- base/gsrop.c | 2 +- base/gsrop.h | 2 +- base/gsroprun.c | 2 +- base/gsroprun1.h | 2 +- base/gsroprun24.h | 2 +- base/gsroprun8.h | 2 +- base/gsropt.h | 2 +- base/gsroptab.c | 2 +- base/gsserial.c | 2 +- base/gsserial.h | 2 +- base/gsshade.c | 2 +- base/gsshade.h | 2 +- base/gssprintf.c | 16 +- base/gssprintf.h | 2 +- base/gsstate.c | 182 +- base/gsstate.h | 4 +- base/gsstrl.h | 2 +- base/gsstrtok.h | 2 +- base/gsstruct.h | 2 +- base/gsstype.h | 2 +- base/gstext.c | 81 +- base/gstext.h | 6 +- base/gstiffio.c | 17 +- base/gstiffio.h | 2 +- base/gstparam.h | 2 +- base/gstrans.c | 27 +- base/gstrans.h | 16 +- base/gstrap.c | 2 +- base/gstrap.h | 2 +- base/gstype1.c | 224 +- base/gstype1.h | 2 +- base/gstype2.c | 172 +- base/gstype42.c | 9 +- base/gstypes.h | 2 +- base/gsuid.h | 2 +- base/gsutil.c | 10 +- base/gsutil.h | 2 +- base/gswin.rc | 2 +- base/gsxfont.h | 2 +- base/gx.h | 2 +- base/gxacpath.c | 2 +- base/gxalloc.h | 2 +- base/gxalpha.h | 2 +- base/gxarith.h | 2 +- base/gxband.h | 2 +- base/gxbcache.c | 7 +- base/gxbcache.h | 2 +- base/gxbitfmt.h | 2 +- base/gxbitmap.h | 2 +- base/gxbitops.h | 2 +- base/gxblend.c | 36 +- base/gxblend.h | 6 +- base/gxblend1.c | 19 +- base/gxccache.c | 2 +- base/gxccman.c | 9 +- base/gxcdevn.h | 2 +- base/gxchar.c | 2 +- base/gxchar.h | 2 +- base/gxchrout.c | 2 +- base/gxchrout.h | 2 +- base/gxcht.c | 8 +- base/gxcid.h | 2 +- base/gxcie.h | 2 +- base/gxcindex.h | 2 +- base/gxclbits.c | 29 +- base/gxcldev.h | 16 +- base/gxclfile.c | 2 +- base/gxclimag.c | 52 +- base/gxclio.h | 2 +- base/gxclip.c | 10 +- base/gxclip.h | 2 +- base/gxclip2.c | 8 +- base/gxclip2.h | 2 +- base/gxclipm.c | 8 +- base/gxclipm.h | 2 +- base/gxclipsr.h | 2 +- base/gxclist.c | 154 +- base/gxclist.h | 21 +- base/gxcllzw.c | 2 +- base/gxclmem.c | 2 +- base/gxclmem.h | 2 +- base/gxclpage.c | 2 +- base/gxclpage.h | 2 +- base/gxclpath.c | 2 +- base/gxclpath.h | 2 +- base/gxclrast.c | 22 +- base/gxclread.c | 22 +- base/gxclrect.c | 15 +- base/gxclthrd.c | 4 +- base/gxclthrd.h | 2 +- base/gxclutil.c | 10 +- base/gxclzlib.c | 2 +- base/gxcmap.c | 6 +- base/gxcmap.h | 11 +- base/gxcolor2.h | 2 +- base/gxcomp.h | 6 +- base/gxcoord.h | 2 +- base/gxcpath.c | 2 +- base/gxcpath.h | 2 +- base/gxcspace.h | 18 +- base/gxctable.c | 2 +- base/gxctable.h | 2 +- base/gxcvalue.h | 2 +- base/gxdcconv.c | 2 +- base/gxdcconv.h | 2 +- base/gxdcolor.c | 34 +- base/gxdcolor.h | 6 +- base/gxdda.h | 2 +- base/gxdevbuf.h | 2 +- base/gxdevcli.h | 22 +- base/gxdevice.h | 10 +- base/gxdevmem.h | 2 +- base/gxdevndi.c | 2 +- base/gxdevrop.h | 2 +- base/gxdevsop.h | 41 +- base/gxdht.h | 9 +- base/gxdhtres.h | 2 +- base/gxdhtserial.c | 2 +- base/gxdhtserial.h | 2 +- base/gxdither.h | 2 +- base/gxdownscale.c | 2 +- base/gxdownscale.h | 2 +- base/gxdtfill.h | 2 +- base/gxfapi.c | 22 +- base/gxfapi.h | 12 +- base/gxfapiu.c | 2 +- base/gxfapiu.h | 2 +- base/gxfarith.h | 2 +- base/gxfcache.h | 4 +- base/gxfcid.h | 2 +- base/gxfcmap.h | 2 +- base/gxfcmap1.h | 2 +- base/gxfill.c | 2 +- base/gxfill.h | 2 +- base/gxfillsl.h | 2 +- base/gxfilltr.h | 2 +- base/gxfillts.h | 2 +- base/gxfixed.h | 2 +- base/gxfmap.h | 2 +- base/gxfont.h | 2 +- base/gxfont0.h | 2 +- base/gxfont0c.h | 2 +- base/gxfont1.h | 2 +- base/gxfont42.h | 2 +- base/gxfrac.h | 2 +- base/gxftype.h | 2 +- base/gxfunc.h | 2 +- base/gxgetbit.h | 2 +- base/gxgstate.h | 18 +- base/gxhintn.c | 2 +- base/gxhintn.h | 2 +- base/gxhintn1.c | 2 +- base/gxhldevc.c | 2 +- base/gxhldevc.h | 2 +- base/gxht.c | 2 +- base/gxht.h | 2 +- base/gxht_thresh.c | 2 +- base/gxht_thresh.h | 2 +- base/gxhtbit.c | 173 +- base/gxhttile.h | 2 +- base/gxhttype.h | 2 +- base/gxi12bit.c | 10 +- base/gxi16bit.c | 2 +- base/gxiclass.h | 2 +- base/gxicolor.c | 18 +- base/gxidata.c | 9 +- base/gxifast.c | 6 +- base/gximag3x.c | 15 +- base/gximag3x.h | 2 +- base/gximage.c | 2 +- base/gximage.h | 4 +- base/gximage1.c | 2 +- base/gximage3.c | 7 +- base/gximage3.h | 2 +- base/gximage4.c | 2 +- base/gximask.c | 2 +- base/gximask.h | 2 +- base/gximdecode.c | 4 +- base/gximdecode.h | 2 +- base/gximono.c | 3 +- base/gxiodev.h | 2 +- base/gxiparam.h | 2 +- base/gxipixel.c | 26 +- base/gxiscale.c | 147 +- base/gxline.h | 2 +- base/gxlum.h | 2 +- base/gxmatrix.h | 2 +- base/gxmclip.c | 2 +- base/gxmclip.h | 2 +- base/gxobj.h | 2 +- base/gxoprect.c | 2 +- base/gxoprect.h | 2 +- base/gxp1fill.c | 2 +- base/gxp1impl.h | 2 +- base/gxpaint.c | 22 +- base/gxpaint.h | 2 +- base/gxpath.c | 2 +- base/gxpath.h | 12 +- base/gxpath2.c | 2 +- base/gxpcache.h | 2 +- base/gxpcmap.c | 4 +- base/gxpcolor.h | 2 +- base/gxpcopy.c | 6 +- base/gxpdash.c | 2 +- base/gxpflat.c | 2 +- base/gxrplane.h | 2 +- base/gxsample.c | 2 +- base/gxsample.h | 2 +- base/gxsamplp.h | 2 +- base/gxscanc.c | 18 +- base/gxscanc.h | 2 +- base/gxshade.c | 2 +- base/gxshade.h | 2 +- base/gxshade1.c | 6 +- base/gxshade4.c | 2 +- base/gxshade4.h | 2 +- base/gxshade6.c | 15 +- base/gxstate.h | 2 +- base/gxstdio.h | 2 +- base/gxstroke.c | 2 +- base/gxsync.c | 2 +- base/gxsync.h | 2 +- base/gxtext.h | 5 +- base/gxtmap.h | 2 +- base/gxttf.h | 2 +- base/gxttfb.c | 2 +- base/gxttfb.h | 2 +- base/gxtype1.c | 2 +- base/gxtype1.h | 2 +- base/gxxfont.h | 2 +- base/gzacpath.h | 2 +- base/gzcpath.h | 2 +- base/gzht.h | 2 +- base/gzline.h | 2 +- base/gzpath.h | 2 +- base/gzspotan.c | 2 +- base/gzspotan.h | 2 +- base/gzstate.h | 2 +- base/icc34.h | 192 +- base/ijs.mak | 6 +- base/instcopy | 2 +- base/jbig2.mak | 8 +- base/jerror_.h | 2 +- base/jmemcust.c | 2 +- base/jmemcust.h | 2 +- base/jpeg.mak | 6 +- base/jpegxr.mak | 4 +- base/lcms2.mak | 2 +- base/lcms2mt.mak | 2 +- base/lcups.mak | 12 +- base/lcupsi.mak | 36 +- base/ldf_jb2.mak | 497 - base/leptonica.mak | 4 - base/lib.mak | 161 +- base/locale_.h | 2 +- base/lwf_jp2.mak | 397 - base/malloc_.h | 2 +- base/math_.h | 2 +- base/memento.c | 497 +- base/memento.h | 38 +- base/memory_.h | 2 +- base/mkromfs.c | 51 +- base/msvccmd.mak | 12 +- base/msvclib.mak | 125 +- base/msvctail.mak | 2 +- base/ocr.mak | 4 +- base/openjpeg.mak | 8 +- base/openvms.mak | 2 +- base/openvms.mmk | 2 +- base/pack_ps.c | 4 +- base/pcwin.mak | 2 +- base/pipe_.h | 2 +- base/png.mak | 4 +- base/png_.h | 2 +- base/ramfs.c | 2 +- base/ramfs.h | 2 +- base/sa85d.c | 8 +- base/sa85d.h | 2 +- base/sa85x.h | 2 +- base/saes.c | 2 +- base/saes.h | 2 +- base/sarc4.c | 2 +- base/sarc4.h | 2 +- base/sbcp.c | 2 +- base/sbcp.h | 2 +- base/sbtx.h | 2 +- base/scanchar.h | 2 +- base/scantab.c | 2 +- base/scf.h | 2 +- base/scfd.c | 615 +- base/scfdgen.c | 2 +- base/scfdtab.c | 2 +- base/scfe.c | 2 +- base/scfetab.c | 2 +- base/scfparam.c | 2 +- base/scfx.h | 2 +- base/scommon.h | 39 +- base/sdcparam.c | 2 +- base/sdcparam.h | 2 +- base/sdct.h | 2 +- base/sdctc.c | 6 +- base/sdctd.c | 48 +- base/sdcte.c | 10 +- base/sddparam.c | 2 +- base/sdeparam.c | 2 +- base/seexec.c | 2 +- base/setjmp_.h | 2 +- base/sfilter.h | 2 +- base/sfilter1.c | 2 +- base/sfilter2.c | 167 +- base/sfxboth.c | 2 +- base/sfxcommon.c | 2 +- base/sfxfd.c | 2 +- base/sfxstdio.c | 2 +- base/shc.c | 2 +- base/shc.h | 2 +- base/sidscale.c | 12 +- base/sidscale.h | 2 +- base/siinterp.c | 2 +- base/siinterp.h | 2 +- base/simscale.c | 2 +- base/simscale.h | 2 +- base/simscale_foo.c | 4 +- base/simscale_foo.h | 2 +- base/siscale.c | 8 +- base/siscale.h | 2 +- base/siscale_cal.c | 2 +- base/sisparam.h | 2 +- base/sjbig2.c | 2 +- base/sjbig2.h | 2 +- base/sjbig2_luratech.c | 627 - base/sjbig2_luratech.h | 87 - base/sjpeg.h | 2 +- base/sjpegc.c | 6 +- base/sjpegd.c | 4 +- base/sjpege.c | 2 +- base/sjpx_luratech.c | 1096 -- base/sjpx_luratech.h | 103 - base/sjpx_none.c | 2 +- base/sjpx_openjpeg.c | 58 +- base/sjpx_openjpeg.h | 4 +- base/slzwc.c | 2 +- base/slzwd.c | 392 +- base/slzwe.c | 2 +- base/slzwx.h | 2 +- base/smd5.c | 2 +- base/smd5.h | 2 +- base/smtf.h | 2 +- base/spdiff.c | 2 +- base/spdiffx.h | 2 +- base/spngp.c | 2 +- base/spngpx.h | 2 +- base/spprint.c | 2 +- base/spprint.h | 2 +- base/spsdf.c | 10 +- base/spsdf.h | 2 +- base/spwgd.c | 2 +- base/spwgx.h | 2 +- base/srdline.h | 2 +- base/srld.c | 2 +- base/srle.c | 2 +- base/srlx.h | 2 +- base/ssha2.c | 2 +- base/ssha2.h | 2 +- base/sstring.c | 145 +- base/sstring.h | 2 +- base/stat_.h | 2 +- base/std.h | 2 +- base/stdint_.h | 2 +- base/stdio_.h | 2 +- base/stdpre.h | 2 +- base/stream.c | 11 +- base/stream.h | 2 +- base/strimpl.h | 2 +- base/string_.h | 2 +- base/strmio.c | 2 +- base/strmio.h | 2 +- base/stub.mak | 2 +- base/szlibc.c | 2 +- base/szlibd.c | 2 +- base/szlibe.c | 2 +- base/szlibx.h | 2 +- base/szlibxx.h | 2 +- base/tesseract.mak | 28 +- base/tessocr.cpp | 394 +- base/tessocr.h | 70 +- base/tiff.mak | 8 +- base/time_.h | 2 +- base/ttcalc.c | 2 +- base/ttcalc.h | 2 +- base/ttcommon.h | 2 +- base/ttconf.h | 2 +- base/ttconfig.h | 2 +- base/ttfinp.c | 2 +- base/ttfinp.h | 2 +- base/ttfmain.c | 2 +- base/ttfmemd.c | 2 +- base/ttfmemd.h | 2 +- base/ttfoutl.h | 2 +- base/ttfsfnt.h | 2 +- base/ttinterp.c | 2 +- base/ttinterp.h | 2 +- base/ttload.c | 2 +- base/ttload.h | 2 +- base/ttmisc.h | 2 +- base/ttobjs.c | 2 +- base/ttobjs.h | 2 +- base/tttables.h | 2 +- base/tttype.h | 2 +- base/tttypes.h | 2 +- base/ugcclib.mak | 2 +- base/unistd_.h | 2 +- base/unix-aux.mak | 2 +- base/unix-dll.mak | 72 +- base/unix-end.mak | 2 +- base/unix-gcc.mak | 21 +- base/unixansi.mak | 2 +- base/unixhead.mak | 2 +- base/unixinst.mak | 6 +- base/unixlink.mak | 2 +- base/valgrind.h | 2 +- base/version.mak | 8 +- base/vms_x_fix.h | 2 +- base/vmsmath.h | 2 +- base/windows_.h | 2 +- base/winlib.mak | 11 +- base/winplat.mak | 4 +- base/winrtsup.cpp | 2 +- base/winrtsup.h | 2 +- base/wrfont.c | 2 +- base/wrfont.h | 2 +- base/write_t1.c | 2 +- base/write_t1.h | 2 +- base/write_t2.c | 20 +- base/write_t2.h | 2 +- base/x_.h | 2 +- base/zlib.mak | 7 +- config.guess | 582 +- config.sub | 2572 +-- configure | 255 +- configure.ac | 184 +- contrib/contrib.mak | 9 +- contrib/gdevadmp.c | 2 +- contrib/gdevdj9.c | 2 +- contrib/gdevlx32.c | 79 +- contrib/lips4/gdevl4r.c | 2 +- contrib/pcl3/eprn/gdeveprn.c | 1 + cups/cups.mak | 2 +- cups/gdevcups.c | 6 +- cups/libs/images/color-wheel.png | Bin 0 -> 16384 bytes cups/libs/images/cups-block-diagram.png | Bin 0 -> 76386 bytes cups/libs/images/cups-block-diagram.svg | 841 + cups/libs/images/cups-command-chain.png | Bin 0 -> 14902 bytes cups/libs/images/cups-command-chain.svg | 439 + cups/libs/images/cups-icon.png | Bin 0 -> 4888 bytes cups/libs/images/cups-postscript-chain.png | Bin 0 -> 17498 bytes cups/libs/images/cups-postscript-chain.svg | 531 + cups/libs/images/cups-raster-chain.png | Bin 0 -> 16916 bytes cups/libs/images/cups-raster-chain.svg | 534 + cups/libs/images/cups.png | Bin 0 -> 4888 bytes cups/libs/images/cups.svg | 533 + cups/libs/images/left.gif | Bin 0 -> 1492 bytes cups/libs/images/left.xcf.gz | Bin 0 -> 1194 bytes cups/libs/images/raster-organization.png | Bin 0 -> 20974 bytes cups/libs/images/raster-organization.svg | 189 + cups/libs/images/raster.png | Bin 0 -> 37656 bytes cups/libs/images/raster.svg | 386 + cups/libs/images/right.gif | Bin 0 -> 341 bytes cups/libs/images/sample-image.png | Bin 0 -> 3541 bytes cups/libs/images/sel.gif | Bin 0 -> 362 bytes cups/libs/images/smiley.jpg | Bin 0 -> 14120 bytes cups/libs/images/unsel.gif | Bin 0 -> 127 bytes cups/libs/images/wait.gif | Bin 0 -> 1810 bytes cups/libs/images/webinterface.png | Bin 0 -> 150003 bytes demos/c/Makefile | 12 + demos/c/api_test.c | 31 +- demos/csharp/api/ghostapi.cs | 109 +- demos/csharp/api/ghostnet.cs | 497 +- .../csharp/windows/ghostnet_wpf_example/DocPage.cs | 10 +- .../windows/ghostnet_wpf_example/MainPrint.cs | 83 +- .../windows/ghostnet_wpf_example/MainRender.cs | 158 +- .../ghostnet_wpf_example/MainThumbRendering.cs | 23 +- .../ghostnet_wpf_example/MainWindow.xaml.cs | 164 +- .../windows/ghostnet_wpf_example/MainZoom.cs | 47 +- .../windows/ghostnet_wpf_example/PrintStatus.xaml | 21 + .../ghostnet_wpf_example/PrintStatus.xaml.cs | 27 + .../ghostnet_simple_viewer.csproj | 41 +- demos/java/gsjava/.classpath | 6 + demos/java/gsjava/.project | 17 + demos/java/gsjava/README.txt | 149 + .../java/gsjava/src/com/artifex/gsjava/GSAPI.java | 284 + .../gsjava/src/com/artifex/gsjava/GSInstance.java | 320 + .../artifex/gsjava/callbacks/DisplayCallback.java | 75 + .../artifex/gsjava/callbacks/ICalloutFunction.java | 7 + .../artifex/gsjava/callbacks/IPollFunction.java | 7 + .../artifex/gsjava/callbacks/IStdErrFunction.java | 15 + .../artifex/gsjava/callbacks/IStdInFunction.java | 15 + .../artifex/gsjava/callbacks/IStdOutFunction.java | 16 + .../src/com/artifex/gsjava/devices/BMPDevice.java | 18 + .../src/com/artifex/gsjava/devices/Device.java | 308 + .../gsjava/devices/DeviceInUseException.java | 17 + .../devices/DeviceNotSupportedException.java | 28 + .../com/artifex/gsjava/devices/DisplayDevice.java | 55 + .../src/com/artifex/gsjava/devices/EPSDevice.java | 9 + .../src/com/artifex/gsjava/devices/FAXDevice.java | 18 + .../src/com/artifex/gsjava/devices/FileDevice.java | 36 + .../artifex/gsjava/devices/HighLevelDevice.java | 13 + .../src/com/artifex/gsjava/devices/JPEGDevice.java | 19 + .../src/com/artifex/gsjava/devices/OCRDevice.java | 24 + .../src/com/artifex/gsjava/devices/PCXDevice.java | 17 + .../src/com/artifex/gsjava/devices/PDFDevice.java | 90 + .../com/artifex/gsjava/devices/PDFImageDevice.java | 19 + .../gsjava/devices/PDFPostscriptDeviceFamily.java | 340 + .../src/com/artifex/gsjava/devices/PNGDevice.java | 36 + .../src/com/artifex/gsjava/devices/PNMDevice.java | 25 + .../src/com/artifex/gsjava/devices/PSDDevice.java | 17 + .../src/com/artifex/gsjava/devices/PXLDevice.java | 17 + .../artifex/gsjava/devices/PostScriptDevice.java | 59 + .../src/com/artifex/gsjava/devices/TIFFDevice.java | 80 + .../src/com/artifex/gsjava/devices/TextDevice.java | 14 + .../src/com/artifex/gsjava/devices/XPSDevice.java | 9 + .../com/artifex/gsjava/util/AllocationError.java | 33 + .../artifex/gsjava/util/ByteArrayReference.java | 23 + .../src/com/artifex/gsjava/util/BytePointer.java | 68 + .../src/com/artifex/gsjava/util/NativeArray.java | 67 + .../src/com/artifex/gsjava/util/NativePointer.java | 157 + .../src/com/artifex/gsjava/util/Reference.java | 45 + .../src/com/artifex/gsjava/util/StringUtil.java | 41 + demos/java/gstest/.classpath | 7 + demos/java/gstest/.project | 17 + demos/java/gstest/src/gstest/Main.java | 41 + demos/java/gsviewer/.classpath | 7 + demos/java/gsviewer/.project | 17 + demos/java/gsviewer/README.txt | 4 + .../gsviewer/DefaultUnhandledExceptionHandler.java | 107 + .../src/com/artifex/gsviewer/Document.java | 1075 ++ .../src/com/artifex/gsviewer/GSFileFilter.java | 50 + .../src/com/artifex/gsviewer/ImageUtil.java | 45 + .../gsviewer/src/com/artifex/gsviewer/Main.java | 42 + .../src/com/artifex/gsviewer/PDFFileFilter.java | 28 + .../gsviewer/src/com/artifex/gsviewer/Page.java | 359 + .../com/artifex/gsviewer/PageUpdateCallback.java | 15 + .../src/com/artifex/gsviewer/Settings.java | 142 + .../gsviewer/src/com/artifex/gsviewer/StdIO.java | 38 + .../src/com/artifex/gsviewer/ViewerController.java | 372 + .../src/com/artifex/gsviewer/gui/ScrollMap.java | 142 + .../com/artifex/gsviewer/gui/SettingsDialog.java | 241 + .../artifex/gsviewer/gui/ViewerGUIListener.java | 61 + .../src/com/artifex/gsviewer/gui/ViewerWindow.java | 1020 + demos/java/jni/gs_jni/callbacks.cpp | 368 + demos/java/jni/gs_jni/callbacks.h | 54 + demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp | 555 + demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h | 386 + .../com_artifex_gsjava_util_NativePointer.cpp | 131 + .../gs_jni/com_artifex_gsjava_util_NativePointer.h | 169 + demos/java/jni/gs_jni/dllmain.cpp | 19 + demos/java/jni/gs_jni/framework.h | 5 + demos/java/jni/gs_jni/gs_jni.sln | 31 + demos/java/jni/gs_jni/gs_jni.vcxproj | 184 + demos/java/jni/gs_jni/gs_jni.vcxproj.filters | 51 + .../java/jni/gs_jni/include/classfile_constants.h | 560 + demos/java/jni/gs_jni/include/jawt.h | 299 + demos/java/jni/gs_jni/include/jdwpTransport.h | 259 + demos/java/jni/gs_jni/include/jni.h | 1964 ++ demos/java/jni/gs_jni/include/jvmti.h | 2533 +++ demos/java/jni/gs_jni/include/jvmticmlr.h | 115 + .../include/win32/bridge/AccessBridgeCallbacks.h | 96 + .../include/win32/bridge/AccessBridgeCalls.c | 1131 ++ .../include/win32/bridge/AccessBridgeCalls.h | 706 + .../include/win32/bridge/AccessBridgePackages.h | 2215 +++ demos/java/jni/gs_jni/include/win32/jawt_md.h | 59 + demos/java/jni/gs_jni/include/win32/jni_md.h | 37 + demos/java/jni/gs_jni/jni_util.cpp | 593 + demos/java/jni/gs_jni/jni_util.h | 377 + demos/python/gsapiwrap.py | 699 - demos/python/jlib.py | 1355 -- devices/dcontrib.mak | 2 +- devices/devs.mak | 75 +- devices/extract.mak | 48 + devices/gdev3852.c | 2 +- devices/gdev4081.c | 2 +- devices/gdev8510.c | 2 +- devices/gdev8bcm.c | 2 +- devices/gdev8bcm.h | 2 +- devices/gdevatx.c | 2 +- devices/gdevbit.c | 7 +- devices/gdevbj10.c | 2 +- devices/gdevbjc.h | 2 +- devices/gdevbjcl.c | 2 +- devices/gdevbjcl.h | 2 +- devices/gdevbmp.c | 2 +- devices/gdevbmp.h | 2 +- devices/gdevbmpc.c | 2 +- devices/gdevccr.c | 2 +- devices/gdevcdj.c | 2 +- devices/gdevcfax.c | 2 +- devices/gdevchameleon.c | 2 +- devices/gdevcif.c | 2 +- devices/gdevclj.c | 2 +- devices/gdevcljc.c | 2 +- devices/gdevcmykog.c | 8 +- devices/gdevcslw.c | 2 +- devices/gdevdfax.c | 2 +- devices/gdevdjet.c | 2 +- devices/gdevdjtc.c | 2 +- devices/gdevdljm.c | 2 +- devices/gdevdljm.h | 2 +- devices/gdevdm24.c | 2 +- devices/gdevdsp.c | 87 +- devices/gdevdsp.h | 2 +- devices/gdevdsp2.h | 2 +- devices/gdevepsc.c | 6 +- devices/gdevepsn.c | 8 +- devices/gdevescp.c | 2 +- devices/gdevfax.c | 4 +- devices/gdevfax.h | 2 +- devices/gdevfpng.c | 2 +- devices/gdevhl7x.c | 2 +- devices/gdevicov.c | 8 +- devices/gdevijs.c | 2 +- devices/gdevimgn.c | 2 +- devices/gdevjbig2.c | 128 - devices/gdevjpeg.c | 2 +- devices/gdevjpx.c | 229 - devices/gdevl31s.c | 2 +- devices/gdevlbp8.c | 2 +- devices/gdevlj56.c | 2 +- devices/gdevlp8k.c | 2 +- devices/gdevlxm.c | 4 +- devices/gdevmeds.c | 2 +- devices/gdevmeds.h | 2 +- devices/gdevmgr.c | 2 +- devices/gdevmgr.h | 2 +- devices/gdevmiff.c | 2 +- devices/gdevn533.c | 2 +- devices/gdevo182.c | 2 +- devices/gdevocr.c | 58 +- devices/gdevokii.c | 2 +- devices/gdevpbm.c | 2 +- devices/gdevpcl.c | 2 +- devices/gdevpcl.h | 2 +- devices/gdevpcx.c | 2 +- devices/gdevpdfimg.c | 42 +- devices/gdevpdfimg.h | 13 +- devices/gdevpdfocr.c | 64 +- devices/gdevpe.c | 2 +- devices/gdevperm.c | 2 +- devices/gdevphex.c | 2 +- devices/gdevpjet.c | 2 +- devices/gdevplan.c | 2 +- devices/gdevplib.c | 2 +- devices/gdevplib.h | 2 +- devices/gdevpm.h | 2 +- devices/gdevpng.c | 2 +- devices/gdevpsd.c | 75 +- devices/gdevpsd.h | 2 +- devices/gdevpsim.c | 2 +- devices/gdevpxut.c | 4 +- devices/gdevpxut.h | 2 +- devices/gdevrinkj.c | 2 +- devices/gdevsj48.c | 2 +- devices/gdevsnfb.c | 2 +- devices/gdevsppr.c | 2 +- devices/gdevstc.c | 2 +- devices/gdevstc.h | 2 +- devices/gdevstc1.c | 2 +- devices/gdevstc2.c | 2 +- devices/gdevstc3.c | 2 +- devices/gdevstc4.c | 2 +- devices/gdevtfax.c | 2 +- devices/gdevtfax.h | 2 +- devices/gdevtfnx.c | 2 +- devices/gdevtifs.c | 2 +- devices/gdevtifs.h | 2 +- devices/gdevtknk.c | 2 +- devices/gdevtrac.c | 2 +- devices/gdevtsep.c | 10 +- devices/gdevupd.c | 2 +- devices/gdevwpr2.c | 10 +- devices/gdevx.c | 21 +- devices/gdevx.h | 6 +- devices/gdevxalt.c | 2 +- devices/gdevxcf.c | 4 +- devices/gdevxcmp.c | 2 +- devices/gdevxcmp.h | 2 +- devices/gdevxini.c | 32 +- devices/gdevxres.c | 2 +- devices/gxfcopy.c | 100 +- devices/gxfcopy.h | 2 +- devices/minftrsz.c | 2 +- devices/minftrsz.h | 2 +- devices/rinkj/evenbetter-rll.c | 2 +- devices/rinkj/evenbetter-rll.h | 2 +- devices/rinkj/rinkj-byte-stream.c | 2 +- devices/rinkj/rinkj-byte-stream.h | 2 +- devices/rinkj/rinkj-config.c | 2 +- devices/rinkj/rinkj-config.h | 2 +- devices/rinkj/rinkj-device.c | 2 +- devices/rinkj/rinkj-device.h | 2 +- devices/rinkj/rinkj-dither.c | 2 +- devices/rinkj/rinkj-dither.h | 2 +- devices/rinkj/rinkj-epson870.c | 2 +- devices/rinkj/rinkj-epson870.h | 2 +- devices/rinkj/rinkj-screen-eb.c | 2 +- devices/rinkj/rinkj-screen-eb.h | 2 +- devices/vector/doc_common.c | 532 + devices/vector/doc_common.h | 58 + devices/vector/gdevagl.c | 2 +- devices/vector/gdevagl.h | 2 +- devices/vector/gdevdocxw.c | 1376 ++ devices/vector/gdevpdf.c | 171 +- devices/vector/gdevpdfb.c | 48 +- devices/vector/gdevpdfb.h | 19 +- devices/vector/gdevpdfc.c | 43 +- devices/vector/gdevpdfc.h | 2 +- devices/vector/gdevpdfd.c | 2 +- devices/vector/gdevpdfe.c | 32 +- devices/vector/gdevpdfg.c | 4 +- devices/vector/gdevpdfg.h | 4 +- devices/vector/gdevpdfi.c | 512 +- devices/vector/gdevpdfj.c | 17 +- devices/vector/gdevpdfk.c | 4 +- devices/vector/gdevpdfm.c | 101 +- devices/vector/gdevpdfo.c | 17 +- devices/vector/gdevpdfo.h | 4 +- devices/vector/gdevpdfp.c | 182 +- devices/vector/gdevpdfr.c | 33 +- devices/vector/gdevpdft.c | 4 +- devices/vector/gdevpdfu.c | 25 +- devices/vector/gdevpdfv.c | 2 +- devices/vector/gdevpdfx.h | 41 +- devices/vector/gdevpdt.c | 2 +- devices/vector/gdevpdt.h | 2 +- devices/vector/gdevpdtb.c | 22 +- devices/vector/gdevpdtb.h | 2 +- devices/vector/gdevpdtc.c | 2 +- devices/vector/gdevpdtd.c | 23 +- devices/vector/gdevpdtd.h | 4 +- devices/vector/gdevpdte.c | 272 +- devices/vector/gdevpdtf.c | 18 +- devices/vector/gdevpdtf.h | 2 +- devices/vector/gdevpdti.c | 9 +- devices/vector/gdevpdti.h | 2 +- devices/vector/gdevpdts.c | 2 +- devices/vector/gdevpdts.h | 2 +- devices/vector/gdevpdtt.c | 119 +- devices/vector/gdevpdtt.h | 2 +- devices/vector/gdevpdtv.c | 2 +- devices/vector/gdevpdtv.h | 2 +- devices/vector/gdevpdtw.c | 2 +- devices/vector/gdevpdtw.h | 2 +- devices/vector/gdevpdtx.h | 2 +- devices/vector/gdevpsdf.h | 2 +- devices/vector/gdevpsdi.c | 92 +- devices/vector/gdevpsdp.c | 25 +- devices/vector/gdevpsds.c | 2 +- devices/vector/gdevpsds.h | 2 +- devices/vector/gdevpsdu.c | 12 +- devices/vector/gdevpsf.h | 4 +- devices/vector/gdevpsf1.c | 20 +- devices/vector/gdevpsf2.c | 11 +- devices/vector/gdevpsfm.c | 2 +- devices/vector/gdevpsft.c | 2 +- devices/vector/gdevpsfu.c | 2 +- devices/vector/gdevpsfx.c | 2 +- devices/vector/gdevpsu.c | 2 +- devices/vector/gdevpsu.h | 2 +- devices/vector/gdevpx.c | 6 +- devices/vector/gdevtxtw.c | 778 +- devices/vector/gdevxps.c | 247 +- devices/vector/opdfread.ps | 6 +- devices/vector/whitelst.c | 2 +- devices/vector/whitelst.h | 2 +- doc/API.htm | 19 +- doc/C-style.htm | 8 +- doc/Commprod.htm | 7 +- doc/DLL.htm | 7 +- doc/Deprecated.htm | 7 +- doc/Develop.htm | 14 +- doc/Devices.htm | 84 +- doc/Drivers.htm | 33 +- doc/Fonts.htm | 7 +- doc/GPDL.htm | 7 +- doc/GS9_Color_Management.tex | 2 +- doc/History9.htm | 8910 ++++++++- doc/Install.htm | 7 +- doc/Internal.htm | 7 +- doc/Language.htm | 29 +- doc/Lib.htm | 7 +- doc/Make.htm | 74 +- doc/News.htm | 83 +- doc/Ps-style.htm | 7 +- doc/Ps2epsi.htm | 7 +- doc/Psfiles.htm | 7 +- doc/Readme.htm | 9 +- doc/Release.htm | 7 +- doc/SavedPages.htm | 7 +- doc/Source.htm | 7 +- doc/Unix-lpr.htm | 7 +- doc/Use.htm | 109 +- doc/VectorDevices.htm | 90 +- doc/WhatIsGS.htm | 123 +- doc/gdevds32.c | 2 +- doc/gs-vms.hlp | 2 +- doc/sample_downscale_device.htm | 7 +- doc/subclass.htm | 7 +- doc/thirdparty.htm | 27 +- examples/alphabet.ps | 3 +- examples/colorcir.ps | 3 +- examples/doretree.ps | 3 +- examples/escher.ps | 4 +- examples/golfer.eps | 3 +- examples/grayalph.ps | 3 +- examples/snowflak.ps | 5 +- examples/tiger.eps | 5 +- examples/vasarely.ps | 4 +- examples/waterfal.ps | 3 +- extract/COPYING | 661 + extract/Makefile | 482 + extract/README | 12 + extract/include/extract.h | 212 + extract/include/extract_alloc.h | 76 + extract/include/extract_buffer.h | 278 + extract/include/extract_buffer_impl.h | 72 + extract/include/extract_compat_inline.h | 15 + extract/src/alloc.c | 120 + extract/src/astring.c | 41 + extract/src/astring.h | 23 + extract/src/buffer-test.c | 306 + extract/src/buffer.c | 477 + extract/src/compat_stdint.h | 25 + extract/src/compat_strtoll.h | 9 + extract/src/compat_va_copy.h | 8 + extract/src/document.h | 150 + extract/src/docx.c | 1097 ++ extract/src/docx.h | 84 + extract/src/docx_template.c | 910 + extract/src/docx_template.h | 17 + extract/src/docx_template_build.py | 210 + extract/src/extract-exe.c | 244 + extract/src/extract.c | 1226 ++ extract/src/join.c | 951 + extract/src/mem.c | 51 + extract/src/mem.h | 14 + extract/src/memento.c | 3574 ++++ extract/src/memento.h | 343 + extract/src/memento.py | 83 + extract/src/misc-test.c | 86 + extract/src/outf.c | 42 + extract/src/outf.h | 32 + extract/src/template.docx | Bin 0 -> 14108 bytes extract/src/xml.c | 505 + extract/src/xml.h | 123 + extract/src/zip-test.c | 224 + extract/src/zip.c | 307 + extract/src/zip.h | 64 + extract/test/Python2.pdf | Bin 0 -> 61412 bytes .../[Content_Types].xml | 2 + .../test/Python2.pdf.gs.docx.dir.ref/_rels/.rels | 2 + .../Python2.pdf.gs.docx.dir.ref/docProps/app.xml | 2 + .../Python2.pdf.gs.docx.dir.ref/docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../Python2.pdf.gs.docx.dir.ref/word/document.xml | 834 + .../Python2.pdf.gs.docx.dir.ref/word/fontTable.xml | 2 + .../Python2.pdf.gs.docx.dir.ref/word/settings.xml | 2 + .../Python2.pdf.gs.docx.dir.ref/word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 718 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 682 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 718 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 682 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 177 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../Python2.pdf.mutool.docx.dir.ref/_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 682 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + extract/test/Python2clipped.pdf | Bin 0 -> 61412 bytes .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 173 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 674 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + extract/test/text_graphic_image.pdf | 627 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 14 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 26 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 26 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 14 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 26 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 82 + .../word/fontTable.xml | 2 + .../word/media/image11.jpeg | Bin 0 -> 68027 bytes .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 82 + .../word/fontTable.xml | 2 + .../word/media/image11.jpeg | Bin 0 -> 68027 bytes .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 70 + .../word/fontTable.xml | 2 + .../word/media/image11.jpeg | Bin 0 -> 68027 bytes .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 82 + .../word/fontTable.xml | 2 + .../word/media/image11.jpeg | Bin 0 -> 68027 bytes .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 70 + .../word/fontTable.xml | 2 + .../word/media/image11.jpeg | Bin 0 -> 68027 bytes .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 70 + .../word/fontTable.xml | 2 + .../word/media/image11.jpeg | Bin 0 -> 68027 bytes .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + extract/test/zlib.3.pdf | Bin 0 -> 19318 bytes .../zlib.3.pdf.gs.docx.dir.ref/[Content_Types].xml | 2 + .../test/zlib.3.pdf.gs.docx.dir.ref/_rels/.rels | 2 + .../zlib.3.pdf.gs.docx.dir.ref/docProps/app.xml | 2 + .../zlib.3.pdf.gs.docx.dir.ref/docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../zlib.3.pdf.gs.docx.dir.ref/word/document.xml | 185 + .../zlib.3.pdf.gs.docx.dir.ref/word/fontTable.xml | 2 + .../zlib.3.pdf.gs.docx.dir.ref/word/settings.xml | 2 + .../zlib.3.pdf.gs.docx.dir.ref/word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 185 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 185 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 321 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 185 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + .../[Content_Types].xml | 2 + .../zlib.3.pdf.mutool.docx.dir.ref/_rels/.rels | 2 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../word/_rels/document.xml.rels | 2 + .../word/document.xml | 185 + .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../zlib.3.pdf.mutool.docx.dir.ref/word/styles.xml | 2 + .../word/theme/theme1.xml | 2 + .../word/webSettings.xml | 2 + freetype/.clang-format | 16 + freetype/CMakeLists.txt | 145 +- freetype/ChangeLog | 1954 +- freetype/ChangeLog.20 | 2 +- freetype/ChangeLog.21 | 8 +- freetype/ChangeLog.22 | 2 +- freetype/ChangeLog.23 | 2 +- freetype/ChangeLog.24 | 2 +- freetype/ChangeLog.25 | 2 +- freetype/ChangeLog.26 | 2 +- freetype/ChangeLog.27 | 2 +- freetype/ChangeLog.28 | 2 +- freetype/ChangeLog.29 | 2 +- freetype/Jamfile | 223 - freetype/Jamrules | 71 - freetype/Makefile | 2 +- freetype/README | 31 +- freetype/README.git | 2 +- freetype/autogen.sh | 2 +- freetype/builds/amiga/README | 2 +- freetype/builds/amiga/include/config/ftconfig.h | 2 +- freetype/builds/amiga/include/config/ftmodule.h | 4 +- freetype/builds/amiga/makefile | 2 +- freetype/builds/amiga/makefile.os4 | 2 +- freetype/builds/amiga/smakefile | 2 +- freetype/builds/amiga/src/base/ftdebug.c | 8 +- freetype/builds/amiga/src/base/ftsystem.c | 10 +- freetype/builds/ansi/ansi-def.mk | 2 +- freetype/builds/ansi/ansi.mk | 2 +- freetype/builds/beos/beos-def.mk | 2 +- freetype/builds/beos/beos.mk | 2 +- freetype/builds/beos/detect.mk | 2 +- freetype/builds/cmake/FindBrotliDec.cmake | 51 + freetype/builds/cmake/FindHarfBuzz.cmake | 72 +- freetype/builds/cmake/iOS.cmake | 2 +- freetype/builds/cmake/testbuild.sh | 4 +- freetype/builds/compiler/ansi-cc.mk | 2 +- freetype/builds/compiler/bcc-dev.mk | 2 +- freetype/builds/compiler/bcc.mk | 2 +- freetype/builds/compiler/emx.mk | 2 +- freetype/builds/compiler/gcc-dev.mk | 2 +- freetype/builds/compiler/gcc.mk | 2 +- freetype/builds/compiler/intelc.mk | 2 +- freetype/builds/compiler/unix-lcc.mk | 2 +- freetype/builds/compiler/visualage.mk | 2 +- freetype/builds/compiler/visualc.mk | 2 +- freetype/builds/compiler/watcom.mk | 2 +- freetype/builds/compiler/win-lcc.mk | 2 +- freetype/builds/detect.mk | 4 +- freetype/builds/dos/detect.mk | 2 +- freetype/builds/dos/dos-def.mk | 2 +- freetype/builds/dos/dos-emx.mk | 2 +- freetype/builds/dos/dos-gcc.mk | 2 +- freetype/builds/dos/dos-wat.mk | 2 +- freetype/builds/exports.mk | 2 +- freetype/builds/freetype.mk | 52 +- freetype/builds/link_dos.mk | 2 +- freetype/builds/link_std.mk | 2 +- freetype/builds/mac/ftmac.c | 9 +- freetype/builds/meson/extract_freetype_version.py | 107 + freetype/builds/meson/extract_libtool_version.py | 105 + freetype/builds/meson/generate_reference_docs.py | 79 + freetype/builds/meson/parse_modules_cfg.py | 160 + freetype/builds/meson/process_ftoption_h.py | 105 + freetype/builds/modules.mk | 2 +- freetype/builds/os2/detect.mk | 2 +- freetype/builds/os2/os2-def.mk | 2 +- freetype/builds/os2/os2-dev.mk | 2 +- freetype/builds/os2/os2-gcc.mk | 2 +- freetype/builds/symbian/bld.inf | 2 +- freetype/builds/symbian/freetype.mmp | 2 +- freetype/builds/toplevel.mk | 6 +- freetype/builds/unix/aclocal.m4 | 2 + freetype/builds/unix/ax_compare_version.m4 | 177 + freetype/builds/unix/ax_prog_python_version.m4 | 66 + freetype/builds/unix/configure.ac | 119 +- freetype/builds/unix/configure.raw | 117 +- freetype/builds/unix/detect.mk | 2 +- freetype/builds/unix/freetype-config.in | 2 +- freetype/builds/unix/freetype2.m4 | 6 +- freetype/builds/unix/ft-munmap.m4 | 2 +- freetype/builds/unix/ftconfig.h.in | 62 + freetype/builds/unix/ftconfig.in | 603 - freetype/builds/unix/ftsystem.c | 16 +- freetype/builds/unix/install.mk | 2 +- freetype/builds/unix/unix-cc.in | 17 +- freetype/builds/unix/unix-def.in | 3 +- freetype/builds/unix/unix-dev.mk | 2 +- freetype/builds/unix/unix-lcc.mk | 2 +- freetype/builds/unix/unix.mk | 2 +- freetype/builds/unix/unixddef.mk | 2 +- freetype/builds/vms/ftconfig.h | 505 +- freetype/builds/vms/ftsystem.c | 12 +- freetype/builds/wince/ftdebug.c | 9 +- freetype/builds/wince/vc2005-ce/freetype.vcproj | 80 +- freetype/builds/wince/vc2005-ce/index.html | 10 +- freetype/builds/wince/vc2008-ce/freetype.vcproj | 85 +- freetype/builds/wince/vc2008-ce/index.html | 10 +- freetype/builds/windows/detect.mk | 2 +- freetype/builds/windows/ftdebug.c | 9 +- freetype/builds/windows/vc2010/index.html | 2 +- freetype/builds/windows/visualc/index.html | 2 +- freetype/builds/windows/visualce/freetype.dsp | 28 +- freetype/builds/windows/visualce/freetype.vcproj | 93 +- freetype/builds/windows/visualce/index.html | 10 +- freetype/builds/windows/w32-bcc.mk | 2 +- freetype/builds/windows/w32-bccd.mk | 2 +- freetype/builds/windows/w32-dev.mk | 2 +- freetype/builds/windows/w32-gcc.mk | 2 +- freetype/builds/windows/w32-icc.mk | 2 +- freetype/builds/windows/w32-intl.mk | 2 +- freetype/builds/windows/w32-lcc.mk | 2 +- freetype/builds/windows/w32-mingw32.mk | 2 +- freetype/builds/windows/w32-vcc.mk | 2 +- freetype/builds/windows/w32-wat.mk | 2 +- freetype/builds/windows/win32-def.mk | 2 +- freetype/devel/ft2build.h | 3 +- freetype/devel/ftoption.h | 32 +- freetype/docs/CHANGES | 105 +- freetype/docs/CUSTOMIZE | 2 +- freetype/docs/DEBUG | 135 +- freetype/docs/DOCGUIDE | 2 +- freetype/docs/INSTALL | 2 +- freetype/docs/INSTALL.ANY | 12 +- freetype/docs/INSTALL.CROSS | 2 +- freetype/docs/INSTALL.GNU | 4 +- freetype/docs/INSTALL.UNIX | 2 +- freetype/docs/INSTALL.VMS | 2 +- freetype/docs/README | 35 + freetype/docs/TODO | 2 +- freetype/docs/VERSIONS.TXT | 101 +- freetype/docs/formats.txt | 2 +- freetype/docs/freetype-config.1 | 2 +- freetype/docs/raster.txt | 2 +- freetype/docs/reference/404.html | 1036 + freetype/docs/reference/README | 35 - .../docs/reference/assets/fonts/font-awesome.css | 4 + .../docs/reference/assets/fonts/material-icons.css | 13 + .../assets/fonts/specimen/FontAwesome.ttf | Bin 0 -> 165548 bytes .../assets/fonts/specimen/FontAwesome.woff | Bin 0 -> 98024 bytes .../assets/fonts/specimen/FontAwesome.woff2 | Bin 0 -> 77160 bytes .../fonts/specimen/MaterialIcons-Regular.ttf | Bin 0 -> 128180 bytes .../fonts/specimen/MaterialIcons-Regular.woff | Bin 0 -> 57620 bytes .../fonts/specimen/MaterialIcons-Regular.woff2 | Bin 0 -> 44300 bytes freetype/docs/reference/assets/images/favicon.png | Bin 0 -> 521 bytes .../assets/images/icons/bitbucket.1b09e088.svg | 1 + .../assets/images/icons/github.f0b8504a.svg | 1 + .../assets/images/icons/gitlab.6dd19c00.svg | 1 + .../assets/javascripts/application.c33a9706.js | 60 + .../reference/assets/javascripts/lunr/lunr.ar.js | 20 + .../reference/assets/javascripts/lunr/lunr.da.js | 17 + .../reference/assets/javascripts/lunr/lunr.de.js | 17 + .../reference/assets/javascripts/lunr/lunr.du.js | 17 + .../reference/assets/javascripts/lunr/lunr.es.js | 17 + .../reference/assets/javascripts/lunr/lunr.fi.js | 17 + .../reference/assets/javascripts/lunr/lunr.fr.js | 17 + .../reference/assets/javascripts/lunr/lunr.hu.js | 17 + .../reference/assets/javascripts/lunr/lunr.it.js | 17 + .../reference/assets/javascripts/lunr/lunr.ja.js | 17 + .../reference/assets/javascripts/lunr/lunr.jp.js | 1 + .../assets/javascripts/lunr/lunr.multi.js | 1 + .../reference/assets/javascripts/lunr/lunr.nl.js | 17 + .../reference/assets/javascripts/lunr/lunr.no.js | 17 + .../reference/assets/javascripts/lunr/lunr.pt.js | 17 + .../reference/assets/javascripts/lunr/lunr.ro.js | 17 + .../reference/assets/javascripts/lunr/lunr.ru.js | 17 + .../javascripts/lunr/lunr.stemmer.support.js | 9 + .../reference/assets/javascripts/lunr/lunr.sv.js | 17 + .../reference/assets/javascripts/lunr/lunr.th.js | 17 + .../reference/assets/javascripts/lunr/lunr.tr.js | 17 + .../reference/assets/javascripts/lunr/lunr.vi.js | 17 + .../reference/assets/javascripts/lunr/tinyseg.js | 1 + .../reference/assets/javascripts/lunr/wordcut.js | 1 + .../assets/javascripts/modernizr.86422ebf.js | 1 + .../stylesheets/application-palette.a8b3c06d.css | 1 + .../assets/stylesheets/application.adb8469c.css | 1 + freetype/docs/reference/ft2-auto_hinter.html | 1158 ++ freetype/docs/reference/ft2-base_interface.html | 5109 +++++ freetype/docs/reference/ft2-basic_types.html | 2299 +++ freetype/docs/reference/ft2-bdf_fonts.html | 1375 ++ freetype/docs/reference/ft2-bitmap_handling.html | 1504 ++ freetype/docs/reference/ft2-bzip2.html | 1200 ++ freetype/docs/reference/ft2-cache_subsystem.html | 2344 +++ freetype/docs/reference/ft2-cff_driver.html | 1166 ++ freetype/docs/reference/ft2-cid_fonts.html | 1314 ++ freetype/docs/reference/ft2-color_management.html | 1457 ++ freetype/docs/reference/ft2-computations.html | 2005 ++ freetype/docs/reference/ft2-error_code_values.html | 1395 ++ .../docs/reference/ft2-error_enumerations.html | 1244 ++ freetype/docs/reference/ft2-font_formats.html | 1197 ++ freetype/docs/reference/ft2-gasp_table.html | 1252 ++ freetype/docs/reference/ft2-glyph_management.html | 1821 ++ freetype/docs/reference/ft2-glyph_stroker.html | 2092 ++ freetype/docs/reference/ft2-glyph_variants.html | 1387 ++ freetype/docs/reference/ft2-gx_validation.html | 1478 ++ freetype/docs/reference/ft2-gzip.html | 1266 ++ .../docs/reference/ft2-header_file_macros.html | 2215 +++ freetype/docs/reference/ft2-header_inclusion.html | 1161 ++ freetype/docs/reference/ft2-incremental.html | 1507 ++ freetype/docs/reference/ft2-index.html | 2145 +++ freetype/docs/reference/ft2-layer_management.html | 1310 ++ freetype/docs/reference/ft2-lcd_rendering.html | 1408 ++ freetype/docs/reference/ft2-list_processing.html | 1624 ++ freetype/docs/reference/ft2-lzw.html | 1200 ++ freetype/docs/reference/ft2-mac_specific.html | 1486 ++ freetype/docs/reference/ft2-module_management.html | 2159 +++ freetype/docs/reference/ft2-multiple_masters.html | 2069 ++ freetype/docs/reference/ft2-ot_validation.html | 1306 ++ .../docs/reference/ft2-outline_processing.html | 2250 +++ freetype/docs/reference/ft2-parameter_tags.html | 1334 ++ freetype/docs/reference/ft2-pcf_driver.html | 1157 ++ freetype/docs/reference/ft2-pfr_fonts.html | 1318 ++ freetype/docs/reference/ft2-properties.html | 1906 ++ freetype/docs/reference/ft2-quick_advance.html | 1297 ++ freetype/docs/reference/ft2-raster.html | 1706 ++ freetype/docs/reference/ft2-sfnt_names.html | 1405 ++ freetype/docs/reference/ft2-sizes_management.html | 1276 ++ freetype/docs/reference/ft2-system_interface.html | 1549 ++ freetype/docs/reference/ft2-t1_cid_driver.html | 1160 ++ freetype/docs/reference/ft2-truetype_engine.html | 1237 ++ freetype/docs/reference/ft2-truetype_tables.html | 3158 +++ freetype/docs/reference/ft2-tt_driver.html | 1173 ++ freetype/docs/reference/ft2-type1_tables.html | 2101 ++ freetype/docs/reference/ft2-user_allocation.html | 1156 ++ freetype/docs/reference/ft2-version.html | 1332 ++ freetype/docs/reference/ft2-winfnt_fonts.html | 1392 ++ freetype/docs/reference/images/favico.ico | Bin 0 -> 1150 bytes freetype/docs/reference/index.html | 1276 ++ freetype/docs/reference/javascripts/extra.js | 54 + freetype/docs/reference/search/search_index.json | 1 + freetype/docs/reference/site/404.html | 1034 - .../reference/site/assets/fonts/font-awesome.css | 4 - .../reference/site/assets/fonts/material-icons.css | 13 - .../site/assets/fonts/specimen/FontAwesome.ttf | Bin 165548 -> 0 bytes .../site/assets/fonts/specimen/FontAwesome.woff | Bin 98024 -> 0 bytes .../site/assets/fonts/specimen/FontAwesome.woff2 | Bin 77160 -> 0 bytes .../fonts/specimen/MaterialIcons-Regular.ttf | Bin 128180 -> 0 bytes .../fonts/specimen/MaterialIcons-Regular.woff | Bin 57620 -> 0 bytes .../fonts/specimen/MaterialIcons-Regular.woff2 | Bin 44300 -> 0 bytes .../docs/reference/site/assets/images/favicon.png | Bin 521 -> 0 bytes .../assets/images/icons/bitbucket.1b09e088.svg | 20 - .../site/assets/images/icons/github.f0b8504a.svg | 18 - .../site/assets/images/icons/gitlab.6dd19c00.svg | 38 - .../assets/javascripts/application.d9aa80ab.js | 6 - .../site/assets/javascripts/lunr/lunr.da.js | 1 - .../site/assets/javascripts/lunr/lunr.de.js | 1 - .../site/assets/javascripts/lunr/lunr.du.js | 1 - .../site/assets/javascripts/lunr/lunr.es.js | 1 - .../site/assets/javascripts/lunr/lunr.fi.js | 1 - .../site/assets/javascripts/lunr/lunr.fr.js | 1 - .../site/assets/javascripts/lunr/lunr.hu.js | 1 - .../site/assets/javascripts/lunr/lunr.it.js | 1 - .../site/assets/javascripts/lunr/lunr.ja.js | 1 - .../site/assets/javascripts/lunr/lunr.jp.js | 1 - .../site/assets/javascripts/lunr/lunr.multi.js | 1 - .../site/assets/javascripts/lunr/lunr.nl.js | 1 - .../site/assets/javascripts/lunr/lunr.no.js | 1 - .../site/assets/javascripts/lunr/lunr.pt.js | 1 - .../site/assets/javascripts/lunr/lunr.ro.js | 1 - .../site/assets/javascripts/lunr/lunr.ru.js | 1 - .../javascripts/lunr/lunr.stemmer.support.js | 1 - .../site/assets/javascripts/lunr/lunr.sv.js | 1 - .../site/assets/javascripts/lunr/lunr.th.js | 1 - .../site/assets/javascripts/lunr/lunr.tr.js | 1 - .../site/assets/javascripts/lunr/tinyseg.js | 1 - .../site/assets/javascripts/lunr/wordcut.js | 1 - .../site/assets/javascripts/modernizr.1f0bcf2b.js | 1 - .../stylesheets/application-palette.224b79ff.css | 1 - .../assets/stylesheets/application.982221ab.css | 1 - freetype/docs/reference/site/ft2-auto_hinter.html | 1155 -- .../docs/reference/site/ft2-base_interface.html | 5342 ------ freetype/docs/reference/site/ft2-basic_types.html | 2422 --- freetype/docs/reference/site/ft2-bdf_fonts.html | 1387 -- .../docs/reference/site/ft2-bitmap_handling.html | 1522 -- freetype/docs/reference/site/ft2-bzip2.html | 1200 -- .../docs/reference/site/ft2-cache_subsystem.html | 2425 --- freetype/docs/reference/site/ft2-cff_driver.html | 1163 -- freetype/docs/reference/site/ft2-cid_fonts.html | 1320 -- .../docs/reference/site/ft2-color_management.html | 1471 -- freetype/docs/reference/site/ft2-computations.html | 2074 -- .../docs/reference/site/ft2-error_code_values.html | 1395 -- .../reference/site/ft2-error_enumerations.html | 1244 -- freetype/docs/reference/site/ft2-font_formats.html | 1197 -- freetype/docs/reference/site/ft2-gasp_table.html | 1255 -- .../docs/reference/site/ft2-glyph_management.html | 1860 -- .../docs/reference/site/ft2-glyph_stroker.html | 2154 --- .../docs/reference/site/ft2-glyph_variants.html | 1399 -- .../docs/reference/site/ft2-gx_validation.html | 1482 -- freetype/docs/reference/site/ft2-gzip.html | 1269 -- .../reference/site/ft2-header_file_macros.html | 2355 --- .../docs/reference/site/ft2-header_inclusion.html | 1159 -- freetype/docs/reference/site/ft2-incremental.html | 1531 -- freetype/docs/reference/site/ft2-index.html | 2141 --- .../docs/reference/site/ft2-layer_management.html | 1313 -- .../docs/reference/site/ft2-lcd_rendering.html | 1420 -- .../docs/reference/site/ft2-list_processing.html | 1660 -- freetype/docs/reference/site/ft2-lzw.html | 1200 -- freetype/docs/reference/site/ft2-mac_specific.html | 1501 -- .../docs/reference/site/ft2-module_management.html | 2225 --- .../docs/reference/site/ft2-multiple_masters.html | 2126 --- .../docs/reference/site/ft2-ot_validation.html | 1326 -- .../reference/site/ft2-outline_processing.html | 2314 --- .../docs/reference/site/ft2-parameter_tags.html | 1352 -- freetype/docs/reference/site/ft2-pcf_driver.html | 1154 -- freetype/docs/reference/site/ft2-pfr_fonts.html | 1324 -- freetype/docs/reference/site/ft2-properties.html | 1919 -- .../docs/reference/site/ft2-quick_advance.html | 1303 -- freetype/docs/reference/site/ft2-raster.html | 1741 -- freetype/docs/reference/site/ft2-sfnt_names.html | 1417 -- .../docs/reference/site/ft2-sizes_management.html | 1282 -- .../docs/reference/site/ft2-system_interface.html | 1576 -- .../docs/reference/site/ft2-t1_cid_driver.html | 1157 -- .../docs/reference/site/ft2-truetype_engine.html | 1240 -- .../docs/reference/site/ft2-truetype_tables.html | 3227 ---- freetype/docs/reference/site/ft2-tt_driver.html | 1170 -- freetype/docs/reference/site/ft2-type1_tables.html | 2155 --- .../docs/reference/site/ft2-user_allocation.html | 1153 -- freetype/docs/reference/site/ft2-version.html | 1341 -- freetype/docs/reference/site/ft2-winfnt_fonts.html | 1401 -- freetype/docs/reference/site/images/favico.ico | Bin 1150 -> 0 bytes freetype/docs/reference/site/index.html | 1273 -- freetype/docs/reference/site/javascripts/extra.js | 54 - .../docs/reference/site/search/search_index.json | 1 - freetype/docs/reference/site/sitemap.xml | 258 - freetype/docs/reference/site/sitemap.xml.gz | Bin 221 -> 0 bytes freetype/docs/reference/site/stylesheets/extra.css | 221 - freetype/docs/reference/sitemap.xml | 207 + freetype/docs/reference/sitemap.xml.gz | Bin 0 -> 219 bytes freetype/docs/reference/stylesheets/extra.css | 183 + freetype/docs/release | 2 +- freetype/include/freetype/config/ftconfig.h | 532 +- freetype/include/freetype/config/ftheader.h | 64 +- freetype/include/freetype/config/ftmodule.h | 2 - freetype/include/freetype/config/ftoption.h | 32 +- freetype/include/freetype/config/ftstdlib.h | 2 +- freetype/include/freetype/config/integer-types.h | 245 + freetype/include/freetype/config/mac-support.h | 49 + freetype/include/freetype/config/public-macros.h | 120 + freetype/include/freetype/freetype.h | 82 +- freetype/include/freetype/ftadvanc.h | 6 +- freetype/include/freetype/ftbbox.h | 5 +- freetype/include/freetype/ftbdf.h | 5 +- freetype/include/freetype/ftbitmap.h | 7 +- freetype/include/freetype/ftbzip2.h | 24 +- freetype/include/freetype/ftcache.h | 5 +- freetype/include/freetype/ftcid.h | 5 +- freetype/include/freetype/ftcolor.h | 20 +- freetype/include/freetype/ftdriver.h | 11 +- freetype/include/freetype/fterrdef.h | 2 +- freetype/include/freetype/fterrors.h | 23 +- freetype/include/freetype/ftfntfmt.h | 5 +- freetype/include/freetype/ftgasp.h | 5 +- freetype/include/freetype/ftglyph.h | 5 +- freetype/include/freetype/ftgxval.h | 5 +- freetype/include/freetype/ftgzip.h | 24 +- freetype/include/freetype/ftimage.h | 41 +- freetype/include/freetype/ftincrem.h | 7 +- freetype/include/freetype/ftlcdfil.h | 34 +- freetype/include/freetype/ftlist.h | 5 +- freetype/include/freetype/ftlzw.h | 24 +- freetype/include/freetype/ftmac.h | 3 +- freetype/include/freetype/ftmm.h | 5 +- freetype/include/freetype/ftmodapi.h | 9 +- freetype/include/freetype/ftmoderr.h | 4 +- freetype/include/freetype/ftotval.h | 5 +- freetype/include/freetype/ftoutln.h | 21 +- freetype/include/freetype/ftparams.h | 5 +- freetype/include/freetype/ftpfr.h | 5 +- freetype/include/freetype/ftrender.h | 7 +- freetype/include/freetype/ftsizes.h | 5 +- freetype/include/freetype/ftsnames.h | 7 +- freetype/include/freetype/ftstroke.h | 43 +- freetype/include/freetype/ftsynth.h | 5 +- freetype/include/freetype/ftsystem.h | 3 +- freetype/include/freetype/fttrigon.h | 4 +- freetype/include/freetype/fttypes.h | 6 +- freetype/include/freetype/ftwinfnt.h | 5 +- freetype/include/freetype/internal/autohint.h | 8 +- freetype/include/freetype/internal/cffotypes.h | 13 +- freetype/include/freetype/internal/cfftypes.h | 15 +- .../include/freetype/internal/compiler-macros.h | 307 + freetype/include/freetype/internal/ftcalc.h | 9 +- freetype/include/freetype/internal/ftdebug.h | 8 +- freetype/include/freetype/internal/ftdrv.h | 6 +- freetype/include/freetype/internal/ftgloadr.h | 7 +- freetype/include/freetype/internal/fthash.h | 3 +- freetype/include/freetype/internal/ftmemory.h | 23 +- freetype/include/freetype/internal/ftobjs.h | 33 +- freetype/include/freetype/internal/ftpsprop.h | 5 +- freetype/include/freetype/internal/ftrfork.h | 5 +- freetype/include/freetype/internal/ftserv.h | 30 +- freetype/include/freetype/internal/ftstream.h | 6 +- freetype/include/freetype/internal/fttrace.h | 3 +- freetype/include/freetype/internal/ftvalid.h | 5 +- freetype/include/freetype/internal/internal.h | 67 - freetype/include/freetype/internal/psaux.h | 17 +- freetype/include/freetype/internal/pshints.h | 7 +- .../include/freetype/internal/services/svbdf.h | 6 +- .../include/freetype/internal/services/svcfftl.h | 6 +- .../include/freetype/internal/services/svcid.h | 4 +- .../include/freetype/internal/services/svfntfmt.h | 4 +- .../include/freetype/internal/services/svgldict.h | 4 +- .../include/freetype/internal/services/svgxval.h | 6 +- .../include/freetype/internal/services/svkern.h | 6 +- .../include/freetype/internal/services/svmetric.h | 4 +- freetype/include/freetype/internal/services/svmm.h | 4 +- .../include/freetype/internal/services/svotval.h | 6 +- .../include/freetype/internal/services/svpfr.h | 7 +- .../include/freetype/internal/services/svpostnm.h | 4 +- .../include/freetype/internal/services/svprop.h | 2 +- .../include/freetype/internal/services/svpscmap.h | 4 +- .../include/freetype/internal/services/svpsinfo.h | 6 +- .../include/freetype/internal/services/svsfnt.h | 6 +- .../include/freetype/internal/services/svttcmap.h | 6 +- .../include/freetype/internal/services/svtteng.h | 6 +- .../include/freetype/internal/services/svttglyf.h | 6 +- .../include/freetype/internal/services/svwinfnt.h | 6 +- freetype/include/freetype/internal/sfnt.h | 9 +- freetype/include/freetype/internal/t1types.h | 13 +- freetype/include/freetype/internal/tttypes.h | 11 +- freetype/include/freetype/internal/wofftypes.h | 208 +- freetype/include/freetype/t1tables.h | 5 +- freetype/include/freetype/ttnameid.h | 3 +- freetype/include/freetype/tttables.h | 5 +- freetype/include/freetype/tttags.h | 6 +- freetype/include/ft2build.h | 10 +- freetype/meson.build | 368 + freetype/meson_options.txt | 47 + freetype/modules.cfg | 2 +- freetype/src/Jamfile | 19 - freetype/src/autofit/Jamfile | 53 - freetype/src/autofit/afangles.c | 2 +- freetype/src/autofit/afblue.c | 65 +- freetype/src/autofit/afblue.cin | 2 +- freetype/src/autofit/afblue.dat | 79 +- freetype/src/autofit/afblue.h | 164 +- freetype/src/autofit/afblue.hin | 2 +- freetype/src/autofit/afcjk.c | 25 +- freetype/src/autofit/afcjk.h | 2 +- freetype/src/autofit/afcover.h | 2 +- freetype/src/autofit/afdummy.c | 2 +- freetype/src/autofit/afdummy.h | 2 +- freetype/src/autofit/aferrors.h | 6 +- freetype/src/autofit/afglobal.c | 6 +- freetype/src/autofit/afglobal.h | 2 +- freetype/src/autofit/afhints.c | 6 +- freetype/src/autofit/afhints.h | 2 +- freetype/src/autofit/afindic.c | 2 +- freetype/src/autofit/afindic.h | 2 +- freetype/src/autofit/aflatin.c | 61 +- freetype/src/autofit/aflatin.h | 2 +- freetype/src/autofit/aflatin2.c | 4 +- freetype/src/autofit/aflatin2.h | 2 +- freetype/src/autofit/afloader.c | 4 +- freetype/src/autofit/afloader.h | 2 +- freetype/src/autofit/afmodule.c | 16 +- freetype/src/autofit/afmodule.h | 8 +- freetype/src/autofit/afranges.c | 26 +- freetype/src/autofit/afranges.h | 2 +- freetype/src/autofit/afscript.h | 14 +- freetype/src/autofit/afshaper.c | 7 +- freetype/src/autofit/afshaper.h | 5 +- freetype/src/autofit/afstyles.h | 16 +- freetype/src/autofit/aftypes.h | 11 +- freetype/src/autofit/afwarp.c | 2 +- freetype/src/autofit/afwarp.h | 2 +- freetype/src/autofit/afwrtsys.h | 2 +- freetype/src/autofit/autofit.c | 3 +- freetype/src/autofit/module.mk | 2 +- freetype/src/autofit/rules.mk | 2 +- freetype/src/base/Jamfile | 90 - freetype/src/base/ftadvanc.c | 9 +- freetype/src/base/ftbase.c | 3 +- freetype/src/base/ftbase.h | 9 +- freetype/src/base/ftbbox.c | 23 +- freetype/src/base/ftbdf.c | 9 +- freetype/src/base/ftbitmap.c | 17 +- freetype/src/base/ftcalc.c | 13 +- freetype/src/base/ftcid.c | 9 +- freetype/src/base/ftcolor.c | 11 +- freetype/src/base/ftdbgmem.c | 18 +- freetype/src/base/ftdebug.c | 9 +- freetype/src/base/fterrors.c | 9 +- freetype/src/base/ftfntfmt.c | 9 +- freetype/src/base/ftfstype.c | 11 +- freetype/src/base/ftgasp.c | 7 +- freetype/src/base/ftgloadr.c | 32 +- freetype/src/base/ftglyph.c | 15 +- freetype/src/base/ftgxval.c | 9 +- freetype/src/base/fthash.c | 5 +- freetype/src/base/ftinit.c | 8 +- freetype/src/base/ftlcdfil.c | 11 +- freetype/src/base/ftmac.c | 9 +- freetype/src/base/ftmm.c | 13 +- freetype/src/base/ftobjs.c | 114 +- freetype/src/base/ftotval.c | 11 +- freetype/src/base/ftoutln.c | 22 +- freetype/src/base/ftpatent.c | 15 +- freetype/src/base/ftpfr.c | 9 +- freetype/src/base/ftpsprop.c | 17 +- freetype/src/base/ftrfork.c | 15 +- freetype/src/base/ftsnames.c | 11 +- freetype/src/base/ftstream.c | 9 +- freetype/src/base/ftstroke.c | 228 +- freetype/src/base/ftsynth.c | 15 +- freetype/src/base/ftsystem.c | 12 +- freetype/src/base/fttrigon.c | 9 +- freetype/src/base/fttype1.c | 11 +- freetype/src/base/ftutil.c | 11 +- freetype/src/base/ftver.rc | 8 +- freetype/src/base/ftwinfnt.c | 11 +- freetype/src/base/rules.mk | 2 +- freetype/src/bdf/Jamfile | 31 - freetype/src/bdf/bdf.c | 1 - freetype/src/bdf/bdf.h | 7 +- freetype/src/bdf/bdfdrivr.c | 44 +- freetype/src/bdf/bdfdrivr.h | 3 +- freetype/src/bdf/bdferror.h | 4 +- freetype/src/bdf/bdflib.c | 9 +- freetype/src/bzip2/Jamfile | 18 - freetype/src/bzip2/ftbzip2.c | 15 +- freetype/src/bzip2/rules.mk | 2 +- freetype/src/cache/Jamfile | 37 - freetype/src/cache/ftcache.c | 3 +- freetype/src/cache/ftcbasic.c | 17 +- freetype/src/cache/ftccache.c | 7 +- freetype/src/cache/ftccache.h | 4 +- freetype/src/cache/ftccback.h | 7 +- freetype/src/cache/ftccmap.c | 13 +- freetype/src/cache/ftcerror.h | 6 +- freetype/src/cache/ftcglyph.c | 9 +- freetype/src/cache/ftcglyph.h | 3 +- freetype/src/cache/ftcimage.c | 9 +- freetype/src/cache/ftcimage.h | 5 +- freetype/src/cache/ftcmanag.c | 11 +- freetype/src/cache/ftcmanag.h | 5 +- freetype/src/cache/ftcmru.c | 9 +- freetype/src/cache/ftcmru.h | 6 +- freetype/src/cache/ftcsbits.c | 11 +- freetype/src/cache/ftcsbits.h | 5 +- freetype/src/cache/rules.mk | 2 +- freetype/src/cff/Jamfile | 36 - freetype/src/cff/cff.c | 3 +- freetype/src/cff/cffcmap.c | 5 +- freetype/src/cff/cffcmap.h | 8 +- freetype/src/cff/cffdrivr.c | 39 +- freetype/src/cff/cffdrivr.h | 5 +- freetype/src/cff/cfferrs.h | 6 +- freetype/src/cff/cffgload.c | 27 +- freetype/src/cff/cffgload.h | 7 +- freetype/src/cff/cffload.c | 62 +- freetype/src/cff/cffload.h | 7 +- freetype/src/cff/cffobjs.c | 101 +- freetype/src/cff/cffobjs.h | 3 +- freetype/src/cff/cffparse.c | 31 +- freetype/src/cff/cffparse.h | 7 +- freetype/src/cff/cfftoken.h | 2 +- freetype/src/cff/module.mk | 2 +- freetype/src/cff/rules.mk | 2 +- freetype/src/cid/Jamfile | 34 - freetype/src/cid/ciderrs.h | 6 +- freetype/src/cid/cidgload.c | 19 +- freetype/src/cid/cidgload.h | 3 +- freetype/src/cid/cidload.c | 20 +- freetype/src/cid/cidload.h | 5 +- freetype/src/cid/cidobjs.c | 18 +- freetype/src/cid/cidobjs.h | 6 +- freetype/src/cid/cidparse.c | 9 +- freetype/src/cid/cidparse.h | 9 +- freetype/src/cid/cidriver.c | 21 +- freetype/src/cid/cidriver.h | 5 +- freetype/src/cid/cidtoken.h | 2 +- freetype/src/cid/module.mk | 2 +- freetype/src/cid/rules.mk | 2 +- freetype/src/cid/type1cid.c | 3 +- freetype/src/gxvalid/Jamfile | 52 - freetype/src/gxvalid/README | 2 +- freetype/src/gxvalid/gxvalid.c | 3 +- freetype/src/gxvalid/gxvalid.h | 11 +- freetype/src/gxvalid/gxvbsln.c | 2 +- freetype/src/gxvalid/gxvcommn.c | 2 +- freetype/src/gxvalid/gxvcommn.h | 7 +- freetype/src/gxvalid/gxverror.h | 6 +- freetype/src/gxvalid/gxvfeat.c | 2 +- freetype/src/gxvalid/gxvfeat.h | 2 +- freetype/src/gxvalid/gxvfgen.c | 2 +- freetype/src/gxvalid/gxvjust.c | 4 +- freetype/src/gxvalid/gxvkern.c | 6 +- freetype/src/gxvalid/gxvlcar.c | 2 +- freetype/src/gxvalid/gxvmod.c | 13 +- freetype/src/gxvalid/gxvmod.h | 5 +- freetype/src/gxvalid/gxvmort.c | 2 +- freetype/src/gxvalid/gxvmort.h | 9 +- freetype/src/gxvalid/gxvmort0.c | 2 +- freetype/src/gxvalid/gxvmort1.c | 2 +- freetype/src/gxvalid/gxvmort2.c | 2 +- freetype/src/gxvalid/gxvmort4.c | 2 +- freetype/src/gxvalid/gxvmort5.c | 2 +- freetype/src/gxvalid/gxvmorx.c | 2 +- freetype/src/gxvalid/gxvmorx.h | 9 +- freetype/src/gxvalid/gxvmorx0.c | 2 +- freetype/src/gxvalid/gxvmorx1.c | 2 +- freetype/src/gxvalid/gxvmorx2.c | 2 +- freetype/src/gxvalid/gxvmorx4.c | 2 +- freetype/src/gxvalid/gxvmorx5.c | 2 +- freetype/src/gxvalid/gxvopbd.c | 2 +- freetype/src/gxvalid/gxvprop.c | 2 +- freetype/src/gxvalid/gxvtrak.c | 2 +- freetype/src/gxvalid/module.mk | 2 +- freetype/src/gxvalid/rules.mk | 2 +- freetype/src/gzip/Jamfile | 16 - freetype/src/gzip/ftgzip.c | 25 +- freetype/src/gzip/infutil.h | 2 +- freetype/src/gzip/rules.mk | 2 +- freetype/src/lzw/Jamfile | 16 - freetype/src/lzw/ftlzw.c | 15 +- freetype/src/lzw/ftzopen.c | 8 +- freetype/src/lzw/ftzopen.h | 8 +- freetype/src/lzw/rules.mk | 2 +- freetype/src/otvalid/Jamfile | 37 - freetype/src/otvalid/module.mk | 2 +- freetype/src/otvalid/otvalid.c | 3 +- freetype/src/otvalid/otvalid.h | 11 +- freetype/src/otvalid/otvbase.c | 2 +- freetype/src/otvalid/otvcommn.c | 5 +- freetype/src/otvalid/otvcommn.h | 5 +- freetype/src/otvalid/otverror.h | 6 +- freetype/src/otvalid/otvgdef.c | 2 +- freetype/src/otvalid/otvgpos.c | 2 +- freetype/src/otvalid/otvgpos.h | 2 +- freetype/src/otvalid/otvgsub.c | 2 +- freetype/src/otvalid/otvjstf.c | 2 +- freetype/src/otvalid/otvmath.c | 2 +- freetype/src/otvalid/otvmod.c | 13 +- freetype/src/otvalid/otvmod.h | 5 +- freetype/src/otvalid/rules.mk | 2 +- freetype/src/pcf/Jamfile | 32 - freetype/src/pcf/pcf.c | 1 - freetype/src/pcf/pcf.h | 5 +- freetype/src/pcf/pcfdrivr.c | 36 +- freetype/src/pcf/pcfdrivr.h | 3 +- freetype/src/pcf/pcferror.h | 4 +- freetype/src/pcf/pcfread.c | 27 +- freetype/src/pcf/pcfread.h | 1 - freetype/src/pcf/pcfutil.c | 1 - freetype/src/pcf/pcfutil.h | 2 +- freetype/src/pfr/Jamfile | 35 - freetype/src/pfr/module.mk | 2 +- freetype/src/pfr/pfr.c | 3 +- freetype/src/pfr/pfrcmap.c | 5 +- freetype/src/pfr/pfrcmap.h | 5 +- freetype/src/pfr/pfrdrivr.c | 11 +- freetype/src/pfr/pfrdrivr.h | 5 +- freetype/src/pfr/pfrerror.h | 6 +- freetype/src/pfr/pfrgload.c | 8 +- freetype/src/pfr/pfrgload.h | 2 +- freetype/src/pfr/pfrload.c | 6 +- freetype/src/pfr/pfrload.h | 4 +- freetype/src/pfr/pfrobjs.c | 10 +- freetype/src/pfr/pfrobjs.h | 2 +- freetype/src/pfr/pfrsbit.c | 8 +- freetype/src/pfr/pfrsbit.h | 2 +- freetype/src/pfr/pfrtypes.h | 5 +- freetype/src/pfr/rules.mk | 2 +- freetype/src/psaux/Jamfile | 45 - freetype/src/psaux/afmparse.c | 9 +- freetype/src/psaux/afmparse.h | 5 +- freetype/src/psaux/cffdecode.c | 16 +- freetype/src/psaux/cffdecode.h | 5 +- freetype/src/psaux/module.mk | 2 +- freetype/src/psaux/psarrst.c | 2 +- freetype/src/psaux/psaux.c | 3 +- freetype/src/psaux/psauxerr.h | 6 +- freetype/src/psaux/psauxmod.c | 11 +- freetype/src/psaux/psauxmod.h | 21 +- freetype/src/psaux/psblues.c | 2 +- freetype/src/psaux/psconv.c | 7 +- freetype/src/psaux/psconv.h | 5 +- freetype/src/psaux/pserror.h | 5 +- freetype/src/psaux/psfont.c | 3 +- freetype/src/psaux/psfont.h | 2 +- freetype/src/psaux/psft.c | 16 +- freetype/src/psaux/psft.h | 6 +- freetype/src/psaux/pshints.c | 4 +- freetype/src/psaux/psintrp.c | 16 +- freetype/src/psaux/psobjs.c | 19 +- freetype/src/psaux/psobjs.h | 7 +- freetype/src/psaux/psread.c | 2 +- freetype/src/psaux/psstack.c | 14 +- freetype/src/psaux/psstack.h | 1 + freetype/src/psaux/pstypes.h | 3 +- freetype/src/psaux/rules.mk | 2 +- freetype/src/psaux/t1cmap.c | 4 +- freetype/src/psaux/t1cmap.h | 7 +- freetype/src/psaux/t1decode.c | 215 +- freetype/src/psaux/t1decode.h | 7 +- freetype/src/pshinter/Jamfile | 34 - freetype/src/pshinter/module.mk | 2 +- freetype/src/pshinter/pshalgo.c | 9 +- freetype/src/pshinter/pshalgo.h | 2 +- freetype/src/pshinter/pshglob.c | 9 +- freetype/src/pshinter/pshglob.h | 6 +- freetype/src/pshinter/pshinter.c | 3 +- freetype/src/pshinter/pshmod.c | 6 +- freetype/src/pshinter/pshmod.h | 5 +- freetype/src/pshinter/pshnterr.h | 6 +- freetype/src/pshinter/pshrec.c | 13 +- freetype/src/pshinter/pshrec.h | 5 +- freetype/src/pshinter/rules.mk | 2 +- freetype/src/psnames/Jamfile | 31 - freetype/src/psnames/module.mk | 2 +- freetype/src/psnames/psmodule.c | 9 +- freetype/src/psnames/psmodule.h | 5 +- freetype/src/psnames/psnamerr.h | 6 +- freetype/src/psnames/psnames.c | 3 +- freetype/src/psnames/pstables.h | 2 +- freetype/src/psnames/rules.mk | 2 +- freetype/src/raster/Jamfile | 32 - freetype/src/raster/ftmisc.h | 2 +- freetype/src/raster/ftraster.c | 121 +- freetype/src/raster/ftraster.h | 5 +- freetype/src/raster/ftrend1.c | 9 +- freetype/src/raster/ftrend1.h | 5 +- freetype/src/raster/module.mk | 2 +- freetype/src/raster/raster.c | 3 +- freetype/src/raster/rasterrs.h | 6 +- freetype/src/raster/rules.mk | 2 +- freetype/src/sfnt/Jamfile | 42 - freetype/src/sfnt/module.mk | 2 +- freetype/src/sfnt/pngshim.c | 31 +- freetype/src/sfnt/pngshim.h | 3 +- freetype/src/sfnt/rules.mk | 30 +- freetype/src/sfnt/sfdriver.c | 27 +- freetype/src/sfnt/sfdriver.h | 5 +- freetype/src/sfnt/sferrors.h | 6 +- freetype/src/sfnt/sfnt.c | 5 +- freetype/src/sfnt/sfobjs.c | 61 +- freetype/src/sfnt/sfobjs.h | 7 +- freetype/src/sfnt/sfwoff.c | 21 +- freetype/src/sfnt/sfwoff.h | 7 +- freetype/src/sfnt/sfwoff2.c | 2337 +++ freetype/src/sfnt/sfwoff2.h | 75 + freetype/src/sfnt/ttbdf.c | 9 +- freetype/src/sfnt/ttbdf.h | 5 +- freetype/src/sfnt/ttcmap.c | 42 +- freetype/src/sfnt/ttcmap.h | 14 +- freetype/src/sfnt/ttcmapc.h | 2 +- freetype/src/sfnt/ttcolr.c | 17 +- freetype/src/sfnt/ttcolr.h | 3 +- freetype/src/sfnt/ttcpal.c | 23 +- freetype/src/sfnt/ttcpal.h | 3 +- freetype/src/sfnt/ttkern.c | 9 +- freetype/src/sfnt/ttkern.h | 7 +- freetype/src/sfnt/ttload.c | 27 +- freetype/src/sfnt/ttload.h | 7 +- freetype/src/sfnt/ttmtx.c | 11 +- freetype/src/sfnt/ttmtx.h | 7 +- freetype/src/sfnt/ttpost.c | 13 +- freetype/src/sfnt/ttpost.h | 4 +- freetype/src/sfnt/ttsbit.c | 13 +- freetype/src/sfnt/ttsbit.h | 3 +- freetype/src/sfnt/woff2tags.c | 109 + freetype/src/sfnt/woff2tags.h | 39 + freetype/src/smooth/Jamfile | 32 - freetype/src/smooth/ftgrays.c | 13 +- freetype/src/smooth/ftgrays.h | 4 +- freetype/src/smooth/ftsmerrs.h | 6 +- freetype/src/smooth/ftsmooth.c | 702 +- freetype/src/smooth/ftsmooth.h | 9 +- freetype/src/smooth/module.mk | 6 +- freetype/src/smooth/rules.mk | 2 +- freetype/src/smooth/smooth.c | 3 +- freetype/src/tools/Jamfile | 5 - freetype/src/tools/afblue.pl | 2 +- freetype/src/tools/ftrandom/ftrandom.c | 4 +- freetype/src/tools/glnames.py | 2 +- freetype/src/tools/make_distribution_archives.py | 208 + freetype/src/tools/test_afm.c | 7 +- freetype/src/tools/test_bbox.c | 5 +- freetype/src/tools/test_trig.c | 5 +- freetype/src/tools/update-copyright-year | 2 +- freetype/src/truetype/Jamfile | 37 - freetype/src/truetype/module.mk | 2 +- freetype/src/truetype/rules.mk | 2 +- freetype/src/truetype/truetype.c | 3 +- freetype/src/truetype/ttdriver.c | 25 +- freetype/src/truetype/ttdriver.h | 5 +- freetype/src/truetype/tterrors.h | 6 +- freetype/src/truetype/ttgload.c | 83 +- freetype/src/truetype/ttgload.h | 3 +- freetype/src/truetype/ttgxvar.c | 149 +- freetype/src/truetype/ttgxvar.h | 3 +- freetype/src/truetype/ttinterp.c | 519 +- freetype/src/truetype/ttinterp.h | 5 +- freetype/src/truetype/ttobjs.c | 21 +- freetype/src/truetype/ttobjs.h | 7 +- freetype/src/truetype/ttpload.c | 29 +- freetype/src/truetype/ttpload.h | 5 +- freetype/src/truetype/ttsubpix.c | 17 +- freetype/src/truetype/ttsubpix.h | 3 +- freetype/src/type1/Jamfile | 35 - freetype/src/type1/module.mk | 2 +- freetype/src/type1/rules.mk | 2 +- freetype/src/type1/t1afm.c | 9 +- freetype/src/type1/t1afm.h | 5 +- freetype/src/type1/t1driver.c | 31 +- freetype/src/type1/t1driver.h | 5 +- freetype/src/type1/t1errors.h | 6 +- freetype/src/type1/t1gload.c | 19 +- freetype/src/type1/t1gload.h | 3 +- freetype/src/type1/t1load.c | 60 +- freetype/src/type1/t1load.h | 9 +- freetype/src/type1/t1objs.c | 21 +- freetype/src/type1/t1objs.h | 6 +- freetype/src/type1/t1parse.c | 9 +- freetype/src/type1/t1parse.h | 7 +- freetype/src/type1/t1tokens.h | 2 +- freetype/src/type1/type1.c | 3 +- freetype/src/type42/Jamfile | 32 - freetype/src/type42/module.mk | 2 +- freetype/src/type42/rules.mk | 2 +- freetype/src/type42/t42drivr.c | 12 +- freetype/src/type42/t42drivr.h | 5 +- freetype/src/type42/t42error.h | 6 +- freetype/src/type42/t42objs.c | 8 +- freetype/src/type42/t42objs.h | 17 +- freetype/src/type42/t42parse.c | 10 +- freetype/src/type42/t42parse.h | 4 +- freetype/src/type42/t42types.h | 11 +- freetype/src/type42/type42.c | 3 +- freetype/src/winfonts/Jamfile | 16 - freetype/src/winfonts/fnterrs.h | 6 +- freetype/src/winfonts/module.mk | 2 +- freetype/src/winfonts/rules.mk | 2 +- freetype/src/winfonts/winfnt.c | 23 +- freetype/src/winfonts/winfnt.h | 7 +- freetype/vms_make.com | 2 +- ijs/Makefile.am | 2 +- ijs/configure.ac | 2 +- ijs/ijs.c | 2 +- ijs/ijs.h | 2 +- ijs/ijs_client.c | 2 +- ijs/ijs_client.h | 2 +- ijs/ijs_client_example.c | 2 +- ijs/ijs_exec_unix.c | 2 +- ijs/ijs_exec_win.c | 2 +- ijs/ijs_server.c | 2 +- ijs/ijs_server.h | 2 +- ijs/ijs_server_example.c | 2 +- ijs/unistd_.h | 2 +- install-sh | 161 +- ios/build_ios_gslib.sh | 4 +- ios/ios_arch-arm.h | 18 +- ios/ios_arch-x86.h | 14 +- jbig2dec/config_win32.h | 2 +- jbig2dec/jbig2.c | 2 +- jbig2dec/jbig2.h | 2 +- jbig2dec/jbig2_arith.c | 2 +- jbig2dec/jbig2_arith.h | 2 +- jbig2dec/jbig2_arith_iaid.c | 2 +- jbig2dec/jbig2_arith_iaid.h | 2 +- jbig2dec/jbig2_arith_int.c | 2 +- jbig2dec/jbig2_arith_int.h | 2 +- jbig2dec/jbig2_generic.c | 2 +- jbig2dec/jbig2_generic.h | 2 +- jbig2dec/jbig2_halftone.c | 12 +- jbig2dec/jbig2_halftone.h | 2 +- jbig2dec/jbig2_huffman.c | 2 +- jbig2dec/jbig2_huffman.h | 2 +- jbig2dec/jbig2_hufftab.c | 2 +- jbig2dec/jbig2_hufftab.h | 2 +- jbig2dec/jbig2_image.c | 6 +- jbig2dec/jbig2_image.h | 2 +- jbig2dec/jbig2_image_pbm.c | 2 +- jbig2dec/jbig2_image_png.c | 2 +- jbig2dec/jbig2_image_rw.h | 2 +- jbig2dec/jbig2_mmr.c | 21 +- jbig2dec/jbig2_mmr.h | 2 +- jbig2dec/jbig2_page.c | 2 +- jbig2dec/jbig2_page.h | 2 +- jbig2dec/jbig2_priv.h | 2 +- jbig2dec/jbig2_refinement.c | 2 +- jbig2dec/jbig2_refinement.h | 2 +- jbig2dec/jbig2_segment.c | 2 +- jbig2dec/jbig2_segment.h | 2 +- jbig2dec/jbig2_symbol_dict.c | 2 +- jbig2dec/jbig2_symbol_dict.h | 2 +- jbig2dec/jbig2_text.c | 2 +- jbig2dec/jbig2_text.h | 2 +- jbig2dec/jbig2dec.c | 2 +- jbig2dec/memcmp.c | 2 +- jbig2dec/memento.c | 2 +- jbig2dec/memento.h | 2 +- jbig2dec/os_types.h | 2 +- jbig2dec/pbm2png.c | 2 +- lcms2mt/COPYING | 19 +- lcms2mt/ChangeLog | 26 + lcms2mt/Makefile.am | 24 +- lcms2mt/Makefile.in | 75 +- lcms2mt/Projects/BorlandC_5.5/lcms2mt.rc | 12 +- lcms2mt/Projects/VC2013/lcms2mt.rc | 4 +- lcms2mt/Projects/VC2015/lcms2mt.rc | 10 +- lcms2mt/Projects/VC2017/lcms2mt.rc | 10 +- lcms2mt/Projects/VC2019/lcms2mt.rc | 10 +- .../VC2019/lcms2mt_static/lcms2mt_static.vcxproj | 2 +- lcms2mt/Projects/VC2019/linkicc/linkicc.vcxproj | 4 +- lcms2mt/Projects/VC2019/tiffdiff/tiffdiff.vcxproj | 16 +- lcms2mt/Projects/VC2019/tifficc/tifficc.vcxproj | 16 +- lcms2mt/README.1ST | 8 +- lcms2mt/aclocal.m4 | 191 +- lcms2mt/configure | 404 +- lcms2mt/configure.ac | 51 +- lcms2mt/include/Makefile.in | 14 +- lcms2mt/include/lcms2mt.h | 9 +- lcms2mt/include/lcms2mt_plugin.h | 33 +- lcms2mt/lcms2mt.pc.in | 2 +- .../VC2019/lcms2mt_fast_float_plugin.vcxproj | 2 + .../lcms2mt_fast_float_plugin.vcxproj.filters | 12 +- .../fast_float/include/lcms2mt_fast_float.h | 15 +- lcms2mt/plugins/fast_float/src/Makefile.am | 9 +- lcms2mt/plugins/fast_float/src/fast_16_tethra.c | 20 +- lcms2mt/plugins/fast_float/src/fast_8_curves.c | 16 +- lcms2mt/plugins/fast_float/src/fast_8_matsh.c | 58 +- lcms2mt/plugins/fast_float/src/fast_8_tethra.c | 15 +- lcms2mt/plugins/fast_float/src/fast_float_15bits.c | 11 +- lcms2mt/plugins/fast_float/src/fast_float_15mats.c | 3 + lcms2mt/plugins/fast_float/src/fast_float_cmyk.c | 297 +- lcms2mt/plugins/fast_float/src/fast_float_curves.c | 265 +- .../plugins/fast_float/src/fast_float_internal.h | 91 +- lcms2mt/plugins/fast_float/src/fast_float_matsh.c | 98 +- .../plugins/fast_float/src/fast_float_separate.c | 2 +- lcms2mt/plugins/fast_float/src/fast_float_sup.c | 50 +- lcms2mt/plugins/fast_float/src/fast_float_tethra.c | 224 +- lcms2mt/plugins/fast_float/testbed/Makefile.am | 12 +- .../fast_float/testbed/fast_float_testbed.c | 524 +- lcms2mt/plugins/fast_float/testbed/test0.icc | Bin 560 -> 568 bytes lcms2mt/src/Makefile.in | 148 +- lcms2mt/src/cmsalpha.c | 27 +- lcms2mt/src/cmscgats.c | 21 +- lcms2mt/src/cmscnvrt.c | 93 +- lcms2mt/src/cmsgamma.c | 76 +- lcms2mt/src/cmsintrp.c | 534 +- lcms2mt/src/cmsio0.c | 31 +- lcms2mt/src/cmslut.c | 12 +- lcms2mt/src/cmsnamed.c | 20 +- lcms2mt/src/cmsopt.c | 28 +- lcms2mt/src/cmspack.c | 2 +- lcms2mt/src/cmspcs.c | 2 +- lcms2mt/src/cmsplugin.c | 39 +- lcms2mt/src/cmsps2.c | 11 +- lcms2mt/src/cmssamp.c | 4 +- lcms2mt/src/cmstypes.c | 20 +- lcms2mt/src/cmsxform.c | 85 +- lcms2mt/src/extra_xform.h | 4 +- lcms2mt/src/lcms2_internal.h | 34 +- lcms2mt/src/lcms2mt.def | 1 + lcms2mt/testbed/Makefile.am | 4 +- lcms2mt/testbed/Makefile.in | 42 +- lcms2mt/testbed/testcms2.c | 172 +- lcms2mt/testbed/testcms2.h | 4 + lcms2mt/testbed/testplugin.c | 35 +- lcms2mt/testbed/zoo_icc.c | 2 +- lcms2mt/utils/common/utils.h | 2 - lcms2mt/utils/common/vprf.c | 6 +- lcms2mt/utils/common/xgetopt.c | 121 +- lcms2mt/utils/jpgicc/Makefile.in | 16 +- lcms2mt/utils/jpgicc/jpgicc.c | 133 +- lcms2mt/utils/linkicc/Makefile.in | 16 +- lcms2mt/utils/linkicc/linkicc.c | 318 +- lcms2mt/utils/matlab/lcms_rsp | 53 +- lcms2mt/utils/psicc/Makefile.in | 16 +- lcms2mt/utils/psicc/psicc.c | 77 +- lcms2mt/utils/tificc/Makefile.in | 16 +- lcms2mt/utils/tificc/tifdiff.c | 12 +- lcms2mt/utils/tificc/tificc.c | 130 +- lcms2mt/utils/transicc/Makefile.in | 16 +- lcms2mt/utils/transicc/transicc.c | 65 +- leptonica/.github/workflows/sw.yml | 23 + leptonica/.travis.yml | 65 + leptonica/CMakeLists.txt | 294 + leptonica/Doxyfile | 2432 +++ leptonica/Makefile.am | 85 + leptonica/README.html | 1233 ++ leptonica/README.md | 82 + leptonica/appveyor.yml | 39 + leptonica/autogen.sh | 15 + leptonica/cmake/Configure.cmake | 164 + .../templates/LeptonicaConfig-version.cmake.in | 14 + leptonica/cmake/templates/LeptonicaConfig.cmake.in | 45 + leptonica/cmake/templates/cmake_uninstall.cmake.in | 22 + leptonica/configure.ac | 276 + leptonica/lept.pc.cmake | 11 + leptonica/lept.pc.in | 12 + leptonica/leptonica-license.txt | 26 + leptonica/lok.lua | 157 + leptonica/m4/ax_split_version.m4 | 38 + leptonica/make-for-auto | 8 + leptonica/make-for-local | 8 + leptonica/moller52.jpg | Bin 0 -> 9610 bytes leptonica/prog/1555.003.jpg | Bin 0 -> 198621 bytes leptonica/prog/1555.007.jpg | Bin 0 -> 209558 bytes leptonica/prog/19-colors.png | Bin 0 -> 627 bytes leptonica/prog/CMakeLists.txt | 322 + leptonica/prog/Leptonica.jpg | Bin 0 -> 6723 bytes leptonica/prog/Makefile.am | 138 + leptonica/prog/adaptmap_dark.c | 198 + leptonica/prog/adaptmap_reg.c | 208 + leptonica/prog/adaptnorm_reg.c | 154 + leptonica/prog/affine_reg.c | 425 + leptonica/prog/alltests_reg.c | 282 + leptonica/prog/alphaops_reg.c | 337 + leptonica/prog/alphaxform_reg.c | 230 + leptonica/prog/amoris.2.150.jpg | Bin 0 -> 256907 bytes leptonica/prog/aneurisms8.jpg | Bin 0 -> 13702 bytes leptonica/prog/arabic.png | Bin 0 -> 128175 bytes leptonica/prog/arabic2.png | Bin 0 -> 107581 bytes leptonica/prog/arabic_lines.c | 166 + leptonica/prog/arithtest.c | 83 + leptonica/prog/autogen.137.c | 98 + leptonica/prog/autogen.137.h | 306 + leptonica/prog/autogentest1.c | 80 + leptonica/prog/autogentest2.c | 69 + leptonica/prog/barcode-128-300.png | Bin 0 -> 2667 bytes leptonica/prog/barcode-2of5-300.png | Bin 0 -> 2446 bytes leptonica/prog/barcode-39-300.png | Bin 0 -> 3608 bytes leptonica/prog/barcode-93-300.png | Bin 0 -> 2405 bytes leptonica/prog/barcode-codabar-300.png | Bin 0 -> 2929 bytes leptonica/prog/barcode-digits.png | Bin 0 -> 619 bytes leptonica/prog/barcode-i2of5-300.png | Bin 0 -> 2325 bytes leptonica/prog/barcode-upc-300.png | Bin 0 -> 5351 bytes leptonica/prog/barcodetest.c | 90 + leptonica/prog/barcodetest1.jpg | Bin 0 -> 19862 bytes leptonica/prog/barcodetest2.jpg | Bin 0 -> 8320 bytes leptonica/prog/baseline_reg.c | 135 + leptonica/prog/bigweasel2.4c.png | Bin 0 -> 1206 bytes leptonica/prog/bilateral1_reg.c | 136 + leptonica/prog/bilateral2_reg.c | 105 + leptonica/prog/bilinear_reg.c | 263 + leptonica/prog/binarize_reg.c | 180 + leptonica/prog/binarize_set.c | 177 + leptonica/prog/binarizefiles.c | 120 + leptonica/prog/bincompare.c | 98 + leptonica/prog/binding-example.45.jpg | Bin 0 -> 73283 bytes leptonica/prog/binmorph1_reg.c | 578 + leptonica/prog/binmorph2_reg.c | 227 + leptonica/prog/binmorph3_reg.c | 404 + leptonica/prog/binmorph4_reg.c | 544 + leptonica/prog/binmorph5_reg.c | 329 + leptonica/prog/binmorph6_reg.c | 89 + leptonica/prog/blackwhite_reg.c | 114 + leptonica/prog/blend-green1.jpg | Bin 0 -> 13979 bytes leptonica/prog/blend-green2.png | Bin 0 -> 7770 bytes leptonica/prog/blend-green3.png | Bin 0 -> 4570 bytes leptonica/prog/blend-orange.jpg | Bin 0 -> 15094 bytes leptonica/prog/blend-red.png | Bin 0 -> 3945 bytes leptonica/prog/blend-yellow.jpg | Bin 0 -> 17918 bytes leptonica/prog/blend1_reg.c | 328 + leptonica/prog/blend2_reg.c | 182 + leptonica/prog/blend3_reg.c | 216 + leptonica/prog/blend4_reg.c | 102 + leptonica/prog/blend5_reg.c | 182 + leptonica/prog/blendcmaptest.c | 112 + leptonica/prog/blender1.tif | Bin 0 -> 496 bytes leptonica/prog/blender8.png | Bin 0 -> 1811 bytes leptonica/prog/blendtext.tif | Bin 0 -> 496 bytes leptonica/prog/bois-2.tif | Bin 0 -> 31732 bytes leptonica/prog/bois-3.tif | Bin 0 -> 40290 bytes leptonica/prog/bois-4.tif | Bin 0 -> 48922 bytes leptonica/prog/bois-5.tif | Bin 0 -> 48784 bytes leptonica/prog/books_logo.png | Bin 0 -> 23078 bytes leptonica/prog/boxa1.ba | 47 + leptonica/prog/boxa1_reg.c | 161 + leptonica/prog/boxa2.ba | 379 + leptonica/prog/boxa2_reg.c | 196 + leptonica/prog/boxa3.ba | 379 + leptonica/prog/boxa3_reg.c | 202 + leptonica/prog/boxa4.ba | 55 + leptonica/prog/boxa4_reg.c | 226 + leptonica/prog/boxa5.ba | 21 + leptonica/prog/boxap1.ba | 129 + leptonica/prog/boxap2.ba | 303 + leptonica/prog/boxap3.ba | 15 + leptonica/prog/boxap4.ba | 53 + leptonica/prog/boxap5.ba | 553 + leptonica/prog/boxedpage.jpg | Bin 0 -> 61244 bytes leptonica/prog/brev.06.75.jpg | Bin 0 -> 33364 bytes leptonica/prog/brev.10.75.jpg | Bin 0 -> 42274 bytes leptonica/prog/brev.14.75.jpg | Bin 0 -> 37460 bytes leptonica/prog/brev.20.75.jpg | Bin 0 -> 38733 bytes leptonica/prog/brev.36.75.jpg | Bin 0 -> 41245 bytes leptonica/prog/brev.53.75.jpg | Bin 0 -> 28953 bytes leptonica/prog/brev.56.75.jpg | Bin 0 -> 41320 bytes leptonica/prog/breviar.38.150.jpg | Bin 0 -> 146456 bytes leptonica/prog/brothers.150.jpg | Bin 0 -> 81310 bytes leptonica/prog/buffertest.c | 114 + leptonica/prog/bytea_reg.c | 180 + leptonica/prog/candelabrum.011.jpg | Bin 0 -> 59408 bytes leptonica/prog/cat-and-mouse.png | Bin 0 -> 15550 bytes leptonica/prog/cat.007.jpg | Bin 0 -> 139783 bytes leptonica/prog/cat.035.jpg | Bin 0 -> 140334 bytes leptonica/prog/cavalerie.11.jpg | Bin 0 -> 240511 bytes leptonica/prog/cavalerie.29.jpg | Bin 0 -> 198691 bytes leptonica/prog/ccbord_reg.c | 231 + leptonica/prog/ccbordtest.c | 246 + leptonica/prog/cctest1.c | 125 + leptonica/prog/ccthin1_reg.c | 202 + leptonica/prog/ccthin2_reg.c | 192 + leptonica/prog/char.tif | Bin 0 -> 232 bytes leptonica/prog/chars-10.tif | Bin 0 -> 2788 bytes leptonica/prog/chars-12.tif | Bin 0 -> 3250 bytes leptonica/prog/chars-14.tif | Bin 0 -> 3612 bytes leptonica/prog/chars-16.tif | Bin 0 -> 4066 bytes leptonica/prog/chars-18.tif | Bin 0 -> 4530 bytes leptonica/prog/chars-20.tif | Bin 0 -> 5004 bytes leptonica/prog/chars-4.tif | Bin 0 -> 1446 bytes leptonica/prog/chars-6.tif | Bin 0 -> 1860 bytes leptonica/prog/chars-8.tif | Bin 0 -> 2340 bytes leptonica/prog/checkerboard1.tif | Bin 0 -> 1228 bytes leptonica/prog/checkerboard2.tif | Bin 0 -> 3086 bytes leptonica/prog/checkerboard_reg.c | 94 + leptonica/prog/church.png | Bin 0 -> 65442 bytes leptonica/prog/circle_reg.c | 140 + leptonica/prog/circles.pa | Bin 0 -> 4334 bytes leptonica/prog/cleanpdf.c | 278 + leptonica/prog/cmapquant_reg.c | 136 + leptonica/prog/coffeebeans.png | Bin 0 -> 2449 bytes leptonica/prog/color-wheel-hue.jpg | Bin 0 -> 7684 bytes leptonica/prog/colorcontent_reg.c | 170 + leptonica/prog/colorfill_reg.c | 167 + leptonica/prog/coloring_reg.c | 158 + leptonica/prog/colorize_reg.c | 290 + leptonica/prog/colormask_reg.c | 158 + leptonica/prog/colormorph_reg.c | 101 + leptonica/prog/colorpage.030.jpg | Bin 0 -> 57025 bytes leptonica/prog/colorquant_reg.c | 241 + leptonica/prog/colorseg.jpg | Bin 0 -> 55238 bytes leptonica/prog/colorseg_reg.c | 113 + leptonica/prog/colorsegtest.c | 109 + leptonica/prog/colorspace_reg.c | 208 + leptonica/prog/comap.063.jpg | Bin 0 -> 34357 bytes leptonica/prog/comap.068.jpg | Bin 0 -> 30426 bytes leptonica/prog/comap.073.jpg | Bin 0 -> 29973 bytes leptonica/prog/comap.100.jpg | Bin 0 -> 38859 bytes leptonica/prog/comap.110.jpg | Bin 0 -> 47121 bytes leptonica/prog/comap.118.jpg | Bin 0 -> 42039 bytes leptonica/prog/compare_reg.c | 143 + leptonica/prog/comparepages.c | 116 + leptonica/prog/comparepixa.c | 101 + leptonica/prog/comparetest.c | 159 + leptonica/prog/compfilter_reg.c | 346 + leptonica/prog/concatpdf.c | 177 + leptonica/prog/conncomp_reg.c | 163 + leptonica/prog/contrast-orig-60.jpg | Bin 0 -> 107226 bytes leptonica/prog/contrast1.jpg | Bin 0 -> 23371 bytes leptonica/prog/contrasttest.c | 94 + leptonica/prog/conversion_reg.c | 424 + leptonica/prog/convertfilestopdf.c | 109 + leptonica/prog/convertfilestops.c | 85 + leptonica/prog/convertformat.c | 181 + leptonica/prog/convertsegfilestopdf.c | 162 + leptonica/prog/convertsegfilestops.c | 137 + leptonica/prog/converttogray.c | 123 + leptonica/prog/converttopdf.c | 78 + leptonica/prog/converttops.c | 68 + leptonica/prog/convolve_reg.c | 211 + leptonica/prog/cootoots.png | Bin 0 -> 12806 bytes leptonica/prog/copernicus.png | Bin 0 -> 53027 bytes leptonica/prog/cornertest.c | 104 + leptonica/prog/corrupttest.c | 271 + leptonica/prog/crop_reg.c | 320 + leptonica/prog/croptext.c | 99 + leptonica/prog/dave-orig.png | Bin 0 -> 188112 bytes leptonica/prog/deskew_it.c | 140 + leptonica/prog/dewarp_reg.c | 211 + leptonica/prog/dewarprules.c | 176 + leptonica/prog/dewarptest1.c | 182 + leptonica/prog/dewarptest2.c | 123 + leptonica/prog/dewarptest3.c | 167 + leptonica/prog/dewarptest4.c | 123 + leptonica/prog/dewarptest5.c | 140 + leptonica/prog/digitprep1.c | 106 + leptonica/prog/dinos.pac | Bin 0 -> 244424 bytes leptonica/prog/displayboxa.c | 91 + leptonica/prog/displayboxes_on_pixa.c | 98 + leptonica/prog/displaypix.c | 61 + leptonica/prog/displaypixa.c | 176 + leptonica/prog/distance_reg.c | 158 + leptonica/prog/dither_reg.c | 86 + leptonica/prog/dna_reg.c | 123 + leptonica/prog/dreyfus1.png | Bin 0 -> 10341 bytes leptonica/prog/dreyfus2.png | Bin 0 -> 17827 bytes leptonica/prog/dreyfus4.png | Bin 0 -> 22525 bytes leptonica/prog/dreyfus8.png | Bin 0 -> 34971 bytes leptonica/prog/dwalinear.3.c | 343 + leptonica/prog/dwalineargen.c | 79 + leptonica/prog/dwalinearlow.3.c | 16986 +++++++++++++++++ leptonica/prog/dwamorph1_reg.c | 244 + leptonica/prog/dwamorph2_reg.c | 321 + leptonica/prog/edge_reg.c | 90 + leptonica/prog/encoding_reg.c | 107 + leptonica/prog/enhance_reg.c | 298 + leptonica/prog/equal_reg.c | 139 + leptonica/prog/expand_reg.c | 165 + leptonica/prog/extrema_reg.c | 102 + leptonica/prog/falsecolor_reg.c | 93 + leptonica/prog/fcombautogen.c | 80 + leptonica/prog/feyn-fract.tif | Bin 0 -> 11520 bytes leptonica/prog/feyn-fract2.tif | Bin 0 -> 4952 bytes leptonica/prog/feyn-word.tif | Bin 0 -> 426 bytes leptonica/prog/feyn.tif | Bin 0 -> 104796 bytes leptonica/prog/feynman-stamp.jpg | Bin 0 -> 14394 bytes leptonica/prog/fhmtauto_reg.c | 90 + leptonica/prog/fhmtautogen.c | 74 + leptonica/prog/fileinfo.c | 52 + leptonica/prog/files_reg.c | 290 + leptonica/prog/find_colorregions.c | 343 + leptonica/prog/findbinding.c | 164 + leptonica/prog/findcorners_reg.c | 210 + leptonica/prog/findpattern1.c | 145 + leptonica/prog/findpattern2.c | 161 + leptonica/prog/findpattern3.c | 160 + leptonica/prog/findpattern_reg.c | 173 + leptonica/prog/fish24.jpg | Bin 0 -> 103695 bytes leptonica/prog/flipdetect_reg.c | 119 + leptonica/prog/flipselgen.c.notused | 124 + leptonica/prog/flipsels.txt | 35 + leptonica/prog/fmorphauto_reg.c | 163 + leptonica/prog/fmorphautogen.c | 74 + leptonica/prog/fonts/chars-10.pa | Bin 0 -> 17399 bytes leptonica/prog/fonts/chars-10.ps | 21 + leptonica/prog/fonts/chars-10.tif | Bin 0 -> 2858 bytes leptonica/prog/fonts/chars-12.pa | Bin 0 -> 18554 bytes leptonica/prog/fonts/chars-12.ps | 21 + leptonica/prog/fonts/chars-12.tif | Bin 0 -> 3342 bytes leptonica/prog/fonts/chars-14.pa | Bin 0 -> 19414 bytes leptonica/prog/fonts/chars-14.ps | 21 + leptonica/prog/fonts/chars-14.tif | Bin 0 -> 3680 bytes leptonica/prog/fonts/chars-16.pa | Bin 0 -> 20343 bytes leptonica/prog/fonts/chars-16.ps | 21 + leptonica/prog/fonts/chars-16.tif | Bin 0 -> 4142 bytes leptonica/prog/fonts/chars-18.pa | Bin 0 -> 21457 bytes leptonica/prog/fonts/chars-18.ps | 21 + leptonica/prog/fonts/chars-18.tif | Bin 0 -> 4606 bytes leptonica/prog/fonts/chars-20.pa | Bin 0 -> 22376 bytes leptonica/prog/fonts/chars-20.ps | 21 + leptonica/prog/fonts/chars-20.tif | Bin 0 -> 5070 bytes leptonica/prog/fonts/chars-4.pa | Bin 0 -> 13693 bytes leptonica/prog/fonts/chars-4.ps | 21 + leptonica/prog/fonts/chars-4.tif | Bin 0 -> 1508 bytes leptonica/prog/fonts/chars-6.pa | Bin 0 -> 14988 bytes leptonica/prog/fonts/chars-6.ps | 21 + leptonica/prog/fonts/chars-6.tif | Bin 0 -> 1928 bytes leptonica/prog/fonts/chars-8.pa | Bin 0 -> 16217 bytes leptonica/prog/fonts/chars-8.ps | 21 + leptonica/prog/fonts/chars-8.tif | Bin 0 -> 2416 bytes leptonica/prog/form1.tif | Bin 0 -> 6074 bytes leptonica/prog/form2.tif | Bin 0 -> 5116 bytes leptonica/prog/fpix1_reg.c | 364 + leptonica/prog/fpix2_reg.c | 116 + leptonica/prog/fpixcontours.c | 76 + leptonica/prog/fuzzing/README.md | 25 + leptonica/prog/fuzzing/adaptmap_fuzzer.cc | 75 + leptonica/prog/fuzzing/affine_fuzzer.cc | 40 + leptonica/prog/fuzzing/barcode_fuzzer.cc | 22 + .../prog/fuzzing/barcode_fuzzer_seed_corpus.zip | Bin 0 -> 51247 bytes leptonica/prog/fuzzing/baseline_fuzzer.cc | 24 + leptonica/prog/fuzzing/bilateral_fuzzer.cc | 25 + leptonica/prog/fuzzing/bilinear_fuzzer.cc | 37 + leptonica/prog/fuzzing/binarize_fuzzer.cc | 55 + leptonica/prog/fuzzing/blend_fuzzer.cc | 93 + leptonica/prog/fuzzing/boxfunc3_fuzzer.cc | 107 + leptonica/prog/fuzzing/boxfunc4_fuzzer.cc | 39 + leptonica/prog/fuzzing/boxfunc5_fuzzer.cc | 51 + leptonica/prog/fuzzing/boxfunc_fuzzer.cc | 23 + leptonica/prog/fuzzing/ccbord_fuzzer.cc | 27 + leptonica/prog/fuzzing/ccthin_fuzzer.cc | 28 + leptonica/prog/fuzzing/checkerboard_fuzzer.cc | 25 + leptonica/prog/fuzzing/classapp_fuzzer.cc | 24 + leptonica/prog/fuzzing/colorfill_fuzzer.cc | 17 + leptonica/prog/fuzzing/colorquant_fuzzer.cc | 83 + leptonica/prog/fuzzing/compare_fuzzer.cc | 49 + leptonica/prog/fuzzing/dewarp_fuzzer.cc | 29 + leptonica/prog/fuzzing/edge_fuzzer.cc | 18 + leptonica/prog/fuzzing/enhance_fuzzer.cc | 101 + leptonica/prog/fuzzing/fhmtgen_fuzzer.cc | 33 + leptonica/prog/fuzzing/finditalic_fuzzer.cc | 18 + leptonica/prog/fuzzing/flipdetect_fuzzer.cc | 31 + leptonica/prog/fuzzing/fpix2_fuzzer.cc | 111 + leptonica/prog/fuzzing/general_corpus.zip | Bin 0 -> 99986 bytes leptonica/prog/fuzzing/graphics_fuzzer.cc | 81 + leptonica/prog/fuzzing/graymorph_fuzzer.cc | 36 + leptonica/prog/fuzzing/grayquant_fuzzer.cc | 47 + leptonica/prog/fuzzing/jpegiostub_fuzzer.cc | 15 + leptonica/prog/fuzzing/kernel_fuzzer.cc | 16 + leptonica/prog/fuzzing/leptfuzz.h | 16 + leptonica/prog/fuzzing/mask_fuzzer.cc | 42 + leptonica/prog/fuzzing/maze_fuzzer.cc | 24 + leptonica/prog/fuzzing/morph_fuzzer.cc | 48 + leptonica/prog/fuzzing/morphapp_fuzzer.cc | 65 + leptonica/prog/fuzzing/oss-fuzz-build.sh | 128 + leptonica/prog/fuzzing/pageseg_fuzzer.cc | 42 + leptonica/prog/fuzzing/paintcmap_fuzzer.cc | 27 + leptonica/prog/fuzzing/pix1_fuzzer.cc | 19 + leptonica/prog/fuzzing/pix3_fuzzer.cc | 133 + leptonica/prog/fuzzing/pix4_fuzzer.cc | 109 + .../prog/fuzzing/pixMirrorDetectDwa_fuzzer.cc | 20 + leptonica/prog/fuzzing/pix_orient_fuzzer.cc | 19 + leptonica/prog/fuzzing/pix_rotate_shear_fuzzer.cc | 67 + leptonica/prog/fuzzing/pixa_recog_fuzzer.cc | 49 + .../prog/fuzzing/pixa_recog_fuzzer_seed_corpus.zip | Bin 0 -> 43179 bytes leptonica/prog/fuzzing/pixconv_fuzzer.cc | 23 + leptonica/prog/fuzzing/recog_basic_fuzzer.cc | 25 + leptonica/prog/gammatest.c | 98 + leptonica/prog/genfonts_reg.c | 173 + leptonica/prog/german.png | Bin 0 -> 46306 bytes leptonica/prog/gifio_reg.c | 232 + leptonica/prog/google-searchbox.png | Bin 0 -> 3456 bytes leptonica/prog/gplotdata.example | 82 + leptonica/prog/graphicstest.c | 100 + leptonica/prog/gray-alpha.tif | Bin 0 -> 410 bytes leptonica/prog/grayfill_reg.c | 207 + leptonica/prog/graymorph1_reg.c | 332 + leptonica/prog/graymorph2_reg.c | 153 + leptonica/prog/graymorphtest.c | 103 + leptonica/prog/grayquant_reg.c | 398 + leptonica/prog/graytext.png | Bin 0 -> 4071 bytes leptonica/prog/greencover.jpg | Bin 0 -> 21727 bytes leptonica/prog/hardlight1_1.jpg | Bin 0 -> 2932 bytes leptonica/prog/hardlight1_2.jpg | Bin 0 -> 1731 bytes leptonica/prog/hardlight2_1.jpg | Bin 0 -> 2967 bytes leptonica/prog/hardlight2_2.jpg | Bin 0 -> 3475 bytes leptonica/prog/hardlight_reg.c | 140 + leptonica/prog/harmoniam-11.tif | Bin 0 -> 35522 bytes leptonica/prog/harmoniam100-11.png | Bin 0 -> 72398 bytes leptonica/prog/hash_reg.c | 471 + leptonica/prog/heap_reg.c | 155 + leptonica/prog/histoduptest.c | 267 + leptonica/prog/histotest.c | 102 + leptonica/prog/hmttemplate1.txt | 170 + leptonica/prog/hmttemplate2.txt | 103 + leptonica/prog/hole-filler.png | Bin 0 -> 30776 bytes leptonica/prog/htmlviewer.c | 286 + leptonica/prog/imagetops.c | 101 + leptonica/prog/insert_reg.c | 163 + leptonica/prog/invertedtext.tif | Bin 0 -> 694 bytes leptonica/prog/ioformats_reg.c | 921 + leptonica/prog/iomisc_reg.c | 300 + leptonica/prog/italic.png | Bin 0 -> 20761 bytes leptonica/prog/italic_reg.c | 116 + leptonica/prog/jbclass_reg.c | 211 + leptonica/prog/jbcorrelation.c | 226 + leptonica/prog/jbrankhaus.c | 224 + leptonica/prog/jbwords.c | 135 + leptonica/prog/jp2kio_reg.c | 184 + leptonica/prog/jpeg-coded.tif | Bin 0 -> 7064 bytes leptonica/prog/jpegio_reg.c | 265 + leptonica/prog/juditharismax.jpg | Bin 0 -> 149756 bytes leptonica/prog/karen8.jpg | Bin 0 -> 15966 bytes leptonica/prog/kernel_reg.c | 356 + leptonica/prog/keystone.png | Bin 0 -> 39141 bytes leptonica/prog/label_reg.c | 220 + leptonica/prog/lapide.052.100.jpg | Bin 0 -> 289835 bytes leptonica/prog/leptonica-license.txt | 26 + leptonica/prog/lightcolortest.c | 128 + leptonica/prog/lighttext.jpg | Bin 0 -> 82345 bytes leptonica/prog/lineremoval_reg.c | 124 + leptonica/prog/lion-mask.00010.tif | Bin 0 -> 422 bytes leptonica/prog/lion-mask.00016.tif | Bin 0 -> 410 bytes leptonica/prog/lion-page.00010.jpg | Bin 0 -> 53313 bytes leptonica/prog/lion-page.00011.png | Bin 0 -> 18202 bytes leptonica/prog/lion-page.00012.png | Bin 0 -> 3489 bytes leptonica/prog/lion-page.00013.png | Bin 0 -> 15806 bytes leptonica/prog/lion-page.00016.jpg | Bin 0 -> 49650 bytes leptonica/prog/lion-page.00017.png | Bin 0 -> 19845 bytes leptonica/prog/listtest.c | 279 + leptonica/prog/livre_adapt.c | 105 + leptonica/prog/livre_hmt.c | 151 + leptonica/prog/livre_makefigs.c | 107 + leptonica/prog/livre_orient.c | 94 + leptonica/prog/livre_pageseg.c | 311 + leptonica/prog/livre_seedgen.c | 75 + leptonica/prog/livre_tophat.c | 75 + leptonica/prog/locminmax_reg.c | 102 + leptonica/prog/logicops_reg.c | 178 + leptonica/prog/lowaccess_reg.c | 304 + leptonica/prog/lowsat_reg.c | 107 + leptonica/prog/lucasta-frag.jpg | Bin 0 -> 54841 bytes leptonica/prog/lucasta.047.jpg | Bin 0 -> 240757 bytes leptonica/prog/lucasta.1.300.tif | Bin 0 -> 28952 bytes leptonica/prog/lucasta.150.jpg | Bin 0 -> 103707 bytes leptonica/prog/lyra.005.jpg | Bin 0 -> 103429 bytes leptonica/prog/lyra.036.jpg | Bin 0 -> 122737 bytes leptonica/prog/lyra.5.na | 725 + leptonica/prog/makefile.static | 1236 ++ leptonica/prog/maketile.c | 118 + leptonica/prog/map.057.jpg | Bin 0 -> 45042 bytes leptonica/prog/map1.jpg | Bin 0 -> 118180 bytes leptonica/prog/maptest.c | 426 + leptonica/prog/marge.jpg | Bin 0 -> 33094 bytes leptonica/prog/maze_reg.c | 110 + leptonica/prog/messagetest.c | 181 + leptonica/prog/minisblack.tif | Bin 0 -> 746 bytes leptonica/prog/miniswhite.tif | Bin 0 -> 742 bytes leptonica/prog/misctest1.c | 331 + leptonica/prog/modifyhuesat.c | 107 + leptonica/prog/morphseq_reg.c | 121 + leptonica/prog/morphtemplate1.txt | 224 + leptonica/prog/morphtemplate2.txt | 104 + leptonica/prog/morphtest1.c | 140 + leptonica/prog/mtiff_reg.c | 378 + leptonica/prog/multitype_reg.c | 483 + leptonica/prog/nearline_reg.c | 189 + leptonica/prog/newspaper_reg.c | 171 + leptonica/prog/numa1_reg.c | 321 + leptonica/prog/numa2_reg.c | 490 + leptonica/prog/numa3_reg.c | 215 + leptonica/prog/numaranktest.c | 97 + leptonica/prog/ortiz-02.tif | Bin 0 -> 59428 bytes leptonica/prog/ortiz-03.tif | Bin 0 -> 68303 bytes leptonica/prog/ortiz-04.tif | Bin 0 -> 67339 bytes leptonica/prog/ortiz-05.tif | Bin 0 -> 69301 bytes leptonica/prog/otsutest1.c | 161 + leptonica/prog/otsutest2.c | 129 + leptonica/prog/overlap_reg.c | 261 + leptonica/prog/pageseg1.tif | Bin 0 -> 133362 bytes leptonica/prog/pageseg2-mask.png | Bin 0 -> 36764 bytes leptonica/prog/pageseg2-seed.png | Bin 0 -> 2352 bytes leptonica/prog/pageseg2.tif | Bin 0 -> 258864 bytes leptonica/prog/pageseg3.tif | Bin 0 -> 122112 bytes leptonica/prog/pageseg4.tif | Bin 0 -> 114878 bytes leptonica/prog/pageseg_reg.c | 237 + leptonica/prog/pagesegtest1.c | 71 + leptonica/prog/pagesegtest2.c | 131 + leptonica/prog/paint_reg.c | 364 + leptonica/prog/paintmask_reg.c | 215 + leptonica/prog/pancrazi.15.jpg | Bin 0 -> 91677 bytes leptonica/prog/partifytest.c | 53 + leptonica/prog/partitiontest.c | 177 + leptonica/prog/patent.png | Bin 0 -> 75966 bytes leptonica/prog/pdf2jpeg | 58 + leptonica/prog/pdf2mtiff | 51 + leptonica/prog/pdf2png | 46 + leptonica/prog/pdf2png-binary | 38 + leptonica/prog/pdf2png-color | 46 + leptonica/prog/pdf2png-gray | 46 + leptonica/prog/pdf2tiff | 47 + leptonica/prog/pdfio1_reg.c | 318 + leptonica/prog/pdfio2_reg.c | 376 + leptonica/prog/pdfseg_reg.c | 183 + leptonica/prog/pedante.079.jpg | Bin 0 -> 70343 bytes leptonica/prog/percolate-4cc.png | Bin 0 -> 5844 bytes leptonica/prog/percolate-8cc.png | Bin 0 -> 5571 bytes leptonica/prog/percolatetest.c | 322 + leptonica/prog/pixa1_reg.c | 170 + leptonica/prog/pixa2_reg.c | 121 + leptonica/prog/pixaatest.c | 109 + leptonica/prog/pixadisp_reg.c | 166 + leptonica/prog/pixafileinfo.c | 82 + leptonica/prog/pixalloc_reg.c | 208 + leptonica/prog/pixcomp_reg.c | 236 + leptonica/prog/pixmem_reg.c | 152 + leptonica/prog/pixserial_reg.c | 142 + leptonica/prog/pixtile_reg.c | 105 + leptonica/prog/plottest.c | 156 + leptonica/prog/pngio_reg.c | 477 + leptonica/prog/pnmio_reg.c | 183 + leptonica/prog/printimage.c | 158 + leptonica/prog/printsplitimage.c | 150 + leptonica/prog/printtiff.c | 98 + leptonica/prog/projection_reg.c | 155 + leptonica/prog/projectionstats.jpg | Bin 0 -> 3315 bytes leptonica/prog/projective_reg.c | 234 + leptonica/prog/ps2jpeg | 32 + leptonica/prog/ps2png | 43 + leptonica/prog/ps2png-binary | 35 + leptonica/prog/ps2png-color | 33 + leptonica/prog/ps2png-gray | 33 + leptonica/prog/ps2tiff | 42 + leptonica/prog/psio_reg.c | 250 + leptonica/prog/psioseg_reg.c | 174 + leptonica/prog/pta_reg.c | 228 + leptonica/prog/ptra1_reg.c | 488 + leptonica/prog/ptra2_reg.c | 266 + leptonica/prog/quadtree_reg.c | 141 + leptonica/prog/rabi-tiny.png | Bin 0 -> 2408 bytes leptonica/prog/rabi.png | Bin 0 -> 232718 bytes leptonica/prog/raggededge.png | Bin 0 -> 452 bytes leptonica/prog/rank_reg.c | 226 + leptonica/prog/rankbin_reg.c | 204 + leptonica/prog/rankhisto_reg.c | 135 + leptonica/prog/rasterop_reg.c | 103 + leptonica/prog/rasteropip_reg.c | 81 + leptonica/prog/rasteroptest.c | 143 + leptonica/prog/rbtreetest.c | 111 + leptonica/prog/recog/digits/bootnum1.pa | Bin 0 -> 25134 bytes leptonica/prog/recog/digits/bootnum2.pa | Bin 0 -> 24608 bytes leptonica/prog/recog/digits/bootnum3.pa | Bin 0 -> 31903 bytes leptonica/prog/recog/digits/bootnum4.pa | Bin 0 -> 39338 bytes leptonica/prog/recog/digits/digit0.comp.tif | Bin 0 -> 6354 bytes leptonica/prog/recog/digits/digit1.comp.tif | Bin 0 -> 4266 bytes leptonica/prog/recog/digits/digit2.comp.tif | Bin 0 -> 7370 bytes leptonica/prog/recog/digits/digit3.comp.tif | Bin 0 -> 7638 bytes leptonica/prog/recog/digits/digit4.comp.tif | Bin 0 -> 6154 bytes leptonica/prog/recog/digits/digit5.comp.tif | Bin 0 -> 7240 bytes leptonica/prog/recog/digits/digit5.orig-25.pa | Bin 0 -> 13207 bytes leptonica/prog/recog/digits/digit6.comp.tif | Bin 0 -> 7748 bytes leptonica/prog/recog/digits/digit7.comp.tif | Bin 0 -> 5354 bytes leptonica/prog/recog/digits/digit8.comp.tif | Bin 0 -> 8310 bytes leptonica/prog/recog/digits/digit9.comp.tif | Bin 0 -> 7840 bytes leptonica/prog/recog/digits/digit_set01.pa | Bin 0 -> 31628 bytes leptonica/prog/recog/digits/digit_set02.pa | Bin 0 -> 27769 bytes leptonica/prog/recog/digits/digit_set03.pa | Bin 0 -> 30837 bytes leptonica/prog/recog/digits/digit_set04.pa | Bin 0 -> 30919 bytes leptonica/prog/recog/digits/digit_set05.pa | Bin 0 -> 31727 bytes leptonica/prog/recog/digits/digit_set06.pa | Bin 0 -> 31833 bytes leptonica/prog/recog/digits/digit_set07.pa | Bin 0 -> 30147 bytes leptonica/prog/recog/digits/digit_set08.pa | Bin 0 -> 31465 bytes leptonica/prog/recog/digits/digit_set09.pa | Bin 0 -> 31646 bytes leptonica/prog/recog/digits/digit_set10.pa | Bin 0 -> 31606 bytes leptonica/prog/recog/digits/digit_set11.pa | Bin 0 -> 30785 bytes leptonica/prog/recog/digits/digit_set12.pa | Bin 0 -> 28035 bytes leptonica/prog/recog/digits/digit_set13.pa | Bin 0 -> 29991 bytes leptonica/prog/recog/digits/digit_set14.pa | Bin 0 -> 22769 bytes leptonica/prog/recog/digits/digit_set15.pa | Bin 0 -> 9339 bytes leptonica/prog/recog/digits/page.306.png | Bin 0 -> 1673 bytes leptonica/prog/recog/digits/page.590.png | Bin 0 -> 4181 bytes leptonica/prog/recog/sets/samples06.png | Bin 0 -> 17243 bytes leptonica/prog/recog/sets/test01.pa | Bin 0 -> 176457 bytes leptonica/prog/recog/sets/test02.pa | Bin 0 -> 162495 bytes leptonica/prog/recog/sets/test03.pa | Bin 0 -> 11701 bytes leptonica/prog/recog/sets/test05.pa | Bin 0 -> 100922 bytes leptonica/prog/recog/sets/test06.pa | Bin 0 -> 82665 bytes leptonica/prog/recog/sets/train01.pa | Bin 0 -> 7199 bytes leptonica/prog/recog/sets/train02.pa | Bin 0 -> 25789 bytes leptonica/prog/recog/sets/train03.pa | Bin 0 -> 30837 bytes leptonica/prog/recog/sets/train04.pa | Bin 0 -> 41903 bytes leptonica/prog/recog/sets/train05.pa | Bin 0 -> 30785 bytes leptonica/prog/recog/sets/train06.pa | Bin 0 -> 31423 bytes leptonica/prog/recog_bootnum1.c | 320 + leptonica/prog/recog_bootnum2.c | 183 + leptonica/prog/recog_bootnum3.c | 90 + leptonica/prog/recogsort.c | 124 + leptonica/prog/recogtest1.c | 176 + leptonica/prog/recogtest2.c | 193 + leptonica/prog/recogtest3.c | 182 + leptonica/prog/recogtest4.c | 131 + leptonica/prog/recogtest5.c | 115 + leptonica/prog/recogtest6.c | 134 + leptonica/prog/recogtest7.c | 144 + leptonica/prog/rectangle_reg.c | 182 + leptonica/prog/redcover.jpg | Bin 0 -> 21690 bytes leptonica/prog/reducetest.c | 75 + leptonica/prog/reg_wrapper.sh | 48 + leptonica/prog/removecmap.c | 80 + leptonica/prog/renderfonts.c | 103 + leptonica/prog/replacebytes.c | 82 + leptonica/prog/rgb16.tif | Bin 0 -> 64396 bytes leptonica/prog/rock.png | Bin 0 -> 84115 bytes leptonica/prog/rotate1_reg.c | 195 + leptonica/prog/rotate2_reg.c | 175 + leptonica/prog/rotate_it.c | 113 + leptonica/prog/rotatefastalt.c | 351 + leptonica/prog/rotateorth_reg.c | 146 + leptonica/prog/rotateorthtest1.c | 145 + leptonica/prog/rotatetest1.c | 224 + leptonica/prog/runlengthtest.c | 106 + leptonica/prog/scale_it.c | 143 + leptonica/prog/scale_reg.c | 307 + leptonica/prog/scaleandtile.c | 103 + leptonica/prog/scaletest1.c | 92 + leptonica/prog/scaletest2.c | 363 + leptonica/prog/scots-frag.tif | Bin 0 -> 210976 bytes leptonica/prog/seedfilltest.c | 170 + leptonica/prog/seedspread_reg.c | 160 + leptonica/prog/selio_reg.c | 133 + leptonica/prog/settest.c | 146 + leptonica/prog/sevens.tif | Bin 0 -> 742 bytes leptonica/prog/sharptest.c | 70 + leptonica/prog/shear1_reg.c | 283 + leptonica/prog/shear2_reg.c | 185 + leptonica/prog/shearer.148.tif | Bin 0 -> 81910 bytes leptonica/prog/sheartest.c | 169 + leptonica/prog/showboxes.pac | Bin 0 -> 153286 bytes leptonica/prog/showboxes1.baa | 27 + leptonica/prog/showboxes2.baa | 51 + leptonica/prog/showedges.c | 71 + leptonica/prog/singlecc.tif | Bin 0 -> 398 bytes leptonica/prog/skew_reg.c | 132 + leptonica/prog/skewtest.c | 192 + leptonica/prog/smallpix_reg.c | 231 + leptonica/prog/smoothedge_reg.c | 100 + leptonica/prog/sorttest.c | 100 + leptonica/prog/speckle.png | Bin 0 -> 358 bytes leptonica/prog/speckle2.png | Bin 0 -> 482 bytes leptonica/prog/speckle4.png | Bin 0 -> 1319 bytes leptonica/prog/speckle_reg.c | 119 + leptonica/prog/splitcomp_reg.c | 158 + leptonica/prog/splitimage2pdf.c | 71 + leptonica/prog/stampede2.jpg | Bin 0 -> 75390 bytes leptonica/prog/string_reg.c | 229 + leptonica/prog/stringtemplate1.txt | 96 + leptonica/prog/stringtemplate2.txt | 61 + leptonica/prog/subpixel_reg.c | 209 + leptonica/prog/sudoku1.dat | 12 + leptonica/prog/sudoku2.dat | 11 + leptonica/prog/sudoku3.dat | 14 + leptonica/prog/sudoku4.dat | 13 + leptonica/prog/sudoku5.dat | 14 + leptonica/prog/sudoku6.dat | 11 + leptonica/prog/sudoku7.dat | 11 + leptonica/prog/sudokutest.c | 93 + leptonica/prog/table.15.tif | Bin 0 -> 24694 bytes leptonica/prog/table.150.png | Bin 0 -> 18003 bytes leptonica/prog/table.27.tif | Bin 0 -> 25888 bytes leptonica/prog/test-1bit-alpha.png | Bin 0 -> 16598 bytes leptonica/prog/test-87220.59.png | Bin 0 -> 7039 bytes leptonica/prog/test-cmap-alpha.png | Bin 0 -> 830 bytes leptonica/prog/test-cmap-alpha2.png | Bin 0 -> 557 bytes leptonica/prog/test-fulltrans-alpha.png | Bin 0 -> 260 bytes leptonica/prog/test-gray-alpha.png | Bin 0 -> 561 bytes leptonica/prog/test1.bmp | Bin 0 -> 30734 bytes leptonica/prog/test1.png | Bin 0 -> 14824 bytes leptonica/prog/test16.png | Bin 0 -> 25630 bytes leptonica/prog/test16.tif | Bin 0 -> 23570 bytes leptonica/prog/test24.jpg | Bin 0 -> 248613 bytes leptonica/prog/test32-alpha.png | Bin 0 -> 1284 bytes leptonica/prog/test8.jpg | Bin 0 -> 55081 bytes leptonica/prog/testangle.na | 19 + leptonica/prog/testbuffer.tif | Bin 0 -> 14570 bytes leptonica/prog/testfile1.pdf | Bin 0 -> 1735 bytes leptonica/prog/testfile2.pdf | Bin 0 -> 2396 bytes leptonica/prog/testscore.na | 19 + leptonica/prog/tetons.jpg | Bin 0 -> 30174 bytes leptonica/prog/textorient.c | 95 + leptonica/prog/texturefill_reg.c | 194 + leptonica/prog/threshnorm_reg.c | 105 + leptonica/prog/tickets.tif | Bin 0 -> 138180 bytes leptonica/prog/tiffpdftest.c | 142 + leptonica/prog/toc.99.tif | Bin 0 -> 7776 bytes leptonica/prog/topotest.png | Bin 0 -> 22899 bytes leptonica/prog/translate_reg.c | 163 + leptonica/prog/trctest.c | 66 + leptonica/prog/tribune-page-4x.png | Bin 0 -> 84393 bytes leptonica/prog/tribune-t.png | Bin 0 -> 1793 bytes leptonica/prog/tribune-word.png | Bin 0 -> 7015 bytes leptonica/prog/turingtest.png | Bin 0 -> 13930 bytes leptonica/prog/two-peak-histo.na | 260 + leptonica/prog/underline1.jpg | Bin 0 -> 33885 bytes leptonica/prog/underline2.jpg | Bin 0 -> 27295 bytes leptonica/prog/underline3.jpg | Bin 0 -> 31659 bytes leptonica/prog/underline4.jpg | Bin 0 -> 25106 bytes leptonica/prog/underline5.jpg | Bin 0 -> 18646 bytes leptonica/prog/underline6.jpg | Bin 0 -> 21221 bytes leptonica/prog/underline7.jpg | Bin 0 -> 33031 bytes leptonica/prog/underlinetest.c | 95 + leptonica/prog/w91frag.jpg | Bin 0 -> 137531 bytes leptonica/prog/warped_paper.jpg | Bin 0 -> 84631 bytes leptonica/prog/warped_sudoku.jpg | Bin 0 -> 49133 bytes leptonica/prog/warper_reg.c | 138 + leptonica/prog/warpertest.c | 256 + leptonica/prog/watershed_reg.c | 157 + leptonica/prog/weasel-113c.png | Bin 0 -> 2470 bytes leptonica/prog/weasel-44c.png | Bin 0 -> 1540 bytes leptonica/prog/weasel-4c.2.png | Bin 0 -> 571 bytes leptonica/prog/weasel-64g.png | Bin 0 -> 2387 bytes leptonica/prog/weasel-8g.png | Bin 0 -> 1066 bytes leptonica/prog/weasel2.4c.bmp | Bin 0 -> 3414 bytes leptonica/prog/weasel2.4c.png | Bin 0 -> 965 bytes leptonica/prog/weasel2.4g.png | Bin 0 -> 744 bytes leptonica/prog/weasel2.png | Bin 0 -> 720 bytes leptonica/prog/weasel32.png | Bin 0 -> 3383 bytes leptonica/prog/weasel4.11c.png | Bin 0 -> 985 bytes leptonica/prog/weasel4.16c.png | Bin 0 -> 1559 bytes leptonica/prog/weasel4.16g.png | Bin 0 -> 1524 bytes leptonica/prog/weasel4.5g.png | Bin 0 -> 852 bytes leptonica/prog/weasel4.8g.png | Bin 0 -> 1028 bytes leptonica/prog/weasel4.png | Bin 0 -> 1461 bytes leptonica/prog/weasel8.149g.png | Bin 0 -> 3117 bytes leptonica/prog/weasel8.16g.nocmap.png | Bin 0 -> 1601 bytes leptonica/prog/weasel8.16g.png | Bin 0 -> 1539 bytes leptonica/prog/weasel8.240c.png | Bin 0 -> 3628 bytes leptonica/prog/weasel8.5g.nocmap.png | Bin 0 -> 1083 bytes leptonica/prog/weasel8.5g.png | Bin 0 -> 927 bytes leptonica/prog/weasel8.png | Bin 0 -> 1593 bytes leptonica/prog/webpanimio_reg.c | 96 + leptonica/prog/webpio_reg.c | 147 + leptonica/prog/wet-day.jpg | Bin 0 -> 192734 bytes leptonica/prog/witten.tif | Bin 0 -> 108326 bytes leptonica/prog/wordboxes_reg.c | 288 + leptonica/prog/words.15.tif | Bin 0 -> 14630 bytes leptonica/prog/words.44.tif | Bin 0 -> 19040 bytes leptonica/prog/wordsinorder.c | 145 + leptonica/prog/writemtiff.c | 61 + leptonica/prog/writetext_reg.c | 177 + leptonica/prog/wyom.jpg | Bin 0 -> 122842 bytes leptonica/prog/xformbox_reg.c | 325 + leptonica/prog/xtractprotos.c | 263 + leptonica/prog/yuvtest.c | 221 + leptonica/prog/zanotti-78.jpg | Bin 0 -> 154657 bytes leptonica/prog/zier.jpg | Bin 0 -> 25502 bytes leptonica/src/CMakeLists.txt | 99 + leptonica/src/Makefile.am | 102 + leptonica/src/adaptmap.c | 2948 +++ leptonica/src/affine.c | 1624 ++ leptonica/src/affinecompose.c | 665 + leptonica/src/allheaders.h | 2779 +++ leptonica/src/allheaders_bot.txt | 5 + leptonica/src/allheaders_top.txt | 37 + leptonica/src/alltypes.h | 67 + leptonica/src/array.h | 158 + leptonica/src/arrayaccess.c | 364 + leptonica/src/arrayaccess.h | 270 + leptonica/src/bardecode.c | 1047 + leptonica/src/baseline.c | 600 + leptonica/src/bbuffer.c | 485 + leptonica/src/bbuffer.h | 60 + leptonica/src/bilateral.c | 829 + leptonica/src/bilateral.h | 136 + leptonica/src/bilinear.c | 912 + leptonica/src/binarize.c | 1101 ++ leptonica/src/binexpand.c | 304 + leptonica/src/binreduce.c | 412 + leptonica/src/blend.c | 2295 +++ leptonica/src/bmf.c | 876 + leptonica/src/bmf.h | 64 + leptonica/src/bmfdata.h | 636 + leptonica/src/bmp.h | 124 + leptonica/src/bmpio.c | 646 + leptonica/src/bmpiostub.c | 72 + leptonica/src/bootnumgen1.c | 308 + leptonica/src/bootnumgen2.c | 291 + leptonica/src/bootnumgen3.c | 368 + leptonica/src/bootnumgen4.c | 823 + leptonica/src/boxbasic.c | 2440 +++ leptonica/src/boxfunc1.c | 2737 +++ leptonica/src/boxfunc2.c | 1933 ++ leptonica/src/boxfunc3.c | 1629 ++ leptonica/src/boxfunc4.c | 1426 ++ leptonica/src/boxfunc5.c | 2212 +++ leptonica/src/bytearray.c | 653 + leptonica/src/ccbord.c | 2631 +++ leptonica/src/ccbord.h | 121 + leptonica/src/ccthin.c | 476 + leptonica/src/checkerboard.c | 316 + leptonica/src/classapp.c | 1050 + leptonica/src/colorcontent.c | 2051 ++ leptonica/src/colorfill.c | 913 + leptonica/src/colorfill.h | 67 + leptonica/src/coloring.c | 1106 ++ leptonica/src/colormap.c | 2433 +++ leptonica/src/colormorph.c | 128 + leptonica/src/colorquant1.c | 4157 ++++ leptonica/src/colorquant2.c | 1692 ++ leptonica/src/colorseg.c | 658 + leptonica/src/colorspace.c | 2471 +++ leptonica/src/compare.c | 3611 ++++ leptonica/src/conncomp.c | 1243 ++ leptonica/src/convertfiles.c | 149 + leptonica/src/convolve.c | 2582 +++ leptonica/src/correlscore.c | 883 + leptonica/src/dewarp.h | 191 + leptonica/src/dewarp1.c | 1715 ++ leptonica/src/dewarp2.c | 2017 ++ leptonica/src/dewarp3.c | 1016 + leptonica/src/dewarp4.c | 1179 ++ leptonica/src/dnabasic.c | 1728 ++ leptonica/src/dnafunc1.c | 452 + leptonica/src/dnahash.c | 605 + leptonica/src/dwacomb.2.c | 299 + leptonica/src/dwacomblow.2.c | 4970 +++++ leptonica/src/edge.c | 647 + leptonica/src/encoding.c | 738 + leptonica/src/endianness.h.in | 11 + leptonica/src/enhance.c | 2360 +++ leptonica/src/environ.h | 586 + leptonica/src/fhmtauto.c | 823 + leptonica/src/fhmtgen.1.c | 177 + leptonica/src/fhmtgenlow.1.c | 445 + leptonica/src/finditalic.c | 241 + leptonica/src/flipdetect.c | 821 + leptonica/src/flipdetectdwa.c.notused | 668 + leptonica/src/fmorphauto.c | 879 + leptonica/src/fmorphgen.1.c | 277 + leptonica/src/fmorphgenlow.1.c | 5862 ++++++ leptonica/src/fpix1.c | 2190 +++ leptonica/src/fpix2.c | 2447 +++ leptonica/src/gifio.c | 687 + leptonica/src/gifiostub.c | 72 + leptonica/src/gplot.c | 1364 ++ leptonica/src/gplot.h | 96 + leptonica/src/graphics.c | 2910 +++ leptonica/src/graymorph.c | 1376 ++ leptonica/src/grayquant.c | 2913 +++ leptonica/src/heap.c | 589 + leptonica/src/heap.h | 87 + leptonica/src/hmttemplate1.txt | 170 + leptonica/src/hmttemplate2.txt | 103 + leptonica/src/imageio.h | 245 + leptonica/src/jbclass.c | 2569 +++ leptonica/src/jbclass.h | 142 + leptonica/src/jp2kheader.c | 321 + leptonica/src/jp2kheaderstub.c | 75 + leptonica/src/jp2kio.c | 949 + leptonica/src/jp2kiostub.c | 98 + leptonica/src/jpegio.c | 1303 ++ leptonica/src/jpegiostub.c | 151 + leptonica/src/kernel.c | 1286 ++ leptonica/src/leptonica-license.txt | 26 + leptonica/src/leptwin.c | 368 + leptonica/src/leptwin.h | 45 + leptonica/src/libversions.c | 208 + leptonica/src/list.c | 814 + leptonica/src/list.h | 90 + leptonica/src/mainpage.txt | 47 + leptonica/src/makefile.static | 401 + leptonica/src/map.c | 268 + leptonica/src/maze.c | 912 + leptonica/src/morph.c | 1915 ++ leptonica/src/morph.h | 225 + leptonica/src/morphapp.c | 1636 ++ leptonica/src/morphdwa.c | 1599 ++ leptonica/src/morphseq.c | 1243 ++ leptonica/src/morphtemplate1.txt | 224 + leptonica/src/morphtemplate2.txt | 104 + leptonica/src/numabasic.c | 2097 ++ leptonica/src/numafunc1.c | 3697 ++++ leptonica/src/numafunc2.c | 3319 ++++ leptonica/src/pageseg.c | 2473 +++ leptonica/src/paintcmap.c | 765 + leptonica/src/parseprotos.c | 978 + leptonica/src/partify.c | 315 + leptonica/src/partition.c | 662 + leptonica/src/pdfio1.c | 2255 +++ leptonica/src/pdfio1stub.c | 309 + leptonica/src/pdfio2.c | 2608 +++ leptonica/src/pdfio2stub.c | 172 + leptonica/src/pix.h | 1302 ++ leptonica/src/pix1.c | 2039 ++ leptonica/src/pix2.c | 3573 ++++ leptonica/src/pix3.c | 3716 ++++ leptonica/src/pix4.c | 3568 ++++ leptonica/src/pix5.c | 3221 ++++ leptonica/src/pixabasic.c | 3283 ++++ leptonica/src/pixacc.c | 355 + leptonica/src/pixafunc1.c | 3112 +++ leptonica/src/pixafunc2.c | 2610 +++ leptonica/src/pixalloc.c | 532 + leptonica/src/pixarith.c | 1633 ++ leptonica/src/pixcomp.c | 2481 +++ leptonica/src/pixconv.c | 4297 +++++ leptonica/src/pixlabel.c | 637 + leptonica/src/pixtiling.c | 422 + leptonica/src/pngio.c | 2135 +++ leptonica/src/pngiostub.c | 143 + leptonica/src/pnmio.c | 1534 ++ leptonica/src/pnmiostub.c | 120 + leptonica/src/projective.c | 932 + leptonica/src/psio1.c | 1077 ++ leptonica/src/psio1stub.c | 137 + leptonica/src/psio2.c | 2044 ++ leptonica/src/psio2stub.c | 160 + leptonica/src/ptabasic.c | 1607 ++ leptonica/src/ptafunc1.c | 2667 +++ leptonica/src/ptafunc2.c | 899 + leptonica/src/ptra.c | 1010 + leptonica/src/ptra.h | 97 + leptonica/src/quadtree.c | 701 + leptonica/src/queue.c | 326 + leptonica/src/queue.h | 77 + leptonica/src/rank.c | 544 + leptonica/src/rbtree.c | 905 + leptonica/src/rbtree.h | 91 + leptonica/src/readbarcode.c | 1532 ++ leptonica/src/readbarcode.h | 239 + leptonica/src/readfile.c | 1633 ++ leptonica/src/recog.h | 264 + leptonica/src/recogbasic.c | 1231 ++ leptonica/src/recogdid.c | 1078 ++ leptonica/src/recogident.c | 1883 ++ leptonica/src/recogtrain.c | 2482 +++ leptonica/src/regutils.c | 887 + leptonica/src/regutils.h | 141 + leptonica/src/rop.c | 572 + leptonica/src/roplow.c | 2506 +++ leptonica/src/rotate.c | 598 + leptonica/src/rotateam.c | 1132 ++ leptonica/src/rotateorth.c | 715 + leptonica/src/rotateshear.c | 498 + leptonica/src/runlength.c | 814 + leptonica/src/sarray1.c | 2070 ++ leptonica/src/sarray2.c | 730 + leptonica/src/scale1.c | 3764 ++++ leptonica/src/scale2.c | 2347 +++ leptonica/src/seedfill.c | 3456 ++++ leptonica/src/sel1.c | 2446 +++ leptonica/src/sel2.c | 897 + leptonica/src/selgen.c | 987 + leptonica/src/shear.c | 854 + leptonica/src/skew.c | 1247 ++ leptonica/src/spixio.c | 518 + leptonica/src/stack.c | 293 + leptonica/src/stack.h | 70 + leptonica/src/stringcode.c | 806 + leptonica/src/stringcode.h | 61 + leptonica/src/stringtemplate1.txt | 96 + leptonica/src/stringtemplate2.txt | 61 + leptonica/src/strokes.c | 439 + leptonica/src/sudoku.c | 881 + leptonica/src/sudoku.h | 77 + leptonica/src/textops.c | 1129 ++ leptonica/src/tiffio.c | 2895 +++ leptonica/src/tiffiostub.c | 242 + leptonica/src/utils1.c | 1352 ++ leptonica/src/utils2.c | 3485 ++++ leptonica/src/warper.c | 1394 ++ leptonica/src/watershed.c | 1126 ++ leptonica/src/watershed.h | 64 + leptonica/src/webpanimio.c | 273 + leptonica/src/webpanimiostub.c | 71 + leptonica/src/webpio.c | 417 + leptonica/src/webpiostub.c | 99 + leptonica/src/writefile.c | 1209 ++ leptonica/src/zlibmem.c | 282 + leptonica/src/zlibmemstub.c | 59 + leptonica/style-guide.txt | 230 + leptonica/sw.cpp | 391 + leptonica/version-notes.html | 1600 ++ lib/FCOfontmap-PCLPS3 | 2 +- lib/FCOfontmap-PS3 | 2 +- lib/Fontmap.ATB | 2 +- lib/Fontmap.ATM | 2 +- lib/Fontmap.OS2 | 2 +- lib/Fontmap.SGI | 2 +- lib/Fontmap.Sol | 2 +- lib/Fontmap.Ult | 2 +- lib/Fontmap.VMS | 2 +- lib/align.ps | 2 +- lib/caption.ps | 2 +- lib/cat.ps | 2 +- lib/cid2code.ps | 2 +- lib/docie.ps | 2 +- lib/font2pcl.ps | 2 +- lib/gs_ce_e.ps | 2 +- lib/gs_css_e.ps | 117 + lib/gs_il2_e.ps | 2 +- lib/gs_kanji.ps | 2 +- lib/gs_ksb_e.ps | 2 +- lib/gs_lgo_e.ps | 2 +- lib/gs_lgx_e.ps | 2 +- lib/gs_wl1_e.ps | 2 +- lib/gs_wl2_e.ps | 2 +- lib/gs_wl5_e.ps | 2 +- lib/gslp.ps | 2 +- lib/gsnup.ps | 2 +- lib/image-qa.ps | 2 +- lib/jispaper.ps | 2 +- lib/lines.ps | 2 +- lib/mkcidfm.ps | 2 +- lib/pdf2dsc.ps | 2 +- lib/pdf_info.ps | 155 +- lib/pfbtopfa.ps | 2 +- lib/ppath.ps | 2 +- lib/pphs.ps | 2 +- lib/prfont.ps | 2 +- lib/ps2ai.ps | 2 +- lib/ps2epsi | 4 +- lib/ps2epsi.ps | 2 +- lib/rollconv.ps | 2 +- lib/stcinfo.ps | 2 +- lib/stcolor.ps | 2 +- lib/stocht.ps | 2 +- lib/traceimg.ps | 2 +- lib/traceop.ps | 2 +- lib/uninfo.ps | 2 +- lib/viewcmyk.ps | 2 +- lib/viewgif.ps | 2 +- lib/viewmiff.ps | 2 +- lib/viewpbm.ps | 2 +- lib/viewpcx.ps | 2 +- lib/viewps2a.ps | 2 +- lib/viewpwg.ps | 2 +- lib/viewraw.ps | 2 +- lib/viewrgb.ps | 2 +- lib/winmaps.ps | 2 +- lib/zeroline.ps | 2 +- lib/zugferd.ps | 316 + man/dvipdf.1 | 4 +- man/gs.1 | 45 +- man/gslp.1 | 4 +- man/gsnd.1 | 4 +- man/pdf2dsc.1 | 4 +- man/pdf2ps.1 | 4 +- man/pf2afm.1 | 4 +- man/pfbtopfa.1 | 4 +- man/printafm.1 | 4 +- man/ps2ascii.1 | 4 +- man/ps2epsi.1 | 4 +- man/ps2pdf.1 | 4 +- man/ps2pdfwr.1 | 7 +- man/ps2ps.1 | 4 +- openjpeg/CHANGELOG.md | 87 + openjpeg/NEWS.md | 10 + openjpeg/appveyor.yml | 2 +- openjpeg/doc/CMakeLists.txt | 2 +- openjpeg/src/lib/openjp2/CMakeLists.txt | 4 +- openjpeg/src/lib/openjp2/bench_dwt.c | 140 +- openjpeg/src/lib/openjp2/dwt.c | 1768 +- openjpeg/src/lib/openjp2/dwt.h | 20 +- openjpeg/src/lib/openjp2/j2k.c | 1137 +- openjpeg/src/lib/openjp2/j2k.h | 28 +- openjpeg/src/lib/openjp2/jp2.c | 22 +- openjpeg/src/lib/openjp2/jp2.h | 14 + openjpeg/src/lib/openjp2/mct.c | 215 +- openjpeg/src/lib/openjp2/mct.h | 5 +- openjpeg/src/lib/openjp2/mqc.c | 176 +- openjpeg/src/lib/openjp2/mqc.h | 9 +- openjpeg/src/lib/openjp2/mqc_inl.h | 90 +- openjpeg/src/lib/openjp2/openjpeg.c | 45 +- openjpeg/src/lib/openjp2/openjpeg.h | 86 +- openjpeg/src/lib/openjp2/opj_codec.h | 5 + openjpeg/src/lib/openjp2/opj_common.h | 6 + openjpeg/src/lib/openjp2/opj_intmath.h | 10 + openjpeg/src/lib/openjp2/pi.c | 457 +- openjpeg/src/lib/openjp2/pi.h | 25 +- openjpeg/src/lib/openjp2/t1.c | 863 +- openjpeg/src/lib/openjp2/t1.h | 5 +- openjpeg/src/lib/openjp2/t2.c | 50 +- openjpeg/src/lib/openjp2/t2.h | 2 + openjpeg/src/lib/openjp2/tcd.c | 135 +- openjpeg/src/lib/openjp2/tcd.h | 41 +- psi/apitest.c | 6 +- psi/bfont.h | 2 +- psi/btoken.h | 2 +- psi/dmmain.c | 2 +- psi/dmmain.r | 2 +- psi/dpmain.c | 2 +- psi/dscparse.c | 2 +- psi/dscparse.h | 2 +- psi/dstack.h | 2 +- psi/dwdll.c | 2 +- psi/dwdll.h | 2 +- psi/dwimg.c | 2 +- psi/dwimg.h | 2 +- psi/dwmain.c | 2 +- psi/dwmain.rc | 2 +- psi/dwmainc.c | 4 +- psi/dwnodll.c | 2 +- psi/dwreg.c | 2 +- psi/dwreg.h | 2 +- psi/dwres.h | 2 +- psi/dwtext.c | 2 +- psi/dwtext.h | 2 +- psi/dwtrace.c | 2 +- psi/dwtrace.h | 2 +- psi/dxmain.c | 4 +- psi/dxmainc.c | 2 +- psi/estack.h | 2 +- psi/files.h | 2 +- psi/ghost.h | 2 +- psi/gs.c | 2 +- psi/gsdll.c | 2 +- psi/gsdll2.rc | 2 +- psi/gsdll32.rc | 2 +- psi/gserver.c | 2 +- psi/gsos2.rc | 2 +- psi/ialloc.c | 2 +- psi/ialloc.h | 2 +- psi/iapi.c | 2 +- psi/iapi.h | 2 +- psi/iastate.h | 2 +- psi/iastruct.h | 2 +- psi/ibnum.c | 2 +- psi/ibnum.h | 2 +- psi/ichar.h | 2 +- psi/ichar1.h | 2 +- psi/icharout.h | 2 +- psi/icid.h | 2 +- psi/icie.h | 2 +- psi/icolor.h | 2 +- psi/iconf.c | 2 +- psi/iconf.h | 2 +- psi/icontext.c | 2 +- psi/icontext.h | 2 +- psi/icremap.h | 2 +- psi/icsmap.h | 2 +- psi/icstate.h | 2 +- psi/iddict.h | 2 +- psi/iddstack.h | 2 +- psi/idebug.c | 2 +- psi/idebug.h | 2 +- psi/idict.c | 16 +- psi/idict.h | 2 +- psi/idictdef.h | 2 +- psi/idicttpl.h | 2 +- psi/idisp.c | 2 +- psi/idisp.h | 2 +- psi/idosave.h | 2 +- psi/idparam.c | 2 +- psi/idparam.h | 2 +- psi/idsdata.h | 2 +- psi/idstack.c | 2 +- psi/idstack.h | 2 +- psi/ierrors.h | 2 +- psi/iesdata.h | 2 +- psi/iestack.h | 2 +- psi/ifapi.h | 2 +- psi/ifcid.h | 2 +- psi/ifilter.h | 2 +- psi/ifilter2.h | 2 +- psi/ifont.h | 2 +- psi/ifont1.h | 2 +- psi/ifont2.h | 2 +- psi/ifont42.h | 2 +- psi/ifrpred.h | 2 +- psi/ifunc.h | 2 +- psi/ifwpred.h | 2 +- psi/igc.c | 2 +- psi/igc.h | 2 +- psi/igcref.c | 2 +- psi/igcstr.c | 2 +- psi/igcstr.h | 2 +- psi/igstate.h | 2 +- psi/iht.h | 2 +- psi/iimage.h | 2 +- psi/iinit.c | 2 +- psi/iinit.h | 2 +- psi/ilevel.h | 2 +- psi/ilocate.c | 2 +- psi/imain.c | 20 +- psi/imain.h | 2 +- psi/imainarg.c | 2 +- psi/imainarg.h | 2 +- psi/imemory.h | 2 +- psi/iminst.h | 2 +- psi/iname.c | 2 +- psi/iname.h | 2 +- psi/inamedef.h | 2 +- psi/inameidx.h | 2 +- psi/inames.h | 2 +- psi/inamestr.h | 2 +- psi/inobtokn.c | 2 +- psi/inouparm.c | 2 +- psi/int.mak | 33 +- psi/interp.c | 61 +- psi/interp.h | 2 +- psi/iosdata.h | 2 +- psi/iostack.h | 2 +- psi/ipacked.h | 2 +- psi/iparam.c | 2 +- psi/iparam.h | 2 +- psi/iparray.h | 2 +- psi/ipcolor.h | 2 +- psi/iplugin.c | 2 +- psi/iplugin.h | 2 +- psi/ireclaim.c | 2 +- psi/iref.h | 2 +- psi/isave.c | 2 +- psi/isave.h | 2 +- psi/iscan.c | 21 +- psi/iscan.h | 2 +- psi/iscanbin.c | 2 +- psi/iscanbin.h | 2 +- psi/iscannum.c | 2 +- psi/iscannum.h | 2 +- psi/isdata.h | 2 +- psi/isstate.h | 2 +- psi/istack.c | 2 +- psi/istack.h | 2 +- psi/istkparm.h | 2 +- psi/istream.h | 2 +- psi/istruct.h | 2 +- psi/itoken.h | 2 +- psi/iutil.c | 24 +- psi/iutil.h | 2 +- psi/iutil2.c | 2 +- psi/iutil2.h | 2 +- psi/ivmem2.h | 2 +- psi/ivmspace.h | 2 +- psi/main.h | 2 +- psi/mkfilelt.cpp | 2 +- psi/msvc.mak | 217 +- psi/msvc32.mak | 2 +- psi/msvc64.mak | 2 +- psi/nsisinst.nsi | 2 +- psi/oparc.h | 2 +- psi/opcheck.h | 2 +- psi/opdef.h | 2 +- psi/oper.h | 2 +- psi/opextern.h | 2 +- psi/os2.mak | 2 +- psi/ostack.h | 2 +- psi/psapi.c | 2 +- psi/psapi.h | 2 +- psi/psromfs.mak | 2 +- psi/store.h | 2 +- psi/winint.mak | 6 +- psi/zalg.c | 80 +- psi/zarith.c | 2 +- psi/zarray.c | 2 +- psi/zbfont.c | 2 +- psi/zbseq.c | 2 +- psi/zcfont.c | 2 +- psi/zchar.c | 13 +- psi/zchar1.c | 2 +- psi/zchar2.c | 2 +- psi/zchar32.c | 2 +- psi/zchar42.c | 18 +- psi/zchar42.h | 2 +- psi/zcharout.c | 2 +- psi/zcharx.c | 2 +- psi/zcid.c | 2 +- psi/zcie.c | 2 +- psi/zcie.h | 2 +- psi/zcolor.c | 4 +- psi/zcolor.h | 2 +- psi/zcolor1.c | 2 +- psi/zcolor2.c | 2 +- psi/zcolor3.c | 2 +- psi/zcontrol.c | 2 +- psi/zcrd.c | 2 +- psi/zcsindex.c | 2 +- psi/zcspixel.c | 2 +- psi/zcssepr.c | 2 +- psi/zdevcal.c | 2 +- psi/zdevice.c | 20 +- psi/zdevice2.c | 2 +- psi/zdfilter.c | 2 +- psi/zdict.c | 2 +- psi/zdouble.c | 2 +- psi/zdps1.c | 2 +- psi/zdscpars.c | 2 +- psi/zfaes.c | 2 +- psi/zfapi.c | 20 +- psi/zfarc4.c | 15 +- psi/zfbcp.c | 2 +- psi/zfcid.c | 2 +- psi/zfcid0.c | 2 +- psi/zfcid1.c | 2 +- psi/zfcmap.c | 2 +- psi/zfdctd.c | 2 +- psi/zfdcte.c | 2 +- psi/zfdecode.c | 2 +- psi/zfile.c | 2 +- psi/zfile.h | 2 +- psi/zfile1.c | 2 +- psi/zfileio.c | 2 +- psi/zfilter.c | 2 +- psi/zfilter2.c | 2 +- psi/zfimscale.c | 6 +- psi/zfjbig2.c | 6 +- psi/zfjpx.c | 6 +- psi/zfmd5.c | 2 +- psi/zfont.c | 8 +- psi/zfont0.c | 2 +- psi/zfont1.c | 22 +- psi/zfont2.c | 12 +- psi/zfont32.c | 2 +- psi/zfont42.c | 2 +- psi/zfontenum.c | 48 +- psi/zform.c | 4 +- psi/zfproc.c | 2 +- psi/zfrsd.c | 2 +- psi/zfrsd.h | 2 +- psi/zfsample.c | 16 +- psi/zfsha2.c | 2 +- psi/zfunc.c | 2 +- psi/zfunc.h | 2 +- psi/zfunc0.c | 2 +- psi/zfunc3.c | 2 +- psi/zfunc4.c | 2 +- psi/zfzlib.c | 2 +- psi/zgeneric.c | 2 +- psi/zgstate.c | 2 +- psi/zht.c | 2 +- psi/zht1.c | 2 +- psi/zht2.c | 24 +- psi/zht2.h | 2 +- psi/zicc.c | 2 +- psi/zicc.h | 2 +- psi/zimage.c | 2 +- psi/zimage3.c | 2 +- psi/ziodev.c | 2 +- psi/ziodev2.c | 2 +- psi/ziodevsc.c | 2 +- psi/zmath.c | 2 +- psi/zmatrix.c | 2 +- psi/zmedia2.c | 2 +- psi/zmisc.c | 2 +- psi/zmisc1.c | 2 +- psi/zmisc2.c | 2 +- psi/zmisc3.c | 2 +- psi/zncdummy.c | 2 +- psi/zpacked.c | 2 +- psi/zpaint.c | 2 +- psi/zpath.c | 2 +- psi/zpath1.c | 2 +- psi/zpcolor.c | 4 +- psi/zpdf_r6.c | 4 +- psi/zpdfops.c | 2 +- psi/zrelbit.c | 2 +- psi/zshade.c | 6 +- psi/zstack.c | 2 +- psi/zstring.c | 2 +- psi/zsysvm.c | 2 +- psi/ztoken.c | 2 +- psi/ztrans.c | 21 +- psi/ztrap.c | 2 +- psi/ztype.c | 2 +- psi/zupath.c | 2 +- psi/zusparam.c | 2 +- psi/zutf8.c | 2 +- psi/zvmem.c | 37 +- psi/zvmem2.c | 2 +- psi/zwinutf8.c | 2 +- tesseract/.clang-format | 9 + tesseract/.gitattributes | 1 + tesseract/.github/ISSUE_TEMPLATE.md | 23 + tesseract/.github/workflows/autotools.yml | 196 + .../.github/workflows/cmake-linuxclang-win.yml | 79 + tesseract/.github/workflows/cmake.yml | 96 + tesseract/.github/workflows/sw.yml | 73 + .../.github/workflows/unittest-disablelegacy.yml | 76 + tesseract/.github/workflows/unittest.yml | 101 + tesseract/.gitmodules | 9 + tesseract/.lgtm.yml | 18 + tesseract/.travis.yml | 59 + tesseract/AUTHORS | 47 + tesseract/CMakeLists.txt | 764 + tesseract/CONTRIBUTING.md | 80 + tesseract/ChangeLog | 282 + tesseract/Dockerfile | 17 + tesseract/INSTALL | 229 + tesseract/INSTALL.GIT.md | 67 + tesseract/LICENSE | 202 + tesseract/Makefile.am | 1669 ++ tesseract/README.md | 136 + tesseract/VERSION | 1 + tesseract/appveyor.yml | 47 + tesseract/autogen.sh | 122 + tesseract/cmake/AddCompilerFlag.cmake | 130 + tesseract/cmake/BuildFunctions.cmake | 23 + tesseract/cmake/Configure.cmake | 125 + tesseract/cmake/OptimizeForArchitecture.cmake | 581 + tesseract/cmake/SourceGroups.cmake | 37 + tesseract/cmake/templates/TesseractConfig.cmake.in | 28 + tesseract/cmake/templates/cmake_uninstall.cmake.in | 22 + tesseract/configure.ac | 596 + tesseract/doc/Doxyfile | 2562 +++ tesseract/doc/ambiguous_words.1.asc | 32 + tesseract/doc/classifier_tester.1.asc | 61 + tesseract/doc/cntraining.1.asc | 37 + tesseract/doc/combine_lang_model.1.asc | 71 + tesseract/doc/combine_tessdata.1.asc | 201 + tesseract/doc/dawg2wordlist.1.asc | 45 + tesseract/doc/generate_manpages.sh | 34 + tesseract/doc/lstmeval.1.asc | 55 + tesseract/doc/lstmtraining.1.asc | 118 + tesseract/doc/merge_unicharsets.1.asc | 51 + tesseract/doc/mftraining.1.asc | 56 + tesseract/doc/set_unicharset_properties.1.asc | 50 + tesseract/doc/shapeclustering.1.asc | 59 + tesseract/doc/tesseract.1.asc | 489 + tesseract/doc/tesseract.bib | 69 + tesseract/doc/tesseract.natvis | 34 + tesseract/doc/text2image.1.asc | 168 + tesseract/doc/unicharambigs.5.asc | 89 + tesseract/doc/unicharset.5.asc | 133 + tesseract/doc/unicharset_extractor.1.asc | 47 + tesseract/doc/wordlist2dawg.1.asc | 69 + tesseract/docker-compose.yml | 2 + tesseract/include/tesseract/baseapi.h | 825 + tesseract/include/tesseract/capi.h | 465 + tesseract/include/tesseract/export.h | 39 + tesseract/include/tesseract/ltrresultiterator.h | 241 + tesseract/include/tesseract/ocrclass.h | 157 + tesseract/include/tesseract/osdetect.h | 139 + tesseract/include/tesseract/pageiterator.h | 362 + tesseract/include/tesseract/publictypes.h | 283 + tesseract/include/tesseract/renderer.h | 310 + tesseract/include/tesseract/resultiterator.h | 252 + tesseract/include/tesseract/thresholder.h | 188 + tesseract/include/tesseract/unichar.h | 177 + tesseract/include/tesseract/version.h.in | 30 + tesseract/java/Makefile.am | 73 + tesseract/java/Manifest.txt | 2 + tesseract/java/com/Makefile.am | 1 + tesseract/java/com/google/Makefile.am | 1 + tesseract/java/com/google/scrollview/Makefile.am | 4 + .../java/com/google/scrollview/ScrollView.java | 403 + .../java/com/google/scrollview/events/Makefile.am | 5 + .../java/com/google/scrollview/events/SVEvent.java | 87 + .../google/scrollview/events/SVEventHandler.java | 301 + .../com/google/scrollview/events/SVEventType.java | 31 + .../java/com/google/scrollview/ui/Makefile.am | 7 + .../google/scrollview/ui/SVAbstractMenuItem.java | 57 + .../google/scrollview/ui/SVCheckboxMenuItem.java | 57 + .../com/google/scrollview/ui/SVEmptyMenuItem.java | 46 + .../com/google/scrollview/ui/SVImageHandler.java | 74 + .../java/com/google/scrollview/ui/SVMenuBar.java | 130 + .../java/com/google/scrollview/ui/SVMenuItem.java | 60 + .../java/com/google/scrollview/ui/SVPopupMenu.java | 144 + .../com/google/scrollview/ui/SVSubMenuItem.java | 39 + .../java/com/google/scrollview/ui/SVWindow.java | 648 + tesseract/m4/ax_check_compile_flag.m4 | 53 + tesseract/m4/ax_split_version.m4 | 38 + tesseract/snap/snapcraft.yaml | 50 + tesseract/src/api/altorenderer.cpp | 249 + tesseract/src/api/baseapi.cpp | 2280 +++ tesseract/src/api/capi.cpp | 793 + tesseract/src/api/hocrrenderer.cpp | 491 + tesseract/src/api/lstmboxrenderer.cpp | 107 + tesseract/src/api/pdf_ttf.h | 75 + tesseract/src/api/pdfrenderer.cpp | 948 + tesseract/src/api/renderer.cpp | 227 + tesseract/src/api/tesseractmain.cpp | 793 + tesseract/src/api/wordstrboxrenderer.cpp | 105 + tesseract/src/arch/dotproduct.cpp | 28 + tesseract/src/arch/dotproduct.h | 36 + tesseract/src/arch/dotproductavx.cpp | 59 + tesseract/src/arch/dotproductfma.cpp | 57 + tesseract/src/arch/dotproductsse.cpp | 81 + tesseract/src/arch/intsimdmatrix.cpp | 93 + tesseract/src/arch/intsimdmatrix.h | 126 + tesseract/src/arch/intsimdmatrixavx2.cpp | 375 + tesseract/src/arch/intsimdmatrixneon.cpp | 177 + tesseract/src/arch/intsimdmatrixsse.cpp | 104 + tesseract/src/arch/simddetect.cpp | 282 + tesseract/src/arch/simddetect.h | 87 + tesseract/src/ccmain/adaptions.cpp | 114 + tesseract/src/ccmain/applybox.cpp | 807 + tesseract/src/ccmain/control.cpp | 2110 ++ tesseract/src/ccmain/control.h | 38 + tesseract/src/ccmain/docqual.cpp | 981 + tesseract/src/ccmain/docqual.h | 43 + tesseract/src/ccmain/equationdetect.cpp | 1516 ++ tesseract/src/ccmain/equationdetect.h | 273 + tesseract/src/ccmain/fixspace.cpp | 885 + tesseract/src/ccmain/fixspace.h | 36 + tesseract/src/ccmain/fixxht.cpp | 216 + tesseract/src/ccmain/linerec.cpp | 307 + tesseract/src/ccmain/ltrresultiterator.cpp | 492 + tesseract/src/ccmain/mutableiterator.cpp | 24 + tesseract/src/ccmain/mutableiterator.h | 63 + tesseract/src/ccmain/osdetect.cpp | 579 + tesseract/src/ccmain/output.cpp | 418 + tesseract/src/ccmain/output.h | 37 + tesseract/src/ccmain/pageiterator.cpp | 635 + tesseract/src/ccmain/pagesegmain.cpp | 420 + tesseract/src/ccmain/pagewalk.cpp | 43 + tesseract/src/ccmain/par_control.cpp | 73 + tesseract/src/ccmain/paragraphs.cpp | 2590 +++ tesseract/src/ccmain/paragraphs.h | 110 + tesseract/src/ccmain/paragraphs_internal.h | 314 + tesseract/src/ccmain/paramsd.cpp | 365 + tesseract/src/ccmain/paramsd.h | 134 + tesseract/src/ccmain/pgedit.cpp | 981 + tesseract/src/ccmain/pgedit.h | 71 + tesseract/src/ccmain/recogtraining.cpp | 238 + tesseract/src/ccmain/reject.cpp | 792 + tesseract/src/ccmain/reject.h | 39 + tesseract/src/ccmain/resultiterator.cpp | 752 + tesseract/src/ccmain/superscript.cpp | 610 + tesseract/src/ccmain/tessbox.cpp | 75 + tesseract/src/ccmain/tessedit.cpp | 474 + tesseract/src/ccmain/tesseractclass.cpp | 707 + tesseract/src/ccmain/tesseractclass.h | 1163 ++ tesseract/src/ccmain/tessvars.cpp | 24 + tesseract/src/ccmain/tessvars.h | 27 + tesseract/src/ccmain/tfacepp.cpp | 322 + tesseract/src/ccmain/thresholder.cpp | 334 + tesseract/src/ccmain/werdit.cpp | 68 + tesseract/src/ccmain/werdit.h | 34 + tesseract/src/ccstruct/blamer.cpp | 603 + tesseract/src/ccstruct/blamer.h | 354 + tesseract/src/ccstruct/blobbox.cpp | 1100 ++ tesseract/src/ccstruct/blobbox.h | 854 + tesseract/src/ccstruct/blobs.cpp | 1001 + tesseract/src/ccstruct/blobs.h | 474 + tesseract/src/ccstruct/blread.cpp | 74 + tesseract/src/ccstruct/blread.h | 40 + tesseract/src/ccstruct/boxread.cpp | 266 + tesseract/src/ccstruct/boxread.h | 94 + tesseract/src/ccstruct/boxword.cpp | 199 + tesseract/src/ccstruct/boxword.h | 98 + tesseract/src/ccstruct/ccstruct.cpp | 36 + tesseract/src/ccstruct/ccstruct.h | 41 + tesseract/src/ccstruct/coutln.cpp | 1064 ++ tesseract/src/ccstruct/coutln.h | 301 + tesseract/src/ccstruct/crakedge.h | 42 + tesseract/src/ccstruct/debugpixa.h | 56 + tesseract/src/ccstruct/detlinefit.cpp | 293 + tesseract/src/ccstruct/detlinefit.h | 162 + tesseract/src/ccstruct/dppoint.cpp | 98 + tesseract/src/ccstruct/dppoint.h | 105 + tesseract/src/ccstruct/fontinfo.cpp | 217 + tesseract/src/ccstruct/fontinfo.h | 208 + tesseract/src/ccstruct/imagedata.cpp | 729 + tesseract/src/ccstruct/imagedata.h | 403 + tesseract/src/ccstruct/linlsq.cpp | 262 + tesseract/src/ccstruct/linlsq.h | 140 + tesseract/src/ccstruct/matrix.cpp | 161 + tesseract/src/ccstruct/matrix.h | 646 + tesseract/src/ccstruct/mod128.cpp | 91 + tesseract/src/ccstruct/mod128.h | 88 + tesseract/src/ccstruct/normalis.cpp | 571 + tesseract/src/ccstruct/normalis.h | 319 + tesseract/src/ccstruct/ocrblock.cpp | 519 + tesseract/src/ccstruct/ocrblock.h | 236 + tesseract/src/ccstruct/ocrpara.cpp | 105 + tesseract/src/ccstruct/ocrpara.h | 196 + tesseract/src/ccstruct/ocrrow.cpp | 246 + tesseract/src/ccstruct/ocrrow.h | 177 + tesseract/src/ccstruct/otsuthr.cpp | 211 + tesseract/src/ccstruct/otsuthr.h | 56 + tesseract/src/ccstruct/pageres.cpp | 1689 ++ tesseract/src/ccstruct/pageres.h | 802 + tesseract/src/ccstruct/params_training_featdef.cpp | 40 + tesseract/src/ccstruct/params_training_featdef.h | 153 + tesseract/src/ccstruct/pdblock.cpp | 387 + tesseract/src/ccstruct/pdblock.h | 177 + tesseract/src/ccstruct/points.cpp | 148 + tesseract/src/ccstruct/points.h | 783 + tesseract/src/ccstruct/polyaprx.cpp | 591 + tesseract/src/ccstruct/polyaprx.h | 50 + tesseract/src/ccstruct/polyblk.cpp | 423 + tesseract/src/ccstruct/polyblk.h | 116 + tesseract/src/ccstruct/quadlsq.cpp | 148 + tesseract/src/ccstruct/quadlsq.h | 72 + tesseract/src/ccstruct/quadratc.h | 67 + tesseract/src/ccstruct/quspline.cpp | 415 + tesseract/src/ccstruct/quspline.h | 107 + tesseract/src/ccstruct/ratngs.cpp | 853 + tesseract/src/ccstruct/ratngs.h | 661 + tesseract/src/ccstruct/rect.cpp | 257 + tesseract/src/ccstruct/rect.h | 507 + tesseract/src/ccstruct/rejctmap.cpp | 453 + tesseract/src/ccstruct/rejctmap.h | 269 + tesseract/src/ccstruct/seam.cpp | 254 + tesseract/src/ccstruct/seam.h | 204 + tesseract/src/ccstruct/split.cpp | 317 + tesseract/src/ccstruct/split.h | 124 + tesseract/src/ccstruct/statistc.cpp | 779 + tesseract/src/ccstruct/statistc.h | 170 + tesseract/src/ccstruct/stepblob.cpp | 558 + tesseract/src/ccstruct/stepblob.h | 142 + tesseract/src/ccstruct/werd.cpp | 582 + tesseract/src/ccstruct/werd.h | 199 + tesseract/src/ccutil/ambigs.cpp | 400 + tesseract/src/ccutil/ambigs.h | 226 + tesseract/src/ccutil/bits16.h | 26 + tesseract/src/ccutil/bitvector.cpp | 271 + tesseract/src/ccutil/bitvector.h | 141 + tesseract/src/ccutil/ccutil.cpp | 29 + tesseract/src/ccutil/ccutil.h | 82 + tesseract/src/ccutil/clst.cpp | 508 + tesseract/src/ccutil/clst.h | 937 + tesseract/src/ccutil/elst.cpp | 457 + tesseract/src/ccutil/elst.h | 977 + tesseract/src/ccutil/elst2.cpp | 486 + tesseract/src/ccutil/elst2.h | 997 + tesseract/src/ccutil/errcode.cpp | 97 + tesseract/src/ccutil/errcode.h | 68 + tesseract/src/ccutil/fileerr.h | 38 + tesseract/src/ccutil/genericheap.h | 238 + tesseract/src/ccutil/genericvector.h | 1143 ++ tesseract/src/ccutil/helpers.h | 193 + tesseract/src/ccutil/host.h | 57 + tesseract/src/ccutil/indexmapbidi.cpp | 256 + tesseract/src/ccutil/indexmapbidi.h | 180 + tesseract/src/ccutil/kdpair.h | 194 + tesseract/src/ccutil/lsterr.h | 48 + tesseract/src/ccutil/mainblk.cpp | 91 + tesseract/src/ccutil/object_cache.h | 118 + tesseract/src/ccutil/params.cpp | 219 + tesseract/src/ccutil/params.h | 339 + tesseract/src/ccutil/qrsequence.h | 80 + tesseract/src/ccutil/scanutils.cpp | 503 + tesseract/src/ccutil/scanutils.h | 35 + tesseract/src/ccutil/serialis.cpp | 294 + tesseract/src/ccutil/serialis.h | 147 + tesseract/src/ccutil/sorthelper.h | 112 + tesseract/src/ccutil/strngs.cpp | 131 + tesseract/src/ccutil/strngs.h | 94 + tesseract/src/ccutil/tessdatamanager.cpp | 321 + tesseract/src/ccutil/tessdatamanager.h | 253 + tesseract/src/ccutil/tprintf.cpp | 75 + tesseract/src/ccutil/tprintf.h | 33 + tesseract/src/ccutil/unichar.cpp | 245 + tesseract/src/ccutil/unicharcompress.cpp | 424 + tesseract/src/ccutil/unicharcompress.h | 239 + tesseract/src/ccutil/unicharmap.cpp | 135 + tesseract/src/ccutil/unicharmap.h | 77 + tesseract/src/ccutil/unicharset.cpp | 1112 ++ tesseract/src/ccutil/unicharset.h | 1034 + tesseract/src/ccutil/unicity_table.h | 171 + tesseract/src/ccutil/universalambigs.cpp | 19038 +++++++++++++++++++ tesseract/src/ccutil/universalambigs.h | 31 + tesseract/src/classify/adaptive.cpp | 498 + tesseract/src/classify/adaptive.h | 128 + tesseract/src/classify/adaptmatch.cpp | 2317 +++ tesseract/src/classify/blobclass.cpp | 110 + tesseract/src/classify/blobclass.h | 39 + tesseract/src/classify/classify.cpp | 230 + tesseract/src/classify/classify.h | 583 + tesseract/src/classify/cluster.cpp | 2425 +++ tesseract/src/classify/cluster.h | 138 + tesseract/src/classify/clusttool.cpp | 319 + tesseract/src/classify/clusttool.h | 43 + tesseract/src/classify/cutoffs.cpp | 73 + tesseract/src/classify/featdefs.cpp | 280 + tesseract/src/classify/featdefs.h | 87 + tesseract/src/classify/float2int.cpp | 109 + tesseract/src/classify/float2int.h | 30 + tesseract/src/classify/fpoint.cpp | 54 + tesseract/src/classify/fpoint.h | 53 + tesseract/src/classify/intfeaturespace.cpp | 124 + tesseract/src/classify/intfeaturespace.h | 104 + tesseract/src/classify/intfx.cpp | 488 + tesseract/src/classify/intfx.h | 68 + tesseract/src/classify/intmatcher.cpp | 1226 ++ tesseract/src/classify/intmatcher.h | 165 + tesseract/src/classify/intproto.cpp | 1743 ++ tesseract/src/classify/intproto.h | 265 + tesseract/src/classify/kdtree.cpp | 541 + tesseract/src/classify/kdtree.h | 98 + tesseract/src/classify/mf.cpp | 82 + tesseract/src/classify/mf.h | 40 + tesseract/src/classify/mfdefs.cpp | 46 + tesseract/src/classify/mfdefs.h | 61 + tesseract/src/classify/mfoutline.cpp | 446 + tesseract/src/classify/mfoutline.h | 135 + tesseract/src/classify/mfx.cpp | 152 + tesseract/src/classify/mfx.h | 46 + tesseract/src/classify/normfeat.cpp | 73 + tesseract/src/classify/normfeat.h | 40 + tesseract/src/classify/normmatch.cpp | 231 + tesseract/src/classify/normmatch.h | 34 + tesseract/src/classify/ocrfeatures.cpp | 190 + tesseract/src/classify/ocrfeatures.h | 122 + tesseract/src/classify/outfeat.cpp | 168 + tesseract/src/classify/outfeat.h | 49 + tesseract/src/classify/picofeat.cpp | 264 + tesseract/src/classify/picofeat.h | 65 + tesseract/src/classify/protos.cpp | 178 + tesseract/src/classify/protos.h | 107 + tesseract/src/classify/shapeclassifier.cpp | 234 + tesseract/src/classify/shapeclassifier.h | 121 + tesseract/src/classify/shapetable.cpp | 727 + tesseract/src/classify/shapetable.h | 379 + tesseract/src/classify/tessclassifier.cpp | 84 + tesseract/src/classify/tessclassifier.h | 72 + tesseract/src/classify/trainingsample.cpp | 339 + tesseract/src/classify/trainingsample.h | 252 + tesseract/src/cutil/bitvec.h | 88 + tesseract/src/cutil/oldlist.cpp | 223 + tesseract/src/cutil/oldlist.h | 136 + tesseract/src/dict/context.cpp | 76 + tesseract/src/dict/dawg.cpp | 417 + tesseract/src/dict/dawg.h | 554 + tesseract/src/dict/dawg_cache.cpp | 96 + tesseract/src/dict/dawg_cache.h | 53 + tesseract/src/dict/dict.cpp | 888 + tesseract/src/dict/dict.h | 651 + tesseract/src/dict/hyphen.cpp | 61 + tesseract/src/dict/matchdefs.h | 50 + tesseract/src/dict/permdawg.cpp | 390 + tesseract/src/dict/stopper.cpp | 515 + tesseract/src/dict/stopper.h | 50 + tesseract/src/dict/trie.cpp | 716 + tesseract/src/dict/trie.h | 432 + tesseract/src/lstm/convolve.cpp | 120 + tesseract/src/lstm/convolve.h | 76 + tesseract/src/lstm/fullyconnected.cpp | 323 + tesseract/src/lstm/fullyconnected.h | 136 + tesseract/src/lstm/functions.cpp | 8200 ++++++++ tesseract/src/lstm/functions.h | 232 + tesseract/src/lstm/generate_lut.py | 25 + tesseract/src/lstm/input.cpp | 146 + tesseract/src/lstm/input.h | 109 + tesseract/src/lstm/lstm.cpp | 778 + tesseract/src/lstm/lstm.h | 162 + tesseract/src/lstm/lstmrecognizer.cpp | 562 + tesseract/src/lstm/lstmrecognizer.h | 328 + tesseract/src/lstm/maxpool.cpp | 80 + tesseract/src/lstm/maxpool.h | 70 + tesseract/src/lstm/network.cpp | 341 + tesseract/src/lstm/network.h | 309 + tesseract/src/lstm/networkio.cpp | 991 + tesseract/src/lstm/networkio.h | 345 + tesseract/src/lstm/networkscratch.h | 264 + tesseract/src/lstm/parallel.cpp | 183 + tesseract/src/lstm/parallel.h | 88 + tesseract/src/lstm/plumbing.cpp | 243 + tesseract/src/lstm/plumbing.h | 146 + tesseract/src/lstm/recodebeam.cpp | 1314 ++ tesseract/src/lstm/recodebeam.h | 455 + tesseract/src/lstm/reconfig.cpp | 118 + tesseract/src/lstm/reconfig.h | 88 + tesseract/src/lstm/reversed.cpp | 88 + tesseract/src/lstm/reversed.h | 91 + tesseract/src/lstm/series.cpp | 200 + tesseract/src/lstm/series.h | 96 + tesseract/src/lstm/static_shape.h | 104 + tesseract/src/lstm/stridemap.cpp | 174 + tesseract/src/lstm/stridemap.h | 135 + tesseract/src/lstm/tfnetwork.cpp | 145 + tesseract/src/lstm/tfnetwork.h | 102 + tesseract/src/lstm/tfnetwork.pb.cc | 932 + tesseract/src/lstm/tfnetwork.pb.h | 727 + tesseract/src/lstm/tfnetwork.proto | 74 + tesseract/src/lstm/weightmatrix.cpp | 432 + tesseract/src/lstm/weightmatrix.h | 185 + tesseract/src/opencl/oclkernels.h | 1057 + tesseract/src/opencl/openclwrapper.cpp | 2597 +++ tesseract/src/opencl/openclwrapper.h | 187 + tesseract/src/textord/alignedblob.cpp | 535 + tesseract/src/textord/alignedblob.h | 124 + tesseract/src/textord/baselinedetect.cpp | 869 + tesseract/src/textord/baselinedetect.h | 276 + tesseract/src/textord/bbgrid.cpp | 285 + tesseract/src/textord/bbgrid.h | 957 + tesseract/src/textord/blkocc.cpp | 165 + tesseract/src/textord/blkocc.h | 253 + tesseract/src/textord/blobgrid.cpp | 45 + tesseract/src/textord/blobgrid.h | 46 + tesseract/src/textord/ccnontextdetect.cpp | 323 + tesseract/src/textord/ccnontextdetect.h | 87 + tesseract/src/textord/cjkpitch.cpp | 1070 ++ tesseract/src/textord/cjkpitch.h | 75 + tesseract/src/textord/colfind.cpp | 1642 ++ tesseract/src/textord/colfind.h | 366 + tesseract/src/textord/colpartition.cpp | 2597 +++ tesseract/src/textord/colpartition.h | 927 + tesseract/src/textord/colpartitiongrid.cpp | 1743 ++ tesseract/src/textord/colpartitiongrid.h | 252 + tesseract/src/textord/colpartitionset.cpp | 667 + tesseract/src/textord/colpartitionset.h | 171 + tesseract/src/textord/devanagari_processing.cpp | 502 + tesseract/src/textord/devanagari_processing.h | 210 + tesseract/src/textord/drawtord.cpp | 423 + tesseract/src/textord/drawtord.h | 103 + tesseract/src/textord/edgblob.cpp | 462 + tesseract/src/textord/edgblob.h | 100 + tesseract/src/textord/edgloop.cpp | 162 + tesseract/src/textord/edgloop.h | 44 + tesseract/src/textord/equationdetectbase.cpp | 64 + tesseract/src/textord/equationdetectbase.h | 59 + tesseract/src/textord/fpchop.cpp | 890 + tesseract/src/textord/fpchop.h | 84 + tesseract/src/textord/gap_map.cpp | 189 + tesseract/src/textord/gap_map.h | 53 + tesseract/src/textord/imagefind.cpp | 1366 ++ tesseract/src/textord/imagefind.h | 159 + tesseract/src/textord/linefind.cpp | 769 + tesseract/src/textord/linefind.h | 149 + tesseract/src/textord/makerow.cpp | 2673 +++ tesseract/src/textord/makerow.h | 291 + tesseract/src/textord/oldbasel.cpp | 1698 ++ tesseract/src/textord/oldbasel.h | 164 + tesseract/src/textord/pithsync.cpp | 693 + tesseract/src/textord/pithsync.h | 136 + tesseract/src/textord/pitsync1.cpp | 422 + tesseract/src/textord/pitsync1.h | 125 + tesseract/src/textord/scanedg.cpp | 405 + tesseract/src/textord/scanedg.h | 38 + tesseract/src/textord/sortflts.cpp | 81 + tesseract/src/textord/sortflts.h | 76 + tesseract/src/textord/strokewidth.cpp | 2030 ++ tesseract/src/textord/strokewidth.h | 355 + tesseract/src/textord/tabfind.cpp | 1438 ++ tesseract/src/textord/tabfind.h | 384 + tesseract/src/textord/tablefind.cpp | 2088 ++ tesseract/src/textord/tablefind.h | 427 + tesseract/src/textord/tablerecog.cpp | 1067 ++ tesseract/src/textord/tablerecog.h | 378 + tesseract/src/textord/tabvector.cpp | 982 + tesseract/src/textord/tabvector.h | 429 + tesseract/src/textord/textlineprojection.cpp | 779 + tesseract/src/textord/textlineprojection.h | 206 + tesseract/src/textord/textord.cpp | 349 + tesseract/src/textord/textord.h | 403 + tesseract/src/textord/topitch.cpp | 1847 ++ tesseract/src/textord/topitch.h | 191 + tesseract/src/textord/tordmain.cpp | 994 + tesseract/src/textord/tordmain.h | 45 + tesseract/src/textord/tospace.cpp | 1894 ++ tesseract/src/textord/tovars.cpp | 85 + tesseract/src/textord/tovars.h | 94 + tesseract/src/textord/underlin.cpp | 278 + tesseract/src/textord/underlin.h | 56 + tesseract/src/textord/wordseg.cpp | 625 + tesseract/src/textord/wordseg.h | 78 + tesseract/src/textord/workingpartset.cpp | 144 + tesseract/src/textord/workingpartset.h | 88 + tesseract/src/training/CMakeLists.txt | 345 + tesseract/src/training/ambiguous_words.cpp | 79 + tesseract/src/training/classifier_tester.cpp | 136 + tesseract/src/training/cntraining.cpp | 251 + tesseract/src/training/combine_lang_model.cpp | 83 + tesseract/src/training/combine_tessdata.cpp | 232 + tesseract/src/training/common/commandlineflags.cpp | 337 + tesseract/src/training/common/commandlineflags.h | 83 + tesseract/src/training/common/commontraining.cpp | 847 + tesseract/src/training/common/commontraining.h | 225 + tesseract/src/training/common/ctc.cpp | 413 + tesseract/src/training/common/ctc.h | 130 + tesseract/src/training/common/errorcounter.cpp | 509 + tesseract/src/training/common/errorcounter.h | 227 + tesseract/src/training/common/export.h | 5 + tesseract/src/training/common/intfeaturedist.cpp | 159 + tesseract/src/training/common/intfeaturedist.h | 80 + tesseract/src/training/common/intfeaturemap.cpp | 244 + tesseract/src/training/common/intfeaturemap.h | 164 + tesseract/src/training/common/mastertrainer.cpp | 983 + tesseract/src/training/common/mastertrainer.h | 308 + tesseract/src/training/common/networkbuilder.cpp | 501 + tesseract/src/training/common/networkbuilder.h | 159 + tesseract/src/training/common/sampleiterator.cpp | 275 + tesseract/src/training/common/sampleiterator.h | 195 + .../src/training/common/trainingsampleset.cpp | 771 + tesseract/src/training/common/trainingsampleset.h | 288 + tesseract/src/training/dawg2wordlist.cpp | 100 + tesseract/src/training/degradeimage.cpp | 311 + tesseract/src/training/degradeimage.h | 61 + tesseract/src/training/language-specific.sh | 1199 ++ tesseract/src/training/language_specific.py | 1414 ++ tesseract/src/training/lstmeval.cpp | 80 + tesseract/src/training/lstmtraining.cpp | 228 + tesseract/src/training/merge_unicharsets.cpp | 57 + tesseract/src/training/mergenf.cpp | 324 + tesseract/src/training/mergenf.h | 78 + tesseract/src/training/mftraining.cpp | 281 + tesseract/src/training/pango/boxchar.cpp | 345 + tesseract/src/training/pango/boxchar.h | 132 + tesseract/src/training/pango/export.h | 5 + tesseract/src/training/pango/ligature_table.cpp | 194 + tesseract/src/training/pango/ligature_table.h | 80 + tesseract/src/training/pango/pango_font_info.cpp | 749 + tesseract/src/training/pango/pango_font_info.h | 206 + tesseract/src/training/pango/stringrenderer.cpp | 910 + tesseract/src/training/pango/stringrenderer.h | 227 + tesseract/src/training/pango/tlog.cpp | 25 + tesseract/src/training/pango/tlog.h | 44 + .../src/training/set_unicharset_properties.cpp | 44 + tesseract/src/training/shapeclustering.cpp | 75 + tesseract/src/training/tesstrain.py | 112 + tesseract/src/training/tesstrain.sh | 98 + tesseract/src/training/tesstrain_utils.py | 734 + tesseract/src/training/tesstrain_utils.sh | 627 + tesseract/src/training/text2image.cpp | 747 + tesseract/src/training/unicharset/export.h | 5 + tesseract/src/training/unicharset/fileio.cpp | 199 + tesseract/src/training/unicharset/fileio.h | 113 + tesseract/src/training/unicharset/icuerrorcode.cpp | 28 + tesseract/src/training/unicharset/icuerrorcode.h | 63 + .../src/training/unicharset/lang_model_helpers.cpp | 244 + .../src/training/unicharset/lang_model_helpers.h | 89 + tesseract/src/training/unicharset/lstmtester.cpp | 153 + tesseract/src/training/unicharset/lstmtester.h | 94 + tesseract/src/training/unicharset/lstmtrainer.cpp | 1340 ++ tesseract/src/training/unicharset/lstmtrainer.h | 470 + tesseract/src/training/unicharset/normstrngs.cpp | 304 + tesseract/src/training/unicharset/normstrngs.h | 117 + .../unicharset/unicharset_training_utils.cpp | 209 + .../unicharset/unicharset_training_utils.h | 63 + .../src/training/unicharset/validate_grapheme.cpp | 180 + .../src/training/unicharset/validate_grapheme.h | 35 + .../src/training/unicharset/validate_indic.cpp | 281 + tesseract/src/training/unicharset/validate_indic.h | 44 + .../src/training/unicharset/validate_javanese.cpp | 275 + .../src/training/unicharset/validate_javanese.h | 63 + .../src/training/unicharset/validate_khmer.cpp | 106 + tesseract/src/training/unicharset/validate_khmer.h | 27 + .../src/training/unicharset/validate_myanmar.cpp | 168 + .../src/training/unicharset/validate_myanmar.h | 47 + tesseract/src/training/unicharset/validator.cpp | 222 + tesseract/src/training/unicharset/validator.h | 249 + tesseract/src/training/unicharset_extractor.cpp | 115 + tesseract/src/training/wordlist2dawg.cpp | 104 + tesseract/src/viewer/scrollview.cpp | 850 + tesseract/src/viewer/scrollview.h | 420 + tesseract/src/viewer/svmnode.cpp | 147 + tesseract/src/viewer/svmnode.h | 99 + tesseract/src/viewer/svpaint.cpp | 241 + tesseract/src/viewer/svutil.cpp | 344 + tesseract/src/viewer/svutil.h | 106 + tesseract/src/wordrec/associate.cpp | 171 + tesseract/src/wordrec/associate.h | 123 + tesseract/src/wordrec/chop.cpp | 323 + tesseract/src/wordrec/chop.h | 36 + tesseract/src/wordrec/chopper.cpp | 633 + tesseract/src/wordrec/drawfx.cpp | 85 + tesseract/src/wordrec/drawfx.h | 36 + tesseract/src/wordrec/findseam.cpp | 365 + tesseract/src/wordrec/findseam.h | 38 + tesseract/src/wordrec/gradechop.cpp | 84 + tesseract/src/wordrec/language_model.cpp | 1482 ++ tesseract/src/wordrec/language_model.h | 428 + tesseract/src/wordrec/lm_consistency.cpp | 113 + tesseract/src/wordrec/lm_consistency.h | 142 + tesseract/src/wordrec/lm_pain_points.cpp | 219 + tesseract/src/wordrec/lm_pain_points.h | 133 + tesseract/src/wordrec/lm_state.cpp | 80 + tesseract/src/wordrec/lm_state.h | 244 + tesseract/src/wordrec/measure.h | 120 + tesseract/src/wordrec/outlines.cpp | 76 + tesseract/src/wordrec/outlines.h | 129 + tesseract/src/wordrec/params_model.cpp | 162 + tesseract/src/wordrec/params_model.h | 88 + tesseract/src/wordrec/pieces.cpp | 334 + tesseract/src/wordrec/plotedges.cpp | 115 + tesseract/src/wordrec/plotedges.h | 48 + tesseract/src/wordrec/render.cpp | 133 + tesseract/src/wordrec/render.h | 56 + tesseract/src/wordrec/segsearch.cpp | 338 + tesseract/src/wordrec/tface.cpp | 155 + tesseract/src/wordrec/wordclass.cpp | 82 + tesseract/src/wordrec/wordrec.cpp | 138 + tesseract/src/wordrec/wordrec.h | 555 + tesseract/sw.cpp | 347 + tesseract/tessdata/Makefile.am | 12 + tesseract/tessdata/configs/Makefile.am | 8 + tesseract/tessdata/configs/alto | 1 + tesseract/tessdata/configs/ambigs.train | 7 + tesseract/tessdata/configs/api_config | 1 + tesseract/tessdata/configs/bazaar | 4 + tesseract/tessdata/configs/bigram | 5 + tesseract/tessdata/configs/box.train | 12 + tesseract/tessdata/configs/box.train.stderr | 13 + tesseract/tessdata/configs/digits | 1 + tesseract/tessdata/configs/get.images | 1 + tesseract/tessdata/configs/hocr | 2 + tesseract/tessdata/configs/inter | 2 + tesseract/tessdata/configs/kannada | 4 + tesseract/tessdata/configs/linebox | 2 + tesseract/tessdata/configs/logfile | 1 + tesseract/tessdata/configs/lstm.train | 11 + tesseract/tessdata/configs/lstmbox | 1 + tesseract/tessdata/configs/lstmdebug | 4 + tesseract/tessdata/configs/makebox | 1 + tesseract/tessdata/configs/pdf | 1 + tesseract/tessdata/configs/quiet | 1 + tesseract/tessdata/configs/rebox | 2 + tesseract/tessdata/configs/strokewidth | 12 + tesseract/tessdata/configs/tsv | 1 + tesseract/tessdata/configs/txt | 3 + tesseract/tessdata/configs/unlv | 2 + tesseract/tessdata/configs/wordstrbox | 1 + tesseract/tessdata/eng.user-patterns | 2 + tesseract/tessdata/eng.user-words | 5 + tesseract/tessdata/pdf.ttf | Bin 0 -> 572 bytes tesseract/tessdata/tessconfigs/Makefile.am | 3 + tesseract/tessdata/tessconfigs/batch | 1 + tesseract/tessdata/tessconfigs/batch.nochop | 2 + tesseract/tessdata/tessconfigs/matdemo | 7 + tesseract/tessdata/tessconfigs/msdemo | 12 + tesseract/tessdata/tessconfigs/nobatch | 1 + tesseract/tessdata/tessconfigs/segdemo | 9 + tesseract/tesseract.pc.cmake | 12 + tesseract/tesseract.pc.in | 16 + tesseract/unittest/README.md | 88 + tesseract/unittest/apiexample_test.cc | 119 + tesseract/unittest/applybox_test.cc | 128 + tesseract/unittest/baseapi_test.cc | 402 + tesseract/unittest/baseapi_thread_test.cc | 229 + tesseract/unittest/bitvector_test.cc | 166 + tesseract/unittest/capiexample_c_test.c | 21 + tesseract/unittest/capiexample_test.cc | 19 + tesseract/unittest/cleanapi_test.cc | 28 + tesseract/unittest/colpartition_test.cc | 76 + tesseract/unittest/commandlineflags_test.cc | 158 + tesseract/unittest/cycletimer.h | 61 + tesseract/unittest/dawg_test.cc | 115 + tesseract/unittest/denorm_test.cc | 99 + tesseract/unittest/doubleptr.h | 93 + tesseract/unittest/equationdetect_test.cc | 549 + tesseract/unittest/fileio_test.cc | 66 + tesseract/unittest/fuzzers/fuzzer-api.cpp | 101 + tesseract/unittest/fuzzers/oss-fuzz-build.sh | 59 + tesseract/unittest/heap_test.cc | 202 + tesseract/unittest/imagedata_test.cc | 131 + tesseract/unittest/include_gunit.h | 76 + tesseract/unittest/indexmapbidi_test.cc | 117 + tesseract/unittest/intfeaturemap_test.cc | 129 + tesseract/unittest/intsimdmatrix_test.cc | 135 + tesseract/unittest/lang_model_test.cc | 217 + tesseract/unittest/layout_test.cc | 234 + tesseract/unittest/ligature_table_test.cc | 111 + tesseract/unittest/linlsq_test.cc | 118 + tesseract/unittest/list_test.cc | 68 + tesseract/unittest/loadlang_test.cc | 251 + tesseract/unittest/log.h | 67 + tesseract/unittest/lstm_recode_test.cc | 45 + tesseract/unittest/lstm_squashed_test.cc | 31 + tesseract/unittest/lstm_test.cc | 221 + tesseract/unittest/lstm_test.h | 189 + tesseract/unittest/lstmtrainer_test.cc | 106 + tesseract/unittest/mastertrainer_test.cc | 298 + tesseract/unittest/matrix_test.cc | 137 + tesseract/unittest/networkio_test.cc | 217 + tesseract/unittest/normstrngs_test.cc | 422 + tesseract/unittest/normstrngs_test.h | 84 + tesseract/unittest/nthitem_test.cc | 120 + tesseract/unittest/osd_test.cc | 133 + tesseract/unittest/pagesegmode_test.cc | 114 + tesseract/unittest/pango_font_info_test.cc | 334 + tesseract/unittest/paragraphs_test.cc | 705 + tesseract/unittest/params_model_test.cc | 75 + tesseract/unittest/progress_test.cc | 165 + tesseract/unittest/qrsequence_test.cc | 69 + tesseract/unittest/recodebeam_test.cc | 483 + tesseract/unittest/rect_test.cc | 176 + tesseract/unittest/resultiterator_test.cc | 612 + tesseract/unittest/scanutils_test.cc | 114 + tesseract/unittest/shapetable_test.cc | 182 + tesseract/unittest/stats_test.cc | 59 + tesseract/unittest/stridemap_test.cc | 219 + tesseract/unittest/stringrenderer_test.cc | 564 + tesseract/unittest/syntaxnet/base.h | 61 + tesseract/unittest/tablefind_test.cc | 261 + tesseract/unittest/tablerecog_test.cc | 316 + tesseract/unittest/tabvector_test.cc | 130 + tesseract/unittest/tatweel_test.cc | 114 + tesseract/unittest/tesseract_leaksanitizer.supp | 12 + tesseract/unittest/textlineprojection_test.cc | 262 + tesseract/unittest/tfile_test.cc | 179 + tesseract/unittest/third_party/utf/rune.c | 357 + tesseract/unittest/third_party/utf/utf.h | 246 + tesseract/unittest/third_party/utf/utfdef.h | 14 + tesseract/unittest/unichar_test.cc | 43 + tesseract/unittest/unicharcompress_test.cc | 257 + tesseract/unittest/unicharset_test.cc | 161 + tesseract/unittest/util/utf8/unicodetext.cc | 507 + tesseract/unittest/util/utf8/unicodetext.h | 477 + tesseract/unittest/util/utf8/unilib.cc | 58 + tesseract/unittest/util/utf8/unilib.h | 63 + tesseract/unittest/util/utf8/unilib_utf8_utils.h | 66 + tesseract/unittest/validate_grapheme_test.cc | 179 + tesseract/unittest/validate_indic_test.cc | 231 + tesseract/unittest/validate_khmer_test.cc | 50 + tesseract/unittest/validate_myanmar_test.cc | 54 + tesseract/unittest/validator_test.cc | 76 + tiff/CMakeLists.txt | 57 +- tiff/ChangeLog | 1442 ++ tiff/Makefile.in | 36 +- tiff/Makefile.vc | 3 + tiff/RELEASE-DATE | 2 +- tiff/VERSION | 2 +- tiff/aclocal.m4 | 50 +- tiff/build/Makefile.in | 4 +- tiff/configure | 221 +- tiff/configure.ac | 68 +- tiff/contrib/Makefile.in | 4 +- tiff/contrib/addtiffo/CMakeLists.txt | 6 + tiff/contrib/addtiffo/Makefile.in | 4 +- tiff/contrib/addtiffo/tif_ovrcache.c | 1 + tiff/contrib/dbs/CMakeLists.txt | 11 + tiff/contrib/dbs/Makefile.in | 4 +- tiff/contrib/dbs/xtiff/Makefile.in | 4 +- tiff/contrib/iptcutil/Makefile.in | 4 +- tiff/contrib/mfs/Makefile.in | 4 +- tiff/contrib/pds/Makefile.in | 4 +- tiff/contrib/ras/Makefile.in | 4 +- tiff/contrib/stream/Makefile.in | 4 +- tiff/contrib/tags/Makefile.in | 4 +- tiff/contrib/win_dib/Makefile.in | 4 +- tiff/contrib/win_dib/tiff2dib.c | 2 + tiff/html/Makefile.am | 3 +- tiff/html/Makefile.in | 7 +- tiff/html/addingtags.html | 17 +- tiff/html/bugs.html | 13 +- tiff/html/build.html | 16 +- tiff/html/contrib.html | 17 +- tiff/html/document.html | 11 +- tiff/html/images.html | 11 +- tiff/html/images/Makefile.in | 4 +- tiff/html/index.html | 6 +- tiff/html/internals.html | 75 +- tiff/html/intro.html | 13 +- tiff/html/libtiff.html | 30 +- tiff/html/man/Makefile.in | 4 +- tiff/html/misc.html | 16 +- tiff/html/support.html | 2 +- tiff/html/tools.html | 19 +- tiff/html/v3.4beta007.html | 1 + tiff/html/v3.4beta016.html | 1 + tiff/html/v3.4beta018.html | 1 + tiff/html/v3.4beta024.html | 1 + tiff/html/v3.4beta028.html | 1 + tiff/html/v3.4beta029.html | 1 + tiff/html/v3.4beta031.html | 1 + tiff/html/v3.4beta032.html | 1 + tiff/html/v3.4beta033.html | 1 + tiff/html/v3.4beta034.html | 1 + tiff/html/v3.4beta035.html | 1 + tiff/html/v3.4beta036.html | 1 + tiff/html/v3.5.1.html | 1 + tiff/html/v3.5.2.html | 1 + tiff/html/v3.5.3.html | 1 + tiff/html/v3.5.4.html | 1 + tiff/html/v3.5.5.html | 1 + tiff/html/v3.5.6-beta.html | 1 + tiff/html/v3.5.7.html | 1 + tiff/html/v3.6.0.html | 1 + tiff/html/v3.6.1.html | 1 + tiff/html/v3.7.0.html | 1 + tiff/html/v3.7.0alpha.html | 1 + tiff/html/v3.7.0beta.html | 1 + tiff/html/v3.7.0beta2.html | 1 + tiff/html/v3.7.1.html | 1 + tiff/html/v3.7.2.html | 1 + tiff/html/v3.7.3.html | 1 + tiff/html/v3.7.4.html | 1 + tiff/html/v3.8.0.html | 1 + tiff/html/v3.8.1.html | 1 + tiff/html/v3.8.2.html | 1 + tiff/html/v3.9.0beta.html | 1 + tiff/html/v3.9.1.html | 1 + tiff/html/v3.9.2.html | 1 + tiff/html/v4.0.0.html | 1 + tiff/html/v4.0.1.html | 1 + tiff/html/v4.0.10.html | 1 + tiff/html/v4.0.2.html | 1 + tiff/html/v4.0.3.html | 1 + tiff/html/v4.0.4.html | 1 + tiff/html/v4.0.4beta.html | 1 + tiff/html/v4.0.5.html | 1 + tiff/html/v4.0.6.html | 1 + tiff/html/v4.0.7.html | 1 + tiff/html/v4.0.8.html | 1 + tiff/html/v4.0.9.html | 1 + tiff/html/v4.1.0.html | 53 +- tiff/html/v4.2.0.html | 205 + tiff/libtiff/Makefile.in | 8 +- tiff/libtiff/libtiff.def | 8 +- tiff/libtiff/tif_aux.c | 24 +- tiff/libtiff/tif_compress.c | 2 +- tiff/libtiff/tif_config.h.in | 3 + tiff/libtiff/tif_config.vc.h | 21 +- tiff/libtiff/tif_dir.c | 94 +- tiff/libtiff/tif_dir.h | 2 + tiff/libtiff/tif_dirinfo.c | 244 +- tiff/libtiff/tif_dirread.c | 120 +- tiff/libtiff/tif_dirwrite.c | 512 +- tiff/libtiff/tif_fax3.c | 114 +- tiff/libtiff/tif_fax3.h | 39 +- tiff/libtiff/tif_getimage.c | 33 +- tiff/libtiff/tif_jbig.c | 1 + tiff/libtiff/tif_jpeg.c | 65 +- tiff/libtiff/tif_luv.c | 28 +- tiff/libtiff/tif_lzma.c | 7 +- tiff/libtiff/tif_lzw.c | 12 +- tiff/libtiff/tif_ojpeg.c | 63 +- tiff/libtiff/tif_open.c | 5 +- tiff/libtiff/tif_pixarlog.c | 31 +- tiff/libtiff/tif_predict.c | 6 +- tiff/libtiff/tif_read.c | 18 +- tiff/libtiff/tif_thunder.c | 8 +- tiff/libtiff/tif_unix.c | 2 +- tiff/libtiff/tif_webp.c | 15 +- tiff/libtiff/tif_win32.c | 60 +- tiff/libtiff/tif_write.c | 11 + tiff/libtiff/tif_zip.c | 280 +- tiff/libtiff/tif_zstd.c | 6 +- tiff/libtiff/tiff.h | 117 +- tiff/libtiff/tiffconf.h.cmake.in | 3 + tiff/libtiff/tiffconf.h.in | 3 + tiff/libtiff/tiffio.h | 16 +- tiff/libtiff/tiffiop.h | 21 +- tiff/libtiff/tiffvers.h | 4 +- tiff/man/Makefile.in | 4 +- tiff/man/TIFFGetField.3tiff | 62 +- tiff/man/TIFFReadEncodedStrip.3tiff | 2 +- tiff/man/TIFFstrip.3tiff | 6 +- tiff/man/tiff2pdf.1 | 3 + tiff/man/tiff2ps.1 | 4 + tiff/man/tiff2rgba.1 | 4 + tiff/man/tiffcp.1 | 15 + tiff/man/tiffcrop.1 | 4 + tiff/nmake.opt | 10 +- tiff/port/Makefile.in | 4 +- tiff/port/Makefile.vc | 44 +- tiff/port/libport.h | 12 +- tiff/test/CMakeLists.txt | 47 +- tiff/test/Makefile.am | 28 +- tiff/test/Makefile.in | 129 +- tiff/test/common.sh | 3 +- tiff/test/custom_dir_EXIF_231.c | 1398 ++ tiff/test/defer_strile_loading.c | 13 +- tiff/test/images/README.txt | 3 + .../test/images/deflate-last-strip-extra-data.tiff | Bin 0 -> 12789 bytes .../images/ojpeg_chewey_subsamp21_multi_strip.tiff | Bin 0 -> 39752 bytes .../images/ojpeg_single_strip_no_rowsperstrip.tiff | Bin 0 -> 8258 bytes .../ojpeg_zackthecat_subsamp22_single_strip.tiff | Bin 0 -> 8258 bytes tiff/test/images/rgb-3c-16b.ppm | Bin 0 -> 142305 bytes tiff/test/images/testfax4.tiff | Bin 0 -> 39637 bytes tiff/test/ppm2tiff_pbm.sh | 1 - tiff/test/ppm2tiff_pgm.sh | 1 - tiff/test/ppm2tiff_ppm.sh | 7 +- tiff/test/rational_precision2double.c | 972 + .../test/refs/o-deflate-last-strip-extra-data.tiff | Bin 0 -> 12560 bytes tiff/test/refs/o-testfax4.tiff | Bin 0 -> 106326 bytes tiff/test/testdeflatelaststripextradata.sh | 43 + tiff/test/testfax4.sh | 24 + tiff/test/tiff2ps-EPS1.sh | 2 +- tiff/test/tiff2ps-PS1.sh | 3 +- tiff/test/tiff2ps-PS2.sh | 2 +- tiff/test/tiff2ps-PS3.sh | 2 +- ...tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh | 7 + ...tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh | 7 + ...rgba-ojpeg_zackthecat_subsamp22_single_strip.sh | 7 + tiff/tools/CMakeLists.txt | 27 + tiff/tools/Makefile.in | 4 +- tiff/tools/fax2ps.c | 30 +- tiff/tools/fax2tiff.c | 23 +- tiff/tools/pal2rgb.c | 50 +- tiff/tools/ppm2tiff.c | 230 +- tiff/tools/raw2tiff.c | 63 +- tiff/tools/rgb2ycbcr.c | 32 +- tiff/tools/thumbnail.c | 32 +- tiff/tools/tiff2bw.c | 40 +- tiff/tools/tiff2pdf.c | 409 +- tiff/tools/tiff2ps.c | 122 +- tiff/tools/tiff2rgba.c | 62 +- tiff/tools/tiffcmp.c | 42 +- tiff/tools/tiffcp.c | 149 +- tiff/tools/tiffcrop.c | 235 +- tiff/tools/tiffdither.c | 46 +- tiff/tools/tiffdump.c | 17 +- tiff/tools/tiffgt.c | 51 +- tiff/tools/tiffinfo.c | 103 +- tiff/tools/tiffmedian.c | 49 +- tiff/tools/tiffset.c | 61 +- tiff/tools/tiffsplit.c | 17 +- toolbin/GenSubstCID.ps | Bin 5702 -> 5702 bytes toolbin/afmutil.py | 2 +- toolbin/color/icc_creator/ICC_Creator/CIELAB.h | 2 +- .../color/icc_creator/ICC_Creator/ICC_Creator.cpp | 2 +- .../color/icc_creator/ICC_Creator/ICC_Creator.h | 2 +- .../icc_creator/ICC_Creator/ICC_CreatorDlg.cpp | 2 +- .../color/icc_creator/ICC_Creator/ICC_CreatorDlg.h | 2 +- .../color/icc_creator/ICC_Creator/icc_create.cpp | 2 +- toolbin/color/icc_creator/ICC_Creator/icc_create.h | 2 +- toolbin/color/icc_creator/README.txt | 2 +- toolbin/encs2c.ps | 23 +- toolbin/errlist.tcl | 2 +- toolbin/extractFonts.ps | 2 +- toolbin/extractICCprofiles.ps | 2 +- toolbin/gen_ldf_jb2.py | 2 +- toolbin/genfontmap.ps | 2 +- toolbin/gitlog2changelog.py | 6 +- toolbin/gsmake.tcl | 2 +- toolbin/halftone/ETS/test_ets.c | 97 +- toolbin/halftone/ETS/win32/ETS.sln | 11 +- toolbin/halftone/ETS/win32/ETS.vcproj | 196 - toolbin/halftone/ETS/win32/ETS.vcxproj | 93 + toolbin/halftone/ETS/win32/ETS.vcxproj.filters | 33 + toolbin/halftone/gen_ordered/README | 2 +- toolbin/halftone/gen_ordered/gen_ordered_main.c | 2 +- toolbin/halftone/gen_stochastic/gen_stochastic.c | 2 +- toolbin/halftone/thresh_remap/thresh_remap.c | 2 +- toolbin/headers.tcl | 2 +- toolbin/jpxtopdf.c | 2 +- toolbin/leaks.tcl | 2 +- toolbin/localcluster/clusterpush.pl | 45 +- toolbin/makehist.tcl | 2 +- toolbin/memory.py | 2 +- toolbin/ocheck.py | 2 +- toolbin/pre.tcl | 2 +- toolbin/precheck.tcl | 2 +- toolbin/split_changelog.py | 2 +- toolbin/suite.tcl | 2 +- toolbin/tests/build_revision.py | 2 +- toolbin/tests/check_all.py | 2 +- toolbin/tests/check_comments.py | 2 +- toolbin/tests/check_dirs.py | 2 +- toolbin/tests/check_docrefs.py | 2 +- toolbin/tests/cmpi.py | 2 +- toolbin/tests/compare_checksumdb.py | 2 +- toolbin/tests/compare_checksums.py | 2 +- toolbin/tests/dump_checksum.py | 2 +- toolbin/tests/dump_checksum_plus.py | 2 +- toolbin/tests/dump_checksum_raw.py | 2 +- toolbin/tests/fuzzy.c | 2 +- toolbin/tests/get_baseline_log.py | 2 +- toolbin/tests/get_baselines.py | 2 +- toolbin/tests/gscheck_all.py | 2 +- toolbin/tests/gscheck_fuzzypdf.py | 2 +- toolbin/tests/gscheck_pdfwrite.py | 2 +- toolbin/tests/gscheck_raster.py | 2 +- toolbin/tests/gscheck_testfiles.py | 2 +- toolbin/tests/gsconf.py | 2 +- toolbin/tests/gsparamsets.py | 2 +- toolbin/tests/gssum.py | 2 +- toolbin/tests/gstestgs.py | 2 +- toolbin/tests/gstestutils.py | 2 +- toolbin/tests/gsutil.py | 2 +- toolbin/tests/make_baselinedb.py | 2 +- toolbin/tests/make_testdb.py | 2 +- toolbin/tests/make_two_pdfversions | 2 +- toolbin/tests/make_two_versions | 2 +- toolbin/tests/myoptparse.py | 2 +- toolbin/tests/rasterdb.py | 2 +- toolbin/tests/revert_baseline | 2 +- toolbin/tests/revert_pdfbaseline | 2 +- toolbin/tests/run_nightly.py | 2 +- toolbin/tests/run_parallel | 2 +- toolbin/tests/run_regression.py | 2 +- toolbin/tests/testdiff.py | 2 +- toolbin/tests/update_baseline.py | 2 +- toolbin/tests/update_specific | 2 +- toolbin/tmake.tcl | 2 +- windows/All.vcxproj | 44 +- windows/GhostPDL.sln | 14 + windows/ghostpcl-ufst.vcproj | 130 + windows/ghostpcl.vcxproj | 46 +- windows/ghostpcl.vcxproj.filters | 6 - windows/ghostpdl.vcxproj | 44 +- windows/ghostscript.vcproj | 28 +- windows/ghostscript.vcxproj | 70 +- windows/ghostscript.vcxproj.filters | 26 +- windows/ghostscript_rt.vcxproj | 7 +- windows/ghostxps.vcxproj | 44 +- 5020 files changed, 768054 insertions(+), 114211 deletions(-) create mode 100644 Resource/IdiomSet/PPI_CUtils create mode 100644 base/gdevnup.c create mode 100644 base/gdevnup.h create mode 100644 base/gsicc_blacktext.c create mode 100644 base/gsicc_blacktext.h delete mode 100644 base/ldf_jb2.mak delete mode 100644 base/lwf_jp2.mak delete mode 100644 base/sjbig2_luratech.c delete mode 100644 base/sjbig2_luratech.h delete mode 100644 base/sjpx_luratech.c delete mode 100644 base/sjpx_luratech.h create mode 100644 cups/libs/images/color-wheel.png create mode 100644 cups/libs/images/cups-block-diagram.png create mode 100644 cups/libs/images/cups-block-diagram.svg create mode 100644 cups/libs/images/cups-command-chain.png create mode 100644 cups/libs/images/cups-command-chain.svg create mode 100644 cups/libs/images/cups-icon.png create mode 100644 cups/libs/images/cups-postscript-chain.png create mode 100644 cups/libs/images/cups-postscript-chain.svg create mode 100644 cups/libs/images/cups-raster-chain.png create mode 100644 cups/libs/images/cups-raster-chain.svg create mode 100644 cups/libs/images/cups.png create mode 100644 cups/libs/images/cups.svg create mode 100644 cups/libs/images/left.gif create mode 100644 cups/libs/images/left.xcf.gz create mode 100644 cups/libs/images/raster-organization.png create mode 100644 cups/libs/images/raster-organization.svg create mode 100644 cups/libs/images/raster.png create mode 100644 cups/libs/images/raster.svg create mode 100644 cups/libs/images/right.gif create mode 100644 cups/libs/images/sample-image.png create mode 100644 cups/libs/images/sel.gif create mode 100644 cups/libs/images/smiley.jpg create mode 100644 cups/libs/images/unsel.gif create mode 100644 cups/libs/images/wait.gif create mode 100644 cups/libs/images/webinterface.png create mode 100644 demos/c/Makefile create mode 100644 demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml create mode 100644 demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml.cs create mode 100644 demos/java/gsjava/.classpath create mode 100644 demos/java/gsjava/.project create mode 100644 demos/java/gsjava/README.txt create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/GSAPI.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/GSInstance.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/callbacks/DisplayCallback.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/callbacks/ICalloutFunction.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/callbacks/IPollFunction.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdErrFunction.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdInFunction.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdOutFunction.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/BMPDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceInUseException.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceNotSupportedException.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/FAXDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/FileDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/HighLevelDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/JPEGDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/OCRDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PCXDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PDFImageDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PNGDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PNMDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PSDDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PXLDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/TIFFDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/TextDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/devices/XPSDevice.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/util/AllocationError.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/util/ByteArrayReference.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/util/BytePointer.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/util/NativeArray.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/util/NativePointer.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/util/Reference.java create mode 100644 demos/java/gsjava/src/com/artifex/gsjava/util/StringUtil.java create mode 100644 demos/java/gstest/.classpath create mode 100644 demos/java/gstest/.project create mode 100644 demos/java/gstest/src/gstest/Main.java create mode 100644 demos/java/gsviewer/.classpath create mode 100644 demos/java/gsviewer/.project create mode 100644 demos/java/gsviewer/README.txt create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/DefaultUnhandledExceptionHandler.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/Document.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/GSFileFilter.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/ImageUtil.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/Main.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/Page.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/PageUpdateCallback.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/Settings.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/StdIO.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/gui/ScrollMap.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/gui/SettingsDialog.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerGUIListener.java create mode 100644 demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java create mode 100644 demos/java/jni/gs_jni/callbacks.cpp create mode 100644 demos/java/jni/gs_jni/callbacks.h create mode 100644 demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp create mode 100644 demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h create mode 100644 demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.cpp create mode 100644 demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.h create mode 100644 demos/java/jni/gs_jni/dllmain.cpp create mode 100644 demos/java/jni/gs_jni/framework.h create mode 100644 demos/java/jni/gs_jni/gs_jni.sln create mode 100644 demos/java/jni/gs_jni/gs_jni.vcxproj create mode 100644 demos/java/jni/gs_jni/gs_jni.vcxproj.filters create mode 100644 demos/java/jni/gs_jni/include/classfile_constants.h create mode 100644 demos/java/jni/gs_jni/include/jawt.h create mode 100644 demos/java/jni/gs_jni/include/jdwpTransport.h create mode 100644 demos/java/jni/gs_jni/include/jni.h create mode 100644 demos/java/jni/gs_jni/include/jvmti.h create mode 100644 demos/java/jni/gs_jni/include/jvmticmlr.h create mode 100644 demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCallbacks.h create mode 100644 demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.c create mode 100644 demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.h create mode 100644 demos/java/jni/gs_jni/include/win32/bridge/AccessBridgePackages.h create mode 100644 demos/java/jni/gs_jni/include/win32/jawt_md.h create mode 100644 demos/java/jni/gs_jni/include/win32/jni_md.h create mode 100644 demos/java/jni/gs_jni/jni_util.cpp create mode 100644 demos/java/jni/gs_jni/jni_util.h delete mode 100755 demos/python/gsapiwrap.py delete mode 100644 demos/python/jlib.py create mode 100644 devices/extract.mak delete mode 100644 devices/gdevjbig2.c delete mode 100644 devices/gdevjpx.c create mode 100644 devices/vector/doc_common.c create mode 100644 devices/vector/doc_common.h create mode 100644 devices/vector/gdevdocxw.c create mode 100644 extract/COPYING create mode 100644 extract/Makefile create mode 100644 extract/README create mode 100644 extract/include/extract.h create mode 100644 extract/include/extract_alloc.h create mode 100644 extract/include/extract_buffer.h create mode 100644 extract/include/extract_buffer_impl.h create mode 100644 extract/include/extract_compat_inline.h create mode 100644 extract/src/alloc.c create mode 100644 extract/src/astring.c create mode 100644 extract/src/astring.h create mode 100644 extract/src/buffer-test.c create mode 100644 extract/src/buffer.c create mode 100644 extract/src/compat_stdint.h create mode 100644 extract/src/compat_strtoll.h create mode 100644 extract/src/compat_va_copy.h create mode 100644 extract/src/document.h create mode 100644 extract/src/docx.c create mode 100644 extract/src/docx.h create mode 100644 extract/src/docx_template.c create mode 100644 extract/src/docx_template.h create mode 100755 extract/src/docx_template_build.py create mode 100644 extract/src/extract-exe.c create mode 100644 extract/src/extract.c create mode 100644 extract/src/join.c create mode 100644 extract/src/mem.c create mode 100644 extract/src/mem.h create mode 100644 extract/src/memento.c create mode 100644 extract/src/memento.h create mode 100755 extract/src/memento.py create mode 100644 extract/src/misc-test.c create mode 100644 extract/src/outf.c create mode 100644 extract/src/outf.h create mode 100644 extract/src/template.docx create mode 100644 extract/src/xml.c create mode 100644 extract/src/xml.h create mode 100644 extract/src/zip-test.c create mode 100644 extract/src/zip.c create mode 100644 extract/src/zip.h create mode 100644 extract/test/Python2.pdf create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.gs.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2.pdf.mutool.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2clipped.pdf create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/_rels/.rels create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/document.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/settings.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/styles.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/media/image11.jpeg create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/media/image11.jpeg create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/media/image11.jpeg create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/media/image11.jpeg create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/media/image11.jpeg create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/_rels/.rels create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/document.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/media/image11.jpeg create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/settings.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/styles.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.gs.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/[Content_Types].xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/_rels/.rels create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/app.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/core.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/document.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/fontTable.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/settings.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/styles.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/theme/theme1.xml create mode 100644 extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/webSettings.xml create mode 100644 freetype/.clang-format delete mode 100644 freetype/Jamfile delete mode 100644 freetype/Jamrules create mode 100644 freetype/builds/cmake/FindBrotliDec.cmake create mode 100644 freetype/builds/meson/extract_freetype_version.py create mode 100644 freetype/builds/meson/extract_libtool_version.py create mode 100644 freetype/builds/meson/generate_reference_docs.py create mode 100644 freetype/builds/meson/parse_modules_cfg.py create mode 100644 freetype/builds/meson/process_ftoption_h.py create mode 100644 freetype/builds/unix/ax_compare_version.m4 create mode 100644 freetype/builds/unix/ax_prog_python_version.m4 create mode 100644 freetype/builds/unix/ftconfig.h.in delete mode 100644 freetype/builds/unix/ftconfig.in create mode 100644 freetype/docs/README create mode 100644 freetype/docs/reference/404.html delete mode 100644 freetype/docs/reference/README create mode 100644 freetype/docs/reference/assets/fonts/font-awesome.css create mode 100644 freetype/docs/reference/assets/fonts/material-icons.css create mode 100644 freetype/docs/reference/assets/fonts/specimen/FontAwesome.ttf create mode 100644 freetype/docs/reference/assets/fonts/specimen/FontAwesome.woff create mode 100644 freetype/docs/reference/assets/fonts/specimen/FontAwesome.woff2 create mode 100644 freetype/docs/reference/assets/fonts/specimen/MaterialIcons-Regular.ttf create mode 100644 freetype/docs/reference/assets/fonts/specimen/MaterialIcons-Regular.woff create mode 100644 freetype/docs/reference/assets/fonts/specimen/MaterialIcons-Regular.woff2 create mode 100644 freetype/docs/reference/assets/images/favicon.png create mode 100644 freetype/docs/reference/assets/images/icons/bitbucket.1b09e088.svg create mode 100644 freetype/docs/reference/assets/images/icons/github.f0b8504a.svg create mode 100644 freetype/docs/reference/assets/images/icons/gitlab.6dd19c00.svg create mode 100644 freetype/docs/reference/assets/javascripts/application.c33a9706.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.ar.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.da.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.de.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.du.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.es.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.fi.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.fr.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.hu.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.it.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.ja.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.jp.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.multi.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.nl.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.no.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.pt.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.ro.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.ru.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.stemmer.support.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.sv.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.th.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.tr.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/lunr.vi.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/tinyseg.js create mode 100644 freetype/docs/reference/assets/javascripts/lunr/wordcut.js create mode 100644 freetype/docs/reference/assets/javascripts/modernizr.86422ebf.js create mode 100644 freetype/docs/reference/assets/stylesheets/application-palette.a8b3c06d.css create mode 100644 freetype/docs/reference/assets/stylesheets/application.adb8469c.css create mode 100644 freetype/docs/reference/ft2-auto_hinter.html create mode 100644 freetype/docs/reference/ft2-base_interface.html create mode 100644 freetype/docs/reference/ft2-basic_types.html create mode 100644 freetype/docs/reference/ft2-bdf_fonts.html create mode 100644 freetype/docs/reference/ft2-bitmap_handling.html create mode 100644 freetype/docs/reference/ft2-bzip2.html create mode 100644 freetype/docs/reference/ft2-cache_subsystem.html create mode 100644 freetype/docs/reference/ft2-cff_driver.html create mode 100644 freetype/docs/reference/ft2-cid_fonts.html create mode 100644 freetype/docs/reference/ft2-color_management.html create mode 100644 freetype/docs/reference/ft2-computations.html create mode 100644 freetype/docs/reference/ft2-error_code_values.html create mode 100644 freetype/docs/reference/ft2-error_enumerations.html create mode 100644 freetype/docs/reference/ft2-font_formats.html create mode 100644 freetype/docs/reference/ft2-gasp_table.html create mode 100644 freetype/docs/reference/ft2-glyph_management.html create mode 100644 freetype/docs/reference/ft2-glyph_stroker.html create mode 100644 freetype/docs/reference/ft2-glyph_variants.html create mode 100644 freetype/docs/reference/ft2-gx_validation.html create mode 100644 freetype/docs/reference/ft2-gzip.html create mode 100644 freetype/docs/reference/ft2-header_file_macros.html create mode 100644 freetype/docs/reference/ft2-header_inclusion.html create mode 100644 freetype/docs/reference/ft2-incremental.html create mode 100644 freetype/docs/reference/ft2-index.html create mode 100644 freetype/docs/reference/ft2-layer_management.html create mode 100644 freetype/docs/reference/ft2-lcd_rendering.html create mode 100644 freetype/docs/reference/ft2-list_processing.html create mode 100644 freetype/docs/reference/ft2-lzw.html create mode 100644 freetype/docs/reference/ft2-mac_specific.html create mode 100644 freetype/docs/reference/ft2-module_management.html create mode 100644 freetype/docs/reference/ft2-multiple_masters.html create mode 100644 freetype/docs/reference/ft2-ot_validation.html create mode 100644 freetype/docs/reference/ft2-outline_processing.html create mode 100644 freetype/docs/reference/ft2-parameter_tags.html create mode 100644 freetype/docs/reference/ft2-pcf_driver.html create mode 100644 freetype/docs/reference/ft2-pfr_fonts.html create mode 100644 freetype/docs/reference/ft2-properties.html create mode 100644 freetype/docs/reference/ft2-quick_advance.html create mode 100644 freetype/docs/reference/ft2-raster.html create mode 100644 freetype/docs/reference/ft2-sfnt_names.html create mode 100644 freetype/docs/reference/ft2-sizes_management.html create mode 100644 freetype/docs/reference/ft2-system_interface.html create mode 100644 freetype/docs/reference/ft2-t1_cid_driver.html create mode 100644 freetype/docs/reference/ft2-truetype_engine.html create mode 100644 freetype/docs/reference/ft2-truetype_tables.html create mode 100644 freetype/docs/reference/ft2-tt_driver.html create mode 100644 freetype/docs/reference/ft2-type1_tables.html create mode 100644 freetype/docs/reference/ft2-user_allocation.html create mode 100644 freetype/docs/reference/ft2-version.html create mode 100644 freetype/docs/reference/ft2-winfnt_fonts.html create mode 100644 freetype/docs/reference/images/favico.ico create mode 100644 freetype/docs/reference/index.html create mode 100644 freetype/docs/reference/javascripts/extra.js create mode 100644 freetype/docs/reference/search/search_index.json delete mode 100644 freetype/docs/reference/site/404.html delete mode 100644 freetype/docs/reference/site/assets/fonts/font-awesome.css delete mode 100644 freetype/docs/reference/site/assets/fonts/material-icons.css delete mode 100644 freetype/docs/reference/site/assets/fonts/specimen/FontAwesome.ttf delete mode 100644 freetype/docs/reference/site/assets/fonts/specimen/FontAwesome.woff delete mode 100644 freetype/docs/reference/site/assets/fonts/specimen/FontAwesome.woff2 delete mode 100644 freetype/docs/reference/site/assets/fonts/specimen/MaterialIcons-Regular.ttf delete mode 100644 freetype/docs/reference/site/assets/fonts/specimen/MaterialIcons-Regular.woff delete mode 100644 freetype/docs/reference/site/assets/fonts/specimen/MaterialIcons-Regular.woff2 delete mode 100644 freetype/docs/reference/site/assets/images/favicon.png delete mode 100644 freetype/docs/reference/site/assets/images/icons/bitbucket.1b09e088.svg delete mode 100644 freetype/docs/reference/site/assets/images/icons/github.f0b8504a.svg delete mode 100644 freetype/docs/reference/site/assets/images/icons/gitlab.6dd19c00.svg delete mode 100644 freetype/docs/reference/site/assets/javascripts/application.d9aa80ab.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.da.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.de.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.du.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.es.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.fi.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.fr.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.hu.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.it.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.ja.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.jp.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.multi.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.nl.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.no.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.pt.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.ro.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.ru.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.stemmer.support.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.sv.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.th.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/lunr.tr.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/tinyseg.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/lunr/wordcut.js delete mode 100644 freetype/docs/reference/site/assets/javascripts/modernizr.1f0bcf2b.js delete mode 100644 freetype/docs/reference/site/assets/stylesheets/application-palette.224b79ff.css delete mode 100644 freetype/docs/reference/site/assets/stylesheets/application.982221ab.css delete mode 100644 freetype/docs/reference/site/ft2-auto_hinter.html delete mode 100644 freetype/docs/reference/site/ft2-base_interface.html delete mode 100644 freetype/docs/reference/site/ft2-basic_types.html delete mode 100644 freetype/docs/reference/site/ft2-bdf_fonts.html delete mode 100644 freetype/docs/reference/site/ft2-bitmap_handling.html delete mode 100644 freetype/docs/reference/site/ft2-bzip2.html delete mode 100644 freetype/docs/reference/site/ft2-cache_subsystem.html delete mode 100644 freetype/docs/reference/site/ft2-cff_driver.html delete mode 100644 freetype/docs/reference/site/ft2-cid_fonts.html delete mode 100644 freetype/docs/reference/site/ft2-color_management.html delete mode 100644 freetype/docs/reference/site/ft2-computations.html delete mode 100644 freetype/docs/reference/site/ft2-error_code_values.html delete mode 100644 freetype/docs/reference/site/ft2-error_enumerations.html delete mode 100644 freetype/docs/reference/site/ft2-font_formats.html delete mode 100644 freetype/docs/reference/site/ft2-gasp_table.html delete mode 100644 freetype/docs/reference/site/ft2-glyph_management.html delete mode 100644 freetype/docs/reference/site/ft2-glyph_stroker.html delete mode 100644 freetype/docs/reference/site/ft2-glyph_variants.html delete mode 100644 freetype/docs/reference/site/ft2-gx_validation.html delete mode 100644 freetype/docs/reference/site/ft2-gzip.html delete mode 100644 freetype/docs/reference/site/ft2-header_file_macros.html delete mode 100644 freetype/docs/reference/site/ft2-header_inclusion.html delete mode 100644 freetype/docs/reference/site/ft2-incremental.html delete mode 100644 freetype/docs/reference/site/ft2-index.html delete mode 100644 freetype/docs/reference/site/ft2-layer_management.html delete mode 100644 freetype/docs/reference/site/ft2-lcd_rendering.html delete mode 100644 freetype/docs/reference/site/ft2-list_processing.html delete mode 100644 freetype/docs/reference/site/ft2-lzw.html delete mode 100644 freetype/docs/reference/site/ft2-mac_specific.html delete mode 100644 freetype/docs/reference/site/ft2-module_management.html delete mode 100644 freetype/docs/reference/site/ft2-multiple_masters.html delete mode 100644 freetype/docs/reference/site/ft2-ot_validation.html delete mode 100644 freetype/docs/reference/site/ft2-outline_processing.html delete mode 100644 freetype/docs/reference/site/ft2-parameter_tags.html delete mode 100644 freetype/docs/reference/site/ft2-pcf_driver.html delete mode 100644 freetype/docs/reference/site/ft2-pfr_fonts.html delete mode 100644 freetype/docs/reference/site/ft2-properties.html delete mode 100644 freetype/docs/reference/site/ft2-quick_advance.html delete mode 100644 freetype/docs/reference/site/ft2-raster.html delete mode 100644 freetype/docs/reference/site/ft2-sfnt_names.html delete mode 100644 freetype/docs/reference/site/ft2-sizes_management.html delete mode 100644 freetype/docs/reference/site/ft2-system_interface.html delete mode 100644 freetype/docs/reference/site/ft2-t1_cid_driver.html delete mode 100644 freetype/docs/reference/site/ft2-truetype_engine.html delete mode 100644 freetype/docs/reference/site/ft2-truetype_tables.html delete mode 100644 freetype/docs/reference/site/ft2-tt_driver.html delete mode 100644 freetype/docs/reference/site/ft2-type1_tables.html delete mode 100644 freetype/docs/reference/site/ft2-user_allocation.html delete mode 100644 freetype/docs/reference/site/ft2-version.html delete mode 100644 freetype/docs/reference/site/ft2-winfnt_fonts.html delete mode 100644 freetype/docs/reference/site/images/favico.ico delete mode 100644 freetype/docs/reference/site/index.html delete mode 100644 freetype/docs/reference/site/javascripts/extra.js delete mode 100644 freetype/docs/reference/site/search/search_index.json delete mode 100644 freetype/docs/reference/site/sitemap.xml delete mode 100644 freetype/docs/reference/site/sitemap.xml.gz delete mode 100644 freetype/docs/reference/site/stylesheets/extra.css create mode 100644 freetype/docs/reference/sitemap.xml create mode 100644 freetype/docs/reference/sitemap.xml.gz create mode 100644 freetype/docs/reference/stylesheets/extra.css create mode 100644 freetype/include/freetype/config/integer-types.h create mode 100644 freetype/include/freetype/config/mac-support.h create mode 100644 freetype/include/freetype/config/public-macros.h create mode 100644 freetype/include/freetype/internal/compiler-macros.h delete mode 100644 freetype/include/freetype/internal/internal.h create mode 100644 freetype/meson.build create mode 100644 freetype/meson_options.txt delete mode 100644 freetype/src/Jamfile delete mode 100644 freetype/src/autofit/Jamfile delete mode 100644 freetype/src/base/Jamfile delete mode 100644 freetype/src/bdf/Jamfile delete mode 100644 freetype/src/bzip2/Jamfile delete mode 100644 freetype/src/cache/Jamfile delete mode 100644 freetype/src/cff/Jamfile delete mode 100644 freetype/src/cid/Jamfile delete mode 100644 freetype/src/gxvalid/Jamfile delete mode 100644 freetype/src/gzip/Jamfile delete mode 100644 freetype/src/lzw/Jamfile delete mode 100644 freetype/src/otvalid/Jamfile delete mode 100644 freetype/src/pcf/Jamfile delete mode 100644 freetype/src/pfr/Jamfile delete mode 100644 freetype/src/psaux/Jamfile delete mode 100644 freetype/src/pshinter/Jamfile delete mode 100644 freetype/src/psnames/Jamfile delete mode 100644 freetype/src/raster/Jamfile delete mode 100644 freetype/src/sfnt/Jamfile create mode 100644 freetype/src/sfnt/sfwoff2.c create mode 100644 freetype/src/sfnt/sfwoff2.h create mode 100644 freetype/src/sfnt/woff2tags.c create mode 100644 freetype/src/sfnt/woff2tags.h delete mode 100644 freetype/src/smooth/Jamfile delete mode 100644 freetype/src/tools/Jamfile create mode 100755 freetype/src/tools/make_distribution_archives.py delete mode 100644 freetype/src/truetype/Jamfile delete mode 100644 freetype/src/type1/Jamfile delete mode 100644 freetype/src/type42/Jamfile delete mode 100644 freetype/src/winfonts/Jamfile create mode 100644 leptonica/.github/workflows/sw.yml create mode 100644 leptonica/.travis.yml create mode 100644 leptonica/CMakeLists.txt create mode 100644 leptonica/Doxyfile create mode 100644 leptonica/Makefile.am create mode 100644 leptonica/README.html create mode 100644 leptonica/README.md create mode 100644 leptonica/appveyor.yml create mode 100755 leptonica/autogen.sh create mode 100644 leptonica/cmake/Configure.cmake create mode 100644 leptonica/cmake/templates/LeptonicaConfig-version.cmake.in create mode 100644 leptonica/cmake/templates/LeptonicaConfig.cmake.in create mode 100644 leptonica/cmake/templates/cmake_uninstall.cmake.in create mode 100644 leptonica/configure.ac create mode 100644 leptonica/lept.pc.cmake create mode 100644 leptonica/lept.pc.in create mode 100644 leptonica/leptonica-license.txt create mode 100644 leptonica/lok.lua create mode 100644 leptonica/m4/ax_split_version.m4 create mode 100755 leptonica/make-for-auto create mode 100755 leptonica/make-for-local create mode 100644 leptonica/moller52.jpg create mode 100644 leptonica/prog/1555.003.jpg create mode 100644 leptonica/prog/1555.007.jpg create mode 100644 leptonica/prog/19-colors.png create mode 100644 leptonica/prog/CMakeLists.txt create mode 100644 leptonica/prog/Leptonica.jpg create mode 100644 leptonica/prog/Makefile.am create mode 100644 leptonica/prog/adaptmap_dark.c create mode 100644 leptonica/prog/adaptmap_reg.c create mode 100644 leptonica/prog/adaptnorm_reg.c create mode 100644 leptonica/prog/affine_reg.c create mode 100644 leptonica/prog/alltests_reg.c create mode 100644 leptonica/prog/alphaops_reg.c create mode 100644 leptonica/prog/alphaxform_reg.c create mode 100644 leptonica/prog/amoris.2.150.jpg create mode 100644 leptonica/prog/aneurisms8.jpg create mode 100644 leptonica/prog/arabic.png create mode 100644 leptonica/prog/arabic2.png create mode 100644 leptonica/prog/arabic_lines.c create mode 100644 leptonica/prog/arithtest.c create mode 100644 leptonica/prog/autogen.137.c create mode 100644 leptonica/prog/autogen.137.h create mode 100644 leptonica/prog/autogentest1.c create mode 100644 leptonica/prog/autogentest2.c create mode 100644 leptonica/prog/barcode-128-300.png create mode 100644 leptonica/prog/barcode-2of5-300.png create mode 100644 leptonica/prog/barcode-39-300.png create mode 100644 leptonica/prog/barcode-93-300.png create mode 100644 leptonica/prog/barcode-codabar-300.png create mode 100644 leptonica/prog/barcode-digits.png create mode 100644 leptonica/prog/barcode-i2of5-300.png create mode 100644 leptonica/prog/barcode-upc-300.png create mode 100644 leptonica/prog/barcodetest.c create mode 100644 leptonica/prog/barcodetest1.jpg create mode 100644 leptonica/prog/barcodetest2.jpg create mode 100644 leptonica/prog/baseline_reg.c create mode 100644 leptonica/prog/bigweasel2.4c.png create mode 100644 leptonica/prog/bilateral1_reg.c create mode 100644 leptonica/prog/bilateral2_reg.c create mode 100644 leptonica/prog/bilinear_reg.c create mode 100644 leptonica/prog/binarize_reg.c create mode 100644 leptonica/prog/binarize_set.c create mode 100644 leptonica/prog/binarizefiles.c create mode 100644 leptonica/prog/bincompare.c create mode 100644 leptonica/prog/binding-example.45.jpg create mode 100644 leptonica/prog/binmorph1_reg.c create mode 100644 leptonica/prog/binmorph2_reg.c create mode 100644 leptonica/prog/binmorph3_reg.c create mode 100644 leptonica/prog/binmorph4_reg.c create mode 100644 leptonica/prog/binmorph5_reg.c create mode 100644 leptonica/prog/binmorph6_reg.c create mode 100644 leptonica/prog/blackwhite_reg.c create mode 100644 leptonica/prog/blend-green1.jpg create mode 100644 leptonica/prog/blend-green2.png create mode 100644 leptonica/prog/blend-green3.png create mode 100644 leptonica/prog/blend-orange.jpg create mode 100644 leptonica/prog/blend-red.png create mode 100644 leptonica/prog/blend-yellow.jpg create mode 100644 leptonica/prog/blend1_reg.c create mode 100644 leptonica/prog/blend2_reg.c create mode 100644 leptonica/prog/blend3_reg.c create mode 100644 leptonica/prog/blend4_reg.c create mode 100644 leptonica/prog/blend5_reg.c create mode 100644 leptonica/prog/blendcmaptest.c create mode 100644 leptonica/prog/blender1.tif create mode 100644 leptonica/prog/blender8.png create mode 100644 leptonica/prog/blendtext.tif create mode 100644 leptonica/prog/bois-2.tif create mode 100644 leptonica/prog/bois-3.tif create mode 100644 leptonica/prog/bois-4.tif create mode 100644 leptonica/prog/bois-5.tif create mode 100644 leptonica/prog/books_logo.png create mode 100644 leptonica/prog/boxa1.ba create mode 100644 leptonica/prog/boxa1_reg.c create mode 100644 leptonica/prog/boxa2.ba create mode 100644 leptonica/prog/boxa2_reg.c create mode 100644 leptonica/prog/boxa3.ba create mode 100644 leptonica/prog/boxa3_reg.c create mode 100644 leptonica/prog/boxa4.ba create mode 100644 leptonica/prog/boxa4_reg.c create mode 100644 leptonica/prog/boxa5.ba create mode 100644 leptonica/prog/boxap1.ba create mode 100644 leptonica/prog/boxap2.ba create mode 100644 leptonica/prog/boxap3.ba create mode 100644 leptonica/prog/boxap4.ba create mode 100644 leptonica/prog/boxap5.ba create mode 100644 leptonica/prog/boxedpage.jpg create mode 100644 leptonica/prog/brev.06.75.jpg create mode 100644 leptonica/prog/brev.10.75.jpg create mode 100644 leptonica/prog/brev.14.75.jpg create mode 100644 leptonica/prog/brev.20.75.jpg create mode 100644 leptonica/prog/brev.36.75.jpg create mode 100644 leptonica/prog/brev.53.75.jpg create mode 100644 leptonica/prog/brev.56.75.jpg create mode 100644 leptonica/prog/breviar.38.150.jpg create mode 100644 leptonica/prog/brothers.150.jpg create mode 100644 leptonica/prog/buffertest.c create mode 100644 leptonica/prog/bytea_reg.c create mode 100644 leptonica/prog/candelabrum.011.jpg create mode 100644 leptonica/prog/cat-and-mouse.png create mode 100644 leptonica/prog/cat.007.jpg create mode 100644 leptonica/prog/cat.035.jpg create mode 100644 leptonica/prog/cavalerie.11.jpg create mode 100644 leptonica/prog/cavalerie.29.jpg create mode 100644 leptonica/prog/ccbord_reg.c create mode 100644 leptonica/prog/ccbordtest.c create mode 100644 leptonica/prog/cctest1.c create mode 100644 leptonica/prog/ccthin1_reg.c create mode 100644 leptonica/prog/ccthin2_reg.c create mode 100644 leptonica/prog/char.tif create mode 100644 leptonica/prog/chars-10.tif create mode 100644 leptonica/prog/chars-12.tif create mode 100644 leptonica/prog/chars-14.tif create mode 100644 leptonica/prog/chars-16.tif create mode 100644 leptonica/prog/chars-18.tif create mode 100644 leptonica/prog/chars-20.tif create mode 100644 leptonica/prog/chars-4.tif create mode 100644 leptonica/prog/chars-6.tif create mode 100644 leptonica/prog/chars-8.tif create mode 100644 leptonica/prog/checkerboard1.tif create mode 100644 leptonica/prog/checkerboard2.tif create mode 100644 leptonica/prog/checkerboard_reg.c create mode 100644 leptonica/prog/church.png create mode 100644 leptonica/prog/circle_reg.c create mode 100644 leptonica/prog/circles.pa create mode 100644 leptonica/prog/cleanpdf.c create mode 100644 leptonica/prog/cmapquant_reg.c create mode 100644 leptonica/prog/coffeebeans.png create mode 100644 leptonica/prog/color-wheel-hue.jpg create mode 100644 leptonica/prog/colorcontent_reg.c create mode 100644 leptonica/prog/colorfill_reg.c create mode 100644 leptonica/prog/coloring_reg.c create mode 100644 leptonica/prog/colorize_reg.c create mode 100644 leptonica/prog/colormask_reg.c create mode 100644 leptonica/prog/colormorph_reg.c create mode 100644 leptonica/prog/colorpage.030.jpg create mode 100644 leptonica/prog/colorquant_reg.c create mode 100644 leptonica/prog/colorseg.jpg create mode 100644 leptonica/prog/colorseg_reg.c create mode 100644 leptonica/prog/colorsegtest.c create mode 100644 leptonica/prog/colorspace_reg.c create mode 100644 leptonica/prog/comap.063.jpg create mode 100644 leptonica/prog/comap.068.jpg create mode 100644 leptonica/prog/comap.073.jpg create mode 100644 leptonica/prog/comap.100.jpg create mode 100644 leptonica/prog/comap.110.jpg create mode 100644 leptonica/prog/comap.118.jpg create mode 100644 leptonica/prog/compare_reg.c create mode 100644 leptonica/prog/comparepages.c create mode 100644 leptonica/prog/comparepixa.c create mode 100644 leptonica/prog/comparetest.c create mode 100644 leptonica/prog/compfilter_reg.c create mode 100644 leptonica/prog/concatpdf.c create mode 100644 leptonica/prog/conncomp_reg.c create mode 100644 leptonica/prog/contrast-orig-60.jpg create mode 100644 leptonica/prog/contrast1.jpg create mode 100644 leptonica/prog/contrasttest.c create mode 100644 leptonica/prog/conversion_reg.c create mode 100644 leptonica/prog/convertfilestopdf.c create mode 100644 leptonica/prog/convertfilestops.c create mode 100644 leptonica/prog/convertformat.c create mode 100644 leptonica/prog/convertsegfilestopdf.c create mode 100644 leptonica/prog/convertsegfilestops.c create mode 100644 leptonica/prog/converttogray.c create mode 100644 leptonica/prog/converttopdf.c create mode 100644 leptonica/prog/converttops.c create mode 100644 leptonica/prog/convolve_reg.c create mode 100644 leptonica/prog/cootoots.png create mode 100644 leptonica/prog/copernicus.png create mode 100644 leptonica/prog/cornertest.c create mode 100644 leptonica/prog/corrupttest.c create mode 100644 leptonica/prog/crop_reg.c create mode 100644 leptonica/prog/croptext.c create mode 100644 leptonica/prog/dave-orig.png create mode 100644 leptonica/prog/deskew_it.c create mode 100644 leptonica/prog/dewarp_reg.c create mode 100644 leptonica/prog/dewarprules.c create mode 100644 leptonica/prog/dewarptest1.c create mode 100644 leptonica/prog/dewarptest2.c create mode 100644 leptonica/prog/dewarptest3.c create mode 100644 leptonica/prog/dewarptest4.c create mode 100644 leptonica/prog/dewarptest5.c create mode 100644 leptonica/prog/digitprep1.c create mode 100644 leptonica/prog/dinos.pac create mode 100644 leptonica/prog/displayboxa.c create mode 100644 leptonica/prog/displayboxes_on_pixa.c create mode 100644 leptonica/prog/displaypix.c create mode 100644 leptonica/prog/displaypixa.c create mode 100644 leptonica/prog/distance_reg.c create mode 100644 leptonica/prog/dither_reg.c create mode 100644 leptonica/prog/dna_reg.c create mode 100644 leptonica/prog/dreyfus1.png create mode 100644 leptonica/prog/dreyfus2.png create mode 100644 leptonica/prog/dreyfus4.png create mode 100644 leptonica/prog/dreyfus8.png create mode 100644 leptonica/prog/dwalinear.3.c create mode 100644 leptonica/prog/dwalineargen.c create mode 100644 leptonica/prog/dwalinearlow.3.c create mode 100644 leptonica/prog/dwamorph1_reg.c create mode 100644 leptonica/prog/dwamorph2_reg.c create mode 100644 leptonica/prog/edge_reg.c create mode 100644 leptonica/prog/encoding_reg.c create mode 100644 leptonica/prog/enhance_reg.c create mode 100644 leptonica/prog/equal_reg.c create mode 100644 leptonica/prog/expand_reg.c create mode 100644 leptonica/prog/extrema_reg.c create mode 100644 leptonica/prog/falsecolor_reg.c create mode 100644 leptonica/prog/fcombautogen.c create mode 100644 leptonica/prog/feyn-fract.tif create mode 100644 leptonica/prog/feyn-fract2.tif create mode 100644 leptonica/prog/feyn-word.tif create mode 100644 leptonica/prog/feyn.tif create mode 100644 leptonica/prog/feynman-stamp.jpg create mode 100644 leptonica/prog/fhmtauto_reg.c create mode 100644 leptonica/prog/fhmtautogen.c create mode 100644 leptonica/prog/fileinfo.c create mode 100644 leptonica/prog/files_reg.c create mode 100644 leptonica/prog/find_colorregions.c create mode 100644 leptonica/prog/findbinding.c create mode 100644 leptonica/prog/findcorners_reg.c create mode 100644 leptonica/prog/findpattern1.c create mode 100644 leptonica/prog/findpattern2.c create mode 100644 leptonica/prog/findpattern3.c create mode 100644 leptonica/prog/findpattern_reg.c create mode 100644 leptonica/prog/fish24.jpg create mode 100644 leptonica/prog/flipdetect_reg.c create mode 100644 leptonica/prog/flipselgen.c.notused create mode 100644 leptonica/prog/flipsels.txt create mode 100644 leptonica/prog/fmorphauto_reg.c create mode 100644 leptonica/prog/fmorphautogen.c create mode 100644 leptonica/prog/fonts/chars-10.pa create mode 100644 leptonica/prog/fonts/chars-10.ps create mode 100644 leptonica/prog/fonts/chars-10.tif create mode 100644 leptonica/prog/fonts/chars-12.pa create mode 100644 leptonica/prog/fonts/chars-12.ps create mode 100644 leptonica/prog/fonts/chars-12.tif create mode 100644 leptonica/prog/fonts/chars-14.pa create mode 100644 leptonica/prog/fonts/chars-14.ps create mode 100644 leptonica/prog/fonts/chars-14.tif create mode 100644 leptonica/prog/fonts/chars-16.pa create mode 100644 leptonica/prog/fonts/chars-16.ps create mode 100644 leptonica/prog/fonts/chars-16.tif create mode 100644 leptonica/prog/fonts/chars-18.pa create mode 100644 leptonica/prog/fonts/chars-18.ps create mode 100644 leptonica/prog/fonts/chars-18.tif create mode 100644 leptonica/prog/fonts/chars-20.pa create mode 100644 leptonica/prog/fonts/chars-20.ps create mode 100644 leptonica/prog/fonts/chars-20.tif create mode 100644 leptonica/prog/fonts/chars-4.pa create mode 100644 leptonica/prog/fonts/chars-4.ps create mode 100644 leptonica/prog/fonts/chars-4.tif create mode 100644 leptonica/prog/fonts/chars-6.pa create mode 100644 leptonica/prog/fonts/chars-6.ps create mode 100644 leptonica/prog/fonts/chars-6.tif create mode 100644 leptonica/prog/fonts/chars-8.pa create mode 100644 leptonica/prog/fonts/chars-8.ps create mode 100644 leptonica/prog/fonts/chars-8.tif create mode 100644 leptonica/prog/form1.tif create mode 100644 leptonica/prog/form2.tif create mode 100644 leptonica/prog/fpix1_reg.c create mode 100644 leptonica/prog/fpix2_reg.c create mode 100644 leptonica/prog/fpixcontours.c create mode 100644 leptonica/prog/fuzzing/README.md create mode 100644 leptonica/prog/fuzzing/adaptmap_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/affine_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/barcode_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/barcode_fuzzer_seed_corpus.zip create mode 100644 leptonica/prog/fuzzing/baseline_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/bilateral_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/bilinear_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/binarize_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/blend_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/boxfunc3_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/boxfunc4_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/boxfunc5_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/boxfunc_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/ccbord_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/ccthin_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/checkerboard_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/classapp_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/colorfill_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/colorquant_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/compare_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/dewarp_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/edge_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/enhance_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/fhmtgen_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/finditalic_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/flipdetect_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/fpix2_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/general_corpus.zip create mode 100644 leptonica/prog/fuzzing/graphics_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/graymorph_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/grayquant_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/jpegiostub_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/kernel_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/leptfuzz.h create mode 100644 leptonica/prog/fuzzing/mask_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/maze_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/morph_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/morphapp_fuzzer.cc create mode 100755 leptonica/prog/fuzzing/oss-fuzz-build.sh create mode 100644 leptonica/prog/fuzzing/pageseg_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/paintcmap_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pix1_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pix3_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pix4_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pixMirrorDetectDwa_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pix_orient_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pix_rotate_shear_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pixa_recog_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/pixa_recog_fuzzer_seed_corpus.zip create mode 100644 leptonica/prog/fuzzing/pixconv_fuzzer.cc create mode 100644 leptonica/prog/fuzzing/recog_basic_fuzzer.cc create mode 100644 leptonica/prog/gammatest.c create mode 100644 leptonica/prog/genfonts_reg.c create mode 100644 leptonica/prog/german.png create mode 100644 leptonica/prog/gifio_reg.c create mode 100644 leptonica/prog/google-searchbox.png create mode 100644 leptonica/prog/gplotdata.example create mode 100644 leptonica/prog/graphicstest.c create mode 100644 leptonica/prog/gray-alpha.tif create mode 100644 leptonica/prog/grayfill_reg.c create mode 100644 leptonica/prog/graymorph1_reg.c create mode 100644 leptonica/prog/graymorph2_reg.c create mode 100644 leptonica/prog/graymorphtest.c create mode 100644 leptonica/prog/grayquant_reg.c create mode 100644 leptonica/prog/graytext.png create mode 100644 leptonica/prog/greencover.jpg create mode 100644 leptonica/prog/hardlight1_1.jpg create mode 100644 leptonica/prog/hardlight1_2.jpg create mode 100644 leptonica/prog/hardlight2_1.jpg create mode 100644 leptonica/prog/hardlight2_2.jpg create mode 100644 leptonica/prog/hardlight_reg.c create mode 100644 leptonica/prog/harmoniam-11.tif create mode 100644 leptonica/prog/harmoniam100-11.png create mode 100644 leptonica/prog/hash_reg.c create mode 100644 leptonica/prog/heap_reg.c create mode 100644 leptonica/prog/histoduptest.c create mode 100644 leptonica/prog/histotest.c create mode 100644 leptonica/prog/hmttemplate1.txt create mode 100644 leptonica/prog/hmttemplate2.txt create mode 100644 leptonica/prog/hole-filler.png create mode 100644 leptonica/prog/htmlviewer.c create mode 100644 leptonica/prog/imagetops.c create mode 100644 leptonica/prog/insert_reg.c create mode 100644 leptonica/prog/invertedtext.tif create mode 100644 leptonica/prog/ioformats_reg.c create mode 100644 leptonica/prog/iomisc_reg.c create mode 100644 leptonica/prog/italic.png create mode 100644 leptonica/prog/italic_reg.c create mode 100644 leptonica/prog/jbclass_reg.c create mode 100644 leptonica/prog/jbcorrelation.c create mode 100644 leptonica/prog/jbrankhaus.c create mode 100644 leptonica/prog/jbwords.c create mode 100644 leptonica/prog/jp2kio_reg.c create mode 100644 leptonica/prog/jpeg-coded.tif create mode 100644 leptonica/prog/jpegio_reg.c create mode 100644 leptonica/prog/juditharismax.jpg create mode 100644 leptonica/prog/karen8.jpg create mode 100644 leptonica/prog/kernel_reg.c create mode 100644 leptonica/prog/keystone.png create mode 100644 leptonica/prog/label_reg.c create mode 100644 leptonica/prog/lapide.052.100.jpg create mode 100644 leptonica/prog/leptonica-license.txt create mode 100644 leptonica/prog/lightcolortest.c create mode 100644 leptonica/prog/lighttext.jpg create mode 100644 leptonica/prog/lineremoval_reg.c create mode 100644 leptonica/prog/lion-mask.00010.tif create mode 100644 leptonica/prog/lion-mask.00016.tif create mode 100644 leptonica/prog/lion-page.00010.jpg create mode 100644 leptonica/prog/lion-page.00011.png create mode 100644 leptonica/prog/lion-page.00012.png create mode 100644 leptonica/prog/lion-page.00013.png create mode 100644 leptonica/prog/lion-page.00016.jpg create mode 100644 leptonica/prog/lion-page.00017.png create mode 100644 leptonica/prog/listtest.c create mode 100644 leptonica/prog/livre_adapt.c create mode 100644 leptonica/prog/livre_hmt.c create mode 100644 leptonica/prog/livre_makefigs.c create mode 100644 leptonica/prog/livre_orient.c create mode 100644 leptonica/prog/livre_pageseg.c create mode 100644 leptonica/prog/livre_seedgen.c create mode 100644 leptonica/prog/livre_tophat.c create mode 100644 leptonica/prog/locminmax_reg.c create mode 100644 leptonica/prog/logicops_reg.c create mode 100644 leptonica/prog/lowaccess_reg.c create mode 100644 leptonica/prog/lowsat_reg.c create mode 100644 leptonica/prog/lucasta-frag.jpg create mode 100644 leptonica/prog/lucasta.047.jpg create mode 100644 leptonica/prog/lucasta.1.300.tif create mode 100644 leptonica/prog/lucasta.150.jpg create mode 100644 leptonica/prog/lyra.005.jpg create mode 100644 leptonica/prog/lyra.036.jpg create mode 100644 leptonica/prog/lyra.5.na create mode 100644 leptonica/prog/makefile.static create mode 100644 leptonica/prog/maketile.c create mode 100644 leptonica/prog/map.057.jpg create mode 100644 leptonica/prog/map1.jpg create mode 100644 leptonica/prog/maptest.c create mode 100644 leptonica/prog/marge.jpg create mode 100644 leptonica/prog/maze_reg.c create mode 100644 leptonica/prog/messagetest.c create mode 100644 leptonica/prog/minisblack.tif create mode 100644 leptonica/prog/miniswhite.tif create mode 100644 leptonica/prog/misctest1.c create mode 100644 leptonica/prog/modifyhuesat.c create mode 100644 leptonica/prog/morphseq_reg.c create mode 100644 leptonica/prog/morphtemplate1.txt create mode 100644 leptonica/prog/morphtemplate2.txt create mode 100644 leptonica/prog/morphtest1.c create mode 100644 leptonica/prog/mtiff_reg.c create mode 100644 leptonica/prog/multitype_reg.c create mode 100644 leptonica/prog/nearline_reg.c create mode 100644 leptonica/prog/newspaper_reg.c create mode 100644 leptonica/prog/numa1_reg.c create mode 100644 leptonica/prog/numa2_reg.c create mode 100644 leptonica/prog/numa3_reg.c create mode 100644 leptonica/prog/numaranktest.c create mode 100644 leptonica/prog/ortiz-02.tif create mode 100644 leptonica/prog/ortiz-03.tif create mode 100644 leptonica/prog/ortiz-04.tif create mode 100644 leptonica/prog/ortiz-05.tif create mode 100644 leptonica/prog/otsutest1.c create mode 100644 leptonica/prog/otsutest2.c create mode 100644 leptonica/prog/overlap_reg.c create mode 100644 leptonica/prog/pageseg1.tif create mode 100644 leptonica/prog/pageseg2-mask.png create mode 100644 leptonica/prog/pageseg2-seed.png create mode 100644 leptonica/prog/pageseg2.tif create mode 100644 leptonica/prog/pageseg3.tif create mode 100644 leptonica/prog/pageseg4.tif create mode 100644 leptonica/prog/pageseg_reg.c create mode 100644 leptonica/prog/pagesegtest1.c create mode 100644 leptonica/prog/pagesegtest2.c create mode 100644 leptonica/prog/paint_reg.c create mode 100644 leptonica/prog/paintmask_reg.c create mode 100644 leptonica/prog/pancrazi.15.jpg create mode 100644 leptonica/prog/partifytest.c create mode 100644 leptonica/prog/partitiontest.c create mode 100644 leptonica/prog/patent.png create mode 100644 leptonica/prog/pdf2jpeg create mode 100755 leptonica/prog/pdf2mtiff create mode 100644 leptonica/prog/pdf2png create mode 100644 leptonica/prog/pdf2png-binary create mode 100644 leptonica/prog/pdf2png-color create mode 100644 leptonica/prog/pdf2png-gray create mode 100644 leptonica/prog/pdf2tiff create mode 100644 leptonica/prog/pdfio1_reg.c create mode 100644 leptonica/prog/pdfio2_reg.c create mode 100644 leptonica/prog/pdfseg_reg.c create mode 100644 leptonica/prog/pedante.079.jpg create mode 100644 leptonica/prog/percolate-4cc.png create mode 100644 leptonica/prog/percolate-8cc.png create mode 100644 leptonica/prog/percolatetest.c create mode 100644 leptonica/prog/pixa1_reg.c create mode 100644 leptonica/prog/pixa2_reg.c create mode 100644 leptonica/prog/pixaatest.c create mode 100644 leptonica/prog/pixadisp_reg.c create mode 100644 leptonica/prog/pixafileinfo.c create mode 100644 leptonica/prog/pixalloc_reg.c create mode 100644 leptonica/prog/pixcomp_reg.c create mode 100644 leptonica/prog/pixmem_reg.c create mode 100644 leptonica/prog/pixserial_reg.c create mode 100644 leptonica/prog/pixtile_reg.c create mode 100644 leptonica/prog/plottest.c create mode 100644 leptonica/prog/pngio_reg.c create mode 100644 leptonica/prog/pnmio_reg.c create mode 100644 leptonica/prog/printimage.c create mode 100644 leptonica/prog/printsplitimage.c create mode 100644 leptonica/prog/printtiff.c create mode 100644 leptonica/prog/projection_reg.c create mode 100644 leptonica/prog/projectionstats.jpg create mode 100644 leptonica/prog/projective_reg.c create mode 100644 leptonica/prog/ps2jpeg create mode 100644 leptonica/prog/ps2png create mode 100644 leptonica/prog/ps2png-binary create mode 100644 leptonica/prog/ps2png-color create mode 100644 leptonica/prog/ps2png-gray create mode 100644 leptonica/prog/ps2tiff create mode 100644 leptonica/prog/psio_reg.c create mode 100644 leptonica/prog/psioseg_reg.c create mode 100644 leptonica/prog/pta_reg.c create mode 100644 leptonica/prog/ptra1_reg.c create mode 100644 leptonica/prog/ptra2_reg.c create mode 100644 leptonica/prog/quadtree_reg.c create mode 100644 leptonica/prog/rabi-tiny.png create mode 100644 leptonica/prog/rabi.png create mode 100644 leptonica/prog/raggededge.png create mode 100644 leptonica/prog/rank_reg.c create mode 100644 leptonica/prog/rankbin_reg.c create mode 100644 leptonica/prog/rankhisto_reg.c create mode 100644 leptonica/prog/rasterop_reg.c create mode 100644 leptonica/prog/rasteropip_reg.c create mode 100644 leptonica/prog/rasteroptest.c create mode 100644 leptonica/prog/rbtreetest.c create mode 100644 leptonica/prog/recog/digits/bootnum1.pa create mode 100644 leptonica/prog/recog/digits/bootnum2.pa create mode 100644 leptonica/prog/recog/digits/bootnum3.pa create mode 100644 leptonica/prog/recog/digits/bootnum4.pa create mode 100644 leptonica/prog/recog/digits/digit0.comp.tif create mode 100644 leptonica/prog/recog/digits/digit1.comp.tif create mode 100644 leptonica/prog/recog/digits/digit2.comp.tif create mode 100644 leptonica/prog/recog/digits/digit3.comp.tif create mode 100644 leptonica/prog/recog/digits/digit4.comp.tif create mode 100644 leptonica/prog/recog/digits/digit5.comp.tif create mode 100644 leptonica/prog/recog/digits/digit5.orig-25.pa create mode 100644 leptonica/prog/recog/digits/digit6.comp.tif create mode 100644 leptonica/prog/recog/digits/digit7.comp.tif create mode 100644 leptonica/prog/recog/digits/digit8.comp.tif create mode 100644 leptonica/prog/recog/digits/digit9.comp.tif create mode 100644 leptonica/prog/recog/digits/digit_set01.pa create mode 100644 leptonica/prog/recog/digits/digit_set02.pa create mode 100644 leptonica/prog/recog/digits/digit_set03.pa create mode 100644 leptonica/prog/recog/digits/digit_set04.pa create mode 100644 leptonica/prog/recog/digits/digit_set05.pa create mode 100644 leptonica/prog/recog/digits/digit_set06.pa create mode 100644 leptonica/prog/recog/digits/digit_set07.pa create mode 100644 leptonica/prog/recog/digits/digit_set08.pa create mode 100644 leptonica/prog/recog/digits/digit_set09.pa create mode 100644 leptonica/prog/recog/digits/digit_set10.pa create mode 100644 leptonica/prog/recog/digits/digit_set11.pa create mode 100644 leptonica/prog/recog/digits/digit_set12.pa create mode 100644 leptonica/prog/recog/digits/digit_set13.pa create mode 100644 leptonica/prog/recog/digits/digit_set14.pa create mode 100644 leptonica/prog/recog/digits/digit_set15.pa create mode 100644 leptonica/prog/recog/digits/page.306.png create mode 100644 leptonica/prog/recog/digits/page.590.png create mode 100644 leptonica/prog/recog/sets/samples06.png create mode 100644 leptonica/prog/recog/sets/test01.pa create mode 100644 leptonica/prog/recog/sets/test02.pa create mode 100644 leptonica/prog/recog/sets/test03.pa create mode 100644 leptonica/prog/recog/sets/test05.pa create mode 100644 leptonica/prog/recog/sets/test06.pa create mode 100644 leptonica/prog/recog/sets/train01.pa create mode 100644 leptonica/prog/recog/sets/train02.pa create mode 100644 leptonica/prog/recog/sets/train03.pa create mode 100644 leptonica/prog/recog/sets/train04.pa create mode 100644 leptonica/prog/recog/sets/train05.pa create mode 100644 leptonica/prog/recog/sets/train06.pa create mode 100644 leptonica/prog/recog_bootnum1.c create mode 100644 leptonica/prog/recog_bootnum2.c create mode 100644 leptonica/prog/recog_bootnum3.c create mode 100644 leptonica/prog/recogsort.c create mode 100644 leptonica/prog/recogtest1.c create mode 100644 leptonica/prog/recogtest2.c create mode 100644 leptonica/prog/recogtest3.c create mode 100644 leptonica/prog/recogtest4.c create mode 100644 leptonica/prog/recogtest5.c create mode 100644 leptonica/prog/recogtest6.c create mode 100644 leptonica/prog/recogtest7.c create mode 100644 leptonica/prog/rectangle_reg.c create mode 100644 leptonica/prog/redcover.jpg create mode 100644 leptonica/prog/reducetest.c create mode 100755 leptonica/prog/reg_wrapper.sh create mode 100644 leptonica/prog/removecmap.c create mode 100644 leptonica/prog/renderfonts.c create mode 100644 leptonica/prog/replacebytes.c create mode 100644 leptonica/prog/rgb16.tif create mode 100644 leptonica/prog/rock.png create mode 100644 leptonica/prog/rotate1_reg.c create mode 100644 leptonica/prog/rotate2_reg.c create mode 100644 leptonica/prog/rotate_it.c create mode 100644 leptonica/prog/rotatefastalt.c create mode 100644 leptonica/prog/rotateorth_reg.c create mode 100644 leptonica/prog/rotateorthtest1.c create mode 100644 leptonica/prog/rotatetest1.c create mode 100644 leptonica/prog/runlengthtest.c create mode 100644 leptonica/prog/scale_it.c create mode 100644 leptonica/prog/scale_reg.c create mode 100644 leptonica/prog/scaleandtile.c create mode 100644 leptonica/prog/scaletest1.c create mode 100644 leptonica/prog/scaletest2.c create mode 100644 leptonica/prog/scots-frag.tif create mode 100644 leptonica/prog/seedfilltest.c create mode 100644 leptonica/prog/seedspread_reg.c create mode 100644 leptonica/prog/selio_reg.c create mode 100644 leptonica/prog/settest.c create mode 100644 leptonica/prog/sevens.tif create mode 100644 leptonica/prog/sharptest.c create mode 100644 leptonica/prog/shear1_reg.c create mode 100644 leptonica/prog/shear2_reg.c create mode 100644 leptonica/prog/shearer.148.tif create mode 100644 leptonica/prog/sheartest.c create mode 100644 leptonica/prog/showboxes.pac create mode 100644 leptonica/prog/showboxes1.baa create mode 100644 leptonica/prog/showboxes2.baa create mode 100644 leptonica/prog/showedges.c create mode 100644 leptonica/prog/singlecc.tif create mode 100644 leptonica/prog/skew_reg.c create mode 100644 leptonica/prog/skewtest.c create mode 100644 leptonica/prog/smallpix_reg.c create mode 100644 leptonica/prog/smoothedge_reg.c create mode 100644 leptonica/prog/sorttest.c create mode 100644 leptonica/prog/speckle.png create mode 100644 leptonica/prog/speckle2.png create mode 100644 leptonica/prog/speckle4.png create mode 100644 leptonica/prog/speckle_reg.c create mode 100644 leptonica/prog/splitcomp_reg.c create mode 100644 leptonica/prog/splitimage2pdf.c create mode 100644 leptonica/prog/stampede2.jpg create mode 100644 leptonica/prog/string_reg.c create mode 100644 leptonica/prog/stringtemplate1.txt create mode 100644 leptonica/prog/stringtemplate2.txt create mode 100644 leptonica/prog/subpixel_reg.c create mode 100644 leptonica/prog/sudoku1.dat create mode 100644 leptonica/prog/sudoku2.dat create mode 100644 leptonica/prog/sudoku3.dat create mode 100644 leptonica/prog/sudoku4.dat create mode 100644 leptonica/prog/sudoku5.dat create mode 100644 leptonica/prog/sudoku6.dat create mode 100644 leptonica/prog/sudoku7.dat create mode 100644 leptonica/prog/sudokutest.c create mode 100644 leptonica/prog/table.15.tif create mode 100644 leptonica/prog/table.150.png create mode 100644 leptonica/prog/table.27.tif create mode 100644 leptonica/prog/test-1bit-alpha.png create mode 100644 leptonica/prog/test-87220.59.png create mode 100644 leptonica/prog/test-cmap-alpha.png create mode 100644 leptonica/prog/test-cmap-alpha2.png create mode 100644 leptonica/prog/test-fulltrans-alpha.png create mode 100644 leptonica/prog/test-gray-alpha.png create mode 100644 leptonica/prog/test1.bmp create mode 100644 leptonica/prog/test1.png create mode 100644 leptonica/prog/test16.png create mode 100644 leptonica/prog/test16.tif create mode 100644 leptonica/prog/test24.jpg create mode 100644 leptonica/prog/test32-alpha.png create mode 100644 leptonica/prog/test8.jpg create mode 100644 leptonica/prog/testangle.na create mode 100644 leptonica/prog/testbuffer.tif create mode 100644 leptonica/prog/testfile1.pdf create mode 100644 leptonica/prog/testfile2.pdf create mode 100644 leptonica/prog/testscore.na create mode 100644 leptonica/prog/tetons.jpg create mode 100644 leptonica/prog/textorient.c create mode 100644 leptonica/prog/texturefill_reg.c create mode 100644 leptonica/prog/threshnorm_reg.c create mode 100644 leptonica/prog/tickets.tif create mode 100644 leptonica/prog/tiffpdftest.c create mode 100644 leptonica/prog/toc.99.tif create mode 100644 leptonica/prog/topotest.png create mode 100644 leptonica/prog/translate_reg.c create mode 100644 leptonica/prog/trctest.c create mode 100644 leptonica/prog/tribune-page-4x.png create mode 100644 leptonica/prog/tribune-t.png create mode 100644 leptonica/prog/tribune-word.png create mode 100644 leptonica/prog/turingtest.png create mode 100644 leptonica/prog/two-peak-histo.na create mode 100644 leptonica/prog/underline1.jpg create mode 100644 leptonica/prog/underline2.jpg create mode 100644 leptonica/prog/underline3.jpg create mode 100644 leptonica/prog/underline4.jpg create mode 100644 leptonica/prog/underline5.jpg create mode 100644 leptonica/prog/underline6.jpg create mode 100644 leptonica/prog/underline7.jpg create mode 100644 leptonica/prog/underlinetest.c create mode 100644 leptonica/prog/w91frag.jpg create mode 100644 leptonica/prog/warped_paper.jpg create mode 100644 leptonica/prog/warped_sudoku.jpg create mode 100644 leptonica/prog/warper_reg.c create mode 100644 leptonica/prog/warpertest.c create mode 100644 leptonica/prog/watershed_reg.c create mode 100644 leptonica/prog/weasel-113c.png create mode 100644 leptonica/prog/weasel-44c.png create mode 100644 leptonica/prog/weasel-4c.2.png create mode 100644 leptonica/prog/weasel-64g.png create mode 100644 leptonica/prog/weasel-8g.png create mode 100644 leptonica/prog/weasel2.4c.bmp create mode 100644 leptonica/prog/weasel2.4c.png create mode 100644 leptonica/prog/weasel2.4g.png create mode 100644 leptonica/prog/weasel2.png create mode 100644 leptonica/prog/weasel32.png create mode 100644 leptonica/prog/weasel4.11c.png create mode 100644 leptonica/prog/weasel4.16c.png create mode 100644 leptonica/prog/weasel4.16g.png create mode 100644 leptonica/prog/weasel4.5g.png create mode 100644 leptonica/prog/weasel4.8g.png create mode 100644 leptonica/prog/weasel4.png create mode 100644 leptonica/prog/weasel8.149g.png create mode 100644 leptonica/prog/weasel8.16g.nocmap.png create mode 100644 leptonica/prog/weasel8.16g.png create mode 100644 leptonica/prog/weasel8.240c.png create mode 100644 leptonica/prog/weasel8.5g.nocmap.png create mode 100644 leptonica/prog/weasel8.5g.png create mode 100644 leptonica/prog/weasel8.png create mode 100644 leptonica/prog/webpanimio_reg.c create mode 100644 leptonica/prog/webpio_reg.c create mode 100644 leptonica/prog/wet-day.jpg create mode 100644 leptonica/prog/witten.tif create mode 100644 leptonica/prog/wordboxes_reg.c create mode 100644 leptonica/prog/words.15.tif create mode 100644 leptonica/prog/words.44.tif create mode 100644 leptonica/prog/wordsinorder.c create mode 100644 leptonica/prog/writemtiff.c create mode 100644 leptonica/prog/writetext_reg.c create mode 100644 leptonica/prog/wyom.jpg create mode 100644 leptonica/prog/xformbox_reg.c create mode 100644 leptonica/prog/xtractprotos.c create mode 100644 leptonica/prog/yuvtest.c create mode 100644 leptonica/prog/zanotti-78.jpg create mode 100644 leptonica/prog/zier.jpg create mode 100644 leptonica/src/CMakeLists.txt create mode 100644 leptonica/src/Makefile.am create mode 100644 leptonica/src/adaptmap.c create mode 100644 leptonica/src/affine.c create mode 100644 leptonica/src/affinecompose.c create mode 100644 leptonica/src/allheaders.h create mode 100644 leptonica/src/allheaders_bot.txt create mode 100644 leptonica/src/allheaders_top.txt create mode 100644 leptonica/src/alltypes.h create mode 100644 leptonica/src/array.h create mode 100644 leptonica/src/arrayaccess.c create mode 100644 leptonica/src/arrayaccess.h create mode 100644 leptonica/src/bardecode.c create mode 100644 leptonica/src/baseline.c create mode 100644 leptonica/src/bbuffer.c create mode 100644 leptonica/src/bbuffer.h create mode 100644 leptonica/src/bilateral.c create mode 100644 leptonica/src/bilateral.h create mode 100644 leptonica/src/bilinear.c create mode 100644 leptonica/src/binarize.c create mode 100644 leptonica/src/binexpand.c create mode 100644 leptonica/src/binreduce.c create mode 100644 leptonica/src/blend.c create mode 100644 leptonica/src/bmf.c create mode 100644 leptonica/src/bmf.h create mode 100644 leptonica/src/bmfdata.h create mode 100644 leptonica/src/bmp.h create mode 100644 leptonica/src/bmpio.c create mode 100644 leptonica/src/bmpiostub.c create mode 100644 leptonica/src/bootnumgen1.c create mode 100644 leptonica/src/bootnumgen2.c create mode 100644 leptonica/src/bootnumgen3.c create mode 100644 leptonica/src/bootnumgen4.c create mode 100644 leptonica/src/boxbasic.c create mode 100644 leptonica/src/boxfunc1.c create mode 100644 leptonica/src/boxfunc2.c create mode 100644 leptonica/src/boxfunc3.c create mode 100644 leptonica/src/boxfunc4.c create mode 100644 leptonica/src/boxfunc5.c create mode 100644 leptonica/src/bytearray.c create mode 100644 leptonica/src/ccbord.c create mode 100644 leptonica/src/ccbord.h create mode 100644 leptonica/src/ccthin.c create mode 100644 leptonica/src/checkerboard.c create mode 100644 leptonica/src/classapp.c create mode 100644 leptonica/src/colorcontent.c create mode 100644 leptonica/src/colorfill.c create mode 100644 leptonica/src/colorfill.h create mode 100644 leptonica/src/coloring.c create mode 100644 leptonica/src/colormap.c create mode 100644 leptonica/src/colormorph.c create mode 100644 leptonica/src/colorquant1.c create mode 100644 leptonica/src/colorquant2.c create mode 100644 leptonica/src/colorseg.c create mode 100644 leptonica/src/colorspace.c create mode 100644 leptonica/src/compare.c create mode 100644 leptonica/src/conncomp.c create mode 100644 leptonica/src/convertfiles.c create mode 100644 leptonica/src/convolve.c create mode 100644 leptonica/src/correlscore.c create mode 100644 leptonica/src/dewarp.h create mode 100644 leptonica/src/dewarp1.c create mode 100644 leptonica/src/dewarp2.c create mode 100644 leptonica/src/dewarp3.c create mode 100644 leptonica/src/dewarp4.c create mode 100644 leptonica/src/dnabasic.c create mode 100644 leptonica/src/dnafunc1.c create mode 100644 leptonica/src/dnahash.c create mode 100644 leptonica/src/dwacomb.2.c create mode 100644 leptonica/src/dwacomblow.2.c create mode 100644 leptonica/src/edge.c create mode 100644 leptonica/src/encoding.c create mode 100644 leptonica/src/endianness.h.in create mode 100644 leptonica/src/enhance.c create mode 100644 leptonica/src/environ.h create mode 100644 leptonica/src/fhmtauto.c create mode 100644 leptonica/src/fhmtgen.1.c create mode 100644 leptonica/src/fhmtgenlow.1.c create mode 100644 leptonica/src/finditalic.c create mode 100644 leptonica/src/flipdetect.c create mode 100644 leptonica/src/flipdetectdwa.c.notused create mode 100644 leptonica/src/fmorphauto.c create mode 100644 leptonica/src/fmorphgen.1.c create mode 100644 leptonica/src/fmorphgenlow.1.c create mode 100644 leptonica/src/fpix1.c create mode 100644 leptonica/src/fpix2.c create mode 100644 leptonica/src/gifio.c create mode 100644 leptonica/src/gifiostub.c create mode 100644 leptonica/src/gplot.c create mode 100644 leptonica/src/gplot.h create mode 100644 leptonica/src/graphics.c create mode 100644 leptonica/src/graymorph.c create mode 100644 leptonica/src/grayquant.c create mode 100644 leptonica/src/heap.c create mode 100644 leptonica/src/heap.h create mode 100644 leptonica/src/hmttemplate1.txt create mode 100644 leptonica/src/hmttemplate2.txt create mode 100644 leptonica/src/imageio.h create mode 100644 leptonica/src/jbclass.c create mode 100644 leptonica/src/jbclass.h create mode 100644 leptonica/src/jp2kheader.c create mode 100644 leptonica/src/jp2kheaderstub.c create mode 100644 leptonica/src/jp2kio.c create mode 100644 leptonica/src/jp2kiostub.c create mode 100644 leptonica/src/jpegio.c create mode 100644 leptonica/src/jpegiostub.c create mode 100644 leptonica/src/kernel.c create mode 100644 leptonica/src/leptonica-license.txt create mode 100644 leptonica/src/leptwin.c create mode 100644 leptonica/src/leptwin.h create mode 100644 leptonica/src/libversions.c create mode 100644 leptonica/src/list.c create mode 100644 leptonica/src/list.h create mode 100644 leptonica/src/mainpage.txt create mode 100644 leptonica/src/makefile.static create mode 100644 leptonica/src/map.c create mode 100644 leptonica/src/maze.c create mode 100644 leptonica/src/morph.c create mode 100644 leptonica/src/morph.h create mode 100644 leptonica/src/morphapp.c create mode 100644 leptonica/src/morphdwa.c create mode 100644 leptonica/src/morphseq.c create mode 100644 leptonica/src/morphtemplate1.txt create mode 100644 leptonica/src/morphtemplate2.txt create mode 100644 leptonica/src/numabasic.c create mode 100644 leptonica/src/numafunc1.c create mode 100644 leptonica/src/numafunc2.c create mode 100644 leptonica/src/pageseg.c create mode 100644 leptonica/src/paintcmap.c create mode 100644 leptonica/src/parseprotos.c create mode 100644 leptonica/src/partify.c create mode 100644 leptonica/src/partition.c create mode 100644 leptonica/src/pdfio1.c create mode 100644 leptonica/src/pdfio1stub.c create mode 100644 leptonica/src/pdfio2.c create mode 100644 leptonica/src/pdfio2stub.c create mode 100644 leptonica/src/pix.h create mode 100644 leptonica/src/pix1.c create mode 100644 leptonica/src/pix2.c create mode 100644 leptonica/src/pix3.c create mode 100644 leptonica/src/pix4.c create mode 100644 leptonica/src/pix5.c create mode 100644 leptonica/src/pixabasic.c create mode 100644 leptonica/src/pixacc.c create mode 100644 leptonica/src/pixafunc1.c create mode 100644 leptonica/src/pixafunc2.c create mode 100644 leptonica/src/pixalloc.c create mode 100644 leptonica/src/pixarith.c create mode 100644 leptonica/src/pixcomp.c create mode 100644 leptonica/src/pixconv.c create mode 100644 leptonica/src/pixlabel.c create mode 100644 leptonica/src/pixtiling.c create mode 100644 leptonica/src/pngio.c create mode 100644 leptonica/src/pngiostub.c create mode 100644 leptonica/src/pnmio.c create mode 100644 leptonica/src/pnmiostub.c create mode 100644 leptonica/src/projective.c create mode 100644 leptonica/src/psio1.c create mode 100644 leptonica/src/psio1stub.c create mode 100644 leptonica/src/psio2.c create mode 100644 leptonica/src/psio2stub.c create mode 100644 leptonica/src/ptabasic.c create mode 100644 leptonica/src/ptafunc1.c create mode 100644 leptonica/src/ptafunc2.c create mode 100644 leptonica/src/ptra.c create mode 100644 leptonica/src/ptra.h create mode 100644 leptonica/src/quadtree.c create mode 100644 leptonica/src/queue.c create mode 100644 leptonica/src/queue.h create mode 100644 leptonica/src/rank.c create mode 100644 leptonica/src/rbtree.c create mode 100644 leptonica/src/rbtree.h create mode 100644 leptonica/src/readbarcode.c create mode 100644 leptonica/src/readbarcode.h create mode 100644 leptonica/src/readfile.c create mode 100644 leptonica/src/recog.h create mode 100644 leptonica/src/recogbasic.c create mode 100644 leptonica/src/recogdid.c create mode 100644 leptonica/src/recogident.c create mode 100644 leptonica/src/recogtrain.c create mode 100644 leptonica/src/regutils.c create mode 100644 leptonica/src/regutils.h create mode 100644 leptonica/src/rop.c create mode 100644 leptonica/src/roplow.c create mode 100644 leptonica/src/rotate.c create mode 100644 leptonica/src/rotateam.c create mode 100644 leptonica/src/rotateorth.c create mode 100644 leptonica/src/rotateshear.c create mode 100644 leptonica/src/runlength.c create mode 100644 leptonica/src/sarray1.c create mode 100644 leptonica/src/sarray2.c create mode 100644 leptonica/src/scale1.c create mode 100644 leptonica/src/scale2.c create mode 100644 leptonica/src/seedfill.c create mode 100644 leptonica/src/sel1.c create mode 100644 leptonica/src/sel2.c create mode 100644 leptonica/src/selgen.c create mode 100644 leptonica/src/shear.c create mode 100644 leptonica/src/skew.c create mode 100644 leptonica/src/spixio.c create mode 100644 leptonica/src/stack.c create mode 100644 leptonica/src/stack.h create mode 100644 leptonica/src/stringcode.c create mode 100644 leptonica/src/stringcode.h create mode 100644 leptonica/src/stringtemplate1.txt create mode 100644 leptonica/src/stringtemplate2.txt create mode 100644 leptonica/src/strokes.c create mode 100644 leptonica/src/sudoku.c create mode 100644 leptonica/src/sudoku.h create mode 100644 leptonica/src/textops.c create mode 100644 leptonica/src/tiffio.c create mode 100644 leptonica/src/tiffiostub.c create mode 100644 leptonica/src/utils1.c create mode 100644 leptonica/src/utils2.c create mode 100644 leptonica/src/warper.c create mode 100644 leptonica/src/watershed.c create mode 100644 leptonica/src/watershed.h create mode 100644 leptonica/src/webpanimio.c create mode 100644 leptonica/src/webpanimiostub.c create mode 100644 leptonica/src/webpio.c create mode 100644 leptonica/src/webpiostub.c create mode 100644 leptonica/src/writefile.c create mode 100644 leptonica/src/zlibmem.c create mode 100644 leptonica/src/zlibmemstub.c create mode 100644 leptonica/style-guide.txt create mode 100644 leptonica/sw.cpp create mode 100644 leptonica/version-notes.html create mode 100644 lib/gs_css_e.ps create mode 100644 lib/zugferd.ps create mode 100644 tesseract/.clang-format create mode 100644 tesseract/.gitattributes create mode 100644 tesseract/.github/ISSUE_TEMPLATE.md create mode 100644 tesseract/.github/workflows/autotools.yml create mode 100644 tesseract/.github/workflows/cmake-linuxclang-win.yml create mode 100644 tesseract/.github/workflows/cmake.yml create mode 100644 tesseract/.github/workflows/sw.yml create mode 100644 tesseract/.github/workflows/unittest-disablelegacy.yml create mode 100644 tesseract/.github/workflows/unittest.yml create mode 100644 tesseract/.gitmodules create mode 100644 tesseract/.lgtm.yml create mode 100644 tesseract/.travis.yml create mode 100644 tesseract/AUTHORS create mode 100644 tesseract/CMakeLists.txt create mode 100644 tesseract/CONTRIBUTING.md create mode 100644 tesseract/ChangeLog create mode 100644 tesseract/Dockerfile create mode 100644 tesseract/INSTALL create mode 100644 tesseract/INSTALL.GIT.md create mode 100644 tesseract/LICENSE create mode 100644 tesseract/Makefile.am create mode 100644 tesseract/README.md create mode 100644 tesseract/VERSION create mode 100644 tesseract/appveyor.yml create mode 100755 tesseract/autogen.sh create mode 100644 tesseract/cmake/AddCompilerFlag.cmake create mode 100644 tesseract/cmake/BuildFunctions.cmake create mode 100644 tesseract/cmake/Configure.cmake create mode 100644 tesseract/cmake/OptimizeForArchitecture.cmake create mode 100644 tesseract/cmake/SourceGroups.cmake create mode 100644 tesseract/cmake/templates/TesseractConfig.cmake.in create mode 100644 tesseract/cmake/templates/cmake_uninstall.cmake.in create mode 100644 tesseract/configure.ac create mode 100644 tesseract/doc/Doxyfile create mode 100644 tesseract/doc/ambiguous_words.1.asc create mode 100644 tesseract/doc/classifier_tester.1.asc create mode 100644 tesseract/doc/cntraining.1.asc create mode 100644 tesseract/doc/combine_lang_model.1.asc create mode 100644 tesseract/doc/combine_tessdata.1.asc create mode 100644 tesseract/doc/dawg2wordlist.1.asc create mode 100755 tesseract/doc/generate_manpages.sh create mode 100644 tesseract/doc/lstmeval.1.asc create mode 100644 tesseract/doc/lstmtraining.1.asc create mode 100644 tesseract/doc/merge_unicharsets.1.asc create mode 100644 tesseract/doc/mftraining.1.asc create mode 100644 tesseract/doc/set_unicharset_properties.1.asc create mode 100644 tesseract/doc/shapeclustering.1.asc create mode 100644 tesseract/doc/tesseract.1.asc create mode 100644 tesseract/doc/tesseract.bib create mode 100644 tesseract/doc/tesseract.natvis create mode 100644 tesseract/doc/text2image.1.asc create mode 100644 tesseract/doc/unicharambigs.5.asc create mode 100644 tesseract/doc/unicharset.5.asc create mode 100644 tesseract/doc/unicharset_extractor.1.asc create mode 100644 tesseract/doc/wordlist2dawg.1.asc create mode 100644 tesseract/docker-compose.yml create mode 100644 tesseract/include/tesseract/baseapi.h create mode 100644 tesseract/include/tesseract/capi.h create mode 100644 tesseract/include/tesseract/export.h create mode 100644 tesseract/include/tesseract/ltrresultiterator.h create mode 100644 tesseract/include/tesseract/ocrclass.h create mode 100644 tesseract/include/tesseract/osdetect.h create mode 100644 tesseract/include/tesseract/pageiterator.h create mode 100644 tesseract/include/tesseract/publictypes.h create mode 100644 tesseract/include/tesseract/renderer.h create mode 100644 tesseract/include/tesseract/resultiterator.h create mode 100644 tesseract/include/tesseract/thresholder.h create mode 100644 tesseract/include/tesseract/unichar.h create mode 100644 tesseract/include/tesseract/version.h.in create mode 100644 tesseract/java/Makefile.am create mode 100644 tesseract/java/Manifest.txt create mode 100644 tesseract/java/com/Makefile.am create mode 100644 tesseract/java/com/google/Makefile.am create mode 100644 tesseract/java/com/google/scrollview/Makefile.am create mode 100644 tesseract/java/com/google/scrollview/ScrollView.java create mode 100644 tesseract/java/com/google/scrollview/events/Makefile.am create mode 100644 tesseract/java/com/google/scrollview/events/SVEvent.java create mode 100644 tesseract/java/com/google/scrollview/events/SVEventHandler.java create mode 100644 tesseract/java/com/google/scrollview/events/SVEventType.java create mode 100644 tesseract/java/com/google/scrollview/ui/Makefile.am create mode 100644 tesseract/java/com/google/scrollview/ui/SVAbstractMenuItem.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVCheckboxMenuItem.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVEmptyMenuItem.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVImageHandler.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVMenuBar.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVMenuItem.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVPopupMenu.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVSubMenuItem.java create mode 100644 tesseract/java/com/google/scrollview/ui/SVWindow.java create mode 100644 tesseract/m4/ax_check_compile_flag.m4 create mode 100644 tesseract/m4/ax_split_version.m4 create mode 100644 tesseract/snap/snapcraft.yaml create mode 100644 tesseract/src/api/altorenderer.cpp create mode 100644 tesseract/src/api/baseapi.cpp create mode 100644 tesseract/src/api/capi.cpp create mode 100644 tesseract/src/api/hocrrenderer.cpp create mode 100644 tesseract/src/api/lstmboxrenderer.cpp create mode 100644 tesseract/src/api/pdf_ttf.h create mode 100644 tesseract/src/api/pdfrenderer.cpp create mode 100644 tesseract/src/api/renderer.cpp create mode 100644 tesseract/src/api/tesseractmain.cpp create mode 100644 tesseract/src/api/wordstrboxrenderer.cpp create mode 100644 tesseract/src/arch/dotproduct.cpp create mode 100644 tesseract/src/arch/dotproduct.h create mode 100644 tesseract/src/arch/dotproductavx.cpp create mode 100644 tesseract/src/arch/dotproductfma.cpp create mode 100644 tesseract/src/arch/dotproductsse.cpp create mode 100644 tesseract/src/arch/intsimdmatrix.cpp create mode 100644 tesseract/src/arch/intsimdmatrix.h create mode 100644 tesseract/src/arch/intsimdmatrixavx2.cpp create mode 100644 tesseract/src/arch/intsimdmatrixneon.cpp create mode 100644 tesseract/src/arch/intsimdmatrixsse.cpp create mode 100644 tesseract/src/arch/simddetect.cpp create mode 100644 tesseract/src/arch/simddetect.h create mode 100644 tesseract/src/ccmain/adaptions.cpp create mode 100644 tesseract/src/ccmain/applybox.cpp create mode 100644 tesseract/src/ccmain/control.cpp create mode 100644 tesseract/src/ccmain/control.h create mode 100644 tesseract/src/ccmain/docqual.cpp create mode 100644 tesseract/src/ccmain/docqual.h create mode 100644 tesseract/src/ccmain/equationdetect.cpp create mode 100644 tesseract/src/ccmain/equationdetect.h create mode 100644 tesseract/src/ccmain/fixspace.cpp create mode 100644 tesseract/src/ccmain/fixspace.h create mode 100644 tesseract/src/ccmain/fixxht.cpp create mode 100644 tesseract/src/ccmain/linerec.cpp create mode 100644 tesseract/src/ccmain/ltrresultiterator.cpp create mode 100644 tesseract/src/ccmain/mutableiterator.cpp create mode 100644 tesseract/src/ccmain/mutableiterator.h create mode 100644 tesseract/src/ccmain/osdetect.cpp create mode 100644 tesseract/src/ccmain/output.cpp create mode 100644 tesseract/src/ccmain/output.h create mode 100644 tesseract/src/ccmain/pageiterator.cpp create mode 100644 tesseract/src/ccmain/pagesegmain.cpp create mode 100644 tesseract/src/ccmain/pagewalk.cpp create mode 100644 tesseract/src/ccmain/par_control.cpp create mode 100644 tesseract/src/ccmain/paragraphs.cpp create mode 100644 tesseract/src/ccmain/paragraphs.h create mode 100644 tesseract/src/ccmain/paragraphs_internal.h create mode 100644 tesseract/src/ccmain/paramsd.cpp create mode 100644 tesseract/src/ccmain/paramsd.h create mode 100644 tesseract/src/ccmain/pgedit.cpp create mode 100644 tesseract/src/ccmain/pgedit.h create mode 100644 tesseract/src/ccmain/recogtraining.cpp create mode 100644 tesseract/src/ccmain/reject.cpp create mode 100644 tesseract/src/ccmain/reject.h create mode 100644 tesseract/src/ccmain/resultiterator.cpp create mode 100644 tesseract/src/ccmain/superscript.cpp create mode 100644 tesseract/src/ccmain/tessbox.cpp create mode 100644 tesseract/src/ccmain/tessedit.cpp create mode 100644 tesseract/src/ccmain/tesseractclass.cpp create mode 100644 tesseract/src/ccmain/tesseractclass.h create mode 100644 tesseract/src/ccmain/tessvars.cpp create mode 100644 tesseract/src/ccmain/tessvars.h create mode 100644 tesseract/src/ccmain/tfacepp.cpp create mode 100644 tesseract/src/ccmain/thresholder.cpp create mode 100644 tesseract/src/ccmain/werdit.cpp create mode 100644 tesseract/src/ccmain/werdit.h create mode 100644 tesseract/src/ccstruct/blamer.cpp create mode 100644 tesseract/src/ccstruct/blamer.h create mode 100644 tesseract/src/ccstruct/blobbox.cpp create mode 100644 tesseract/src/ccstruct/blobbox.h create mode 100644 tesseract/src/ccstruct/blobs.cpp create mode 100644 tesseract/src/ccstruct/blobs.h create mode 100644 tesseract/src/ccstruct/blread.cpp create mode 100644 tesseract/src/ccstruct/blread.h create mode 100644 tesseract/src/ccstruct/boxread.cpp create mode 100644 tesseract/src/ccstruct/boxread.h create mode 100644 tesseract/src/ccstruct/boxword.cpp create mode 100644 tesseract/src/ccstruct/boxword.h create mode 100644 tesseract/src/ccstruct/ccstruct.cpp create mode 100644 tesseract/src/ccstruct/ccstruct.h create mode 100644 tesseract/src/ccstruct/coutln.cpp create mode 100644 tesseract/src/ccstruct/coutln.h create mode 100644 tesseract/src/ccstruct/crakedge.h create mode 100644 tesseract/src/ccstruct/debugpixa.h create mode 100644 tesseract/src/ccstruct/detlinefit.cpp create mode 100644 tesseract/src/ccstruct/detlinefit.h create mode 100644 tesseract/src/ccstruct/dppoint.cpp create mode 100644 tesseract/src/ccstruct/dppoint.h create mode 100644 tesseract/src/ccstruct/fontinfo.cpp create mode 100644 tesseract/src/ccstruct/fontinfo.h create mode 100644 tesseract/src/ccstruct/imagedata.cpp create mode 100644 tesseract/src/ccstruct/imagedata.h create mode 100644 tesseract/src/ccstruct/linlsq.cpp create mode 100644 tesseract/src/ccstruct/linlsq.h create mode 100644 tesseract/src/ccstruct/matrix.cpp create mode 100644 tesseract/src/ccstruct/matrix.h create mode 100644 tesseract/src/ccstruct/mod128.cpp create mode 100644 tesseract/src/ccstruct/mod128.h create mode 100644 tesseract/src/ccstruct/normalis.cpp create mode 100644 tesseract/src/ccstruct/normalis.h create mode 100644 tesseract/src/ccstruct/ocrblock.cpp create mode 100644 tesseract/src/ccstruct/ocrblock.h create mode 100644 tesseract/src/ccstruct/ocrpara.cpp create mode 100644 tesseract/src/ccstruct/ocrpara.h create mode 100644 tesseract/src/ccstruct/ocrrow.cpp create mode 100644 tesseract/src/ccstruct/ocrrow.h create mode 100644 tesseract/src/ccstruct/otsuthr.cpp create mode 100644 tesseract/src/ccstruct/otsuthr.h create mode 100644 tesseract/src/ccstruct/pageres.cpp create mode 100644 tesseract/src/ccstruct/pageres.h create mode 100644 tesseract/src/ccstruct/params_training_featdef.cpp create mode 100644 tesseract/src/ccstruct/params_training_featdef.h create mode 100644 tesseract/src/ccstruct/pdblock.cpp create mode 100644 tesseract/src/ccstruct/pdblock.h create mode 100644 tesseract/src/ccstruct/points.cpp create mode 100644 tesseract/src/ccstruct/points.h create mode 100644 tesseract/src/ccstruct/polyaprx.cpp create mode 100644 tesseract/src/ccstruct/polyaprx.h create mode 100644 tesseract/src/ccstruct/polyblk.cpp create mode 100644 tesseract/src/ccstruct/polyblk.h create mode 100644 tesseract/src/ccstruct/quadlsq.cpp create mode 100644 tesseract/src/ccstruct/quadlsq.h create mode 100644 tesseract/src/ccstruct/quadratc.h create mode 100644 tesseract/src/ccstruct/quspline.cpp create mode 100644 tesseract/src/ccstruct/quspline.h create mode 100644 tesseract/src/ccstruct/ratngs.cpp create mode 100644 tesseract/src/ccstruct/ratngs.h create mode 100644 tesseract/src/ccstruct/rect.cpp create mode 100644 tesseract/src/ccstruct/rect.h create mode 100644 tesseract/src/ccstruct/rejctmap.cpp create mode 100644 tesseract/src/ccstruct/rejctmap.h create mode 100644 tesseract/src/ccstruct/seam.cpp create mode 100644 tesseract/src/ccstruct/seam.h create mode 100644 tesseract/src/ccstruct/split.cpp create mode 100644 tesseract/src/ccstruct/split.h create mode 100644 tesseract/src/ccstruct/statistc.cpp create mode 100644 tesseract/src/ccstruct/statistc.h create mode 100644 tesseract/src/ccstruct/stepblob.cpp create mode 100644 tesseract/src/ccstruct/stepblob.h create mode 100644 tesseract/src/ccstruct/werd.cpp create mode 100644 tesseract/src/ccstruct/werd.h create mode 100644 tesseract/src/ccutil/ambigs.cpp create mode 100644 tesseract/src/ccutil/ambigs.h create mode 100644 tesseract/src/ccutil/bits16.h create mode 100644 tesseract/src/ccutil/bitvector.cpp create mode 100644 tesseract/src/ccutil/bitvector.h create mode 100644 tesseract/src/ccutil/ccutil.cpp create mode 100644 tesseract/src/ccutil/ccutil.h create mode 100644 tesseract/src/ccutil/clst.cpp create mode 100644 tesseract/src/ccutil/clst.h create mode 100644 tesseract/src/ccutil/elst.cpp create mode 100644 tesseract/src/ccutil/elst.h create mode 100644 tesseract/src/ccutil/elst2.cpp create mode 100644 tesseract/src/ccutil/elst2.h create mode 100644 tesseract/src/ccutil/errcode.cpp create mode 100644 tesseract/src/ccutil/errcode.h create mode 100644 tesseract/src/ccutil/fileerr.h create mode 100644 tesseract/src/ccutil/genericheap.h create mode 100644 tesseract/src/ccutil/genericvector.h create mode 100644 tesseract/src/ccutil/helpers.h create mode 100644 tesseract/src/ccutil/host.h create mode 100644 tesseract/src/ccutil/indexmapbidi.cpp create mode 100644 tesseract/src/ccutil/indexmapbidi.h create mode 100644 tesseract/src/ccutil/kdpair.h create mode 100644 tesseract/src/ccutil/lsterr.h create mode 100644 tesseract/src/ccutil/mainblk.cpp create mode 100644 tesseract/src/ccutil/object_cache.h create mode 100644 tesseract/src/ccutil/params.cpp create mode 100644 tesseract/src/ccutil/params.h create mode 100644 tesseract/src/ccutil/qrsequence.h create mode 100644 tesseract/src/ccutil/scanutils.cpp create mode 100644 tesseract/src/ccutil/scanutils.h create mode 100644 tesseract/src/ccutil/serialis.cpp create mode 100644 tesseract/src/ccutil/serialis.h create mode 100644 tesseract/src/ccutil/sorthelper.h create mode 100644 tesseract/src/ccutil/strngs.cpp create mode 100644 tesseract/src/ccutil/strngs.h create mode 100644 tesseract/src/ccutil/tessdatamanager.cpp create mode 100644 tesseract/src/ccutil/tessdatamanager.h create mode 100644 tesseract/src/ccutil/tprintf.cpp create mode 100644 tesseract/src/ccutil/tprintf.h create mode 100644 tesseract/src/ccutil/unichar.cpp create mode 100644 tesseract/src/ccutil/unicharcompress.cpp create mode 100644 tesseract/src/ccutil/unicharcompress.h create mode 100644 tesseract/src/ccutil/unicharmap.cpp create mode 100644 tesseract/src/ccutil/unicharmap.h create mode 100644 tesseract/src/ccutil/unicharset.cpp create mode 100644 tesseract/src/ccutil/unicharset.h create mode 100644 tesseract/src/ccutil/unicity_table.h create mode 100644 tesseract/src/ccutil/universalambigs.cpp create mode 100644 tesseract/src/ccutil/universalambigs.h create mode 100644 tesseract/src/classify/adaptive.cpp create mode 100644 tesseract/src/classify/adaptive.h create mode 100644 tesseract/src/classify/adaptmatch.cpp create mode 100644 tesseract/src/classify/blobclass.cpp create mode 100644 tesseract/src/classify/blobclass.h create mode 100644 tesseract/src/classify/classify.cpp create mode 100644 tesseract/src/classify/classify.h create mode 100644 tesseract/src/classify/cluster.cpp create mode 100644 tesseract/src/classify/cluster.h create mode 100644 tesseract/src/classify/clusttool.cpp create mode 100644 tesseract/src/classify/clusttool.h create mode 100644 tesseract/src/classify/cutoffs.cpp create mode 100644 tesseract/src/classify/featdefs.cpp create mode 100644 tesseract/src/classify/featdefs.h create mode 100644 tesseract/src/classify/float2int.cpp create mode 100644 tesseract/src/classify/float2int.h create mode 100644 tesseract/src/classify/fpoint.cpp create mode 100644 tesseract/src/classify/fpoint.h create mode 100644 tesseract/src/classify/intfeaturespace.cpp create mode 100644 tesseract/src/classify/intfeaturespace.h create mode 100644 tesseract/src/classify/intfx.cpp create mode 100644 tesseract/src/classify/intfx.h create mode 100644 tesseract/src/classify/intmatcher.cpp create mode 100644 tesseract/src/classify/intmatcher.h create mode 100644 tesseract/src/classify/intproto.cpp create mode 100644 tesseract/src/classify/intproto.h create mode 100644 tesseract/src/classify/kdtree.cpp create mode 100644 tesseract/src/classify/kdtree.h create mode 100644 tesseract/src/classify/mf.cpp create mode 100644 tesseract/src/classify/mf.h create mode 100644 tesseract/src/classify/mfdefs.cpp create mode 100644 tesseract/src/classify/mfdefs.h create mode 100644 tesseract/src/classify/mfoutline.cpp create mode 100644 tesseract/src/classify/mfoutline.h create mode 100644 tesseract/src/classify/mfx.cpp create mode 100644 tesseract/src/classify/mfx.h create mode 100644 tesseract/src/classify/normfeat.cpp create mode 100644 tesseract/src/classify/normfeat.h create mode 100644 tesseract/src/classify/normmatch.cpp create mode 100644 tesseract/src/classify/normmatch.h create mode 100644 tesseract/src/classify/ocrfeatures.cpp create mode 100644 tesseract/src/classify/ocrfeatures.h create mode 100644 tesseract/src/classify/outfeat.cpp create mode 100644 tesseract/src/classify/outfeat.h create mode 100644 tesseract/src/classify/picofeat.cpp create mode 100644 tesseract/src/classify/picofeat.h create mode 100644 tesseract/src/classify/protos.cpp create mode 100644 tesseract/src/classify/protos.h create mode 100644 tesseract/src/classify/shapeclassifier.cpp create mode 100644 tesseract/src/classify/shapeclassifier.h create mode 100644 tesseract/src/classify/shapetable.cpp create mode 100644 tesseract/src/classify/shapetable.h create mode 100644 tesseract/src/classify/tessclassifier.cpp create mode 100644 tesseract/src/classify/tessclassifier.h create mode 100644 tesseract/src/classify/trainingsample.cpp create mode 100644 tesseract/src/classify/trainingsample.h create mode 100644 tesseract/src/cutil/bitvec.h create mode 100644 tesseract/src/cutil/oldlist.cpp create mode 100644 tesseract/src/cutil/oldlist.h create mode 100644 tesseract/src/dict/context.cpp create mode 100644 tesseract/src/dict/dawg.cpp create mode 100644 tesseract/src/dict/dawg.h create mode 100644 tesseract/src/dict/dawg_cache.cpp create mode 100644 tesseract/src/dict/dawg_cache.h create mode 100644 tesseract/src/dict/dict.cpp create mode 100644 tesseract/src/dict/dict.h create mode 100644 tesseract/src/dict/hyphen.cpp create mode 100644 tesseract/src/dict/matchdefs.h create mode 100644 tesseract/src/dict/permdawg.cpp create mode 100644 tesseract/src/dict/stopper.cpp create mode 100644 tesseract/src/dict/stopper.h create mode 100644 tesseract/src/dict/trie.cpp create mode 100644 tesseract/src/dict/trie.h create mode 100644 tesseract/src/lstm/convolve.cpp create mode 100644 tesseract/src/lstm/convolve.h create mode 100644 tesseract/src/lstm/fullyconnected.cpp create mode 100644 tesseract/src/lstm/fullyconnected.h create mode 100644 tesseract/src/lstm/functions.cpp create mode 100644 tesseract/src/lstm/functions.h create mode 100755 tesseract/src/lstm/generate_lut.py create mode 100644 tesseract/src/lstm/input.cpp create mode 100644 tesseract/src/lstm/input.h create mode 100644 tesseract/src/lstm/lstm.cpp create mode 100644 tesseract/src/lstm/lstm.h create mode 100644 tesseract/src/lstm/lstmrecognizer.cpp create mode 100644 tesseract/src/lstm/lstmrecognizer.h create mode 100644 tesseract/src/lstm/maxpool.cpp create mode 100644 tesseract/src/lstm/maxpool.h create mode 100644 tesseract/src/lstm/network.cpp create mode 100644 tesseract/src/lstm/network.h create mode 100644 tesseract/src/lstm/networkio.cpp create mode 100644 tesseract/src/lstm/networkio.h create mode 100644 tesseract/src/lstm/networkscratch.h create mode 100644 tesseract/src/lstm/parallel.cpp create mode 100644 tesseract/src/lstm/parallel.h create mode 100644 tesseract/src/lstm/plumbing.cpp create mode 100644 tesseract/src/lstm/plumbing.h create mode 100644 tesseract/src/lstm/recodebeam.cpp create mode 100644 tesseract/src/lstm/recodebeam.h create mode 100644 tesseract/src/lstm/reconfig.cpp create mode 100644 tesseract/src/lstm/reconfig.h create mode 100644 tesseract/src/lstm/reversed.cpp create mode 100644 tesseract/src/lstm/reversed.h create mode 100644 tesseract/src/lstm/series.cpp create mode 100644 tesseract/src/lstm/series.h create mode 100644 tesseract/src/lstm/static_shape.h create mode 100644 tesseract/src/lstm/stridemap.cpp create mode 100644 tesseract/src/lstm/stridemap.h create mode 100644 tesseract/src/lstm/tfnetwork.cpp create mode 100644 tesseract/src/lstm/tfnetwork.h create mode 100644 tesseract/src/lstm/tfnetwork.pb.cc create mode 100644 tesseract/src/lstm/tfnetwork.pb.h create mode 100644 tesseract/src/lstm/tfnetwork.proto create mode 100644 tesseract/src/lstm/weightmatrix.cpp create mode 100644 tesseract/src/lstm/weightmatrix.h create mode 100644 tesseract/src/opencl/oclkernels.h create mode 100644 tesseract/src/opencl/openclwrapper.cpp create mode 100644 tesseract/src/opencl/openclwrapper.h create mode 100644 tesseract/src/textord/alignedblob.cpp create mode 100644 tesseract/src/textord/alignedblob.h create mode 100644 tesseract/src/textord/baselinedetect.cpp create mode 100644 tesseract/src/textord/baselinedetect.h create mode 100644 tesseract/src/textord/bbgrid.cpp create mode 100644 tesseract/src/textord/bbgrid.h create mode 100644 tesseract/src/textord/blkocc.cpp create mode 100644 tesseract/src/textord/blkocc.h create mode 100644 tesseract/src/textord/blobgrid.cpp create mode 100644 tesseract/src/textord/blobgrid.h create mode 100644 tesseract/src/textord/ccnontextdetect.cpp create mode 100644 tesseract/src/textord/ccnontextdetect.h create mode 100644 tesseract/src/textord/cjkpitch.cpp create mode 100644 tesseract/src/textord/cjkpitch.h create mode 100644 tesseract/src/textord/colfind.cpp create mode 100644 tesseract/src/textord/colfind.h create mode 100644 tesseract/src/textord/colpartition.cpp create mode 100644 tesseract/src/textord/colpartition.h create mode 100644 tesseract/src/textord/colpartitiongrid.cpp create mode 100644 tesseract/src/textord/colpartitiongrid.h create mode 100644 tesseract/src/textord/colpartitionset.cpp create mode 100644 tesseract/src/textord/colpartitionset.h create mode 100644 tesseract/src/textord/devanagari_processing.cpp create mode 100644 tesseract/src/textord/devanagari_processing.h create mode 100644 tesseract/src/textord/drawtord.cpp create mode 100644 tesseract/src/textord/drawtord.h create mode 100644 tesseract/src/textord/edgblob.cpp create mode 100644 tesseract/src/textord/edgblob.h create mode 100644 tesseract/src/textord/edgloop.cpp create mode 100644 tesseract/src/textord/edgloop.h create mode 100644 tesseract/src/textord/equationdetectbase.cpp create mode 100644 tesseract/src/textord/equationdetectbase.h create mode 100644 tesseract/src/textord/fpchop.cpp create mode 100644 tesseract/src/textord/fpchop.h create mode 100644 tesseract/src/textord/gap_map.cpp create mode 100644 tesseract/src/textord/gap_map.h create mode 100644 tesseract/src/textord/imagefind.cpp create mode 100644 tesseract/src/textord/imagefind.h create mode 100644 tesseract/src/textord/linefind.cpp create mode 100644 tesseract/src/textord/linefind.h create mode 100644 tesseract/src/textord/makerow.cpp create mode 100644 tesseract/src/textord/makerow.h create mode 100644 tesseract/src/textord/oldbasel.cpp create mode 100644 tesseract/src/textord/oldbasel.h create mode 100644 tesseract/src/textord/pithsync.cpp create mode 100644 tesseract/src/textord/pithsync.h create mode 100644 tesseract/src/textord/pitsync1.cpp create mode 100644 tesseract/src/textord/pitsync1.h create mode 100644 tesseract/src/textord/scanedg.cpp create mode 100644 tesseract/src/textord/scanedg.h create mode 100644 tesseract/src/textord/sortflts.cpp create mode 100644 tesseract/src/textord/sortflts.h create mode 100644 tesseract/src/textord/strokewidth.cpp create mode 100644 tesseract/src/textord/strokewidth.h create mode 100644 tesseract/src/textord/tabfind.cpp create mode 100644 tesseract/src/textord/tabfind.h create mode 100644 tesseract/src/textord/tablefind.cpp create mode 100644 tesseract/src/textord/tablefind.h create mode 100644 tesseract/src/textord/tablerecog.cpp create mode 100644 tesseract/src/textord/tablerecog.h create mode 100644 tesseract/src/textord/tabvector.cpp create mode 100644 tesseract/src/textord/tabvector.h create mode 100644 tesseract/src/textord/textlineprojection.cpp create mode 100644 tesseract/src/textord/textlineprojection.h create mode 100644 tesseract/src/textord/textord.cpp create mode 100644 tesseract/src/textord/textord.h create mode 100644 tesseract/src/textord/topitch.cpp create mode 100644 tesseract/src/textord/topitch.h create mode 100644 tesseract/src/textord/tordmain.cpp create mode 100644 tesseract/src/textord/tordmain.h create mode 100644 tesseract/src/textord/tospace.cpp create mode 100644 tesseract/src/textord/tovars.cpp create mode 100644 tesseract/src/textord/tovars.h create mode 100644 tesseract/src/textord/underlin.cpp create mode 100644 tesseract/src/textord/underlin.h create mode 100644 tesseract/src/textord/wordseg.cpp create mode 100644 tesseract/src/textord/wordseg.h create mode 100644 tesseract/src/textord/workingpartset.cpp create mode 100644 tesseract/src/textord/workingpartset.h create mode 100644 tesseract/src/training/CMakeLists.txt create mode 100644 tesseract/src/training/ambiguous_words.cpp create mode 100644 tesseract/src/training/classifier_tester.cpp create mode 100644 tesseract/src/training/cntraining.cpp create mode 100644 tesseract/src/training/combine_lang_model.cpp create mode 100644 tesseract/src/training/combine_tessdata.cpp create mode 100644 tesseract/src/training/common/commandlineflags.cpp create mode 100644 tesseract/src/training/common/commandlineflags.h create mode 100644 tesseract/src/training/common/commontraining.cpp create mode 100644 tesseract/src/training/common/commontraining.h create mode 100644 tesseract/src/training/common/ctc.cpp create mode 100644 tesseract/src/training/common/ctc.h create mode 100644 tesseract/src/training/common/errorcounter.cpp create mode 100644 tesseract/src/training/common/errorcounter.h create mode 100644 tesseract/src/training/common/export.h create mode 100644 tesseract/src/training/common/intfeaturedist.cpp create mode 100644 tesseract/src/training/common/intfeaturedist.h create mode 100644 tesseract/src/training/common/intfeaturemap.cpp create mode 100644 tesseract/src/training/common/intfeaturemap.h create mode 100644 tesseract/src/training/common/mastertrainer.cpp create mode 100644 tesseract/src/training/common/mastertrainer.h create mode 100644 tesseract/src/training/common/networkbuilder.cpp create mode 100644 tesseract/src/training/common/networkbuilder.h create mode 100644 tesseract/src/training/common/sampleiterator.cpp create mode 100644 tesseract/src/training/common/sampleiterator.h create mode 100644 tesseract/src/training/common/trainingsampleset.cpp create mode 100644 tesseract/src/training/common/trainingsampleset.h create mode 100644 tesseract/src/training/dawg2wordlist.cpp create mode 100644 tesseract/src/training/degradeimage.cpp create mode 100644 tesseract/src/training/degradeimage.h create mode 100755 tesseract/src/training/language-specific.sh create mode 100644 tesseract/src/training/language_specific.py create mode 100644 tesseract/src/training/lstmeval.cpp create mode 100644 tesseract/src/training/lstmtraining.cpp create mode 100644 tesseract/src/training/merge_unicharsets.cpp create mode 100644 tesseract/src/training/mergenf.cpp create mode 100644 tesseract/src/training/mergenf.h create mode 100644 tesseract/src/training/mftraining.cpp create mode 100644 tesseract/src/training/pango/boxchar.cpp create mode 100644 tesseract/src/training/pango/boxchar.h create mode 100644 tesseract/src/training/pango/export.h create mode 100644 tesseract/src/training/pango/ligature_table.cpp create mode 100644 tesseract/src/training/pango/ligature_table.h create mode 100644 tesseract/src/training/pango/pango_font_info.cpp create mode 100644 tesseract/src/training/pango/pango_font_info.h create mode 100644 tesseract/src/training/pango/stringrenderer.cpp create mode 100644 tesseract/src/training/pango/stringrenderer.h create mode 100644 tesseract/src/training/pango/tlog.cpp create mode 100644 tesseract/src/training/pango/tlog.h create mode 100644 tesseract/src/training/set_unicharset_properties.cpp create mode 100644 tesseract/src/training/shapeclustering.cpp create mode 100755 tesseract/src/training/tesstrain.py create mode 100755 tesseract/src/training/tesstrain.sh create mode 100644 tesseract/src/training/tesstrain_utils.py create mode 100644 tesseract/src/training/tesstrain_utils.sh create mode 100644 tesseract/src/training/text2image.cpp create mode 100644 tesseract/src/training/unicharset/export.h create mode 100644 tesseract/src/training/unicharset/fileio.cpp create mode 100644 tesseract/src/training/unicharset/fileio.h create mode 100644 tesseract/src/training/unicharset/icuerrorcode.cpp create mode 100644 tesseract/src/training/unicharset/icuerrorcode.h create mode 100644 tesseract/src/training/unicharset/lang_model_helpers.cpp create mode 100644 tesseract/src/training/unicharset/lang_model_helpers.h create mode 100644 tesseract/src/training/unicharset/lstmtester.cpp create mode 100644 tesseract/src/training/unicharset/lstmtester.h create mode 100644 tesseract/src/training/unicharset/lstmtrainer.cpp create mode 100644 tesseract/src/training/unicharset/lstmtrainer.h create mode 100644 tesseract/src/training/unicharset/normstrngs.cpp create mode 100644 tesseract/src/training/unicharset/normstrngs.h create mode 100644 tesseract/src/training/unicharset/unicharset_training_utils.cpp create mode 100644 tesseract/src/training/unicharset/unicharset_training_utils.h create mode 100644 tesseract/src/training/unicharset/validate_grapheme.cpp create mode 100644 tesseract/src/training/unicharset/validate_grapheme.h create mode 100644 tesseract/src/training/unicharset/validate_indic.cpp create mode 100644 tesseract/src/training/unicharset/validate_indic.h create mode 100644 tesseract/src/training/unicharset/validate_javanese.cpp create mode 100644 tesseract/src/training/unicharset/validate_javanese.h create mode 100644 tesseract/src/training/unicharset/validate_khmer.cpp create mode 100644 tesseract/src/training/unicharset/validate_khmer.h create mode 100644 tesseract/src/training/unicharset/validate_myanmar.cpp create mode 100644 tesseract/src/training/unicharset/validate_myanmar.h create mode 100644 tesseract/src/training/unicharset/validator.cpp create mode 100644 tesseract/src/training/unicharset/validator.h create mode 100644 tesseract/src/training/unicharset_extractor.cpp create mode 100644 tesseract/src/training/wordlist2dawg.cpp create mode 100644 tesseract/src/viewer/scrollview.cpp create mode 100644 tesseract/src/viewer/scrollview.h create mode 100644 tesseract/src/viewer/svmnode.cpp create mode 100644 tesseract/src/viewer/svmnode.h create mode 100644 tesseract/src/viewer/svpaint.cpp create mode 100644 tesseract/src/viewer/svutil.cpp create mode 100644 tesseract/src/viewer/svutil.h create mode 100644 tesseract/src/wordrec/associate.cpp create mode 100644 tesseract/src/wordrec/associate.h create mode 100644 tesseract/src/wordrec/chop.cpp create mode 100644 tesseract/src/wordrec/chop.h create mode 100644 tesseract/src/wordrec/chopper.cpp create mode 100644 tesseract/src/wordrec/drawfx.cpp create mode 100644 tesseract/src/wordrec/drawfx.h create mode 100644 tesseract/src/wordrec/findseam.cpp create mode 100644 tesseract/src/wordrec/findseam.h create mode 100644 tesseract/src/wordrec/gradechop.cpp create mode 100644 tesseract/src/wordrec/language_model.cpp create mode 100644 tesseract/src/wordrec/language_model.h create mode 100644 tesseract/src/wordrec/lm_consistency.cpp create mode 100644 tesseract/src/wordrec/lm_consistency.h create mode 100644 tesseract/src/wordrec/lm_pain_points.cpp create mode 100644 tesseract/src/wordrec/lm_pain_points.h create mode 100644 tesseract/src/wordrec/lm_state.cpp create mode 100644 tesseract/src/wordrec/lm_state.h create mode 100644 tesseract/src/wordrec/measure.h create mode 100644 tesseract/src/wordrec/outlines.cpp create mode 100644 tesseract/src/wordrec/outlines.h create mode 100644 tesseract/src/wordrec/params_model.cpp create mode 100644 tesseract/src/wordrec/params_model.h create mode 100644 tesseract/src/wordrec/pieces.cpp create mode 100644 tesseract/src/wordrec/plotedges.cpp create mode 100644 tesseract/src/wordrec/plotedges.h create mode 100644 tesseract/src/wordrec/render.cpp create mode 100644 tesseract/src/wordrec/render.h create mode 100644 tesseract/src/wordrec/segsearch.cpp create mode 100644 tesseract/src/wordrec/tface.cpp create mode 100644 tesseract/src/wordrec/wordclass.cpp create mode 100644 tesseract/src/wordrec/wordrec.cpp create mode 100644 tesseract/src/wordrec/wordrec.h create mode 100644 tesseract/sw.cpp create mode 100644 tesseract/tessdata/Makefile.am create mode 100644 tesseract/tessdata/configs/Makefile.am create mode 100644 tesseract/tessdata/configs/alto create mode 100644 tesseract/tessdata/configs/ambigs.train create mode 100644 tesseract/tessdata/configs/api_config create mode 100644 tesseract/tessdata/configs/bazaar create mode 100644 tesseract/tessdata/configs/bigram create mode 100644 tesseract/tessdata/configs/box.train create mode 100644 tesseract/tessdata/configs/box.train.stderr create mode 100644 tesseract/tessdata/configs/digits create mode 100644 tesseract/tessdata/configs/get.images create mode 100644 tesseract/tessdata/configs/hocr create mode 100644 tesseract/tessdata/configs/inter create mode 100644 tesseract/tessdata/configs/kannada create mode 100644 tesseract/tessdata/configs/linebox create mode 100644 tesseract/tessdata/configs/logfile create mode 100644 tesseract/tessdata/configs/lstm.train create mode 100644 tesseract/tessdata/configs/lstmbox create mode 100644 tesseract/tessdata/configs/lstmdebug create mode 100644 tesseract/tessdata/configs/makebox create mode 100644 tesseract/tessdata/configs/pdf create mode 100644 tesseract/tessdata/configs/quiet create mode 100644 tesseract/tessdata/configs/rebox create mode 100644 tesseract/tessdata/configs/strokewidth create mode 100644 tesseract/tessdata/configs/tsv create mode 100644 tesseract/tessdata/configs/txt create mode 100644 tesseract/tessdata/configs/unlv create mode 100644 tesseract/tessdata/configs/wordstrbox create mode 100644 tesseract/tessdata/eng.user-patterns create mode 100644 tesseract/tessdata/eng.user-words create mode 100644 tesseract/tessdata/pdf.ttf create mode 100644 tesseract/tessdata/tessconfigs/Makefile.am create mode 100644 tesseract/tessdata/tessconfigs/batch create mode 100644 tesseract/tessdata/tessconfigs/batch.nochop create mode 100644 tesseract/tessdata/tessconfigs/matdemo create mode 100644 tesseract/tessdata/tessconfigs/msdemo create mode 100644 tesseract/tessdata/tessconfigs/nobatch create mode 100644 tesseract/tessdata/tessconfigs/segdemo create mode 100644 tesseract/tesseract.pc.cmake create mode 100644 tesseract/tesseract.pc.in create mode 100644 tesseract/unittest/README.md create mode 100644 tesseract/unittest/apiexample_test.cc create mode 100644 tesseract/unittest/applybox_test.cc create mode 100644 tesseract/unittest/baseapi_test.cc create mode 100644 tesseract/unittest/baseapi_thread_test.cc create mode 100644 tesseract/unittest/bitvector_test.cc create mode 100644 tesseract/unittest/capiexample_c_test.c create mode 100644 tesseract/unittest/capiexample_test.cc create mode 100644 tesseract/unittest/cleanapi_test.cc create mode 100644 tesseract/unittest/colpartition_test.cc create mode 100644 tesseract/unittest/commandlineflags_test.cc create mode 100644 tesseract/unittest/cycletimer.h create mode 100644 tesseract/unittest/dawg_test.cc create mode 100644 tesseract/unittest/denorm_test.cc create mode 100644 tesseract/unittest/doubleptr.h create mode 100644 tesseract/unittest/equationdetect_test.cc create mode 100644 tesseract/unittest/fileio_test.cc create mode 100644 tesseract/unittest/fuzzers/fuzzer-api.cpp create mode 100755 tesseract/unittest/fuzzers/oss-fuzz-build.sh create mode 100644 tesseract/unittest/heap_test.cc create mode 100644 tesseract/unittest/imagedata_test.cc create mode 100644 tesseract/unittest/include_gunit.h create mode 100644 tesseract/unittest/indexmapbidi_test.cc create mode 100644 tesseract/unittest/intfeaturemap_test.cc create mode 100644 tesseract/unittest/intsimdmatrix_test.cc create mode 100644 tesseract/unittest/lang_model_test.cc create mode 100644 tesseract/unittest/layout_test.cc create mode 100644 tesseract/unittest/ligature_table_test.cc create mode 100644 tesseract/unittest/linlsq_test.cc create mode 100644 tesseract/unittest/list_test.cc create mode 100644 tesseract/unittest/loadlang_test.cc create mode 100644 tesseract/unittest/log.h create mode 100644 tesseract/unittest/lstm_recode_test.cc create mode 100644 tesseract/unittest/lstm_squashed_test.cc create mode 100644 tesseract/unittest/lstm_test.cc create mode 100644 tesseract/unittest/lstm_test.h create mode 100644 tesseract/unittest/lstmtrainer_test.cc create mode 100644 tesseract/unittest/mastertrainer_test.cc create mode 100644 tesseract/unittest/matrix_test.cc create mode 100644 tesseract/unittest/networkio_test.cc create mode 100644 tesseract/unittest/normstrngs_test.cc create mode 100644 tesseract/unittest/normstrngs_test.h create mode 100644 tesseract/unittest/nthitem_test.cc create mode 100644 tesseract/unittest/osd_test.cc create mode 100644 tesseract/unittest/pagesegmode_test.cc create mode 100644 tesseract/unittest/pango_font_info_test.cc create mode 100644 tesseract/unittest/paragraphs_test.cc create mode 100644 tesseract/unittest/params_model_test.cc create mode 100644 tesseract/unittest/progress_test.cc create mode 100644 tesseract/unittest/qrsequence_test.cc create mode 100644 tesseract/unittest/recodebeam_test.cc create mode 100644 tesseract/unittest/rect_test.cc create mode 100644 tesseract/unittest/resultiterator_test.cc create mode 100644 tesseract/unittest/scanutils_test.cc create mode 100644 tesseract/unittest/shapetable_test.cc create mode 100644 tesseract/unittest/stats_test.cc create mode 100644 tesseract/unittest/stridemap_test.cc create mode 100644 tesseract/unittest/stringrenderer_test.cc create mode 100644 tesseract/unittest/syntaxnet/base.h create mode 100644 tesseract/unittest/tablefind_test.cc create mode 100644 tesseract/unittest/tablerecog_test.cc create mode 100644 tesseract/unittest/tabvector_test.cc create mode 100644 tesseract/unittest/tatweel_test.cc create mode 100644 tesseract/unittest/tesseract_leaksanitizer.supp create mode 100644 tesseract/unittest/textlineprojection_test.cc create mode 100644 tesseract/unittest/tfile_test.cc create mode 100644 tesseract/unittest/third_party/utf/rune.c create mode 100644 tesseract/unittest/third_party/utf/utf.h create mode 100644 tesseract/unittest/third_party/utf/utfdef.h create mode 100644 tesseract/unittest/unichar_test.cc create mode 100644 tesseract/unittest/unicharcompress_test.cc create mode 100644 tesseract/unittest/unicharset_test.cc create mode 100644 tesseract/unittest/util/utf8/unicodetext.cc create mode 100644 tesseract/unittest/util/utf8/unicodetext.h create mode 100644 tesseract/unittest/util/utf8/unilib.cc create mode 100644 tesseract/unittest/util/utf8/unilib.h create mode 100644 tesseract/unittest/util/utf8/unilib_utf8_utils.h create mode 100644 tesseract/unittest/validate_grapheme_test.cc create mode 100644 tesseract/unittest/validate_indic_test.cc create mode 100644 tesseract/unittest/validate_khmer_test.cc create mode 100644 tesseract/unittest/validate_myanmar_test.cc create mode 100644 tesseract/unittest/validator_test.cc create mode 100644 tiff/html/v4.2.0.html create mode 100644 tiff/test/custom_dir_EXIF_231.c create mode 100644 tiff/test/images/deflate-last-strip-extra-data.tiff create mode 100644 tiff/test/images/ojpeg_chewey_subsamp21_multi_strip.tiff create mode 100644 tiff/test/images/ojpeg_single_strip_no_rowsperstrip.tiff create mode 100644 tiff/test/images/ojpeg_zackthecat_subsamp22_single_strip.tiff create mode 100644 tiff/test/images/rgb-3c-16b.ppm create mode 100644 tiff/test/images/testfax4.tiff create mode 100644 tiff/test/rational_precision2double.c create mode 100644 tiff/test/refs/o-deflate-last-strip-extra-data.tiff create mode 100644 tiff/test/refs/o-testfax4.tiff create mode 100755 tiff/test/testdeflatelaststripextradata.sh create mode 100755 tiff/test/testfax4.sh create mode 100755 tiff/test/tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh create mode 100755 tiff/test/tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh create mode 100755 tiff/test/tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.sh delete mode 100644 toolbin/halftone/ETS/win32/ETS.vcproj create mode 100644 toolbin/halftone/ETS/win32/ETS.vcxproj create mode 100644 toolbin/halftone/ETS/win32/ETS.vcxproj.filters create mode 100644 windows/ghostpcl-ufst.vcproj diff --git a/Makefile.in b/Makefile.in index 8fc446d6..5a647990 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -117,6 +117,11 @@ COMPILE_INITS=@COMPILE_INITS@ GS_LIB_DEFAULT=$(gsdatadir)/Resource/Init:$(gsdatadir)/lib:$(gsdatadir)/Resource/Font:$(gsdir)/fonts:@fontpath@ +# Define the default search path for Tesseract. Separate multiple directories +# with a :. + +TESSDATA=@tessdata@ + # Define the default directory for cached data files # this must be a single path. @@ -223,6 +228,9 @@ CAL_SSE4_2_CFLAGS=@CAL_SSE4_2_CFLAGS@ CAL_AVX2_CFLAGS=@CAL_AVX2_CFLAGS@ CAL_NEON_CFLAGS=@CAL_NEON_CFLAGS@ +# Location of extract library (can be empty). +EXTRACT_DIR=@EXTRACT_DIR@ + # Define whether to compile in the FreeType library, and if so, where # the source tree is location. Otherwise, what library name to use # in linking to a shared implementation. @@ -232,6 +240,7 @@ SHARE_FT=@SHARE_FT@ FTSRCDIR=@FTSRCDIR@ FT_CFLAGS=@FT_CFLAGS@ -DSHARE_FT=@SHARE_FT@ FT_LIBS=@FT_LIBS@ +FT_LIB_PATH=@FT_LIB_PATH@ FT_CONFIG_SYSTEM_ZLIB=@FT_SYS_ZLIB@ # Define whether to compile in UFST. @@ -304,15 +313,6 @@ SHARE_JBIG2=@SHARE_JBIG2@ JBIG2SRCDIR=@JBIG2DIR@ JBIG2_CFLAGS=@JBIG2_AUTOCONF_CFLAGS@ -# uncomment the following three lines and one of the last two to -# compile in the Luratech ldf_jb2 codec -#JBIG2_LIB=luratech -#SHARE_JBIG2=0 -#JBIG2SRCDIR=ldf_jb2 -#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DLINUX -#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD - - # Choose the library to use for (JPXDecode support) # whether to link to an external build or compile in from source # and source location and configuration flags for compiling in @@ -321,20 +321,6 @@ SHARE_JPX=@SHARE_JPX@ JPXSRCDIR=@JPXDIR@ JPX_CFLAGS=-DSHARE_JPX=$(SHARE_JPX) @JPX_AUTOCONF_CFLAGS@ @JPX_SSE_CFLAGS@ -# uncomment the following three lines and one of the last two to -# compile in the Luratech lwf_jp2 codec -#JPX_LIB=luratech -#SHARE_JPX=0 -#JPXSRCDIR=lwf_jp2 -#JPX_CFLAGS=-DUSE_LWF_JP2 -DLINUX -#JPX_CFLAGS=-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD - -# Uncomment the following 4 lines to to compile in OpenJPEG codec -#JPX_LIB=openjpeg -#SHARE_JPX=0 -#JPXSRCDIR=openjpeg -#JPX_CFLAGS=-DUSE_OPENJPEG_JP2 -DOPJ_STATIC - # options for lcms color management library SHARE_LCMS=@SHARELCMS@ LCMS2SRCDIR=@LCMS2DIR@ @@ -729,6 +715,8 @@ TESSSSE41=@TESS_SSE4_1@ TESSNEON=@TESS_NEON@ TESSCXXFLAGS=@TESS_CXXFLAGS@ TESSERACTDIR=@TESSERACTDIR@ +# Since C++ is only used for tesseract, set the compiler here +CXX=@CXX@ # ---------------- End of platform-specific section ---------------- # @@ -750,18 +738,17 @@ include @PXL_MAK@ # pxl.mak include @XPS_MAK@ # xps.mak +include $(GLSRCDIR)/jpeg.mak + include @GPDL_MAK@ # gpdl.mak include $(GLSRCDIR)/freetype.mak include @FAPIUFST_MAK@ -include $(GLSRCDIR)/jpeg.mak # zlib.mak must precede png.mak include $(GLSRCDIR)/zlib.mak include $(GLSRCDIR)/png.mak include $(GLSRCDIR)/tiff.mak include $(GLSRCDIR)/jbig2.mak -include $(GLSRCDIR)/ldf_jb2.mak -include $(GLSRCDIR)/lwf_jp2.mak include $(GLSRCDIR)/openjpeg.mak include $(GLSRCDIR)/cal.mak @LEPTONICAINCLUDE@ @@ -771,6 +758,8 @@ include $(GLSRCDIR)/ocr.mak include $(GLSRCDIR)/jpegxr.mak include $(GLSRCDIR)/expat.mak +include $(DEVSRCDIR)/extract.mak + include $(GLSRCDIR)/$(WHICH_CMS).mak include $(GLSRCDIR)/ijs.mak @LCUPSINCLUDE@ diff --git a/Resource/CIDFont/ArtifexBullet b/Resource/CIDFont/ArtifexBullet index 18c98f16..268d518f 100644 Binary files a/Resource/CIDFont/ArtifexBullet and b/Resource/CIDFont/ArtifexBullet differ diff --git a/Resource/CMap/Identity-UTF16-H b/Resource/CMap/Identity-UTF16-H index a47413aa..5c1c3eac 100644 --- a/Resource/CMap/Identity-UTF16-H +++ b/Resource/CMap/Identity-UTF16-H @@ -1,4 +1,4 @@ -% Copyright (C) 2003-2018 Artifex Software. All rights reserved. +% Copyright (C) 2003-2021 Artifex Software. All rights reserved. % % This software is provided AS-IS with no warranty, either express or % implied. diff --git a/Resource/ColorSpace/DefaultCMYK b/Resource/ColorSpace/DefaultCMYK index cba9326c..f3d71823 100644 --- a/Resource/ColorSpace/DefaultCMYK +++ b/Resource/ColorSpace/DefaultCMYK @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/ColorSpace/DefaultGray b/Resource/ColorSpace/DefaultGray index 95c9ef41..21a72fd6 100644 --- a/Resource/ColorSpace/DefaultGray +++ b/Resource/ColorSpace/DefaultGray @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/ColorSpace/DefaultRGB b/Resource/ColorSpace/DefaultRGB index 53ddf3ea..d715587b 100644 --- a/Resource/ColorSpace/DefaultRGB +++ b/Resource/ColorSpace/DefaultRGB @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/ColorSpace/TrivialCMYK b/Resource/ColorSpace/TrivialCMYK index b3dec8b8..66776bcd 100644 --- a/Resource/ColorSpace/TrivialCMYK +++ b/Resource/ColorSpace/TrivialCMYK @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/ColorSpace/sGray b/Resource/ColorSpace/sGray index a0997d0b..501ed376 100644 --- a/Resource/ColorSpace/sGray +++ b/Resource/ColorSpace/sGray @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/ColorSpace/sRGB b/Resource/ColorSpace/sRGB index 16f3ecfa..0aadbc01 100644 --- a/Resource/ColorSpace/sRGB +++ b/Resource/ColorSpace/sRGB @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Decoding/FCO_Dingbats b/Resource/Decoding/FCO_Dingbats index 8da04509..76cd6d1a 100644 --- a/Resource/Decoding/FCO_Dingbats +++ b/Resource/Decoding/FCO_Dingbats @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Decoding/FCO_Symbol b/Resource/Decoding/FCO_Symbol index c9411a03..4c2dcecb 100644 --- a/Resource/Decoding/FCO_Symbol +++ b/Resource/Decoding/FCO_Symbol @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Decoding/FCO_Unicode b/Resource/Decoding/FCO_Unicode index 4cdf58a5..acc8e022 100644 --- a/Resource/Decoding/FCO_Unicode +++ b/Resource/Decoding/FCO_Unicode @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Decoding/FCO_Wingdings b/Resource/Decoding/FCO_Wingdings index a31cefd8..2eaca0df 100644 --- a/Resource/Decoding/FCO_Wingdings +++ b/Resource/Decoding/FCO_Wingdings @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Decoding/Latin1 b/Resource/Decoding/Latin1 index 8960ab4f..b9dff0f3 100644 --- a/Resource/Decoding/Latin1 +++ b/Resource/Decoding/Latin1 @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Decoding/StandardEncoding b/Resource/Decoding/StandardEncoding index f2b27a56..5ac6d63c 100644 --- a/Resource/Decoding/StandardEncoding +++ b/Resource/Decoding/StandardEncoding @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Decoding/Unicode b/Resource/Decoding/Unicode index 7ecd3069..dfc137d9 100644 --- a/Resource/Decoding/Unicode +++ b/Resource/Decoding/Unicode @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Encoding/CEEncoding b/Resource/Encoding/CEEncoding index bd3f8abb..b2d7e574 100644 --- a/Resource/Encoding/CEEncoding +++ b/Resource/Encoding/CEEncoding @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Encoding/ExpertEncoding b/Resource/Encoding/ExpertEncoding index fe879bda..97b33213 100644 --- a/Resource/Encoding/ExpertEncoding +++ b/Resource/Encoding/ExpertEncoding @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Encoding/ExpertSubsetEncoding b/Resource/Encoding/ExpertSubsetEncoding index 6f789bc5..6177adb0 100644 --- a/Resource/Encoding/ExpertSubsetEncoding +++ b/Resource/Encoding/ExpertSubsetEncoding @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Encoding/NotDefEncoding b/Resource/Encoding/NotDefEncoding index a5e0b8d3..0c810e48 100644 --- a/Resource/Encoding/NotDefEncoding +++ b/Resource/Encoding/NotDefEncoding @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Encoding/Wingdings b/Resource/Encoding/Wingdings index 4a245571..efb7d3fa 100644 --- a/Resource/Encoding/Wingdings +++ b/Resource/Encoding/Wingdings @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/IdiomSet/PPI_CUtils b/Resource/IdiomSet/PPI_CUtils new file mode 100644 index 00000000..7e6ecb23 --- /dev/null +++ b/Resource/IdiomSet/PPI_CUtils @@ -0,0 +1,24 @@ +%% +%% Idioms for the PPI Media GmbH PPI_ColorUtils ProcSet +%% This appears to be a kind of desktop colour separation utility. If it is +%% used with the pdfwrite PassThroughJPEGImages feature then instead of +%% converting images from colour to gray, we embed the colour image data +%% but with a DeviceGray colour space, which leads to incorrect output. +%% To fix that, turn off the feature if cuForceGray is set to true. This +%% is the first time we've seen this, and more work may be required. +%% + +currentuserparams /IdiomRecognition get +<> setuserparams + +/PPI_CUtils +<< +/cuForceGray [ +{/_cuForceGray exch cuPut} bind +{dup //true eq {currentdevice //null //false mark /PassThroughJPEGImages //false .putdeviceparamsonly}if /_cuForceGray exch cuPut} bind +] +>> + +/IdiomSet defineresource pop + +<> setuserparams diff --git a/Resource/Init/FCOfontmap-PCLPS2 b/Resource/Init/FCOfontmap-PCLPS2 index 91bd8f7f..e51db629 100644 --- a/Resource/Init/FCOfontmap-PCLPS2 +++ b/Resource/Init/FCOfontmap-PCLPS2 @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/Fontmap.GS b/Resource/Init/Fontmap.GS index 5f47b6b4..b6fce711 100644 --- a/Resource/Init/Fontmap.GS +++ b/Resource/Init/Fontmap.GS @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_agl.ps b/Resource/Init/gs_agl.ps index 9c1c52d2..ce5ea1ce 100644 --- a/Resource/Init/gs_agl.ps +++ b/Resource/Init/gs_agl.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_btokn.ps b/Resource/Init/gs_btokn.ps index 410b8419..1f63fb5c 100644 --- a/Resource/Init/gs_btokn.ps +++ b/Resource/Init/gs_btokn.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_cff.ps b/Resource/Init/gs_cff.ps index 6cfa1ec1..43cf7d01 100644 --- a/Resource/Init/gs_cff.ps +++ b/Resource/Init/gs_cff.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_cidcm.ps b/Resource/Init/gs_cidcm.ps index 503ec867..1ec03b36 100644 --- a/Resource/Init/gs_cidcm.ps +++ b/Resource/Init/gs_cidcm.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_ciddc.ps b/Resource/Init/gs_ciddc.ps index 6cdba039..9e2ea1ea 100644 --- a/Resource/Init/gs_ciddc.ps +++ b/Resource/Init/gs_ciddc.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_cidfm.ps b/Resource/Init/gs_cidfm.ps index f22e45d6..1a456ab1 100644 --- a/Resource/Init/gs_cidfm.ps +++ b/Resource/Init/gs_cidfm.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_cidfn.ps b/Resource/Init/gs_cidfn.ps index 20af1c87..870a2e11 100644 --- a/Resource/Init/gs_cidfn.ps +++ b/Resource/Init/gs_cidfn.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_cidtt.ps b/Resource/Init/gs_cidtt.ps index e045cfdd..b856ba65 100644 --- a/Resource/Init/gs_cidtt.ps +++ b/Resource/Init/gs_cidtt.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_cmap.ps b/Resource/Init/gs_cmap.ps index 3252089a..0c2e1421 100644 --- a/Resource/Init/gs_cmap.ps +++ b/Resource/Init/gs_cmap.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_cspace.ps b/Resource/Init/gs_cspace.ps index 8aaf6b74..c005cef4 100644 --- a/Resource/Init/gs_cspace.ps +++ b/Resource/Init/gs_cspace.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_dbt_e.ps b/Resource/Init/gs_dbt_e.ps index 2aca0c68..89e24131 100644 --- a/Resource/Init/gs_dbt_e.ps +++ b/Resource/Init/gs_dbt_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps index 85ff07e3..825ff8d9 100644 --- a/Resource/Init/gs_diskn.ps +++ b/Resource/Init/gs_diskn.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps index 14cc5d6d..ba5b9b54 100644 --- a/Resource/Init/gs_dps1.ps +++ b/Resource/Init/gs_dps1.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_dps2.ps b/Resource/Init/gs_dps2.ps index 2dfaaa49..03206446 100644 --- a/Resource/Init/gs_dps2.ps +++ b/Resource/Init/gs_dps2.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_dscp.ps b/Resource/Init/gs_dscp.ps index 15764b17..4ea3d454 100644 --- a/Resource/Init/gs_dscp.ps +++ b/Resource/Init/gs_dscp.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_epsf.ps b/Resource/Init/gs_epsf.ps index cf020751..47b68bba 100644 --- a/Resource/Init/gs_epsf.ps +++ b/Resource/Init/gs_epsf.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -29,6 +29,7 @@ % After %%HiResBoundingBox processed, state is 3 if OK or 4 if cropped. % After %%EndComments processed, state is 5. /EPSBoundingBoxState 5 def +/EPSBoundingBoxString () def % set if either BoundingBox is seen (even if invalid) /EPSBoundingBoxSetState { //systemdict /EPSBoundingBoxState 3 -1 roll .forceput } .bind executeonly odef % .forceput must be bound and hidden @@ -60,7 +61,10 @@ /EPSBoundingBoxFitPage { % llx lly urx ury -- EPSDEBUG { (gs_epsf.ps: Rescaling EPS to fit page\n) print flush } if clippath pathbbox newpath % ellx elly eurx eury pllx plly purx pury - + EPSDEBUG { + (Page Coordinates: LLX: ) print 3 index =print (, LLY: ) print + 2 index =print (, URX: ) print 1 index =print (, URY: ) print dup = flush + } if % Convert box corners to coordinates of the center and box sizes 2 { % loop doing the page coordinates, the the EPS bbox coordinates 3 -1 roll exch % ... llx urx lly ury @@ -82,7 +86,19 @@ % Find orientation of the best fit. Square pages or files don't rotate. 2 copy sub % edx ecx edy ecy pdx pdy pdx-pdy - 6 index 5 index sub mul % edx ecx edy ecy pdx pdy (pdx-pdy)*(edx-edy) + EPSDEBUG { + (pdx: ) print 2 index =print (, pdy: ) print 1 index =print + (, pdx-pdy: ) print dup = flush + } if + 6 index 5 index sub + EPSDEBUG { + (edx: ) print 7 index =print (, edy: ) print 5 index =print + (, edx-edy: ) print dup = flush + } if + mul % edx ecx edy ecy pdx pdy (pdx-pdy)*(edx-edy) + EPSDEBUG { + (product: ) print dup = flush + } if 0 lt { 90 rotate exch @@ -100,15 +116,17 @@ } bind executeonly odef /EPSBoundingBoxProcess { % (llx lly urx ury) state -- + % The following 'lt' check prioritzies HiResBoundingBox over BoundingBox + % even if HiResBoundingBox occurs first in the EPS file. //systemdict /EPSBoundingBoxState get 1 index lt { - exch EPSBoundingBoxParse + % save the BBoxString for possible FitPage when EndComments is seen + exch dup //systemdict /EPSBoundingBoxString 3 -1 roll .forceput + EPSBoundingBoxParse { //systemdict /EPSCrop known { EPSBoundingBoxCrop } { - //systemdict /EPSFitPage known { - EPSBoundingBoxFitPage - } { + //systemdict /EPSFitPage known not { % Warn if some of the EPS file will be clipped clippath pathbbox newpath { % context for exit @@ -124,10 +142,17 @@ flush 1 add } if + } { + pop pop pop pop } ifelse } ifelse EPSBoundingBoxSetState } { + % improperly formed BoundingBox string. + QUIET not { + (\n **** Warning: BoundingBox values are invalid and will be ignored: ') print + EPSBoundBoxString print (') = flush + } if pop % state } ifelse } { @@ -135,6 +160,25 @@ } ifelse } bind executeonly odef +% Perform anchorsearch on the strings in the array until a match is found. +/anchorsearchforany { % haystack [needle1 ...] --> post needle true + % --> haystack false + false 3 1 roll % false haystack [...] + { % false haystack needle + dup 3 1 roll % false needle haystack needle + anchorsearch { + % false needle post needle + pop % false needle post + 3 1 roll % post false needle + exch not exch % post true needle + exit + } { + % false needle haystack + exch pop % false haystack + } ifelse + } forall + exch % haystack false | post needle true +} bind def /ProcessEPSComment { % file comment -- file comment /EPSBoundingBoxState .systemvar 3 lt { @@ -188,12 +232,23 @@ } ifelse } ifelse } { - (%%EndComments) anchorsearch { - pop pop + {(%%EndComments) (%%BeginProlog) (%%BeginSetup)} anchorsearchforany { + EPSDEBUG { (EPSComment processing finished, encountered: ) print dup = } if + pop pop % discard the strings from the anchorsearch + % We may have seen BoundingBox or HiResBounfingBox. If so and if EPSFitPage + % is set, then we do the transformation here to scale and center the page, + % rotating if needed (and AllowFitPageRotation is true -- the default.) + //systemdict /EPSFitPage known + //systemdict /EPSBoundingBoxState get 0 gt + and { + EPSBoundingBoxString EPSBoundingBoxParse { + EPSBoundingBoxFitPage + } if + } if % Ignore any following comments 5 EPSBoundingBoxSetState } { - pop + pop % Not %%EndComments -- ignore it } ifelse } ifelse } if @@ -310,6 +365,7 @@ end /.runnoepsf /.runEPS /EPSBoundingBoxSetState + /EPSBoundingBoxString /EPSBoundingBoxCrop /EPSBoundingBoxFitPage /EPSBoundingBoxParse diff --git a/Resource/Init/gs_fapi.ps b/Resource/Init/gs_fapi.ps index 0b493c6a..b0f74820 100644 --- a/Resource/Init/gs_fapi.ps +++ b/Resource/Init/gs_fapi.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_fntem.ps b/Resource/Init/gs_fntem.ps index d5ac0bfa..8904352d 100644 --- a/Resource/Init/gs_fntem.ps +++ b/Resource/Init/gs_fntem.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps index 3f4f4af8..f1e26b09 100644 --- a/Resource/Init/gs_fonts.ps +++ b/Resource/Init/gs_fonts.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_frsd.ps b/Resource/Init/gs_frsd.ps index 74c1dd27..80d39910 100644 --- a/Resource/Init/gs_frsd.ps +++ b/Resource/Init/gs_frsd.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -61,13 +61,29 @@ level2dict begin .currentglobal 1 index gcheck .setglobal exch currentpacking //false setpacking exch + 2 dict begin /filelen 0 def % scratch dict for filelen and pos (below). % Stack: dict filters parms CloseSource oldglobal oldpacking file - [ exch { dup 40000 string readstring not { exit } if exch } loop + [ exch { + dup 40000 string readstring + /filelen 2 index length filelen add def % accumulate filelen + not { exit } if exch + } loop exch pop ] - % Stack: dict filters parms CloseSource oldglobal oldpacking [()...] + { filelen string } stopped { % try allocating a single string + pop % couldn't make a string - discard filelen value + } { + % transfer the array-of-strings to the single string. + % stack: ... [() ...] string + /pos 0 def exch { + 1 index exch pos exch putinterval /pos pos 40000 add def + } forall + } ifelse + % top of stack is either array of strings or one string == stream_data + end % done with scratch dict + % Stack: dict filters parms CloseSource oldglobal oldpacking stream_data 3 1 roll setpacking setglobal - % Stack: dict filters parms CloseSource [()...] + % Stack: dict filters parms CloseSource stream_data 1 index .reusablestream } if % We created the stream successfully: clean up. diff --git a/Resource/Init/gs_icc.ps b/Resource/Init/gs_icc.ps index fac0cb25..0bf8313f 100644 --- a/Resource/Init/gs_icc.ps +++ b/Resource/Init/gs_icc.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_il1_e.ps b/Resource/Init/gs_il1_e.ps index f8cfff04..35250233 100644 --- a/Resource/Init/gs_il1_e.ps +++ b/Resource/Init/gs_il1_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_img.ps b/Resource/Init/gs_img.ps index 00d79df3..3750ad30 100644 --- a/Resource/Init/gs_img.ps +++ b/Resource/Init/gs_img.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2002-2018 Artifex, Inc. All rights reserved. +% Copyright (C) 2002-2021 Artifex, Inc. All rights reserved. % % This software is provided AS-IS with no warranty, either express or % implied. diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps index f843119a..088c8583 100644 --- a/Resource/Init/gs_init.ps +++ b/Resource/Init/gs_init.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -34,7 +34,7 @@ % Interpreter library version number % NOTE: the interpreter code requires that the first non-comment token % in this file be an integer, and that it match the compiled-in version! -9531 +9540 % Check the interpreter revision. dup revision ne @@ -144,7 +144,8 @@ currentdict /PDFNOCIDFALLBACK known /PDFNOCIDFALLBACK exch def currentdict /BATCH known /BATCH exch def currentdict /DELAYBIND known /DELAYBIND exch def -currentdict /DOINTERPOLATE .knownget { { -1 } { 0 } ifelse /InterpolateControl exch def } if +currentdict /DOINTERPOLATE .knownget { { -1 } { 1 } ifelse /InterpolateControl exch def } if +currentdict /NOINTERPOLATE .knownget { { 0 } { 1 } ifelse /InterpolateControl exch def } if currentdict /ESTACKPRINT known /ESTACKPRINT exch def currentdict /FAKEFONTS known /FAKEFONTS exch def currentdict /FIXEDMEDIA known /FIXEDMEDIA exch def @@ -159,7 +160,6 @@ currentdict /NODISPLAY known not /DISPLAYING exch def currentdict /NOFONTMAP known /NOFONTMAP exch def currentdict /NOFONTPATH known /NOFONTPATH exch def currentdict /NOGC known /NOGC exch def -currentdict /NOINTERPOLATE .knownget { /InterpolateControl 0 def } if currentdict /NOMEDIAATTRS known /NOMEDIAATTRS exch def currentdict /NOOUTERSAVE known /NOOUTERSAVE exch def currentdict /NOPAGEPROMPT known /NOPAGEPROMPT exch def @@ -215,6 +215,13 @@ currentdict /EPSFitPage known { /PSFitPage //true def } if % This is a "convenience" option that sets a combination of EPSFitPage, PDFFitPage and PSFitPage currentdict /FitPage known { /EPSFitPage //true def /PDFFitPage //true def /PSFitPage //true def } if +currentdict /SimulateOverprint known { + (\n**** -dSimulateOverprint={true|false} is no longer supported. ****\n) print + (**** It has been replaced by -dOverprint={enable|disable|simulate} ****\n\n) print + % Set the new variable appropriately. + /Overprint SimulateOverprint { /enable } { /disable } ifelse def +} if + % Acquire environment variables. currentdict /DEVICE known not { (GS_DEVICE) getenv { /DEVICE exch def } if } if diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps index fefa732b..54849370 100644 --- a/Resource/Init/gs_lev2.ps +++ b/Resource/Init/gs_lev2.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_ll3.ps b/Resource/Init/gs_ll3.ps index f6d98482..98e2a65f 100644 --- a/Resource/Init/gs_ll3.ps +++ b/Resource/Init/gs_ll3.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_mex_e.ps b/Resource/Init/gs_mex_e.ps index dda0675c..cced43b3 100644 --- a/Resource/Init/gs_mex_e.ps +++ b/Resource/Init/gs_mex_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_mgl_e.ps b/Resource/Init/gs_mgl_e.ps index e02729b1..b437285b 100644 --- a/Resource/Init/gs_mgl_e.ps +++ b/Resource/Init/gs_mgl_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_mro_e.ps b/Resource/Init/gs_mro_e.ps index 7d0e3b7c..e476322b 100644 --- a/Resource/Init/gs_mro_e.ps +++ b/Resource/Init/gs_mro_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_pdf_e.ps b/Resource/Init/gs_pdf_e.ps index 172cd72c..2d3ec9ff 100644 --- a/Resource/Init/gs_pdf_e.ps +++ b/Resource/Init/gs_pdf_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps index a53b8c3f..9386339b 100644 --- a/Resource/Init/gs_pdfwr.ps +++ b/Resource/Init/gs_pdfwr.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -278,19 +278,6 @@ languagelevel 2 .setlanguagelevel % ---------------- End of predefined configurations ---------------- % -% Set optimizations for converting PostScript to PDF. -% The ps2pdf* scripts invoke this. -/.setpdfwrite { % - .setpdfwrite - - % Set a large VM threshold to reduce garbage collection. - (\n**** WARNING: The .setpdfwrite operator has been deprecated and will be removed entirely\n) print - ( in the next release of Ghostscript. The functionality of this operator has\n) print - ( been reduced to increasing the size of the VM threshold. If you believe you\n) print - ( have a real need for this then you should replace your call to .setpdfwrite\n) print - ( with:\n\n) print - ( 3000000 setvmthreshold\n\n) print - currentuserparams /VMThreshold get 3000000 .max setvmthreshold -} bind def - % ---------------- pdfmark and DSC processing ---------------- % /.write_small_positive_real % .write_small_positive_real - diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps index 18f63a30..41214bf3 100644 --- a/Resource/Init/gs_res.ps +++ b/Resource/Init/gs_res.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_resmp.ps b/Resource/Init/gs_resmp.ps index 5ba4f43e..a7eb70fc 100644 --- a/Resource/Init/gs_resmp.ps +++ b/Resource/Init/gs_resmp.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps index 51b26899..2a333bf7 100644 --- a/Resource/Init/gs_setpd.ps +++ b/Resource/Init/gs_setpd.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_statd.ps b/Resource/Init/gs_statd.ps index 7b85ef0f..8f01c78c 100644 --- a/Resource/Init/gs_statd.ps +++ b/Resource/Init/gs_statd.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_std_e.ps b/Resource/Init/gs_std_e.ps index 4bfa6c5b..c696b714 100644 --- a/Resource/Init/gs_std_e.ps +++ b/Resource/Init/gs_std_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_sym_e.ps b/Resource/Init/gs_sym_e.ps index fb92a299..e6c58f6f 100644 --- a/Resource/Init/gs_sym_e.ps +++ b/Resource/Init/gs_sym_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_trap.ps b/Resource/Init/gs_trap.ps index e4d6cafe..9a089eef 100644 --- a/Resource/Init/gs_trap.ps +++ b/Resource/Init/gs_trap.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_ttf.ps b/Resource/Init/gs_ttf.ps index 394cba28..95d50c6b 100644 --- a/Resource/Init/gs_ttf.ps +++ b/Resource/Init/gs_ttf.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -414,7 +414,16 @@ pop /firstcode startc 0 getu16a 16#ff00 and dup 16#f000 ne { pop 0 } if def /putglyph { - glyphs code 3 -1 roll put /code code 1 add def + glyphs code known + { + glyphs /.cmap_warning_issued known not { + (**** Warning: Invalid TTF cmap mapping (overlapping/repeated map)\n) print flush + glyphs /.cmap_warning_issued //true put + } if + pop + } + {glyphs code 3 -1 roll put}ifelse + /code code 1 add def } bind def /glyphs 0 dict def @@ -438,6 +447,10 @@ % Two choices are: drop later repeated/overlapping segments entirely, % or only use codes from later, overlapping segments not already set % by the earlier segment. (Inspired by Bug 700968). + % Revision: bug 703589 has an (invalid) cmap table with overlapping + % (actually repeating) ranges, and requires the *first* range definition + % to be used in order to render correctly. So /putglyph now refuses to + % overwrite existing keys in the "glyphs" dictionary 0 2 nseg2 dup 4 lt {pop 4}if 3 sub { /i2 exch def /scode startc i2 getu16a def @@ -464,7 +477,10 @@ } for } ifelse } if - } for glyphs /glyphs //null def % for GC + } for + % If we've encoutered an invalid table, remove the key before returning + glyphs /.cmap_warning_issued undef + glyphs /glyphs //null def % for GC } .bind 6 { % Single interval lookup. dup 6 getu16a /firstcode exch def diff --git a/Resource/Init/gs_typ32.ps b/Resource/Init/gs_typ32.ps index 2d5fc814..4c2035c7 100644 --- a/Resource/Init/gs_typ32.ps +++ b/Resource/Init/gs_typ32.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_typ42.ps b/Resource/Init/gs_typ42.ps index 654a268c..a3bb9795 100644 --- a/Resource/Init/gs_typ42.ps +++ b/Resource/Init/gs_typ42.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps index 18488ebe..fa3cdd88 100644 --- a/Resource/Init/gs_type1.ps +++ b/Resource/Init/gs_type1.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/gs_wan_e.ps b/Resource/Init/gs_wan_e.ps index 5d3673cc..fe821352 100644 --- a/Resource/Init/gs_wan_e.ps +++ b/Resource/Init/gs_wan_e.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps index 2cc18270..2453b6bc 100644 --- a/Resource/Init/pdf_base.ps +++ b/Resource/Init/pdf_base.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -779,17 +779,19 @@ currentdict /token_nofail_dict .undef % Read the data for all objects. We check to see if we get % the number of objects that we expect. % Stack: strm# objstreamdict N objectstream [obj#] PDFDEBUG - mark 3 -1 roll % Get objectstream + /ResolveObjectStreamMark 3 -1 roll count 4 index add % Determine stack depth with objects 3 1 roll resolveobjstreamopdict .pdfrun % Get PDF objects - count counttomark 1 add index ne + count /ResolveObjectStreamMark CountToKey not {0} if + 1 add index + ne { - count counttomark 1 add index gt { + count /ResolveObjectStreamMark CountToKey not {0} if + 1 add index gt { ( **** Error: Incorrect object count in object stream (too many objects).\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } if - % Its possible for us to end up here with a valid file. The way we work is to read the % stream and tokenise all the objects, but that assumes there will be delimiters or % whitespace between each object in the stream. We can easily think of cases where @@ -821,13 +823,13 @@ currentdict /token_nofail_dict .undef % the stack, in the right order, preceded by a mark, a count, and an array containing % all the object numbers. - % First, discard everything we read up to now; we can reuse the mark which was placed - % by the preceding code to do this, as long as we remember to replace that mark. + % First, discard everything we read up to now; we can reuse the 'mark' which was placed + % by the preceding code to do this, as long as we remember to replace that 'mark'. % Handily this will leave the count and the array which contains the object numbers in place. - cleartomark + /ResolveObjectStreamMark ClearToKey - % Replace the mark consumed by conttomark above, so that we match what the code following this error handling expects. - mark + % Replace the 'mark' consumed by conttomark above, so that we match what the code following this error handling expects. + /ResolveObjectStreamMark % copy the ObjStm dictionary and then copy the count of objects expected 4 index 4 index @@ -894,14 +896,15 @@ currentdict /token_nofail_dict .undef % but leave count of objects. Check that aginst the number of objects % retrieved. If we got too few then issue a warning. - pop pop exch pop counttomark 1 sub lt { + pop pop exch pop /ResolveObjectStreamMark CountToKey not {1} if + 1 sub lt { ( **** Error: Incorrect object count in object stream (too few objects).\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } if } if % We have the object data - counttomark array astore % Put objects into an array + /ResolveObjectStreamMark CountToKey not {0} if array astore exch pop exch pop % Remove mark and count currentdict //no_debug_dict eq { end } if % Restore debug context % Save the objects into Objects @@ -1090,15 +1093,30 @@ currentdict /no_debug_dict undef % Some (bad) PDf files have invalid stream lengths. This causes problems % if we reposition beyond the end of the file. So we compare the given % length to number of bytes left in the file. - dup /Length knownoget { - dup PDFfile bytesavailable lt { % compare to to bytes left in file - PDFfile fileposition % reposition to the end of stream - add PDFfile exch setfileposition - } { - pop % bad stream length - do not reposition. - % This will force a length warning below - } ifelse - } if + dup mark exch /Length {knownoget} stopped { + % Bug 703372 is a PDF file where the XRef stream dictionary has a Length which is an + % indirect object. Clearly we cannot look that up in an xref which we haevn't yet + % read! We catch the error from knownoget and do not reposition the steam. After + % that the normal recovery code kicks in and we will eventually manage to read + % the compressed xref. + cleartomark + } + { + { + dup type /realtype eq { + ( **** Warning: stream length is a real number; converting to integer.\n) pdfformatwarning + cvi 2 copy /Length exch put + } if + dup PDFfile bytesavailable lt { % compare to to bytes left in file + PDFfile fileposition % reposition to the end of stream + add PDFfile exch setfileposition + } { + pop % bad stream length - do not reposition. + % This will force a length warning below + } ifelse + } if + pop % the mark from the Length dereference guard above. + } ifelse } { pop % We're already reading from a stream, which we can't reposition. @@ -1191,7 +1209,7 @@ currentdict /no_debug_dict undef //unabbrevfilterdict 1 index .knownget { exch pop } if dup /Filter resourcestatus { pop pop } { Repaired exch % this error is not the creator's fault - RepiredAnError exch + RepairedAnError exch ( **** ERROR: Unable to process ) pdfformaterror 64 string cvs pdfformaterror ( data. Page will be missing data.\n) pdfformaterror diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps index a93a526c..8527312c 100644 --- a/Resource/Init/pdf_draw.ps +++ b/Resource/Init/pdf_draw.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -762,6 +762,24 @@ def .pdfruncontext end grestore + + % check for extra garbage on the operand stack and clean it up + count pdfemptycount sub dup 0 ne { + ( **** Error: Transparency Group, Form XObject execution corrupted the stack.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + PDFSTOPONERROR { + /.execgroup cvx /rangecheck signalerror + } { + dup 0 gt { + { pop } repeat + }{ + pop + } ifelse + } ifelse + } { + pop + } ifelse + /pdfemptycount exch store } bind executeonly def @@ -796,12 +814,22 @@ def %% as arguments to .execgroup mark currentcolor counttomark array astore exch pop currentcolorspace 5 2 roll - - dup /Group oget exch /BBox oget + dup /Group oget dup type /dicttype eq { + exch /BBox oget dup type /arraytype eq { % Stack: resdict stream groupdict bbox - .beginformgroup - .execgroup - .endtransparencygroup + .beginformgroup + .execgroup + .endtransparencygroup + }{ + ( **** Error: Form XObject has a BBox entry with an invalid type.\n) pdfformaterror + ( Ignoring transparency Group, output may be incorrect.\n) pdfformaterror + pop pop pop pop pop pop + } ifelse + } { + ( **** Error: Form XObject has a Group entry with an invalid type.\n) pdfformaterror + ( Ignoring transparency Group, output may be incorrect.\n) pdfformaterror + pop pop pop pop pop pop + } ifelse } bind executeonly def % Make an ImageType 103 (soft-masked) image. @@ -2169,7 +2197,15 @@ currentdict /last-ditch-bpc-csp undef ( Output may be incorrect.\n) pdfformaterror } ifelse } if - 1 index /Mask knownoget { 1 index exch /Mask exch put } if + 1 index /Mask knownoget { + dup type dup /dicttype eq exch /arraytype eq or { % Bug #703681 + 1 index exch /Mask exch put + } { + pop + ( **** Error: Ignoring Mask attribute that is not an array or a dictionary.\n) + pdfformaterror + } ifelse + } if makeimagedict doimagesmask } bind executeonly def /makemaskimage { % makemaskimage @@ -2287,6 +2323,14 @@ currentdict /last-ditch-bpc-csp undef currentdict /SMask knownoget { % We are doing transparency and SMask is present in the image % stack: + % Normalize /Matte attribute for .begintransparencymaskimage + dup /Matte .knownget { + oforce dup //null eq { + pop dup /Matte undef + } { + 1 index /Matte [ 4 -1 roll { oforce } forall ] put + } ifelse + } if .begintransparencymaskimage PDFfile fileposition exch gsave //nodict begin @@ -2308,6 +2352,12 @@ currentdict /last-ditch-bpc-csp undef % code only picks up the current colour space, not the space from the dictionary. currentdict /SMask get /Matte known {/CS currentdict /ColorSpace get dup pdfopdict /cs get exec } if >> 0 0 1 1 + gsave 1 1 moveto 0 0 lineto + % If we get an error, just emit an empty box + { pathbbox } stopped { 0 0 0 0 } if + 4 array astore grestore + /image + setup_trans .begintransparencygroup .currentstrokeconstantalpha .currentfillconstantalpha 3 -1 roll 1 .setfillconstantalpha 1 .setstrokeconstantalpha @@ -2409,12 +2459,6 @@ currentdict /last-ditch-bpc-csp undef makemaskimage } if % Stack: datasource imagemask - gsave 1 1 moveto 0 0 lineto - % If we get an error, just emit an empty box - { pathbbox } stopped { 0 0 0 0 } if - 4 array astore grestore - /image - setup_trans { currentdict end setsmaskstate //true ValidateDecode { imagemask } } { ColorSpace setgcolorspace currentdict end setsmaskstate //false ValidateDecode { image } } ifelse @@ -3008,6 +3052,12 @@ drawopdict begin /File PDFsource def currentdict makeimagekeys OFFlevels length 0 eq { + gsave 1 1 moveto 0 0 lineto + % If we get an error, just emit an empty box + { pathbbox } stopped { 0 0 0 0 } if + 4 array astore grestore + /image + setup_trans doimage } { pop Width @@ -4252,7 +4302,7 @@ currentdict /set_bc_color undef dup annotsetcolor { dup drawborder dup calc_annot_scale 2 copy mul 0 ne - {3 -1 roll drawwidget //false} + {3 -1 roll drawwidget} { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror @@ -4260,6 +4310,7 @@ currentdict /set_bc_color undef }ifelse } if //endannottransparency exec + //false } bind executeonly def /Ink { % -> @@ -5359,14 +5410,9 @@ currentdict /drawannottypes undef /Ink {mark exch loadannot /ANN pdfmark //false} bind executeonly def -/Line { - mark exch dup /L .knownget { - aload 5 1 roll transform 4 -2 roll transform 4 2 roll - 5 -1 roll astore - 1 index /L 3 -1 roll put - } if - loadannot /ANN pdfmark //false -} bind executeonly def +/PolyLine {mark exch loadannot /ANN pdfmark //false} bind executeonly def + +/Line {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Link { /NO_PDFMARK_DESTS where {pop NO_PDFMARK_DESTS not}{//true}ifelse @@ -5456,7 +5502,8 @@ currentdict /drawannottypes undef //false } bind executeonly def -/Movie {mark exch loadannot /ANN pdfmark //false} bind executeonly def +%% We don't handle movies correctly, so don't try to preserve them +%/Movie {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Popup {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Sound {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Square {mark exch loadannot /ANN pdfmark //false} bind executeonly def @@ -5717,22 +5764,25 @@ currentdict end def % The recursive enumeration of the form fields doesn't descend into widget annotations. /draw_form_field { % draw_form_field - - dup /Kids knownoget { % field [] - dup length 0 gt { - dup 0 oget /Parent knownoget { % field [] kid - pop % mon-terminal field % field [] - exch pop % [] - { oforce draw_form_field } forall + dup type /dicttyype eq { % File for Bug692447 has 'null' Fields entries + % This matches what pdf_main process_trailer_attrs + dup /Kids knownoget { % field [] + dup length 0 gt { + dup 0 oget /Parent knownoget { % field [] kid + pop % mon-terminal field % field [] + exch pop % [] + { oforce draw_form_field } forall + } { + pop draw_terminal_field % separate annots % - + } ifelse } { - pop draw_terminal_field % separate annots % - + ( **** Error: Ignoring empty /Kids array in Form field.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror } ifelse } { - ( **** Error: Ignoring empty /Kids array in Form field.\n) pdfformaterror - ( Output may be incorrect.\n) pdfformaterror + draw_terminal_field % merged annotation % - } ifelse - } { - draw_terminal_field % merged annotation % - - } ifelse + } if } bind executeonly def /draw_acro_form { %
draw_acro_form - diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps index 98a9e3d4..699c14fe 100644 --- a/Resource/Init/pdf_font.ps +++ b/Resource/Init/pdf_font.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -1234,6 +1234,23 @@ setglobal { /undef_proc_warning /missing-type1-procs /readonly-op-dict } { currentdict exch undef } forall + % Bug703454.pdf contains a number of fonts with multiple definitions + % of a given glyph name in the CharStrings dict - i.e. two entries + % for /a - the first of which is "correct" the second is "wrong". + % Normal Postscript behaviour replaces the first value with the second + % for the given key/value pair. + % To handle this, *only* for Type 1 fonts embedded in PDFs, we + % have a special definition of "def" which won't overwrite existing + % values in the CharStrings dict. + /def + { + 3 index /CharStrings eq + currentdict 3 index known and + { pstack flush pop pop } + { systemdict /def get exec } + ifelse + } bind executeonly def + end readonly def currentdict /eexec_pdf_param_dict .undef @@ -1481,7 +1498,9 @@ currentdict /eexec_pdf_param_dict .undef } { % filepos fontres stream 1 index /FontDescriptor oget - /Flags oget 4 and 0 ne { + /Flags oget dup % only believe the symbolic flag if the non-symbolic flag is not also set! + 4 and 0 ne + exch 32 and 0 eq and { //true % symbolic } { 1 index /Encoding oknown not % no encoding => symbolic diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps index d7933700..ded2782a 100644 --- a/Resource/Init/pdf_main.ps +++ b/Resource/Init/pdf_main.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -26,10 +26,12 @@ userdict /GS_PDF_ProcSet undef /#? //false def % Test whether the current output device handles pdfmark. -/.writepdfmarkdict 1 dict dup /pdfmark //null put readonly def /.writepdfmarks { % - .writepdfmarks - currentdevice //.writepdfmarkdict .getdeviceparams - mark eq { //false } { pop pop //true } ifelse + /PdfmarkCapable /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse systemdict /DOPDFMARKS known or } bind executeonly def @@ -282,12 +284,22 @@ currentdict /runpdfstring .undef { systemdict /FirstPage known systemdict /LastPage known or - systemdict /Pagelist known or + systemdict /PageList known or { <> setpagedevice } if } bind def +/EnablePageHandlerDevice +{ + systemdict /FirstPage known + systemdict /LastPage known or + systemdict /PageList known or + { + <> setpagedevice + } if +} bind def + /runpdfbegin { % runpdfbegin - userdict begin % It turns out that the PDF interpreter uses memory more @@ -295,20 +307,22 @@ currentdict /runpdfstring .undef % This is counter-intuitive, and we don't understand why it happens, % but the improvement is significant. /PDFTopSave save def - <> setuserparams - <> setuserparams - %% Bug #696487, allow dict stack to grow without limit, as these PDF - %% files have stupidly deep gsave nesting and we need a dictionary per gsave - %% at the moment. - %% Remove ths if bug #696511 is ever completed (move ExtGstate parameters into gstate) - <> setuserparams - %% Bug #696567, same customer as above. Ths time they have a file with a page whch has - %% 447000 ExtGState references (all of hwch contain no gstate!) Because we allocate - %% these on the stack, allow the stack to grow indefinitely in order to accomodate - %% such stupid files. Also move these lines from the end of the routine, so that - %% the increases are in place before we call odfopen, which will build the - %% resources and needs this definition in place. - <> setuserparams + << + /ProcessDSCComment //null + /ProcessComment //null + %% Bug #696487, allow dict stack to grow without limit, as these PDF + %% files have stupidly deep gsave nesting and we need a dictionary per gsave + %% at the moment. + %% Remove ths if bug #696511 is ever completed (move ExtGstate parameters into gstate) + /MaxDictStack -1 + %% Bug #696567, same customer as above. Ths time they have a file with a page whch has + %% 447000 ExtGState references (all of which contain no gstate!) Because we allocate + %% these on the stack, allow the stack to grow indefinitely in order to accomodate + %% such stupid files. Also move these lines from the end of the routine, so that + %% the increases are in place before we call odfopen, which will build the + %% resources and needs this definition in place. + /MaxOpStack -1 + >> setuserparams //DisablePageHandlerDevice exec @@ -323,7 +337,6 @@ currentdict /runpdfstring .undef /CumulativePageCount currentpagedevice /PageCount get def } bind executeonly def -currentdict /DisablePageHandlerDevice undef /runpdfpagerange { % - runpdfpagerange /PortfolioPage where { @@ -375,9 +388,8 @@ currentdict /DisablePageHandlerDevice undef 2 2 pdfpagecount { PDFPageList exch 1 put } for - 1 pdfpagecount QUIET not { - (Processing even-numbered pages\n) print + (Processing even-numbered pages\n) print (1 through ) print pdfpagecount =only (.) = flush } if } { @@ -389,9 +401,8 @@ currentdict /DisablePageHandlerDevice undef 1 2 pdfpagecount { PDFPageList exch 1 put } for - 1 pdfpagecount QUIET not { - (Processing odd-numbered pages\n) print 1 index =only ( through ) print dup =only + (Processing odd-numbered pages\n) print (1 through ) print pdfpagecount =only (.) = flush } if } { @@ -525,10 +536,16 @@ currentdict /DisablePageHandlerDevice undef dup /Page# exch store QUIET not { (Page ) print dup //== exec flush } if pdfgetpage - dup //null ne { pdfshowpage } { - ( **** Error: Page #) pdfformaterror Page# 10 string cvs pdfformaterror - ( not found.\n) pdfformaterror - /dopdfpages cvx /syntaxerror signalerror + dup //null ne { + pdfshowpage + } { + PDFSTOPONERROR { + /dopdfpages cvx /syntaxerror signalerror + } { + pop + ( **** Error: Page #) pdfformaterror Page# 10 string cvs pdfformaterror + ( not found.\n) pdfformaterror + } ifelse } ifelse }{ pop @@ -554,9 +571,12 @@ currentdict /DisablePageHandlerDevice undef PDFTopSave restore end % userdict 2 vmreclaim % couldn't hurt - <> setpagedevice + //EnablePageHandlerDevice exec } bind executeonly def +currentdict /DisablePageHandlerDevice undef +currentdict /EnablePageHandlerDevice undef + % Copy stream to an external temporary file and % return the file name as PS name. /copy_embedded_file { @@ -890,7 +910,25 @@ pdfdict begin { % xref line tag was not /n /f ne % verify that the tag was /f { /setxrefentry cvx /syntaxerror signalerror - } if + } { + % Bug #703214 has a invalid initial xref table. The table entries are correct + % but the subsection begins 1 7 instead of 0 7, which means the initial entry is + % declared as object 1 instead of object 0. The file is incrementally updated + % many times and every object *except* object 1 is redefined. Object 1 is + % therefore defined as free and having an offset of 0. Acrobat can open this + % without complaint! Because the PDF header is a comment line it is skipped + % so Acrobat must simply be ignoring the free flag. We can't easily detect + % this, but we can check for the generation number being the canonical + % head of the free list. If it is, and the object number we have is not + % zero, then pretend its not free....... + dup 65535 eq { + 2 index 0 ne { + 0 3 1 roll + //false setxrefentry + 3 -1 roll pop + } if + }if + }ifelse } ifelse pop pop % pop and % stack: @@ -1254,26 +1292,26 @@ currentdict /xref-char-dict undef % to the parent field. Trailer /Root knownoget { /AcroForm knownoget { - %% If we don't have a NeedAppearances entry, treat as if true. - %% We know Acrobat always regenerates all annotait - dup /NeedAppearances knownoget not { //true } if { - /NeedAppearances //true def - dup - /Fields knownoget { - { oforce - %% Make sure the entry from the Fields array is a dictionary - %% Bug #692447.pdf has an array of nulls. - dup type /dicttype eq { - link_widget_annots - }if - pop - } forall - } if - pop - } { - pop - } ifelse - } if + %% If we don't have a NeedAppearances entry, treat as if true. + %% We know Acrobat always regenerates all annotations. + dup /NeedAppearances knownoget not { //true } if { + /NeedAppearances //true def + dup + /Fields knownoget { + { oforce + %% Make sure the entry from the Fields array is a dictionary + %% Bug #692447.pdf has an array of nulls. + dup type /dicttype eq { + link_widget_annots + }if + pop + } forall + } if + pop + } { + pop + } ifelse + } if } if % Use OutputIntent ICC profile @@ -1427,14 +1465,15 @@ currentdict /xref-char-dict undef % Guess whether the output device is a printer. /Printed currentpagedevice /OutputFile known def } ifelse - currentpagedevice /OutputFile known { - currentpagedevice /OutputFile get (%d) search { - pop pop pop + % If the file name has an odd number of '%', it is either a request for + % separate pages, or is invalid. In either case some marks can be omitted. + currentpagedevice /OutputFile .knownget { + //false exch { + 37 eq xor + } forall { /NO_PDFMARK_OUTLINES //true def /NO_PDFMARK_DESTS //true def - } { - pop - }ifelse + } if } if /PSLevel1 where { pop } { /PSLevel1 //false def } ifelse % NB: PDFfile is used outside of the PDF code to determine that a @@ -1579,10 +1618,9 @@ currentdict /xref-char-dict undef % Check for recursion in the page tree. Bug 689954, MOAB-06-01-2007 % Make sure that the operand stack is cleaned up in case there's % an error and we ignore it (bug #700953) - mark + /StackMarkVerifyPageTree verify_page_tree - cleartomark - + /StackMarkVerifyPageTree ClearToKey currentdict end } bind executeonly def @@ -1923,7 +1961,6 @@ currentdict /xref-char-dict undef }ifelse }{ % No Page Resources, recursively try ParentResources as a last resort - pop % page Resources LocalResources parent_obj_get } ifelse } { @@ -1971,7 +2008,8 @@ currentdict /xref-char-dict undef % Get the total number of pages in the document. /pdfpagecount % - pdfpagecount - { Trailer /Root knownoget { + { + Trailer /Root knownoget { /Pages knownoget { dup /Count knownoget { dup type /integertype eq { dup 0 le } { //true } ifelse { @@ -2078,10 +2116,20 @@ currentdict /xref-char-dict undef exch pop //null 0 1 3 index length 1 sub { 2 index exch get - dup oforce dup /Kids known { /Count oget } { pop 1 } ifelse + dup oforce + dup //null eq { + PDFSTOPONERROR { + /pdffindpage? cvx /syntaxerror signalerror + } { + ( **** Error: Ignoring a null node in the Page tree.\n) pdfformaterror + pop pop + } ifelse + } { + dup /Kids known { /Count oget } { pop 1 } ifelse % Stack: index kids null noderef count - dup 5 index ge { pop exch pop exit } if - 5 -1 roll exch sub 4 1 roll pop + dup 5 index ge { pop exch pop exit } if + 5 -1 roll exch sub 4 1 roll pop + } ifelse } for exch pop % Stack: index null|noderef dup //null eq { pop pop 1 //null exit } if @@ -2511,7 +2559,7 @@ end readonly def 2 index sub exch 3 index sub exch 4 2 roll pop pop % stack: savedCTM [Box] XImageable YImageable 2 index aload pop 2 index sub exch 3 index sub exch 4 2 roll pop pop - 5 index /Rotate pget not { 0 } if 90 cvi idiv 1 and 0 ne { exch } if + 5 index /Rotate pget not { 0 } if cvi 90 idiv 1 and 0 ne { exch } if % stack: savedCTM [Box] XImageable YImageable XBox YBox 4 copy 3 -1 roll exch div 3 1 roll div .min @@ -2647,7 +2695,11 @@ currentdict /PDF2PS_matrix_key undef % Determine the number of spot colors used on the page. Note: This searches % the pages resources. It may be high if a spot color is in a resource but % is not actually used on the page. - currentpagedevice /PageSpotColors known { /PageSpotColors 2 index countspotcolors def } if + currentpagedevice /PageSpotColors known { + /PageSpotColors 2 index countspotcolors + userdict /PageSpotColors 2 index put + def + } if % If the user told us to use a named OutputIntent systemdict /UseOutputIntent .knownget { @@ -2701,6 +2753,30 @@ currentdict /PDF2PS_matrix_key undef % Stack: pagedict currentpagedict installproc /Install exch def % Stack: pagedict currentpagedict + % If the Overprint device flag is not /disable, check usage of OP/op + /PageUsesOverprint //false def % assume we don't need OP simulation + dup /Overprint get /disable ne + % If the device suppports SpotColors (DeviceN device) we don't need simulation + 1 index /PageSpotColors known + not and + /HighLevelDevice /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + not and % Only if not HighLevelDevice + { + % Overprint is /enable, so the device might need the overprint compositor + % if it does not support spot colors, thus check if overprint is used so + % overprint simulation can be done with the pdf14 compositor + 1 index countspotcolors userdict exch /PageSpotColors exch put % save it in a known place + 1 index pageusesoverprint + 1 index /ProcessColorModel get /DeviceCMYK eq { + PageSpotColors 0 gt % count of colorants NOT including CMYK + and + } if + /PageUsesOverprint exch def % the page needs OP simulation so set device param. + } if pop currentdict end setpagedevice } bind executeonly def @@ -2769,18 +2845,46 @@ currentdict /PDF2PS_matrix_key undef % and the result was set in the pagedevice dictionary. Use it rather than % scanning again IF it is present. If the pdfshowpage_setup was not called % (eg GSView 5) then it will not be present, so we must rescan. - currentpagedevice /PageUsesTransparency .knownget not {dup pageusestransparency} if + currentdict /PageUsesTransparency .knownget not {dup pageusestransparency} if dup /PDFusingtransparency exch def { - % If the current device isn't CMYK, or if it is a device that (currently) supports transparency + % If the current device isn't CMYK, or if it is a device that supports transparency % we don't need the special handling of Overprint transparency, so disable the checking. - currentpagedevice dup /Colors get 4 lt 1 index /SimulateOverprint get not or - exch /HaveTransparency .knownget not { //false } if or - % device needs special Oveprint handling + + 4 dict begin % working directory to simplify + currentpagedevice dup /Colors get + /devColors exch def % put into our convenience dict + dup /HaveTransparency .knownget not { //false } if + /devSupportsTrans exch def % put into our convenience dict + dup /Overprint get + /SimOP exch def % put into our convenience dict + SimOP /simulate eq + exch /PageUsesOverprint .knownget not { //false } if + and % both Overprint==/simulate and PageUsesOverprint + { + % Determine if the device needs the special pdf14 compositor push + devColors 4 eq PageSpotColors 0 gt and % CMYK device, but device has spot colors + devColors 4 lt % RGB or Gray device + or + } { + //false % Overprint is not /simulate or PageUseOverprint is false + } ifelse + % Determine if the device needs SMask for Overprint + SimOP /simulate eq { + //true % we will need setupOPrtans for Compatible BM + } { + SimOP /enable eq + devColors 4 ge % CMYK device + and + } ifelse + devSupportsTrans not and % If device supports transparency (e.g. pdfwrite) then no setupOPtrans + end % pop the convenience dict /setup_trans exch - { /setupSMtrans } { /setupOPtrans } ifelse + { /setupOPtrans } { /setupSMtrans } ifelse load def + % Show the page within a PDF 1.4 device filter. - 0 .pushpdf14devicefilter { + { -1 } { 0 } ifelse + .pushpdf14devicefilter { /DefaultQstate qstate store % device has changed -- reset DefaultQstate % If the page has a Group, enclose contents in transparency group. % (Adobe Tech Note 5407, sec 9.2) @@ -2808,7 +2912,31 @@ currentdict /PDF2PS_matrix_key undef } { /setup_trans { pop pop } def % no-op this if the page doesn't use transparency % NB: original will be restored from PDFsave - showpagecontents + % The page doesn't use transparency, but if Overprint is /simulate, we may need to + % push a pdf14devicefilter to handle the overprint simulation using the pdf14 device. + currentpagedevice + dup /Overprint get /simulate eq + 1 index /PageSpotColors known + not and + exch /PageUsesOverprint .knownget not { //false } if + and + { + % Show the page within a PDF 1.4 device filter for overprint_simulation. + -1 .pushpdf14devicefilter { + /DefaultQstate qstate store % device has changed -- reset DefaultQstate + showpagecontents + } stopped { + % abort the transparency device + .abortpdf14devicefilter + /DefaultQstate qstate store % device has changed -- reset DefaultQstate + stop + } if + { } settransfer % identity transfer during popdevice (put_image) + .poppdf14devicefilter % NB: reset to DefaultQstate will also restore transfer function + /DefaultQstate qstate store % device has changed -- reset DefaultQstate + } { + showpagecontents + } ifelse } ifelse .free_page_resources % todo: mixing drawing ops outside the device filter could cause @@ -2967,7 +3095,8 @@ currentdict /PDF2PS_matrix_key undef } ifelse } if } if - //systemdict /ShowAcroForm .knownget { //true eq } { //false } ifelse { + % default AcroForm to true to match Acrobat. + //systemdict /ShowAcroForm .knownget { //true eq } { //true } ifelse { Trailer /Root oget /AcroForm knownoget { draw_acro_form } if } if } bind executeonly def @@ -2980,6 +3109,112 @@ currentdict /PDF2PS_matrix_key undef dup { setcolorspace } //.internalstopped exec { pop /DeviceRGB } if } bind executeonly def +% returns true if OP or op is true in an ExtGState +/pageusesoverprint { % pageusesoverprint + dup //false exch { + 4 dict 1 index resourceusesoverprint { pop not exit } if + %% Check the current dictionary and its Parent (if any) to see + %% if they both have stored object numbers. If they do then + %% check the numbers, don't allow self-references. + dup /Parent knownoget not { pop exit } + { + exch /.gs.pdfobj# .knownget + { + 1 index /.gs.pdfobj# .knownget { + eq { + pop exit + }if + }{ + pop + }ifelse + }if + } ifelse + } loop + % Also check for transparency in the annotation (if not in resources). + { pop //true } { annotsuseoverprint } ifelse +} bind def + +% Check if Overprint (OP/op) is specified in an ExtGState dict +/extgstateusesoverprint { % extgstateusesoverprint + //false exch % Assume no overprint + dup //null eq { + pop % bug 692050 + } { + { % establish loop context + dup /OP knownoget { { pop not exit } if } if + dup /op knownoget { { pop not exit } if } if + pop exit + } loop + } ifelse +} bind def + +% Check if overprint is used in a Pattern +/patternusesoverprint { % patternusesoverprint + //false exch % Assume no overprint + { + 4 dict 1 index resourceusesoverprint { pop not exit } if + dup /ExtGState knownoget { extgstateusesoverprint { pop not exit } if } if + pop exit + } loop +} bind def + +% Check the Resources of a page or Form. Check for loops in the resource chain. +/resourceusesoverprint { % resourceusesoverprint + { % Use loop to provide an exitable context. + /Resources knownoget not { 0 dict } if + 2 copy .knownget { + { % Some circular references may be missed because scanning stops + % when the 1st overprint is found. + ( **** File has circular references in resource dictionaries.\n) + pdfformaterror + } if + pop //false exit + } if + 2 copy //true put % In the current chain. + dup /ExtGState knownoget { + //false exch + { exch pop oforce extgstateusesoverprint { pop //true exit } if + } forall + { pop //true exit } if + } if + dup /Pattern knownoget { + //false exch + { exch pop oforce patternusesoverprint { pop //true exit } if + } forall + { pop //true exit } if + } if + 2 copy //false put % Visited but not in the current chain. + pop //false exit + } loop + exch pop +} bind def + +% Check if the annotations on a page use overprint +/annotsuseoverprint { % annotsuseoverprint + //false exch % Assume no overprint + /Annots knownoget { % Get Annots array + dup type /arraytype eq { + { + oforce + dup //null ne { + /AP knownoget { % Get appearance dict for the annoation + /N knownogetdict { % Get the /N (i.e. normal) appearance stream + 4 dict exch resourceusesoverprint { pop pop //true exit } if + } if + } if % If AP dict known + } { + pop + } ifelse + } forall % For all annots on the page + } { + ( **** Error: Annotation array is not an array, ignoring it.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop + } + ifelse + } if +} bind def + % ------ Transparency support ------ % % Determine whether a page might invoke any transparency features: @@ -3162,31 +3397,37 @@ currentdict /PDF2PS_matrix_key undef } { exch pop % remove the 'on error' marker - dup //null ne { - dup /Subtype knownoget { - /Highlight eq { % Highlight annotation is always implemented - pop pop //true exit % as transparency. + dup type /dicttype eq { + dup //null ne { + dup /Subtype knownoget { + /Highlight eq { % Highlight annotation is always implemented + pop pop //true exit % as transparency. + } if } if - } if - dup /AP knownoget { % Get appearance dict for the annoation - /N knownogetdict { % Get the /N (i.e. normal) appearance stream - 4 dict exch resourceusestransparency { pop pop //true exit } if + dup /AP knownoget { % Get appearance dict for the annoation + /N knownogetdict { % Get the /N (i.e. normal) appearance stream + 4 dict exch resourceusestransparency { pop pop //true exit } if + } if + } if % If AP dict known + dup /BM knownoget { + pop pop pop //true exit } if - } if % If AP dict known - dup /BM knownoget { - pop pop pop //true exit - } if - dup /CA knownoget { - 1 le { - pop pop //true exit + dup /CA knownoget { + 1 le { + pop pop //true exit + } if } if - } if - /ca knownoget { - 1 le { - pop //true exit + /ca knownoget { + 1 le { + pop //true exit + } if } if - } if + } { + pop + } ifelse } { + ( **** Error: Annotation entry is not a dictionary, ignoring it.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror pop } ifelse } ifelse @@ -3213,21 +3454,32 @@ currentdict /PDF2PS_matrix_key undef % Thus it may include Cyan, Magenta, Yellow, and Black. % colorspacespotcolors - /colorspacespotcolors { - exch dup type /arraytype eq { + % Make sure we have an array, and that it is has enough info + exch dup type /arraytype eq + { % If we have an Indexed color space then get the base space. dup 0 oget % <<>> [csp] /Type dup /Indexed eq { pop 1 oget % <<>> [base] 2 copy exch colorspacespotcolors } { - % Stack: - dup /Separation eq exch /DeviceN eq or { - dup 1 oget dup type /arraytype eq { - { oforce 2 index putspotcolor } forall + dup /Pattern eq { + 1 index length 1 gt { % only uncolored patterns have colorspace + pop 1 oget % <<>> [base] + 2 copy exch colorspacespotcolors } { - 2 index putspotcolor + pop } ifelse - } if + } { + % Stack: + dup /Separation eq exch /DeviceN eq or { + dup 1 oget dup type /arraytype eq { + { oforce 2 index putspotcolor } forall + } { + 2 index putspotcolor + } ifelse + } if + } ifelse } ifelse } if pop pop @@ -3647,6 +3899,70 @@ currentdict /PDF2PS_matrix_key undef } if } bind executeonly def +% These functions can be used in error handling. It is not always possible to +% use the PostScript sequence 'mark ..... cleartomark' to clean up behind a +% sequence of operations, because processing the PDF might leave a mark +% object on the stack. There are a number of ways to address that problem; one +% is to count the objects on the stack at the time and store that value in a +% convenient dictionary, presented here is an alternative. Instead of using a +% mark object, we can use a specific name object as if it were a mark object +% and use the two routines below to count the number of objects on the stack +% up to a specific key, and to clear the stack back to a named key. + +% +% /key CountToKey false | int true +% +% Counts the operand stack backwards until it encounters +% a specific name key on the stack. Returns true and the count +% of objects on the stack after that key, or false if the key +% was not found on the stack. Consumes the key passed +% to CountToKey. Throws a typecheck if the operand is not +% a name type. +% +/CountToKey +{ + dup type /nametype eq { + //false + 0 1 count 5 sub + { + dup 3 add index + 3 index eq + { + 3 1 roll pop pop //true exit + } + {pop} ifelse + } for + + { + //true + } + { + pop //false + } ifelse + } + { + /CountToKey cvx /typecheck signalerror + }ifelse +}bind readonly def + +% +% /key ClearToKey - +% +% Clears the operand stack backwards until it encounters +% the name object passed as an operand. If the name object +% is not present on the stack then it will clear the entire +% stack. Like cleartomark this removes the 'key' from the stack. +% +/ClearToKey +{ + 0 1 count 4 sub + { + pop + dup 3 1 roll eq {exit} if + } for + pop +}bind readonly def + end % pdfdict diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps index 47ff512d..fe61b12d 100644 --- a/Resource/Init/pdf_ops.ps +++ b/Resource/Init/pdf_ops.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -695,10 +695,11 @@ end { % Check OP and BM in case we need to push a group //OPsaveDstack begin //Dpush exec % push the current OPsaveDstack values into 'previous' + /SupportsDevn .special_op okOPcs currentcolorspace 0 get dup /Indexed eq { pop currentcolorspace 1 get % use the base space } if - known { + known or { 1 index /stroke ne { .currentfilloverprint } { .currentstrokeoverprint } ifelse % Change BM to CompatibleOverprint if this has overprint true dup /ChangeBM exch def @@ -1478,19 +1479,8 @@ currentdict /clip_if_required .undef % width under pdfwrite. Pdfwrite uses (in text mode) an identity % CTM, so we need to calculate the stroke width which would result % if the CTM had been unity. - currentlinewidth dup - currentdict /qTextSaveMatrix known { - matrix defaultmatrix idtransform qTextSaveMatrix dtransform - }{ - matrix defaultmatrix idtransform TextSaveMatrix dtransform - } ifelse - abs 2 copy exch abs eq { - pop - }{ - % non-square scaling reduces to Text matrix in pdfwrite , so - % we can ignore it. (wrong answer, but consistent) - pop pop currentlinewidth - }ifelse setlinewidth + calc_text_linewidth + setlinewidth show setlinewidth} bind executeonly % Tr 2 - Fill then Stroke { currentlinewidth exch setsmaskstate @@ -1498,19 +1488,8 @@ currentdict /clip_if_required .undef % width under pdfwrite. Pdfwrite uses (in text mode) an identity % CTM, so we need to calculate the stroke width which would result % if the CTM had been unity. - currentlinewidth dup - currentdict /qTextSaveMatrix known { - matrix defaultmatrix idtransform qTextSaveMatrix dtransform - }{ - matrix defaultmatrix idtransform TextSaveMatrix dtransform - } ifelse - abs 2 copy exch abs eq { - pop - }{ - % non-square scaling reduces to Text matrix in pdfwrite , so - % we can ignore it. (wrong answer, but consistent) - pop pop currentlinewidth - }ifelse setlinewidth + calc_text_linewidth + setlinewidth setsmaskstate show setlinewidth} bind executeonly % Tr 3 - Neither fill nor stroke { setsmaskstate show } bind executeonly @@ -1525,38 +1504,50 @@ currentdict /clip_if_required .undef setsmaskstate dup show grestore //true charpath } bind executeonly % Tr 5 - Stroke, add to clip { gsave 1 .settextrenderingmode - currentlinewidth dup - matrix defaultmatrix idtransform TextSaveMatrix dtransform - abs 2 copy exch abs eq { - pop - }{ - % non-square scaling reduces to Text matrix in pdfwrite , so - % we can ignore it. (wrong answer, but consistent) - pop pop currentlinewidth - }ifelse setlinewidth + calc_text_linewidth + setlinewidth setsmaskstate dup show grestore //true charpath} bind executeonly % Tr 6 - Fill, stroke, add to clip { gsave 2 .settextrenderingmode - currentlinewidth dup - currentdict /qTextSaveMatrix known { - matrix defaultmatrix idtransform qTextSaveMatrix dtransform - }{ - matrix defaultmatrix idtransform TextSaveMatrix dtransform - } ifelse - abs 2 copy exch abs eq { - pop - }{ - % non-square scaling reduces to Text matrix in pdfwrite , so - % we can ignore it. (wrong answer, but consistent) - pop pop currentlinewidth - }ifelse setlinewidth + calc_text_linewidth + setlinewidth setsmaskstate dup show grestore //true charpath} bind executeonly % Tr 7 - Add to clip { //true charpath} bind executeonly ] readonly def +% - calc_text_linewidth calculated_width +% This calculates the required linewidth for stroke for *pdfwrite*, it must not be +% used for rendering. Because pdfwrite writes text scaled into a 72 dpi resolution +% we cannot use the current linewidth for it, it will be too large. Instead we must +% re-calculate the original linewidth (removing the default CTM) and then apply the +% TextSaveMatrix to find the appropriate new linewidth. +% We check to see if the x and y scaling are approximately the same, if they are not +% then we calculate a linewidth based on a right triangle with the x and y values +% of the current linewidth in each direction and then calculate the hypotenuse, which +% we then use as an approximation to the required width. +% The 'approximation' of 0.01 is just a guess. +/calc_text_linewidth +{ + currentlinewidth dup + currentdict /qTextSaveMatrix known { + matrix defaultmatrix idtransform qTextSaveMatrix dtransform + }{ + matrix defaultmatrix idtransform TextSaveMatrix dtransform + } ifelse + abs 2 copy exch abs sub abs 0.01 le { + pop + }{ + % We used to leave the linewidth alone for non-square resolutions, + % claiming it reduced to the text matrix in pdfwrite. This is not + % true. So handle it the same way we usually do, the hypotenuse of + % the unit square transformed through the TextSaveMatrix. + dup mul exch dup mul add sqrt 2 div + }ifelse +} bind executeonly def + /setstrokeforTrpreservation { % Check to see if the current device supports Tr /PreserveTrMode /GetDeviceParam .special_op { @@ -1573,15 +1564,7 @@ currentdict /clip_if_required .undef % CTM, so we need to calculate the stroke width which would result % if the CTM had been unity. NOTE! Only interested in magnitudes, % not signs. - currentlinewidth dup - matrix defaultmatrix idtransform TextSaveMatrix dtransform - abs 2 copy exch abs eq { - pop - }{ - % non-square scaling reduces to Text matrix in pdfwrite , so - % we can ignore it. (wrong answer, but consistent) - pop pop currentlinewidth - }ifelse + calc_text_linewidth setlinewidth } if } if diff --git a/Resource/Init/pdf_rbld.ps b/Resource/Init/pdf_rbld.ps index 037f10b7..6eeb6085 100644 --- a/Resource/Init/pdf_rbld.ps +++ b/Resource/Init/pdf_rbld.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -142,13 +142,28 @@ PDFfile token pop % get starting entry - or 'trailer' (trailer) ne { % if we do not already have 'trailer' PDFfile token pop % get number of entries - PDFfile token pop pop % this moves us into the middle of the first entry - 25 string exch % define working string for readline - { PDFfile 1 index readline pop pop - } repeat % skip entries - pop % pop working string - PDFfile token pop pop % get 'trailer' - PDFfile fileposition % get file position + % The following check could be more efficient + % but broken file..... + dup + PDFfile fileposition + PDFfile 0 setfileposition + PDFfile bytesavailable + exch PDFfile exch setfileposition + % On the basis it requires at least 15 bytes to define an object + % in PDF, if the claimed number of objects is more than the number + % of bytes in the file, then it is clearly bogus, and we just give up + 15 idiv + lt { + PDFfile token pop pop % this moves us into the middle of the first entry + 25 string exch % define working string for readline + { PDFfile 1 index readline pop pop + } repeat % skip entries + pop % pop working string + PDFfile token pop pop % get 'trailer' + PDFfile fileposition % get file position + } + { pop 0} + ifelse } if } { pop 0 % no xref, should not happen, report it upstrem diff --git a/Resource/Init/pdf_sec.ps b/Resource/Init/pdf_sec.ps index b6f2bfce..9e6c1c0f 100644 --- a/Resource/Init/pdf_sec.ps +++ b/Resource/Init/pdf_sec.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -481,15 +481,33 @@ systemdict /check_r6_password .forceundef % Even if StmF and StrF are Identity, if the StdCF is missing AuthEvent % or it is DocOpen, we require the password. Check for that. 1 index /CF .knownget { - /StdCF .knownget { - /AuthEvent .knownget { - /DocOpen eq - or + oforce dup type /dicttype eq { + /StdCF .knownget { + oforce dup type /dicttype eq { + /AuthEvent .knownget { + oforce dup type /nametype eq { + /DocOpen eq + or + }{ + ( **** Error: AuthEvent has wrong type.\n) pdfformaterror + ( Cannot decrypt PDF file.\n) pdfformaterror + /pdf_process_Encrypt cvx /invalidfileaccess signalerror + } ifelse + } { + pop true % no AuthEvent, default is DocOpen, require password + } ifelse + }{ + ( **** Error: StdCF has wrong type.\n) pdfformaterror + ( Cannot decrypt PDF file.\n) pdfformaterror + /pdf_process_Encrypt cvx /invalidfileaccess signalerror + } ifelse } { - pop true % no AuthEvent, default is DocOpen, require password + pop true % no StdCF, require password } ifelse - } { - pop true % no StdCF, require password + }{ + ( **** Error: CF has wrong type.\n) pdfformaterror + ( Cannot decrypt PDF file.\n) pdfformaterror + /pdf_process_Encrypt cvx /invalidfileaccess signalerror } ifelse } { pop true % no CF, require password diff --git a/Resource/SubstCID/CNS1-WMode b/Resource/SubstCID/CNS1-WMode index cc0e9bbd..9b3939fa 100644 --- a/Resource/SubstCID/CNS1-WMode +++ b/Resource/SubstCID/CNS1-WMode @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/SubstCID/GB1-WMode b/Resource/SubstCID/GB1-WMode index 22da0829..7d022f85 100644 --- a/Resource/SubstCID/GB1-WMode +++ b/Resource/SubstCID/GB1-WMode @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/SubstCID/Japan1-WMode b/Resource/SubstCID/Japan1-WMode index 9f85a86e..f2110449 100644 --- a/Resource/SubstCID/Japan1-WMode +++ b/Resource/SubstCID/Japan1-WMode @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/Resource/SubstCID/Korea1-WMode b/Resource/SubstCID/Korea1-WMode index ff59b9dc..8832bbe4 100644 --- a/Resource/SubstCID/Korea1-WMode +++ b/Resource/SubstCID/Korea1-WMode @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2020 Artifex Software, Inc. +% Copyright (C) 2001-2021 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or diff --git a/arch/arch_autoconf.h.in b/arch/arch_autoconf.h.in index 87fa50b9..457dba17 100644 --- a/arch/arch_autoconf.h.in +++ b/arch/arch_autoconf.h.in @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/arch/windows-arm-msvc.h b/arch/windows-arm-msvc.h index b347381e..3b5831f4 100644 --- a/arch/windows-arm-msvc.h +++ b/arch/windows-arm-msvc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/arch/windows-x64-msvc.h b/arch/windows-x64-msvc.h index 3be724f3..cfffda1c 100644 --- a/arch/windows-x64-msvc.h +++ b/arch/windows-x64-msvc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/arch/windows-x86-msvc.h b/arch/windows-x86-msvc.h index 76b6e806..2aa8cd0b 100644 --- a/arch/windows-x86-msvc.h +++ b/arch/windows-x86-msvc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/all-arch.mak b/base/all-arch.mak index cb9b56b5..14f36a16 100644 --- a/base/all-arch.mak +++ b/base/all-arch.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -44,7 +44,7 @@ # Usage: # make TARGETS='...' # -# or, for convenience at Utah, +# or, for convenience at Utah, # # make `hostname` # @@ -665,7 +665,7 @@ sgi-mips-irix6.1: init XINCLUDE=-I/usr/include/X11 \ XLIBDIRS='-L/usr/local/lib -L/usr/lib/X11' -# +# sgi-mips-irix6.3: init $(MAKE) $(ARGS) \ CC='cc $(SGIARCHFLAGS) -D_POSIX_4SOURCE ' \ diff --git a/base/assert_.h b/base/assert_.h index 6be404ed..878c55b1 100644 --- a/base/assert_.h +++ b/base/assert_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/bench.c b/base/bench.c index 6ff8aca9..4ea338c2 100644 --- a/base/bench.c +++ b/base/bench.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/bobbin.c b/base/bobbin.c index 63720f3e..8ab76a23 100644 --- a/base/bobbin.c +++ b/base/bobbin.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2020 Artifex Software, Inc. +/* Copyright (C) 2016-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -298,7 +298,7 @@ static int Bobbin_thread(void *thread) int i; for (i = 0; i < bobbins.num_threads; i++) - if (BOBBIN_THREAD_EQUAL(bobbins.thread[i].thread, thread) && + if (BOBBIN_THREAD_EQUAL(bobbins.thread[i].thread, thread) && (bobbins.thread[i].flags & BOBBIN_THREAD_FINISHED) == 0) break; if (i == bobbins.num_threads) diff --git a/base/bobbin.h b/base/bobbin.h index 04c6d9aa..f34578fd 100644 --- a/base/bobbin.h +++ b/base/bobbin.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2020 Artifex Software, Inc. +/* Copyright (C) 2016-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/cal.mak b/base/cal.mak index 8a718a29..606c2f2b 100644 --- a/base/cal.mak +++ b/base/cal.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2019 Artifex Software, Inc. +# Copyright (C) 2019-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -82,7 +82,7 @@ $(GLOBJ)cal.dev : $(ECHOGS_XE) $(cal_OBJS) \ $(SETMOD) $(GLOBJ)cal $(cal_OBJS) # define our specific compiler -CAL_CC=$(CC) $(CFLAGS) $(CAL_CFLAGS) $(I_)$(CAL_GEN)$(_I) $(I_)$(CAL_SRC)$(_I) +CAL_CC=$(CC) $(CCFLAGS) $(CAL_CFLAGS) $(I_)$(CAL_GEN)$(_I) $(I_)$(CAL_SRC)$(_I) CAL_O=$(O_)$(CAL_OBJ)$(CAL_PREFIX) CAL_DEP=$(AK) $(CAL_MAK) $(MAKEDIRS) diff --git a/base/claptrap-impl.h b/base/claptrap-impl.h index f758d5e0..3ebff10a 100644 --- a/base/claptrap-impl.h +++ b/base/claptrap-impl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/claptrap-init.c b/base/claptrap-init.c index 3e20d3ed..85b88a23 100644 --- a/base/claptrap-init.c +++ b/base/claptrap-init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2018 Artifex Software, Inc. +/* Copyright (C) 2015-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/claptrap-planar.c b/base/claptrap-planar.c index e77233ae..9c6358b4 100644 --- a/base/claptrap-planar.c +++ b/base/claptrap-planar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2018 Artifex Software, Inc. +/* Copyright (C) 2015-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/claptrap.c b/base/claptrap.c index 5829f09e..23a76ea6 100644 --- a/base/claptrap.c +++ b/base/claptrap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2020 Artifex Software, Inc. +/* Copyright (C) 2015-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/claptrap.h b/base/claptrap.h index 2b28c04f..c9ddf9d8 100644 --- a/base/claptrap.h +++ b/base/claptrap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2020 Artifex Software, Inc. +/* Copyright (C) 2015-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ctype_.h b/base/ctype_.h index 32e8f9a6..416c0e8b 100644 --- a/base/ctype_.h +++ b/base/ctype_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/dirent_.h b/base/dirent_.h index 6eae53d2..618e8455 100644 --- a/base/dirent_.h +++ b/base/dirent_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/dos_.h b/base/dos_.h index 29f92aa5..dff1bdb5 100644 --- a/base/dos_.h +++ b/base/dos_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/echogs.c b/base/echogs.c index b8e93d9f..2b58e754 100644 --- a/base/echogs.c +++ b/base/echogs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/errno_.h b/base/errno_.h index 5f05c616..c1b22dcb 100644 --- a/base/errno_.h +++ b/base/errno_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ets.c b/base/ets.c index 2b6a073f..f24d118f 100644 --- a/base/ets.c +++ b/base/ets.c @@ -10,7 +10,7 @@ * agreement between artofcode LLC and the licensee. Please see * http://www.artofcode.com/eventone/ for information on licensing. * - * Subsequent Changes: Copyright (C) 2013-2020 Artifex Software, Inc. + * Subsequent Changes: Copyright (C) 2013-2021 Artifex Software, Inc. * * All Rights Reserved. * @@ -844,7 +844,7 @@ ets_plane_new(void *malloc_arg, const ETS_Params *params, ETS_Ctx *etc, int plan { result->line[i].a = 1; result->line[i].b = 1; - /* Initialize error with a non zero random value to ensure dots don't + /* Initialize error with a non zero random value to ensure dots don't land on dots when we have same planes with same gray level and the plane interaction option is turned off. Ideally the level of this error should be based upon the values of the first line @@ -877,7 +877,7 @@ ets_destroy(void *malloc_arg, ETS_Ctx *ctx) { int i; int n_planes; - + if (ctx == NULL) return; diff --git a/base/ets.h b/base/ets.h index a57bef52..29530442 100644 --- a/base/ets.h +++ b/base/ets.h @@ -10,7 +10,7 @@ * agreement between artofcode LLC and the licensee. Please see * http://www.artofcode.com/eventone/ for information on licensing. * - * Subsequent Changes: Copyright (C) 2013-2020 Artifex Software, Inc. + * Subsequent Changes: Copyright (C) 2013-2021 Artifex Software, Inc. * * All Rights Reserved. * @@ -57,7 +57,7 @@ extern "C" { #define ETS_SRC_MAX 65535 #endif -/* Photoshop (and possibly other image formats define white in a CMYK image with a +/* Photoshop (and possibly other image formats define white in a CMYK image with a value of 255 (65535). This is opposite of the PAM files that Robin has created. The ETS code expects white to be at 0. Adjustments to the values in gray level will be baked into the LUT if needed */ diff --git a/base/ets_tm.h b/base/ets_tm.h index 5decb9c3..61318977 100644 --- a/base/ets_tm.h +++ b/base/ets_tm.h @@ -10,7 +10,7 @@ * agreement between artofcode LLC and the licensee. Please see * http://www.artofcode.com/eventone/ for information on licensing. * - * Subsequent Changes: Copyright (C) 2013-2020 Artifex Software, Inc. + * Subsequent Changes: Copyright (C) 2013-2021 Artifex Software, Inc. * * All Rights Reserved. * diff --git a/base/expat.mak b/base/expat.mak index 08db2a1d..43da830f 100644 --- a/base/expat.mak +++ b/base/expat.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -31,8 +31,8 @@ EXPATGEN=$(EXPATGENDIR)$(D) EXPATOBJ=$(EXPATOBJDIR)$(D) EXPATO_=$(O_)$(EXPATOBJ) -EXPATCC=$(CC) $(CFLAGS) $(I_)$(EXPATSRC)lib$(_I) \ -$(D_)XML_POOR_ENTROPY$(_D) $(EXPAT_CFLAGS) +EXPATCC=$(CC) $(I_)$(EXPATSRC)lib$(_I) \ +$(D_)XML_POOR_ENTROPY$(_D) $(EXPAT_CFLAGS) $(CCFLAGS) expat.clean : expat.config-clean expat.clean-not-config-clean diff --git a/base/fapi_bs.mak b/base/fapi_bs.mak index 894bcb82..7487ad38 100644 --- a/base/fapi_bs.mak +++ b/base/fapi_bs.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -37,11 +37,11 @@ $(GLD)fapib1.dev : $(FAPI_BS_MAK) $(ECHOGS_XE) \ $(GLOBJ)glyph.$(OBJ) $(GLOBJ)t1.$(OBJ) $(GLOBJ)t2kstrm.$(OBJ) $(GLOBJ)truetype.$(OBJ)\ $(GLOBJ)util.$(OBJ) $(GLOBJ)fnt.$(OBJ) $(GLOBJ)pclread.$(OBJ) $(GLOBJ)t2ksc.$(OBJ)\ $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ) $(MAKEDIRS) - $(SETMOD) $(GLD)fapib1 $(GLOBJ)fapibstm.$(OBJ) + $(SETMOD) $(GLD)fapib1 $(GLOBJ)fapibstm.$(OBJ) $(ADDMOD) $(GLD)fapib1 $(GLOBJ)t2k.$(OBJ) $(GLOBJ)t2kextra.$(OBJ) $(GLOBJ)fnt.$(OBJ) $(ADDMOD) $(GLD)fapib1 $(GLOBJ)tsimem.$(OBJ) $(GLOBJ)t2ktt.$(OBJ) $(GLOBJ)util.$(OBJ) $(ADDMOD) $(GLD)fapib1 $(GLOBJ)t2kstrm.$(OBJ) $(GLOBJ)truetype.$(OBJ) $(GLOBJ)cstream.$(OBJ) - $(ADDMOD) $(GLD)fapib1 $(GLOBJ)fft1hint.$(OBJ) $(GLOBJ)ghints.$(OBJ) $(GLOBJ)glyph.$(OBJ) + $(ADDMOD) $(GLD)fapib1 $(GLOBJ)fft1hint.$(OBJ) $(GLOBJ)ghints.$(OBJ) $(GLOBJ)glyph.$(OBJ) $(ADDMOD) $(GLD)fapib1 $(GLOBJ)t1.$(OBJ) $(GLOBJ)pclread.$(OBJ) $(GLOBJ)t2ksc.$(OBJ) $(ADDMOD) $(GLD)fapib1 $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ) $(ADDMOD) $(GLD)fapib1 -plugin fapibstm diff --git a/base/fapi_ft.c b/base/fapi_ft.c index 46f865ef..e4d935d9 100644 --- a/base/fapi_ft.c +++ b/base/fapi_ft.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -125,7 +125,7 @@ static void delete_inc_int_info(gs_fapi_server * a_server, FT_IncrementalRec * a_inc_int_info); -FT_CALLBACK_DEF(void *) +static void * FF_alloc(FT_Memory memory, long size) { gs_memory_t *mem = (gs_memory_t *) memory->user; @@ -133,7 +133,7 @@ FF_alloc(FT_Memory memory, long size) return (gs_malloc(mem, size, 1, "FF_alloc")); } -FT_CALLBACK_DEF(void *) +static void * FF_realloc(FT_Memory memory, long cur_size, long new_size, void *block) { gs_memory_t *mem = (gs_memory_t *) memory->user; @@ -153,7 +153,7 @@ FT_CALLBACK_DEF(void *) return (tmp); } -FT_CALLBACK_DEF(void) +static void FF_free(FT_Memory memory, void *block) { gs_memory_t *mem = (gs_memory_t *) memory->user; @@ -621,23 +621,34 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, face->ft_inc_int->object->fapi_font = a_fapi_font; /* Store the overriding metrics if they have been supplied. */ - if (face->ft_inc_int - && a_char_ref->metrics_type != gs_fapi_metrics_notdef) { + if (face->ft_inc_int && a_char_ref->metrics_type != gs_fapi_metrics_notdef) { + + FT_Incremental_MetricsRec *m = &face->ft_inc_int->object->glyph_metrics; - FT_Incremental_MetricsRec *m = - &face->ft_inc_int->object->glyph_metrics; m->bearing_x = a_char_ref->sb_x >> 16; m->bearing_y = a_char_ref->sb_y >> 16; m->advance = a_char_ref->aw_x >> 16; + face->ft_inc_int->object->glyph_metrics_index = index; - face->ft_inc_int->object->metrics_type = a_char_ref->metrics_type; - /* we only want this for fonts with TT outlines */ - if (!a_fapi_font->is_type1) { - delta.y = 0; - delta.x = FT_MulFix(a_char_ref->sb_x, ft_face->size->metrics.x_scale); - FT_Vector_Transform( &delta, &face->ft_transform); - } + /* For most font types, the original metrics come directly from the font, and + what we have here are customized (such as a Matrics dict in Postscript). We + only want to use the width, in that case, because other metrics can mess up + the hinting in Freetype. We'll apply custom lsb outselves, using the "delta" + stuff below. + The exception here is PCL/XL embedded TTF fonts, where the h/vmtx tables can + be missing, and we *have* to use the explicit metrics from the PCL/XL glyph + data. (NOTE: if those do not match the original font's metrics, again, the hinting + can be distorted) + */ + if (a_char_ref->metrics_type == gs_fapi_metrics_replace && !a_fapi_font->is_mtx_skipped) + face->ft_inc_int->object->metrics_type = gs_fapi_metrics_replace_width; + else + face->ft_inc_int->object->metrics_type = a_char_ref->metrics_type; + + delta.x = FT_MulFix(a_char_ref->sb_x >> 16, ft_face->size->metrics.x_scale); + delta.y = FT_MulFix(a_char_ref->sb_y >> 16, ft_face->size->metrics.y_scale); + FT_Vector_Transform( &delta, &face->ft_transform); } else if (face->ft_inc_int) /* Make sure we don't leave this set to the last value, as we may then use inappropriate metrics values */ @@ -699,10 +710,10 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, /* If FT gives us an error, try to fall back to the notdef - if that doesn't work, we'll throw an error over to Ghostscript */ if (ft_error) { gs_string notdef_str; - + notdef_str.data = (byte *)".notdef"; notdef_str.size = 7; - + a_fapi_font->char_data = (void *)(¬def_str); a_fapi_font->char_data_len = 0; @@ -719,7 +730,7 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, } if ((!ft_error || !ft_error_fb) && (delta.x != 0 || delta.y != 0)) { - FT_Outline_Translate( &ft_face->glyph->outline, delta.x >> 16, delta.y >> 16 ); + FT_Outline_Translate( &ft_face->glyph->outline, delta.x, delta.y); } /* Previously we interpreted the glyph unscaled, and derived the metrics from that. Now we only interpret it @@ -735,10 +746,10 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, */ hx = (FT_Long) (((double)ft_face->glyph->metrics.horiBearingX * ft_face->units_per_EM * 72.0) / - ((double)face->width * face->horz_res)); + ((double)face->width * face->horz_res)) + (a_fapi_font->is_mtx_skipped == 1 ? 0 : a_char_ref->sb_x >> 16); hy = (FT_Long) (((double)ft_face->glyph->metrics.horiBearingY * ft_face->units_per_EM * 72.0) / - ((double)face->height * face->vert_res)); + ((double)face->height * face->vert_res)) + (a_fapi_font->is_mtx_skipped == 1 ? 0 : a_char_ref->sb_y >> 16); w = (FT_Long) (((double)ft_face->glyph->metrics.width * ft_face->units_per_EM * 72.0) / ((double)face->width * @@ -1365,7 +1376,7 @@ gs_fapi_ft_get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font, */ FT_Set_Transform(face->ft_face, &face->ft_transform, NULL); - + if (!a_font->is_type1) { for (i = 0; i < GS_FAPI_NUM_TTF_CMAP_REQ && !cmap; i++) { if (a_font->ttf_cmap_req[i].platform_id > 0) { @@ -1817,7 +1828,7 @@ gs_fapi_ft_set_mm_weight_vector(gs_fapi_server *server, gs_fapi_font *ff, float setit = true; } } - + if (setit == true) { ft_error = FT_Set_MM_WeightVector(face->ft_face, length, nwv); if (ft_error != 0) return_error(gs_error_invalidaccess); diff --git a/base/fapibstm.c b/base/fapibstm.c index 0eb120c2..978dd754 100644 --- a/base/fapibstm.c +++ b/base/fapibstm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -326,7 +326,7 @@ gs_fapi_bstm_set_mm_weight_vector(gs_fapi_server *server, gs_fapi_font *ff, floa (void)ff; (void)wvector; (void)length; - + return gs_error_invalidaccess; } diff --git a/base/fapiufst.c b/base/fapiufst.c index 4089e905..628d54c0 100644 --- a/base/fapiufst.c +++ b/base/fapiufst.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1805,7 +1805,7 @@ get_char(gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, */ code = CGIFFwidth2(FSA &glyph_width_code, 1, sizeof(glyph_width), glyph_width); } - + if (code >= 0) { code = CGIFchar_handle(FSA cc, &result, (SW16) 0); } @@ -1816,7 +1816,7 @@ get_char(gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, if (code == ERR_TT_UNDEFINED_INSTRUCTION #if UFST_VERSION_MAJOR >= 6 || (code >= ERR_TT_NULL_FUNCDEF && code <= ERR_TT_STACK_OUT_OF_RANGE) -#endif +#endif ) { int savehint = FC_DONTHINTTT(fc); @@ -1861,7 +1861,7 @@ get_char(gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, code2 = CGIFchar_handle(FSA c1, &result, (SW16) 0); if (code2 && code2 != ERR_fixed_space && code2 != ERR_bm_buff && code2 != ERR_bm_too_big) { - + notdef_str.data = (byte *)space; notdef_str.size = strlen(space); ff->char_data = (void *)¬def_str; @@ -1911,7 +1911,7 @@ get_char(gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, design_bbox[1] = pbm->top_indent; design_bbox[2] = pbm->black_width; design_bbox[3] = pbm->black_depth; - + if (ff->is_vertical) { /* FIXME: this probably isn't need - we can probably just use glyph_width */ if (pIFS->glyphMetricsDU.aw.x == 0 && pIFS->glyphMetricsDU.aw.y == 0) { @@ -1958,13 +1958,13 @@ get_char(gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, design_bbox[1] = pol->bottom; design_bbox[2] = pol->right; design_bbox[3] = pol->top; - + r->char_data = (IFOUTLINE *) result; } else { design_escapement[0] = glyph_width[0]; design_escapement[1] = glyph_width[1]; - + design_bbox[0] = design_bbox[1] = design_bbox[2] = design_bbox[3] = 0; } #if 1 /* UFST 5.0 */ @@ -2224,7 +2224,7 @@ gs_fapi_ufst_set_mm_weight_vector(gs_fapi_server *server, gs_fapi_font *ff, floa (void)ff; (void)wvector; (void)length; - + return gs_error_invalidaccess; } diff --git a/base/fcntl_.h b/base/fcntl_.h index fc2cdb46..aa2ed334 100644 --- a/base/fcntl_.h +++ b/base/fcntl_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/freetype.mak b/base/freetype.mak index ec85b5ce..41a6a949 100644 --- a/base/freetype.mak +++ b/base/freetype.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -22,6 +22,7 @@ # FT_CFLAGS - The include options for the freetype library # SHARE_FT - 0 to compile in freetype, 1 to link a shared library # FT_LIBS - if SHARE_FT=1, the link options for the shared library +# FT_LIB_PATH - if SHARE_FT=1, the path(s) for the shared library # (Rename directories.) FTSRC=$(FTSRCDIR)$(D)src$(D) @@ -33,7 +34,9 @@ FTO_=$(O_)$(FTOBJ) # we must define FT2_BUILD_LIBRARY to get internal declarations # If GS is using the system zlib, freetype should also do so, # FT_CONFIG_SYSTEM_ZLIB is set by the top makefile. -FTCC=$(CC_) $(I_)$(FTGEN)$(_I) $(I_)$(FTSRCDIR)$(D)include$(_I) $(D_)FT_CONFIG_OPTIONS_H=\"$(FTCONFH)\"$(_D) $(D_)FT2_BUILD_LIBRARY$(_D) $(D_)DARWIN_NO_CARBON$(_D) $(FT_CONFIG_SYSTEM_ZLIB) +FTCC=$(CC) $(I_)$(FTGEN)$(_I) $(I_)$(FTSRCDIR)$(D)include$(_I) \ + $(D_)FT_CONFIG_OPTIONS_H=\"$(FTCONFH)\"$(_D) $(D_)FT2_BUILD_LIBRARY$(_D) \ + $(D_)DARWIN_NO_CARBON$(_D) $(FT_CONFIG_SYSTEM_ZLIB) $(CCFLAGS) # Define the name of this makefile. FT_MAK=$(GLSRC)freetype.mak $(TOP_MAKEFILES) @@ -213,7 +216,8 @@ $(FTGEN)freetype.dev : $(FTGEN)freetype_$(SHARE_FT).dev $(FT_MAK) $(GENFTCONFH) # Define the shared version. $(FTGEN)freetype_1.dev : $(TOP_MAKEFILES) $(FT_MAK) $(ECHOGS_XE) $(FT_MAK) $(GENFTCONFH) $(MAKEDIRS) - $(SETMOD) $(FTGEN)freetype_1 -link $(FT_LIBS) + $(SETMOD) $(FTGEN)freetype_1 -lib $(FT_LIBS) + $(ADDMOD) $(FTGEN)freetype_1 -libpath $(FT_LIB_PATH) # Define the non-shared version. $(FTGEN)freetype_0.dev : $(FT_MAK) $(ECHOGS_XE) \ diff --git a/base/gconf.c b/base/gconf.c index 68aecb75..38e0f258 100644 --- a/base/gconf.c +++ b/base/gconf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gconf.h b/base/gconf.h index 1dcfa6c2..cc42ba3a 100644 --- a/base/gconf.h +++ b/base/gconf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdbflags.h b/base/gdbflags.h index c7d3fe91..073ca73f 100644 --- a/base/gdbflags.h +++ b/base/gdbflags.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdebug.h b/base/gdebug.h index 8fa4cca0..8d663331 100644 --- a/base/gdebug.h +++ b/base/gdebug.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevabuf.c b/base/gdevabuf.c index e937299d..1f7c3902 100644 --- a/base/gdevabuf.c +++ b/base/gdevabuf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevbbox.c b/base/gdevbbox.c index 20f80d3a..542124a9 100644 --- a/base/gdevbbox.c +++ b/base/gdevbbox.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -497,7 +497,7 @@ bbox_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, static int bbox_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, - int x, int y, int w, int h, const gx_drawing_color *pdcolor0, + int x, int y, int w, int h, const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int px, int py) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; @@ -1245,7 +1245,7 @@ bbox_create_compositor(gx_device * dev, (target, &temp_cdev, pcte, pgs, memory, cindev); /* If the target did not create a new compositor then we are done. */ - if (code < 0 || target == temp_cdev) { + if (code <= 0) { *pcdev = dev; return code; } @@ -1261,7 +1261,9 @@ bbox_create_compositor(gx_device * dev, bbcdev->box_procs = box_procs_forward; bbcdev->box_proc_data = bdev; *pcdev = (gx_device *) bbcdev; - return 0; + /* We return 1 to indicate that a new compositor was created + * that wrapped dev. */ + return 1; } } diff --git a/base/gdevbbox.h b/base/gdevbbox.h index 1abf2cf4..8cf89959 100644 --- a/base/gdevbbox.h +++ b/base/gdevbbox.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdbit.c b/base/gdevdbit.c index fb9ff800..aba17446 100644 --- a/base/gdevdbit.c +++ b/base/gdevdbit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -169,16 +169,16 @@ gx_no_copy_alpha(gx_device * dev, const byte * data, int data_x, /* Currently we really should only be here if the target device is planar AND it supports devn colors AND is 8 or 16 bit. For example tiffsep - and psdcmyk may make use of this if AA is enabled. It is basically - designed for devices that need more than 64 bits for color support + and psdcmyk may make use of this if AA is enabled. It is basically + designed for devices that need more than 64 bits for color support - So that I can follow things and make it readable for future generations, + So that I can follow things and make it readable for future generations, I am not using the macro nightmare that default_copy_alpha uses. */ int gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, const gx_drawing_color *pdcolor, int depth) -{ +{ const byte *row_alpha; gs_memory_t *mem = dev->memory; int bpp = dev->color_info.depth; @@ -223,7 +223,7 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, | GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD - | GB_SELECT_PLANES; + | GB_SELECT_PLANES; gb_rect.p.x = x; gb_rect.q.x = x + width; for (ry = y; ry < y + height; row_alpha += raster, ++ry) { @@ -234,13 +234,13 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, for (k = 0; k < ncomps; k++) { /* First set the params to zero for all planes except the one we want */ /* I am not sure why get_bits_rectangle for the planar device can - not hand back the data in a proper planar form. To get the + not hand back the data in a proper planar form. To get the individual planes seems that I need to jump through some hoops here */ - for (j = 0; j < ncomps; j++) + for (j = 0; j < ncomps; j++) gb_params.data[j] = 0; gb_params.data[k] = gb_buff + k * out_raster; - code = dev_proc(dev, get_bits_rectangle) (dev, &gb_rect, + code = dev_proc(dev, get_bits_rectangle) (dev, &gb_rect, &gb_params, 0); src_planes[k] = gb_params.data[k]; if (code < 0) { @@ -248,7 +248,7 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, return code; } } - /* At this point we have to carry around some additional variables + /* At this point we have to carry around some additional variables so that we can handle any buffer flushes due to alpha == 0 values. See below why this is needed */ x_curr = x; @@ -276,14 +276,14 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, if (alpha == 0) { /* With alpha 0 we want to avoid writing out this value. - * While it is true that writting it out leaves the color - * unchanged, any device that's watching what pixels are - * written (such as the pattern tile devices) may have problems. - * As in gx_default_copy_alpha the right thing to do is to write - * out what we have so far and then continue to collect when we + * While it is true that writting it out leaves the color + * unchanged, any device that's watching what pixels are + * written (such as the pattern tile devices) may have problems. + * As in gx_default_copy_alpha the right thing to do is to write + * out what we have so far and then continue to collect when we * get back to non zero alpha. */ - code = dev_proc(dev, copy_planes)(dev, &(gb_buff[gb_buff_start]), - 0, out_raster, gs_no_bitmap_id, + code = dev_proc(dev, copy_planes)(dev, &(gb_buff[gb_buff_start]), + 0, out_raster, gs_no_bitmap_id, x_curr, ry, w_curr-1, 1, 1); if (code < 0) { gs_free_object(mem, gb_buff, "copy_alpha_hl_color"); @@ -303,7 +303,7 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, /* First get the old color */ for (k = 0; k < ncomps; k++) { /* We only have 8 and 16 bit depth to worry about. - However, this stuff should really be done with + However, this stuff should really be done with the device encode/decode procedure. */ byte *ptr = ((src_planes[k]) + (sx - data_x) * word_width); curr_cv[k] = 0; @@ -316,13 +316,13 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, curr_cv[k] += *ptr; curr_cv[k] += curr_cv[k] << 8; } - /* Now compute the new color which is a blend of + /* Now compute the new color which is a blend of the old and the new */ blend_cv[k] = ((curr_cv[k]<<8) + (((long) src_cv[k] - (long) curr_cv[k]) * alpha))>>8; composite = &(blend_cv[0]); } - } + } /* Update our plane data buffers. Just reuse the current one */ for (k = 0; k < ncomps; k++) { byte *ptr = ((src_planes[k]) + (sx - data_x) * word_width); @@ -335,10 +335,10 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, } } /* else on alpha != 0 */ } /* loop on x */ - /* Flush what ever we have left. We may only have a partial due to + /* Flush what ever we have left. We may only have a partial due to the presence of alpha = 0 values */ - code = dev_proc(dev, copy_planes)(dev, &(gb_buff[gb_buff_start]), - 0, out_raster, gs_no_bitmap_id, + code = dev_proc(dev, copy_planes)(dev, &(gb_buff[gb_buff_start]), + 0, out_raster, gs_no_bitmap_id, x_curr, ry, w_curr, 1, 1); } /* loop on y */ gs_free_object(mem, gb_buff, "copy_alpha_hl_color"); @@ -596,15 +596,15 @@ gx_default_fill_mask(gx_device * orig_dev, } /* Default implementation of strip_tile_rect_devn. With the current design - only devices that support devn color will be making use of this + only devices that support devn color will be making use of this procedure and those are planar devices. So we have an implemenation for planar devices and not a default implemenetation at this time. */ int gx_default_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, - int x, int y, int w, int h, const gx_drawing_color * pdcolor0, + int x, int y, int w, int h, const gx_drawing_color * pdcolor0, const gx_drawing_color * pdcolor1, int px, int py) { - return_error(gs_error_unregistered); + return_error(gs_error_unregistered); } /* Default implementation of strip_tile_rectangle */ diff --git a/base/gdevdcrd.c b/base/gdevdcrd.c index 299afc52..6086459f 100644 --- a/base/gdevdcrd.c +++ b/base/gdevdcrd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdcrd.h b/base/gdevdcrd.h index 7ef729a2..fe387d72 100644 --- a/base/gdevdcrd.h +++ b/base/gdevdcrd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevddrw.c b/base/gdevddrw.c index 19089b88..4f91a02d 100644 --- a/base/gdevddrw.c +++ b/base/gdevddrw.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevddrw.h b/base/gdevddrw.h index dcf4468a..dc49513f 100644 --- a/base/gdevddrw.h +++ b/base/gdevddrw.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdevn.c b/base/gdevdevn.c index 4cbf11b5..692edf76 100644 --- a/base/gdevdevn.c +++ b/base/gdevdevn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdevn.h b/base/gdevdevn.h index fea7c3d7..fb34e1c0 100644 --- a/base/gdevdevn.h +++ b/base/gdevdevn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdevnprn.h b/base/gdevdevnprn.h index 6c3020e6..4d556b60 100644 --- a/base/gdevdevnprn.h +++ b/base/gdevdevnprn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdflt.c b/base/gdevdflt.c index 1d949080..4f92c7a2 100644 --- a/base/gdevdflt.c +++ b/base/gdevdflt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -843,7 +843,7 @@ gx_upright_get_initial_matrix(gx_device * dev, register gs_matrix * pmat) } int -gx_default_sync_output(gx_device * dev) +gx_default_sync_output(gx_device * dev) /* lgtm [cpp/useless-expression] */ { return 0; } @@ -1431,6 +1431,8 @@ int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, uns rc_increment(dev_to_subclass->icc_struct); if (dev_to_subclass->PageList) rc_increment(dev_to_subclass->PageList); + if (dev_to_subclass->NupControl) + rc_increment(dev_to_subclass->NupControl); /* In case the new device we're creating has already been initialised, copy * its additional data. @@ -1561,6 +1563,8 @@ int gx_device_unsubclass(gx_device *dev) rc_decrement(child->icc_struct, "gx_unsubclass_device, icc_struct"); if (child->PageList) rc_decrement(child->PageList, "gx_unsubclass_device, PageList"); + if (child->NupControl) + rc_decrement(child->NupControl, "gx_unsubclass_device, NupControl"); /* we cannot afford to free the child device if its stype is not dynamic because * we can't 'null' the finalise routine, and we cannot permit the device to be finalised * because we have copied it up one level, not discarded it. @@ -1692,6 +1696,10 @@ int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_co p14dev->target = subclass_device; + /* We return 0, rather than 1, as we have not created + * a new compositor that wraps dev. */ + if (code == 1) + code = 0; return code; } break; diff --git a/base/gdevdgbr.c b/base/gdevdgbr.c index 164124d7..d7b34b77 100644 --- a/base/gdevdgbr.c +++ b/base/gdevdgbr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdrop.c b/base/gdevdrop.c index b22823a9..9186eea1 100644 --- a/base/gdevdrop.c +++ b/base/gdevdrop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevdsha.c b/base/gdevdsha.c index 2111974d..646fd9bd 100644 --- a/base/gdevdsha.c +++ b/base/gdevdsha.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -111,6 +111,11 @@ gx_hl_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, for (k = 0; k < n; k++) { devc.colors.devn.values[k] = frac312cv(curr[k]); } + if (device_encodes_tags(dev)) { + devc.tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + } else { + devc.tag = 0; + } code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL); if (code < 0) return code; @@ -174,6 +179,11 @@ gx_hl_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, for (k = 0; k < n; k++) { devc.colors.devn.values[k] = frac312cv(curr[k]); } + if (device_encodes_tags(dev)) { + devc.tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + } else { + devc.tag = 0; + } return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL); } return 0; diff --git a/base/gdevemap.c b/base/gdevemap.c index b307fb78..db2636ee 100644 --- a/base/gdevemap.c +++ b/base/gdevemap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevepo.c b/base/gdevepo.c index e3454273..7c9eb0b7 100644 --- a/base/gdevepo.c +++ b/base/gdevepo.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -193,16 +193,23 @@ gx_device_epo gs_epo_device = #undef MAX_COORD #undef MAX_RESOLUTION -static bool -is_device_installed(gx_device *dev, const char *name) +/* Starting at the top of the device chain (top parent) find */ +/* and return the epo device, or NULL if not found. */ +static gx_device * +find_installed_epo_device(gx_device *dev) { - while (dev) { - if (!strcmp(dev->dname, name)) { - return true; + gx_device *next_dev = dev; + + while (next_dev->parent != NULL) + next_dev = next_dev->parent; + + while (next_dev) { + if (next_dev->procs.fillpage == epo_fillpage) { + return next_dev; } - dev = dev->child; + next_dev = next_dev->child; } - return false; + return NULL; } /* See if this is a device we can optimize @@ -212,7 +219,12 @@ is_device_installed(gx_device *dev, const char *name) static bool device_wants_optimization(gx_device *dev) { - return (!gs_is_null_device(dev) && dev_proc(dev, fillpage) == gx_default_fillpage); + gx_device *terminal = dev; + + while(terminal->child != NULL) + terminal = terminal->child; + + return (!gs_is_null_device(terminal) && dev_proc(terminal, fillpage) == gx_default_fillpage); } /* Use this when debugging to enable/disable epo @@ -228,33 +240,31 @@ int epo_check_and_install(gx_device *dev) { int code = 0; - bool is_installed; + gx_device *installed_epo_device = NULL; bool can_optimize = false; - + /* Debugging mode to totally disable this */ if (gs_debug_c(gs_debug_flag_epo_disable)) { return code; } - + DPRINTF1(dev->memory, "current device is %s\n", dev->dname); - is_installed = is_device_installed(dev, EPO_DEVICENAME); - - if (is_installed) { + installed_epo_device = find_installed_epo_device(dev); + + if (installed_epo_device != NULL) { DPRINTF1(dev->memory, "device %s already installed\n", EPO_DEVICENAME); /* This is looking for the case where the device * changed into something we can't optimize, after it was already installed * (could be clist or some other weird thing) */ - if (dev->child) { - can_optimize = device_wants_optimization(dev->child); + if (installed_epo_device->child) { + can_optimize = device_wants_optimization(installed_epo_device->child); } if (!can_optimize) { - DPRINTF1(dev->memory, "child %s can't be optimized, uninstalling\n", dev->child->dname); - /* Not doing any pending fillpages because we are about to do - * a fillpage anyway - */ - gx_device_unsubclass(dev); + DPRINTF1(dev->memory, "child %s can't be optimized, uninstalling\n", installed_epo_device->child->dname); + /* Not doing any pending fillpages because we are about to do a fillpage anyway */ + gx_device_unsubclass(installed_epo_device); return code; } } else { @@ -262,7 +272,7 @@ epo_check_and_install(gx_device *dev) } /* Already installed, nothing to do */ - if (is_installed) { + if (installed_epo_device != NULL) { return code; } @@ -278,7 +288,7 @@ epo_check_and_install(gx_device *dev) DPRINTF1(dev->memory, "ERROR installing device %s\n", EPO_DEVICENAME); return code; } - + DPRINTF1(dev->memory, "SUCCESS installed device %s\n", dev->dname); return code; } @@ -288,7 +298,7 @@ epo_handle_erase_page(gx_device *dev) { erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; int code = 0; - + if (gs_debug_c(gs_debug_flag_epo_install_only)) { gx_device_unsubclass(dev); DPRINTF1(dev->memory, "Uninstall erasepage, device=%s\n", dev->dname); @@ -314,7 +324,7 @@ epo_handle_erase_page(gx_device *dev) int epo_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) { erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; - + if (gs_debug_c(gs_debug_flag_epo_install_only)) { return default_subclass_fillpage(dev, pgs, pdevc); } @@ -322,13 +332,13 @@ int epo_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) /* If color is not pure, don't defer this, uninstall and do it now */ if (!color_is_pure(pdevc)) { DPRINTF(dev->memory, "epo_fillpage(), color is not pure, uninstalling\n"); - gx_device_unsubclass(dev); + gx_device_unsubclass(dev); return dev_proc(dev, fillpage)(dev, pgs, pdevc); } - + /* Save the color being requested, and swallow the fillpage */ data->last_color = pdevc->colors.pure; - + DPRINTF(dev->memory, "Swallowing fillpage\n"); return 0; } diff --git a/base/gdevepo.h b/base/gdevepo.h index 68f47686..029a54ad 100644 --- a/base/gdevepo.h +++ b/base/gdevepo.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevflp.c b/base/gdevflp.c index 7b02bc35..20757bbe 100644 --- a/base/gdevflp.c +++ b/base/gdevflp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -221,7 +221,7 @@ gx_device_flp gs_flp_device = static int ParsePageList(gx_device *dev, first_last_subclass_data *psubclass_data, char *PageList) { char *str, *oldstr, *workstr, c, *ArgCopy; - int LastPage, Page, byte, bit, i; + int LastPage, Page, byte, bit, i, prev_page = -1; psubclass_data->ProcessedPageList = true; if (strcmp(PageList, "even") == 0) { @@ -309,6 +309,13 @@ static int ParsePageList(gx_device *dev, first_last_subclass_data *psubclass_dat if (LastPage < 0) LastPage = 0; + if (LastPage < Page || Page <= prev_page) { + /* Strictly monotonic increasing required */ + emprintf(dev->memory, "\n**** Error : rangecheck processing PageList\n"); + return_error(gs_error_rangecheck); + } + prev_page = LastPage; + for (i=Page; i<= LastPage;i++) { if (i > psubclass_data->LastListPage - 1) { emprintf(dev->memory, "\n**** Error : rangecheck processing PageList\n"); @@ -323,10 +330,13 @@ static int ParsePageList(gx_device *dev, first_last_subclass_data *psubclass_dat Page = atoi(oldstr) - 1; if (Page < 0) Page = 0; - if (Page > psubclass_data->LastListPage - 1) { + if (Page <= prev_page || Page > psubclass_data->LastListPage - 1) { + /* Strictly monotonic increasing required */ emprintf(dev->memory, "\n**** Error : rangecheck processing PageList\n"); return_error(gs_error_rangecheck); } + prev_page = Page; + byte = (int)(Page / 8); bit = Page % 8; c = 0x01 << bit; @@ -519,7 +529,7 @@ int flp_put_params(gx_device * dev, gs_param_list * plist) { bool temp_bool = false; - int code, ecode; + int code, ecode = 0; gs_param_string pagelist; code = param_read_int(plist, "FirstPage", &dev->FirstPage); @@ -875,6 +885,7 @@ flp_image_plane_data(gx_image_enum_common_t * info, static int flp_image_end_image(gx_image_enum_common_t * info, bool draw_last) { + gs_free_object(info->memory, info, "flp_end_image"); return 0; } diff --git a/base/gdevflp.h b/base/gdevflp.h index ba38f1c1..453f401a 100644 --- a/base/gdevflp.h +++ b/base/gdevflp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevhit.c b/base/gdevhit.c index 769e8d3a..0a804b4c 100644 --- a/base/gdevhit.c +++ b/base/gdevhit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevkrnlsclass.c b/base/gdevkrnlsclass.c index 8625df4c..d615a100 100644 --- a/base/gdevkrnlsclass.c +++ b/base/gdevkrnlsclass.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -15,11 +15,12 @@ #include "gx.h" #include "gxdcolor.h" -#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and object filter */ +#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently Page, Object, and Nup filter */ /* If set to '1' ths forces all devices to be loaded, even if they won't do anything. * This is useful for cluster testing that the very presence of a device doesn't - * break anything. + * break anything. This requires that all of these devices pass through if the params + * they use are 0/NULL. */ #define FORCE_TESTING_SUBCLASSING 0 @@ -28,6 +29,44 @@ int install_internal_subclass_devices(gx_device **ppdev, int *devices_loaded) int code = 0; gx_device *dev = (gx_device *)*ppdev, *saved; + /* + * NOTE: the Nup device should precede the PageHandler so the FirstPage, LastPage + * and PageList will filter pages out BEFORE they are seen by the nesting. + */ + +#if FORCE_TESTING_SUBCLASSING + if (!dev->NupHandlerPushed) { +#else + if (!dev->NupHandlerPushed && dev->NupControl != 0) { +#endif + code = gx_device_subclass(dev, (gx_device *)&gs_nup_device, sizeof(Nup_device_subclass_data)); + if (code < 0) + return code; + + saved = dev = dev->child; + + /* Open all devices *after* the new current device */ + do { + dev->is_open = true; + dev = dev->child; + }while(dev); + + dev = saved; + + /* Rewind to top device in chain */ + while(dev->parent) + dev = dev->parent; + + /* Note in all devices in chain that we have loaded the NupHandler */ + do { + dev->NupHandlerPushed = true; + dev = dev->child; + }while(dev); + + dev = saved; + if (devices_loaded) + *devices_loaded = true; + } #if FORCE_TESTING_SUBCLASSING if (!dev->PageHandlerPushed) { #else diff --git a/base/gdevkrnlsclass.h b/base/gdevkrnlsclass.h index b73ce3c2..e9f0a0b4 100644 --- a/base/gdevkrnlsclass.h +++ b/base/gdevkrnlsclass.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -19,6 +19,7 @@ #ifndef gdev_subclass_dev_INCLUDED # define gdev_subclass_dev_INCLUDED +#include "gdevnup.h" #include "gdevflp.h" #include "gdevoflt.h" @@ -26,6 +27,8 @@ extern gx_device_obj_filter gs_obj_filter_device; extern gx_device_flp gs_flp_device; +extern gx_device_nup gs_nup_device; + int install_internal_subclass_devices(gx_device **ppdev, int *devices_loaded); #endif /* gdev_subclass_dev_INCLUDED */ diff --git a/base/gdevm1.c b/base/gdevm1.c index 299cf65d..7801c3a6 100644 --- a/base/gdevm1.c +++ b/base/gdevm1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm16.c b/base/gdevm16.c index f20b4461..f4d662eb 100644 --- a/base/gdevm16.c +++ b/base/gdevm16.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm2.c b/base/gdevm2.c index 3443ac2a..863811b8 100644 --- a/base/gdevm2.c +++ b/base/gdevm2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm24.c b/base/gdevm24.c index 5cea72f8..332279b6 100644 --- a/base/gdevm24.c +++ b/base/gdevm24.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm32.c b/base/gdevm32.c index 0e5e7f15..414831c1 100644 --- a/base/gdevm32.c +++ b/base/gdevm32.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm4.c b/base/gdevm4.c index dadb4755..51940a5b 100644 --- a/base/gdevm4.c +++ b/base/gdevm4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm40.c b/base/gdevm40.c index e2e9ef7d..0946a033 100644 --- a/base/gdevm40.c +++ b/base/gdevm40.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm48.c b/base/gdevm48.c index 987a6390..d951ccfa 100644 --- a/base/gdevm48.c +++ b/base/gdevm48.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm56.c b/base/gdevm56.c index 2efbaf9b..72774fb9 100644 --- a/base/gdevm56.c +++ b/base/gdevm56.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm64.c b/base/gdevm64.c index 8c3be0d1..899713ef 100644 --- a/base/gdevm64.c +++ b/base/gdevm64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevm8.c b/base/gdevm8.c index 55f956b3..65013507 100644 --- a/base/gdevm8.c +++ b/base/gdevm8.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmem.c b/base/gdevmem.c index 95da5d6c..68e7e857 100644 --- a/base/gdevmem.c +++ b/base/gdevmem.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -338,14 +338,18 @@ gdev_mem_mono_set_inverted(gx_device_memory * dev, bool black_is_1) int gdev_mem_bits_size(const gx_device_memory * dev, int width, int height, ulong *psize) { - int num_planes = dev->is_planar ? dev->color_info.num_components : 0; + int num_planes; gx_render_plane_t plane1; const gx_render_plane_t *planes; ulong size; int pi; - if (num_planes) + if (dev->is_planar) + { + int has_tags = device_encodes_tags((const gx_device *)dev); + num_planes = dev->color_info.num_components + has_tags; planes = dev->planes; + } else planes = &plane1, plane1.depth = dev->color_info.depth, num_planes = 1; for (size = 0, pi = 0; pi < num_planes; ++pi) @@ -362,7 +366,11 @@ gdev_mem_bits_size(const gx_device_memory * dev, int width, int height, ulong *p ulong gdev_mem_line_ptrs_size(const gx_device_memory * dev, int width, int height) { - return (ulong)height * sizeof(byte *) * (dev->is_planar ? dev->color_info.num_components : 1); + int has_tags = device_encodes_tags((const gx_device *)dev); + int num_planes = 1; + if (dev->is_planar) + num_planes = dev->color_info.num_components + has_tags; + return (ulong)height * sizeof(byte *) * num_planes; } int gdev_mem_data_size(const gx_device_memory * dev, int width, int height, ulong *psize) diff --git a/base/gdevmem.h b/base/gdevmem.h index 15759322..71db0797 100644 --- a/base/gdevmem.h +++ b/base/gdevmem.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmpla.c b/base/gdevmpla.c index d889efcf..d233a132 100644 --- a/base/gdevmpla.c +++ b/base/gdevmpla.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmpla.h b/base/gdevmpla.h index 1b424098..1d0f5f98 100644 --- a/base/gdevmpla.h +++ b/base/gdevmpla.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmplt.c b/base/gdevmplt.c index 520b22cf..89720535 100644 --- a/base/gdevmplt.c +++ b/base/gdevmplt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmplt.h b/base/gdevmplt.h index 4b1b44cd..669efdc7 100644 --- a/base/gdevmplt.h +++ b/base/gdevmplt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmr1.c b/base/gdevmr1.c index 2911f4f3..ed2faab9 100644 --- a/base/gdevmr1.c +++ b/base/gdevmr1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -78,7 +78,7 @@ mem_mono_strip_copy_rop(gx_device * dev, const byte * sdata, */ if (invert) - rop = byte_reverse_bits[rop] ^ 0xff; + rop = byte_reverse_bits[rop & 0xff] ^ 0xff; return mem_mono_strip_copy_rop_dev(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, diff --git a/base/gdevmr2n.c b/base/gdevmr2n.c index 228f29dd..a19b9f69 100644 --- a/base/gdevmr2n.c +++ b/base/gdevmr2n.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmr8n.c b/base/gdevmr8n.c index 055e79cc..e90bb151 100644 --- a/base/gdevmr8n.c +++ b/base/gdevmr8n.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -352,6 +352,7 @@ df: return mem_default_strip_copy_rop(dev, int ty = y + phase_y; rop_set_s_constant(&ropper, const_source); + rop_set_t_colors(&ropper, tcolors); if (rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_1bit)) { for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ int dx = x, w = width, nw; diff --git a/base/gdevmrop.h b/base/gdevmrop.h index 6caebdf6..87e4e557 100644 --- a/base/gdevmrop.h +++ b/base/gdevmrop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmrun.c b/base/gdevmrun.c index df1667e2..fa16ffbc 100644 --- a/base/gdevmrun.c +++ b/base/gdevmrun.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -117,14 +117,12 @@ rp_delete_next(run_ptr *prpc, run *data, run_line *line) RP_PREV(rpn) = 0; line->free = rpn.index; } -static int -rp_insert_next(run_ptr *prpc, run *data, run_line *line, run_ptr *prpn) +static void +rp_insert_next_cant_fail(run_ptr *prpc, run *data, run_line *line, run_ptr *prpn) { run_index new = line->free; run *prnew = data + new; - if (new == 0) - return -1; RP_TO_NEXT(*prpc, data, *prpn); RP_NEXT(*prpc) = new; RP_PREV(*prpn) = new; @@ -133,6 +131,13 @@ rp_insert_next(run_ptr *prpc, run *data, run_line *line, run_ptr *prpn) prnew->next = prpn->index; prpn->index = new; prpn->ptr = prnew; +} +static int +rp_insert_next(run_ptr *prpc, run *data, run_line *line, run_ptr *prpn) +{ + if (line->free == 0) + return -1; + rp_insert_next_cant_fail(prpc, data, line, prpn); return 0; } static int @@ -524,6 +529,7 @@ run_fill_interval(run_line *line, int xo, int xe, run_value new) ) RP_LENGTH(rp0) += left; else { + run_ptr rpn = {0}; /* * If we need more than one run, we divide up the length to * create more runs with length less than MAX_RUN_LENGTH in @@ -542,14 +548,13 @@ run_fill_interval(run_line *line, int xo, int xe, run_value new) len = (left + pieces - 1) / pieces; } do { - run_ptr rpn; /* * The allocation in rp_insert_next can't fail, because * we just deleted at least as many runs as we're going * to insert. */ - rp_insert_next(&rp0, data, line, &rpn); + rp_insert_next_cant_fail(&rp0, data, line, &rpn); RP_LENGTH(rpn) = min(left, len); RP_VALUE(rpn) = new; } diff --git a/base/gdevmrun.h b/base/gdevmrun.h index b9cf0e54..15ee2f79 100644 --- a/base/gdevmrun.h +++ b/base/gdevmrun.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevmx.c b/base/gdevmx.c index ee8c6396..fa2287cc 100644 --- a/base/gdevmx.c +++ b/base/gdevmx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevnfwd.c b/base/gdevnfwd.c index b81ff0e1..a6c69e44 100644 --- a/base/gdevnfwd.c +++ b/base/gdevnfwd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -865,6 +865,11 @@ gx_forward_dev_spec_op(gx_device * dev, int dev_spec_op, void *data, int size) d->target = fdev->target; return 1; } + } else if (dev_spec_op == gxdso_device_insert_child) { + fdev->target = (gx_device *)data; + rc_increment(fdev->target); + rc_decrement_only(tdev, "gx_forward_device"); + return 0; } return dev_proc(tdev, dev_spec_op)(tdev, dev_spec_op, data, size); } @@ -1009,6 +1014,12 @@ gx_forward_create_compositor(gx_device * dev, gx_device ** pcdev, code = dev_proc(tdev, create_compositor)(tdev, pcdev, pcte, pgs, memory, cdev); /* the compositor may have changed color_info. Pick up the new value */ dev->color_info = tdev->color_info; + if (code == 1) { + /* If a new compositor was made that wrapped tdev, then that + * compositor should be our target now. */ + gx_device_set_target((gx_device_forward *)dev, *pcdev); + code = 0; /* We have not made a new compositor that wrapped dev. */ + } return code; } diff --git a/base/gdevnup.c b/base/gdevnup.c new file mode 100644 index 00000000..e1d79d1c --- /dev/null +++ b/base/gdevnup.c @@ -0,0 +1,593 @@ +/* Copyright (C) 2001-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Device to implement N-up printing */ +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gpmisc.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gsdevice.h" /* requires gsmatrix.h */ +#include "gxiparam.h" /* for image source size */ +#include "gxgstate.h" +#include "gxpaint.h" +#include "gxpath.h" +#include "gxcpath.h" +#include "gsstype.h" +#include "gdevprn.h" +#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ +#include "gdevsclass.h" +#include "gxdevsop.h" +#include "gdevnup.h" + +/* GC descriptor */ +#define public_st_nup_device() /* in gsdevice.c */\ + gs_public_st_complex_only(st_nup_device, gx_device, "Nup Device",\ + 0, nup_device_enum_ptrs, nup_device_reloc_ptrs, default_subclass_finalize) + +static +ENUM_PTRS_WITH(nup_device_enum_ptrs, gx_device *dev); +return 0; /* default case */ +case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); +case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); +ENUM_PTRS_END +static RELOC_PTRS_WITH(nup_device_reloc_ptrs, gx_device *dev) +{ + dev->parent = gx_device_reloc_ptr(dev->parent, gcst); + dev->child = gx_device_reloc_ptr(dev->child, gcst); +} +RELOC_PTRS_END + +public_st_nup_device(); + + +/**************************************************************************************/ +/* Externals not in headers */ +/* Imported from gsdparam.c */ +extern void rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname); +/**************************************************************************************/ + +/* This device is one of the 'subclassing' devices, part of a chain or pipeline + * of devices, each of which can process some aspect of the graphics methods + * before passing them on to the next device in the chain. + * + * This operates by hooking the device procs: + * get_initial_matrix To modify the scale and origin of the sub-page + * fillpage To prevent erasing previously imaged sub-pages + * output_page To ignore all output_page calls until all sub-pages + * have been imaged + * close_device To output the final (partial) collection of sub-pages + */ + +/* Device procedures */ +static dev_proc_get_initial_matrix(nup_get_initial_matrix); +static dev_proc_close_device(nup_close_device); +static dev_proc_put_params(nup_put_params); +static dev_proc_output_page(nup_output_page); +static dev_proc_fillpage(nup_fillpage); +static dev_proc_dev_spec_op(nup_dev_spec_op); + +/* The device prototype */ + +#define MAX_COORD (max_int_in_fixed - 1000) +#define MAX_RESOLUTION 4000 + +const +gx_device_nup gs_nup_device = +{ + /* + * Define the device as 8-bit gray scale to avoid computing halftones. + */ + std_device_dci_type_body(gx_device_nup, 0, "N-up", &st_nup_device, + MAX_COORD, MAX_COORD, + MAX_RESOLUTION, MAX_RESOLUTION, + 1, 8, 255, 0, 256, 1), + {default_subclass_open_device, + nup_get_initial_matrix, + default_subclass_sync_output, /* sync_output */ + nup_output_page, + nup_close_device, + default_subclass_map_rgb_color, + default_subclass_map_color_rgb, + default_subclass_fill_rectangle, + default_subclass_tile_rectangle, /* tile_rectangle */ + default_subclass_copy_mono, + default_subclass_copy_color, + default_subclass_draw_line, /* draw_line */ + default_subclass_get_bits, /* get_bits */ + default_subclass_get_params, + nup_put_params, /* to catch PageSize changes */ + default_subclass_map_cmyk_color, + default_subclass_get_xfont_procs, /* get_xfont_procs */ + default_subclass_get_xfont_device, /* get_xfont_device */ + default_subclass_map_rgb_alpha_color, + default_subclass_get_page_device, + default_subclass_get_alpha_bits, /* get_alpha_bits */ + default_subclass_copy_alpha, + default_subclass_get_band, /* get_band */ + default_subclass_copy_rop, /* copy_rop */ + default_subclass_fill_path, + default_subclass_stroke_path, + default_subclass_fill_mask, + default_subclass_fill_trapezoid, + default_subclass_fill_parallelogram, + default_subclass_fill_triangle, + default_subclass_draw_thin_line, + default_subclass_begin_image, + default_subclass_image_data, /* image_data */ + default_subclass_end_image, /* end_image */ + default_subclass_strip_tile_rectangle, + default_subclass_strip_copy_rop, + default_subclass_get_clipping_box, /* get_clipping_box */ + default_subclass_begin_typed_image, + default_subclass_get_bits_rectangle, /* get_bits_rectangle */ + default_subclass_map_color_rgb_alpha, + default_subclass_create_compositor, + default_subclass_get_hardware_params, /* get_hardware_params */ + default_subclass_text_begin, + default_subclass_finish_copydevice, /* finish_copydevice */ + default_subclass_begin_transparency_group, /* begin_transparency_group */ + default_subclass_end_transparency_group, /* end_transparency_group */ + default_subclass_begin_transparency_mask, /* begin_transparency_mask */ + default_subclass_end_transparency_mask, /* end_transparency_mask */ + default_subclass_discard_transparency_layer, /* discard_transparency_layer */ + default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ + default_subclass_get_color_comp_index, /* get_color_comp_index */ + default_subclass_encode_color, /* encode_color */ + default_subclass_decode_color, /* decode_color */ + default_subclass_pattern_manage, /* pattern_manage */ + default_subclass_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ + default_subclass_include_color_space, /* include_color_space */ + default_subclass_fill_linear_color_scanline, /* fill_linear_color_scanline */ + default_subclass_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ + default_subclass_fill_linear_color_triangle, /* fill_linear_color_triangle */ + default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ + default_subclass_ret_devn_params, /* ret_devn_params */ + nup_fillpage, /* fillpage */ + default_subclass_push_transparency_state, /* push_transparency_state */ + default_subclass_pop_transparency_state, /* pop_transparency_state */ + default_subclass_put_image, /* put_image */ + nup_dev_spec_op, /* for GetParam of PdfmarkCapable */ + default_subclass_copy_planes, /* copy_planes */ + default_subclass_get_profile, /* get_profile */ + default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ + default_subclass_strip_copy_rop2, + default_subclass_strip_tile_rect_devn, + default_subclass_copy_alpha_hl_color, + default_subclass_process_page, + default_subclass_transform_pixel_region, + default_subclass_fill_stroke_path, + } +}; + +#undef MAX_COORD +#undef MAX_RESOLUTION + +static void +nup_disable_nesting(Nup_device_subclass_data *pNup_data) +{ + /* set safe non-nesting defaults if we don't know the size of the Nested Page */ + pNup_data->PagesPerNest = 1; + pNup_data->NupH = 1; + pNup_data->NupV = 1; + pNup_data->Scale = 1.0; + pNup_data->PageCount = 0; +} + +static int +ParseNupControl(gx_device *dev, Nup_device_subclass_data *pNup_data) +{ + int code = 0; + float HScale, VScale; + + /* Make sure PageW and PageH are set -- from dev->width, dev->height */ + pNup_data->PageW = dev->width * 72.0 / dev->HWResolution[0]; + pNup_data->PageH = dev->height * 72.0 / dev->HWResolution[1]; + + /* pNup_data->NestedPage[WH] size is set by nup_put_params by PageSize or .MediaSize */ + if (dev->NupControl== NULL) { + nup_disable_nesting(pNup_data); + return 0; + } + /* First parse the NupControl string for our parameters */ + if (sscanf(dev->NupControl->nupcontrol_str, "%dx%d", &(pNup_data->NupH), &(pNup_data->NupV)) != 2) { + emprintf1(dev->memory, "*** Invalid NupControl format '%s'\n", dev->NupControl->nupcontrol_str); + nup_disable_nesting(pNup_data); + return_error(gs_error_unknownerror); + } + pNup_data->PagesPerNest = pNup_data->NupH * pNup_data->NupV; + + /* -dNupControl=1x1 effectively turns off nesting */ + if (pNup_data->PagesPerNest == 1) { + nup_disable_nesting(pNup_data); + return 0; + } + if (pNup_data->NestedPageW == 0.0 || pNup_data->NestedPageH == 0.0) { + pNup_data->NestedPageW = pNup_data->PageW; + pNup_data->NestedPageH = pNup_data->PageH; + } + /* Calculate based on the PageW and PageH and NestedPage size */ + /* Set HSize, VSize, Scale, HMargin, and VMargin */ + + HScale = pNup_data->PageW / (pNup_data->NestedPageW * pNup_data->NupH); + VScale = pNup_data->PageH / (pNup_data->NestedPageH * pNup_data->NupV); + if (HScale < VScale) { + pNup_data->Scale = HScale; + pNup_data->HMargin = 0.0; + pNup_data->VMargin = (pNup_data->PageH - (HScale * pNup_data->NestedPageH * pNup_data->NupV))/2.0; + } else { + pNup_data->Scale = VScale; + pNup_data->VMargin = 0.0; + pNup_data->HMargin = (pNup_data->PageW - (VScale * pNup_data->NestedPageW * pNup_data->NupH))/2.0; + } + pNup_data->HSize = pNup_data->NestedPageW * pNup_data->Scale; + pNup_data->VSize = pNup_data->NestedPageH * pNup_data->Scale; + + return code; +} + +static void +nup_get_initial_matrix(gx_device *dev, gs_matrix *pmat) +{ + int code = 0, Hindex, Vindex; + Nup_device_subclass_data *pNup_data = dev->subclass_data; + + if (pNup_data->PagesPerNest == 0) /* not yet initialized */ + code = ParseNupControl(dev, pNup_data); + + default_subclass_get_initial_matrix(dev, pmat); /* get the matrix from the device */ + if (code < 0) + return; + + if (pNup_data->PagesPerNest == 1) + return; /* nesting disabled */ + + /* Modify the matrix according to N-up nesting paramters */ + pmat->tx += pNup_data->HMargin * pmat->xx; + pmat->ty += pNup_data->VMargin * pmat->yy; /* ty is the bottom */ + + Hindex = imod(pNup_data->PageCount, pNup_data->NupH); + Vindex = pNup_data->PageCount/pNup_data->NupH; + Vindex = pNup_data->NupV - (imod(Vindex, pNup_data->NupV) + 1); /* rows from top down */ + + pmat->tx += pNup_data->HSize * Hindex * pmat->xx; + pmat->tx += pNup_data->VSize * Vindex * pmat->xy; + + pmat->ty += pNup_data->HSize * Hindex * pmat->yx; + pmat->ty += pNup_data->VSize * Vindex * pmat->yy; + + pmat->xx *= pNup_data->Scale; + pmat->xy *= pNup_data->Scale; + pmat->yx *= pNup_data->Scale; + pmat->yy *= pNup_data->Scale; + + return; +} + +/* Used to set/resest child device's MediaSize which is needed around output_page */ +static void +nup_set_children_MediaSize(gx_device *dev, float PageW, float PageH) +{ + do { + dev = dev->child; + dev->MediaSize[0] = PageW; + dev->MediaSize[1] = PageH; + } while (dev->child != NULL); + return; +} + +static int +nup_flush_nest_to_output(gx_device *dev, Nup_device_subclass_data *pNup_data, bool flush) +{ + int code = 0; + + nup_set_children_MediaSize(dev, pNup_data->PageW, pNup_data->PageH); + code = default_subclass_output_page(dev, 1, true); + nup_set_children_MediaSize(dev, pNup_data->NestedPageW, pNup_data->NestedPageH); + + pNup_data->PageCount = 0; + return code; +} + +static int +nup_close_device(gx_device *dev) +{ + int code = 0, acode = 0; + Nup_device_subclass_data *pNup_data = dev->subclass_data; + + if (pNup_data->PagesPerNest == 0) + code = ParseNupControl(dev, pNup_data); + if (code < 0) + return code; + + if (pNup_data->PageCount > 0) + acode = nup_flush_nest_to_output(dev, pNup_data, true); + + /* Reset the Nup control data */ + /* NB: the data will be freed from non_gc_memory by the finalize function */ + memset(pNup_data, 0, sizeof(Nup_device_subclass_data)); + + /* close children devices, even if there was an error from flush (acode < 0) */ + code = default_subclass_close_device(dev); + + return min(code, acode); +} + + /* + * Template: + * BEGIN_ARRAY_PARAM(param_read_xxx_array, "pname", pxxa, size, pxxe) { + * ... check value if desired ... + * if (success) + * break; + * ... set ecode ... + * } END_ARRAY_PARAM(pxxa, pxxe); + */ + +#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\ + BEGIN\ + switch (code = pread(plist, (param_name = pname), &(pa))) {\ + case 0:\ + if ((pa).size != psize) {\ + ecode = gs_note_error(gs_error_rangecheck);\ + (pa).data = 0; /* mark as not filled */\ + } else +#define END_ARRAY_PARAM(pa, e)\ + goto e;\ + default:\ + ecode = code;\ +e: param_signal_error(plist, param_name, ecode);\ + case 1:\ + (pa).data = 0; /* mark as not filled */\ + }\ + END + +/* Read .MediaSize or, if supported as a synonym, PageSize. */ +static int +param_MediaSize(gs_param_list * plist, gs_param_name pname, + const float *res, gs_param_float_array * pa) +{ + gs_param_name param_name; + int ecode = 0; + int code; + + BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) { + float width_new = pa->data[0] * res[0] / 72; + float height_new = pa->data[1] * res[1] / 72; + + if (width_new < 0 || height_new < 0) + ecode = gs_note_error(gs_error_rangecheck); +#define max_coord (max_fixed / fixed_1) +#if max_coord < max_int + else if (width_new > (long)max_coord || height_new > (long)max_coord) + ecode = gs_note_error(gs_error_limitcheck); +#endif +#undef max_coord + else + break; + } END_ARRAY_PARAM(*pa, mse); + return ecode; +} + +static int +nup_put_params(gx_device *dev, gs_param_list * plist) +{ + int code, ecode = 0; + gs_param_float_array msa; + const float *data; + const float *res = dev->HWResolution; + gs_param_string nuplist; + Nup_device_subclass_data* pNup_data = dev->subclass_data; + gx_device *next_dev; + +#if 0000 +gs_param_list_dump(plist); +#endif + + code = param_read_string(plist, "NupControl", &nuplist); + if (code < 0) + ecode = code; + + if (code == 0) { + if (dev->NupControl && (nuplist.size == 0 || + (strncmp(dev->NupControl->nupcontrol_str, (const char *)nuplist.data, nuplist.size) != 0))) { + /* If we have accumulated a nest when the NupControl changes, flush the nest */ + if (pNup_data->PagesPerNest > 1 && pNup_data->PageCount > 0) + code = nup_flush_nest_to_output(dev, pNup_data, true); + if (code < 0) + ecode = code; + /* There was a NupControl, but this one is different -- no longer use the old one */ + rc_decrement(dev->NupControl, "default put_params NupControl"); + dev->NupControl = 0; + } + if (dev->NupControl == NULL && nuplist.size > 0) { + dev->NupControl = (gdev_nupcontrol *)gs_alloc_bytes(dev->memory->non_gc_memory, + sizeof(gdev_nupcontrol), "structure to hold nupcontrol_str"); + if (dev->NupControl == NULL) + return gs_note_error(gs_error_VMerror); + dev->NupControl->nupcontrol_str = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, + nuplist.size + 1, "nupcontrol string"); + if (dev->NupControl->nupcontrol_str == NULL){ + gs_free(dev->memory->non_gc_memory, dev->NupControl, 1, sizeof(gdev_nupcontrol), + "free structure to hold nupcontrol string"); + dev->NupControl = 0; + return gs_note_error(gs_error_VMerror); + } + memset(dev->NupControl->nupcontrol_str, 0x00, nuplist.size + 1); + memcpy(dev->NupControl->nupcontrol_str, nuplist.data, nuplist.size); + rc_init_free(dev->NupControl, dev->memory->non_gc_memory, 1, rc_free_NupControl); + } + /* Propagate the new NupControl struct to children so get_params has a valid param */ + next_dev = dev->child; + while (next_dev != NULL) { + rc_decrement(next_dev->NupControl, "nup_put_params"); + next_dev->NupControl = dev->NupControl; + rc_increment(next_dev->NupControl); + next_dev = next_dev->child; + } + /* Propagate the new NupControl struct to parents so get_params has a valid param */ + next_dev = dev->parent; + while (next_dev != NULL) { + rc_decrement(next_dev->NupControl, "nup_put_params"); + next_dev->NupControl = dev->NupControl; + rc_increment(next_dev->NupControl); + next_dev = next_dev->parent; + } + if (ecode < 0) + return ecode; + } + + code = ParseNupControl(dev, pNup_data); /* update the nesting params */ + if (code < 0) + return code; + + /* If nesting is now off, just pass params on to children devices */ + if (pNup_data->PagesPerNest == 1) + return default_subclass_put_params(dev, plist); + + /* .MediaSize takes precedence over PageSize, so we read PageSize first. */ + code = param_MediaSize(plist, "PageSize", res, &msa); + if (code < 0) + ecode = code; + /* Prevent data from being set to 0 if PageSize is specified */ + /* but .MediaSize is not. */ + data = msa.data; + code = param_MediaSize(plist, ".MediaSize", res, &msa); + if (code < 0) + ecode = code; + else if (msa.data == 0) + msa.data = data; + if (ecode < 0) + return ecode; + + /* If there was PageSize or .MediaSize, update the NestedPage size */ + if (msa.data != 0) { + Nup_device_subclass_data *pNup_data = dev->subclass_data; + + /* FIXME: Handle changing size (if previous value was non-zero) */ + if (msa.data[0] != pNup_data->NestedPageW || msa.data[1] != pNup_data->NestedPageH) { + /* If needed, flush previous nest before changing */ + if (pNup_data->PageCount > 0 && pNup_data->PagesPerNest > 1) { + code = nup_flush_nest_to_output(dev, pNup_data, true); + if (code < 0) + return code; + } + pNup_data->NestedPageW = msa.data[0]; + pNup_data->NestedPageH = msa.data[1]; + /* And update the Nup parameters based on the updated PageSize */ + code = ParseNupControl(dev, pNup_data); + if (code < 0) + return code; + } + } + + /* now that we've intercepted PageSize and/or MediaSize, pass the rest along */ + code = default_subclass_put_params(dev, plist); + return code; +} + +static int +nup_output_page(gx_device *dev, int num_copies, int flush) +{ + int code = 0; + Nup_device_subclass_data *pNup_data = dev->subclass_data; + + if (pNup_data->PagesPerNest == 0) + code = ParseNupControl(dev, pNup_data); /* ensure reasonable values */ + if (code < 0) + return code; + + /* If nesting is off, pass output_page to children */ + if (pNup_data->PagesPerNest == 1) { + code = default_subclass_output_page(dev, num_copies, flush); + dev->PageCount = dev->child->PageCount; + dev->ShowpageCount = dev->child->ShowpageCount; + return code; + } + + /* FIXME: Handle num_copies > 1 */ + pNup_data->PageCount++; + dev->PageCount++; + dev->ShowpageCount = dev->child->ShowpageCount; + if (pNup_data->PageCount >= pNup_data->PagesPerNest) + code = nup_flush_nest_to_output(dev, pNup_data, flush); + + return code; +} + +static int +nup_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) +{ + int code = 0; + Nup_device_subclass_data *pNup_data = dev->subclass_data; + + if (pNup_data->PagesPerNest == 0) + code = ParseNupControl(dev, pNup_data); + if (code < 0) + return code; + + /* Only fill the first page of a nest */ + if (pNup_data->PageCount == 0) + code = default_subclass_fillpage(dev, pgs, pdevc); + + return code; +} + +static int +nup_dev_spec_op(gx_device *dev, int dev_spec_op, void *data, int size) +{ + Nup_device_subclass_data *pNup_data = dev->subclass_data; + int code = 0; + + if (pNup_data->PagesPerNest == 0) /* not yet initialized */ + code = ParseNupControl(dev, pNup_data); + if (code < 0) + return code; + + /* If nesting is now off, just pass spec_op on to children devices */ + if (pNup_data->PagesPerNest == 1) + return default_subclass_dev_spec_op(dev, dev_spec_op, data, size); + + switch (dev_spec_op) { + case gxdso_set_HWSize: + /* Call ParseNupControl since that will set the PageW and PageH from the */ + /* dev->width, dev->height as the size for the page on which we are placing */ + /* the nested pages. If we get here we know PagesPerNest > 0, so don't set */ + /* the dev->width and dev->height */ + code = ParseNupControl(dev, pNup_data); + if (code < 0) + return code; + return 1; + break; + case gxdso_get_dev_param: + { + dev_param_req_t *request = (dev_param_req_t *)data; + int code = false; + + /* We need to disable pdfmark writing, primarily for CropBox, but also */ + /* they are probably not relevant for multiple input files to a single */ + /* output "page" (nest of several pages). */ + /* Write a 'false' (0) into the param list provided by the caller. */ + if (strcmp(request->Param, "PdfmarkCapable") == 0) { + return(param_write_bool(request->list, "PdfmarkCapable", &code)); + } + } + /* Fall through */ + default: + break; + } + return default_subclass_dev_spec_op(dev, dev_spec_op, data, size); +} diff --git a/base/gdevnup.h b/base/gdevnup.h new file mode 100644 index 00000000..a8b34c4b --- /dev/null +++ b/base/gdevnup.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2001-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Common definitions for N-up device */ + +#ifndef gdevnup_INCLUDED +# define gdevnup_INCLUDED + +#include "gxdevice.h" + +typedef struct gx_device_s gx_device_nup; + +/* Initialize device. */ +void gx_device_nup_device_init(gx_device_nup * dev); + +typedef struct { + subclass_common; + int PageCount; + int PagesPerNest; + int NupH; + int NupV; + float PageW; /* points width of carrier page */ + float PageH; /* points height of carrier page */ + float NestedPageW; /* points -- from MediaSize */ + float NestedPageH; /* points -- from MediaSize */ + float Scale; /* 1:1 aspect ratio */ + float HMargin; + float VMargin; + float HSize; + float VSize; +} Nup_device_subclass_data; + +extern_st(st_device_nup); + +#endif /* gdevnup_INCLUDED */ diff --git a/base/gdevoflt.c b/base/gdevoflt.c index a481e0b6..e7fc3809 100644 --- a/base/gdevoflt.c +++ b/base/gdevoflt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevoflt.h b/base/gdevoflt.h index d1a9581d..8afca579 100644 --- a/base/gdevoflt.h +++ b/base/gdevoflt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevp14.c b/base/gdevp14.c index 0ac027f2..8819ad90 100644 --- a/base/gdevp14.c +++ b/base/gdevp14.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -64,7 +64,11 @@ #include "gsicc.h" #ifdef WITH_CAL #include "cal.h" +#define CAL_SLOP 16 +#else +#define CAL_SLOP 0 #endif +#include "assert_.h" #if RAW_DUMP unsigned int global_index = 0; @@ -200,10 +204,12 @@ static dev_proc_dev_spec_op(pdf14_dev_spec_op); static dev_proc_push_transparency_state(pdf14_push_transparency_state); static dev_proc_pop_transparency_state(pdf14_pop_transparency_state); static dev_proc_ret_devn_params(pdf14_ret_devn_params); +static dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors); static dev_proc_copy_alpha(pdf14_copy_alpha); static dev_proc_copy_planes(pdf14_copy_planes); static dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color); static dev_proc_discard_transparency_layer(pdf14_discard_trans_layer); +static dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn); static const gx_color_map_procs * pdf14_get_cmap_procs(const gs_gstate *, const gx_device *); @@ -284,7 +290,7 @@ static const gx_color_map_procs * NULL, /* */\ gx_forward_set_graphics_type_tag, /* set_graphics_type_tag */\ NULL, /* strip_copy_rop2 */\ - NULL, /* strip_tile_rect_devn */\ + pdf14_strip_tile_rect_devn, /* strip_tile_rect_devn */\ pdf14_copy_alpha_hl_color, /* copy_alpha_hl_color */\ NULL, /* process_page */\ NULL, /* transform_pixel_region */\ @@ -328,7 +334,7 @@ static const gx_device_procs pdf14_custom_procs = gx_forward_encode_color, gx_forward_decode_color); -struct_proc_finalize(pdf14_device_finalize); +static struct_proc_finalize(pdf14_device_finalize); gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device", pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs, @@ -607,6 +613,23 @@ struct gx_device_pdf14_accum_s { }; typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum; +int +pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) +{ + gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev; + + if (dev_spec_op == gxdso_device_child) { + gxdso_device_child_request *req = (gxdso_device_child_request *)data; + if (size < sizeof(*req)) + return gs_error_unknownerror; + req->target = adev->save_p14dev; + req->n = 0; + return 0; + } + + return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size); +} + gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum, "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs, gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev); @@ -887,13 +910,14 @@ resolve_matte(pdf14_buf *maskbuf, byte *src_data, int src_planestride, int src_r need to do the offset to our data in the buffer. Bug 700686: If we are in a softmask that includes a matte entry, then we need to undo the matte entry here at this time in the image's native color space not the parent - color space. The big_endian term here is only set to true if the data - has been baked as such during the put_image blending operation. */ + color space. The endian_swap term here is only set to true if the data + has been baked as BE during the put_image blending operation and we are + on a LE machine. */ static forceinline pdf14_buf* template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev, pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile, cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc, - bool has_matte, bool deep, bool big_endian) + bool has_matte, bool deep, bool endian_swap) { gsicc_rendering_param_t rendering_params; gsicc_link_t *icc_link; @@ -913,6 +937,8 @@ template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev, pdf14_buf *output = src_buf; pdf14_mask_t *mask_stack; pdf14_buf *maskbuf; + int code; + *did_alloc = false; /* Same profile */ @@ -943,7 +969,7 @@ template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev, des_n_planes = src_n_planes + diff; des_n_chan = src_n_chan + diff; des_data = gs_alloc_bytes(ctx->memory, - (size_t)des_planestride * des_n_planes, + (size_t)des_planestride * des_n_planes + CAL_SLOP, "pdf14_transform_color_buffer"); if (des_data == NULL) return NULL; @@ -970,10 +996,8 @@ template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev, gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc, + code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc, src_data, des_data); gsicc_release_link(icc_link); + if (code < 0) + return NULL; output->planestride = des_planestride; output->rowstride = des_rowstride; @@ -1045,28 +1071,28 @@ static pdf14_buf* pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev, pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile, cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc, - bool deep, bool big_endian) + bool deep, bool endian_swap) { if (deep) return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile, - des_profile, x0, y0, width, height, did_alloc, false, true, big_endian); + des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap); else return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile, - des_profile, x0, y0, width, height, did_alloc, false, false, big_endian); + des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap); } static pdf14_buf* pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev, pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile, cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc, - bool deep, bool big_endian) + bool deep, bool endian_swap) { if (deep) return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile, - des_profile, x0, y0, width, height, did_alloc, true, true, big_endian); + des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap); else return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile, - des_profile, x0, y0, width, height, did_alloc, true, false, big_endian); + des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap); } /** @@ -1135,7 +1161,7 @@ pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g, planestride = rowstride * height; result->planestride = planestride; result->data = gs_alloc_bytes(memory, - (size_t)planestride * n_planes, + (size_t)planestride * n_planes + CAL_SLOP, "pdf14_buf_new"); if (result->data == NULL) { gs_free_object(memory, result, "pdf14_buf_new"); @@ -1222,7 +1248,7 @@ pdf14_ctx_new(gx_device *dev, bool deep) { pdf14_ctx *result; gs_memory_t *memory = dev->memory->stable_memory; - + result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new"); if (result == NULL) return result; @@ -1332,7 +1358,7 @@ pdf14_make_base_group_color(gx_device* dev) memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift), GX_DEVICE_COLOR_MAX_COMPONENTS); group_color->get_cmap_procs = pdf14_get_cmap_procs; - group_color->icc_profile = + group_color->icc_profile = pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]; gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color"); @@ -1420,7 +1446,7 @@ pdf14_initialize_ctx(gx_device* dev, int n_chan, bool additive, const gs_gstate* memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift), GX_DEVICE_COLOR_MAX_COMPONENTS); buf->group_color_info->previous = NULL; /* used during clist writing */ - buf->group_color_info->icc_profile = + buf->group_color_info->icc_profile = pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]; if (buf->group_color_info->icc_profile != NULL) gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx"); @@ -1536,7 +1562,7 @@ pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated, an isolated knockout group. */ if (buf->knockout && pdf14_backdrop != NULL) { buf->backdrop = gs_alloc_bytes(ctx->memory, - (size_t)buf->planestride * buf->n_planes, + (size_t)buf->planestride * buf->n_planes + CAL_SLOP, "pdf14_push_transparency_group"); if (buf->backdrop == NULL) { return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed"); @@ -1597,7 +1623,7 @@ pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx, if (maskbuf != NULL && maskbuf->matte != NULL) has_matte = true; - /* Check if this is our last buffer, if yes, there is nothing to + /* Check if this is our last buffer, if yes, there is nothing to compose to. Keep this buffer until we have the put image. If we have another group push, this group must be destroyed. This only occurs sometimes when at clist creation time @@ -1693,8 +1719,7 @@ pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx, look at pdf14_begin_transparency_group and pdf14_end_transparency group which is where all the ICC information is handled. We will return to look at that later */ if (nos->group_color_info->icc_profile != NULL) { - no_icc_match = (nos->group_color_info->icc_profile->hashcode != - curr_icc_profile->hashcode); + no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile); } else { /* Let the other tests make the decision if we need to transform */ no_icc_match = false; @@ -1785,7 +1810,7 @@ pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alph if (ctx->stack == NULL) { return_error(gs_error_VMerror); - } + } /* An optimization to consider is that if the SubType is Alpha then we really should only be allocating the alpha band and @@ -1810,7 +1835,7 @@ pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alph buf->group_color_info = group_color; if (Matte_components) { - buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t), + buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP, "pdf14_push_transparency_mask"); if (buf->matte == NULL) return_error(gs_error_VMerror); @@ -1908,6 +1933,7 @@ pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev) gsicc_link_t *icc_link; gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; + int code = 0; dev_proc(dev, get_profile)(dev, &dev_profile); gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile, @@ -1917,7 +1943,7 @@ pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev) icc_match == 0 means use icc code icc_match == 1 mean no conversion needed */ if (des_profile != NULL && src_profile != NULL ) { - icc_match = (des_profile->hashcode == src_profile->hashcode); + icc_match = gsicc_profiles_equal(des_profile, src_profile); } else { icc_match = -1; } @@ -1971,7 +1997,7 @@ pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev) /* This will reduce our memory. We won't reuse the existing one, due */ /* Due to the fact that on certain systems we may have issues recovering */ /* the data after a resize */ - new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride, + new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP, "pdf14_pop_transparency_mask"); if (new_data_buf == NULL) return_error(gs_error_VMerror); @@ -2058,7 +2084,7 @@ pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev) rendering_params.cmm = gsCMM_DEFAULT; icc_link = gsicc_get_link_profile(pgs, dev, des_profile, src_profile, &rendering_params, pgs->memory, false); - smask_icc(dev, tos->rect.q.y - tos->rect.p.y, + code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y, tos->rect.q.x - tos->rect.p.x, tos->n_chan, tos->rowstride, tos->planestride, tos->data, new_data_buf, icc_link, tos->deep); @@ -2089,7 +2115,7 @@ pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev) return gs_note_error(gs_error_VMerror); ctx->mask_stack->rc_mask->mask_buf = tos; } - return 0; + return code; } static pdf14_mask_t * @@ -2301,7 +2327,7 @@ pdf14_get_buffer_information(const gx_device * dev, gs_alloc_bytes(mem, (size_t)planestride * (buf->n_chan + - buf->has_tags ? 1 : 0), + buf->has_tags ? 1 : 0) + CAL_SLOP, "pdf14_get_buffer_information"); if (transbuff->transbytes == NULL) return gs_error_VMerror; @@ -2407,7 +2433,7 @@ pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profi cmm_profile_t* des_profile; gsicc_rendering_param_t render_cond; bool did_alloc; - bool big_endian; + bool endian_swap; gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile, &render_cond); @@ -2419,17 +2445,26 @@ pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profi global_index++; #endif - /* If we are doing a 16 bit buffer it will be big endian if we have already done the - blend, otherwise it will be native endian */ + /* If we are doing a 16 bit buffer it will be big endian if we have already done the + blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE + but for sanity pdf14 device maintains 16bit buffers in native format. The CMM + will need to know if it is dealing with native or BE data. */ if (was_blended && (*buf)->deep) { - big_endian = true; + /* Data is in BE. If we are in a LE machine, CMM will need to swap for + color conversion */ +#if ARCH_IS_BIG_ENDIAN + endian_swap = false; +#else + endian_swap = true; +#endif } else { - big_endian = false; + /* Data is in native format. No swap needed for CMM */ + endian_swap = false; } cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf, *buf_ptr, src_profile, des_profile, x, y, width, - height, &did_alloc, (*buf)->deep, big_endian); + height, &did_alloc, (*buf)->deep, endian_swap); if (cm_result == NULL) return_error(gs_error_VMerror); @@ -2542,23 +2577,8 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) } /* Check if we have a color conversion issue */ - if (!(src_profile->hash_is_valid)) { - gsicc_get_icc_buff_hash(src_profile->buffer, - &(src_profile->hashcode), - src_profile->buffer_size); - src_profile->hash_is_valid = true; - } - des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]; - if (!(des_profile->hash_is_valid)) { - gsicc_get_icc_buff_hash(des_profile->buffer, - &(des_profile->hashcode), - des_profile->buffer_size); - des_profile->hash_is_valid = true; - } - - if (pdev->using_blend_cs || - des_profile->hashcode != src_profile->hashcode) + if (pdev->using_blend_cs || !gsicc_profiles_equal(des_profile, src_profile)) color_mismatch = true; /* Check if target supports alpha */ @@ -2588,7 +2608,7 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) } else { /* In this case, just color convert and maintain alpha. This is a case where we either either blend in the right color space and have no - alpha for the output device or hand back the wrong color space with + alpha for the output device or hand back the wrong color space with alpha data. We choose the later. */ code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y, @@ -2615,7 +2635,7 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) /* We are going out to a device that supports tags */ if (deep) { gx_blend_image_buffer16(buf_ptr, width, height, rowstride, - buf->planestride, num_comp, bg); + buf->planestride, num_comp, bg, false); } else { gx_blend_image_buffer(buf_ptr, width, height, rowstride, buf->planestride, num_comp, bg >> 8); @@ -2660,7 +2680,7 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) rect.p.x, rect.p.y, width, height, rowstride, alpha_offset, tag_offset); /* Right now code has number of rows written */ - + } /* If code > 0 then put image worked. Let it finish and then exit */ @@ -2774,10 +2794,235 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) return code; } +/* Overprint simulation with spots. Collapse to CMYK */ +static void +template_spots_to_cmyk(byte *buf_ptr, int width, int height, int rowstride, + int planestride, int num_comp, int spot_start, int tag_offset, + cmyk_composite_map *map, bool keep_alpha) +{ + int comp_num; + uint cyan, magenta, yellow, black; + cmyk_composite_map *cmyk_map_entry; + int x, y; + int position; + byte comp, a; + + for (y = 0; y < height; y++) { + position = y * rowstride; + for (x = 0; x < width; x++) { + a = buf_ptr[position + planestride * num_comp]; + if (a != 0) { + cyan = buf_ptr[position] * frac_1; + magenta = buf_ptr[position + planestride] * frac_1; + yellow = buf_ptr[position + planestride * 2] * frac_1; + black = buf_ptr[position + planestride * 3] * frac_1; + cmyk_map_entry = &(map[4]); + for (comp_num = spot_start; comp_num < num_comp; comp_num++) { + comp = buf_ptr[position + planestride * comp_num]; + cyan += cmyk_map_entry->c * comp; + magenta += cmyk_map_entry->m * comp; + yellow += cmyk_map_entry->y * comp; + black += cmyk_map_entry->k * comp; + cmyk_map_entry++; + } + cyan /= frac_1; + magenta /= frac_1; + yellow /= frac_1; + black /= frac_1; + + if (cyan > 255) + cyan = 255; + if (magenta > 255) + magenta = 255; + if (yellow > 255) + yellow = 255; + if (black > 255) + black = 255; + + buf_ptr[position] = cyan; + buf_ptr[position + planestride] = magenta; + buf_ptr[position + planestride * 2] = yellow; + buf_ptr[position + planestride * 3] = black; + } + if (keep_alpha) { + /* Move the alpha and tag data */ + buf_ptr[position + planestride * 4] = a; + if (tag_offset > 0) { + buf_ptr[position + planestride * 5] = + buf_ptr[position + planestride * tag_offset]; + } + } else { + /* Remove alpha but keep tags */ + if (tag_offset > 0) { + buf_ptr[position + planestride * 4] = + buf_ptr[position + planestride * tag_offset]; + } + + } + position += 1; + } + } +} + +static void +template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, int rowstride, + int planestride, int num_comp, int spot_start, int tag_offset, + cmyk_composite_map *map, bool keep_alpha) +{ + int comp_num; + ulong cyan, magenta, yellow, black; + cmyk_composite_map *cmyk_map_entry; + int x, y; + int position; + ulong comp, a; + uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_; + + /* planestride and rowstride are in bytes, and we want them in shorts */ + planestride >>= 1; + rowstride >>= 1; + + for (y = 0; y < height; y++) { + position = y * rowstride; + for (x = 0; x < width; x++) { + a = buf_ptr[position + planestride * num_comp]; + if (a != 0) { + cyan = (ulong)buf_ptr[position] * frac_1_long; + magenta = (ulong)buf_ptr[position + planestride] * frac_1_long; + yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long; + black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long; + cmyk_map_entry = &(map[4]); + for (comp_num = spot_start; comp_num < num_comp; comp_num++) { + comp = buf_ptr[position + planestride * comp_num]; + cyan += (ulong)cmyk_map_entry->c * comp; + magenta += (ulong)cmyk_map_entry->m * comp; + yellow += (ulong)cmyk_map_entry->y * comp; + black += (ulong)cmyk_map_entry->k * comp; + cmyk_map_entry++; + } + cyan /= frac_1_long; + magenta /= frac_1_long; + yellow /= frac_1_long; + black /= frac_1_long; + + if (cyan > 65535) + cyan = 65535; + if (magenta > 65535) + magenta = 65535; + if (yellow > 65535) + yellow = 65535; + if (black > 65535) + black = 65535; + +#if ARCH_IS_BIG_ENDIAN + buf_ptr[position] = cyan; + buf_ptr[position + planestride] = magenta; + buf_ptr[position + planestride * 2] = yellow; + buf_ptr[position + planestride * 3] = black; +#else + ((byte *)&buf_ptr[position])[0] = cyan >> 8; + ((byte *)&buf_ptr[position])[1] = cyan; + ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8; + ((byte *)&buf_ptr[position + planestride])[1] = magenta; + ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8; + ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow; + ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8; + ((byte *)&buf_ptr[position + planestride * 3])[1] = black; +#endif + } + /* Move the alpha and tag data */ +#if ARCH_IS_BIG_ENDIAN + if (keep_alpha) { + buf_ptr[position + planestride * 4] = a; + if (tag_offset > 0) { + buf_ptr[position + planestride * 5] = + buf_ptr[position + planestride * tag_offset]; + } + } else { + if (tag_offset > 0) { + buf_ptr[position + planestride * 4] = + buf_ptr[position + planestride * tag_offset]; + } + } +#else + if (keep_alpha) { + ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8; + ((byte *)&buf_ptr[position + planestride * 4])[1] = a; + if (tag_offset > 0) { + ((byte *)&buf_ptr[position + planestride * 5])[0] = + buf_ptr[position + planestride * tag_offset] >> 8; + ((byte *)&buf_ptr[position + planestride * 5])[1] = + buf_ptr[position + planestride * tag_offset]; + } + } else { + if (tag_offset > 0) { + ((byte *)&buf_ptr[position + planestride * 4])[0] = + buf_ptr[position + planestride * tag_offset] >> 8; + ((byte *)&buf_ptr[position + planestride * 4])[1] = + buf_ptr[position + planestride * tag_offset]; + } + } +#endif + position += 1; + } + } +} + +static void +pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, int rowstride, + int planestride, int num_comp, int spot_start, int tag_offset, + cmyk_composite_map *map, bool keep_alpha, bool deep) +{ + if (deep) { + if (keep_alpha) { + if (tag_offset > 0) { + template_spots_to_cmyk_16(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, tag_offset, + map, true); + } else { + template_spots_to_cmyk_16(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, 0, + map, true); + } + } else { + if (tag_offset > 0) { + template_spots_to_cmyk_16(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, tag_offset, + map, false); + } else { + template_spots_to_cmyk_16(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, 0, + map, false); + } + } + } else { + if (keep_alpha) { + if (tag_offset > 0) { + template_spots_to_cmyk(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, tag_offset, + map, true); + } else { + template_spots_to_cmyk(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, 0, + map, true); + } + } else { + if (tag_offset > 0) { + template_spots_to_cmyk(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, tag_offset, + map, false); + } else { + template_spots_to_cmyk(buf_ptr, width, height, rowstride, + planestride, num_comp, spot_start, 0, + map, false); + } + } + } +} + /* This is for the case where we have mixture of spots and additive color. For example, RGB + spots or Gray + spots */ static void -gx_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, int rowstride, +pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, int rowstride, int planestride, int num_comp, int spot_start) { int x, y; @@ -2817,7 +3062,7 @@ gx_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, int rowstride, } static void -gx_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, int rowstride, +pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, int rowstride, int planestride, int num_comp, int spot_start) { uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_; @@ -2886,22 +3131,12 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, int num_comp, uint16_t bg, bool has_tags, gs_int_rect rect_in, gs_separations* pseparations, bool deep) { - const pdf14_device* pdev = (pdf14_device*)dev; + pdf14_device* pdev = (pdf14_device*)dev; int code = 0; - int x, y, tmp, comp_num, output_comp_num; - gx_color_index color; - gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value comp; - int input_map[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int output_map[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int num_known_comp = 0; - int output_num_comp = target->color_info.num_components; - int num_sep = pseparations->num_separations++; + int y; int num_rows_left; int i; - gx_drawing_color pdcolor; gs_int_rect rect = rect_in; - gs_fixed_rect rect_fixed; int planestride = planestride_in; int rowstride = rowstride_in; byte* buf_ptr = NULL; @@ -2914,38 +3149,13 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS]; int alpha_offset = num_comp; int tag_offset = has_tags ? num_comp + 1 : 0; - - /* - * The process color model for the PDF 1.4 compositor device is CMYK plus - * spot colors. The target device may have only some of these colorants due - * to the SeparationOrder device parameter. Thus we need to determine the - * mapping between the PDF 1.4 compositor and the target device. Note: - * There should not be a spot colorant in the PDF 1.4 device that is not - * present in the target device. - */ - /* Check if target processes CMYK colorants. */ - for (comp_num = 0; comp_num < 4; comp_num++) { - const char* pcomp_name = (const char*)DeviceCMYKComponents[comp_num]; - - output_comp_num = dev_proc(target, get_color_comp_index) - (target, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE); - if (output_comp_num >= 0 && - output_comp_num < GX_DEVICE_COLOR_MAX_COMPONENTS) { - output_map[num_known_comp] = output_comp_num; - input_map[num_known_comp++] = comp_num; - } - } - /* Check if target processes our spot colorants. */ - for (comp_num = 0; comp_num < num_sep; comp_num++) { - output_comp_num = dev_proc(target, get_color_comp_index) - (target, (const char*)(pseparations->names[comp_num].data), - pseparations->names[comp_num].size, NO_COMP_NAME_TYPE); - if (output_comp_num >= 0 && - output_comp_num < GX_DEVICE_COLOR_MAX_COMPONENTS) { - output_map[num_known_comp] = output_comp_num; - input_map[num_known_comp++] = comp_num + 4; - } - } + bool keep_native = pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0; + gs_color_space *pcs; + gs_image1_t image; + gx_image_enum_common_t *info; + gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS]; + pdf14_buf *cm_result = NULL; + bool did_alloc; /* Check if group color space is CMYK based */ code = dev_proc(target, get_profile)(target, &dev_target_profile); @@ -2962,24 +3172,41 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]; } - /* Check if we have a color conversion issue */ - if (!(src_profile->hash_is_valid)) { - gsicc_get_icc_buff_hash(src_profile->buffer, - &(src_profile->hashcode), - src_profile->buffer_size); - src_profile->hash_is_valid = true; + /* If we have spot colors and are doing overprint simulation and the source + space is not CMYK due to a blending color space being used, then convert + base colors to CMYK so that we can properly blend the spot colors */ + if (keep_native && src_profile->data_cs != gsCMYK) { + + cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf, + buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x, + buf->rect.q.y, &did_alloc, buf->deep, false); + if (cm_result == NULL) + return_error(gs_error_VMerror); + + /* Update */ + buf = cm_result; + src_profile = pgs->icc_manager->default_cmyk; + num_comp = buf->n_chan - 1; + bg = 0; + tag_offset = has_tags ? num_comp + 1 : 0; + alpha_offset = num_comp; + +#if RAW_DUMP + buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep); + dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride, + "post_to_cmyk_for_spot_blend", buf_ptr, deep); + global_index++; +#endif } - des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]; - if (!(des_profile->hash_is_valid)) { - gsicc_get_icc_buff_hash(des_profile->buffer, - &(des_profile->hashcode), - des_profile->buffer_size); - des_profile->hash_is_valid = true; + /* Fix order map if needed */ + for (i = 0; i < num_comp; i++) { + pdev->devn_params.separation_order_map[i] = i; } - if (pdev->using_blend_cs || - des_profile->hashcode != src_profile->hashcode) + /* Check if we have a color conversion issue */ + des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]; + if (pdev->using_blend_cs || !gsicc_profiles_equal(des_profile, src_profile)) color_mismatch = true; /* Check if target supports alpha */ @@ -2991,6 +3218,35 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, /* Note. The logic below will need a little rework if we ever have a device that has tags and alpha support */ if (supports_alpha) { + + /* If doing simulated overprint, Bring the spot color channels into + CMYK. Data is planar and 16 bit data in native format. */ + if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) { + cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS]; /* Fracs */ + + /* In the clist case, we need to get equiv spots out of the pseudo-band. */ + if (pdev->pclist_device != NULL) { + gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device); + + code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors)); + if (code < 0) + return code; + } + build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map); + + /* Now we go to big endian */ + pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride, + planestride, num_comp, src_profile->num_comps, + tag_offset, cmyk_map, true, deep); + + /* Reset buffer information. We have CMYK+alpha and maybe tags */ + buf->n_chan = buf->n_chan - buf->num_spots; + buf->n_planes = buf->n_planes - buf->num_spots; + buf->num_spots = 0; + num_comp = buf->n_chan - 1; + tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */ + } + if (!color_mismatch) { for (i = 0; i < buf->n_planes; i++) buf_ptrs[i] = buf_ptr + i * planestride; @@ -3023,37 +3279,81 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp, rect.p.x, rect.p.y, width, height, rowstride, alpha_offset, tag_offset); - /* Right now code has number of rows written */ + /* Right now code has number of rows written. Writing continues below */ } } else { /* Device could not handle the alpha data (we actually don't have a device that does spot colorants and has an alpha channel so - the above code is untested. Go ahead and - preblend now and then color convert if needed */ + the above code is untested. Go ahead and preblend now and then + color convert if needed */ #if RAW_DUMP /* Dump before and after the blend to make sure we are doing that ok */ - dump_raw_buffer(target->memory, height, width, num_comp + 1, planestride, rowstride, - "pre_final_blend", buf_ptr, deep); + dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride, + "pre_put_image_blend_image", buf_ptr, deep); global_index++; #endif + + /* Delay the baking to big endian if we have to do spots to CMYK still. We will take + care of the conversion at that point */ if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) { if (deep) { - gx_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride, + pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride, planestride, num_comp, src_profile->num_comps); } else { - gx_blend_image_mixed_buffer(buf_ptr, width, height, rowstride, + pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride, planestride, num_comp, src_profile->num_comps); } } else { if (deep) { gx_blend_image_buffer16(buf_ptr, width, height, rowstride, - planestride, num_comp, bg); + planestride, num_comp, bg, keep_native); } else { gx_blend_image_buffer(buf_ptr, width, height, rowstride, planestride, num_comp, bg >> 8); } } +#if RAW_DUMP + dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride, + "post_put_image_blend_image", buf_ptr, deep); + global_index++; +#endif + + /* If doing simulated overprint, Bring the spot color channels into + CMYK. Data is planar and 16 bit data is still in native format. */ + if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) { + cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS]; /* Fracs */ + + /* In the clist case, we need to get equiv spots out of the + pseudo-band. */ + if (pdev->pclist_device != NULL) { + gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device); + code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors)); + if (code < 0) + return code; + } + + build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map); + pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride, + planestride, num_comp, src_profile->num_comps, + tag_offset, cmyk_map, false, deep); + + /* Reset buffer information. We have CMYK and maybe tags */ + num_comp = 4; + alpha_offset = 0; + buf->n_chan = buf->n_chan - buf->num_spots - 1; /* No spots or alpha */ + buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */ + tag_offset = has_tags ? buf->n_chan : 0; /* Tags at end */ + buf->num_spots = 0; + +#if RAW_DUMP + dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride, + "post_put_image_spot_to_cmyk", buf_ptr, deep); + global_index++; +#endif + } + + /* Map to the destination color space */ if (color_mismatch) { code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile, &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height); @@ -3063,19 +3363,20 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, /* reset */ rowstride = buf->rowstride; planestride = buf->planestride; - num_comp = buf->n_chan - 1; + num_comp = buf->n_chan; tag_offset = buf->has_tags ? buf->n_chan : 0; } - #if RAW_DUMP - /* Dump before and after the blend to make sure we are doing that ok */ - dump_raw_buffer_be(target->memory, height, width, num_comp, planestride, rowstride, - "post_final_blend", buf_ptr, deep); + /* Dump after the CS transform */ + dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride, + "post_put_image_color_convert", buf_ptr, deep); global_index++; /* clist_band_count++; */ #endif - /* Try put_image again now */ + + /* Try put_image again. This can occur if the + target, like psdcmyk and tiffsep, support put_image */ alpha_offset = 0; for (i = 0; i < buf->n_planes; i++) buf_ptrs[i] = buf_ptr + i * planestride; @@ -3083,13 +3384,14 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, rect.p.x, rect.p.y, width, height, rowstride, alpha_offset, tag_offset); } + + /* Put image was succesful. We processed some or all of the rows. + Continue until we are done */ if (code > 0) { - /* We processed some or all of the rows. Continue until we are done */ num_rows_left = height - code; while (num_rows_left > 0) { code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp, - rect.p.x, rect.p.y + code, width, - num_rows_left, rowstride, + rect.p.x, rect.p.y + code, width, num_rows_left, rowstride, alpha_offset, tag_offset); if (code < 0) { return code; @@ -3099,123 +3401,78 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, return 0; } - /* No put_image working at all. Resort to fill_rect */ - - planestride = planestride_in; - rowstride = rowstride_in; - - /* Clear all output colorants first */ - for (comp_num = 0; comp_num < output_num_comp; comp_num++) - cv[comp_num] = 0; - - /* Send pixel data to the target device. */ - if (deep) { - /* NOTE: buf_ptr points to big endian data */ - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - - /* composite CMYKA, etc. pixel with over solid background */ -#define GET16_BE2NATIVE(v) \ -((((byte *)&(v))[0]<<8) | (((byte *)&(v))[1])) - uint16_t a = GET16_BE2NATIVE(buf_ptr[x + planestride * num_comp]); + /* Sep devices all support put_image (tiffsep and psdcmyk) + as well as those devices that support alpha (pngalpha) + If we are here, then we are doing an overprint simulation + on some other device. Image data is aleady blended and in + device color space. */ + code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory); + if (code < 0) + return code; - if (a == 0) { - for (comp_num = 0; comp_num < num_known_comp; comp_num++) { - cv[output_map[comp_num]] = bg; - } - } else if (a == 0xffff) { - for (comp_num = 0; comp_num < num_known_comp; comp_num++) { - comp = GET16_BE2NATIVE(buf_ptr[x + planestride * input_map[comp_num]]); - cv[output_map[comp_num]] = comp; - } - } else { - /* a ^= 0xff; */ /* No inversion here! Bug 689895 */ - for (comp_num = 0; comp_num < num_known_comp; comp_num++) { - comp = GET16_BE2NATIVE(buf_ptr[x + planestride * input_map[comp_num]]); - tmp = ((comp - bg) * a) + 0x8000; - comp += (tmp + (tmp >> 16)) >> 16; - cv[output_map[comp_num]] = comp; - } - } + /* Already in destination CS */ + pcs->cmm_icc_profile_data = des_profile; - /* If we have spot colors we need to encode and fill as a high level - color if the device supports it which should always be the case - if we are in this procedure */ - if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) { - for (i = 0; i < output_num_comp; i++) { - pdcolor.colors.devn.values[i] = cv[i]; - } - pdcolor.type = gx_dc_type_devn; - rect_fixed.p.x = int2fixed(x + x0); - rect_fixed.p.y = int2fixed(y + y0); - rect_fixed.q.x = int2fixed(x + x0 + 1); - rect_fixed.q.y = int2fixed(y + y0 + 1); - code = dev_proc(target, fill_rectangle_hl_color)(target, &rect_fixed, - NULL, &pdcolor, NULL); - } else { - /* encode as a color index */ - color = dev_proc(target, encode_color)(target, cv); - code = dev_proc(target, fill_rectangle)(target, x + x0, y + y0, 1, 1, color); - } - if (code < 0) - return code; - } + /* pcs takes a reference to the profile data it just retrieved. */ + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot"); + gsicc_set_icc_range(&(pcs->cmm_icc_profile_data)); + gs_image_t_init_adjust(&image, pcs, false); + image.ImageMatrix.xx = (float)width; + image.ImageMatrix.yy = (float)height; + image.Width = width; + image.Height = height; + image.BitsPerComponent = deep ? 16 : 8; + image.ColorSpace = pcs; + image.format = gs_image_format_component_planar; - buf_ptr += rowstride; - } - } else { - bg >>= 8; - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { + ctm_only_writable(pgs).xx = (float)width; + ctm_only_writable(pgs).xy = 0; + ctm_only_writable(pgs).yx = 0; + ctm_only_writable(pgs).yy = (float)height; + ctm_only_writable(pgs).tx = (float)rect.p.x; + ctm_only_writable(pgs).ty = (float)rect.p.y; + code = dev_proc(target, begin_typed_image) (target, + pgs, NULL, (gs_image_common_t *)&image, + NULL, NULL, NULL, pgs->memory, &info); + if (code < 0) { + rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot"); + return code; + } +#if RAW_DUMP + /* Dump the current buffer to see what we have. */ + dump_raw_buffer(pdev->ctx->memory, + pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y, + pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x, + pdev->ctx->stack->n_planes, + pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, + "put_image_final_big", pdev->ctx->stack->data, deep); + dump_raw_buffer(pdev->ctx->memory, + height, width, buf->n_planes, + pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, + "put_image_final_small", buf_ptr, deep); + global_index++; + clist_band_count++; +#endif - /* composite CMYKA, etc. pixel with over solid background */ - byte a = buf_ptr[x + planestride * num_comp]; + for (i = 0; i < num_comp; i++) { + planes[i].data = buf_ptr + i * planestride; + planes[i].data_x = 0; + planes[i].raster = buf->rowstride; + } - if ((a + 1) & 0xfe) { - /* a ^= 0xff; */ /* No inversion here! Bug 689895 */ - for (comp_num = 0; comp_num < num_known_comp; comp_num++) { - comp = buf_ptr[x + planestride * input_map[comp_num]]; - tmp = ((comp - bg) * a) + 0x80; - comp += tmp + (tmp >> 8); - cv[output_map[comp_num]] = comp; - } - } else if (a == 0) { - for (comp_num = 0; comp_num < num_known_comp; comp_num++) { - cv[output_map[comp_num]] = bg; - } - } else { - for (comp_num = 0; comp_num < num_known_comp; comp_num++) { - comp = buf_ptr[x + planestride * input_map[comp_num]]; - cv[output_map[comp_num]] = (comp << 8) + comp; - } - } + for (y = 0; y < height; y++) { + int rows_used; - /* If we have spot colors we need to encode and fill as a high level - color if the device supports it which should always be the case - if we are in this procedure */ - if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) { - for (i = 0; i < output_num_comp; i++) { - pdcolor.colors.devn.values[i] = cv[i]; - } - pdcolor.type = gx_dc_type_devn; - rect_fixed.p.x = int2fixed(x + x0); - rect_fixed.p.y = int2fixed(y + y0); - rect_fixed.q.x = int2fixed(x + x0 + 1); - rect_fixed.q.y = int2fixed(y + y0 + 1); - code = dev_proc(target, fill_rectangle_hl_color)(target, &rect_fixed, - NULL, &pdcolor, NULL); - } else { - /* encode as a color index */ - color = dev_proc(target, encode_color)(target, cv); - code = dev_proc(target, fill_rectangle)(target, x + x0, y + y0, 1, 1, color); - } - if (code < 0) - return code; - } + info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used); - buf_ptr += rowstride; + for (i = 0; i < num_comp; i++) { + planes[i].data += buf->rowstride; } } + info->procs->end_image(info, true); + + /* This will also decrement the profile */ + rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot"); return code; } @@ -3372,7 +3629,7 @@ static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev) gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_end_transparency_group"); - pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = + pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color_info->icc_profile; group_color_info->icc_profile = NULL; } @@ -3505,7 +3762,7 @@ gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target) in the PDF14 device without messing up the target device profile. Also if the device is using a blend color space it will grab that too */ if (dev->icc_struct == NULL) { - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); profile_dev14 = dev->icc_struct; dev_proc((gx_device *) target, get_profile)((gx_device *) target, &(profile_targ)); @@ -3526,6 +3783,7 @@ gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target) dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor; dev->icc_struct->supports_devn = profile_targ->supports_devn; dev->icc_struct->usefastcolor = profile_targ->usefastcolor; + dev->icc_struct->blacktext = profile_targ->blacktext; if (pdev->using_blend_cs) { /* Swap the device profile and the blend profile. */ @@ -3538,7 +3796,7 @@ gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target) profile_dev14->blend_profile = profile_targ->device_profile[GS_DEFAULT_DEVICE_PROFILE]; profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = profile_targ->blend_profile; } - profile_dev14->sim_overprint = profile_targ->sim_overprint; + profile_dev14->overprint_control = profile_targ->overprint_control; } #undef COPY_ARRAY_PARAM #undef COPY_PARAM @@ -3628,7 +3886,7 @@ pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs) } pdev->alpha = pdev->opacity * pdev->shape; pdev->blend_mode = pgs->blend_mode; - if (pdev->icc_struct->sim_overprint) { + if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) { pdev->overprint = pgs->overprint; pdev->stroke_overprint = pgs->stroke_overprint; } else { @@ -3666,8 +3924,12 @@ update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor) hastrans = true; } } - /* The only idempotent blend modes are Normal, Darken and Lighten */ - if ((pgs->blend_mode != BLEND_MODE_Normal && pgs->blend_mode != BLEND_MODE_Darken && pgs->blend_mode != BLEND_MODE_Lighten) || + /* The only idempotent blend modes are Normal, Darken and Lighten. + This appears to be the only place where this test is done so + not adding a is_idempotent method */ + if ((pgs->blend_mode != BLEND_MODE_Normal && + pgs->blend_mode != BLEND_MODE_Darken && + pgs->blend_mode != BLEND_MODE_Lighten) || (pgs->fillconstantalpha != 1.0) || (pgs->strokeconstantalpha != 1.0) || (hastrans)) @@ -3810,7 +4072,8 @@ pdf14_fill_path(gx_device *dev, const gs_gstate *pgs, return code; } } - if (gx_dc_is_pattern2_color(pdcolor)) { + if (gx_dc_is_pattern2_color(pdcolor) || + pdcolor->type == &gx_dc_devn_masked) { /* Non-idempotent blends require a transparency * group to be pushed because shadings might * paint several pixels twice. */ @@ -4086,11 +4349,11 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath, /* If we are in an overprint situation, set the blend mode to compatible overprint */ - if (p14dev->icc_struct->sim_overprint && pgs->overprint && + if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */ code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath); - if (p14dev->icc_struct->sim_overprint && pgs->overprint && + if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */ if (code < 0) @@ -4101,7 +4364,7 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath, gs_swapcolors_quick(pgs); p14dev->op_state = PDF14_OP_STATE_STROKE; - if (p14dev->icc_struct->sim_overprint && pgs->stroke_overprint && + if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */ code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath); @@ -4109,6 +4372,14 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath, gs_swapcolors_quick(pgs); if (code < 0) goto cleanup; + /* Bug 703324 we need to reset the fill constant alpha in the graphics + * state to the correct saved value. We also need to reset the 'opacity' member of the + * device, because some device methods (eg fill_masked_image) don't take a graphics + * state pointer as a parameter and so are unable to set the opacity value themselves. + * We therefore need to make sure it is set according to the current fill state. + */ + (void)gs_setfillconstantalpha(pgs, fill_alpha); + pdf14_set_marking_params(dev, pgs); } cleanup: @@ -5148,7 +5419,15 @@ pdf14_forward_open_device(gx_device * dev) static void pdf14_forward_device_procs(gx_device * dev) { - gx_device_forward * pdev = (gx_device_forward *)dev; + gx_device_forward *pdev = (gx_device_forward *)dev; + pdf14_device *p14dev = (pdf14_device*)dev; + + /* If doing simulated overprint with spot colors + then makes sure to reset devn setting */ + if (p14dev->overprint_sim && + p14dev->color_info.num_components > 4) + p14dev->icc_struct->supports_devn = + p14dev->target_support_devn; /* * We are using gx_device_forward_fill_in_procs to set the various procs. @@ -5270,7 +5549,7 @@ pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum, const char * pcomp_name = (const char *)DeviceCMYKComponents[i]; output_comp_num = dev_proc(pdev, get_color_comp_index) - (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE); + (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP); if (output_comp_num >= 0) { num_cmyk++; if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS) @@ -5330,6 +5609,17 @@ get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, pdf14_determine_default_blend_cs(dev, use_pdf14_accum, &using_blend_cs); bool deep = device_is_deep(dev); + int num_spots = pdf14pct->params.num_spot_colors; + + /* overprint overide */ + if (pdf14pct->params.overprint_sim_push) { + using_blend_cs = false; + if (pdf14pct->params.num_spot_colors_int > 0) { + dev_cs = PDF14_DeviceCMYKspot; + num_spots = pdf14pct->params.num_spot_colors_int; + } else + dev_cs = PDF14_DeviceCMYK; + } switch (dev_cs) { case PDF14_DeviceGray: @@ -5372,13 +5662,11 @@ get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, * of the process components and the number of spot colors * for the page. */ - if (pdf14pct->params.num_spot_colors >= 0) { + if (num_spots >= 0) { *ptempdevproto = **pdevproto; - ptempdevproto->devn_params.page_spot_colors = - pdf14pct->params.num_spot_colors; + ptempdevproto->devn_params.page_spot_colors = num_spots; ptempdevproto->color_info.num_components = - ptempdevproto->devn_params.num_std_colorant_names + - pdf14pct->params.num_spot_colors; + ptempdevproto->devn_params.num_std_colorant_names + num_spots; if (ptempdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS) ptempdevproto->color_info.num_components = @@ -5411,6 +5699,7 @@ get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, return_error(gs_error_rangecheck); } ptempdevproto->using_blend_cs = using_blend_cs; + ptempdevproto->overprint_sim = pdf14pct->params.overprint_sim_push; return 0; } @@ -5503,7 +5792,12 @@ pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs, pdev->color_info = dev_proto->color_info; pdev->pad = target->pad; pdev->log2_align_mod = target->log2_align_mod; - pdev->is_planar = target->is_planar; + + if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar) + pdev->is_planar = true; + else + pdev->is_planar = target->is_planar; + pdev->procs = dev_proto->procs; if (deep) { set_dev_proc(pdev, encode_color, pdf14_encode_color16); @@ -5516,7 +5810,11 @@ pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs, } dev->static_procs = dev_proto->static_procs; gx_device_set_procs(dev); - gx_device_fill_in_procs(dev); + pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD; + gx_device_fill_in_procs((gx_device *)pdev); + pdev->save_get_cmap_procs = pgs->get_cmap_procs; + pgs->get_cmap_procs = pdf14_get_cmap_procs; + gx_set_cmap_procs(pgs, (gx_device *)pdev); check_device_separable(dev); return dev_proc(pdev, open_device)(dev); } @@ -5655,7 +5953,6 @@ pdf14_forward_create_compositor(gx_device * dev, gx_device * * pcdev, { pdf14_device *pdev = (pdf14_device *)dev; gx_device * tdev = pdev->target; - gx_device * ndev; int code; *pcdev = dev; @@ -5666,11 +5963,14 @@ pdf14_forward_create_compositor(gx_device * dev, gx_device * * pcdev, return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem); return 0; } - code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pgs, mem, cdev); - if (code < 0) - return code; - gx_device_set_target((gx_device_forward *)pdev, ndev); - return 0; + code = dev_proc(tdev, create_compositor)(tdev, pcdev, pct, pgs, mem, cdev); + if (code == 1) { + /* We have created a new compositor that wrapped tdev. This means + * that our target should be updated to point to that. */ + gx_device_set_target((gx_device_forward *)pdev, *pcdev); + code = 0; /* We have not created a new compositor that wrapped dev. */ + } + return code; } /* @@ -5843,35 +6143,159 @@ pdf14_finish_copydevice(gx_device *new_dev, const gx_device *from_dev) { pdf14_device *pdev = (pdf14_device*)new_dev; - pdev->ctx = NULL; - pdev->color_model_stack = NULL; - pdev->smaskcolor = NULL; + pdev->ctx = NULL; + pdev->color_model_stack = NULL; + pdev->smaskcolor = NULL; + + /* Only allow copying the prototype. */ + return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); +} + +/* + * Implement copy_mono by filling lots of small rectangles. + */ +static int +pdf14_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + const byte *sptr; + const byte *line; + int sbit, first_bit; + int code, sbyte, bit, count; + int run_length, startx, current_bit, bit_value; + gx_color_index current_color; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + line = base + (sourcex >> 3); + sbit = sourcex & 7; + first_bit = 7 - sbit; + + /* Loop through the height of the specified area. */ + while (h-- > 0) { + /* Set up for the start of each line of the area. */ + sptr = line; + sbyte = *sptr++; + bit = first_bit; + count = w; + run_length = 0; + startx = x; + current_bit = 0; + current_color = zero; + + /* Loop across each pixel of a line. */ + do { + bit_value = (sbyte >> bit) & 1; + if (bit_value == current_bit) { + /* The value did not change, simply increment our run length */ + run_length++; + } else { + /* The value changed, fill the current rectangle. */ + if (run_length != 0) { + if (current_color != gx_no_color_index) { + code = (*dev_proc(dev, fill_rectangle)) + (dev, startx, y, run_length, 1, current_color); + if (code < 0) + return code; + } + startx += run_length; + } + run_length = 1; + current_color = bit_value ? one : zero; + current_bit = bit_value; + } + /* Move to the next input bit. */ + if (bit == 0) { + bit = 7; + sbyte = *sptr++; + } + else + bit--; + } while (--count > 0); + /* Fill the last rectangle in the line. */ + if (run_length != 0 && current_color != gx_no_color_index) { + code = (*dev_proc(dev, fill_rectangle)) + (dev, startx, y, run_length, 1, current_color); + if (code < 0) + return code; + } + /* Move to the next line */ + line += sraster; + y++; + } + return 0; +} + +/* Added to avoid having to go back and forth between fixed and int + in some of the internal methods used for dealing with tiling + and devn colors */ +static int +pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h, + const gx_drawing_color *pdcolor) +{ + pdf14_device *pdev = (pdf14_device *)dev; + pdf14_buf *buf; + int code; + + fit_fill_xywh(dev, x, y, w, h); + if (w <= 0 || h <= 0) + return 0; + + code = pdf14_initialize_ctx(dev, dev->color_info.num_components, + dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL); + if (code < 0) + return code; + buf = pdev->ctx->stack; - /* Only allow copying the prototype. */ - return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); + if (buf->knockout) + return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor, + true); + else + return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true); } -/* - * Implement copy_mono by filling lots of small rectangles. - */ +/* Step through and do rect fills with the devn colors as + we hit each transition in the bitmap. It is possible + that one of the colors is not devn, but is pure and + is set to gx_no_color_index. This type of mix happens + for example from tile_clip_fill_rectangle_hl_color */ static int -pdf14_copy_mono(gx_device * dev, - const byte * base, int sourcex, int sraster, gx_bitmap_id id, - int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +pdf14_copy_mono_devn(gx_device *dev, + const byte *base, int sourcex, int sraster, + int x, int y, int w, int h, const gx_drawing_color *pdcolor0, + const gx_drawing_color *pdcolor1) { const byte *sptr; const byte *line; int sbit, first_bit; int code, sbyte, bit, count; int run_length, startx, current_bit, bit_value; - gx_color_index current_color; + const gx_drawing_color *current_color; + + if ((x | y) < 0) { + if (x < 0) { + w += x; + sourcex -= x; + x = 0; + } + if (y < 0) { + h += y; + base -= (int)(y * sraster); + y = 0; + } + } + if (w > (dev)->width - x) + w = (dev)->width - x; + if (h > (dev)->height - y) + h = (dev)->height - y; + if (w <= 0 || h <= 0) + return 0; - fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); line = base + (sourcex >> 3); sbit = sourcex & 7; first_bit = 7 - sbit; - /* Loop through the height of the specfied area. */ + /* Loop through the height of the specified area. */ while (h-- > 0) { /* Set up for the start of each line of the area. */ sptr = line; @@ -5881,7 +6305,7 @@ pdf14_copy_mono(gx_device * dev, run_length = 0; startx = x; current_bit = 0; - current_color = zero; + current_color = pdcolor0; /* Loop across each pixel of a line. */ do { @@ -5892,30 +6316,33 @@ pdf14_copy_mono(gx_device * dev, } else { /* The value changed, fill the current rectangle. */ if (run_length != 0) { - if (current_color != gx_no_color_index) { - code = (*dev_proc(dev, fill_rectangle)) - (dev, startx, y, run_length, 1, current_color); + if (current_color->type != gx_dc_type_pure && + current_color->colors.pure != gx_no_color_index) { + code = pdf14_fill_rectangle_devn(dev, startx, y, + run_length, 1, current_color); if (code < 0) return code; } startx += run_length; } run_length = 1; - current_color = bit_value ? one : zero; + current_color = bit_value ? pdcolor1 : pdcolor0; current_bit = bit_value; } + /* Move to the next input bit. */ if (bit == 0) { bit = 7; sbyte = *sptr++; - } - else + } else bit--; } while (--count > 0); + /* Fill the last rectangle in the line. */ - if (run_length != 0 && current_color != gx_no_color_index) { - code = (*dev_proc(dev, fill_rectangle)) - (dev, startx, y, run_length, 1, current_color); + if (run_length != 0 && current_color->type != gx_dc_type_pure && + current_color->colors.pure != gx_no_color_index) { + code = pdf14_fill_rectangle_devn(dev, startx, y, + run_length, 1, current_color); if (code < 0) return code; } @@ -5926,9 +6353,173 @@ pdf14_copy_mono(gx_device * dev, return 0; } +/* Step through the tiles doing essentially copy_mono but with devn colors */ +static int +pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles, + int x, int y, int w, int h, const gx_drawing_color *pdcolor0, + const gx_drawing_color *pdcolor1, int px, int py) +{ /* Fill the rectangle in chunks. */ + int width = tiles->size.x; + int height = tiles->size.y; + int raster = tiles->raster; + int rwidth = tiles->rep_width; + int rheight = tiles->rep_height; + int shift = tiles->shift; + + if (rwidth == 0 || rheight == 0) + return_error(gs_error_unregistered); + fit_fill_xy(dev, x, y, w, h); + + { + int xoff = (shift == 0 ? px : + px + (y + py) / rheight * tiles->rep_shift); + int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */ + (x + xoff) & (rwidth - 1) : + (x + xoff) % rwidth); + int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */ + (y + py) & (rheight - 1) : + (y + py) % rheight); + int icw = width - irx; + int ch = height - ry; + byte *row = tiles->data + ry * raster; + int code = 0; + + if (ch >= h) { /* Shallow operation */ + if (icw >= w) { /* Just one (partial) tile to transfer. */ + code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y, + w, h, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + } else { + int ex = x + w; + int fex = ex - width; + int cx = x + icw; + + code = pdf14_copy_mono_devn(dev, row, irx, raster, + x, y, icw, h, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + + while (cx <= fex) { + code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y, + width, h, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + cx += width; + } + if (cx < ex) { + code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y, + ex - cx, h, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + } + } + } else if (icw >= w && shift == 0) { + /* Narrow operation, no shift */ + int ey = y + h; + int fey = ey - height; + int cy = y + ch; + + code = pdf14_copy_mono_devn(dev, row, irx, raster, + x, y, w, ch, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + row = tiles->data; + do { + ch = (cy > fey ? ey - cy : height); + code = pdf14_copy_mono_devn(dev, row, irx, raster, + x, cy, w, ch, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + } while ((cy += ch) < ey); + } else { + /* Full operation. If shift != 0, some scan lines */ + /* may be narrow. We could test shift == 0 in advance */ + /* and use a slightly faster loop, but right now */ + /* we don't bother. */ + int ex = x + w, ey = y + h; + int fex = ex - width, fey = ey - height; + int cx, cy; + + for (cy = y;;) { + if (icw >= w) { + code = pdf14_copy_mono_devn(dev, row, irx, raster, + x, cy, w, ch, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + } else { + code = pdf14_copy_mono_devn(dev, row, irx, raster, + x, cy, icw, ch, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + cx = x + icw; + while (cx <= fex) { + code = pdf14_copy_mono_devn(dev, row, 0, raster, + cx, cy, width, ch, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + cx += width; + } + if (cx < ex) { + code = pdf14_copy_mono_devn(dev, row, 0, raster, + cx, cy, ex - cx, ch, pdcolor0, pdcolor1); + if (code < 0) + return_error(code); + } + } + if ((cy += ch) >= ey) + break; + ch = (cy > fey ? ey - cy : height); + if ((irx += shift) >= rwidth) + irx -= rwidth; + icw = width - irx; + row = tiles->data; + } + } + } + return 0; +} + +/* pdf14 device supports devn */ +static int +pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, + int x, int y, int w, int h, + const gx_drawing_color *pdcolor0, + const gx_drawing_color *pdcolor1, int px, int py) +{ + pdf14_device *pdev = (pdf14_device *)dev; + pdf14_buf *buf = pdev->ctx->stack; + int num_comp = buf->n_chan - 1; + int k; + bool same = false; + int code = 0; + + /* if color0 is identical to color1, do rect fill */ + if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) { + same = true; + for (k = 0; k < num_comp; k++) { + if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) { + same = false; + break; + } + } + } + + if (same) { + code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0); + } else { + /* Go through the tile stepping using code stolen from + gx_default_strip_tile_rectangle and call the rect fills + using code stolen from pdf14_copy_mono but using devn + colors */ + code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles, + x, y, w, h, pdcolor0, pdcolor1, px, py); + } + return code; +} + /* Used in a few odd cases where the target device is planar and we have a planar tile (pattern) and we are copying it into place here */ - static int pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h, int plane_height) @@ -6000,15 +6591,16 @@ pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, int w = fixed2int(rect->q.x) - x; int h = fixed2int(rect->q.y) - y; + fit_fill_xywh(dev, x, y, w, h); + if (w <= 0 || h <= 0) + return 0; + code = pdf14_initialize_ctx(dev, dev->color_info.num_components, dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, pgs); if (code < 0) return code; buf = pdev->ctx->stack; - fit_fill_xywh(dev, x, y, w, h); - if (w <= 0 || h <= 0) - return 0; if (buf->knockout) return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor, true); @@ -6024,6 +6616,10 @@ pdf14_fill_rectangle(gx_device * dev, pdf14_buf *buf; int code; + fit_fill_xywh(dev, x, y, w, h); + if (w <= 0 || h <= 0) + return 0; + code = pdf14_initialize_ctx(dev, dev->color_info.num_components, dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL); if (code < 0) @@ -6031,9 +6627,6 @@ pdf14_fill_rectangle(gx_device * dev, buf = pdev->ctx->stack; - fit_fill_xywh(dev, x, y, w, h); - if (w <= 0 || h <= 0) - return 0; if (buf->knockout) return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL, false); @@ -6139,13 +6732,7 @@ pdf14_begin_transparency_group(gx_device* dev, if (group_profile != NULL) { /* If we have a non-isolated group and the color space is different, we will need to CM the backdrop. */ - if (!(group_profile->hash_is_valid)) { - gsicc_get_icc_buff_hash(group_profile->buffer, - &(group_profile->hashcode), - group_profile->buffer_size); - group_profile->hash_is_valid = true; - } - if (group_profile->hashcode != tos_profile->hashcode) { + if (!gsicc_profiles_equal(group_profile, tos_profile)) { cm_back_drop = true; } } @@ -6216,6 +6803,9 @@ pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color) -1, "pdf14_pop_color_model"); pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile; + + gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + 1, "pdf14_pop_color_model"); } } } @@ -6404,7 +6994,7 @@ pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type, break; } - if (group_color_type == ICC && iccprofile != NULL) { + if (group_color_type == ICC && iccprofile != NULL) { group_color->icc_profile = iccprofile; gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model"); } @@ -6465,6 +7055,7 @@ pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type, /* iccprofile was incremented above if we had not just created it. When we do the pop we will decrement and if we just created it, it will be destroyed */ + gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model"); dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile; } return group_color; @@ -6609,7 +7200,7 @@ pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs, break; case ICC: /* Check if the profile is different. */ - if (old_profile->hashcode != new_profile->hashcode) { + if (!gsicc_profiles_equal(old_profile, new_profile)) { update_color_info = true; new_num_comps = new_profile->num_comps; new_depth = new_profile->num_comps * (8 << deep); @@ -6975,6 +7566,8 @@ pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs) gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_end_transparency_mask"); dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile; + gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + 1, "pdf14_end_transparency_mask"); } } } @@ -7115,8 +7708,25 @@ do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h, } /* Complement the results for subtractive color spaces */ if (additive) { - for (k = 0; k < num_chan; ++k) - dst_ptr[k * planestride] = dst[k]; + if (!overprint) { + for (k = 0; k < num_chan; ++k) + dst_ptr[k * planestride] = dst[k]; + } else { + /* Hybrid additive with subtractive spots */ + /* We may have to do the compatible overprint blending */ + if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) { + art_pdf_composite_knockout_8(dst2, src, num_comp, + blend_mode, pdev->blend_procs, pdev); + } + for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = dst[k]; + } else { + /* Compatible overprint blend result. */ + dst_ptr[k * planestride] = dst2[k]; + } + } + } } else { if (overprint) { /* We may have to do the compatible overprint blending */ @@ -7314,8 +7924,25 @@ do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h, } /* Complement the results for subtractive color spaces */ if (additive) { - for (k = 0; k < num_chan; ++k) - dst_ptr[k * planestride] = dst[k]; + if (!overprint) { + for (k = 0; k < num_chan; ++k) + dst_ptr[k * planestride] = dst[k]; + } else { + /* Hybrid additive with subtractive spots */ + /* We may have to do the compatible overprint blending */ + if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) { + art_pdf_composite_knockout_16(dst2, src, num_comp, + blend_mode, pdev->blend_procs, pdev); + } + for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = dst[k]; + } else { + /* Compatible overprint blend result. */ + dst_ptr[k * planestride] = dst2[k]; + } + } + } } else { if (overprint) { /* We may have to do the compatible overprint blending */ @@ -7435,6 +8062,21 @@ map_components_to_colorants(const frac * pcc, } } +/* See Section 7.6.4 of PDF 1.7 spec */ +static inline bool +pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs) +{ + if (pgs->fillconstantalpha != 1.0 || + pgs->strokeconstantalpha != 1.0 || + !(pgs->blend_mode == BLEND_MODE_Normal || + pgs->blend_mode == BLEND_MODE_CompatibleOverprint)) + return 0; + + /* We can only be opaque if we're not in an SMask. */ + return dev_proc(pdev, dev_spec_op)(pdev, + gxdso_in_smask, + NULL, 0) != 1; +} static void pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, @@ -7453,20 +8095,16 @@ pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, trans_device = dev; } ncomps = trans_device->color_info.num_components; + /* map to the color model */ dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_gray(trans_device, gray, cm_comps); - /* If we are in a Gray blending color space and have spots then we have - * possibly an issue here with the transfer function */ - if (pgs->trans_device != NULL) { - cv[0] = frac2cv(gx_map_color_frac(pgs, cm_comps[0], effective_transfer[0])); - /* FIXME: This looks odd to me... */ - for (i = 1; i < ncomps; i++) - cv[i] = gx_color_value_from_byte(cm_comps[i]); - } else { - /* Not a transparency device. Just use the transfer functions directly */ + if (pdf14_state_opaque(trans_device, pgs)) { for (i = 0; i < ncomps; i++) cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + } else { + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(cm_comps[i]); } /* If output device supports devn, we need to make sure we send it the @@ -7504,21 +8142,15 @@ pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, /* map to the color model */ dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pgs, r, g, b, cm_comps); - /* If we are in an RGB blending color space and have spots then we have - * possibly an issue here with the transfer function */ - if (pgs->trans_device != NULL) { - for (i = 0; i < 3; i++) + if (pdf14_state_opaque(trans_device, pgs)) { + for (i = 0; i < ncomps; i++) cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); - /* FIXME: This looks odd to me... */ - for (i = 3; i < ncomps; i++) - cv[i] = gx_color_value_from_byte(cm_comps[i]); } else { - /* Not a transparency device. Just use the transfer functions directly */ for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + cv[i] = frac2cv(cm_comps[i]); } - /* if output device supports devn, we need to make sure we send it the + /* If output device supports devn, we need to make sure we send it the proper color type. We now support RGB + spots as devn colors */ if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) { for (i = 0; i < ncomps; i++) @@ -7538,7 +8170,7 @@ pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select, const gs_color_space *pcs) { - int i,ncomps; + int i, ncomps; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; @@ -7551,10 +8183,19 @@ pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, trans_device = dev; } ncomps = trans_device->color_info.num_components; - /* map to the color model */ + + /* Map to the color model. Transfer function is only used + if we are drawing with an opaque color. */ dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_cmyk(trans_device, c, m, y, k, cm_comps); - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + + if (pdf14_state_opaque(trans_device, pgs)) { + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + } else { + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(cm_comps[i]); + } + /* if output device supports devn, we need to make sure we send it the proper color type */ if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) { @@ -7818,8 +8459,17 @@ pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op, return p14dev->overprint || p14dev->stroke_overprint; } } + if (dev_spec_op == gxdso_in_smask_construction) + return p14dev->in_smask_construction > 0; if (dev_spec_op == gxdso_in_smask) return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask; + if (dev_spec_op == gxdso_device_insert_child) { + gx_device *tdev = p14dev->target; + p14dev->target = (gx_device *)data; + rc_increment(p14dev->target); + rc_decrement_only(tdev, "pdf14_dev_spec_op"); + return 0; + } return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size); } @@ -7838,7 +8488,7 @@ gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring) return code; } -int +static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct) { @@ -7898,11 +8548,15 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, (const gx_device *) dev_proto, mem); if (code < 0) return code; + gs_pdf14_device_copy_params((gx_device *)p14dev, target); gx_device_set_target((gx_device_forward *)p14dev, target); p14dev->pad = target->pad; p14dev->log2_align_mod = target->log2_align_mod; - p14dev->is_planar = target->is_planar; + if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar) + p14dev->is_planar = true; + else + p14dev->is_planar = target->is_planar; p14dev->alpha = 1.0; p14dev->shape = 1.0; @@ -7910,21 +8564,38 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, p14dev->fillconstantalpha = 1.0; p14dev->strokeconstantalpha = 1.0; - /* If the target profile was CIELAB (and we are not using a blend CS), - then overide with default RGB for - proper blending. During put_image we will convert from RGB to - CIELAB. Need to check that we have a default profile, which - will not be the case if we are coming from the clist reader */ - if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab) - && pgs->icc_manager->default_rgb != NULL && !p14dev->using_blend_cs) { - gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push"); + /* Simulated overprint case. We have to use CMYK-based profile */ + if (p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) { + gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push"); gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], - -1, "gs_pdf14_device_push"); - p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb; + -1, "gs_pdf14_device_push"); + p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk; + } else { + /* If the target profile was CIELAB (and we are not using a blend CS), + then overide with default RGB for proper blending. During put_image + we will convert from RGB to CIELAB. Need to check that we have a + default profile, which will not be the case if we are coming from the clist reader */ + if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab) + && pgs->icc_manager->default_rgb != NULL && !p14dev->using_blend_cs) { + gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push"); + gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + -1, "gs_pdf14_device_push"); + p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb; + } + } + + if (pdf14pct->params.overprint_sim_push && + pdf14pct->params.num_spot_colors_int > 0) { + p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors; + p14dev->procs.ret_devn_params = pdf14_ret_devn_params; + p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false; + p14dev->target_support_devn = p14dev->icc_struct->supports_devn; + p14dev->icc_struct->supports_devn = true; /* Reset when pdf14 device is disabled */ } + /* The number of color planes should not exceed that of the target. Unless we are using a blend CS */ - if (!p14dev->using_blend_cs) { + if (!(p14dev->using_blend_cs || p14dev->overprint_sim)) { if (p14dev->color_info.num_components > target->color_info.num_components) p14dev->color_info.num_components = target->color_info.num_components; if (p14dev->color_info.max_components > target->color_info.max_components) @@ -8166,7 +8837,10 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize, cdev->pdf14_smask_level = 0; cdev->page_pdf14_needed = false; put_value(pbuf, pparams->num_spot_colors); + put_value(pbuf, pparams->num_spot_colors_int); + put_value(pbuf, pparams->overprint_sim_push); put_value(pbuf, pparams->is_pattern); + /* If we happen to be going to a color space like CIELAB then we are going to do our blending in default RGB and convert to CIELAB at the end. To do this, we need to store the @@ -8175,12 +8849,12 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize, if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) { /* Get the default RGB profile. Set the device hash code so that we can extract it during the put_image operation. */ - cdev->trans_dev_icc_hash = pparams->iccprofile->hashcode; + cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile); found_icc = - clist_icc_searchtable(cdev, pparams->iccprofile->hashcode); + clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile)); if (!found_icc) { /* Add it to the table */ - clist_icc_addentry(cdev, pparams->iccprofile->hashcode, + clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile), pparams->iccprofile); } } @@ -8221,7 +8895,7 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize, profile or the ID if it is cached already */ if (pparams->group_color_type == ICC) { /* Check if it is already in the ICC clist table */ - hashcode = pparams->iccprofile->hashcode; + hashcode = gsicc_get_hash(pparams->iccprofile); found_icc = clist_icc_searchtable(cdev, hashcode); if (!found_icc) { /* Add it to the table */ @@ -8274,7 +8948,7 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize, profile or the ID if it is cached already */ if (pparams->group_color_type == ICC) { /* Check if it is already in the ICC clist table */ - hashcode = pparams->iccprofile->hashcode; + hashcode = gsicc_get_hash(pparams->iccprofile); found_icc = clist_icc_searchtable(cdev, hashcode); if (!found_icc) { /* Add it to the table */ @@ -8401,6 +9075,8 @@ c_pdf14trans_read(gs_composite_t * * ppct, const byte * data, break; case PDF14_PUSH_DEVICE: read_value(data, params.num_spot_colors); + read_value(data, params.num_spot_colors_int); + read_value(data, params.overprint_sim_push); read_value(data, params.is_pattern); break; case PDF14_ABORT_DEVICE: @@ -8568,7 +9244,6 @@ c_pdf14trans_create_default_compositor(const gs_composite_t * pct, gs_memory_t * mem) { const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct; - gx_device * p14dev = NULL; int code = 0; /* @@ -8578,8 +9253,11 @@ c_pdf14trans_create_default_compositor(const gs_composite_t * pct, */ switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: - code = gs_pdf14_device_push(mem, pgs, &p14dev, tdev, pdf14pct); - *pp14dev = p14dev; + code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct); + /* Change (non-error) code to 1 to indicate that we created + * a device. */ + if (code >= 0) + code = 1; break; default: /* No other compositor actions are allowed if this isn't a pdf14 compositor */ @@ -8775,7 +9453,7 @@ const gs_composite_type_t gs_composite_pdf14trans_type = { c_pdf14trans_is_friendly, /* procs.is_friendly */ /* Create a PDF 1.4 clist write device */ c_pdf14trans_clist_write_update, /* procs.composite_clist_write_update */ - c_pdf14trans_clist_read_update, /* procs.composite_clist_reade_update */ + c_pdf14trans_clist_read_update, /* procs.composite_clist_read_update */ c_pdf14trans_get_cropping /* procs.composite_get_cropping */ } /* procs */ }; @@ -8792,7 +9470,7 @@ const gs_composite_type_t gs_composite_pdf14trans_no_clist_writer_type = { c_pdf14trans_is_friendly, /* procs.is_friendly */ /* The PDF 1.4 clist writer already exists, Do not create it. */ gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */ - c_pdf14trans_clist_read_update, /* procs.composite_clist_reade_update */ + c_pdf14trans_clist_read_update, /* procs.composite_clist_read_update */ c_pdf14trans_get_cropping /* procs.composite_get_cropping */ } /* procs */ }; @@ -9095,6 +9773,17 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, &using_blend_cs); bool has_tags = device_encodes_tags(dev); bool deep = device_is_deep(dev); + int num_spots = pdf14pct->params.num_spot_colors; + + /* overprint overide */ + if (pdf14pct->params.overprint_sim_push) { + using_blend_cs = false; + if (pdf14pct->params.num_spot_colors_int > 0) { + dev_cs = PDF14_DeviceCMYKspot; + num_spots = pdf14pct->params.num_spot_colors_int; + } else + dev_cs = PDF14_DeviceCMYK; + } switch (dev_cs) { case PDF14_DeviceGray: @@ -9155,12 +9844,10 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, * of the process components and the number of spot colors * for the page. */ - if (pdf14pct->params.num_spot_colors >= 0) { - ptempdevproto->devn_params.page_spot_colors = - pdf14pct->params.num_spot_colors; + if (num_spots >= 0) { + ptempdevproto->devn_params.page_spot_colors = num_spots; ptempdevproto->color_info.num_components = - ptempdevproto->devn_params.num_std_colorant_names + - pdf14pct->params.num_spot_colors; + ptempdevproto->devn_params.num_std_colorant_names + num_spots; if (ptempdevproto->color_info.num_components > ptempdevproto->color_info.max_components) ptempdevproto->color_info.num_components = @@ -9195,6 +9882,7 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, default: /* Should not occur */ return_error(gs_error_rangecheck); } + ptempdevproto->overprint_sim = pdf14pct->params.overprint_sim_push; ptempdevproto->using_blend_cs = using_blend_cs; return 0; } @@ -9213,6 +9901,8 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, cmm_dev_profile_t *dev_profile; uchar k; bool deep = device_is_deep(target); + cmm_profile_t *icc_profile; + code = dev_proc(target, get_profile)(target, &dev_profile); if (code < 0) @@ -9231,7 +9921,7 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, /* If we are not using a blending color space, the number of color planes should not exceed that of the target */ - if (!pdev->using_blend_cs) { + if (!(pdev->using_blend_cs || pdev->overprint_sim)) { if (pdev->color_info.num_components > target->color_info.num_components) pdev->color_info.num_components = target->color_info.num_components; if (pdev->color_info.max_components > target->color_info.max_components) @@ -9240,7 +9930,12 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, pdev->color_info.depth = pdev->color_info.num_components * (8<pad = target->pad; pdev->log2_align_mod = target->log2_align_mod; - pdev->is_planar = target->is_planar; + + if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar) + pdev->is_planar = true; + else + pdev->is_planar = target->is_planar; + pdev->op_state = pgs->is_fill_color; if (deep) { @@ -9270,14 +9965,40 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, } code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev); pdev->pclist_device = target; - /* If the target profile was CIELAB, then overide with default RGB for - proper blending. During put_image we will convert from RGB to - CIELAB */ - if ((target_profile->data_cs == gsCIELAB || target_profile->islab) && - !pdev->using_blend_cs) { - rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], - pgs->icc_manager->default_rgb, "pdf14_create_clist_device"); + + code = dev_proc(target, get_profile)(target, &dev_profile); + if (code < 0) + return code; + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, + &render_cond); + if_debug0m('v', mem, "[v]pdf14_create_clist_device\n"); + + /* Simulated overprint case. We have to use CMYK-based profile */ + if (pdev->overprint_sim && icc_profile->data_cs != gsCMYK) { + gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device"); + gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + -1, "pdf14_create_clist_device"); + pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk; + } else { + /* If the target profile was CIELAB, then overide with default RGB for + proper blending. During put_image we will convert from RGB to + CIELAB */ + if ((target_profile->data_cs == gsCIELAB || target_profile->islab) && + !pdev->using_blend_cs) { + rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + pgs->icc_manager->default_rgb, "pdf14_create_clist_device"); + } + } + + if (pdf14pct->params.overprint_sim_push && + pdf14pct->params.num_spot_colors_int > 0) { + pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors; + pdev->procs.ret_devn_params = pdf14_ret_devn_params; + pdev->op_pequiv_cmyk_colors.all_color_info_valid = false; + pdev->target_support_devn = pdev->icc_struct->supports_devn; + pdev->icc_struct->supports_devn = true; /* Reset when pdf14 device is disabled */ } + pdev->my_encode_color = dev_proc(pdev, encode_color); pdev->my_decode_color = dev_proc(pdev, decode_color); pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs); @@ -9345,8 +10066,17 @@ pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs, pdev->static_procs = dev_proto->static_procs; pdev->pad = target->pad; pdev->log2_align_mod = target->log2_align_mod; - pdev->is_planar = target->is_planar; - gx_device_fill_in_procs(dev); + + if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar) + pdev->is_planar = true; + else + pdev->is_planar = target->is_planar; + + pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD; + gx_device_fill_in_procs((gx_device *)pdev); + pdev->save_get_cmap_procs = pgs->get_cmap_procs; + pgs->get_cmap_procs = pdf14_get_cmap_procs; + gx_set_cmap_procs(pgs, (gx_device *)pdev); check_device_separable((gx_device *)pdev); return code; } @@ -9452,6 +10182,25 @@ pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs return code; } +/* Used when doing overprint simulation and have spot colors */ +static int +pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs) +{ + pdf14_device *pdev = (pdf14_device *)dev; + const gs_color_space *pcs; + int code; + + /* Make sure we are not All or None */ + pcs = gs_currentcolorspace_inline(pgs); + if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation && + pcs->params.separation.sep_type != SEP_OTHER) + return 0; + + code = update_spot_equivalent_cmyk_colors(dev, pgs, &pdev->devn_params, + &pdev->op_pequiv_cmyk_colors); + return code; +} + /* * Retrieve a list of spot color names for the PDF14 device. */ @@ -9576,34 +10325,64 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type; code = dev_proc(pdev->target, create_compositor) (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev); - *pcdev = dev; + /* We should never have created a new device here. */ + assert(code != 1); return code; } case PDF14_POP_DEVICE: + { + gx_device *clistdev = pdev->target; + + /* Find the clist device */ + while (1) { + gxdso_device_child_request req; + /* Ignore any errors here, that's expected as non-clist + * devices don't implement it. */ + code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0); + if (code == 1) + break; + req.n = 0; + req.target = clistdev; + code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req)); + if (code < 0) + return code; + clistdev = req.target; + } + + /* If we have overprint simulation spot color information, store + it in a pseudo-band of the clist */ + if (pdev->overprint_sim && + pdev->devn_params.page_spot_colors > 0) { + code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev, + &pdev->op_pequiv_cmyk_colors); + if (code < 0) + return code; + } + /* If we hit an error during an SMask, we need to undo the color * swapping before continuing. pdf14_decrement_smask_color() checks * for itself if it needs to take action. */ pdf14_decrement_smask_color(pgs, dev); /* Restore the color_info for the clist device */ - pdev->target->color_info = pdev->saved_target_color_info; - set_dev_proc(pdev->target, encode_color, pdev->saved_target_encode_color); - set_dev_proc(pdev->target, decode_color, pdev->saved_target_decode_color); - set_dev_proc(pdev->target, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs); - set_dev_proc(pdev->target, get_color_comp_index, pdev->saved_target_get_color_comp_index); + clistdev->color_info = pdev->saved_target_color_info; + set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color); + set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color); + set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs); + set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index); pgs->get_cmap_procs = pdev->save_get_cmap_procs; - gx_set_cmap_procs(pgs, pdev->target); - gx_device_decache_colors(pdev->target); + gx_set_cmap_procs(pgs, clistdev); + gx_device_decache_colors(clistdev); /* Disable the PDF 1.4 compositor */ pdf14_disable_clist_device(mem, pgs, dev); /* * Make sure that the transfer funtions, etc. are current. */ - code = cmd_put_color_mapping( - (gx_device_clist_writer *)(pdev->target), pgs); + code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs); if (code < 0) return code; break; + } case PDF14_BEGIN_TRANS_PAGE_GROUP: case PDF14_BEGIN_TRANS_GROUP: if (pdev->smask_constructed || pdev->depth_within_smask) @@ -9707,6 +10486,14 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, return code; break; case PDF14_ABORT_DEVICE: + code = gx_abort_trans_device(pgs, dev); + if (pdev->free_devicen) { + devn_free_params(dev); + } + pdf14_disable_device(dev); + pdf14_close(dev); + *pcdev = dev; + return code; break; default: break; /* Pass remaining ops to target */ @@ -9849,8 +10636,11 @@ put_accum_error: } return code; /* DON'T perform set_target */ } - if (*pcdev != pdev->target) + if (code == 1) { + /* We just wrapped pdev->target, so we need to update that.*/ gx_device_set_target((gx_device_forward *)pdev, *pcdev); + code = 0; /* We did not wrap dev. */ + } *pcdev = dev; return code; } @@ -9882,10 +10672,12 @@ pdf14_clist_forward_create_compositor(gx_device * dev, gx_device * * pcdev, return 0; } code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pgs, mem, cdev); - if (code < 0) - return code; - gx_device_set_target((gx_device_forward *)pdev, ndev); - return 0; + if (code == 1) { + /* We just wrapped tdev, so update our target. */ + gx_device_set_target((gx_device_forward *)pdev, ndev); + code = 0; /* We did not wrap dev. */ + } + return code; } /* @@ -9948,7 +10740,7 @@ pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs, } params.changed = changed; /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply - now to the target. Otherwise we send of te compositor action + now to the target. Otherwise we send the compositor action to the pdf14 device at this time. This is due to the fact that we need to often perform this operation when we are already starting to do a compositor action */ @@ -10243,7 +11035,8 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs /* See if overprint is enabled for both stroke and fill AND if ca == CA */ if (pgs->fillconstantalpha == pgs->strokeconstantalpha && - pgs->overprint && pgs->stroke_overprint && dev->icc_struct->sim_overprint && + pgs->overprint && pgs->stroke_overprint && + (dev->icc_struct->overprint_control != gs_overprint_control_disable) && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) { params.Isolated = false; @@ -10294,7 +11087,8 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs /* If we are in an overprint situation, set the blend mode to compatible overprint */ - if (dev->icc_struct->sim_overprint && pgs->overprint && + if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) && + pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */ @@ -10302,7 +11096,8 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs if (code < 0) goto cleanup; - if (dev->icc_struct->sim_overprint && pgs->overprint && + if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) && + pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */ } @@ -10319,7 +11114,8 @@ pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs if (code < 0) goto cleanup; - if (dev->icc_struct->sim_overprint && pgs->overprint && + if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) && + pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */ } @@ -10638,6 +11434,8 @@ gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev, gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer; code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct); + if (code < 0) + return code; /* * Set the color_info of the clist device to match the compositing * device. We will restore it when the compositor is popped. @@ -10699,7 +11497,12 @@ c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev, /* We only handle the push/pop operations */ switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: - return gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct); + code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct); + /* Change (non-error) code to 1 to indicate that we created + * a device. */ + if (code >= 0) + code = 1; + return code; case PDF14_POP_DEVICE: # if 0 /* Disabled because pdf14_clist_create_compositor does so. */ @@ -10828,10 +11631,13 @@ c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev, */ switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: - gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update"); - gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], - -1, "c_pdf14trans_clist_read_update"); - p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile; + /* Overprint simulation sets the profile at prototype creation. */ + if (!p14dev->overprint_sim) { + gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update"); + gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + -1, "c_pdf14trans_clist_read_update"); + p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile; + } /* * If we are blending using spot colors (i.e. the output device * supports spot colors) then we need to transfer @@ -11048,16 +11854,25 @@ pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname, target_get_color_comp_index = dev_proc(tdev, get_color_comp_index); /* The pdf14_clist_create_compositor may have set the color procs. - We need the real target procs */ - if (target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index) + We need the real target procs, but not if we are doing simulated + overprint */ + if (target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index && + !pdev->overprint_sim) target_get_color_comp_index = ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index; /* * If this is not a separation name then simply forward it to the target - * device. + * device or return -1 if we are doing overprint simulation. + * The halftone setup expects this. */ - if (component_type == NO_COMP_NAME_TYPE) + if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT || + component_type == NO_COMP_NAME_TYPE_OP)) { return (*target_get_color_comp_index)(tdev, pname, name_size, component_type); + } + if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) { + return -1; + } + /* * Check if the component is in either the process color model list * or in the SeparationNames list. @@ -11070,19 +11885,23 @@ pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname, */ if (comp_index >= 0) return comp_index - offset; - /* - * If we do not know this color, check if the output (target) device does. - * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add - * the colorant so we will only get < 0 returned when we hit the max. for - * the target device. - */ - comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type); - /* - * Ignore color if unknown to the output device or if color is not being - * imaged due to the SeparationOrder device parameter. - */ - if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS) - return comp_index - offset; + + /* Only worry about the target if we are not doing an overprint simulation */ + if (!pdev->overprint_sim) { + /* + * If we do not know this color, check if the output (target) device does. + * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add + * the colorant so we will only get < 0 returned when we hit the max. for + * the target device. + */ + comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type); + /* + * Ignore color if unknown to the output device or if color is not being + * imaged due to the SeparationOrder device parameter. + */ + if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS) + return comp_index - offset; + } /* * This is a new colorant. Add it to our list of colorants. @@ -11109,6 +11928,11 @@ pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname, else pdevn_params->separation_order_map[color_component_number] = color_component_number; + + /* Indicate that we need to find equivalent CMYK color. */ + pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false; + pdev->op_pequiv_cmyk_colors.all_color_info_valid = false; + return color_component_number; } @@ -11174,11 +11998,11 @@ pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev) result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t, &st_pdf14_smaskcolor, "pdf14_increment_smask_color"); - if (result == NULL) + if (result == NULL) return gs_error_VMerror; result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory); - if (result->profiles == NULL) + if (result->profiles == NULL) return gs_error_VMerror; pdev->smaskcolor = result; @@ -11336,7 +12160,7 @@ pdf14_free_smask_color(pdf14_device * pdev) } } -void +static void pdf14_device_finalize(const gs_memory_t *cmem, void *vptr) { gx_device * const dev = (gx_device *)vptr; diff --git a/base/gdevp14.h b/base/gdevp14.h index 635ab111..44f0b8a5 100644 --- a/base/gdevp14.h +++ b/base/gdevp14.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -100,7 +100,7 @@ struct pdf14_mask_s { /* A structure to hold information about the group color related * procs and other information. These may change depending upon * if the blending space is different than the base space. - * The structure is a list that is updated upo every transparency + * The structure is a list that is updated upo every transparency * group push and pop */ typedef struct pdf14_group_color_s pdf14_group_color_t; @@ -208,6 +208,7 @@ typedef struct pdf14_device_s { const pdf14_procs_t * pdf14_procs; /* Must follow devn_params. */ const pdf14_nonseparable_blending_procs_t * blend_procs; /* Must follow pdf14_procs */ int num_std_colorants; + equivalent_cmyk_color_params op_pequiv_cmyk_colors; pdf14_ctx *ctx; pdf14_smaskcolor_t *smaskcolor; @@ -232,6 +233,8 @@ typedef struct pdf14_device_s { bool free_devicen; /* Used to avoid freeing a deviceN parameter from target clist device */ bool sep_device; bool using_blend_cs; + bool overprint_sim; + bool target_support_devn; /* We now have some variables to help us determine whether * we are in an SMask or not. Firstly, we have in_smask_construction, @@ -320,6 +323,7 @@ int gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring); /* depth are critical since these must match when reading back colors. */ bool pdf14_ok_to_optimize(gx_device *bdev); - +int +pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size); #endif /* gdevp14_INCLUDED */ diff --git a/base/gdevpccm.c b/base/gdevpccm.c index fbbbf97c..fbbffc18 100644 --- a/base/gdevpccm.c +++ b/base/gdevpccm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevpccm.h b/base/gdevpccm.h index ae3de6dc..ccae7917 100644 --- a/base/gdevpccm.h +++ b/base/gdevpccm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevpipe.c b/base/gdevpipe.c index b4f2acb1..96d71f5d 100644 --- a/base/gdevpipe.c +++ b/base/gdevpipe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevplnx.c b/base/gdevplnx.c index 3a85b6d0..e60b7565 100644 --- a/base/gdevplnx.c +++ b/base/gdevplnx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevplnx.h b/base/gdevplnx.h index 63226cbc..3104cb08 100644 --- a/base/gdevplnx.h +++ b/base/gdevplnx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevppla.c b/base/gdevppla.c index a4df7798..93c6d564 100644 --- a/base/gdevppla.c +++ b/base/gdevppla.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -132,6 +132,7 @@ gdev_prn_size_buf_planar(gx_device_buf_space_t *space, gx_device *target, mdev.pad = target->pad; mdev.log2_align_mod = target->log2_align_mod; mdev.is_planar = target->is_planar; + mdev.graphics_type_tag = target->graphics_type_tag; code = gdev_prn_set_planar(&mdev, target); if (code < 0) return code; diff --git a/base/gdevppla.h b/base/gdevppla.h index d3092f0b..466527d1 100644 --- a/base/gdevppla.h +++ b/base/gdevppla.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevprn.c b/base/gdevprn.c index 9bcc5e50..cb3fdf45 100644 --- a/base/gdevprn.c +++ b/base/gdevprn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -100,8 +100,12 @@ gdev_prn_open(gx_device * pdev) gx_copy_device_procs(pdev->parent, pdev, &gs_obj_filter_device); pdev = pdev->parent; } - if (pdev->PageHandlerPushed) + if (pdev->PageHandlerPushed) { gx_copy_device_procs(pdev->parent, pdev, &gs_flp_device); + pdev = pdev->parent; + } + if (pdev->NupHandlerPushed) + gx_copy_device_procs(pdev->parent, pdev, &gs_nup_device); } if (code < 0) return code; @@ -118,10 +122,11 @@ prn_finish_bg_print(gx_device_printer *ppdev) /* if we have a a bg printing device that was created, then wait for its */ /* semaphore (it may already have been signalled, but that's OK.) then */ /* close and unlink the files and free the device and its private allocator */ - if (ppdev->bg_print.device != NULL) { + if (ppdev->bg_print && (ppdev->bg_print->device != NULL)) { int closecode; - gx_device_printer *bgppdev = (gx_device_printer *)ppdev->bg_print.device; - gx_semaphore_wait(ppdev->bg_print.sema); + gx_device_printer *bgppdev = (gx_device_printer *)ppdev->bg_print->device; + + gx_semaphore_wait(ppdev->bg_print->sema); /* If numcopies > 1, then the bg_print->device will have closed and reopened * the output file, so the pointer in the original device is now stale, * so copy it back. @@ -129,29 +134,29 @@ prn_finish_bg_print(gx_device_printer *ppdev) */ ppdev->file = bgppdev->file; closecode = gdev_prn_close_printer((gx_device *)ppdev); - if (ppdev->bg_print.return_code == 0) - ppdev->bg_print.return_code = closecode; /* return code here iff there wasn't another error */ - teardown_device_and_mem_for_thread(ppdev->bg_print.device, - ppdev->bg_print.thread_id, true); - ppdev->bg_print.device = NULL; - if (ppdev->bg_print.ocfile) { - closecode = ppdev->bg_print.oio_procs->fclose(ppdev->bg_print.ocfile, ppdev->bg_print.ocfname, true); - if (ppdev->bg_print.return_code == 0) - ppdev->bg_print.return_code = closecode; + if (ppdev->bg_print->return_code == 0) + ppdev->bg_print->return_code = closecode; /* return code here iff there wasn't another error */ + teardown_device_and_mem_for_thread(ppdev->bg_print->device, + ppdev->bg_print->thread_id, true); + ppdev->bg_print->device = NULL; + if (ppdev->bg_print->ocfile) { + closecode = ppdev->bg_print->oio_procs->fclose(ppdev->bg_print->ocfile, ppdev->bg_print->ocfname, true); + if (ppdev->bg_print->return_code == 0) + ppdev->bg_print->return_code = closecode; } - if (ppdev->bg_print.ocfname) { - gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.ocfname, "prn_finish_bg_print(ocfname)"); + if (ppdev->bg_print->ocfname) { + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print->ocfname, "prn_finish_bg_print(ocfname)"); } - if (ppdev->bg_print.obfile) { - closecode = ppdev->bg_print.oio_procs->fclose(ppdev->bg_print.obfile, ppdev->bg_print.obfname, true); - if (ppdev->bg_print.return_code == 0) - ppdev->bg_print.return_code = closecode; + if (ppdev->bg_print->obfile) { + closecode = ppdev->bg_print->oio_procs->fclose(ppdev->bg_print->obfile, ppdev->bg_print->obfname, true); + if (ppdev->bg_print->return_code == 0) + ppdev->bg_print->return_code = closecode; } - if (ppdev->bg_print.obfname) { - gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.obfname, "prn_finish_bg_print(obfname)"); + if (ppdev->bg_print->obfname) { + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print->obfname, "prn_finish_bg_print(obfname)"); } - ppdev->bg_print.ocfile = ppdev->bg_print.obfile = - ppdev->bg_print.ocfname = ppdev->bg_print.obfname = NULL; + ppdev->bg_print->ocfile = ppdev->bg_print->obfile = + ppdev->bg_print->ocfname = ppdev->bg_print->obfname = NULL; } } /* Generic closing for the printer device. */ @@ -163,9 +168,9 @@ gdev_prn_close(gx_device * pdev) int code = 0; prn_finish_bg_print(ppdev); - if (ppdev->bg_print.sema != NULL) { - gx_semaphore_free(ppdev->bg_print.sema); - ppdev->bg_print.sema = NULL; /* prevent double free */ + if (ppdev->bg_print != NULL && ppdev->bg_print->sema != NULL) { + gx_semaphore_free(ppdev->bg_print->sema); + ppdev->bg_print->sema = NULL; /* prevent double free */ } gdev_prn_free_memory(pdev); if (ppdev->file != NULL) { @@ -213,106 +218,6 @@ gdev_prn_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); } -static int /* returns 0 ok, else -ve error cde */ -gdev_prn_setup_as_command_list(gx_device *pdev, gs_memory_t *buffer_memory, - byte **the_memory, - const gdev_space_params *space_params, - bool bufferSpace_is_exact) -{ - gx_device_printer * const ppdev = (gx_device_printer *)pdev; - gx_device *target = pdev; - uint space; - int code; - gx_device_clist *const pclist_dev = (gx_device_clist *)pdev; - gx_device_clist_common * const pcldev = &pclist_dev->common; - bool reallocate = *the_memory != 0; - byte *base; - bool save_is_open = pdev->is_open; /* Save around temporary failure in open_c loop */ - - while (target->parent != NULL) { - target = target->parent; - gx_update_from_subclass(target); - } - - /* Try to allocate based simply on param-requested buffer size */ -#ifdef DEBUGGING_HACKS -#define BACKTRACE(first_arg)\ - BEGIN\ - ulong *fp_ = (ulong *)&first_arg - 2;\ - for (; fp_ && (fp_[1] & 0xff000000) == 0x08000000; fp_ = (ulong *)*fp_)\ - dmprintf2(buffer_memory, " fp="PRI_INTPTR" ip=0x%lx\n", (intptr_t)fp_, fp_[1]);\ - END -dmputs(buffer_memory, "alloc buffer:\n"); -BACKTRACE(pdev); -#endif /*DEBUGGING_HACKS*/ - for ( space = space_params->BufferSpace; ; ) { - base = (reallocate ? - (byte *)gs_resize_object(buffer_memory, *the_memory, space, - "cmd list buffer") : - gs_alloc_bytes(buffer_memory, space, - "cmd list buffer")); - if (base != 0) - break; - if (bufferSpace_is_exact || (space >>= 1) < PRN_MIN_BUFFER_SPACE) - break; - } - if (base == 0) - return_error(gs_error_VMerror); - *the_memory = base; - - /* Try opening the command list, to see if we allocated */ - /* enough buffer space. */ -open_c: - ppdev->buf = base; - ppdev->buffer_space = space; - pclist_dev->common.orig_spec_op = dev_proc(ppdev, dev_spec_op); - clist_init_io_procs(pclist_dev, ppdev->BLS_force_memory); - clist_init_params(pclist_dev, base, space, target, - ppdev->printer_procs.buf_procs, - space_params->band, - false, /* do_not_open_or_close_bandfiles */ - (ppdev->bandlist_memory == 0 ? pdev->memory->non_gc_memory: - ppdev->bandlist_memory), - ppdev->clist_disable_mask, - ppdev->page_uses_transparency); - code = (*gs_clist_device_procs.open_device)( (gx_device *)pcldev ); - if (code < 0) { - /* If there wasn't enough room, and we haven't */ - /* already shrunk the buffer, try enlarging it. */ - if ( code == gs_error_rangecheck && - space >= space_params->BufferSpace && - !bufferSpace_is_exact - ) { - space += space / 8; - if (reallocate) { - base = gs_resize_object(buffer_memory, - *the_memory, space, - "cmd list buf(retry open)"); - if (base != 0) - *the_memory = base; - } else { - gs_free_object(buffer_memory, base, - "cmd list buf(retry open)"); - *the_memory = base = - gs_alloc_bytes(buffer_memory, space, - "cmd list buf(retry open)"); - } - ppdev->buf = *the_memory; - if (base != 0) { - pdev->is_open = save_is_open; /* allow for success when we loop */ - goto open_c; - } - } - /* Failure. */ - if (!reallocate) { - gs_free_object(buffer_memory, base, "cmd list buf"); - ppdev->buffer_space = 0; - *the_memory = 0; - } - } - return code; -} - static bool /* ret true if device was cmd list, else false */ gdev_prn_tear_down(gx_device *pdev, byte **the_memory) { @@ -387,6 +292,16 @@ gdev_prn_allocate(gx_device *pdev, gdev_space_params *new_space_params, if (reallocate) save_is_command_list = gdev_prn_tear_down(pdev, &the_memory); + + /* bg_print allocation is not fatal, we just continue (as far as possible) without BGPrint */ + if (ppdev->bg_print == NULL) + ppdev->bg_print = (bg_print_t *)gs_alloc_bytes(pdev->memory->non_gc_memory, sizeof(bg_print_t), "prn bg_print"); + if (ppdev->bg_print == NULL) { + emprintf(pdev->memory, "Failed to allocate memory for BGPrint, attempting to continue without BGPrint\n"); + } else { + memset(ppdev->bg_print, 0, sizeof(bg_print_t)); + } + /* Re/allocate memory */ ppdev->orig_procs = pdev->procs; for ( pass = 1; pass <= (reallocate ? 2 : 1); ++pass ) { @@ -505,24 +420,23 @@ gdev_prn_allocate(gx_device *pdev, gdev_space_params *new_space_params, ecode = gs_note_error(gs_error_VMerror); continue; } - ppdev->bg_print.ocfname = ppdev->bg_print.obfname = - ppdev->bg_print.obfile = ppdev->bg_print.ocfile = NULL; + if (ppdev->bg_print) { + ppdev->bg_print->ocfname = ppdev->bg_print->obfname = + ppdev->bg_print->obfile = ppdev->bg_print->ocfile = NULL; + } - code = gdev_prn_setup_as_command_list(pdev, buffer_memory, - &the_memory, &space_params, - !bufferSpace_is_default); + code = clist_mutate_to_clist((gx_device_clist_mutatable *)pdev, + buffer_memory, + &the_memory, &space_params, + !bufferSpace_is_default, + &ppdev->printer_procs.buf_procs, + gdev_prn_forwarding_dev_spec_op, + PRN_MIN_BUFFER_SPACE); if (ecode == 0) ecode = code; if (code >= 0 || (reallocate && pass > 1)) ppdev->procs = gs_clist_device_procs; - if (code > 0) { - /* - * Now the device is a clist device, we enable multi-threaded rendering. - * It will remain enabled, but that doesn't really cause any problems. - */ - clist_enable_multi_thread_render(pdev); - } } else { /* Render entirely in memory. */ gx_device *bdev = (gx_device *)pmemdev; @@ -620,6 +534,8 @@ gdev_prn_free_memory(gx_device *pdev) ppdev->buffer_memory); gdev_prn_tear_down(pdev, &the_memory); + gs_free_object(pdev->memory->non_gc_memory, ppdev->bg_print, "gdev_prn_free_memory"); + ppdev->bg_print = NULL; gs_free_object(buffer_memory, the_memory, "gdev_prn_free_memory"); return 0; } @@ -941,6 +857,7 @@ gdev_prn_put_params(gx_device * pdev, gs_param_list * plist) ppdev->OpenOutputFile = oof; ppdev->ReopenPerPage = rpp; + /* If BGPrint was previously true and it is being turned off, wait for the BG thread */ if (ppdev->bg_print_requested && !bg_print_requested) { prn_finish_bg_print(ppdev); } @@ -1035,7 +952,7 @@ gdev_prn_output_page_aux(gx_device * pdev, int num_copies, int flush, bool seeka int threads_enabled = 0; int print_foreground = 1; /* default to foreground printing */ - if (bg_print_ok && PRINTER_IS_CLIST(ppdev) && + if (bg_print_ok && PRINTER_IS_CLIST(ppdev) && ppdev->bg_print && (ppdev->bg_print_requested || ppdev->num_render_threads_requested > 0)) { threads_enabled = clist_enable_multi_thread_render(pdev); } @@ -1043,12 +960,12 @@ gdev_prn_output_page_aux(gx_device * pdev, int num_copies, int flush, bool seeka /* If there was an error, abort on this page -- no good way to handle this */ /* but it means that the error will be reported AFTER another page was */ /* interpreted and written to clist files. FIXME: ??? */ - if (ppdev->bg_print.return_code < 0) { - outcode = ppdev->bg_print.return_code; + if (ppdev->bg_print && (ppdev->bg_print->return_code < 0)) { + outcode = ppdev->bg_print->return_code; threads_enabled = 0; /* and allow current page to try foreground */ } /* Use 'while' instead of 'if' to avoid nesting */ - while (ppdev->bg_print_requested && threads_enabled) { + while (ppdev->bg_print_requested && ppdev->bg_print && threads_enabled) { gx_device *ndev; gx_device_printer *npdev; gx_device_clist_reader *crdev = (gx_device_clist_reader *)ppdev; @@ -1060,27 +977,27 @@ gdev_prn_output_page_aux(gx_device * pdev, int num_copies, int flush, bool seeka /* We need to hang onto references to these files, so we can ensure the main file data * gets freed with the correct allocator. */ - ppdev->bg_print.ocfname = + ppdev->bg_print->ocfname = (char *)gs_alloc_bytes(ppdev->memory->non_gc_memory, strnlen(crdev->page_info.cfname, gp_file_name_sizeof - 1) + 1, "gdev_prn_output_page_aux(ocfname)"); - ppdev->bg_print.obfname = + ppdev->bg_print->obfname = (char *)gs_alloc_bytes(ppdev->memory->non_gc_memory, strnlen(crdev->page_info.bfname, gp_file_name_sizeof - 1) + 1,"gdev_prn_output_page_aux(ocfname)"); - if (!ppdev->bg_print.ocfname || !ppdev->bg_print.obfname) + if (!ppdev->bg_print->ocfname || !ppdev->bg_print->obfname) break; - strncpy(ppdev->bg_print.ocfname, crdev->page_info.cfname, strnlen(crdev->page_info.cfname, gp_file_name_sizeof - 1) + 1); - strncpy(ppdev->bg_print.obfname, crdev->page_info.bfname, strnlen(crdev->page_info.bfname, gp_file_name_sizeof - 1) + 1); - ppdev->bg_print.obfile = crdev->page_info.bfile; - ppdev->bg_print.ocfile = crdev->page_info.cfile; - ppdev->bg_print.oio_procs = crdev->page_info.io_procs; + strncpy(ppdev->bg_print->ocfname, crdev->page_info.cfname, strnlen(crdev->page_info.cfname, gp_file_name_sizeof - 1) + 1); + strncpy(ppdev->bg_print->obfname, crdev->page_info.bfname, strnlen(crdev->page_info.bfname, gp_file_name_sizeof - 1) + 1); + ppdev->bg_print->obfile = crdev->page_info.bfile; + ppdev->bg_print->ocfile = crdev->page_info.cfile; + ppdev->bg_print->oio_procs = crdev->page_info.io_procs; crdev->page_info.cfile = crdev->page_info.bfile = NULL; - if (ppdev->bg_print.sema == NULL) + if (ppdev->bg_print->sema == NULL) { - ppdev->bg_print.sema = gx_semaphore_label(gx_semaphore_alloc(ppdev->memory->non_gc_memory), "BGPrint"); - if (ppdev->bg_print.sema == NULL) + ppdev->bg_print->sema = gx_semaphore_label(gx_semaphore_alloc(ppdev->memory->non_gc_memory), "BGPrint"); + if (ppdev->bg_print->sema == NULL) break; /* couldn't create the semaphore */ } @@ -1088,20 +1005,26 @@ gdev_prn_output_page_aux(gx_device * pdev, int num_copies, int flush, bool seeka if (ndev == NULL) { break; } - ppdev->bg_print.device = ndev; - ppdev->bg_print.num_copies = num_copies; + ppdev->bg_print->device = ndev; + ppdev->bg_print->num_copies = num_copies; npdev = (gx_device_printer *)ndev; npdev->bg_print_requested = 0; npdev->num_render_threads_requested = ppdev->num_render_threads_requested; + /* The bgprint's device was created with normal procs, so multi-threaded */ + /* rendering was turned off. Re-enable it now if it is needed. */ + if (npdev->num_render_threads_requested > 0) { + /* ignore return code - even if it fails, we'll output the page */ + (void)clist_enable_multi_thread_render(ndev); + } /* Now start the thread to print the page */ if ((code = gp_thread_start(prn_print_page_in_background, - (void *)&(ppdev->bg_print), - &(ppdev->bg_print.thread_id))) < 0) { + (void *)(ppdev->bg_print), + &(ppdev->bg_print->thread_id))) < 0) { /* Did not start cleanly - clean up is in print_foreground block below */ break; } - gp_thread_label(ppdev->bg_print.thread_id, "BG print thread"); + gp_thread_label(ppdev->bg_print->thread_id, "BG print thread"); /* Page was succesfully started in bg_print mode */ print_foreground = 0; /* Now we need to set up the next page so it will use new clist files */ @@ -1111,18 +1034,19 @@ gdev_prn_output_page_aux(gx_device * pdev, int num_copies, int flush, bool seeka break; /* exit the while loop */ } if (print_foreground) { - - gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.ocfname, "gdev_prn_output_page_aux(ocfname)"); - gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.obfname, "gdev_prn_output_page_aux(obfname)"); - ppdev->bg_print.ocfname = ppdev->bg_print.obfname = NULL; - - /* either bg_print was not requested or was not able to start */ - if (ppdev->bg_print.sema != NULL && ppdev->bg_print.device != NULL) { - /* There was a problem. Teardown the device and its allocator, but */ - /* leave the semaphore for possible later use. */ - teardown_device_and_mem_for_thread(ppdev->bg_print.device, - ppdev->bg_print.thread_id, true); - ppdev->bg_print.device = NULL; + if (ppdev->bg_print) { + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print->ocfname, "gdev_prn_output_page_aux(ocfname)"); + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print->obfname, "gdev_prn_output_page_aux(obfname)"); + ppdev->bg_print->ocfname = ppdev->bg_print->obfname = NULL; + + /* either bg_print was not requested or was not able to start */ + if (ppdev->bg_print->sema != NULL && ppdev->bg_print->device != NULL) { + /* There was a problem. Teardown the device and its allocator, but */ + /* leave the semaphore for possible later use. */ + teardown_device_and_mem_for_thread(ppdev->bg_print->device, + ppdev->bg_print->thread_id, true); + ppdev->bg_print->device = NULL; + } } /* Here's where we actually let the device's print_page_copies work */ /* Print the accumulated page description. */ diff --git a/base/gdevprn.h b/base/gdevprn.h index 5b2690b6..fbc7cb0c 100644 --- a/base/gdevprn.h +++ b/base/gdevprn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -141,7 +141,7 @@ typedef struct bg_print_s { bool file_is_new; /* true iff file just opened */\ gp_file *file; /* output file */\ bool bg_print_requested; /* request background printing of page from clist */\ - bg_print_t bg_print; /* background printing data shared with thread */\ + bg_print_t *bg_print; /* background printing data shared with thread */\ int num_render_threads_requested; /* for multiple band rendering threads */\ gx_saved_pages_list *saved_pages_list; /* list when we are saving pages instead of printing */\ gx_device_procs save_procs_while_delaying_erasepage /* save device procs while delaying erasepage. */ @@ -309,7 +309,7 @@ extern const gx_device_procs prn_bg_procs; 0/*false*/, /* file_is_new */\ 0, /* *file */\ 0/*false*/, /* bg_print_requested */\ - { 0/*sema*/, 0/*device*/, 0/*thread_id*/, 0/*num_copies*/, 0/*return_code*/ }, /* bg_print */\ + 0, /* *bg_print */\ 0, /* num_render_threads_requested */\ 0, /* saved_pages_list */\ { 0 } /* save_procs_while_delaying_erasepage */ diff --git a/base/gdevpxat.h b/base/gdevpxat.h index 1b70c569..651fc468 100644 --- a/base/gdevpxat.h +++ b/base/gdevpxat.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevpxen.h b/base/gdevpxen.h index e4c6b76f..fabdb451 100644 --- a/base/gdevpxen.h +++ b/base/gdevpxen.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevpxop.h b/base/gdevpxop.h index f63e30ac..6bc17649 100644 --- a/base/gdevpxop.h +++ b/base/gdevpxop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevrops.c b/base/gdevrops.c index 544593d9..13582008 100644 --- a/base/gdevrops.c +++ b/base/gdevrops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevsclass.c b/base/gdevsclass.c index dfa721f7..9ce98148 100644 --- a/base/gdevsclass.c +++ b/base/gdevsclass.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -32,6 +32,7 @@ #include "gdevprn.h" #include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ #include "gdevsclass.h" +#include "gxdevsop.h" /* * It would be nice if we could rewrite the clist handling to use this kind of device class chain @@ -123,16 +124,20 @@ int default_subclass_sync_output(gx_device *dev) { if (dev->child) return dev_proc(dev->child, sync_output)(dev->child); - else - gx_default_sync_output(dev); - - return 0; + /* else */ + return gx_default_sync_output(dev); } int default_subclass_output_page(gx_device *dev, int num_copies, int flush) { - if (dev->child) - return dev_proc(dev->child, output_page)(dev->child, num_copies, flush); + int code = 0; + + if (dev->child) { + code = dev_proc(dev->child, output_page)(dev->child, num_copies, flush); + dev->PageCount = dev->child->PageCount; + return code; + } + dev->PageCount += num_copies; /* a minor lie */ return 0; } @@ -162,10 +167,8 @@ int default_subclass_map_color_rgb(gx_device *dev, gx_color_index color, gx_colo { if (dev->child) return dev_proc(dev->child, map_color_rgb)(dev->child, color, rgb); - else - gx_default_map_color_rgb(dev, color, rgb); - - return 0; + /* else */ + return gx_default_map_color_rgb(dev, color, rgb); } int default_subclass_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color) @@ -212,19 +215,16 @@ int default_subclass_get_bits(gx_device *dev, int y, byte *data, byte **actual_d { if (dev->child) return dev_proc(dev->child, get_bits)(dev->child, y, data, actual_data); - else - return gx_default_get_bits(dev, y, data, actual_data); - return 0; + /* else */ + return gx_default_get_bits(dev, y, data, actual_data); } int default_subclass_get_params(gx_device *dev, gs_param_list *plist) { if (dev->child) return dev_proc(dev->child, get_params)(dev->child, plist); - else - return gx_default_get_params(dev, plist); - - return 0; + /* else */ + return gx_default_get_params(dev, plist); } int default_subclass_put_params(gx_device *dev, gs_param_list *plist) @@ -238,61 +238,49 @@ int default_subclass_put_params(gx_device *dev, gs_param_list *plist) gx_update_from_subclass(dev); return code; } - else - return gx_default_put_params(dev, plist); - - return 0; + /* else */ + return gx_default_put_params(dev, plist); } gx_color_index default_subclass_map_cmyk_color(gx_device *dev, const gx_color_value cv[]) { if (dev->child) return dev_proc(dev->child, map_cmyk_color)(dev->child, cv); - else - return gx_default_map_cmyk_color(dev, cv); - - return 0; + /* else */ + return gx_default_map_cmyk_color(dev, cv); } const gx_xfont_procs *default_subclass_get_xfont_procs(gx_device *dev) { if (dev->child) return dev_proc(dev->child, get_xfont_procs)(dev->child); - else - return gx_default_get_xfont_procs(dev); - - return 0; + /* else */ + return gx_default_get_xfont_procs(dev); } gx_device *default_subclass_get_xfont_device(gx_device *dev) { if (dev->child) return dev_proc(dev->child, get_xfont_device)(dev->child); - else - return gx_default_get_xfont_device(dev); - - return 0; + /* else */ + return gx_default_get_xfont_device(dev); } gx_color_index default_subclass_map_rgb_alpha_color(gx_device *dev, gx_color_value red, gx_color_value green, gx_color_value blue, gx_color_value alpha) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, map_rgb_alpha_color)(dev->child, red, green, blue, alpha); - } else - return gx_default_map_rgb_alpha_color(dev, red, green, blue, alpha); - - return 0; + /* else */ + return gx_default_map_rgb_alpha_color(dev, red, green, blue, alpha); } gx_device *default_subclass_get_page_device(gx_device *dev) { if (dev->child) return dev_proc(dev->child, get_page_device)(dev->child); - else - return gx_default_get_page_device(dev); - - return 0; + /* else */ + return gx_default_get_page_device(dev); } int default_subclass_get_alpha_bits(gx_device *dev, graphics_object_type type) @@ -315,9 +303,8 @@ int default_subclass_get_band(gx_device *dev, int y, int *band_start) { if (dev->child) return dev_proc(dev->child, get_band)(dev->child, y, band_start); - else - return gx_default_get_band(dev, y, band_start); - return 0; + /* else */ + return gx_default_get_band(dev, y, band_start); } int default_subclass_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, @@ -326,34 +313,30 @@ int default_subclass_copy_rop(gx_device *dev, const byte *sdata, int sourcex, ui int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, copy_rop)(dev->child, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); - } else - return gx_default_copy_rop(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); - return 0; + /* else */ + return gx_default_copy_rop(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); } int default_subclass_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_path)(dev->child, pgs, ppath, params, pdcolor, pcpath); - } else - return gx_default_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); - - return 0; + /* else */ + return gx_default_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); } int default_subclass_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_stroke_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, stroke_path)(dev->child, pgs, ppath, params, pdcolor, pcpath); - } else - return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); - return 0; + /* else */ + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); } int default_subclass_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, @@ -361,53 +344,48 @@ int default_subclass_fill_mask(gx_device *dev, const byte *data, int data_x, int const gx_drawing_color *pdcolor, int depth, gs_logical_operation_t lop, const gx_clip_path *pcpath) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_mask)(dev->child, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); - } else - return gx_default_fill_mask(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); - return 0; + /* else */ + return gx_default_fill_mask(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); } int default_subclass_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, fixed ybot, fixed ytop, bool swap_axes, const gx_drawing_color *pdcolor, gs_logical_operation_t lop) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_trapezoid)(dev->child, left, right, ybot, ytop, swap_axes, pdcolor, lop); - } else - return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); - return 0; + /* else */ + return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); } int default_subclass_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, const gx_drawing_color *pdcolor, gs_logical_operation_t lop) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_parallelogram)(dev->child, px, py, ax, ay, bx, by, pdcolor, lop); - } else - return gx_default_fill_parallelogram(dev, px, py, ax, ay, bx, by, pdcolor, lop); - return 0; + /* else */ + return gx_default_fill_parallelogram(dev, px, py, ax, ay, bx, by, pdcolor, lop); } int default_subclass_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, const gx_drawing_color *pdcolor, gs_logical_operation_t lop) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_triangle)(dev->child, px, py, ax, ay, bx, by, pdcolor, lop); - } else - return gx_default_fill_triangle(dev, px, py, ax, ay, bx, by, pdcolor, lop); - return 0; + /* else */ + return gx_default_fill_triangle(dev, px, py, ax, ay, bx, by, pdcolor, lop); } int default_subclass_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, const gx_drawing_color *pdcolor, gs_logical_operation_t lop, fixed adjustx, fixed adjusty) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, draw_thin_line)(dev->child, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); - } else - return gx_default_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); - return 0; + /* else */ + return gx_default_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); } int default_subclass_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, @@ -415,12 +393,10 @@ int default_subclass_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_ const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *memory, gx_image_enum_common_t **pinfo) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, begin_image)(dev->child, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); - } else - return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); - - return 0; + /* else */ + return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); } int default_subclass_image_data(gx_device *dev, gx_image_enum_common_t *info, const byte **planes, int data_x, @@ -442,11 +418,10 @@ int default_subclass_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, strip_tile_rectangle)(dev->child, tiles, x, y, width, height, color0, color1, phase_x, phase_y); - } else - return gx_default_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); - return 0; + /* else */ + return gx_default_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); } int default_subclass_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, @@ -455,11 +430,10 @@ int default_subclass_strip_copy_rop(gx_device *dev, const byte *sdata, int sourc int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, strip_copy_rop)(dev->child, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); - } else - return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); - return 0; + /* else */ + return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); } void default_subclass_get_clipping_box(gx_device *dev, gs_fixed_rect *pbox) @@ -477,38 +451,32 @@ int default_subclass_begin_typed_image(gx_device *dev, const gs_gstate *pgs, con const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *memory, gx_image_enum_common_t **pinfo) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, begin_typed_image)(dev->child, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); - } else - return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); - return 0; + /* else */ + return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); } int default_subclass_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, gs_get_bits_params_t *params, gs_int_rect **unread) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, get_bits_rectangle)(dev->child, prect, params, unread); - } else - return gx_default_get_bits_rectangle(dev, prect, params, unread); - - return 0; + /* else */ + return gx_default_get_bits_rectangle(dev, prect, params, unread); } int default_subclass_map_color_rgb_alpha(gx_device *dev, gx_color_index color, gx_color_value rgba[4]) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, map_color_rgb_alpha)(dev->child, color, rgba); - } else - return gx_default_map_color_rgb_alpha(dev, color, rgba); - - return 0; + /* else */ + return gx_default_map_color_rgb_alpha(dev, color, rgba); } int default_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) { - default_subclass_subclass_data *psubclass_data = dev->subclass_data; int code; if (dev->child) { @@ -520,35 +488,68 @@ int default_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const if (code < 0) return code; - if (*pcdev != 0L && *pcdev != dev->child){ - /* If the child created a new compositor, which it wants to be the new 'device' in the - * graphics state, it sets it in the returned pcdev variable. When we return from this - * method, if pcdev is not the same as the device in the graphics state then the interpreter - * sets pcdev as the new device in the graphics state. But because we passed in the child device - * to the child method, if it did create a compositor it will be a forwarding device, and it will - * be forwarding to our child, we need it to point to us instead. So if pcdev is not the same as the - * child device, we fixup the target in the child device to point to us. + /* *pcdev is always returned containing a device capable of doing + * compositing. This may mean it is a new device. If this wants + * to be the new 'device' in the graphics state, then code will + * return as 1. */ + if (code == 1) { + /* The device chain on entry to this function was: + * dev(the subclassing device) -> child. + * But now we also have: + * *pcdev -> child. + * Or in some cases: + * *pcdev (-> other device)* -> child + * Most callers would be happy to make dev->child = *pcdev, + * thus giving us: + * dev -> *pcdev (-> other device)* ->child + * Unfortunately, we are not happy with that. We need to + * remain tightly bound to the child. i.e. we are aiming for: + * *pcdev (-> other device)* -> dev -> child + * Accordingly, we need to move ourselves within the device + * chain. */ - gx_device_forward *fdev = (gx_device_forward *)*pcdev; - - if (fdev->target == dev->child) { - if (gs_is_pdf14trans_compositor(pcte) != 0 && strncmp(fdev->dname, "pdf14clist", 10) == 0) { - pdf14_clist_device *p14dev; + gx_device *penult = *pcdev; - p14dev = (pdf14_clist_device *)*pcdev; - - dev->color_info = dev->child->color_info; + if (penult == NULL) { + /* This should never happen. */ + return gs_error_unknownerror; + } - psubclass_data->saved_compositor_method = p14dev->procs.create_compositor; - psubclass_data->forwarding_dev = fdev; - p14dev->procs.create_compositor = gx_subclass_create_compositor; + /* Find the penultimate device. */ + while (1) { + gxdso_device_child_request req; + req.target = penult; + req.n = 0; + code = dev_proc(penult, dev_spec_op)(penult, gxdso_device_child, &req, sizeof(req)); + if (code < 0) + return code; + if (req.target == NULL) { + /* Wooah! Where was dev->child? */ + return gs_error_unknownerror; } + if (req.target == dev->child) + break; /* penult is the parent. */ + penult = req.target; + } - fdev->target = dev; - rc_decrement_only(dev->child, "first-last page compositor code"); - rc_increment(dev); + if (penult == NULL) { + /* This should never happen. We know that we've just + * had a compositor inserted before dev->child, so there + * really ought to be one! */ + return gs_error_unknownerror; } - return_error(gs_error_handled); + + /* We already point to dev->child, and hence own a reference + * to it. */ + + /* Now insert ourselves as the child of the penultimate one. */ + code = dev_proc(penult, dev_spec_op)(penult, gxdso_device_insert_child, dev, 0); + if (code < 0) + return code; + + /* Now we want our caller to update itself to recognise that + * *pcdev should be its child, not dev. So we return 1. */ + return 1; } else { /* See the 2 comments above. Now, if the child did not create a new compositor (eg its a clist) @@ -567,24 +568,20 @@ int default_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const int default_subclass_get_hardware_params(gx_device *dev, gs_param_list *plist) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, get_hardware_params)(dev->child, plist); - } else - return gx_default_get_hardware_params(dev, plist); - - return 0; + /* else */ + return gx_default_get_hardware_params(dev, plist); } int default_subclass_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *memory, gs_text_enum_t **ppte) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, text_begin)(dev->child, pgs, text, font, path, pdcolor, pcpath, memory, ppte); - } else - return gx_default_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); - - return 0; + /* else */ + return gx_default_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); } /* This method seems (despite the name) to be intended to allow for @@ -626,6 +623,7 @@ int default_subclass_end_transparency_mask(gx_device *dev, gs_gstate *pgs) { if (dev->child) return dev_proc(dev->child, end_transparency_mask)(dev->child, pgs); + return 0; } @@ -639,32 +637,26 @@ int default_subclass_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, get_color_mapping_procs)(dev->child); - } else - return gx_default_DevGray_get_color_mapping_procs(dev); - - return 0; + /* else */ + return gx_default_DevGray_get_color_mapping_procs(dev); } int default_subclass_get_color_comp_index(gx_device *dev, const char * pname, int name_size, int component_type) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, get_color_comp_index)(dev->child, pname, name_size, component_type); - } else - return gx_error_get_color_comp_index(dev, pname, name_size, component_type); - - return 0; + /* else */ + return gx_error_get_color_comp_index(dev, pname, name_size, component_type); } gx_color_index default_subclass_encode_color(gx_device *dev, const gx_color_value colors[]) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, encode_color)(dev->child, colors); - } else - return gx_error_encode_color(dev, colors); - - return 0; + /* else */ + return gx_error_encode_color(dev, colors); } int default_subclass_decode_color(gx_device *dev, gx_color_index cindex, gx_color_value colors[]) @@ -692,10 +684,8 @@ int default_subclass_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect { if (dev->child) return dev_proc(dev->child, fill_rectangle_hl_color)(dev->child, rect, pgs, pdcolor, pcpath); - else - return_error(gs_error_rangecheck); - - return 0; + /* else */ + return_error(gs_error_rangecheck); } int default_subclass_include_color_space(gx_device *dev, gs_color_space *cspace, const byte *res_name, int name_length) @@ -710,12 +700,10 @@ int default_subclass_fill_linear_color_scanline(gx_device *dev, const gs_fill_at int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, int32_t cg_den) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_linear_color_scanline)(dev->child, fa, i, j, w, c0, c0_f, cg_num, cg_den); - } else - return gx_default_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); - - return 0; + /* else */ + return gx_default_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); } int default_subclass_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, @@ -724,24 +712,20 @@ int default_subclass_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_a const frac31 *c0, const frac31 *c1, const frac31 *c2, const frac31 *c3) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_linear_color_trapezoid)(dev->child, fa, p0, p1, p2, p3, c0, c1, c2, c3); - } else - return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); - - return 0; + /* else */ + return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); } int default_subclass_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, const gs_fixed_point *p0, const gs_fixed_point *p1, const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fill_linear_color_triangle)(dev->child, fa, p0, p1, p2, c0, c1, c2); - } else - return gx_default_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2); - - return 0; + /* else */ + return gx_default_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2); } int default_subclass_update_spot_equivalent_colors(gx_device *dev, const gs_gstate * pgs) @@ -762,12 +746,10 @@ gs_devn_params *default_subclass_ret_devn_params(gx_device *dev) int default_subclass_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) { - if (dev->child) { + if (dev->child) return dev_proc(dev->child, fillpage)(dev->child, pgs, pdevc); - } else - return gx_default_fillpage(dev, pgs, pdevc); - - return 0; + /* else */ + return gx_default_fillpage(dev, pgs, pdevc); } int default_subclass_push_transparency_state(gx_device *dev, gs_gstate *pgs) @@ -803,6 +785,15 @@ int default_subclass_put_image(gx_device *dev, gx_device *mdev, const byte **buf int default_subclass_dev_spec_op(gx_device *dev, int op, void *data, int datasize) { + if (op == gxdso_is_clist_device) + return 0; + if (op == gxdso_device_child) { + gxdso_device_child_request *d = (gxdso_device_child_request *)data; + if (d->target == dev) { + d->target = dev->child; + return 1; + } + } if (dev->child) return dev_proc(dev->child, dev_spec_op)(dev->child, op, data, datasize); @@ -823,11 +814,8 @@ int default_subclass_get_profile(gx_device *dev, cmm_dev_profile_t **dev_profile if (dev->child) { return dev_proc(dev->child, get_profile)(dev->child, dev_profile); } - else { - return gx_default_get_profile(dev, dev_profile); - } - - return 0; + /* else */ + return gx_default_get_profile(dev, dev_profile); } /* In a delightful asymmetry, we have a set_graphics_type_tag, but no get_graphics_type_tag. Instead @@ -868,10 +856,8 @@ int default_subclass_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap { if (dev->child) return dev_proc(dev->child, strip_tile_rect_devn)(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); - else - return gx_default_strip_tile_rect_devn(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); - - return 0; + /* else */ + return gx_default_strip_tile_rect_devn(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); } int default_subclass_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, @@ -880,10 +866,8 @@ int default_subclass_copy_alpha_hl_color(gx_device *dev, const byte *data, int d { if (dev->child) return dev_proc(dev->child, copy_alpha_hl_color)(dev->child, data, data_x, raster, id, x, y, width, height, pdcolor, depth); - else - return_error(gs_error_rangecheck); - - return 0; + /* else */ + return_error(gs_error_rangecheck); } int default_subclass_process_page(gx_device *dev, gx_process_page_options_t *options) @@ -942,4 +926,6 @@ void default_subclass_finalize(const gs_memory_t *cmem, void *vptr) rc_decrement(dev->icc_struct, "finalize subclass device"); if (dev->PageList) rc_decrement(dev->PageList, "finalize subclass device"); + if (dev->NupControl) + rc_decrement(dev->NupControl, "finalize subclass device"); } diff --git a/base/gdevsclass.h b/base/gdevsclass.h index e020e2c4..aface183 100644 --- a/base/gdevsclass.h +++ b/base/gdevsclass.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevvec.c b/base/gdevvec.c index 3204720f..d2694207 100644 --- a/base/gdevvec.c +++ b/base/gdevvec.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gdevvec.h b/base/gdevvec.h index 3ce08b2c..b7476229 100644 --- a/base/gdevvec.h +++ b/base/gdevvec.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gen_ordered.c b/base/gen_ordered.c index e34e6202..e1cccb4e 100644 --- a/base/gen_ordered.c +++ b/base/gen_ordered.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -23,6 +23,7 @@ #include "string_.h" #include "gsmemory.h" #include "math_.h" +#include "gp.h" # define ALLOC(mem, size) (gs_alloc_bytes((gs_memory_t *)mem, size, "gen_ordered")) # define FREE(mem, ptr) gs_free_object((gs_memory_t *)mem, ptr, "gen_ordered") @@ -34,6 +35,15 @@ # define EPRINTF(mem, str) errprintf((gs_memory_t *)mem, str) # define EPRINTF1(mem, str, v1) errprintf((gs_memory_t *)mem, str, v1) # define EPRINTF3(mem, str, v1, v2, v3) errprintf((gs_memory_t *)mem, str, v1, v2, v3) +# define _FILE gp_file +# define FOPEN(mem, v1, v2) gp_fopen(mem, v1, v2) +# define FCLOSE(fid) gp_fclose(fid) +# define FPRINTF(fid, str) gp_fprintf(fid, str) +# define FPRINTF1(fid, str, v1) gp_fprintf(fid, str, v1) +# define FPRINTF2(fid, str, v1, v2) gp_fprintf(fid, str, v1, v2) +# define FPRINTF6(fid, str, v1, v2, v3, v4, v5, v6) gp_fprintf(fid, str, v1, v2, v3, v4, v5, v6) +# define FWRITE(v1, v2, v3, fid) gp_fwrite(v1, v2, v3, fid) + #endif /* defined GS_LIB_BUILD */ @@ -64,6 +74,14 @@ typedef unsigned char byte; # define EPRINTF(mem, str) fprintf(stderr, str) # define EPRINTF1(mem, str, v1) fprintf(stderr, str, v1) # define EPRINTF3(mem, str, v1, v2, v3) fprintf(stderr, str, v1, v2, v3) +# define _FILE FILE +# define FOPEN(mem, v1, v2) fopen(v1, v2) +# define FCLOSE(fid) fclose(fid) +# define FPRINTF(fid, str) fprintf(fid, str) +# define FPRINTF1(fid, str, v1) fprintf(fid, str, v1) +# define FPRINTF2(fid, str, v1, v2) fprintf(fid, str, v1, v2) +# define FPRINTF6(fid, str, v1, v2, v3, v4, v5, v6) fprintf(fid, str, v1, v2, v3, v4, v5, v6) +# define FWRITE(v1, v2, v3, fid) fwrite(v1, v2, v3, fid) #endif /* ndef LIB_BUILD */ @@ -124,15 +142,16 @@ static int htsc_allocate_supercell(htsc_dig_grid_t *super_cell, int x, int y, in htsc_dig_grid_t dot_grid, int N, int *S, int *H, int *L); static void htsc_tile_supercell(htsc_dig_grid_t *super_cell, htsc_dig_grid_t *dot_grid, int x, int y, int u, int v, int N); -void create_2d_gauss_filter(double *filter, int x_size, int y_size, - double stdvalx, double stdvaly); +int create_2d_gauss_filter(double *filter, int x_size, int y_size, + double stdvalx, double stdvaly, gs_memory_t *mem); static int htsc_create_holladay_mask(htsc_dig_grid_t super_cell, int H, int L, double gamma, htsc_dig_grid_t *final_mask); static int htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, int verbose, int num_levels, int y, int x, double vert_dpi, double horiz_dpi, int N, double gamma, - htsc_dig_grid_t dot_grid, htsc_point_t one_index); + htsc_dig_grid_t dot_grid, htsc_point_t one_index, + gs_memory_t *mem); static int htsc_create_nondithered_mask(htsc_dig_grid_t super_cell, int H, int L, double gamma, htsc_dig_grid_t *final_mask); static int htsc_gcd(int a, int b); @@ -142,11 +161,11 @@ static void htsc_matrix_vector_mult(htsc_matrix_t matrix_in, htsc_vector_t vecto htsc_vector_t *vector_out); static int htsc_mask_to_tos(htsc_dig_grid_t *final_mask); #if RAW_SCREEN_DUMP -static void htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]); -static void htsc_dump_float_image(double *image, int height, int width, double max_val, - char filename[]); -static void htsc_dump_byte_image(byte *image, int height, int width, double max_val, - char filename[]); +static int htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[], gs_memory_t *mem); +static int htsc_dump_float_image(double *image, int height, int width, double max_val, + char filename[], gs_memory_t *mem); +static int htsc_dump_byte_image(byte *image, int height, int width, double max_val, + char filename[], gs_memory_t *mem); #endif /* Initialize default values */ @@ -169,7 +188,7 @@ void htsc_set_default_params(htsc_param_t *params) } int -htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) +htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask, gs_memory_t *mem) { int num_levels; int x=0, y=0, v=0, u=0, N=0; @@ -231,10 +250,12 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) on sequence or dot profile */ code = htsc_create_dot_mask(&dot_grid, x, y, u, v, params.scr_ang, vertices); if (code < 0) { - return -1; + return code; } #if RAW_SCREEN_DUMP - htsc_dump_screen(&dot_grid, "mask"); + code = htsc_dump_screen(&dot_grid, "mask", mem); + if (code < 0) + return code; #endif /* A sanity check */ if (htsc_sumsum(dot_grid) != -N) { @@ -255,7 +276,9 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) params.spot_type, trans_matrix_inv); #if RAW_SCREEN_DUMP - htsc_dump_screen(&dot_grid, "dot_profile"); + code = htsc_dump_screen(&dot_grid, "dot_profile", mem); + if (code < 0) + return code; #endif /* Allocate super cell */ code = htsc_allocate_supercell(&super_cell, x, y, u, v, params.targ_size, @@ -279,7 +302,9 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) /* Go ahead and fill up the super cell grid with our growth dot values */ htsc_tile_supercell(&super_cell, &dot_grid, x, y, u, v, N); #if RAW_SCREEN_DUMP - htsc_dump_screen(&super_cell, "super_cell_tiled"); + code = htsc_dump_screen(&super_cell, "super_cell_tiled", mem); + if (code < 0) + return code; #endif /* If we are using the Holladay grid (non dithered) then we are done. */ if (params.holladay) { @@ -302,7 +327,7 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) } code = htsc_create_dither_mask(super_cell, final_mask, params.verbose, num_levels, y, x, params.vert_dpi, params.horiz_dpi, N, - params.gamma, dot_grid, one_index); + params.gamma, dot_grid, one_index, mem); } } final_mask->bin_center = bin_center; @@ -1136,9 +1161,9 @@ htsc_tile_supercell(htsc_dig_grid_t *super_cell, htsc_dig_grid_t *dot_grid, /* Create 2d gaussian filter that varies with respect to coordinate spatial resolution */ -void +int create_2d_gauss_filter(double *filter, int x_size, int y_size, - double stdvalx, double stdvaly) + double stdvalx, double stdvaly, gs_memory_t *mem) { int x_half_size = (x_size-1)/2; int y_half_size = (y_size-1)/2; @@ -1148,6 +1173,7 @@ create_2d_gauss_filter(double *filter, int x_size, int y_size, double max_val = 0; int total_size = x_size * y_size; int index_x, index_y; + int code = 0; for (j = -y_half_size; j < y_half_size+1; j++) { index_y = j + y_half_size; @@ -1165,8 +1191,9 @@ create_2d_gauss_filter(double *filter, int x_size, int y_size, filter[j]/=sum; } #if RAW_SCREEN_DUMP - htsc_dump_float_image(filter, y_size, x_size, max_val/sum, "guass_filt"); + code = htsc_dump_float_image(filter, y_size, x_size, max_val/sum, "guass_filt", mem); #endif + return code; } /* 2-D convolution (or correlation) with periodic boundary condition */ @@ -1256,6 +1283,7 @@ htsc_add_dots(byte *screen_matrix, int num_cols, int num_rows, int k,j; int dist, curr_dist; htsc_dither_pos_t curr_position; + int code; sizefiltx = ROUND(sigma_x * 4); sizefilty = ROUND(sigma_y * 4); @@ -1268,7 +1296,10 @@ htsc_add_dots(byte *screen_matrix, int num_cols, int num_rows, filter = (double*) ALLOC(mem, sizeof(double) * sizefilty * sizefiltx); if (filter == NULL) return -1; - create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty); + code = create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty, mem); + if (code < 0) + return code; + screen_blur = (double*)ALLOC(mem, sizeof(double) * num_cols * num_rows); if (screen_blur == NULL) { FREE(mem, filter); @@ -1327,6 +1358,7 @@ htsc_init_dot_position(byte *screen_matrix, int num_cols, int num_rows, int k; int dist, curr_dist; bool found_it; + int code = 0; sizefiltx = ROUND(sigma_x * 4); sizefilty = ROUND(sigma_y * 4); @@ -1339,7 +1371,10 @@ htsc_init_dot_position(byte *screen_matrix, int num_cols, int num_rows, filter = (double*) ALLOC(mem, sizeof(double) * sizefilty * sizefiltx); if (filter == NULL) return -1; - create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty); + code = create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty, mem); + if (code < 0) + return code; + screen_blur = (double*) ALLOC(mem, sizeof(double) * num_cols * num_rows); if (screen_blur == NULL) { FREE(mem, filter); @@ -1351,7 +1386,9 @@ htsc_init_dot_position(byte *screen_matrix, int num_cols, int num_rows, htsc_apply_filter(screen_matrix, num_cols, num_rows, filter, sizefiltx, sizefilty, screen_blur, &max_val, &max_pos, &min_val, &min_pos); #if RAW_SCREEN_DUMP - htsc_dump_float_image(screen_blur, num_cols, num_rows, max_val, "blur_one"); + code = htsc_dump_float_image(screen_blur, num_cols, num_rows, max_val, "blur_one", mem); + if (code < 0) + return code; #endif /* Find the closest on dot to the max position */ black_pos = 0; @@ -1425,7 +1462,8 @@ static int htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, int verbose, int num_levels, int y, int x, double vert_dpi, double horiz_dpi, int N, double gamma, - htsc_dig_grid_t dot_grid, htsc_point_t dot_grid_one_index) + htsc_dig_grid_t dot_grid, htsc_point_t dot_grid_one_index, + gs_memory_t *mem) { int *dot_levels = NULL; int *locate = NULL; @@ -1562,8 +1600,10 @@ htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, } } #if RAW_SCREEN_DUMP - htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, - 1, "screen0_init"); + code = htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, "screen0_init", mem); + if (code < 0) + goto out; #endif /* Rearrange these dots into a pleasing pattern, but only if there is * more than 1. Otherwise there are none to move */ @@ -1574,8 +1614,10 @@ htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, if (code < 0) goto out; #if RAW_SCREEN_DUMP - htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, - 1, "screen0_arrange"); + code = htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, "screen0_arrange", mem); + if (code < 0) + goto out; #endif /* Now we want to introduce more dots at each level */ for (k = 1; k < num_levels; k++) { @@ -1589,8 +1631,10 @@ htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, { char str_name[30]; snprintf(str_name, 30, "screen%d_arrange",k); - htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, - 1, str_name); + code = htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, str_name, mem); + if (code < 0) + goto out; } #endif } @@ -1926,13 +1970,161 @@ htsc_spot_value(spottype_t spot_type, double x, double y) } } +#if FINAL_SCREEN_DUMP + +/* Save turn on order list, Assume that htsc_gen_ordered has already converted to TOS */ +static int +htsc_save_tos(htsc_dig_grid_t *final_mask, gs_memory_t *mem) +{ + int width = final_mask->width; + int height = final_mask->height; + int *buff_ptr; + _FILE *fid; + int k = 0; + int count = height * width; + + fid = FOPEN(mem, "turn_on_seq.out", "w"); + if (fid == NULL) + return -1; + + FPRINTF2(fid, "# W=%d H=%d\n", width, height); + + /* Write out */ + buff_ptr = final_mask->data; + for (k = 0; k < count; k++) { + FPRINTF2(fid, "%d\t%d\n", *buff_ptr++, *buff_ptr++); + } + FCLOSE(fid); + return 0; +} + +int +htsc_save_screen(htsc_dig_grid_t *final_mask, bool use_holladay_grid, int S, + htsc_param_t params, gs_memory_t *mem) +{ + char full_file_name[FULL_FILE_NAME_LENGTH]; + _FILE *fid; + int x, y, code = 0; + int *buff_ptr = final_mask->data; + int width = final_mask->width; + int height = final_mask->height; + byte data; + unsigned short data_short; + output_format_type output_format = params.output_format; + char *output_extension = (output_format == OUTPUT_PS) ? "ps" : + ((output_format == OUTPUT_PPM) ? "ppm" : + ((output_format == OUTPUT_RAW16 ? "16.raw" : "raw"))); + + if (output_format == OUTPUT_TOS) { + /* We need to figure out the turn-on sequence from the threshold + array */ + code = htsc_save_tos(final_mask, mem); + } else { + if (use_holladay_grid) { + snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_Holladay_Shift%d_%dx%d.%s", S, width, + height, output_extension); + } else { + snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_Dithered_%dx%d.%s", width, height, + output_extension); + } + fid = FOPEN(mem, full_file_name, "wb"); + if (fid == NULL) + return -1; + + if (output_format == OUTPUT_PPM) + FPRINTF6(fid, "P5\n" + "# Halftone threshold array, %s, [%d, %d], S=%d\n" + "%d %d\n" + "255\n", + use_holladay_grid ? "Holladay_Shift" : "Dithered", width, height, + S, width, height); + if (output_format != OUTPUT_PS) { + /* Both BIN and PPM format write the same binary data */ + if (output_format == OUTPUT_RAW || output_format == OUTPUT_PPM) { + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + data_short = (unsigned short)(*buff_ptr & 0xffff); + data_short = ROUND((double)data_short * 255.0 / MAXVAL); + if (data_short > 255) data_short = 255; + data = (byte)(data_short & 0xff); + FWRITE(&data, sizeof(byte), 1, fid); + buff_ptr++; + } + } + } else { /* raw16 data */ + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + data_short = (unsigned short)(*buff_ptr & 0xffff); + FWRITE(&data_short, sizeof(short), 1, fid); + buff_ptr++; + } + } + } + } else { /* ps output format */ + if (params.targ_quant <= 256) { + /* Output PS HalftoneType 3 dictionary */ + FPRINTF2(fid, "%%!PS\n" + "<< /HalftoneType 3\n" + " /Width %d\n" + " /Height %d\n" + " /Thresholds <\n", + width, height); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + data_short = (unsigned short)(*buff_ptr & 0xffff); + data_short = ROUND((double)data_short * 255.0 / MAXVAL); + if (data_short > 255) data_short = 255; + data = (byte)(data_short & 0xff); + FPRINTF1(fid, "%02x", data); + buff_ptr++; + if ((x & 0x1f) == 0x1f && (x != (width - 1))) + FPRINTF(fid, "\n"); + } + FPRINTF(fid, "\n"); + } + FPRINTF(fid, " >\n" + ">>\n" + ); + } else { + /* Output PS HalftoneType 16 dictionary. Single array. */ + FPRINTF(fid, "%%!PS\n" + "%% Create a 'filter' from local hex data\n" + "{ currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter } exec\n"); + /* hex data follows, 'file' object will be left on stack */ + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + data_short = (unsigned short)(*buff_ptr & 0xffff); + FPRINTF1(fid, "%04x", data_short); + buff_ptr++; + if ((x & 0x1f) == 0x1f && (x != (width - 1))) + FPRINTF(fid, "\n"); + } + FPRINTF(fid, "\n"); /* end of one row */ + } + FPRINTF(fid, ">\n"); /* ASCIIHexDecode EOF */ + FPRINTF2(fid, + "<< /Thresholds 2 index %% file object for the 16-bit data\n" + " /HalftoneType 16\n" + " /Width %d\n" + " /Height %d\n" + ">>\n" + "exch pop %% discard ResuableStreamDecode file leaving the Halftone dict.\n", + width, height); + } + } + FCLOSE(fid); + } + return code; +} +#endif + #if RAW_SCREEN_DUMP -void -static -htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]) +static int +htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[], gs_memory_t *mem) { char full_file_name[FULL_FILE_NAME_LENGTH]; - FILE *fid; + _FILE *fid; int x,y; int *buff_ptr = dig_grid->data; int width = dig_grid->width; @@ -1940,7 +2132,9 @@ htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]) byte data[3]; snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_%s_%dx%dx3.raw",filename,width,height); - fid = fopen(full_file_name,"wb"); + fid = FOPEN(mem, full_file_name,"wb"); + if (fid == NULL) + return -1; for (y = 0; y < height; y++) { for ( x = 0; x < width; x++ ) { @@ -1957,58 +2151,67 @@ htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]) data[1] = *buff_ptr; data[2] = *buff_ptr; } - fwrite(data,sizeof(unsigned char),3,fid); + FWRITE(data,sizeof(unsigned char),3,fid); buff_ptr++; } } - fclose(fid); + FCLOSE(fid); + return 0; } -static void +static int htsc_dump_float_image(double *image, int height, int width, double max_val, - char filename[]) + char filename[], gs_memory_t *mem) { char full_file_name[FULL_FILE_NAME_LENGTH]; - FILE *fid; + _FILE *fid; int x,y; int data; byte data_byte; snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Float_%s_%dx%d.raw",filename,width,height); - fid = fopen(full_file_name,"wb"); + fid = FOPEN(mem, full_file_name,"wb"); + if (fid == NULL) + return -1; + for (y = 0; y < height; y++) { for ( x = 0; x < width; x++ ) { data = (255.0 * image[x + y * width] / max_val); if (data > 255) data = 255; if (data < 0) data = 0; data_byte = data; - fwrite(&data_byte,sizeof(byte),1,fid); + FWRITE(&data_byte,sizeof(byte),1,fid); } } - fclose(fid); + FCLOSE(fid); + return 0; } -static void +static int htsc_dump_byte_image(byte *image, int height, int width, double max_val, - char filename[]) + char filename[], gs_memory_t *mem) { char full_file_name[FULL_FILE_NAME_LENGTH]; - FILE *fid; + _FILE *fid; int x,y; int data; byte data_byte; snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "ByteScaled_%s_%dx%d.raw",filename,width,height); - fid = fopen(full_file_name,"wb"); + fid = FOPEN(mem, full_file_name,"wb"); + if (fid == NULL) + return -1; + for (y = 0; y < height; y++) { for ( x = 0; x < width; x++ ) { data = (255.0 * image[x + y * width] / max_val); if (data > 255) data = 255; if (data < 0) data = 0; data_byte = data; - fwrite(&data_byte,sizeof(byte),1,fid); + FWRITE(&data_byte,sizeof(byte),1,fid); } } - fclose(fid); + FCLOSE(fid); + return 0; } #endif diff --git a/base/gen_ordered.h b/base/gen_ordered.h index 30024773..e602c367 100644 --- a/base/gen_ordered.h +++ b/base/gen_ordered.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -23,7 +23,10 @@ #ifndef RAW_SCREEN_DUMP # define RAW_SCREEN_DUMP 0 /* Noisy output for .raw files for detailed debugging */ #endif -#if RAW_SCREEN_DUMP || !defined(LIB_BUILD) +#ifndef FINAL_SCREEN_DUMP +# define FINAL_SCREEN_DUMP 0 /* Dump of the final PS result */ +#endif +#if RAW_SCREEN_DUMP || FINAL_SCREEN_DUMP || !defined(LIB_BUILD) # define FULL_FILE_NAME_LENGTH 50 #endif @@ -100,6 +103,11 @@ void htsc_set_default_params(htsc_param_t *params); Note that final_mask.memory must be set as needed for the allocator and it is the callers responsibilty to free the final_mask.data that is returned. */ -int htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask); +int htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask, gs_memory_t *mem); + +#if FINAL_SCREEN_DUMP +int htsc_save_screen(htsc_dig_grid_t *final_mask, bool use_holladay_grid, int S, + htsc_param_t params, gs_memory_t *mem); +#endif #endif diff --git a/base/genarch.c b/base/genarch.c index 6953c190..554ee322 100644 --- a/base/genarch.c +++ b/base/genarch.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/genconf.c b/base/genconf.c index 58b271c0..09384bdd 100644 --- a/base/genconf.c +++ b/base/genconf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gendev.c b/base/gendev.c index 8001e26a..97dac7f6 100644 --- a/base/gendev.c +++ b/base/gendev.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/genht.c b/base/genht.c index 7b46a051..cccfdd60 100644 --- a/base/genht.c +++ b/base/genht.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp.h b/base/gp.h index 3321c4e6..b58206b5 100644 --- a/base/gp.h +++ b/base/gp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_dosfe.c b/base/gp_dosfe.c index abea97c8..9093ed51 100644 --- a/base/gp_dosfe.c +++ b/base/gp_dosfe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_dosfs.c b/base/gp_dosfs.c index 76779ad5..4c663e56 100644 --- a/base/gp_dosfs.c +++ b/base/gp_dosfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_dvx.c b/base/gp_dvx.c index 52918cee..21e7f03c 100644 --- a/base/gp_dvx.c +++ b/base/gp_dvx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_getnv.c b/base/gp_getnv.c index 5eab3e34..06ca6aa1 100644 --- a/base/gp_getnv.c +++ b/base/gp_getnv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_mktmp.c b/base/gp_mktmp.c index 5ecef5d7..bfadccbb 100644 --- a/base/gp_mktmp.c +++ b/base/gp_mktmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_msdll.c b/base/gp_msdll.c index 040dd69f..f15d04e6 100644 --- a/base/gp_msdll.c +++ b/base/gp_msdll.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_msdos.c b/base/gp_msdos.c index 16b6e1fe..13beecc5 100644 --- a/base/gp_msdos.c +++ b/base/gp_msdos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_mshdl.c b/base/gp_mshdl.c index 8bc04a1c..2b964ed7 100644 --- a/base/gp_mshdl.c +++ b/base/gp_mshdl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_mslib.c b/base/gp_mslib.c index 3f62985c..84f693f0 100644 --- a/base/gp_mslib.c +++ b/base/gp_mslib.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_mspol.c b/base/gp_mspol.c index 7dc80602..560fb3fe 100644 --- a/base/gp_mspol.c +++ b/base/gp_mspol.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_msprn.c b/base/gp_msprn.c index 758b8a55..ed482796 100644 --- a/base/gp_msprn.c +++ b/base/gp_msprn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_mswin.c b/base/gp_mswin.c index 1415cc82..a44edf99 100644 --- a/base/gp_mswin.c +++ b/base/gp_mswin.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_mswin.h b/base/gp_mswin.h index bf187903..9e2d6578 100644 --- a/base/gp_mswin.h +++ b/base/gp_mswin.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_nsync.c b/base/gp_nsync.c index 32bb772d..cb16fa30 100644 --- a/base/gp_nsync.c +++ b/base/gp_nsync.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_ntfs.c b/base/gp_ntfs.c index 4bcbc341..fc6fe6a9 100644 --- a/base/gp_ntfs.c +++ b/base/gp_ntfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -22,6 +22,7 @@ #include #include #include +#include "malloc_.h" #include "memory_.h" #include "string_.h" #include "gstypes.h" diff --git a/base/gp_nxpsprn.c b/base/gp_nxpsprn.c index e74d64a3..84aacb06 100644 --- a/base/gp_nxpsprn.c +++ b/base/gp_nxpsprn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_os2.c b/base/gp_os2.c index 26a1165b..52f82565 100644 --- a/base/gp_os2.c +++ b/base/gp_os2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_os2.h b/base/gp_os2.h index a0b72c03..7def052e 100644 --- a/base/gp_os2.h +++ b/base/gp_os2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_os2fs.c b/base/gp_os2fs.c index 943d9458..a7dad917 100644 --- a/base/gp_os2fs.c +++ b/base/gp_os2fs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_os2pr.c b/base/gp_os2pr.c index ebbc50b3..f852c71f 100644 --- a/base/gp_os2pr.c +++ b/base/gp_os2pr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_os9.c b/base/gp_os9.c index 190b1277..37b4cfb8 100644 --- a/base/gp_os9.c +++ b/base/gp_os9.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_paper.c b/base/gp_paper.c index f4677338..16ca8441 100644 --- a/base/gp_paper.c +++ b/base/gp_paper.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_psync.c b/base/gp_psync.c index 6d2c583e..7fc177fa 100644 --- a/base/gp_psync.c +++ b/base/gp_psync.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -215,7 +215,7 @@ gp_monitor_open(gp_monitor * mona) if (scode < 0) { goto done; } -#else +#else ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ ((gp_pthread_recursive_t *)mona)->lcount = 0; #endif diff --git a/base/gp_stdia.c b/base/gp_stdia.c index 07da07e7..2b3ede79 100644 --- a/base/gp_stdia.c +++ b/base/gp_stdia.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_stdin.c b/base/gp_stdin.c index 68230cdd..bb8ea16c 100644 --- a/base/gp_stdin.c +++ b/base/gp_stdin.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_strdl.c b/base/gp_strdl.c index b6b345c0..d8a2f516 100644 --- a/base/gp_strdl.c +++ b/base/gp_strdl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -21,7 +21,7 @@ #include "gp.h" int -gp_readline_init(void **preadline_data, gs_memory_t * mem) +gp_readline_init(void **preadline_data, gs_memory_t * mem) /* lgtm [cpp/useless-expression] */ { return 0; } diff --git a/base/gp_unifn.c b/base/gp_unifn.c index bbba02a4..c5a3795d 100644 --- a/base/gp_unifn.c +++ b/base/gp_unifn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_unifs.c b/base/gp_unifs.c index dea5c6da..a007ddce 100644 --- a/base/gp_unifs.c +++ b/base/gp_unifs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -247,7 +247,7 @@ int gp_pwrite_impl(const char *buf, size_t count, gs_offset_t offset, FILE *f) /* Set a file into binary or text mode. */ int -gp_setmode_binary_impl(FILE * pfile, bool mode) +gp_setmode_binary_impl(FILE * pfile, bool mode) /* lgtm [cpp/useless-expression] */ { return 0; /* Noop under Unix */ } diff --git a/base/gp_unix.c b/base/gp_unix.c index e4599508..420f7526 100644 --- a/base/gp_unix.c +++ b/base/gp_unix.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_upapr.c b/base/gp_upapr.c index a3f56c00..8732c4f8 100644 --- a/base/gp_upapr.c +++ b/base/gp_upapr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_vms.c b/base/gp_vms.c index 1d31815b..55dd93bc 100644 --- a/base/gp_vms.c +++ b/base/gp_vms.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_wgetv.c b/base/gp_wgetv.c index 0f634214..f919e1f8 100644 --- a/base/gp_wgetv.c +++ b/base/gp_wgetv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_win32.c b/base/gp_win32.c index ed6516b2..e04a7e45 100644 --- a/base/gp_win32.c +++ b/base/gp_win32.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -70,24 +70,16 @@ gp_get_realtime(long *pdt) void gp_get_usertime(long *pdt) { + FILETIME CreationTime, ExitTime, KernelTime, UserTime; - LARGE_INTEGER freq; - LARGE_INTEGER count; - LARGE_INTEGER seconds; - - if (!QueryPerformanceFrequency(&freq)) { + if (!GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime)) gp_get_realtime(pdt); /* use previous method if high-res perf counter not available */ - return; + else { + ULONGLONG t = (ULONGLONG)UserTime.dwLowDateTime + (ULONGLONG)KernelTime.dwLowDateTime + + (((ULONGLONG)UserTime.dwHighDateTime + (ULONGLONG)KernelTime.dwHighDateTime) << 32); + pdt[0] = (long)(t / 10000000); + pdt[1] = (long)(t % 10000000)*100; } - /* Get the high resolution time as seconds and nanoseconds */ - QueryPerformanceCounter(&count); - - seconds.QuadPart = (count.QuadPart / freq.QuadPart); - pdt[0] = seconds.LowPart; - count.QuadPart -= freq.QuadPart * seconds.QuadPart; - count.QuadPart *= 1000000000; /* we want nanoseconds */ - count.QuadPart /= freq.QuadPart; - pdt[1] = count.LowPart; } /* ------ Console management ------ */ diff --git a/base/gp_winfs.c b/base/gp_winfs.c index 6c01ddc9..39795a19 100644 --- a/base/gp_winfs.c +++ b/base/gp_winfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_winfs2.c b/base/gp_winfs2.c index 423b63fa..94ce9a68 100644 --- a/base/gp_winfs2.c +++ b/base/gp_winfs2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_wpapr.c b/base/gp_wpapr.c index 07efc617..92deaa6c 100644 --- a/base/gp_wpapr.c +++ b/base/gp_wpapr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_wsync.c b/base/gp_wsync.c index 8fca9006..36ec0439 100644 --- a/base/gp_wsync.c +++ b/base/gp_wsync.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_wutf8.c b/base/gp_wutf8.c index 0d816f99..b7b1d075 100644 --- a/base/gp_wutf8.c +++ b/base/gp_wutf8.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gp_wxpsprn.cpp b/base/gp_wxpsprn.cpp index a629b095..d326e1b2 100644 --- a/base/gp_wxpsprn.cpp +++ b/base/gp_wxpsprn.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gpcheck.h b/base/gpcheck.h index 4292c438..a01c6a07 100644 --- a/base/gpcheck.h +++ b/base/gpcheck.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gpgetenv.h b/base/gpgetenv.h index 1f1a4bca..0ab31a93 100644 --- a/base/gpgetenv.h +++ b/base/gpgetenv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gpmisc.c b/base/gpmisc.c index bae297d8..3d878acc 100644 --- a/base/gpmisc.c +++ b/base/gpmisc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -435,7 +435,7 @@ generic_pwrite(gp_file *f, size_t count, gs_offset_t offset, const void *buf) gp_file *gp_file_alloc(const gs_memory_t *mem, const gp_file_ops_t *prototype, size_t size, const char *cname) { - gp_file *file = (gp_file *)gs_alloc_bytes(mem->non_gc_memory, size, cname ? cname : "gp_file"); + gp_file *file = (gp_file *)gs_alloc_bytes(mem->thread_safe_memory, size, cname ? cname : "gp_file"); if (file == NULL) return NULL; @@ -449,7 +449,7 @@ gp_file *gp_file_alloc(const gs_memory_t *mem, const gp_file_ops_t *prototype, s memset(((char *)file)+sizeof(*prototype), 0, size - sizeof(*prototype)); - file->memory = mem->non_gc_memory; + file->memory = mem->thread_safe_memory; return file; } @@ -1077,7 +1077,7 @@ gp_validate_path_len(const gs_memory_t *mem, prefix_len = 0; } rlen = len+1; - bufferfull = (char *)gs_alloc_bytes(mem->non_gc_memory, rlen + prefix_len, "gp_validate_path"); + bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path"); if (bufferfull == NULL) return gs_error_VMerror; @@ -1139,7 +1139,7 @@ gp_validate_path_len(const gs_memory_t *mem, gs_path_control_flag_is_scratch_file); } - gs_free_object(mem->non_gc_memory, bufferfull, "gp_validate_path"); + gs_free_object(mem->thread_safe_memory, bufferfull, "gp_validate_path"); #ifdef EACCES if (code == gs_error_invalidfileaccess) errno = EACCES; diff --git a/base/gpmisc.h b/base/gpmisc.h index 9b3a0654..602285c8 100644 --- a/base/gpmisc.h +++ b/base/gpmisc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gpsync.h b/base/gpsync.h index a2d9b229..3f8715cb 100644 --- a/base/gpsync.h +++ b/base/gpsync.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gs.mak b/base/gs.mak index c4fbb91b..f67a2446 100644 --- a/base/gs.mak +++ b/base/gs.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/gs_dll_call.h b/base/gs_dll_call.h index 3a5efc63..c9db6937 100644 --- a/base/gs_dll_call.h +++ b/base/gs_dll_call.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gs_mgl_e.h b/base/gs_mgl_e.h index ef2d21e6..4d67c64b 100644 --- a/base/gs_mgl_e.h +++ b/base/gs_mgl_e.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gs_mro_e.h b/base/gs_mro_e.h index 32f74114..c2d74970 100644 --- a/base/gs_mro_e.h +++ b/base/gs_mro_e.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsalloc.c b/base/gsalloc.c index b8fb7b67..57a77c7d 100644 --- a/base/gsalloc.c +++ b/base/gsalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -2830,7 +2830,7 @@ debug_print_object(const gs_memory_t *mem, const void *obj, const dump_control_t ; } if (options & dump_do_marks) { - dmprintf2(mem, " smark/back=%u ("PRI_INTPTR")", pre->o_smark, pre->o_smark); + dmprintf2(mem, " smark/back=%u (0x%x)", pre->o_smark, pre->o_smark); } dmputc(mem, '\n'); if (type == &st_free) @@ -2987,8 +2987,8 @@ static void ddct(const gs_memory_t *mem, clump_t *cp, clump_t *parent, int depth dmlprintf7(mem, "Clump "PRI_INTPTR":"PRI_INTPTR" parent="PRI_INTPTR" left="PRI_INTPTR":"PRI_INTPTR" right="PRI_INTPTR":"PRI_INTPTR"\n", (intptr_t)cp, (intptr_t)cp->cbase, (intptr_t)cp->parent, - (intptr_t)cp->left, (intptr_t)cp->left ? cp->left->cbase : NULL, - (intptr_t)cp->right, (intptr_t)cp->right ? cp->right->cbase : NULL); + (intptr_t)cp->left, (intptr_t)(cp->left ? cp->left->cbase : NULL), + (intptr_t)cp->right, (intptr_t)(cp->right ? cp->right->cbase : NULL)); if (cp->parent != parent) dmlprintf(mem, "Parent pointer mismatch!\n"); ddct(mem, cp->left, cp, depth+1); diff --git a/base/gsalloc.h b/base/gsalloc.h index 4c9113fe..da8c8161 100644 --- a/base/gsalloc.h +++ b/base/gsalloc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsargs.c b/base/gsargs.c index 5ea73698..7fa399cb 100644 --- a/base/gsargs.c +++ b/base/gsargs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsargs.h b/base/gsargs.h index 2f277001..4767c85a 100644 --- a/base/gsargs.h +++ b/base/gsargs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsbitcom.c b/base/gsbitcom.c index 0d5856d0..77afae23 100644 --- a/base/gsbitcom.c +++ b/base/gsbitcom.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsbitmap.h b/base/gsbitmap.h index 7e8f87cd..ce761d94 100644 --- a/base/gsbitmap.h +++ b/base/gsbitmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsbitops.c b/base/gsbitops.c index b3a59c27..479ebcd6 100644 --- a/base/gsbitops.c +++ b/base/gsbitops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsbitops.h b/base/gsbitops.h index 6e1826a4..4087f19b 100644 --- a/base/gsbitops.h +++ b/base/gsbitops.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsbittab.c b/base/gsbittab.c index 3e171d3d..b9a42d92 100644 --- a/base/gsbittab.c +++ b/base/gsbittab.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsbittab.h b/base/gsbittab.h index 45b652c5..652ed00f 100644 --- a/base/gsbittab.h +++ b/base/gsbittab.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsccode.h b/base/gsccode.h index 9ed3aa78..10b88d6e 100644 --- a/base/gsccode.h +++ b/base/gsccode.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -79,9 +79,9 @@ typedef uint64_t gs_glyph; #define GS_NO_GLYPH ((gs_glyph)0x7fffffff) -# define GS_MIN_CID_GLYPH ((gs_glyph)0x80000000L) +#define GS_MIN_CID_GLYPH ((gs_glyph)0x80000000) -#define GS_MIN_GLYPH_INDEX (GS_MIN_CID_GLYPH | (GS_MIN_CID_GLYPH >> 1)) +#define GS_MIN_GLYPH_INDEX (gs_glyph)(GS_MIN_CID_GLYPH | (GS_MIN_CID_GLYPH >> 1)) #define GS_GLYPH_TAG (gs_glyph)(GS_MIN_CID_GLYPH | GS_MIN_GLYPH_INDEX) #define GS_MAX_GLYPH max_ulong diff --git a/base/gsccolor.h b/base/gsccolor.h index 1bdef311..86d948bc 100644 --- a/base/gsccolor.h +++ b/base/gsccolor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -36,7 +36,7 @@ typedef struct gs_pattern_instance_s gs_pattern_instance_t; # define GS_CLIENT_COLOR_MAX_COMPONENTS (64) #endif -#ifndef MAX_COMPONENTS_IN_DEVN +#ifndef MAX_COMPONENTS_IN_DEVN # define MAX_COMPONENTS_IN_DEVN (64) #endif diff --git a/base/gscdef.c b/base/gscdef.c index 2dcd6537..67ace135 100644 --- a/base/gscdef.c +++ b/base/gscdef.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscdefs.h b/base/gscdefs.h index 0ef78c02..e5e6123e 100644 --- a/base/gscdefs.h +++ b/base/gscdefs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -27,7 +27,7 @@ #ifndef GS_COPYRIGHT # define GS_COPYRIGHT\ - "Copyright (C) 2020 Artifex Software, Inc. All rights reserved." + "Copyright (C) 2021 Artifex Software, Inc. All rights reserved." #endif #ifndef GS_PRODUCTFAMILY diff --git a/base/gscdevn.c b/base/gscdevn.c index 07b20f4d..94ffc562 100644 --- a/base/gscdevn.c +++ b/base/gscdevn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscdevn.h b/base/gscdevn.h index 1a5603f5..f35e9b0e 100644 --- a/base/gscdevn.h +++ b/base/gscdevn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscedata.c b/base/gscedata.c index e8deca00..2898533d 100644 --- a/base/gscedata.c +++ b/base/gscedata.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -209,164 +209,169 @@ const char gs_c_known_encoding_chars[] = { 't','w','o', /*N(3,294)*/ 'y','e','n', /*N(3,297)*/ 'B','e','t','a', /*N(4,0)*/ -'E','u','r','o', /*N(4,4)*/ -'I','o','t','a', /*N(4,8)*/ -'Z','e','t','a', /*N(4,12)*/ -'a','1','0','0', /*N(4,16)*/ -'a','1','0','1', /*N(4,20)*/ -'a','1','0','2', /*N(4,24)*/ -'a','1','0','3', /*N(4,28)*/ -'a','1','0','4', /*N(4,32)*/ -'a','1','0','5', /*N(4,36)*/ -'a','1','0','6', /*N(4,40)*/ -'a','1','0','7', /*N(4,44)*/ -'a','1','0','8', /*N(4,48)*/ -'a','1','0','9', /*N(4,52)*/ -'a','1','1','0', /*N(4,56)*/ -'a','1','1','1', /*N(4,60)*/ -'a','1','1','2', /*N(4,64)*/ -'a','1','1','7', /*N(4,68)*/ -'a','1','1','8', /*N(4,72)*/ -'a','1','1','9', /*N(4,76)*/ -'a','1','2','0', /*N(4,80)*/ -'a','1','2','1', /*N(4,84)*/ -'a','1','2','2', /*N(4,88)*/ -'a','1','2','3', /*N(4,92)*/ -'a','1','2','4', /*N(4,96)*/ -'a','1','2','5', /*N(4,100)*/ -'a','1','2','6', /*N(4,104)*/ -'a','1','2','7', /*N(4,108)*/ -'a','1','2','8', /*N(4,112)*/ -'a','1','2','9', /*N(4,116)*/ -'a','1','3','0', /*N(4,120)*/ -'a','1','3','1', /*N(4,124)*/ -'a','1','3','2', /*N(4,128)*/ -'a','1','3','3', /*N(4,132)*/ -'a','1','3','4', /*N(4,136)*/ -'a','1','3','5', /*N(4,140)*/ -'a','1','3','6', /*N(4,144)*/ -'a','1','3','7', /*N(4,148)*/ -'a','1','3','8', /*N(4,152)*/ -'a','1','3','9', /*N(4,156)*/ -'a','1','4','0', /*N(4,160)*/ -'a','1','4','1', /*N(4,164)*/ -'a','1','4','2', /*N(4,168)*/ -'a','1','4','3', /*N(4,172)*/ -'a','1','4','4', /*N(4,176)*/ -'a','1','4','5', /*N(4,180)*/ -'a','1','4','6', /*N(4,184)*/ -'a','1','4','7', /*N(4,188)*/ -'a','1','4','8', /*N(4,192)*/ -'a','1','4','9', /*N(4,196)*/ -'a','1','5','0', /*N(4,200)*/ -'a','1','5','1', /*N(4,204)*/ -'a','1','5','2', /*N(4,208)*/ -'a','1','5','3', /*N(4,212)*/ -'a','1','5','4', /*N(4,216)*/ -'a','1','5','5', /*N(4,220)*/ -'a','1','5','6', /*N(4,224)*/ -'a','1','5','7', /*N(4,228)*/ -'a','1','5','8', /*N(4,232)*/ -'a','1','5','9', /*N(4,236)*/ -'a','1','6','0', /*N(4,240)*/ -'a','1','6','1', /*N(4,244)*/ -'a','1','6','2', /*N(4,248)*/ -'a','1','6','3', /*N(4,252)*/ -'a','1','6','4', /*N(4,256)*/ -'a','1','6','5', /*N(4,260)*/ -'a','1','6','6', /*N(4,264)*/ -'a','1','6','7', /*N(4,268)*/ -'a','1','6','8', /*N(4,272)*/ -'a','1','6','9', /*N(4,276)*/ -'a','1','7','0', /*N(4,280)*/ -'a','1','7','1', /*N(4,284)*/ -'a','1','7','2', /*N(4,288)*/ -'a','1','7','3', /*N(4,292)*/ -'a','1','7','4', /*N(4,296)*/ -'a','1','7','5', /*N(4,300)*/ -'a','1','7','6', /*N(4,304)*/ -'a','1','7','7', /*N(4,308)*/ -'a','1','7','8', /*N(4,312)*/ -'a','1','7','9', /*N(4,316)*/ -'a','1','8','0', /*N(4,320)*/ -'a','1','8','1', /*N(4,324)*/ -'a','1','8','2', /*N(4,328)*/ -'a','1','8','3', /*N(4,332)*/ -'a','1','8','4', /*N(4,336)*/ -'a','1','8','5', /*N(4,340)*/ -'a','1','8','6', /*N(4,344)*/ -'a','1','8','7', /*N(4,348)*/ -'a','1','8','8', /*N(4,352)*/ -'a','1','8','9', /*N(4,356)*/ -'a','1','9','0', /*N(4,360)*/ -'a','1','9','1', /*N(4,364)*/ -'a','1','9','2', /*N(4,368)*/ -'a','1','9','3', /*N(4,372)*/ -'a','1','9','4', /*N(4,376)*/ -'a','1','9','5', /*N(4,380)*/ -'a','1','9','6', /*N(4,384)*/ -'a','1','9','7', /*N(4,388)*/ -'a','1','9','8', /*N(4,392)*/ -'a','1','9','9', /*N(4,396)*/ -'a','2','0','0', /*N(4,400)*/ -'a','2','0','1', /*N(4,404)*/ -'a','2','0','2', /*N(4,408)*/ -'a','2','0','3', /*N(4,412)*/ -'a','2','0','4', /*N(4,416)*/ -'b','e','t','a', /*N(4,420)*/ -'c','e','n','t', /*N(4,424)*/ -'c','l','u','b', /*N(4,428)*/ -'f','i','v','e', /*N(4,432)*/ -'f','o','u','r', /*N(4,436)*/ -'i','o','t','a', /*N(4,440)*/ -'l','e','s','s', /*N(4,444)*/ -'n','i','n','e', /*N(4,448)*/ -'p','h','i','1', /*N(4,452)*/ -'p','l','u','s', /*N(4,456)*/ -'r','i','n','g', /*N(4,460)*/ -'z','e','r','o', /*N(4,464)*/ -'z','e','t','a', /*N(4,468)*/ +'B','o','l','d', /*N(4,4)*/ +'B','o','o','k', /*N(4,8)*/ +'E','u','r','o', /*N(4,12)*/ +'I','o','t','a', /*N(4,16)*/ +'Z','e','t','a', /*N(4,20)*/ +'a','1','0','0', /*N(4,24)*/ +'a','1','0','1', /*N(4,28)*/ +'a','1','0','2', /*N(4,32)*/ +'a','1','0','3', /*N(4,36)*/ +'a','1','0','4', /*N(4,40)*/ +'a','1','0','5', /*N(4,44)*/ +'a','1','0','6', /*N(4,48)*/ +'a','1','0','7', /*N(4,52)*/ +'a','1','0','8', /*N(4,56)*/ +'a','1','0','9', /*N(4,60)*/ +'a','1','1','0', /*N(4,64)*/ +'a','1','1','1', /*N(4,68)*/ +'a','1','1','2', /*N(4,72)*/ +'a','1','1','7', /*N(4,76)*/ +'a','1','1','8', /*N(4,80)*/ +'a','1','1','9', /*N(4,84)*/ +'a','1','2','0', /*N(4,88)*/ +'a','1','2','1', /*N(4,92)*/ +'a','1','2','2', /*N(4,96)*/ +'a','1','2','3', /*N(4,100)*/ +'a','1','2','4', /*N(4,104)*/ +'a','1','2','5', /*N(4,108)*/ +'a','1','2','6', /*N(4,112)*/ +'a','1','2','7', /*N(4,116)*/ +'a','1','2','8', /*N(4,120)*/ +'a','1','2','9', /*N(4,124)*/ +'a','1','3','0', /*N(4,128)*/ +'a','1','3','1', /*N(4,132)*/ +'a','1','3','2', /*N(4,136)*/ +'a','1','3','3', /*N(4,140)*/ +'a','1','3','4', /*N(4,144)*/ +'a','1','3','5', /*N(4,148)*/ +'a','1','3','6', /*N(4,152)*/ +'a','1','3','7', /*N(4,156)*/ +'a','1','3','8', /*N(4,160)*/ +'a','1','3','9', /*N(4,164)*/ +'a','1','4','0', /*N(4,168)*/ +'a','1','4','1', /*N(4,172)*/ +'a','1','4','2', /*N(4,176)*/ +'a','1','4','3', /*N(4,180)*/ +'a','1','4','4', /*N(4,184)*/ +'a','1','4','5', /*N(4,188)*/ +'a','1','4','6', /*N(4,192)*/ +'a','1','4','7', /*N(4,196)*/ +'a','1','4','8', /*N(4,200)*/ +'a','1','4','9', /*N(4,204)*/ +'a','1','5','0', /*N(4,208)*/ +'a','1','5','1', /*N(4,212)*/ +'a','1','5','2', /*N(4,216)*/ +'a','1','5','3', /*N(4,220)*/ +'a','1','5','4', /*N(4,224)*/ +'a','1','5','5', /*N(4,228)*/ +'a','1','5','6', /*N(4,232)*/ +'a','1','5','7', /*N(4,236)*/ +'a','1','5','8', /*N(4,240)*/ +'a','1','5','9', /*N(4,244)*/ +'a','1','6','0', /*N(4,248)*/ +'a','1','6','1', /*N(4,252)*/ +'a','1','6','2', /*N(4,256)*/ +'a','1','6','3', /*N(4,260)*/ +'a','1','6','4', /*N(4,264)*/ +'a','1','6','5', /*N(4,268)*/ +'a','1','6','6', /*N(4,272)*/ +'a','1','6','7', /*N(4,276)*/ +'a','1','6','8', /*N(4,280)*/ +'a','1','6','9', /*N(4,284)*/ +'a','1','7','0', /*N(4,288)*/ +'a','1','7','1', /*N(4,292)*/ +'a','1','7','2', /*N(4,296)*/ +'a','1','7','3', /*N(4,300)*/ +'a','1','7','4', /*N(4,304)*/ +'a','1','7','5', /*N(4,308)*/ +'a','1','7','6', /*N(4,312)*/ +'a','1','7','7', /*N(4,316)*/ +'a','1','7','8', /*N(4,320)*/ +'a','1','7','9', /*N(4,324)*/ +'a','1','8','0', /*N(4,328)*/ +'a','1','8','1', /*N(4,332)*/ +'a','1','8','2', /*N(4,336)*/ +'a','1','8','3', /*N(4,340)*/ +'a','1','8','4', /*N(4,344)*/ +'a','1','8','5', /*N(4,348)*/ +'a','1','8','6', /*N(4,352)*/ +'a','1','8','7', /*N(4,356)*/ +'a','1','8','8', /*N(4,360)*/ +'a','1','8','9', /*N(4,364)*/ +'a','1','9','0', /*N(4,368)*/ +'a','1','9','1', /*N(4,372)*/ +'a','1','9','2', /*N(4,376)*/ +'a','1','9','3', /*N(4,380)*/ +'a','1','9','4', /*N(4,384)*/ +'a','1','9','5', /*N(4,388)*/ +'a','1','9','6', /*N(4,392)*/ +'a','1','9','7', /*N(4,396)*/ +'a','1','9','8', /*N(4,400)*/ +'a','1','9','9', /*N(4,404)*/ +'a','2','0','0', /*N(4,408)*/ +'a','2','0','1', /*N(4,412)*/ +'a','2','0','2', /*N(4,416)*/ +'a','2','0','3', /*N(4,420)*/ +'a','2','0','4', /*N(4,424)*/ +'b','e','t','a', /*N(4,428)*/ +'c','e','n','t', /*N(4,432)*/ +'c','l','u','b', /*N(4,436)*/ +'f','i','v','e', /*N(4,440)*/ +'f','o','u','r', /*N(4,444)*/ +'i','o','t','a', /*N(4,448)*/ +'l','e','s','s', /*N(4,452)*/ +'n','i','n','e', /*N(4,456)*/ +'p','h','i','1', /*N(4,460)*/ +'p','l','u','s', /*N(4,464)*/ +'r','i','n','g', /*N(4,468)*/ +'z','e','r','o', /*N(4,472)*/ +'z','e','t','a', /*N(4,476)*/ '.','n','u','l','l', /*N(5,0)*/ 'A','l','p','h','a', /*N(5,5)*/ 'A','r','i','n','g', /*N(5,10)*/ -'D','e','l','t','a', /*N(5,15)*/ -'G','a','m','m','a', /*N(5,20)*/ -'K','a','p','p','a', /*N(5,25)*/ -'O','m','e','g','a', /*N(5,30)*/ -'S','i','g','m','a', /*N(5,35)*/ -'T','h','e','t','a', /*N(5,40)*/ -'T','h','o','r','n', /*N(5,45)*/ -'U','r','i','n','g', /*N(5,50)*/ -'a','c','u','t','e', /*N(5,55)*/ -'a','l','e','p','h', /*N(5,60)*/ -'a','l','p','h','a', /*N(5,65)*/ -'a','n','g','l','e', /*N(5,70)*/ -'a','r','i','n','g', /*N(5,75)*/ -'b','r','e','v','e', /*N(5,80)*/ -'c','a','r','o','n', /*N(5,85)*/ -'c','o','l','o','n', /*N(5,90)*/ -'c','o','m','m','a', /*N(5,95)*/ -'d','e','l','t','a', /*N(5,100)*/ -'e','i','g','h','t', /*N(5,105)*/ -'e','q','u','a','l', /*N(5,110)*/ -'f','r','a','n','c', /*N(5,115)*/ -'g','a','m','m','a', /*N(5,120)*/ -'g','r','a','v','e', /*N(5,125)*/ -'h','e','a','r','t', /*N(5,130)*/ -'k','a','p','p','a', /*N(5,135)*/ -'m','i','n','u','s', /*N(5,140)*/ -'o','m','e','g','a', /*N(5,145)*/ -'s','e','v','e','n', /*N(5,150)*/ -'s','i','g','m','a', /*N(5,155)*/ -'s','l','a','s','h', /*N(5,160)*/ -'s','p','a','c','e', /*N(5,165)*/ -'s','p','a','d','e', /*N(5,170)*/ -'t','h','e','t','a', /*N(5,175)*/ -'t','h','o','r','n', /*N(5,180)*/ -'t','h','r','e','e', /*N(5,185)*/ -'t','i','l','d','e', /*N(5,190)*/ -'u','n','i','o','n', /*N(5,195)*/ -'u','r','i','n','g', /*N(5,200)*/ +'B','l','a','c','k', /*N(5,15)*/ +'D','e','l','t','a', /*N(5,20)*/ +'G','a','m','m','a', /*N(5,25)*/ +'K','a','p','p','a', /*N(5,30)*/ +'L','i','g','h','t', /*N(5,35)*/ +'O','m','e','g','a', /*N(5,40)*/ +'R','o','m','a','n', /*N(5,45)*/ +'S','i','g','m','a', /*N(5,50)*/ +'T','h','e','t','a', /*N(5,55)*/ +'T','h','o','r','n', /*N(5,60)*/ +'U','r','i','n','g', /*N(5,65)*/ +'a','c','u','t','e', /*N(5,70)*/ +'a','l','e','p','h', /*N(5,75)*/ +'a','l','p','h','a', /*N(5,80)*/ +'a','n','g','l','e', /*N(5,85)*/ +'a','r','i','n','g', /*N(5,90)*/ +'b','r','e','v','e', /*N(5,95)*/ +'c','a','r','o','n', /*N(5,100)*/ +'c','o','l','o','n', /*N(5,105)*/ +'c','o','m','m','a', /*N(5,110)*/ +'d','e','l','t','a', /*N(5,115)*/ +'e','i','g','h','t', /*N(5,120)*/ +'e','q','u','a','l', /*N(5,125)*/ +'f','r','a','n','c', /*N(5,130)*/ +'g','a','m','m','a', /*N(5,135)*/ +'g','r','a','v','e', /*N(5,140)*/ +'h','e','a','r','t', /*N(5,145)*/ +'k','a','p','p','a', /*N(5,150)*/ +'m','i','n','u','s', /*N(5,155)*/ +'o','m','e','g','a', /*N(5,160)*/ +'s','e','v','e','n', /*N(5,165)*/ +'s','i','g','m','a', /*N(5,170)*/ +'s','l','a','s','h', /*N(5,175)*/ +'s','p','a','c','e', /*N(5,180)*/ +'s','p','a','d','e', /*N(5,185)*/ +'t','h','e','t','a', /*N(5,190)*/ +'t','h','o','r','n', /*N(5,195)*/ +'t','h','r','e','e', /*N(5,200)*/ +'t','i','l','d','e', /*N(5,205)*/ +'u','n','i','o','n', /*N(5,210)*/ +'u','r','i','n','g', /*N(5,215)*/ 'A','a','c','u','t','e', /*N(6,0)*/ 'A','b','r','e','v','e', /*N(6,6)*/ 'A','g','r','a','v','e', /*N(6,12)*/ @@ -397,159 +402,166 @@ const char gs_c_known_encoding_chars[] = { 'L','c','a','r','o','n', /*N(6,162)*/ 'L','s','l','a','s','h', /*N(6,168)*/ 'L','s','m','a','l','l', /*N(6,174)*/ -'M','s','m','a','l','l', /*N(6,180)*/ -'N','a','c','u','t','e', /*N(6,186)*/ -'N','c','a','r','o','n', /*N(6,192)*/ -'N','s','m','a','l','l', /*N(6,198)*/ -'N','t','i','l','d','e', /*N(6,204)*/ -'O','a','c','u','t','e', /*N(6,210)*/ -'O','g','r','a','v','e', /*N(6,216)*/ -'O','s','l','a','s','h', /*N(6,222)*/ -'O','s','m','a','l','l', /*N(6,228)*/ -'O','t','i','l','d','e', /*N(6,234)*/ -'P','s','m','a','l','l', /*N(6,240)*/ -'Q','s','m','a','l','l', /*N(6,246)*/ -'R','a','c','u','t','e', /*N(6,252)*/ -'R','c','a','r','o','n', /*N(6,258)*/ -'R','s','m','a','l','l', /*N(6,264)*/ -'S','a','c','u','t','e', /*N(6,270)*/ -'S','c','a','r','o','n', /*N(6,276)*/ -'S','s','m','a','l','l', /*N(6,282)*/ -'T','c','a','r','o','n', /*N(6,288)*/ -'T','s','m','a','l','l', /*N(6,294)*/ -'U','a','c','u','t','e', /*N(6,300)*/ -'U','g','r','a','v','e', /*N(6,306)*/ -'U','s','m','a','l','l', /*N(6,312)*/ -'V','s','m','a','l','l', /*N(6,318)*/ -'W','s','m','a','l','l', /*N(6,324)*/ -'X','s','m','a','l','l', /*N(6,330)*/ -'Y','a','c','u','t','e', /*N(6,336)*/ -'Y','s','m','a','l','l', /*N(6,342)*/ -'Z','a','c','u','t','e', /*N(6,348)*/ -'Z','c','a','r','o','n', /*N(6,354)*/ -'Z','s','m','a','l','l', /*N(6,360)*/ -'a','a','c','u','t','e', /*N(6,366)*/ -'a','b','r','e','v','e', /*N(6,372)*/ -'a','g','r','a','v','e', /*N(6,378)*/ -'a','t','i','l','d','e', /*N(6,384)*/ -'b','u','l','l','e','t', /*N(6,390)*/ -'c','a','c','u','t','e', /*N(6,396)*/ -'c','c','a','r','o','n', /*N(6,402)*/ -'d','a','g','g','e','r', /*N(6,408)*/ -'d','c','a','r','o','n', /*N(6,414)*/ -'d','c','r','o','a','t', /*N(6,420)*/ -'d','e','g','r','e','e', /*N(6,426)*/ -'d','i','v','i','d','e', /*N(6,432)*/ -'d','o','l','l','a','r', /*N(6,438)*/ -'e','a','c','u','t','e', /*N(6,444)*/ -'e','c','a','r','o','n', /*N(6,450)*/ -'e','g','r','a','v','e', /*N(6,456)*/ -'e','m','d','a','s','h', /*N(6,462)*/ -'e','n','d','a','s','h', /*N(6,468)*/ -'e','x','c','l','a','m', /*N(6,474)*/ -'f','l','o','r','i','n', /*N(6,480)*/ -'g','b','r','e','v','e', /*N(6,486)*/ -'h','y','p','h','e','n', /*N(6,492)*/ -'i','a','c','u','t','e', /*N(6,498)*/ -'i','g','r','a','v','e', /*N(6,504)*/ -'l','a','c','u','t','e', /*N(6,510)*/ -'l','a','m','b','d','a', /*N(6,516)*/ -'l','c','a','r','o','n', /*N(6,522)*/ -'l','s','l','a','s','h', /*N(6,528)*/ -'m','a','c','r','o','n', /*N(6,534)*/ -'m','i','n','u','t','e', /*N(6,540)*/ -'n','a','c','u','t','e', /*N(6,546)*/ -'n','c','a','r','o','n', /*N(6,552)*/ -'n','t','i','l','d','e', /*N(6,558)*/ -'o','a','c','u','t','e', /*N(6,564)*/ -'o','g','o','n','e','k', /*N(6,570)*/ -'o','g','r','a','v','e', /*N(6,576)*/ -'o','m','e','g','a','1', /*N(6,582)*/ -'o','s','l','a','s','h', /*N(6,588)*/ -'o','t','i','l','d','e', /*N(6,594)*/ -'p','e','r','i','o','d', /*N(6,600)*/ -'r','a','c','u','t','e', /*N(6,606)*/ -'r','c','a','r','o','n', /*N(6,612)*/ -'r','u','p','i','a','h', /*N(6,618)*/ -'s','a','c','u','t','e', /*N(6,624)*/ -'s','c','a','r','o','n', /*N(6,630)*/ -'s','e','c','o','n','d', /*N(6,636)*/ -'s','i','g','m','a','1', /*N(6,642)*/ -'t','c','a','r','o','n', /*N(6,648)*/ -'t','h','e','t','a','1', /*N(6,654)*/ -'u','a','c','u','t','e', /*N(6,660)*/ -'u','g','r','a','v','e', /*N(6,666)*/ -'y','a','c','u','t','e', /*N(6,672)*/ -'z','a','c','u','t','e', /*N(6,678)*/ -'z','c','a','r','o','n', /*N(6,684)*/ +'M','e','d','i','u','m', /*N(6,180)*/ +'M','s','m','a','l','l', /*N(6,186)*/ +'N','a','c','u','t','e', /*N(6,192)*/ +'N','c','a','r','o','n', /*N(6,198)*/ +'N','s','m','a','l','l', /*N(6,204)*/ +'N','t','i','l','d','e', /*N(6,210)*/ +'O','a','c','u','t','e', /*N(6,216)*/ +'O','g','r','a','v','e', /*N(6,222)*/ +'O','s','l','a','s','h', /*N(6,228)*/ +'O','s','m','a','l','l', /*N(6,234)*/ +'O','t','i','l','d','e', /*N(6,240)*/ +'P','s','m','a','l','l', /*N(6,246)*/ +'Q','s','m','a','l','l', /*N(6,252)*/ +'R','a','c','u','t','e', /*N(6,258)*/ +'R','c','a','r','o','n', /*N(6,264)*/ +'R','s','m','a','l','l', /*N(6,270)*/ +'S','a','c','u','t','e', /*N(6,276)*/ +'S','c','a','r','o','n', /*N(6,282)*/ +'S','s','m','a','l','l', /*N(6,288)*/ +'T','c','a','r','o','n', /*N(6,294)*/ +'T','s','m','a','l','l', /*N(6,300)*/ +'U','a','c','u','t','e', /*N(6,306)*/ +'U','g','r','a','v','e', /*N(6,312)*/ +'U','s','m','a','l','l', /*N(6,318)*/ +'V','s','m','a','l','l', /*N(6,324)*/ +'W','s','m','a','l','l', /*N(6,330)*/ +'X','s','m','a','l','l', /*N(6,336)*/ +'Y','a','c','u','t','e', /*N(6,342)*/ +'Y','s','m','a','l','l', /*N(6,348)*/ +'Z','a','c','u','t','e', /*N(6,354)*/ +'Z','c','a','r','o','n', /*N(6,360)*/ +'Z','s','m','a','l','l', /*N(6,366)*/ +'a','a','c','u','t','e', /*N(6,372)*/ +'a','b','r','e','v','e', /*N(6,378)*/ +'a','g','r','a','v','e', /*N(6,384)*/ +'a','t','i','l','d','e', /*N(6,390)*/ +'b','u','l','l','e','t', /*N(6,396)*/ +'c','a','c','u','t','e', /*N(6,402)*/ +'c','c','a','r','o','n', /*N(6,408)*/ +'d','a','g','g','e','r', /*N(6,414)*/ +'d','c','a','r','o','n', /*N(6,420)*/ +'d','c','r','o','a','t', /*N(6,426)*/ +'d','e','g','r','e','e', /*N(6,432)*/ +'d','i','v','i','d','e', /*N(6,438)*/ +'d','o','l','l','a','r', /*N(6,444)*/ +'e','a','c','u','t','e', /*N(6,450)*/ +'e','c','a','r','o','n', /*N(6,456)*/ +'e','g','r','a','v','e', /*N(6,462)*/ +'e','m','d','a','s','h', /*N(6,468)*/ +'e','n','d','a','s','h', /*N(6,474)*/ +'e','x','c','l','a','m', /*N(6,480)*/ +'f','l','o','r','i','n', /*N(6,486)*/ +'g','b','r','e','v','e', /*N(6,492)*/ +'h','y','p','h','e','n', /*N(6,498)*/ +'i','a','c','u','t','e', /*N(6,504)*/ +'i','g','r','a','v','e', /*N(6,510)*/ +'l','a','c','u','t','e', /*N(6,516)*/ +'l','a','m','b','d','a', /*N(6,522)*/ +'l','c','a','r','o','n', /*N(6,528)*/ +'l','s','l','a','s','h', /*N(6,534)*/ +'m','a','c','r','o','n', /*N(6,540)*/ +'m','i','n','u','t','e', /*N(6,546)*/ +'n','a','c','u','t','e', /*N(6,552)*/ +'n','c','a','r','o','n', /*N(6,558)*/ +'n','t','i','l','d','e', /*N(6,564)*/ +'o','a','c','u','t','e', /*N(6,570)*/ +'o','g','o','n','e','k', /*N(6,576)*/ +'o','g','r','a','v','e', /*N(6,582)*/ +'o','m','e','g','a','1', /*N(6,588)*/ +'o','s','l','a','s','h', /*N(6,594)*/ +'o','t','i','l','d','e', /*N(6,600)*/ +'p','e','r','i','o','d', /*N(6,606)*/ +'r','a','c','u','t','e', /*N(6,612)*/ +'r','c','a','r','o','n', /*N(6,618)*/ +'r','u','p','i','a','h', /*N(6,624)*/ +'s','a','c','u','t','e', /*N(6,630)*/ +'s','c','a','r','o','n', /*N(6,636)*/ +'s','e','c','o','n','d', /*N(6,642)*/ +'s','i','g','m','a','1', /*N(6,648)*/ +'t','c','a','r','o','n', /*N(6,654)*/ +'t','h','e','t','a','1', /*N(6,660)*/ +'u','a','c','u','t','e', /*N(6,666)*/ +'u','g','r','a','v','e', /*N(6,672)*/ +'y','a','c','u','t','e', /*N(6,678)*/ +'z','a','c','u','t','e', /*N(6,684)*/ +'z','c','a','r','o','n', /*N(6,690)*/ '.','n','o','t','d','e','f', /*N(7,0)*/ -'A','E','s','m','a','l','l', /*N(7,7)*/ -'A','m','a','c','r','o','n', /*N(7,14)*/ -'A','o','g','o','n','e','k', /*N(7,21)*/ -'E','m','a','c','r','o','n', /*N(7,28)*/ -'E','o','g','o','n','e','k', /*N(7,35)*/ -'E','p','s','i','l','o','n', /*N(7,42)*/ -'I','m','a','c','r','o','n', /*N(7,49)*/ -'I','o','g','o','n','e','k', /*N(7,56)*/ -'O','E','s','m','a','l','l', /*N(7,63)*/ -'O','m','a','c','r','o','n', /*N(7,70)*/ -'O','m','i','c','r','o','n', /*N(7,77)*/ -'U','m','a','c','r','o','n', /*N(7,84)*/ -'U','o','g','o','n','e','k', /*N(7,91)*/ -'U','p','s','i','l','o','n', /*N(7,98)*/ -'a','m','a','c','r','o','n', /*N(7,105)*/ -'a','o','g','o','n','e','k', /*N(7,112)*/ -'a','r','r','o','w','u','p', /*N(7,119)*/ -'b','r','a','c','e','e','x', /*N(7,126)*/ -'c','e','d','i','l','l','a', /*N(7,133)*/ -'d','i','a','m','o','n','d', /*N(7,140)*/ -'d','m','a','c','r','o','n', /*N(7,147)*/ -'d','o','t','m','a','t','h', /*N(7,154)*/ -'e','l','e','m','e','n','t', /*N(7,161)*/ -'e','m','a','c','r','o','n', /*N(7,168)*/ -'e','o','g','o','n','e','k', /*N(7,175)*/ -'e','p','s','i','l','o','n', /*N(7,182)*/ -'g','r','e','a','t','e','r', /*N(7,189)*/ -'i','m','a','c','r','o','n', /*N(7,196)*/ -'i','o','g','o','n','e','k', /*N(7,203)*/ -'l','o','z','e','n','g','e', /*N(7,210)*/ -'n','b','s','p','a','c','e', /*N(7,217)*/ -'o','m','a','c','r','o','n', /*N(7,224)*/ -'o','m','i','c','r','o','n', /*N(7,231)*/ -'o','n','e','h','a','l','f', /*N(7,238)*/ -'p','e','r','c','e','n','t', /*N(7,245)*/ -'p','r','o','d','u','c','t', /*N(7,252)*/ -'r','a','d','i','c','a','l', /*N(7,259)*/ -'s','e','c','t','i','o','n', /*N(7,266)*/ -'s','i','m','i','l','a','r', /*N(7,273)*/ -'u','m','a','c','r','o','n', /*N(7,280)*/ -'u','o','g','o','n','e','k', /*N(7,287)*/ -'u','p','s','i','l','o','n', /*N(7,294)*/ +'0','0','1','.','0','0','0', /*N(7,7)*/ +'0','0','1','.','0','0','1', /*N(7,14)*/ +'0','0','1','.','0','0','2', /*N(7,21)*/ +'0','0','1','.','0','0','3', /*N(7,28)*/ +'A','E','s','m','a','l','l', /*N(7,35)*/ +'A','m','a','c','r','o','n', /*N(7,42)*/ +'A','o','g','o','n','e','k', /*N(7,49)*/ +'E','m','a','c','r','o','n', /*N(7,56)*/ +'E','o','g','o','n','e','k', /*N(7,63)*/ +'E','p','s','i','l','o','n', /*N(7,70)*/ +'I','m','a','c','r','o','n', /*N(7,77)*/ +'I','o','g','o','n','e','k', /*N(7,84)*/ +'O','E','s','m','a','l','l', /*N(7,91)*/ +'O','m','a','c','r','o','n', /*N(7,98)*/ +'O','m','i','c','r','o','n', /*N(7,105)*/ +'R','e','g','u','l','a','r', /*N(7,112)*/ +'U','m','a','c','r','o','n', /*N(7,119)*/ +'U','o','g','o','n','e','k', /*N(7,126)*/ +'U','p','s','i','l','o','n', /*N(7,133)*/ +'a','m','a','c','r','o','n', /*N(7,140)*/ +'a','o','g','o','n','e','k', /*N(7,147)*/ +'a','r','r','o','w','u','p', /*N(7,154)*/ +'b','r','a','c','e','e','x', /*N(7,161)*/ +'c','e','d','i','l','l','a', /*N(7,168)*/ +'d','i','a','m','o','n','d', /*N(7,175)*/ +'d','m','a','c','r','o','n', /*N(7,182)*/ +'d','o','t','m','a','t','h', /*N(7,189)*/ +'e','l','e','m','e','n','t', /*N(7,196)*/ +'e','m','a','c','r','o','n', /*N(7,203)*/ +'e','o','g','o','n','e','k', /*N(7,210)*/ +'e','p','s','i','l','o','n', /*N(7,217)*/ +'g','r','e','a','t','e','r', /*N(7,224)*/ +'i','m','a','c','r','o','n', /*N(7,231)*/ +'i','o','g','o','n','e','k', /*N(7,238)*/ +'l','o','z','e','n','g','e', /*N(7,245)*/ +'n','b','s','p','a','c','e', /*N(7,252)*/ +'o','m','a','c','r','o','n', /*N(7,259)*/ +'o','m','i','c','r','o','n', /*N(7,266)*/ +'o','n','e','h','a','l','f', /*N(7,273)*/ +'p','e','r','c','e','n','t', /*N(7,280)*/ +'p','r','o','d','u','c','t', /*N(7,287)*/ +'r','a','d','i','c','a','l', /*N(7,294)*/ +'s','e','c','t','i','o','n', /*N(7,301)*/ +'s','i','m','i','l','a','r', /*N(7,308)*/ +'u','m','a','c','r','o','n', /*N(7,315)*/ +'u','o','g','o','n','e','k', /*N(7,322)*/ +'u','p','s','i','l','o','n', /*N(7,329)*/ 'C','c','e','d','i','l','l','a', /*N(8,0)*/ 'E','t','h','s','m','a','l','l', /*N(8,8)*/ 'I','f','r','a','k','t','u','r', /*N(8,16)*/ 'R','f','r','a','k','t','u','r', /*N(8,24)*/ 'S','c','e','d','i','l','l','a', /*N(8,32)*/ -'U','p','s','i','l','o','n','1', /*N(8,40)*/ -'a','s','t','e','r','i','s','k', /*N(8,48)*/ -'c','c','e','d','i','l','l','a', /*N(8,56)*/ -'c','u','r','r','e','n','c','y', /*N(8,64)*/ -'d','i','e','r','e','s','i','s', /*N(8,72)*/ -'d','o','t','l','e','s','s','i', /*N(8,80)*/ -'e','l','l','i','p','s','i','s', /*N(8,88)*/ -'e','m','p','t','y','s','e','t', /*N(8,96)*/ -'f','r','a','c','t','i','o','n', /*N(8,104)*/ -'g','r','a','d','i','e','n','t', /*N(8,112)*/ -'i','n','f','i','n','i','t','y', /*N(8,120)*/ -'i','n','t','e','g','r','a','l', /*N(8,128)*/ -'m','u','l','t','i','p','l','y', /*N(8,136)*/ -'n','o','t','e','q','u','a','l', /*N(8,144)*/ -'o','n','e','t','h','i','r','d', /*N(8,152)*/ -'q','u','e','s','t','i','o','n', /*N(8,160)*/ -'q','u','o','t','e','d','b','l', /*N(8,168)*/ -'s','c','e','d','i','l','l','a', /*N(8,176)*/ -'s','t','e','r','l','i','n','g', /*N(8,184)*/ -'s','u','c','h','t','h','a','t', /*N(8,192)*/ +'S','e','m','i','b','o','l','d', /*N(8,40)*/ +'U','p','s','i','l','o','n','1', /*N(8,48)*/ +'a','s','t','e','r','i','s','k', /*N(8,56)*/ +'c','c','e','d','i','l','l','a', /*N(8,64)*/ +'c','u','r','r','e','n','c','y', /*N(8,72)*/ +'d','i','e','r','e','s','i','s', /*N(8,80)*/ +'d','o','t','l','e','s','s','i', /*N(8,88)*/ +'e','l','l','i','p','s','i','s', /*N(8,96)*/ +'e','m','p','t','y','s','e','t', /*N(8,104)*/ +'f','r','a','c','t','i','o','n', /*N(8,112)*/ +'g','r','a','d','i','e','n','t', /*N(8,120)*/ +'i','n','f','i','n','i','t','y', /*N(8,128)*/ +'i','n','t','e','g','r','a','l', /*N(8,136)*/ +'m','u','l','t','i','p','l','y', /*N(8,144)*/ +'n','o','t','e','q','u','a','l', /*N(8,152)*/ +'o','n','e','t','h','i','r','d', /*N(8,160)*/ +'q','u','e','s','t','i','o','n', /*N(8,168)*/ +'q','u','o','t','e','d','b','l', /*N(8,176)*/ +'s','c','e','d','i','l','l','a', /*N(8,184)*/ +'s','t','e','r','l','i','n','g', /*N(8,192)*/ +'s','u','c','h','t','h','a','t', /*N(8,200)*/ 'A','d','i','e','r','e','s','i','s', /*N(9,0)*/ 'E','d','i','e','r','e','s','i','s', /*N(9,9)*/ 'I','d','i','e','r','e','s','i','s', /*N(9,18)*/ @@ -831,12 +843,12 @@ const char gs_c_known_encoding_chars[] = { 't','h','r','e','e','q','u','a','r','t','e','r','s','e','m','d','a','s','h', /*N(19,0)*/ 0}; -const int gs_c_known_encoding_total_chars = 5483; +const int gs_c_known_encoding_total_chars = 5555; const int gs_c_known_encoding_max_length = 19; const ushort gs_c_known_encoding_offsets[] = { -0,0,52,104,404,876,1081,1771,2072,2272,2776,3116,3754,4414,4830,5250,5280,5360,5428,5464,5483}; +0,0,52,104,404,884,1104,1800,2136,2344,2848,3188,3826,4486,4902,5322,5352,5432,5500,5536,5555}; const int gs_c_known_encoding_count = 11; @@ -874,38 +886,38 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(5,165), /*space*/ -N(6,474), /*exclam*/ -N(8,168), /*quotedbl*/ +N(5,180), /*space*/ +N(6,480), /*exclam*/ +N(8,176), /*quotedbl*/ N(10,270), /*numbersign*/ -N(6,438), /*dollar*/ -N(7,245), /*percent*/ +N(6,444), /*dollar*/ +N(7,280), /*percent*/ N(9,72), /*ampersand*/ N(10,300), /*quoteright*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ -N(8,48), /*asterisk*/ -N(4,456), /*plus*/ -N(5,95), /*comma*/ -N(6,492), /*hyphen*/ -N(6,600), /*period*/ -N(5,160), /*slash*/ -N(4,464), /*zero*/ +N(8,56), /*asterisk*/ +N(4,464), /*plus*/ +N(5,110), /*comma*/ +N(6,498), /*hyphen*/ +N(6,606), /*period*/ +N(5,175), /*slash*/ +N(4,472), /*zero*/ N(3,276), /*one*/ N(3,294), /*two*/ -N(5,185), /*three*/ -N(4,436), /*four*/ -N(4,432), /*five*/ +N(5,200), /*three*/ +N(4,444), /*four*/ +N(4,440), /*five*/ N(3,288), /*six*/ -N(5,150), /*seven*/ -N(5,105), /*eight*/ -N(4,448), /*nine*/ -N(5,90), /*colon*/ +N(5,165), /*seven*/ +N(5,120), /*eight*/ +N(4,456), /*nine*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ -N(4,444), /*less*/ -N(5,110), /*equal*/ -N(7,189), /*greater*/ -N(8,160), /*question*/ +N(4,452), /*less*/ +N(5,125), /*equal*/ +N(7,224), /*greater*/ +N(8,168), /*question*/ N(2,34), /*at*/ N(1,0), /*A*/ N(1,1), /*B*/ @@ -1004,13 +1016,13 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(10,180), /*exclamdown*/ -N(4,424), /*cent*/ -N(8,184), /*sterling*/ -N(8,104), /*fraction*/ +N(4,432), /*cent*/ +N(8,192), /*sterling*/ +N(8,112), /*fraction*/ N(3,297), /*yen*/ -N(6,480), /*florin*/ -N(7,266), /*section*/ -N(8,64), /*currency*/ +N(6,486), /*florin*/ +N(7,301), /*section*/ +N(8,72), /*currency*/ N(11,539), /*quotesingle*/ N(12,528), /*quotedblleft*/ N(13,208), /*guillemotleft*/ @@ -1019,38 +1031,38 @@ N(14,252), /*guilsinglright*/ N(2,38), /*fi*/ N(2,40), /*fl*/ N(7,0), /*.notdef*/ -N(6,468), /*endash*/ -N(6,408), /*dagger*/ +N(6,474), /*endash*/ +N(6,414), /*dagger*/ N(9,189), /*daggerdbl*/ N(14,308), /*periodcentered*/ N(7,0), /*.notdef*/ N(9,360), /*paragraph*/ -N(6,390), /*bullet*/ +N(6,396), /*bullet*/ N(14,364), /*quotesinglbase*/ N(12,516), /*quotedblbase*/ N(13,273), /*quotedblright*/ N(14,238), /*guillemotright*/ -N(8,88), /*ellipsis*/ +N(8,96), /*ellipsis*/ N(11,528), /*perthousand*/ N(7,0), /*.notdef*/ N(12,504), /*questiondown*/ N(7,0), /*.notdef*/ -N(5,125), /*grave*/ -N(5,55), /*acute*/ +N(5,140), /*grave*/ +N(5,70), /*acute*/ N(10,160), /*circumflex*/ -N(5,190), /*tilde*/ -N(6,534), /*macron*/ -N(5,80), /*breve*/ +N(5,205), /*tilde*/ +N(6,540), /*macron*/ +N(5,95), /*breve*/ N(9,198), /*dotaccent*/ -N(8,72), /*dieresis*/ +N(8,80), /*dieresis*/ N(7,0), /*.notdef*/ -N(4,460), /*ring*/ -N(7,133), /*cedilla*/ +N(4,468), /*ring*/ +N(7,168), /*cedilla*/ N(7,0), /*.notdef*/ N(12,336), /*hungarumlaut*/ -N(6,570), /*ogonek*/ -N(5,85), /*caron*/ -N(6,462), /*emdash*/ +N(6,576), /*ogonek*/ +N(5,100), /*caron*/ +N(6,468), /*emdash*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ @@ -1075,7 +1087,7 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(6,168), /*Lslash*/ -N(6,222), /*Oslash*/ +N(6,228), /*Oslash*/ N(2,8), /*OE*/ N(12,432), /*ordmasculine*/ N(7,0), /*.notdef*/ @@ -1087,11 +1099,11 @@ N(2,32), /*ae*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(8,80), /*dotlessi*/ +N(8,88), /*dotlessi*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(6,528), /*lslash*/ -N(6,588), /*oslash*/ +N(6,534), /*lslash*/ +N(6,594), /*oslash*/ N(2,46), /*oe*/ N(10,200), /*germandbls*/ N(7,0), /*.notdef*/ @@ -1156,61 +1168,61 @@ static const ushort gs_c_known_encoding_reverse_0[] = { 250, /* N(2,46): oe*/ 118, /* N(1,47): v*/ 119, /* N(1,48): w*/ -42, /* N(8,48): asterisk*/ 120, /* N(1,49): x*/ 121, /* N(1,50): y*/ 122, /* N(1,51): z*/ -194, /* N(5,55): acute*/ -168, /* N(8,64): currency*/ -200, /* N(8,72): dieresis*/ +42, /* N(8,56): asterisk*/ +194, /* N(5,70): acute*/ +168, /* N(8,72): currency*/ 38, /* N(9,72): ampersand*/ -198, /* N(5,80): breve*/ -245, /* N(8,80): dotlessi*/ -207, /* N(5,85): caron*/ -188, /* N(8,88): ellipsis*/ -58, /* N(5,90): colon*/ -44, /* N(5,95): comma*/ -164, /* N(8,104): fraction*/ -56, /* N(5,105): eight*/ -61, /* N(5,110): equal*/ -193, /* N(5,125): grave*/ +200, /* N(8,80): dieresis*/ +245, /* N(8,88): dotlessi*/ +198, /* N(5,95): breve*/ +188, /* N(8,96): ellipsis*/ +207, /* N(5,100): caron*/ +58, /* N(5,105): colon*/ +44, /* N(5,110): comma*/ +164, /* N(8,112): fraction*/ +56, /* N(5,120): eight*/ +61, /* N(5,125): equal*/ 126, /* N(10,130): asciitilde*/ -203, /* N(7,133): cedilla*/ 92, /* N(9,135): backslash*/ +193, /* N(5,140): grave*/ 125, /* N(10,140): braceright*/ 123, /* N(9,144): braceleft*/ -55, /* N(5,150): seven*/ -47, /* N(5,160): slash*/ -63, /* N(8,160): question*/ 195, /* N(10,160): circumflex*/ -32, /* N(5,165): space*/ +55, /* N(5,165): seven*/ 232, /* N(6,168): Lslash*/ -34, /* N(8,168): quotedbl*/ +203, /* N(7,168): cedilla*/ +63, /* N(8,168): question*/ +47, /* N(5,175): slash*/ +34, /* N(8,176): quotedbl*/ +32, /* N(5,180): space*/ 161, /* N(10,180): exclamdown*/ -163, /* N(8,184): sterling*/ -51, /* N(5,185): three*/ -62, /* N(7,189): greater*/ 179, /* N(9,189): daggerdbl*/ -196, /* N(5,190): tilde*/ +163, /* N(8,192): sterling*/ 93, /* N(12,192): bracketright*/ 199, /* N(9,198): dotaccent*/ +51, /* N(5,200): three*/ 251, /* N(10,200): germandbls*/ +196, /* N(5,205): tilde*/ 171, /* N(13,208): guillemotleft*/ 172, /* N(13,221): guilsinglleft*/ -233, /* N(6,222): Oslash*/ +62, /* N(7,224): greater*/ +233, /* N(6,228): Oslash*/ 187, /* N(14,238): guillemotright*/ -37, /* N(7,245): percent*/ 173, /* N(14,252): guilsinglright*/ 124, /* N(3,255): bar*/ -167, /* N(7,266): section*/ 35, /* N(10,270): numbersign*/ 186, /* N(13,273): quotedblright*/ 49, /* N(3,276): one*/ +37, /* N(7,280): percent*/ 54, /* N(3,288): six*/ 41, /* N(10,290): parenright*/ 50, /* N(3,294): two*/ 165, /* N(3,297): yen*/ 39, /* N(10,300): quoteright*/ +167, /* N(7,301): section*/ 94, /* N(11,308): asciicircum*/ 180, /* N(14,308): periodcentered*/ 95, /* N(10,320): underscore*/ @@ -1220,35 +1232,35 @@ static const ushort gs_c_known_encoding_reverse_0[] = { 184, /* N(14,364): quotesinglbase*/ 40, /* N(9,369): parenleft*/ 96, /* N(9,387): quoteleft*/ -183, /* N(6,390): bullet*/ -178, /* N(6,408): dagger*/ +183, /* N(6,396): bullet*/ +178, /* N(6,414): dagger*/ 59, /* N(9,414): semicolon*/ -162, /* N(4,424): cent*/ -53, /* N(4,432): five*/ +162, /* N(4,432): cent*/ 235, /* N(12,432): ordmasculine*/ -52, /* N(4,436): four*/ -36, /* N(6,438): dollar*/ -60, /* N(4,444): less*/ -57, /* N(4,448): nine*/ -43, /* N(4,456): plus*/ -202, /* N(4,460): ring*/ -208, /* N(6,462): emdash*/ -48, /* N(4,464): zero*/ -177, /* N(6,468): endash*/ +53, /* N(4,440): five*/ +52, /* N(4,444): four*/ +36, /* N(6,444): dollar*/ +60, /* N(4,452): less*/ +57, /* N(4,456): nine*/ +43, /* N(4,464): plus*/ +202, /* N(4,468): ring*/ +208, /* N(6,468): emdash*/ +48, /* N(4,472): zero*/ 227, /* N(11,473): ordfeminine*/ -33, /* N(6,474): exclam*/ -166, /* N(6,480): florin*/ -45, /* N(6,492): hyphen*/ +177, /* N(6,474): endash*/ +33, /* N(6,480): exclam*/ +166, /* N(6,486): florin*/ +45, /* N(6,498): hyphen*/ 191, /* N(12,504): questiondown*/ 185, /* N(12,516): quotedblbase*/ -248, /* N(6,528): lslash*/ 189, /* N(11,528): perthousand*/ 170, /* N(12,528): quotedblleft*/ -197, /* N(6,534): macron*/ +248, /* N(6,534): lslash*/ 169, /* N(11,539): quotesingle*/ -206, /* N(6,570): ogonek*/ -249, /* N(6,588): oslash*/ -46, /* N(6,600): period*/ +197, /* N(6,540): macron*/ +206, /* N(6,576): ogonek*/ +249, /* N(6,594): oslash*/ +46, /* N(6,606): period*/ 0}; /* ISOLatin1Encoding */ @@ -1285,38 +1297,38 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(5,165), /*space*/ -N(6,474), /*exclam*/ -N(8,168), /*quotedbl*/ +N(5,180), /*space*/ +N(6,480), /*exclam*/ +N(8,176), /*quotedbl*/ N(10,270), /*numbersign*/ -N(6,438), /*dollar*/ -N(7,245), /*percent*/ +N(6,444), /*dollar*/ +N(7,280), /*percent*/ N(9,72), /*ampersand*/ N(10,300), /*quoteright*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ -N(8,48), /*asterisk*/ -N(4,456), /*plus*/ -N(5,95), /*comma*/ -N(5,140), /*minus*/ -N(6,600), /*period*/ -N(5,160), /*slash*/ -N(4,464), /*zero*/ +N(8,56), /*asterisk*/ +N(4,464), /*plus*/ +N(5,110), /*comma*/ +N(5,155), /*minus*/ +N(6,606), /*period*/ +N(5,175), /*slash*/ +N(4,472), /*zero*/ N(3,276), /*one*/ N(3,294), /*two*/ -N(5,185), /*three*/ -N(4,436), /*four*/ -N(4,432), /*five*/ +N(5,200), /*three*/ +N(4,444), /*four*/ +N(4,440), /*five*/ N(3,288), /*six*/ -N(5,150), /*seven*/ -N(5,105), /*eight*/ -N(4,448), /*nine*/ -N(5,90), /*colon*/ +N(5,165), /*seven*/ +N(5,120), /*eight*/ +N(4,456), /*nine*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ -N(4,444), /*less*/ -N(5,110), /*equal*/ -N(7,189), /*greater*/ -N(8,160), /*question*/ +N(4,452), /*less*/ +N(5,125), /*equal*/ +N(7,224), /*greater*/ +N(8,168), /*question*/ N(2,34), /*at*/ N(1,0), /*A*/ N(1,1), /*B*/ @@ -1397,52 +1409,52 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(8,80), /*dotlessi*/ -N(5,125), /*grave*/ -N(5,55), /*acute*/ +N(8,88), /*dotlessi*/ +N(5,140), /*grave*/ +N(5,70), /*acute*/ N(10,160), /*circumflex*/ -N(5,190), /*tilde*/ -N(6,534), /*macron*/ -N(5,80), /*breve*/ +N(5,205), /*tilde*/ +N(6,540), /*macron*/ +N(5,95), /*breve*/ N(9,198), /*dotaccent*/ -N(8,72), /*dieresis*/ +N(8,80), /*dieresis*/ N(7,0), /*.notdef*/ -N(4,460), /*ring*/ -N(7,133), /*cedilla*/ +N(4,468), /*ring*/ +N(7,168), /*cedilla*/ N(7,0), /*.notdef*/ N(12,336), /*hungarumlaut*/ -N(6,570), /*ogonek*/ -N(5,85), /*caron*/ -N(5,165), /*space*/ +N(6,576), /*ogonek*/ +N(5,100), /*caron*/ +N(5,180), /*space*/ N(10,180), /*exclamdown*/ -N(4,424), /*cent*/ -N(8,184), /*sterling*/ -N(8,64), /*currency*/ +N(4,432), /*cent*/ +N(8,192), /*sterling*/ +N(8,72), /*currency*/ N(3,297), /*yen*/ N(9,153), /*brokenbar*/ -N(7,266), /*section*/ -N(8,72), /*dieresis*/ +N(7,301), /*section*/ +N(8,80), /*dieresis*/ N(9,180), /*copyright*/ N(11,473), /*ordfeminine*/ N(13,208), /*guillemotleft*/ N(10,250), /*logicalnot*/ -N(6,492), /*hyphen*/ +N(6,498), /*hyphen*/ N(10,310), /*registered*/ -N(6,534), /*macron*/ -N(6,426), /*degree*/ +N(6,540), /*macron*/ +N(6,432), /*degree*/ N(9,378), /*plusminus*/ N(11,605), /*twosuperior*/ N(13,377), /*threesuperior*/ -N(5,55), /*acute*/ +N(5,70), /*acute*/ N(2,42), /*mu*/ N(9,360), /*paragraph*/ N(14,308), /*periodcentered*/ -N(7,133), /*cedilla*/ +N(7,168), /*cedilla*/ N(11,462), /*onesuperior*/ N(12,432), /*ordmasculine*/ N(14,238), /*guillemotright*/ N(10,280), /*onequarter*/ -N(7,238), /*onehalf*/ +N(7,273), /*onehalf*/ N(13,364), /*threequarters*/ N(12,504), /*questiondown*/ N(6,12), /*Agrave*/ @@ -1462,52 +1474,52 @@ N(6,120), /*Iacute*/ N(11,88), /*Icircumflex*/ N(9,18), /*Idieresis*/ N(3,6), /*Eth*/ -N(6,204), /*Ntilde*/ -N(6,216), /*Ograve*/ -N(6,210), /*Oacute*/ +N(6,210), /*Ntilde*/ +N(6,222), /*Ograve*/ +N(6,216), /*Oacute*/ N(11,154), /*Ocircumflex*/ -N(6,234), /*Otilde*/ +N(6,240), /*Otilde*/ N(9,27), /*Odieresis*/ -N(8,136), /*multiply*/ -N(6,222), /*Oslash*/ -N(6,306), /*Ugrave*/ -N(6,300), /*Uacute*/ +N(8,144), /*multiply*/ +N(6,228), /*Oslash*/ +N(6,312), /*Ugrave*/ +N(6,306), /*Uacute*/ N(11,231), /*Ucircumflex*/ N(9,45), /*Udieresis*/ -N(6,336), /*Yacute*/ -N(5,45), /*Thorn*/ +N(6,342), /*Yacute*/ +N(5,60), /*Thorn*/ N(10,200), /*germandbls*/ -N(6,378), /*agrave*/ -N(6,366), /*aacute*/ +N(6,384), /*agrave*/ +N(6,372), /*aacute*/ N(11,275), /*acircumflex*/ -N(6,384), /*atilde*/ +N(6,390), /*atilde*/ N(9,63), /*adieresis*/ -N(5,75), /*aring*/ +N(5,90), /*aring*/ N(2,32), /*ae*/ -N(8,56), /*ccedilla*/ -N(6,456), /*egrave*/ -N(6,444), /*eacute*/ +N(8,64), /*ccedilla*/ +N(6,462), /*egrave*/ +N(6,450), /*eacute*/ N(11,363), /*ecircumflex*/ N(9,216), /*edieresis*/ -N(6,504), /*igrave*/ -N(6,498), /*iacute*/ +N(6,510), /*igrave*/ +N(6,504), /*iacute*/ N(11,418), /*icircumflex*/ N(9,234), /*idieresis*/ N(3,264), /*eth*/ -N(6,558), /*ntilde*/ -N(6,576), /*ograve*/ -N(6,564), /*oacute*/ +N(6,564), /*ntilde*/ +N(6,582), /*ograve*/ +N(6,570), /*oacute*/ N(11,429), /*ocircumflex*/ -N(6,594), /*otilde*/ +N(6,600), /*otilde*/ N(9,315), /*odieresis*/ -N(6,432), /*divide*/ -N(6,588), /*oslash*/ -N(6,666), /*ugrave*/ -N(6,660), /*uacute*/ +N(6,438), /*divide*/ +N(6,594), /*oslash*/ +N(6,672), /*ugrave*/ +N(6,666), /*uacute*/ N(11,616), /*ucircumflex*/ N(9,477), /*udieresis*/ -N(6,672), /*yacute*/ -N(5,180), /*thorn*/ +N(6,678), /*yacute*/ +N(5,195), /*thorn*/ N(9,495), /*ydieresis*/ 0}; static const ushort gs_c_known_encoding_reverse_1[] = { @@ -1572,150 +1584,150 @@ static const ushort gs_c_known_encoding_reverse_1[] = { 114, /* N(1,43): r*/ 115, /* N(1,44): s*/ 116, /* N(1,45): t*/ -222, /* N(5,45): Thorn*/ 220, /* N(9,45): Udieresis*/ 117, /* N(1,46): u*/ 118, /* N(1,47): v*/ 119, /* N(1,48): w*/ -42, /* N(8,48): asterisk*/ 120, /* N(1,49): x*/ 121, /* N(1,50): y*/ 122, /* N(1,51): z*/ -146, /* N(5,55): acute*/ -180, /* N(5,55): acute*/ 202, /* N(11,55): Ecircumflex*/ -231, /* N(8,56): ccedilla*/ +42, /* N(8,56): asterisk*/ +222, /* N(5,60): Thorn*/ 228, /* N(9,63): adieresis*/ -164, /* N(8,64): currency*/ +231, /* N(8,64): ccedilla*/ +146, /* N(5,70): acute*/ +180, /* N(5,70): acute*/ 201, /* N(6,72): Eacute*/ -168, /* N(8,72): dieresis*/ -152, /* N(8,72): dieresis*/ +164, /* N(8,72): currency*/ 38, /* N(9,72): ampersand*/ -229, /* N(5,75): aring*/ -150, /* N(5,80): breve*/ -144, /* N(8,80): dotlessi*/ +168, /* N(8,80): dieresis*/ +152, /* N(8,80): dieresis*/ 200, /* N(6,84): Egrave*/ -159, /* N(5,85): caron*/ +144, /* N(8,88): dotlessi*/ 206, /* N(11,88): Icircumflex*/ -58, /* N(5,90): colon*/ -44, /* N(5,95): comma*/ -56, /* N(5,105): eight*/ -61, /* N(5,110): equal*/ +229, /* N(5,90): aring*/ +150, /* N(5,95): breve*/ +159, /* N(5,100): caron*/ +58, /* N(5,105): colon*/ +44, /* N(5,110): comma*/ +56, /* N(5,120): eight*/ 205, /* N(6,120): Iacute*/ -145, /* N(5,125): grave*/ +61, /* N(5,125): equal*/ 204, /* N(6,126): Igrave*/ 126, /* N(10,130): asciitilde*/ -184, /* N(7,133): cedilla*/ -155, /* N(7,133): cedilla*/ 92, /* N(9,135): backslash*/ -215, /* N(8,136): multiply*/ -45, /* N(5,140): minus*/ +145, /* N(5,140): grave*/ 125, /* N(10,140): braceright*/ +215, /* N(8,144): multiply*/ 123, /* N(9,144): braceleft*/ -55, /* N(5,150): seven*/ 166, /* N(9,153): brokenbar*/ 212, /* N(11,154): Ocircumflex*/ -47, /* N(5,160): slash*/ -63, /* N(8,160): question*/ +45, /* N(5,155): minus*/ 147, /* N(10,160): circumflex*/ -160, /* N(5,165): space*/ -32, /* N(5,165): space*/ -34, /* N(8,168): quotedbl*/ -254, /* N(5,180): thorn*/ +55, /* N(5,165): seven*/ +155, /* N(7,168): cedilla*/ +184, /* N(7,168): cedilla*/ +63, /* N(8,168): question*/ +47, /* N(5,175): slash*/ +34, /* N(8,176): quotedbl*/ +160, /* N(5,180): space*/ +32, /* N(5,180): space*/ 169, /* N(9,180): copyright*/ 161, /* N(10,180): exclamdown*/ -163, /* N(8,184): sterling*/ -51, /* N(5,185): three*/ -62, /* N(7,189): greater*/ -148, /* N(5,190): tilde*/ +163, /* N(8,192): sterling*/ 93, /* N(12,192): bracketright*/ +254, /* N(5,195): thorn*/ 151, /* N(9,198): dotaccent*/ +51, /* N(5,200): three*/ 223, /* N(10,200): germandbls*/ -209, /* N(6,204): Ntilde*/ +148, /* N(5,205): tilde*/ 171, /* N(13,208): guillemotleft*/ -211, /* N(6,210): Oacute*/ -210, /* N(6,216): Ograve*/ +209, /* N(6,210): Ntilde*/ +211, /* N(6,216): Oacute*/ 235, /* N(9,216): edieresis*/ -216, /* N(6,222): Oslash*/ +210, /* N(6,222): Ograve*/ +62, /* N(7,224): greater*/ +216, /* N(6,228): Oslash*/ 219, /* N(11,231): Ucircumflex*/ -213, /* N(6,234): Otilde*/ 239, /* N(9,234): idieresis*/ -189, /* N(7,238): onehalf*/ 187, /* N(14,238): guillemotright*/ -37, /* N(7,245): percent*/ +213, /* N(6,240): Otilde*/ 172, /* N(10,250): logicalnot*/ 124, /* N(3,255): bar*/ 240, /* N(3,264): eth*/ -167, /* N(7,266): section*/ 35, /* N(10,270): numbersign*/ +189, /* N(7,273): onehalf*/ 226, /* N(11,275): acircumflex*/ 49, /* N(3,276): one*/ +37, /* N(7,280): percent*/ 188, /* N(10,280): onequarter*/ 54, /* N(3,288): six*/ 41, /* N(10,290): parenright*/ 50, /* N(3,294): two*/ 165, /* N(3,297): yen*/ -218, /* N(6,300): Uacute*/ 39, /* N(10,300): quoteright*/ -217, /* N(6,306): Ugrave*/ +167, /* N(7,301): section*/ +218, /* N(6,306): Uacute*/ 94, /* N(11,308): asciicircum*/ 183, /* N(14,308): periodcentered*/ 174, /* N(10,310): registered*/ +217, /* N(6,312): Ugrave*/ 246, /* N(9,315): odieresis*/ 95, /* N(10,320): underscore*/ -221, /* N(6,336): Yacute*/ 157, /* N(12,336): hungarumlaut*/ 91, /* N(11,341): bracketleft*/ +221, /* N(6,342): Yacute*/ 182, /* N(9,360): paragraph*/ 234, /* N(11,363): ecircumflex*/ 190, /* N(13,364): threequarters*/ -225, /* N(6,366): aacute*/ 40, /* N(9,369): parenleft*/ +225, /* N(6,372): aacute*/ 179, /* N(13,377): threesuperior*/ -224, /* N(6,378): agrave*/ 177, /* N(9,378): plusminus*/ -227, /* N(6,384): atilde*/ +224, /* N(6,384): agrave*/ 96, /* N(9,387): quoteleft*/ +227, /* N(6,390): atilde*/ 59, /* N(9,414): semicolon*/ 238, /* N(11,418): icircumflex*/ -162, /* N(4,424): cent*/ -176, /* N(6,426): degree*/ 244, /* N(11,429): ocircumflex*/ -53, /* N(4,432): five*/ -247, /* N(6,432): divide*/ +162, /* N(4,432): cent*/ +176, /* N(6,432): degree*/ 186, /* N(12,432): ordmasculine*/ -52, /* N(4,436): four*/ -36, /* N(6,438): dollar*/ -60, /* N(4,444): less*/ -233, /* N(6,444): eacute*/ -57, /* N(4,448): nine*/ -43, /* N(4,456): plus*/ -232, /* N(6,456): egrave*/ -154, /* N(4,460): ring*/ +247, /* N(6,438): divide*/ +53, /* N(4,440): five*/ +52, /* N(4,444): four*/ +36, /* N(6,444): dollar*/ +233, /* N(6,450): eacute*/ +60, /* N(4,452): less*/ +57, /* N(4,456): nine*/ +232, /* N(6,462): egrave*/ 185, /* N(11,462): onesuperior*/ -48, /* N(4,464): zero*/ +43, /* N(4,464): plus*/ +154, /* N(4,468): ring*/ +48, /* N(4,472): zero*/ 170, /* N(11,473): ordfeminine*/ -33, /* N(6,474): exclam*/ 252, /* N(9,477): udieresis*/ -173, /* N(6,492): hyphen*/ +33, /* N(6,480): exclam*/ 255, /* N(9,495): ydieresis*/ -237, /* N(6,498): iacute*/ -236, /* N(6,504): igrave*/ +173, /* N(6,498): hyphen*/ +237, /* N(6,504): iacute*/ 191, /* N(12,504): questiondown*/ -175, /* N(6,534): macron*/ -149, /* N(6,534): macron*/ -241, /* N(6,558): ntilde*/ -243, /* N(6,564): oacute*/ -158, /* N(6,570): ogonek*/ -242, /* N(6,576): ograve*/ -248, /* N(6,588): oslash*/ -245, /* N(6,594): otilde*/ -46, /* N(6,600): period*/ +236, /* N(6,510): igrave*/ +175, /* N(6,540): macron*/ +149, /* N(6,540): macron*/ +241, /* N(6,564): ntilde*/ +243, /* N(6,570): oacute*/ +158, /* N(6,576): ogonek*/ +242, /* N(6,582): ograve*/ +248, /* N(6,594): oslash*/ +245, /* N(6,600): otilde*/ 178, /* N(11,605): twosuperior*/ +46, /* N(6,606): period*/ 251, /* N(11,616): ucircumflex*/ -250, /* N(6,660): uacute*/ -249, /* N(6,666): ugrave*/ -253, /* N(6,672): yacute*/ +250, /* N(6,666): uacute*/ +249, /* N(6,672): ugrave*/ +253, /* N(6,678): yacute*/ 0}; /* SymbolEncoding */ @@ -1752,101 +1764,101 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(5,165), /*space*/ -N(6,474), /*exclam*/ +N(5,180), /*space*/ +N(6,480), /*exclam*/ N(9,486), /*universal*/ N(10,270), /*numbersign*/ N(11,396), /*existential*/ -N(7,245), /*percent*/ +N(7,280), /*percent*/ N(9,72), /*ampersand*/ -N(8,192), /*suchthat*/ +N(8,200), /*suchthat*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ N(12,144), /*asteriskmath*/ -N(4,456), /*plus*/ -N(5,95), /*comma*/ -N(5,140), /*minus*/ -N(6,600), /*period*/ -N(5,160), /*slash*/ -N(4,464), /*zero*/ +N(4,464), /*plus*/ +N(5,110), /*comma*/ +N(5,155), /*minus*/ +N(6,606), /*period*/ +N(5,175), /*slash*/ +N(4,472), /*zero*/ N(3,276), /*one*/ N(3,294), /*two*/ -N(5,185), /*three*/ -N(4,436), /*four*/ -N(4,432), /*five*/ +N(5,200), /*three*/ +N(4,444), /*four*/ +N(4,440), /*five*/ N(3,288), /*six*/ -N(5,150), /*seven*/ -N(5,105), /*eight*/ -N(4,448), /*nine*/ -N(5,90), /*colon*/ +N(5,165), /*seven*/ +N(5,120), /*eight*/ +N(4,456), /*nine*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ -N(4,444), /*less*/ -N(5,110), /*equal*/ -N(7,189), /*greater*/ -N(8,160), /*question*/ +N(4,452), /*less*/ +N(5,125), /*equal*/ +N(7,224), /*greater*/ +N(8,168), /*question*/ N(9,171), /*congruent*/ N(5,5), /*Alpha*/ N(4,0), /*Beta*/ N(3,0), /*Chi*/ -N(5,15), /*Delta*/ -N(7,42), /*Epsilon*/ +N(5,20), /*Delta*/ +N(7,70), /*Epsilon*/ N(3,12), /*Phi*/ -N(5,20), /*Gamma*/ +N(5,25), /*Gamma*/ N(3,3), /*Eta*/ -N(4,8), /*Iota*/ -N(6,654), /*theta1*/ -N(5,25), /*Kappa*/ +N(4,16), /*Iota*/ +N(6,660), /*theta1*/ +N(5,30), /*Kappa*/ N(6,156), /*Lambda*/ N(2,4), /*Mu*/ N(2,6), /*Nu*/ -N(7,77), /*Omicron*/ +N(7,105), /*Omicron*/ N(2,10), /*Pi*/ -N(5,40), /*Theta*/ +N(5,55), /*Theta*/ N(3,18), /*Rho*/ -N(5,35), /*Sigma*/ +N(5,50), /*Sigma*/ N(3,21), /*Tau*/ -N(7,98), /*Upsilon*/ -N(6,642), /*sigma1*/ -N(5,30), /*Omega*/ +N(7,133), /*Upsilon*/ +N(6,648), /*sigma1*/ +N(5,40), /*Omega*/ N(2,12), /*Xi*/ N(3,15), /*Psi*/ -N(4,12), /*Zeta*/ +N(4,20), /*Zeta*/ N(11,341), /*bracketleft*/ N(9,441), /*therefore*/ N(12,192), /*bracketright*/ N(13,247), /*perpendicular*/ N(10,320), /*underscore*/ N(9,396), /*radicalex*/ -N(5,65), /*alpha*/ -N(4,420), /*beta*/ +N(5,80), /*alpha*/ +N(4,428), /*beta*/ N(3,258), /*chi*/ -N(5,100), /*delta*/ -N(7,182), /*epsilon*/ +N(5,115), /*delta*/ +N(7,217), /*epsilon*/ N(3,279), /*phi*/ -N(5,120), /*gamma*/ +N(5,135), /*gamma*/ N(3,261), /*eta*/ -N(4,440), /*iota*/ -N(4,452), /*phi1*/ -N(5,135), /*kappa*/ -N(6,516), /*lambda*/ +N(4,448), /*iota*/ +N(4,460), /*phi1*/ +N(5,150), /*kappa*/ +N(6,522), /*lambda*/ N(2,42), /*mu*/ N(2,44), /*nu*/ -N(7,231), /*omicron*/ +N(7,266), /*omicron*/ N(2,48), /*pi*/ -N(5,175), /*theta*/ +N(5,190), /*theta*/ N(3,285), /*rho*/ -N(5,155), /*sigma*/ +N(5,170), /*sigma*/ N(3,291), /*tau*/ -N(7,294), /*upsilon*/ -N(6,582), /*omega1*/ -N(5,145), /*omega*/ +N(7,329), /*upsilon*/ +N(6,588), /*omega1*/ +N(5,160), /*omega*/ N(2,50), /*xi*/ N(3,282), /*psi*/ -N(4,468), /*zeta*/ +N(4,476), /*zeta*/ N(9,144), /*braceleft*/ N(3,255), /*bar*/ N(10,140), /*braceright*/ -N(7,273), /*similar*/ +N(7,308), /*similar*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ @@ -1880,62 +1892,62 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(4,4), /*Euro*/ -N(8,40), /*Upsilon1*/ -N(6,540), /*minute*/ +N(4,12), /*Euro*/ +N(8,48), /*Upsilon1*/ +N(6,546), /*minute*/ N(9,261), /*lessequal*/ -N(8,104), /*fraction*/ -N(8,120), /*infinity*/ -N(6,480), /*florin*/ -N(4,428), /*club*/ -N(7,140), /*diamond*/ -N(5,130), /*heart*/ -N(5,170), /*spade*/ +N(8,112), /*fraction*/ +N(8,128), /*infinity*/ +N(6,486), /*florin*/ +N(4,436), /*club*/ +N(7,175), /*diamond*/ +N(5,145), /*heart*/ +N(5,185), /*spade*/ N(9,99), /*arrowboth*/ N(9,117), /*arrowleft*/ -N(7,119), /*arrowup*/ +N(7,154), /*arrowup*/ N(10,120), /*arrowright*/ N(9,108), /*arrowdown*/ -N(6,426), /*degree*/ +N(6,432), /*degree*/ N(9,378), /*plusminus*/ -N(6,636), /*second*/ +N(6,642), /*second*/ N(12,324), /*greaterequal*/ -N(8,136), /*multiply*/ +N(8,144), /*multiply*/ N(12,492), /*proportional*/ N(11,517), /*partialdiff*/ -N(6,390), /*bullet*/ -N(6,432), /*divide*/ -N(8,144), /*notequal*/ +N(6,396), /*bullet*/ +N(6,438), /*divide*/ +N(8,152), /*notequal*/ N(11,374), /*equivalence*/ N(11,286), /*approxequal*/ -N(8,88), /*ellipsis*/ +N(8,96), /*ellipsis*/ N(11,297), /*arrowvertex*/ N(12,132), /*arrowhorizex*/ N(14,154), /*carriagereturn*/ -N(5,60), /*aleph*/ +N(5,75), /*aleph*/ N(8,16), /*Ifraktur*/ N(8,24), /*Rfraktur*/ N(11,627), /*weierstrass*/ N(14,168), /*circlemultiply*/ N(10,150), /*circleplus*/ -N(8,96), /*emptyset*/ +N(8,104), /*emptyset*/ N(12,348), /*intersection*/ -N(5,195), /*union*/ +N(5,210), /*union*/ N(14,350), /*propersuperset*/ N(14,378), /*reflexsuperset*/ N(9,297), /*notsubset*/ N(12,480), /*propersubset*/ N(12,552), /*reflexsubset*/ -N(7,161), /*element*/ +N(7,196), /*element*/ N(10,260), /*notelement*/ -N(5,70), /*angle*/ -N(8,112), /*gradient*/ +N(5,85), /*angle*/ +N(8,120), /*gradient*/ N(13,286), /*registerserif*/ N(14,182), /*copyrightserif*/ N(14,392), /*trademarkserif*/ -N(7,252), /*product*/ -N(7,259), /*radical*/ -N(7,154), /*dotmath*/ +N(7,287), /*product*/ +N(7,294), /*radical*/ +N(7,189), /*dotmath*/ N(10,250), /*logicalnot*/ N(10,240), /*logicaland*/ N(9,270), /*logicalor*/ @@ -1944,7 +1956,7 @@ N(12,120), /*arrowdblleft*/ N(10,110), /*arrowdblup*/ N(13,52), /*arrowdblright*/ N(12,108), /*arrowdbldown*/ -N(7,210), /*lozenge*/ +N(7,245), /*lozenge*/ N(9,81), /*angleleft*/ N(12,564), /*registersans*/ N(13,156), /*copyrightsans*/ @@ -1959,10 +1971,10 @@ N(13,78), /*bracketleftbt*/ N(11,330), /*bracelefttp*/ N(12,156), /*braceleftmid*/ N(11,319), /*braceleftbt*/ -N(7,126), /*braceex*/ +N(7,161), /*braceex*/ N(7,0), /*.notdef*/ N(10,100), /*angleright*/ -N(8,128), /*integral*/ +N(8,136), /*integral*/ N(10,230), /*integraltp*/ N(10,220), /*integralex*/ N(10,210), /*integralbt*/ @@ -1982,140 +1994,140 @@ static const ushort gs_c_known_encoding_reverse_2[] = { 66, /* N(4,0): Beta*/ 72, /* N(3,3): Eta*/ 77, /* N(2,4): Mu*/ -160, /* N(4,4): Euro*/ 65, /* N(5,5): Alpha*/ 78, /* N(2,6): Nu*/ -73, /* N(4,8): Iota*/ 80, /* N(2,10): Pi*/ 88, /* N(2,12): Xi*/ 70, /* N(3,12): Phi*/ -90, /* N(4,12): Zeta*/ +160, /* N(4,12): Euro*/ 89, /* N(3,15): Psi*/ -68, /* N(5,15): Delta*/ +73, /* N(4,16): Iota*/ 193, /* N(8,16): Ifraktur*/ 82, /* N(3,18): Rho*/ -71, /* N(5,20): Gamma*/ +90, /* N(4,20): Zeta*/ +68, /* N(5,20): Delta*/ 84, /* N(3,21): Tau*/ 194, /* N(8,24): Rfraktur*/ -75, /* N(5,25): Kappa*/ -87, /* N(5,30): Omega*/ -83, /* N(5,35): Sigma*/ -81, /* N(5,40): Theta*/ -161, /* N(8,40): Upsilon1*/ +71, /* N(5,25): Gamma*/ +75, /* N(5,30): Kappa*/ +87, /* N(5,40): Omega*/ 109, /* N(2,42): mu*/ -69, /* N(7,42): Epsilon*/ 110, /* N(2,44): nu*/ 112, /* N(2,48): pi*/ +161, /* N(8,48): Upsilon1*/ 120, /* N(2,50): xi*/ +83, /* N(5,50): Sigma*/ 222, /* N(13,52): arrowdblright*/ -192, /* N(5,60): aleph*/ -97, /* N(5,65): alpha*/ +81, /* N(5,55): Theta*/ 253, /* N(13,65): bracerightmid*/ -208, /* N(5,70): angle*/ +69, /* N(7,70): Epsilon*/ 38, /* N(9,72): ampersand*/ -79, /* N(7,77): Omicron*/ +192, /* N(5,75): aleph*/ 235, /* N(13,78): bracketleftbt*/ +97, /* N(5,80): alpha*/ 225, /* N(9,81): angleleft*/ -188, /* N(8,88): ellipsis*/ -58, /* N(5,90): colon*/ +208, /* N(5,85): angle*/ 234, /* N(13,91): bracketleftex*/ -44, /* N(5,95): comma*/ -198, /* N(8,96): emptyset*/ +188, /* N(8,96): ellipsis*/ 219, /* N(12,96): arrowdblboth*/ -85, /* N(7,98): Upsilon*/ 171, /* N(9,99): arrowboth*/ -100, /* N(5,100): delta*/ 241, /* N(10,100): angleright*/ -164, /* N(8,104): fraction*/ +198, /* N(8,104): emptyset*/ 233, /* N(13,104): bracketlefttp*/ -56, /* N(5,105): eight*/ +58, /* N(5,105): colon*/ +79, /* N(7,105): Omicron*/ 175, /* N(9,108): arrowdown*/ 223, /* N(12,108): arrowdbldown*/ -61, /* N(5,110): equal*/ +44, /* N(5,110): comma*/ 221, /* N(10,110): arrowdblup*/ -209, /* N(8,112): gradient*/ +164, /* N(8,112): fraction*/ 251, /* N(14,112): bracketrightbt*/ +100, /* N(5,115): delta*/ 172, /* N(9,117): arrowleft*/ -173, /* N(7,119): arrowup*/ -103, /* N(5,120): gamma*/ -165, /* N(8,120): infinity*/ +56, /* N(5,120): eight*/ +209, /* N(8,120): gradient*/ 174, /* N(10,120): arrowright*/ 220, /* N(12,120): arrowdblleft*/ -239, /* N(7,126): braceex*/ +61, /* N(5,125): equal*/ 250, /* N(14,126): bracketrightex*/ -242, /* N(8,128): integral*/ -169, /* N(5,130): heart*/ +165, /* N(8,128): infinity*/ 190, /* N(12,132): arrowhorizex*/ -107, /* N(5,135): kappa*/ -180, /* N(8,136): multiply*/ -45, /* N(5,140): minus*/ -168, /* N(7,140): diamond*/ +85, /* N(7,133): Upsilon*/ +103, /* N(5,135): gamma*/ +242, /* N(8,136): integral*/ 125, /* N(10,140): braceright*/ 249, /* N(14,140): bracketrighttp*/ -185, /* N(8,144): notequal*/ +180, /* N(8,144): multiply*/ 123, /* N(9,144): braceleft*/ 42, /* N(12,144): asteriskmath*/ -119, /* N(5,145): omega*/ -55, /* N(5,150): seven*/ +169, /* N(5,145): heart*/ +107, /* N(5,150): kappa*/ 197, /* N(10,150): circleplus*/ -215, /* N(7,154): dotmath*/ +185, /* N(8,152): notequal*/ +173, /* N(7,154): arrowup*/ 191, /* N(14,154): carriagereturn*/ -115, /* N(5,155): sigma*/ +45, /* N(5,155): minus*/ 76, /* N(6,156): Lambda*/ 237, /* N(12,156): braceleftmid*/ 227, /* N(13,156): copyrightsans*/ -47, /* N(5,160): slash*/ -63, /* N(8,160): question*/ -206, /* N(7,161): element*/ -32, /* N(5,165): space*/ +119, /* N(5,160): omega*/ +239, /* N(7,161): braceex*/ +55, /* N(5,165): seven*/ +63, /* N(8,168): question*/ 254, /* N(12,168): bracerightbt*/ 196, /* N(14,168): circlemultiply*/ -170, /* N(5,170): spade*/ +115, /* N(5,170): sigma*/ 64, /* N(9,171): congruent*/ -113, /* N(5,175): theta*/ +47, /* N(5,175): slash*/ +168, /* N(7,175): diamond*/ +32, /* N(5,180): space*/ 252, /* N(12,180): bracerighttp*/ -101, /* N(7,182): epsilon*/ 211, /* N(14,182): copyrightserif*/ -51, /* N(5,185): three*/ -62, /* N(7,189): greater*/ -39, /* N(8,192): suchthat*/ +170, /* N(5,185): spade*/ +215, /* N(7,189): dotmath*/ +113, /* N(5,190): theta*/ 93, /* N(12,192): bracketright*/ -200, /* N(5,195): union*/ -224, /* N(7,210): lozenge*/ +206, /* N(7,196): element*/ +51, /* N(5,200): three*/ +39, /* N(8,200): suchthat*/ +200, /* N(5,210): union*/ 245, /* N(10,210): integralbt*/ +101, /* N(7,217): epsilon*/ 244, /* N(10,220): integralex*/ +62, /* N(7,224): greater*/ 243, /* N(10,230): integraltp*/ -111, /* N(7,231): omicron*/ 217, /* N(10,240): logicaland*/ -37, /* N(7,245): percent*/ +224, /* N(7,245): lozenge*/ 94, /* N(13,247): perpendicular*/ 216, /* N(10,250): logicalnot*/ -213, /* N(7,252): product*/ 124, /* N(3,255): bar*/ 99, /* N(3,258): chi*/ -214, /* N(7,259): radical*/ 207, /* N(10,260): notelement*/ 104, /* N(3,261): eta*/ 163, /* N(9,261): lessequal*/ +111, /* N(7,266): omicron*/ 218, /* N(9,270): logicalor*/ 35, /* N(10,270): numbersign*/ -126, /* N(7,273): similar*/ 49, /* N(3,276): one*/ 102, /* N(3,279): phi*/ +37, /* N(7,280): percent*/ 121, /* N(3,282): psi*/ 114, /* N(3,285): rho*/ 187, /* N(11,286): approxequal*/ 210, /* N(13,286): registerserif*/ +213, /* N(7,287): product*/ 54, /* N(3,288): six*/ 41, /* N(10,290): parenright*/ 116, /* N(3,291): tau*/ 50, /* N(3,294): two*/ -117, /* N(7,294): upsilon*/ +214, /* N(7,294): radical*/ 203, /* N(9,297): notsubset*/ 189, /* N(11,297): arrowvertex*/ +126, /* N(7,308): similar*/ 238, /* N(11,319): braceleftbt*/ 95, /* N(10,320): underscore*/ 179, /* N(12,324): greaterequal*/ +117, /* N(7,329): upsilon*/ 236, /* N(11,330): bracelefttp*/ 91, /* N(11,341): bracketleft*/ 199, /* N(12,348): intersection*/ @@ -2124,49 +2136,49 @@ static const ushort gs_c_known_encoding_reverse_2[] = { 186, /* N(11,374): equivalence*/ 177, /* N(9,378): plusminus*/ 202, /* N(14,378): reflexsuperset*/ -183, /* N(6,390): bullet*/ 228, /* N(13,390): trademarksans*/ 212, /* N(14,392): trademarkserif*/ +183, /* N(6,396): bullet*/ 96, /* N(9,396): radicalex*/ 36, /* N(11,396): existential*/ 59, /* N(9,414): semicolon*/ -98, /* N(4,420): beta*/ -176, /* N(6,426): degree*/ -167, /* N(4,428): club*/ -53, /* N(4,432): five*/ -184, /* N(6,432): divide*/ +98, /* N(4,428): beta*/ +176, /* N(6,432): degree*/ 229, /* N(9,432): summation*/ -52, /* N(4,436): four*/ -105, /* N(4,440): iota*/ +167, /* N(4,436): club*/ +184, /* N(6,438): divide*/ +53, /* N(4,440): five*/ 92, /* N(9,441): therefore*/ -60, /* N(4,444): less*/ +52, /* N(4,444): four*/ 248, /* N(12,444): parenrightbt*/ -57, /* N(4,448): nine*/ -106, /* N(4,452): phi1*/ -43, /* N(4,456): plus*/ +105, /* N(4,448): iota*/ +60, /* N(4,452): less*/ +57, /* N(4,456): nine*/ 247, /* N(12,456): parenrightex*/ -48, /* N(4,464): zero*/ -122, /* N(4,468): zeta*/ +106, /* N(4,460): phi1*/ +43, /* N(4,464): plus*/ 246, /* N(12,468): parenrighttp*/ -33, /* N(6,474): exclam*/ -166, /* N(6,480): florin*/ +48, /* N(4,472): zero*/ +122, /* N(4,476): zeta*/ +33, /* N(6,480): exclam*/ 204, /* N(12,480): propersubset*/ 232, /* N(11,484): parenleftbt*/ +166, /* N(6,486): florin*/ 34, /* N(9,486): universal*/ 181, /* N(12,492): proportional*/ 231, /* N(11,495): parenleftex*/ 230, /* N(11,506): parenlefttp*/ -108, /* N(6,516): lambda*/ 182, /* N(11,517): partialdiff*/ -162, /* N(6,540): minute*/ +108, /* N(6,522): lambda*/ +162, /* N(6,546): minute*/ 205, /* N(12,552): reflexsubset*/ 226, /* N(12,564): registersans*/ -118, /* N(6,582): omega1*/ -46, /* N(6,600): period*/ +118, /* N(6,588): omega1*/ +46, /* N(6,606): period*/ 195, /* N(11,627): weierstrass*/ -178, /* N(6,636): second*/ -86, /* N(6,642): sigma1*/ -74, /* N(6,654): theta1*/ +178, /* N(6,642): second*/ +86, /* N(6,648): sigma1*/ +74, /* N(6,660): theta1*/ 0}; /* DingbatsEncoding */ @@ -2203,23 +2215,23 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(5,165), /*space*/ +N(5,180), /*space*/ N(2,14), /*a1*/ N(2,16), /*a2*/ -N(4,408), /*a202*/ +N(4,416), /*a202*/ N(2,18), /*a3*/ N(2,20), /*a4*/ N(2,22), /*a5*/ -N(4,76), /*a119*/ -N(4,72), /*a118*/ -N(4,68), /*a117*/ +N(4,84), /*a119*/ +N(4,80), /*a118*/ +N(4,76), /*a117*/ N(3,27), /*a11*/ N(3,30), /*a12*/ N(3,33), /*a13*/ N(3,36), /*a14*/ N(3,39), /*a15*/ N(3,42), /*a16*/ -N(4,36), /*a105*/ +N(4,44), /*a105*/ N(3,45), /*a17*/ N(3,48), /*a18*/ N(3,51), /*a19*/ @@ -2283,9 +2295,9 @@ N(3,207), /*a71*/ N(3,210), /*a72*/ N(3,213), /*a73*/ N(3,216), /*a74*/ -N(4,412), /*a203*/ +N(4,420), /*a203*/ N(3,219), /*a75*/ -N(4,416), /*a204*/ +N(4,424), /*a204*/ N(3,222), /*a76*/ N(3,225), /*a77*/ N(3,228), /*a78*/ @@ -2297,7 +2309,7 @@ N(3,243), /*a84*/ N(3,246), /*a97*/ N(3,249), /*a98*/ N(3,252), /*a99*/ -N(4,16), /*a100*/ +N(4,24), /*a100*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ @@ -2332,291 +2344,291 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(4,20), /*a101*/ -N(4,24), /*a102*/ -N(4,28), /*a103*/ -N(4,32), /*a104*/ -N(4,40), /*a106*/ -N(4,44), /*a107*/ -N(4,48), /*a108*/ -N(4,64), /*a112*/ -N(4,60), /*a111*/ -N(4,56), /*a110*/ -N(4,52), /*a109*/ -N(4,80), /*a120*/ -N(4,84), /*a121*/ -N(4,88), /*a122*/ -N(4,92), /*a123*/ -N(4,96), /*a124*/ -N(4,100), /*a125*/ -N(4,104), /*a126*/ -N(4,108), /*a127*/ -N(4,112), /*a128*/ -N(4,116), /*a129*/ -N(4,120), /*a130*/ -N(4,124), /*a131*/ -N(4,128), /*a132*/ -N(4,132), /*a133*/ -N(4,136), /*a134*/ -N(4,140), /*a135*/ -N(4,144), /*a136*/ -N(4,148), /*a137*/ -N(4,152), /*a138*/ -N(4,156), /*a139*/ -N(4,160), /*a140*/ -N(4,164), /*a141*/ -N(4,168), /*a142*/ -N(4,172), /*a143*/ -N(4,176), /*a144*/ -N(4,180), /*a145*/ -N(4,184), /*a146*/ -N(4,188), /*a147*/ -N(4,192), /*a148*/ -N(4,196), /*a149*/ -N(4,200), /*a150*/ -N(4,204), /*a151*/ -N(4,208), /*a152*/ -N(4,212), /*a153*/ -N(4,216), /*a154*/ -N(4,220), /*a155*/ -N(4,224), /*a156*/ -N(4,228), /*a157*/ -N(4,232), /*a158*/ -N(4,236), /*a159*/ -N(4,240), /*a160*/ -N(4,244), /*a161*/ -N(4,252), /*a163*/ -N(4,256), /*a164*/ -N(4,384), /*a196*/ -N(4,260), /*a165*/ -N(4,368), /*a192*/ -N(4,264), /*a166*/ -N(4,268), /*a167*/ -N(4,272), /*a168*/ -N(4,276), /*a169*/ -N(4,280), /*a170*/ -N(4,284), /*a171*/ -N(4,288), /*a172*/ -N(4,292), /*a173*/ -N(4,248), /*a162*/ -N(4,296), /*a174*/ -N(4,300), /*a175*/ -N(4,304), /*a176*/ -N(4,308), /*a177*/ -N(4,312), /*a178*/ -N(4,316), /*a179*/ -N(4,372), /*a193*/ -N(4,320), /*a180*/ -N(4,396), /*a199*/ -N(4,324), /*a181*/ -N(4,400), /*a200*/ -N(4,328), /*a182*/ -N(7,0), /*.notdef*/ -N(4,404), /*a201*/ -N(4,332), /*a183*/ -N(4,336), /*a184*/ -N(4,388), /*a197*/ -N(4,340), /*a185*/ -N(4,376), /*a194*/ -N(4,392), /*a198*/ -N(4,344), /*a186*/ -N(4,380), /*a195*/ -N(4,348), /*a187*/ -N(4,352), /*a188*/ -N(4,356), /*a189*/ -N(4,360), /*a190*/ -N(4,364), /*a191*/ +N(4,28), /*a101*/ +N(4,32), /*a102*/ +N(4,36), /*a103*/ +N(4,40), /*a104*/ +N(4,48), /*a106*/ +N(4,52), /*a107*/ +N(4,56), /*a108*/ +N(4,72), /*a112*/ +N(4,68), /*a111*/ +N(4,64), /*a110*/ +N(4,60), /*a109*/ +N(4,88), /*a120*/ +N(4,92), /*a121*/ +N(4,96), /*a122*/ +N(4,100), /*a123*/ +N(4,104), /*a124*/ +N(4,108), /*a125*/ +N(4,112), /*a126*/ +N(4,116), /*a127*/ +N(4,120), /*a128*/ +N(4,124), /*a129*/ +N(4,128), /*a130*/ +N(4,132), /*a131*/ +N(4,136), /*a132*/ +N(4,140), /*a133*/ +N(4,144), /*a134*/ +N(4,148), /*a135*/ +N(4,152), /*a136*/ +N(4,156), /*a137*/ +N(4,160), /*a138*/ +N(4,164), /*a139*/ +N(4,168), /*a140*/ +N(4,172), /*a141*/ +N(4,176), /*a142*/ +N(4,180), /*a143*/ +N(4,184), /*a144*/ +N(4,188), /*a145*/ +N(4,192), /*a146*/ +N(4,196), /*a147*/ +N(4,200), /*a148*/ +N(4,204), /*a149*/ +N(4,208), /*a150*/ +N(4,212), /*a151*/ +N(4,216), /*a152*/ +N(4,220), /*a153*/ +N(4,224), /*a154*/ +N(4,228), /*a155*/ +N(4,232), /*a156*/ +N(4,236), /*a157*/ +N(4,240), /*a158*/ +N(4,244), /*a159*/ +N(4,248), /*a160*/ +N(4,252), /*a161*/ +N(4,260), /*a163*/ +N(4,264), /*a164*/ +N(4,392), /*a196*/ +N(4,268), /*a165*/ +N(4,376), /*a192*/ +N(4,272), /*a166*/ +N(4,276), /*a167*/ +N(4,280), /*a168*/ +N(4,284), /*a169*/ +N(4,288), /*a170*/ +N(4,292), /*a171*/ +N(4,296), /*a172*/ +N(4,300), /*a173*/ +N(4,256), /*a162*/ +N(4,304), /*a174*/ +N(4,308), /*a175*/ +N(4,312), /*a176*/ +N(4,316), /*a177*/ +N(4,320), /*a178*/ +N(4,324), /*a179*/ +N(4,380), /*a193*/ +N(4,328), /*a180*/ +N(4,404), /*a199*/ +N(4,332), /*a181*/ +N(4,408), /*a200*/ +N(4,336), /*a182*/ +N(7,0), /*.notdef*/ +N(4,412), /*a201*/ +N(4,340), /*a183*/ +N(4,344), /*a184*/ +N(4,396), /*a197*/ +N(4,348), /*a185*/ +N(4,384), /*a194*/ +N(4,400), /*a198*/ +N(4,352), /*a186*/ +N(4,388), /*a195*/ +N(4,356), /*a187*/ +N(4,360), /*a188*/ +N(4,364), /*a189*/ +N(4,368), /*a190*/ +N(4,372), /*a191*/ N(7,0), /*.notdef*/ 0}; static const ushort gs_c_known_encoding_reverse_3[] = { 33, /* N(2,14): a1*/ 34, /* N(2,16): a2*/ -126, /* N(4,16): a100*/ 36, /* N(2,18): a3*/ 37, /* N(2,20): a4*/ -161, /* N(4,20): a101*/ 38, /* N(2,22): a5*/ 61, /* N(2,24): a6*/ 65, /* N(3,24): a10*/ -162, /* N(4,24): a102*/ +126, /* N(4,24): a100*/ 62, /* N(2,26): a7*/ 42, /* N(3,27): a11*/ 63, /* N(2,28): a8*/ -163, /* N(4,28): a103*/ +161, /* N(4,28): a101*/ 64, /* N(2,30): a9*/ 43, /* N(3,30): a12*/ -164, /* N(4,32): a104*/ +162, /* N(4,32): a102*/ 44, /* N(3,33): a13*/ 45, /* N(3,36): a14*/ -48, /* N(4,36): a105*/ +163, /* N(4,36): a103*/ 46, /* N(3,39): a15*/ -165, /* N(4,40): a106*/ +164, /* N(4,40): a104*/ 47, /* N(3,42): a16*/ -166, /* N(4,44): a107*/ +48, /* N(4,44): a105*/ 49, /* N(3,45): a17*/ 50, /* N(3,48): a18*/ -167, /* N(4,48): a108*/ +165, /* N(4,48): a106*/ 51, /* N(3,51): a19*/ -171, /* N(4,52): a109*/ +166, /* N(4,52): a107*/ 52, /* N(3,54): a20*/ -170, /* N(4,56): a110*/ +167, /* N(4,56): a108*/ 53, /* N(3,57): a21*/ 54, /* N(3,60): a22*/ -169, /* N(4,60): a111*/ +171, /* N(4,60): a109*/ 55, /* N(3,63): a23*/ -168, /* N(4,64): a112*/ +170, /* N(4,64): a110*/ 56, /* N(3,66): a24*/ -41, /* N(4,68): a117*/ +169, /* N(4,68): a111*/ 57, /* N(3,69): a25*/ 58, /* N(3,72): a26*/ -40, /* N(4,72): a118*/ +168, /* N(4,72): a112*/ 59, /* N(3,75): a27*/ -39, /* N(4,76): a119*/ +41, /* N(4,76): a117*/ 60, /* N(3,78): a28*/ -172, /* N(4,80): a120*/ +40, /* N(4,80): a118*/ 66, /* N(3,81): a29*/ 67, /* N(3,84): a30*/ -173, /* N(4,84): a121*/ +39, /* N(4,84): a119*/ 68, /* N(3,87): a31*/ -174, /* N(4,88): a122*/ +172, /* N(4,88): a120*/ 69, /* N(3,90): a32*/ -175, /* N(4,92): a123*/ +173, /* N(4,92): a121*/ 70, /* N(3,93): a33*/ 71, /* N(3,96): a34*/ -176, /* N(4,96): a124*/ +174, /* N(4,96): a122*/ 72, /* N(3,99): a35*/ -177, /* N(4,100): a125*/ +175, /* N(4,100): a123*/ 73, /* N(3,102): a36*/ -178, /* N(4,104): a126*/ +176, /* N(4,104): a124*/ 74, /* N(3,105): a37*/ 75, /* N(3,108): a38*/ -179, /* N(4,108): a127*/ +177, /* N(4,108): a125*/ 76, /* N(3,111): a39*/ -180, /* N(4,112): a128*/ +178, /* N(4,112): a126*/ 77, /* N(3,114): a40*/ -181, /* N(4,116): a129*/ +179, /* N(4,116): a127*/ 78, /* N(3,117): a41*/ 79, /* N(3,120): a42*/ -182, /* N(4,120): a130*/ +180, /* N(4,120): a128*/ 80, /* N(3,123): a43*/ -183, /* N(4,124): a131*/ +181, /* N(4,124): a129*/ 81, /* N(3,126): a44*/ -184, /* N(4,128): a132*/ +182, /* N(4,128): a130*/ 82, /* N(3,129): a45*/ 83, /* N(3,132): a46*/ -185, /* N(4,132): a133*/ +183, /* N(4,132): a131*/ 84, /* N(3,135): a47*/ -186, /* N(4,136): a134*/ +184, /* N(4,136): a132*/ 85, /* N(3,138): a48*/ -187, /* N(4,140): a135*/ +185, /* N(4,140): a133*/ 86, /* N(3,141): a49*/ 87, /* N(3,144): a50*/ -188, /* N(4,144): a136*/ +186, /* N(4,144): a134*/ 88, /* N(3,147): a51*/ -189, /* N(4,148): a137*/ +187, /* N(4,148): a135*/ 89, /* N(3,150): a52*/ -190, /* N(4,152): a138*/ +188, /* N(4,152): a136*/ 90, /* N(3,153): a53*/ 91, /* N(3,156): a54*/ -191, /* N(4,156): a139*/ +189, /* N(4,156): a137*/ 92, /* N(3,159): a55*/ -192, /* N(4,160): a140*/ +190, /* N(4,160): a138*/ 93, /* N(3,162): a56*/ -193, /* N(4,164): a141*/ +191, /* N(4,164): a139*/ 94, /* N(3,165): a57*/ -32, /* N(5,165): space*/ 95, /* N(3,168): a58*/ -194, /* N(4,168): a142*/ +192, /* N(4,168): a140*/ 96, /* N(3,171): a59*/ -195, /* N(4,172): a143*/ +193, /* N(4,172): a141*/ 97, /* N(3,174): a60*/ -196, /* N(4,176): a144*/ +194, /* N(4,176): a142*/ 98, /* N(3,177): a61*/ 99, /* N(3,180): a62*/ -197, /* N(4,180): a145*/ +195, /* N(4,180): a143*/ +32, /* N(5,180): space*/ 100, /* N(3,183): a63*/ -198, /* N(4,184): a146*/ +196, /* N(4,184): a144*/ 101, /* N(3,186): a64*/ -199, /* N(4,188): a147*/ +197, /* N(4,188): a145*/ 102, /* N(3,189): a65*/ 103, /* N(3,192): a66*/ -200, /* N(4,192): a148*/ +198, /* N(4,192): a146*/ 104, /* N(3,195): a67*/ -201, /* N(4,196): a149*/ +199, /* N(4,196): a147*/ 105, /* N(3,198): a68*/ -202, /* N(4,200): a150*/ +200, /* N(4,200): a148*/ 106, /* N(3,201): a69*/ 107, /* N(3,204): a70*/ -203, /* N(4,204): a151*/ +201, /* N(4,204): a149*/ 108, /* N(3,207): a71*/ -204, /* N(4,208): a152*/ +202, /* N(4,208): a150*/ 109, /* N(3,210): a72*/ -205, /* N(4,212): a153*/ +203, /* N(4,212): a151*/ 110, /* N(3,213): a73*/ 111, /* N(3,216): a74*/ -206, /* N(4,216): a154*/ +204, /* N(4,216): a152*/ 113, /* N(3,219): a75*/ -207, /* N(4,220): a155*/ +205, /* N(4,220): a153*/ 115, /* N(3,222): a76*/ -208, /* N(4,224): a156*/ +206, /* N(4,224): a154*/ 116, /* N(3,225): a77*/ 117, /* N(3,228): a78*/ -209, /* N(4,228): a157*/ +207, /* N(4,228): a155*/ 118, /* N(3,231): a79*/ -210, /* N(4,232): a158*/ +208, /* N(4,232): a156*/ 119, /* N(3,234): a81*/ -211, /* N(4,236): a159*/ +209, /* N(4,236): a157*/ 120, /* N(3,237): a82*/ 121, /* N(3,240): a83*/ -212, /* N(4,240): a160*/ +210, /* N(4,240): a158*/ 122, /* N(3,243): a84*/ -213, /* N(4,244): a161*/ +211, /* N(4,244): a159*/ 123, /* N(3,246): a97*/ -227, /* N(4,248): a162*/ +212, /* N(4,248): a160*/ 124, /* N(3,249): a98*/ 125, /* N(3,252): a99*/ -214, /* N(4,252): a163*/ -215, /* N(4,256): a164*/ -217, /* N(4,260): a165*/ -219, /* N(4,264): a166*/ -220, /* N(4,268): a167*/ -221, /* N(4,272): a168*/ -222, /* N(4,276): a169*/ -223, /* N(4,280): a170*/ -224, /* N(4,284): a171*/ -225, /* N(4,288): a172*/ -226, /* N(4,292): a173*/ -228, /* N(4,296): a174*/ -229, /* N(4,300): a175*/ -230, /* N(4,304): a176*/ -231, /* N(4,308): a177*/ -232, /* N(4,312): a178*/ -233, /* N(4,316): a179*/ -235, /* N(4,320): a180*/ -237, /* N(4,324): a181*/ -239, /* N(4,328): a182*/ -242, /* N(4,332): a183*/ -243, /* N(4,336): a184*/ -245, /* N(4,340): a185*/ -248, /* N(4,344): a186*/ -250, /* N(4,348): a187*/ -251, /* N(4,352): a188*/ -252, /* N(4,356): a189*/ -253, /* N(4,360): a190*/ -254, /* N(4,364): a191*/ -218, /* N(4,368): a192*/ -234, /* N(4,372): a193*/ -246, /* N(4,376): a194*/ -249, /* N(4,380): a195*/ -216, /* N(4,384): a196*/ -244, /* N(4,388): a197*/ -247, /* N(4,392): a198*/ -236, /* N(4,396): a199*/ -238, /* N(4,400): a200*/ -241, /* N(4,404): a201*/ -35, /* N(4,408): a202*/ -112, /* N(4,412): a203*/ -114, /* N(4,416): a204*/ +213, /* N(4,252): a161*/ +227, /* N(4,256): a162*/ +214, /* N(4,260): a163*/ +215, /* N(4,264): a164*/ +217, /* N(4,268): a165*/ +219, /* N(4,272): a166*/ +220, /* N(4,276): a167*/ +221, /* N(4,280): a168*/ +222, /* N(4,284): a169*/ +223, /* N(4,288): a170*/ +224, /* N(4,292): a171*/ +225, /* N(4,296): a172*/ +226, /* N(4,300): a173*/ +228, /* N(4,304): a174*/ +229, /* N(4,308): a175*/ +230, /* N(4,312): a176*/ +231, /* N(4,316): a177*/ +232, /* N(4,320): a178*/ +233, /* N(4,324): a179*/ +235, /* N(4,328): a180*/ +237, /* N(4,332): a181*/ +239, /* N(4,336): a182*/ +242, /* N(4,340): a183*/ +243, /* N(4,344): a184*/ +245, /* N(4,348): a185*/ +248, /* N(4,352): a186*/ +250, /* N(4,356): a187*/ +251, /* N(4,360): a188*/ +252, /* N(4,364): a189*/ +253, /* N(4,368): a190*/ +254, /* N(4,372): a191*/ +218, /* N(4,376): a192*/ +234, /* N(4,380): a193*/ +246, /* N(4,384): a194*/ +249, /* N(4,388): a195*/ +216, /* N(4,392): a196*/ +244, /* N(4,396): a197*/ +247, /* N(4,400): a198*/ +236, /* N(4,404): a199*/ +238, /* N(4,408): a200*/ +241, /* N(4,412): a201*/ +35, /* N(4,416): a202*/ +112, /* N(4,420): a203*/ +114, /* N(4,424): a204*/ 0}; /* WinAnsiEncoding */ @@ -2653,38 +2665,38 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(5,165), /*space*/ -N(6,474), /*exclam*/ -N(8,168), /*quotedbl*/ +N(5,180), /*space*/ +N(6,480), /*exclam*/ +N(8,176), /*quotedbl*/ N(10,270), /*numbersign*/ -N(6,438), /*dollar*/ -N(7,245), /*percent*/ +N(6,444), /*dollar*/ +N(7,280), /*percent*/ N(9,72), /*ampersand*/ N(11,539), /*quotesingle*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ -N(8,48), /*asterisk*/ -N(4,456), /*plus*/ -N(5,95), /*comma*/ -N(6,492), /*hyphen*/ -N(6,600), /*period*/ -N(5,160), /*slash*/ -N(4,464), /*zero*/ +N(8,56), /*asterisk*/ +N(4,464), /*plus*/ +N(5,110), /*comma*/ +N(6,498), /*hyphen*/ +N(6,606), /*period*/ +N(5,175), /*slash*/ +N(4,472), /*zero*/ N(3,276), /*one*/ N(3,294), /*two*/ -N(5,185), /*three*/ -N(4,436), /*four*/ -N(4,432), /*five*/ +N(5,200), /*three*/ +N(4,444), /*four*/ +N(4,440), /*five*/ N(3,288), /*six*/ -N(5,150), /*seven*/ -N(5,105), /*eight*/ -N(4,448), /*nine*/ -N(5,90), /*colon*/ +N(5,165), /*seven*/ +N(5,120), /*eight*/ +N(4,456), /*nine*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ -N(4,444), /*less*/ -N(5,110), /*equal*/ -N(7,189), /*greater*/ -N(8,160), /*question*/ +N(4,452), /*less*/ +N(5,125), /*equal*/ +N(7,224), /*greater*/ +N(8,168), /*question*/ N(2,34), /*at*/ N(1,0), /*A*/ N(1,1), /*B*/ @@ -2717,7 +2729,7 @@ N(9,135), /*backslash*/ N(12,192), /*bracketright*/ N(11,308), /*asciicircum*/ N(10,320), /*underscore*/ -N(5,125), /*grave*/ +N(5,140), /*grave*/ N(1,26), /*a*/ N(1,27), /*b*/ N(1,28), /*c*/ @@ -2748,69 +2760,69 @@ N(9,144), /*braceleft*/ N(3,255), /*bar*/ N(10,140), /*braceright*/ N(10,130), /*asciitilde*/ -N(6,390), /*bullet*/ -N(4,4), /*Euro*/ -N(6,390), /*bullet*/ +N(6,396), /*bullet*/ +N(4,12), /*Euro*/ +N(6,396), /*bullet*/ N(14,364), /*quotesinglbase*/ -N(6,480), /*florin*/ +N(6,486), /*florin*/ N(12,516), /*quotedblbase*/ -N(8,88), /*ellipsis*/ -N(6,408), /*dagger*/ +N(8,96), /*ellipsis*/ +N(6,414), /*dagger*/ N(9,189), /*daggerdbl*/ N(10,160), /*circumflex*/ N(11,528), /*perthousand*/ -N(6,276), /*Scaron*/ +N(6,282), /*Scaron*/ N(13,221), /*guilsinglleft*/ N(2,8), /*OE*/ -N(6,390), /*bullet*/ -N(6,354), /*Zcaron*/ -N(6,390), /*bullet*/ -N(6,390), /*bullet*/ +N(6,396), /*bullet*/ +N(6,360), /*Zcaron*/ +N(6,396), /*bullet*/ +N(6,396), /*bullet*/ N(9,387), /*quoteleft*/ N(10,300), /*quoteright*/ N(12,528), /*quotedblleft*/ N(13,273), /*quotedblright*/ -N(6,390), /*bullet*/ -N(6,468), /*endash*/ -N(6,462), /*emdash*/ -N(5,190), /*tilde*/ +N(6,396), /*bullet*/ +N(6,474), /*endash*/ +N(6,468), /*emdash*/ +N(5,205), /*tilde*/ N(9,450), /*trademark*/ -N(6,630), /*scaron*/ +N(6,636), /*scaron*/ N(14,252), /*guilsinglright*/ N(2,46), /*oe*/ -N(6,390), /*bullet*/ -N(6,684), /*zcaron*/ +N(6,396), /*bullet*/ +N(6,690), /*zcaron*/ N(9,54), /*Ydieresis*/ -N(5,165), /*space*/ +N(5,180), /*space*/ N(10,180), /*exclamdown*/ -N(4,424), /*cent*/ -N(8,184), /*sterling*/ -N(8,64), /*currency*/ +N(4,432), /*cent*/ +N(8,192), /*sterling*/ +N(8,72), /*currency*/ N(3,297), /*yen*/ N(9,153), /*brokenbar*/ -N(7,266), /*section*/ -N(8,72), /*dieresis*/ +N(7,301), /*section*/ +N(8,80), /*dieresis*/ N(9,180), /*copyright*/ N(11,473), /*ordfeminine*/ N(13,208), /*guillemotleft*/ N(10,250), /*logicalnot*/ -N(6,492), /*hyphen*/ +N(6,498), /*hyphen*/ N(10,310), /*registered*/ -N(6,534), /*macron*/ -N(6,426), /*degree*/ +N(6,540), /*macron*/ +N(6,432), /*degree*/ N(9,378), /*plusminus*/ N(11,605), /*twosuperior*/ N(13,377), /*threesuperior*/ -N(5,55), /*acute*/ +N(5,70), /*acute*/ N(2,42), /*mu*/ N(9,360), /*paragraph*/ N(14,308), /*periodcentered*/ -N(7,133), /*cedilla*/ +N(7,168), /*cedilla*/ N(11,462), /*onesuperior*/ N(12,432), /*ordmasculine*/ N(14,238), /*guillemotright*/ N(10,280), /*onequarter*/ -N(7,238), /*onehalf*/ +N(7,273), /*onehalf*/ N(13,364), /*threequarters*/ N(12,504), /*questiondown*/ N(6,12), /*Agrave*/ @@ -2830,52 +2842,52 @@ N(6,120), /*Iacute*/ N(11,88), /*Icircumflex*/ N(9,18), /*Idieresis*/ N(3,6), /*Eth*/ -N(6,204), /*Ntilde*/ -N(6,216), /*Ograve*/ -N(6,210), /*Oacute*/ +N(6,210), /*Ntilde*/ +N(6,222), /*Ograve*/ +N(6,216), /*Oacute*/ N(11,154), /*Ocircumflex*/ -N(6,234), /*Otilde*/ +N(6,240), /*Otilde*/ N(9,27), /*Odieresis*/ -N(8,136), /*multiply*/ -N(6,222), /*Oslash*/ -N(6,306), /*Ugrave*/ -N(6,300), /*Uacute*/ +N(8,144), /*multiply*/ +N(6,228), /*Oslash*/ +N(6,312), /*Ugrave*/ +N(6,306), /*Uacute*/ N(11,231), /*Ucircumflex*/ N(9,45), /*Udieresis*/ -N(6,336), /*Yacute*/ -N(5,45), /*Thorn*/ +N(6,342), /*Yacute*/ +N(5,60), /*Thorn*/ N(10,200), /*germandbls*/ -N(6,378), /*agrave*/ -N(6,366), /*aacute*/ +N(6,384), /*agrave*/ +N(6,372), /*aacute*/ N(11,275), /*acircumflex*/ -N(6,384), /*atilde*/ +N(6,390), /*atilde*/ N(9,63), /*adieresis*/ -N(5,75), /*aring*/ +N(5,90), /*aring*/ N(2,32), /*ae*/ -N(8,56), /*ccedilla*/ -N(6,456), /*egrave*/ -N(6,444), /*eacute*/ +N(8,64), /*ccedilla*/ +N(6,462), /*egrave*/ +N(6,450), /*eacute*/ N(11,363), /*ecircumflex*/ N(9,216), /*edieresis*/ -N(6,504), /*igrave*/ -N(6,498), /*iacute*/ +N(6,510), /*igrave*/ +N(6,504), /*iacute*/ N(11,418), /*icircumflex*/ N(9,234), /*idieresis*/ N(3,264), /*eth*/ -N(6,558), /*ntilde*/ -N(6,576), /*ograve*/ -N(6,564), /*oacute*/ +N(6,564), /*ntilde*/ +N(6,582), /*ograve*/ +N(6,570), /*oacute*/ N(11,429), /*ocircumflex*/ -N(6,594), /*otilde*/ +N(6,600), /*otilde*/ N(9,315), /*odieresis*/ -N(6,432), /*divide*/ -N(6,588), /*oslash*/ -N(6,666), /*ugrave*/ -N(6,660), /*uacute*/ +N(6,438), /*divide*/ +N(6,594), /*oslash*/ +N(6,672), /*ugrave*/ +N(6,666), /*uacute*/ N(11,616), /*ucircumflex*/ N(9,477), /*udieresis*/ -N(6,672), /*yacute*/ -N(5,180), /*thorn*/ +N(6,678), /*yacute*/ +N(5,195), /*thorn*/ N(9,495), /*ydieresis*/ 0}; static const ushort gs_c_known_encoding_reverse_4[] = { @@ -2888,7 +2900,6 @@ static const ushort gs_c_known_encoding_reverse_4[] = { 67, /* N(1,2): C*/ 68, /* N(1,3): D*/ 69, /* N(1,4): E*/ -128, /* N(4,4): Euro*/ 70, /* N(1,5): F*/ 71, /* N(1,6): G*/ 208, /* N(3,6): Eth*/ @@ -2902,6 +2913,7 @@ static const ushort gs_c_known_encoding_reverse_4[] = { 76, /* N(1,11): L*/ 194, /* N(11,11): Acircumflex*/ 77, /* N(1,12): M*/ +128, /* N(4,12): Euro*/ 192, /* N(6,12): Agrave*/ 78, /* N(1,13): N*/ 79, /* N(1,14): O*/ @@ -2942,167 +2954,167 @@ static const ushort gs_c_known_encoding_reverse_4[] = { 114, /* N(1,43): r*/ 115, /* N(1,44): s*/ 116, /* N(1,45): t*/ -222, /* N(5,45): Thorn*/ 220, /* N(9,45): Udieresis*/ 117, /* N(1,46): u*/ 156, /* N(2,46): oe*/ 118, /* N(1,47): v*/ 119, /* N(1,48): w*/ -42, /* N(8,48): asterisk*/ 120, /* N(1,49): x*/ 121, /* N(1,50): y*/ 122, /* N(1,51): z*/ 159, /* N(9,54): Ydieresis*/ -180, /* N(5,55): acute*/ 202, /* N(11,55): Ecircumflex*/ -231, /* N(8,56): ccedilla*/ +42, /* N(8,56): asterisk*/ +222, /* N(5,60): Thorn*/ 228, /* N(9,63): adieresis*/ -164, /* N(8,64): currency*/ +231, /* N(8,64): ccedilla*/ +180, /* N(5,70): acute*/ 201, /* N(6,72): Eacute*/ -168, /* N(8,72): dieresis*/ +164, /* N(8,72): currency*/ 38, /* N(9,72): ampersand*/ -229, /* N(5,75): aring*/ +168, /* N(8,80): dieresis*/ 200, /* N(6,84): Egrave*/ -133, /* N(8,88): ellipsis*/ 206, /* N(11,88): Icircumflex*/ -58, /* N(5,90): colon*/ -44, /* N(5,95): comma*/ -56, /* N(5,105): eight*/ -61, /* N(5,110): equal*/ +229, /* N(5,90): aring*/ +133, /* N(8,96): ellipsis*/ +58, /* N(5,105): colon*/ +44, /* N(5,110): comma*/ +56, /* N(5,120): eight*/ 205, /* N(6,120): Iacute*/ -96, /* N(5,125): grave*/ +61, /* N(5,125): equal*/ 204, /* N(6,126): Igrave*/ 126, /* N(10,130): asciitilde*/ -184, /* N(7,133): cedilla*/ 92, /* N(9,135): backslash*/ -215, /* N(8,136): multiply*/ +96, /* N(5,140): grave*/ 125, /* N(10,140): braceright*/ +215, /* N(8,144): multiply*/ 123, /* N(9,144): braceleft*/ -55, /* N(5,150): seven*/ 166, /* N(9,153): brokenbar*/ 212, /* N(11,154): Ocircumflex*/ -47, /* N(5,160): slash*/ -63, /* N(8,160): question*/ 136, /* N(10,160): circumflex*/ -160, /* N(5,165): space*/ -32, /* N(5,165): space*/ -34, /* N(8,168): quotedbl*/ -254, /* N(5,180): thorn*/ +55, /* N(5,165): seven*/ +184, /* N(7,168): cedilla*/ +63, /* N(8,168): question*/ +47, /* N(5,175): slash*/ +34, /* N(8,176): quotedbl*/ +32, /* N(5,180): space*/ +160, /* N(5,180): space*/ 169, /* N(9,180): copyright*/ 161, /* N(10,180): exclamdown*/ -163, /* N(8,184): sterling*/ -51, /* N(5,185): three*/ -62, /* N(7,189): greater*/ 135, /* N(9,189): daggerdbl*/ -152, /* N(5,190): tilde*/ +163, /* N(8,192): sterling*/ 93, /* N(12,192): bracketright*/ +254, /* N(5,195): thorn*/ +51, /* N(5,200): three*/ 223, /* N(10,200): germandbls*/ -209, /* N(6,204): Ntilde*/ +152, /* N(5,205): tilde*/ 171, /* N(13,208): guillemotleft*/ -211, /* N(6,210): Oacute*/ -210, /* N(6,216): Ograve*/ +209, /* N(6,210): Ntilde*/ +211, /* N(6,216): Oacute*/ 235, /* N(9,216): edieresis*/ 139, /* N(13,221): guilsinglleft*/ -216, /* N(6,222): Oslash*/ +210, /* N(6,222): Ograve*/ +62, /* N(7,224): greater*/ +216, /* N(6,228): Oslash*/ 219, /* N(11,231): Ucircumflex*/ -213, /* N(6,234): Otilde*/ 239, /* N(9,234): idieresis*/ -189, /* N(7,238): onehalf*/ 187, /* N(14,238): guillemotright*/ -37, /* N(7,245): percent*/ +213, /* N(6,240): Otilde*/ 172, /* N(10,250): logicalnot*/ 155, /* N(14,252): guilsinglright*/ 124, /* N(3,255): bar*/ 240, /* N(3,264): eth*/ -167, /* N(7,266): section*/ 35, /* N(10,270): numbersign*/ +189, /* N(7,273): onehalf*/ 148, /* N(13,273): quotedblright*/ 226, /* N(11,275): acircumflex*/ 49, /* N(3,276): one*/ -138, /* N(6,276): Scaron*/ +37, /* N(7,280): percent*/ 188, /* N(10,280): onequarter*/ +138, /* N(6,282): Scaron*/ 54, /* N(3,288): six*/ 41, /* N(10,290): parenright*/ 50, /* N(3,294): two*/ 165, /* N(3,297): yen*/ -218, /* N(6,300): Uacute*/ 146, /* N(10,300): quoteright*/ -217, /* N(6,306): Ugrave*/ +167, /* N(7,301): section*/ +218, /* N(6,306): Uacute*/ 94, /* N(11,308): asciicircum*/ 183, /* N(14,308): periodcentered*/ 174, /* N(10,310): registered*/ +217, /* N(6,312): Ugrave*/ 246, /* N(9,315): odieresis*/ 95, /* N(10,320): underscore*/ -221, /* N(6,336): Yacute*/ 91, /* N(11,341): bracketleft*/ -142, /* N(6,354): Zcaron*/ +221, /* N(6,342): Yacute*/ +142, /* N(6,360): Zcaron*/ 182, /* N(9,360): paragraph*/ 234, /* N(11,363): ecircumflex*/ 190, /* N(13,364): threequarters*/ 130, /* N(14,364): quotesinglbase*/ -225, /* N(6,366): aacute*/ 40, /* N(9,369): parenleft*/ +225, /* N(6,372): aacute*/ 179, /* N(13,377): threesuperior*/ -224, /* N(6,378): agrave*/ 177, /* N(9,378): plusminus*/ -227, /* N(6,384): atilde*/ +224, /* N(6,384): agrave*/ 145, /* N(9,387): quoteleft*/ -157, /* N(6,390): bullet*/ -149, /* N(6,390): bullet*/ -144, /* N(6,390): bullet*/ -143, /* N(6,390): bullet*/ -141, /* N(6,390): bullet*/ -129, /* N(6,390): bullet*/ -127, /* N(6,390): bullet*/ -134, /* N(6,408): dagger*/ +227, /* N(6,390): atilde*/ +157, /* N(6,396): bullet*/ +149, /* N(6,396): bullet*/ +144, /* N(6,396): bullet*/ +143, /* N(6,396): bullet*/ +141, /* N(6,396): bullet*/ +129, /* N(6,396): bullet*/ +127, /* N(6,396): bullet*/ +134, /* N(6,414): dagger*/ 59, /* N(9,414): semicolon*/ 238, /* N(11,418): icircumflex*/ -162, /* N(4,424): cent*/ -176, /* N(6,426): degree*/ 244, /* N(11,429): ocircumflex*/ -53, /* N(4,432): five*/ -247, /* N(6,432): divide*/ +162, /* N(4,432): cent*/ +176, /* N(6,432): degree*/ 186, /* N(12,432): ordmasculine*/ -52, /* N(4,436): four*/ -36, /* N(6,438): dollar*/ -60, /* N(4,444): less*/ -233, /* N(6,444): eacute*/ -57, /* N(4,448): nine*/ +247, /* N(6,438): divide*/ +53, /* N(4,440): five*/ +52, /* N(4,444): four*/ +36, /* N(6,444): dollar*/ +233, /* N(6,450): eacute*/ 153, /* N(9,450): trademark*/ -43, /* N(4,456): plus*/ -232, /* N(6,456): egrave*/ -151, /* N(6,462): emdash*/ +60, /* N(4,452): less*/ +57, /* N(4,456): nine*/ +232, /* N(6,462): egrave*/ 185, /* N(11,462): onesuperior*/ -48, /* N(4,464): zero*/ -150, /* N(6,468): endash*/ +43, /* N(4,464): plus*/ +151, /* N(6,468): emdash*/ +48, /* N(4,472): zero*/ 170, /* N(11,473): ordfeminine*/ -33, /* N(6,474): exclam*/ +150, /* N(6,474): endash*/ 252, /* N(9,477): udieresis*/ -131, /* N(6,480): florin*/ -173, /* N(6,492): hyphen*/ -45, /* N(6,492): hyphen*/ +33, /* N(6,480): exclam*/ +131, /* N(6,486): florin*/ 255, /* N(9,495): ydieresis*/ -237, /* N(6,498): iacute*/ -236, /* N(6,504): igrave*/ +45, /* N(6,498): hyphen*/ +173, /* N(6,498): hyphen*/ +237, /* N(6,504): iacute*/ 191, /* N(12,504): questiondown*/ +236, /* N(6,510): igrave*/ 132, /* N(12,516): quotedblbase*/ 137, /* N(11,528): perthousand*/ 147, /* N(12,528): quotedblleft*/ -175, /* N(6,534): macron*/ 39, /* N(11,539): quotesingle*/ -241, /* N(6,558): ntilde*/ -243, /* N(6,564): oacute*/ -242, /* N(6,576): ograve*/ -248, /* N(6,588): oslash*/ -245, /* N(6,594): otilde*/ -46, /* N(6,600): period*/ +175, /* N(6,540): macron*/ +241, /* N(6,564): ntilde*/ +243, /* N(6,570): oacute*/ +242, /* N(6,582): ograve*/ +248, /* N(6,594): oslash*/ +245, /* N(6,600): otilde*/ 178, /* N(11,605): twosuperior*/ +46, /* N(6,606): period*/ 251, /* N(11,616): ucircumflex*/ -154, /* N(6,630): scaron*/ -250, /* N(6,660): uacute*/ -249, /* N(6,666): ugrave*/ -253, /* N(6,672): yacute*/ -158, /* N(6,684): zcaron*/ +154, /* N(6,636): scaron*/ +250, /* N(6,666): uacute*/ +249, /* N(6,672): ugrave*/ +253, /* N(6,678): yacute*/ +158, /* N(6,690): zcaron*/ 0}; /* MacRomanEncoding */ @@ -3139,38 +3151,38 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(5,165), /*space*/ -N(6,474), /*exclam*/ -N(8,168), /*quotedbl*/ +N(5,180), /*space*/ +N(6,480), /*exclam*/ +N(8,176), /*quotedbl*/ N(10,270), /*numbersign*/ -N(6,438), /*dollar*/ -N(7,245), /*percent*/ +N(6,444), /*dollar*/ +N(7,280), /*percent*/ N(9,72), /*ampersand*/ N(11,539), /*quotesingle*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ -N(8,48), /*asterisk*/ -N(4,456), /*plus*/ -N(5,95), /*comma*/ -N(6,492), /*hyphen*/ -N(6,600), /*period*/ -N(5,160), /*slash*/ -N(4,464), /*zero*/ +N(8,56), /*asterisk*/ +N(4,464), /*plus*/ +N(5,110), /*comma*/ +N(6,498), /*hyphen*/ +N(6,606), /*period*/ +N(5,175), /*slash*/ +N(4,472), /*zero*/ N(3,276), /*one*/ N(3,294), /*two*/ -N(5,185), /*three*/ -N(4,436), /*four*/ -N(4,432), /*five*/ +N(5,200), /*three*/ +N(4,444), /*four*/ +N(4,440), /*five*/ N(3,288), /*six*/ -N(5,150), /*seven*/ -N(5,105), /*eight*/ -N(4,448), /*nine*/ -N(5,90), /*colon*/ +N(5,165), /*seven*/ +N(5,120), /*eight*/ +N(4,456), /*nine*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ -N(4,444), /*less*/ -N(5,110), /*equal*/ -N(7,189), /*greater*/ -N(8,160), /*question*/ +N(4,452), /*less*/ +N(5,125), /*equal*/ +N(7,224), /*greater*/ +N(8,168), /*question*/ N(2,34), /*at*/ N(1,0), /*A*/ N(1,1), /*B*/ @@ -3203,7 +3215,7 @@ N(9,135), /*backslash*/ N(12,192), /*bracketright*/ N(11,308), /*asciicircum*/ N(10,320), /*underscore*/ -N(5,125), /*grave*/ +N(5,140), /*grave*/ N(1,26), /*a*/ N(1,27), /*b*/ N(1,28), /*c*/ @@ -3239,50 +3251,50 @@ N(9,0), /*Adieresis*/ N(5,10), /*Aring*/ N(8,0), /*Ccedilla*/ N(6,72), /*Eacute*/ -N(6,204), /*Ntilde*/ +N(6,210), /*Ntilde*/ N(9,27), /*Odieresis*/ N(9,45), /*Udieresis*/ -N(6,366), /*aacute*/ -N(6,378), /*agrave*/ +N(6,372), /*aacute*/ +N(6,384), /*agrave*/ N(11,275), /*acircumflex*/ N(9,63), /*adieresis*/ -N(6,384), /*atilde*/ -N(5,75), /*aring*/ -N(8,56), /*ccedilla*/ -N(6,444), /*eacute*/ -N(6,456), /*egrave*/ +N(6,390), /*atilde*/ +N(5,90), /*aring*/ +N(8,64), /*ccedilla*/ +N(6,450), /*eacute*/ +N(6,462), /*egrave*/ N(11,363), /*ecircumflex*/ N(9,216), /*edieresis*/ -N(6,498), /*iacute*/ -N(6,504), /*igrave*/ +N(6,504), /*iacute*/ +N(6,510), /*igrave*/ N(11,418), /*icircumflex*/ N(9,234), /*idieresis*/ -N(6,558), /*ntilde*/ -N(6,564), /*oacute*/ -N(6,576), /*ograve*/ +N(6,564), /*ntilde*/ +N(6,570), /*oacute*/ +N(6,582), /*ograve*/ N(11,429), /*ocircumflex*/ N(9,315), /*odieresis*/ -N(6,594), /*otilde*/ -N(6,660), /*uacute*/ -N(6,666), /*ugrave*/ +N(6,600), /*otilde*/ +N(6,666), /*uacute*/ +N(6,672), /*ugrave*/ N(11,616), /*ucircumflex*/ N(9,477), /*udieresis*/ -N(6,408), /*dagger*/ -N(6,426), /*degree*/ -N(4,424), /*cent*/ -N(8,184), /*sterling*/ -N(7,266), /*section*/ -N(6,390), /*bullet*/ +N(6,414), /*dagger*/ +N(6,432), /*degree*/ +N(4,432), /*cent*/ +N(8,192), /*sterling*/ +N(7,301), /*section*/ +N(6,396), /*bullet*/ N(9,360), /*paragraph*/ N(10,200), /*germandbls*/ N(10,310), /*registered*/ N(9,180), /*copyright*/ N(9,450), /*trademark*/ -N(5,55), /*acute*/ -N(8,72), /*dieresis*/ +N(5,70), /*acute*/ +N(8,80), /*dieresis*/ N(7,0), /*.notdef*/ N(2,0), /*AE*/ -N(6,222), /*Oslash*/ +N(6,228), /*Oslash*/ N(7,0), /*.notdef*/ N(9,378), /*plusminus*/ N(7,0), /*.notdef*/ @@ -3298,35 +3310,35 @@ N(11,473), /*ordfeminine*/ N(12,432), /*ordmasculine*/ N(7,0), /*.notdef*/ N(2,32), /*ae*/ -N(6,588), /*oslash*/ +N(6,594), /*oslash*/ N(12,504), /*questiondown*/ N(10,180), /*exclamdown*/ N(10,250), /*logicalnot*/ N(7,0), /*.notdef*/ -N(6,480), /*florin*/ +N(6,486), /*florin*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(13,208), /*guillemotleft*/ N(14,238), /*guillemotright*/ -N(8,88), /*ellipsis*/ -N(5,165), /*space*/ +N(8,96), /*ellipsis*/ +N(5,180), /*space*/ N(6,12), /*Agrave*/ N(6,24), /*Atilde*/ -N(6,234), /*Otilde*/ +N(6,240), /*Otilde*/ N(2,8), /*OE*/ N(2,46), /*oe*/ -N(6,468), /*endash*/ -N(6,462), /*emdash*/ +N(6,474), /*endash*/ +N(6,468), /*emdash*/ N(12,528), /*quotedblleft*/ N(13,273), /*quotedblright*/ N(9,387), /*quoteleft*/ N(10,300), /*quoteright*/ -N(6,432), /*divide*/ +N(6,438), /*divide*/ N(7,0), /*.notdef*/ N(9,495), /*ydieresis*/ N(9,54), /*Ydieresis*/ -N(8,104), /*fraction*/ -N(8,64), /*currency*/ +N(8,112), /*fraction*/ +N(8,72), /*currency*/ N(13,221), /*guilsinglleft*/ N(14,252), /*guilsinglright*/ N(2,38), /*fi*/ @@ -3345,24 +3357,24 @@ N(6,120), /*Iacute*/ N(11,88), /*Icircumflex*/ N(9,18), /*Idieresis*/ N(6,126), /*Igrave*/ -N(6,210), /*Oacute*/ +N(6,216), /*Oacute*/ N(11,154), /*Ocircumflex*/ N(7,0), /*.notdef*/ -N(6,216), /*Ograve*/ -N(6,300), /*Uacute*/ +N(6,222), /*Ograve*/ +N(6,306), /*Uacute*/ N(11,231), /*Ucircumflex*/ -N(6,306), /*Ugrave*/ -N(8,80), /*dotlessi*/ +N(6,312), /*Ugrave*/ +N(8,88), /*dotlessi*/ N(10,160), /*circumflex*/ -N(5,190), /*tilde*/ -N(6,534), /*macron*/ -N(5,80), /*breve*/ +N(5,205), /*tilde*/ +N(6,540), /*macron*/ +N(5,95), /*breve*/ N(9,198), /*dotaccent*/ -N(4,460), /*ring*/ -N(7,133), /*cedilla*/ +N(4,468), /*ring*/ +N(7,168), /*cedilla*/ N(12,336), /*hungarumlaut*/ -N(6,570), /*ogonek*/ -N(5,85), /*caron*/ +N(6,576), /*ogonek*/ +N(5,100), /*caron*/ 0}; static const ushort gs_c_known_encoding_reverse_5[] = { 65, /* N(1,0): A*/ @@ -3433,87 +3445,87 @@ static const ushort gs_c_known_encoding_reverse_5[] = { 207, /* N(2,46): oe*/ 118, /* N(1,47): v*/ 119, /* N(1,48): w*/ -42, /* N(8,48): asterisk*/ 120, /* N(1,49): x*/ 121, /* N(1,50): y*/ 122, /* N(1,51): z*/ 217, /* N(9,54): Ydieresis*/ -171, /* N(5,55): acute*/ 230, /* N(11,55): Ecircumflex*/ -141, /* N(8,56): ccedilla*/ +42, /* N(8,56): asterisk*/ 138, /* N(9,63): adieresis*/ -219, /* N(8,64): currency*/ +141, /* N(8,64): ccedilla*/ +171, /* N(5,70): acute*/ 131, /* N(6,72): Eacute*/ -172, /* N(8,72): dieresis*/ +219, /* N(8,72): currency*/ 38, /* N(9,72): ampersand*/ -140, /* N(5,75): aring*/ -249, /* N(5,80): breve*/ -245, /* N(8,80): dotlessi*/ +172, /* N(8,80): dieresis*/ 233, /* N(6,84): Egrave*/ -255, /* N(5,85): caron*/ -201, /* N(8,88): ellipsis*/ +245, /* N(8,88): dotlessi*/ 235, /* N(11,88): Icircumflex*/ -58, /* N(5,90): colon*/ -44, /* N(5,95): comma*/ -218, /* N(8,104): fraction*/ -56, /* N(5,105): eight*/ -61, /* N(5,110): equal*/ +140, /* N(5,90): aring*/ +249, /* N(5,95): breve*/ +201, /* N(8,96): ellipsis*/ +255, /* N(5,100): caron*/ +58, /* N(5,105): colon*/ +44, /* N(5,110): comma*/ +218, /* N(8,112): fraction*/ +56, /* N(5,120): eight*/ 234, /* N(6,120): Iacute*/ -96, /* N(5,125): grave*/ +61, /* N(5,125): equal*/ 237, /* N(6,126): Igrave*/ 126, /* N(10,130): asciitilde*/ -252, /* N(7,133): cedilla*/ 92, /* N(9,135): backslash*/ +96, /* N(5,140): grave*/ 125, /* N(10,140): braceright*/ 123, /* N(9,144): braceleft*/ -55, /* N(5,150): seven*/ 239, /* N(11,154): Ocircumflex*/ -47, /* N(5,160): slash*/ -63, /* N(8,160): question*/ 246, /* N(10,160): circumflex*/ -202, /* N(5,165): space*/ -32, /* N(5,165): space*/ -34, /* N(8,168): quotedbl*/ +55, /* N(5,165): seven*/ +252, /* N(7,168): cedilla*/ +63, /* N(8,168): question*/ +47, /* N(5,175): slash*/ +34, /* N(8,176): quotedbl*/ +32, /* N(5,180): space*/ +202, /* N(5,180): space*/ 169, /* N(9,180): copyright*/ 193, /* N(10,180): exclamdown*/ -163, /* N(8,184): sterling*/ -51, /* N(5,185): three*/ -62, /* N(7,189): greater*/ 224, /* N(9,189): daggerdbl*/ -247, /* N(5,190): tilde*/ +163, /* N(8,192): sterling*/ 93, /* N(12,192): bracketright*/ 250, /* N(9,198): dotaccent*/ +51, /* N(5,200): three*/ 167, /* N(10,200): germandbls*/ -132, /* N(6,204): Ntilde*/ +247, /* N(5,205): tilde*/ 199, /* N(13,208): guillemotleft*/ -238, /* N(6,210): Oacute*/ -241, /* N(6,216): Ograve*/ +132, /* N(6,210): Ntilde*/ +238, /* N(6,216): Oacute*/ 145, /* N(9,216): edieresis*/ 220, /* N(13,221): guilsinglleft*/ -175, /* N(6,222): Oslash*/ +241, /* N(6,222): Ograve*/ +62, /* N(7,224): greater*/ +175, /* N(6,228): Oslash*/ 243, /* N(11,231): Ucircumflex*/ -205, /* N(6,234): Otilde*/ 149, /* N(9,234): idieresis*/ 200, /* N(14,238): guillemotright*/ -37, /* N(7,245): percent*/ +205, /* N(6,240): Otilde*/ 194, /* N(10,250): logicalnot*/ 221, /* N(14,252): guilsinglright*/ 124, /* N(3,255): bar*/ -164, /* N(7,266): section*/ 35, /* N(10,270): numbersign*/ 211, /* N(13,273): quotedblright*/ 137, /* N(11,275): acircumflex*/ 49, /* N(3,276): one*/ +37, /* N(7,280): percent*/ 54, /* N(3,288): six*/ 41, /* N(10,290): parenright*/ 50, /* N(3,294): two*/ 180, /* N(3,297): yen*/ -242, /* N(6,300): Uacute*/ 213, /* N(10,300): quoteright*/ -244, /* N(6,306): Ugrave*/ +164, /* N(7,301): section*/ +242, /* N(6,306): Uacute*/ 94, /* N(11,308): asciicircum*/ 225, /* N(14,308): periodcentered*/ 168, /* N(10,310): registered*/ +244, /* N(6,312): Ugrave*/ 154, /* N(9,315): odieresis*/ 95, /* N(10,320): underscore*/ 253, /* N(12,336): hungarumlaut*/ @@ -3521,58 +3533,58 @@ static const ushort gs_c_known_encoding_reverse_5[] = { 166, /* N(9,360): paragraph*/ 144, /* N(11,363): ecircumflex*/ 226, /* N(14,364): quotesinglbase*/ -135, /* N(6,366): aacute*/ 40, /* N(9,369): parenleft*/ -136, /* N(6,378): agrave*/ +135, /* N(6,372): aacute*/ 177, /* N(9,378): plusminus*/ -139, /* N(6,384): atilde*/ +136, /* N(6,384): agrave*/ 212, /* N(9,387): quoteleft*/ -165, /* N(6,390): bullet*/ -160, /* N(6,408): dagger*/ +139, /* N(6,390): atilde*/ +165, /* N(6,396): bullet*/ +160, /* N(6,414): dagger*/ 59, /* N(9,414): semicolon*/ 148, /* N(11,418): icircumflex*/ -162, /* N(4,424): cent*/ -161, /* N(6,426): degree*/ 153, /* N(11,429): ocircumflex*/ -53, /* N(4,432): five*/ -214, /* N(6,432): divide*/ +162, /* N(4,432): cent*/ +161, /* N(6,432): degree*/ 188, /* N(12,432): ordmasculine*/ -52, /* N(4,436): four*/ -36, /* N(6,438): dollar*/ -60, /* N(4,444): less*/ -142, /* N(6,444): eacute*/ -57, /* N(4,448): nine*/ +214, /* N(6,438): divide*/ +53, /* N(4,440): five*/ +52, /* N(4,444): four*/ +36, /* N(6,444): dollar*/ +142, /* N(6,450): eacute*/ 170, /* N(9,450): trademark*/ -43, /* N(4,456): plus*/ -143, /* N(6,456): egrave*/ -251, /* N(4,460): ring*/ -209, /* N(6,462): emdash*/ -48, /* N(4,464): zero*/ -208, /* N(6,468): endash*/ +60, /* N(4,452): less*/ +57, /* N(4,456): nine*/ +143, /* N(6,462): egrave*/ +43, /* N(4,464): plus*/ +251, /* N(4,468): ring*/ +209, /* N(6,468): emdash*/ +48, /* N(4,472): zero*/ 187, /* N(11,473): ordfeminine*/ -33, /* N(6,474): exclam*/ +208, /* N(6,474): endash*/ 159, /* N(9,477): udieresis*/ -196, /* N(6,480): florin*/ -45, /* N(6,492): hyphen*/ +33, /* N(6,480): exclam*/ +196, /* N(6,486): florin*/ 216, /* N(9,495): ydieresis*/ -146, /* N(6,498): iacute*/ -147, /* N(6,504): igrave*/ +45, /* N(6,498): hyphen*/ +146, /* N(6,504): iacute*/ 192, /* N(12,504): questiondown*/ +147, /* N(6,510): igrave*/ 227, /* N(12,516): quotedblbase*/ 228, /* N(11,528): perthousand*/ 210, /* N(12,528): quotedblleft*/ -248, /* N(6,534): macron*/ 39, /* N(11,539): quotesingle*/ -150, /* N(6,558): ntilde*/ -151, /* N(6,564): oacute*/ -254, /* N(6,570): ogonek*/ -152, /* N(6,576): ograve*/ -191, /* N(6,588): oslash*/ -155, /* N(6,594): otilde*/ -46, /* N(6,600): period*/ +248, /* N(6,540): macron*/ +150, /* N(6,564): ntilde*/ +151, /* N(6,570): oacute*/ +254, /* N(6,576): ogonek*/ +152, /* N(6,582): ograve*/ +191, /* N(6,594): oslash*/ +155, /* N(6,600): otilde*/ +46, /* N(6,606): period*/ 158, /* N(11,616): ucircumflex*/ -156, /* N(6,660): uacute*/ -157, /* N(6,666): ugrave*/ +156, /* N(6,666): uacute*/ +157, /* N(6,672): ugrave*/ 0}; /* MacExpertEncoding */ @@ -3609,7 +3621,7 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(5,165), /*space*/ +N(5,180), /*space*/ N(11,385), /*exclamsmall*/ N(17,0), /*Hungarumlautsmall*/ N(12,216), /*centoldstyle*/ @@ -3621,10 +3633,10 @@ N(17,34), /*parenleftsuperior*/ N(18,18), /*parenrightsuperior*/ N(14,406), /*twodotenleader*/ N(14,294), /*onedotenleader*/ -N(5,95), /*comma*/ -N(6,492), /*hyphen*/ -N(6,600), /*period*/ -N(8,104), /*fraction*/ +N(5,110), /*comma*/ +N(6,498), /*hyphen*/ +N(6,606), /*period*/ +N(8,112), /*fraction*/ N(12,636), /*zerooldstyle*/ N(11,451), /*oneoldstyle*/ N(11,594), /*twooldstyle*/ @@ -3635,7 +3647,7 @@ N(11,561), /*sixoldstyle*/ N(13,312), /*sevenoldstyle*/ N(13,182), /*eightoldstyle*/ N(12,408), /*nineoldstyle*/ -N(5,90), /*colon*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ N(7,0), /*.notdef*/ N(19,0), /*threequartersemdash*/ @@ -3649,13 +3661,13 @@ N(8,8), /*Ethsmall*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(10,280), /*onequarter*/ -N(7,238), /*onehalf*/ +N(7,273), /*onehalf*/ N(13,364), /*threequarters*/ N(9,324), /*oneeighth*/ N(12,612), /*threeeighths*/ N(11,407), /*fiveeighths*/ N(12,588), /*seveneighths*/ -N(8,152), /*onethird*/ +N(8,160), /*onethird*/ N(9,468), /*twothirds*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ @@ -3686,23 +3698,23 @@ N(6,132), /*Ismall*/ N(6,138), /*Jsmall*/ N(6,144), /*Ksmall*/ N(6,174), /*Lsmall*/ -N(6,180), /*Msmall*/ -N(6,198), /*Nsmall*/ -N(6,228), /*Osmall*/ -N(6,240), /*Psmall*/ -N(6,246), /*Qsmall*/ -N(6,264), /*Rsmall*/ -N(6,282), /*Ssmall*/ -N(6,294), /*Tsmall*/ -N(6,312), /*Usmall*/ -N(6,318), /*Vsmall*/ -N(6,324), /*Wsmall*/ -N(6,330), /*Xsmall*/ -N(6,342), /*Ysmall*/ -N(6,360), /*Zsmall*/ +N(6,186), /*Msmall*/ +N(6,204), /*Nsmall*/ +N(6,234), /*Osmall*/ +N(6,246), /*Psmall*/ +N(6,252), /*Qsmall*/ +N(6,270), /*Rsmall*/ +N(6,288), /*Ssmall*/ +N(6,300), /*Tsmall*/ +N(6,318), /*Usmall*/ +N(6,324), /*Vsmall*/ +N(6,330), /*Wsmall*/ +N(6,336), /*Xsmall*/ +N(6,348), /*Ysmall*/ +N(6,366), /*Zsmall*/ N(13,117), /*colonmonetary*/ N(9,333), /*onefitted*/ -N(6,618), /*rupiah*/ +N(6,624), /*rupiah*/ N(10,80), /*Tildesmall*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ @@ -3767,7 +3779,7 @@ N(7,0), /*.notdef*/ N(12,396), /*nineinferior*/ N(12,624), /*zeroinferior*/ N(11,264), /*Zcaronsmall*/ -N(7,7), /*AEsmall*/ +N(7,35), /*AEsmall*/ N(11,187), /*Oslashsmall*/ N(17,51), /*questiondownsmall*/ N(11,440), /*oneinferior*/ @@ -3784,7 +3796,7 @@ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ N(7,0), /*.notdef*/ -N(7,63), /*OEsmall*/ +N(7,91), /*OEsmall*/ N(10,190), /*figuredash*/ N(14,280), /*hyphensuperior*/ N(7,0), /*.notdef*/ @@ -3845,7 +3857,6 @@ static const ushort gs_c_known_encoding_reverse_6[] = { 34, /* N(17,0): Hungarumlautsmall*/ 93, /* N(18,0): parenrightinferior*/ 61, /* N(19,0): threequartersemdash*/ -190, /* N(7,7): AEsmall*/ 68, /* N(8,8): Ethsmall*/ 140, /* N(10,10): Aringsmall*/ 172, /* N(13,13): Dieresissmall*/ @@ -3863,6 +3874,7 @@ static const ushort gs_c_known_encoding_reverse_6[] = { 148, /* N(16,32): Icircumflexsmall*/ 139, /* N(11,33): Atildesmall*/ 40, /* N(17,34): parenleftsuperior*/ +190, /* N(7,35): AEsmall*/ 86, /* N(2,36): ff*/ 251, /* N(9,36): Ringsmall*/ 87, /* N(2,38): fi*/ @@ -3874,7 +3886,6 @@ static const ushort gs_c_known_encoding_reverse_6[] = { 96, /* N(10,50): Gravesmall*/ 192, /* N(17,51): questiondownsmall*/ 154, /* N(14,56): Odieresissmall*/ -207, /* N(7,63): OEsmall*/ 158, /* N(16,64): Ucircumflexsmall*/ 100, /* N(6,66): Dsmall*/ 143, /* N(11,66): Egravesmall*/ @@ -3883,15 +3894,16 @@ static const ushort gs_c_known_encoding_reverse_6[] = { 146, /* N(11,77): Iacutesmall*/ 126, /* N(10,80): Tildesmall*/ 216, /* N(14,84): Ydieresissmall*/ -58, /* N(5,90): colon*/ 101, /* N(6,90): Esmall*/ -44, /* N(5,95): comma*/ +207, /* N(7,91): OEsmall*/ 102, /* N(6,96): Fsmall*/ 38, /* N(14,98): ampersandsmall*/ 147, /* N(11,99): Igravesmall*/ -47, /* N(8,104): fraction*/ +58, /* N(5,105): colon*/ 103, /* N(6,108): Gsmall*/ +44, /* N(5,110): comma*/ 194, /* N(11,110): Lslashsmall*/ +47, /* N(8,112): fraction*/ 104, /* N(6,114): Hsmall*/ 123, /* N(13,117): colonmonetary*/ 244, /* N(11,121): Macronsmall*/ @@ -3903,21 +3915,21 @@ static const ushort gs_c_known_encoding_reverse_6[] = { 151, /* N(11,143): Oacutesmall*/ 248, /* N(13,143): commasuperior*/ 107, /* N(6,144): Ksmall*/ -78, /* N(8,152): onethird*/ +78, /* N(8,160): onethird*/ 245, /* N(9,162): bsuperior*/ -32, /* N(5,165): space*/ 242, /* N(11,165): Ogoneksmall*/ 165, /* N(13,169): eightinferior*/ 108, /* N(6,174): Lsmall*/ 152, /* N(11,176): Ogravesmall*/ -109, /* N(6,180): Msmall*/ +32, /* N(5,180): space*/ 56, /* N(13,182): eightoldstyle*/ +109, /* N(6,186): Msmall*/ 191, /* N(11,187): Oslashsmall*/ 208, /* N(10,190): figuredash*/ 161, /* N(13,195): eightsuperior*/ 182, /* N(14,196): dollarinferior*/ -110, /* N(6,198): Nsmall*/ 155, /* N(11,198): Otildesmall*/ +110, /* N(6,204): Nsmall*/ 169, /* N(12,204): centinferior*/ 235, /* N(9,207): dsuperior*/ 167, /* N(11,209): Scaronsmall*/ @@ -3926,51 +3938,51 @@ static const ushort gs_c_known_encoding_reverse_6[] = { 156, /* N(11,220): Uacutesmall*/ 37, /* N(14,224): dollarsuperior*/ 228, /* N(9,225): esuperior*/ -111, /* N(6,228): Osmall*/ 130, /* N(12,228): centsuperior*/ -72, /* N(7,238): onehalf*/ -112, /* N(6,240): Psmall*/ +111, /* N(6,234): Osmall*/ 176, /* N(12,240): fiveinferior*/ 157, /* N(11,242): Ugravesmall*/ -113, /* N(6,246): Qsmall*/ +112, /* N(6,246): Psmall*/ +113, /* N(6,252): Qsmall*/ 233, /* N(9,252): isuperior*/ 53, /* N(12,252): fiveoldstyle*/ 180, /* N(11,253): Yacutesmall*/ 63, /* N(13,260): questionsmall*/ -114, /* N(6,264): Rsmall*/ 189, /* N(11,264): Zcaronsmall*/ 222, /* N(12,264): fivesuperior*/ 95, /* N(14,266): hypheninferior*/ 89, /* N(3,267): ffi*/ 90, /* N(3,270): ffl*/ +114, /* N(6,270): Rsmall*/ +72, /* N(7,273): onehalf*/ 162, /* N(12,276): fourinferior*/ 241, /* N(9,279): lsuperior*/ 71, /* N(10,280): onequarter*/ 209, /* N(14,280): hyphensuperior*/ -115, /* N(6,282): Ssmall*/ +115, /* N(6,288): Ssmall*/ 247, /* N(9,288): msuperior*/ 52, /* N(12,288): fouroldstyle*/ -116, /* N(6,294): Tsmall*/ 43, /* N(14,294): onedotenleader*/ 166, /* N(13,299): seveninferior*/ +116, /* N(6,300): Tsmall*/ 221, /* N(12,300): foursuperior*/ 246, /* N(9,306): nsuperior*/ -117, /* N(6,312): Usmall*/ 55, /* N(13,312): sevenoldstyle*/ -118, /* N(6,318): Vsmall*/ +117, /* N(6,318): Usmall*/ 179, /* N(14,322): periodinferior*/ -119, /* N(6,324): Wsmall*/ +118, /* N(6,324): Vsmall*/ 74, /* N(9,324): oneeighth*/ 224, /* N(13,325): sevensuperior*/ -120, /* N(6,330): Xsmall*/ +119, /* N(6,330): Wsmall*/ 124, /* N(9,333): onefitted*/ +120, /* N(6,336): Xsmall*/ 249, /* N(14,336): periodsuperior*/ 163, /* N(13,338): threeinferior*/ -121, /* N(6,342): Ysmall*/ 175, /* N(9,342): osuperior*/ +121, /* N(6,348): Ysmall*/ 51, /* N(13,351): threeoldstyle*/ -122, /* N(6,360): Zsmall*/ 73, /* N(13,364): threequarters*/ +122, /* N(6,366): Zsmall*/ 220, /* N(13,377): threesuperior*/ 33, /* N(11,385): exclamsmall*/ 187, /* N(12,396): nineinferior*/ @@ -3986,17 +3998,17 @@ static const ushort gs_c_known_encoding_reverse_6[] = { 230, /* N(9,459): tsuperior*/ 218, /* N(11,462): onesuperior*/ 79, /* N(9,468): twothirds*/ -45, /* N(6,492): hyphen*/ +45, /* N(6,498): hyphen*/ 164, /* N(11,550): sixinferior*/ 54, /* N(11,561): sixoldstyle*/ 223, /* N(11,572): sixsuperior*/ 170, /* N(11,583): twoinferior*/ 77, /* N(12,588): seveneighths*/ 50, /* N(11,594): twooldstyle*/ -46, /* N(6,600): period*/ 219, /* N(11,605): twosuperior*/ +46, /* N(6,606): period*/ 75, /* N(12,612): threeeighths*/ -125, /* N(6,618): rupiah*/ +125, /* N(6,624): rupiah*/ 188, /* N(12,624): zeroinferior*/ 48, /* N(12,636): zerooldstyle*/ 226, /* N(12,648): zerosuperior*/ @@ -4007,38 +4019,38 @@ static const ushort gs_c_known_encoding_7[] = { N(7,0), /*.notdef*/ N(5,0), /*.null*/ N(2,2), /*CR*/ -N(5,165), /*space*/ -N(6,474), /*exclam*/ -N(8,168), /*quotedbl*/ +N(5,180), /*space*/ +N(6,480), /*exclam*/ +N(8,176), /*quotedbl*/ N(10,270), /*numbersign*/ -N(6,438), /*dollar*/ -N(7,245), /*percent*/ +N(6,444), /*dollar*/ +N(7,280), /*percent*/ N(9,72), /*ampersand*/ N(11,539), /*quotesingle*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ -N(8,48), /*asterisk*/ -N(4,456), /*plus*/ -N(5,95), /*comma*/ -N(6,492), /*hyphen*/ -N(6,600), /*period*/ -N(5,160), /*slash*/ -N(4,464), /*zero*/ +N(8,56), /*asterisk*/ +N(4,464), /*plus*/ +N(5,110), /*comma*/ +N(6,498), /*hyphen*/ +N(6,606), /*period*/ +N(5,175), /*slash*/ +N(4,472), /*zero*/ N(3,276), /*one*/ N(3,294), /*two*/ -N(5,185), /*three*/ -N(4,436), /*four*/ -N(4,432), /*five*/ +N(5,200), /*three*/ +N(4,444), /*four*/ +N(4,440), /*five*/ N(3,288), /*six*/ -N(5,150), /*seven*/ -N(5,105), /*eight*/ -N(4,448), /*nine*/ -N(5,90), /*colon*/ +N(5,165), /*seven*/ +N(5,120), /*eight*/ +N(4,456), /*nine*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ -N(4,444), /*less*/ -N(5,110), /*equal*/ -N(7,189), /*greater*/ -N(8,160), /*question*/ +N(4,452), /*less*/ +N(5,125), /*equal*/ +N(7,224), /*greater*/ +N(8,168), /*question*/ N(2,34), /*at*/ N(1,0), /*A*/ N(1,1), /*B*/ @@ -4071,7 +4083,7 @@ N(9,135), /*backslash*/ N(12,192), /*bracketright*/ N(11,308), /*asciicircum*/ N(10,320), /*underscore*/ -N(5,125), /*grave*/ +N(5,140), /*grave*/ N(1,26), /*a*/ N(1,27), /*b*/ N(1,28), /*c*/ @@ -4106,51 +4118,51 @@ N(9,0), /*Adieresis*/ N(5,10), /*Aring*/ N(8,0), /*Ccedilla*/ N(6,72), /*Eacute*/ -N(6,204), /*Ntilde*/ +N(6,210), /*Ntilde*/ N(9,27), /*Odieresis*/ N(9,45), /*Udieresis*/ -N(6,366), /*aacute*/ -N(6,378), /*agrave*/ +N(6,372), /*aacute*/ +N(6,384), /*agrave*/ N(11,275), /*acircumflex*/ N(9,63), /*adieresis*/ -N(6,384), /*atilde*/ -N(5,75), /*aring*/ -N(8,56), /*ccedilla*/ -N(6,444), /*eacute*/ -N(6,456), /*egrave*/ +N(6,390), /*atilde*/ +N(5,90), /*aring*/ +N(8,64), /*ccedilla*/ +N(6,450), /*eacute*/ +N(6,462), /*egrave*/ N(11,363), /*ecircumflex*/ N(9,216), /*edieresis*/ -N(6,498), /*iacute*/ -N(6,504), /*igrave*/ +N(6,504), /*iacute*/ +N(6,510), /*igrave*/ N(11,418), /*icircumflex*/ N(9,234), /*idieresis*/ -N(6,558), /*ntilde*/ -N(6,564), /*oacute*/ -N(6,576), /*ograve*/ +N(6,564), /*ntilde*/ +N(6,570), /*oacute*/ +N(6,582), /*ograve*/ N(11,429), /*ocircumflex*/ N(9,315), /*odieresis*/ -N(6,594), /*otilde*/ -N(6,660), /*uacute*/ -N(6,666), /*ugrave*/ +N(6,600), /*otilde*/ +N(6,666), /*uacute*/ +N(6,672), /*ugrave*/ N(11,616), /*ucircumflex*/ N(9,477), /*udieresis*/ -N(6,408), /*dagger*/ -N(6,426), /*degree*/ -N(4,424), /*cent*/ -N(8,184), /*sterling*/ -N(7,266), /*section*/ -N(6,390), /*bullet*/ +N(6,414), /*dagger*/ +N(6,432), /*degree*/ +N(4,432), /*cent*/ +N(8,192), /*sterling*/ +N(7,301), /*section*/ +N(6,396), /*bullet*/ N(9,360), /*paragraph*/ N(10,200), /*germandbls*/ N(10,310), /*registered*/ N(9,180), /*copyright*/ N(9,450), /*trademark*/ -N(5,55), /*acute*/ -N(8,72), /*dieresis*/ -N(8,144), /*notequal*/ +N(5,70), /*acute*/ +N(8,80), /*dieresis*/ +N(8,152), /*notequal*/ N(2,0), /*AE*/ -N(6,222), /*Oslash*/ -N(8,120), /*infinity*/ +N(6,228), /*Oslash*/ +N(8,128), /*infinity*/ N(9,378), /*plusminus*/ N(9,261), /*lessequal*/ N(12,324), /*greaterequal*/ @@ -4158,42 +4170,42 @@ N(3,297), /*yen*/ N(3,273), /*mu1*/ N(11,517), /*partialdiff*/ N(9,432), /*summation*/ -N(7,252), /*product*/ +N(7,287), /*product*/ N(2,48), /*pi*/ -N(8,128), /*integral*/ +N(8,136), /*integral*/ N(11,473), /*ordfeminine*/ N(12,432), /*ordmasculine*/ N(3,9), /*Ohm*/ N(2,32), /*ae*/ -N(6,588), /*oslash*/ +N(6,594), /*oslash*/ N(12,504), /*questiondown*/ N(10,180), /*exclamdown*/ N(10,250), /*logicalnot*/ -N(7,259), /*radical*/ -N(6,480), /*florin*/ +N(7,294), /*radical*/ +N(6,486), /*florin*/ N(11,286), /*approxequal*/ N(9,243), /*increment*/ N(13,208), /*guillemotleft*/ N(14,238), /*guillemotright*/ -N(8,88), /*ellipsis*/ -N(7,217), /*nbspace*/ +N(8,96), /*ellipsis*/ +N(7,252), /*nbspace*/ N(6,12), /*Agrave*/ N(6,24), /*Atilde*/ -N(6,234), /*Otilde*/ +N(6,240), /*Otilde*/ N(2,8), /*OE*/ N(2,46), /*oe*/ -N(6,468), /*endash*/ -N(6,462), /*emdash*/ +N(6,474), /*endash*/ +N(6,468), /*emdash*/ N(12,528), /*quotedblleft*/ N(13,273), /*quotedblright*/ N(9,387), /*quoteleft*/ N(10,300), /*quoteright*/ -N(6,432), /*divide*/ -N(7,210), /*lozenge*/ +N(6,438), /*divide*/ +N(7,245), /*lozenge*/ N(9,495), /*ydieresis*/ N(9,54), /*Ydieresis*/ -N(8,104), /*fraction*/ -N(8,64), /*currency*/ +N(8,112), /*fraction*/ +N(8,72), /*currency*/ N(13,221), /*guilsinglleft*/ N(14,252), /*guilsinglright*/ N(2,38), /*fi*/ @@ -4212,56 +4224,56 @@ N(6,120), /*Iacute*/ N(11,88), /*Icircumflex*/ N(9,18), /*Idieresis*/ N(6,126), /*Igrave*/ -N(6,210), /*Oacute*/ +N(6,216), /*Oacute*/ N(11,154), /*Ocircumflex*/ N(9,90), /*applelogo*/ -N(6,216), /*Ograve*/ -N(6,300), /*Uacute*/ +N(6,222), /*Ograve*/ +N(6,306), /*Uacute*/ N(11,231), /*Ucircumflex*/ -N(6,306), /*Ugrave*/ -N(8,80), /*dotlessi*/ +N(6,312), /*Ugrave*/ +N(8,88), /*dotlessi*/ N(10,160), /*circumflex*/ -N(5,190), /*tilde*/ +N(5,205), /*tilde*/ N(9,351), /*overscore*/ -N(5,80), /*breve*/ +N(5,95), /*breve*/ N(9,198), /*dotaccent*/ -N(4,460), /*ring*/ -N(7,133), /*cedilla*/ +N(4,468), /*ring*/ +N(7,168), /*cedilla*/ N(12,336), /*hungarumlaut*/ -N(6,570), /*ogonek*/ -N(5,85), /*caron*/ +N(6,576), /*ogonek*/ +N(5,100), /*caron*/ N(6,168), /*Lslash*/ -N(6,528), /*lslash*/ -N(6,276), /*Scaron*/ -N(6,630), /*scaron*/ -N(6,354), /*Zcaron*/ -N(6,684), /*zcaron*/ +N(6,534), /*lslash*/ +N(6,282), /*Scaron*/ +N(6,636), /*scaron*/ +N(6,360), /*Zcaron*/ +N(6,690), /*zcaron*/ N(9,153), /*brokenbar*/ N(3,6), /*Eth*/ N(3,264), /*eth*/ -N(6,336), /*Yacute*/ -N(6,672), /*yacute*/ -N(5,45), /*Thorn*/ -N(5,180), /*thorn*/ -N(5,140), /*minus*/ -N(8,136), /*multiply*/ +N(6,342), /*Yacute*/ +N(6,678), /*yacute*/ +N(5,60), /*Thorn*/ +N(5,195), /*thorn*/ +N(5,155), /*minus*/ +N(8,144), /*multiply*/ N(11,462), /*onesuperior*/ N(11,605), /*twosuperior*/ N(13,377), /*threesuperior*/ -N(7,238), /*onehalf*/ +N(7,273), /*onehalf*/ N(10,280), /*onequarter*/ N(13,364), /*threequarters*/ -N(5,115), /*franc*/ +N(5,130), /*franc*/ N(6,102), /*Gbreve*/ -N(6,486), /*gbreve*/ +N(6,492), /*gbreve*/ N(10,60), /*Idotaccent*/ N(8,32), /*Scedilla*/ -N(8,176), /*scedilla*/ +N(8,184), /*scedilla*/ N(6,36), /*Cacute*/ -N(6,396), /*cacute*/ +N(6,402), /*cacute*/ N(6,42), /*Ccaron*/ -N(6,402), /*ccaron*/ -N(7,147), /*dmacron*/ +N(6,408), /*ccaron*/ +N(7,182), /*dmacron*/ 0}; static const ushort gs_c_known_encoding_reverse_7[] = { 36, /* N(1,0): A*/ @@ -4333,194 +4345,194 @@ static const ushort gs_c_known_encoding_reverse_7[] = { 85, /* N(1,43): r*/ 86, /* N(1,44): s*/ 87, /* N(1,45): t*/ -237, /* N(5,45): Thorn*/ 104, /* N(9,45): Udieresis*/ 88, /* N(1,46): u*/ 177, /* N(2,46): oe*/ 89, /* N(1,47): v*/ 90, /* N(1,48): w*/ 155, /* N(2,48): pi*/ -13, /* N(8,48): asterisk*/ 91, /* N(1,49): x*/ 92, /* N(1,50): y*/ 93, /* N(1,51): z*/ 187, /* N(9,54): Ydieresis*/ -141, /* N(5,55): acute*/ 200, /* N(11,55): Ecircumflex*/ -111, /* N(8,56): ccedilla*/ +13, /* N(8,56): asterisk*/ +237, /* N(5,60): Thorn*/ 250, /* N(10,60): Idotaccent*/ 108, /* N(9,63): adieresis*/ -189, /* N(8,64): currency*/ +111, /* N(8,64): ccedilla*/ +141, /* N(5,70): acute*/ 101, /* N(6,72): Eacute*/ -142, /* N(8,72): dieresis*/ +189, /* N(8,72): currency*/ 9, /* N(9,72): ampersand*/ -110, /* N(5,75): aring*/ -219, /* N(5,80): breve*/ -215, /* N(8,80): dotlessi*/ +142, /* N(8,80): dieresis*/ 203, /* N(6,84): Egrave*/ -225, /* N(5,85): caron*/ -171, /* N(8,88): ellipsis*/ +215, /* N(8,88): dotlessi*/ 205, /* N(11,88): Icircumflex*/ -29, /* N(5,90): colon*/ +110, /* N(5,90): aring*/ 210, /* N(9,90): applelogo*/ -15, /* N(5,95): comma*/ +219, /* N(5,95): breve*/ +171, /* N(8,96): ellipsis*/ +225, /* N(5,100): caron*/ 248, /* N(6,102): Gbreve*/ -188, /* N(8,104): fraction*/ -27, /* N(5,105): eight*/ -32, /* N(5,110): equal*/ -247, /* N(5,115): franc*/ +29, /* N(5,105): colon*/ +15, /* N(5,110): comma*/ +188, /* N(8,112): fraction*/ +27, /* N(5,120): eight*/ 204, /* N(6,120): Iacute*/ -146, /* N(8,120): infinity*/ -67, /* N(5,125): grave*/ +32, /* N(5,125): equal*/ 207, /* N(6,126): Igrave*/ -156, /* N(8,128): integral*/ +146, /* N(8,128): infinity*/ +247, /* N(5,130): franc*/ 97, /* N(10,130): asciitilde*/ -222, /* N(7,133): cedilla*/ 63, /* N(9,135): backslash*/ -240, /* N(8,136): multiply*/ -239, /* N(5,140): minus*/ +156, /* N(8,136): integral*/ +67, /* N(5,140): grave*/ 96, /* N(10,140): braceright*/ -143, /* N(8,144): notequal*/ +240, /* N(8,144): multiply*/ 94, /* N(9,144): braceleft*/ -257, /* N(7,147): dmacron*/ -26, /* N(5,150): seven*/ +143, /* N(8,152): notequal*/ 232, /* N(9,153): brokenbar*/ 209, /* N(11,154): Ocircumflex*/ -18, /* N(5,160): slash*/ -34, /* N(8,160): question*/ +239, /* N(5,155): minus*/ 216, /* N(10,160): circumflex*/ -3, /* N(5,165): space*/ +26, /* N(5,165): seven*/ 226, /* N(6,168): Lslash*/ -5, /* N(8,168): quotedbl*/ -252, /* N(8,176): scedilla*/ -238, /* N(5,180): thorn*/ +222, /* N(7,168): cedilla*/ +34, /* N(8,168): question*/ +18, /* N(5,175): slash*/ +5, /* N(8,176): quotedbl*/ +3, /* N(5,180): space*/ 139, /* N(9,180): copyright*/ 163, /* N(10,180): exclamdown*/ -133, /* N(8,184): sterling*/ -22, /* N(5,185): three*/ -33, /* N(7,189): greater*/ +257, /* N(7,182): dmacron*/ +252, /* N(8,184): scedilla*/ 194, /* N(9,189): daggerdbl*/ -217, /* N(5,190): tilde*/ +133, /* N(8,192): sterling*/ 64, /* N(12,192): bracketright*/ +238, /* N(5,195): thorn*/ 220, /* N(9,198): dotaccent*/ +22, /* N(5,200): three*/ 137, /* N(10,200): germandbls*/ -102, /* N(6,204): Ntilde*/ +217, /* N(5,205): tilde*/ 169, /* N(13,208): guillemotleft*/ -208, /* N(6,210): Oacute*/ -185, /* N(7,210): lozenge*/ -211, /* N(6,216): Ograve*/ +102, /* N(6,210): Ntilde*/ +208, /* N(6,216): Oacute*/ 115, /* N(9,216): edieresis*/ -172, /* N(7,217): nbspace*/ 190, /* N(13,221): guilsinglleft*/ -145, /* N(6,222): Oslash*/ +211, /* N(6,222): Ograve*/ +33, /* N(7,224): greater*/ +145, /* N(6,228): Oslash*/ 213, /* N(11,231): Ucircumflex*/ -175, /* N(6,234): Otilde*/ 119, /* N(9,234): idieresis*/ -244, /* N(7,238): onehalf*/ 170, /* N(14,238): guillemotright*/ +175, /* N(6,240): Otilde*/ 168, /* N(9,243): increment*/ -8, /* N(7,245): percent*/ +185, /* N(7,245): lozenge*/ 164, /* N(10,250): logicalnot*/ -154, /* N(7,252): product*/ +172, /* N(7,252): nbspace*/ 191, /* N(14,252): guilsinglright*/ 95, /* N(3,255): bar*/ -165, /* N(7,259): radical*/ 148, /* N(9,261): lessequal*/ 234, /* N(3,264): eth*/ -134, /* N(7,266): section*/ 6, /* N(10,270): numbersign*/ 151, /* N(3,273): mu1*/ +244, /* N(7,273): onehalf*/ 181, /* N(13,273): quotedblright*/ 107, /* N(11,275): acircumflex*/ 20, /* N(3,276): one*/ -228, /* N(6,276): Scaron*/ +8, /* N(7,280): percent*/ 245, /* N(10,280): onequarter*/ +228, /* N(6,282): Scaron*/ 167, /* N(11,286): approxequal*/ +154, /* N(7,287): product*/ 25, /* N(3,288): six*/ 12, /* N(10,290): parenright*/ 21, /* N(3,294): two*/ +165, /* N(7,294): radical*/ 150, /* N(3,297): yen*/ -212, /* N(6,300): Uacute*/ 183, /* N(10,300): quoteright*/ -214, /* N(6,306): Ugrave*/ +134, /* N(7,301): section*/ +212, /* N(6,306): Uacute*/ 65, /* N(11,308): asciicircum*/ 195, /* N(14,308): periodcentered*/ 138, /* N(10,310): registered*/ +214, /* N(6,312): Ugrave*/ 124, /* N(9,315): odieresis*/ 66, /* N(10,320): underscore*/ 149, /* N(12,324): greaterequal*/ -235, /* N(6,336): Yacute*/ 223, /* N(12,336): hungarumlaut*/ 62, /* N(11,341): bracketleft*/ +235, /* N(6,342): Yacute*/ 218, /* N(9,351): overscore*/ -230, /* N(6,354): Zcaron*/ +230, /* N(6,360): Zcaron*/ 136, /* N(9,360): paragraph*/ 114, /* N(11,363): ecircumflex*/ 246, /* N(13,364): threequarters*/ 196, /* N(14,364): quotesinglbase*/ -105, /* N(6,366): aacute*/ 11, /* N(9,369): parenleft*/ +105, /* N(6,372): aacute*/ 243, /* N(13,377): threesuperior*/ -106, /* N(6,378): agrave*/ 147, /* N(9,378): plusminus*/ -109, /* N(6,384): atilde*/ +106, /* N(6,384): agrave*/ 182, /* N(9,387): quoteleft*/ -135, /* N(6,390): bullet*/ -254, /* N(6,396): cacute*/ -256, /* N(6,402): ccaron*/ -130, /* N(6,408): dagger*/ +109, /* N(6,390): atilde*/ +135, /* N(6,396): bullet*/ +254, /* N(6,402): cacute*/ +256, /* N(6,408): ccaron*/ +130, /* N(6,414): dagger*/ 30, /* N(9,414): semicolon*/ 118, /* N(11,418): icircumflex*/ -132, /* N(4,424): cent*/ -131, /* N(6,426): degree*/ 123, /* N(11,429): ocircumflex*/ -24, /* N(4,432): five*/ -184, /* N(6,432): divide*/ +132, /* N(4,432): cent*/ +131, /* N(6,432): degree*/ 153, /* N(9,432): summation*/ 158, /* N(12,432): ordmasculine*/ -23, /* N(4,436): four*/ -7, /* N(6,438): dollar*/ -31, /* N(4,444): less*/ -112, /* N(6,444): eacute*/ -28, /* N(4,448): nine*/ +184, /* N(6,438): divide*/ +24, /* N(4,440): five*/ +23, /* N(4,444): four*/ +7, /* N(6,444): dollar*/ +112, /* N(6,450): eacute*/ 140, /* N(9,450): trademark*/ -14, /* N(4,456): plus*/ -113, /* N(6,456): egrave*/ -221, /* N(4,460): ring*/ -179, /* N(6,462): emdash*/ +31, /* N(4,452): less*/ +28, /* N(4,456): nine*/ +113, /* N(6,462): egrave*/ 241, /* N(11,462): onesuperior*/ -19, /* N(4,464): zero*/ -178, /* N(6,468): endash*/ +14, /* N(4,464): plus*/ +221, /* N(4,468): ring*/ +179, /* N(6,468): emdash*/ +19, /* N(4,472): zero*/ 157, /* N(11,473): ordfeminine*/ -4, /* N(6,474): exclam*/ +178, /* N(6,474): endash*/ 129, /* N(9,477): udieresis*/ -166, /* N(6,480): florin*/ -249, /* N(6,486): gbreve*/ -16, /* N(6,492): hyphen*/ +4, /* N(6,480): exclam*/ +166, /* N(6,486): florin*/ +249, /* N(6,492): gbreve*/ 186, /* N(9,495): ydieresis*/ -116, /* N(6,498): iacute*/ -117, /* N(6,504): igrave*/ +16, /* N(6,498): hyphen*/ +116, /* N(6,504): iacute*/ 162, /* N(12,504): questiondown*/ +117, /* N(6,510): igrave*/ 197, /* N(12,516): quotedblbase*/ 152, /* N(11,517): partialdiff*/ -227, /* N(6,528): lslash*/ 198, /* N(11,528): perthousand*/ 180, /* N(12,528): quotedblleft*/ +227, /* N(6,534): lslash*/ 10, /* N(11,539): quotesingle*/ -120, /* N(6,558): ntilde*/ -121, /* N(6,564): oacute*/ -224, /* N(6,570): ogonek*/ -122, /* N(6,576): ograve*/ -161, /* N(6,588): oslash*/ -125, /* N(6,594): otilde*/ -17, /* N(6,600): period*/ +120, /* N(6,564): ntilde*/ +121, /* N(6,570): oacute*/ +224, /* N(6,576): ogonek*/ +122, /* N(6,582): ograve*/ +161, /* N(6,594): oslash*/ +125, /* N(6,600): otilde*/ 242, /* N(11,605): twosuperior*/ +17, /* N(6,606): period*/ 128, /* N(11,616): ucircumflex*/ -229, /* N(6,630): scaron*/ -126, /* N(6,660): uacute*/ -127, /* N(6,666): ugrave*/ -236, /* N(6,672): yacute*/ -231, /* N(6,684): zcaron*/ +229, /* N(6,636): scaron*/ +126, /* N(6,666): uacute*/ +127, /* N(6,672): ugrave*/ +236, /* N(6,678): yacute*/ +231, /* N(6,690): zcaron*/ 0}; /* AdobeLatinOriginalGlyphEncoding */ @@ -4558,49 +4570,49 @@ N(1,11), /*L*/ N(6,168), /*Lslash*/ N(1,12), /*M*/ N(1,13), /*N*/ -N(6,204), /*Ntilde*/ +N(6,210), /*Ntilde*/ N(1,14), /*O*/ N(2,8), /*OE*/ -N(6,210), /*Oacute*/ +N(6,216), /*Oacute*/ N(11,154), /*Ocircumflex*/ N(9,27), /*Odieresis*/ -N(6,216), /*Ograve*/ -N(6,222), /*Oslash*/ -N(6,234), /*Otilde*/ +N(6,222), /*Ograve*/ +N(6,228), /*Oslash*/ +N(6,240), /*Otilde*/ N(1,15), /*P*/ N(1,16), /*Q*/ N(1,17), /*R*/ N(1,18), /*S*/ -N(6,276), /*Scaron*/ +N(6,282), /*Scaron*/ N(1,19), /*T*/ -N(5,45), /*Thorn*/ +N(5,60), /*Thorn*/ N(1,20), /*U*/ -N(6,300), /*Uacute*/ +N(6,306), /*Uacute*/ N(11,231), /*Ucircumflex*/ N(9,45), /*Udieresis*/ -N(6,306), /*Ugrave*/ +N(6,312), /*Ugrave*/ N(1,21), /*V*/ N(1,22), /*W*/ N(1,23), /*X*/ N(1,24), /*Y*/ -N(6,336), /*Yacute*/ +N(6,342), /*Yacute*/ N(9,54), /*Ydieresis*/ N(1,25), /*Z*/ -N(6,354), /*Zcaron*/ +N(6,360), /*Zcaron*/ N(1,26), /*a*/ -N(6,366), /*aacute*/ +N(6,372), /*aacute*/ N(11,275), /*acircumflex*/ -N(5,55), /*acute*/ +N(5,70), /*acute*/ N(9,63), /*adieresis*/ N(2,32), /*ae*/ -N(6,378), /*agrave*/ +N(6,384), /*agrave*/ N(9,72), /*ampersand*/ -N(5,75), /*aring*/ +N(5,90), /*aring*/ N(11,308), /*asciicircum*/ N(10,130), /*asciitilde*/ -N(8,48), /*asterisk*/ +N(8,56), /*asterisk*/ N(2,34), /*at*/ -N(6,384), /*atilde*/ +N(6,390), /*atilde*/ N(1,27), /*b*/ N(9,135), /*backslash*/ N(3,255), /*bar*/ @@ -4608,108 +4620,108 @@ N(9,144), /*braceleft*/ N(10,140), /*braceright*/ N(11,341), /*bracketleft*/ N(12,192), /*bracketright*/ -N(5,80), /*breve*/ +N(5,95), /*breve*/ N(9,153), /*brokenbar*/ -N(6,390), /*bullet*/ +N(6,396), /*bullet*/ N(1,28), /*c*/ -N(5,85), /*caron*/ -N(8,56), /*ccedilla*/ -N(7,133), /*cedilla*/ -N(4,424), /*cent*/ +N(5,100), /*caron*/ +N(8,64), /*ccedilla*/ +N(7,168), /*cedilla*/ +N(4,432), /*cent*/ N(10,160), /*circumflex*/ -N(5,90), /*colon*/ -N(5,95), /*comma*/ +N(5,105), /*colon*/ +N(5,110), /*comma*/ N(9,180), /*copyright*/ -N(8,64), /*currency*/ +N(8,72), /*currency*/ N(1,29), /*d*/ -N(6,408), /*dagger*/ +N(6,414), /*dagger*/ N(9,189), /*daggerdbl*/ -N(6,426), /*degree*/ -N(8,72), /*dieresis*/ -N(6,432), /*divide*/ -N(6,438), /*dollar*/ +N(6,432), /*degree*/ +N(8,80), /*dieresis*/ +N(6,438), /*divide*/ +N(6,444), /*dollar*/ N(9,198), /*dotaccent*/ -N(8,80), /*dotlessi*/ +N(8,88), /*dotlessi*/ N(1,30), /*e*/ -N(6,444), /*eacute*/ +N(6,450), /*eacute*/ N(11,363), /*ecircumflex*/ N(9,216), /*edieresis*/ -N(6,456), /*egrave*/ -N(5,105), /*eight*/ -N(8,88), /*ellipsis*/ -N(6,462), /*emdash*/ -N(6,468), /*endash*/ -N(5,110), /*equal*/ +N(6,462), /*egrave*/ +N(5,120), /*eight*/ +N(8,96), /*ellipsis*/ +N(6,468), /*emdash*/ +N(6,474), /*endash*/ +N(5,125), /*equal*/ N(3,264), /*eth*/ -N(6,474), /*exclam*/ +N(6,480), /*exclam*/ N(10,180), /*exclamdown*/ N(1,31), /*f*/ N(2,38), /*fi*/ -N(4,432), /*five*/ +N(4,440), /*five*/ N(2,40), /*fl*/ -N(6,480), /*florin*/ -N(4,436), /*four*/ -N(8,104), /*fraction*/ +N(6,486), /*florin*/ +N(4,444), /*four*/ +N(8,112), /*fraction*/ N(1,32), /*g*/ N(10,200), /*germandbls*/ -N(5,125), /*grave*/ -N(7,189), /*greater*/ +N(5,140), /*grave*/ +N(7,224), /*greater*/ N(13,208), /*guillemotleft*/ N(14,238), /*guillemotright*/ N(13,221), /*guilsinglleft*/ N(14,252), /*guilsinglright*/ N(1,33), /*h*/ N(12,336), /*hungarumlaut*/ -N(6,492), /*hyphen*/ +N(6,498), /*hyphen*/ N(1,34), /*i*/ -N(6,498), /*iacute*/ +N(6,504), /*iacute*/ N(11,418), /*icircumflex*/ N(9,234), /*idieresis*/ -N(6,504), /*igrave*/ +N(6,510), /*igrave*/ N(1,35), /*j*/ N(1,36), /*k*/ N(1,37), /*l*/ -N(4,444), /*less*/ +N(4,452), /*less*/ N(10,250), /*logicalnot*/ -N(6,528), /*lslash*/ +N(6,534), /*lslash*/ N(1,38), /*m*/ -N(6,534), /*macron*/ -N(5,140), /*minus*/ +N(6,540), /*macron*/ +N(5,155), /*minus*/ N(2,42), /*mu*/ -N(8,136), /*multiply*/ +N(8,144), /*multiply*/ N(1,39), /*n*/ -N(4,448), /*nine*/ -N(6,558), /*ntilde*/ +N(4,456), /*nine*/ +N(6,564), /*ntilde*/ N(10,270), /*numbersign*/ N(1,40), /*o*/ -N(6,564), /*oacute*/ +N(6,570), /*oacute*/ N(11,429), /*ocircumflex*/ N(9,315), /*odieresis*/ N(2,46), /*oe*/ -N(6,570), /*ogonek*/ -N(6,576), /*ograve*/ +N(6,576), /*ogonek*/ +N(6,582), /*ograve*/ N(3,276), /*one*/ -N(7,238), /*onehalf*/ +N(7,273), /*onehalf*/ N(10,280), /*onequarter*/ N(11,462), /*onesuperior*/ N(11,473), /*ordfeminine*/ N(12,432), /*ordmasculine*/ -N(6,588), /*oslash*/ -N(6,594), /*otilde*/ +N(6,594), /*oslash*/ +N(6,600), /*otilde*/ N(1,41), /*p*/ N(9,360), /*paragraph*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ -N(7,245), /*percent*/ -N(6,600), /*period*/ +N(7,280), /*percent*/ +N(6,606), /*period*/ N(14,308), /*periodcentered*/ N(11,528), /*perthousand*/ -N(4,456), /*plus*/ +N(4,464), /*plus*/ N(9,378), /*plusminus*/ N(1,42), /*q*/ -N(8,160), /*question*/ +N(8,168), /*question*/ N(12,504), /*questiondown*/ -N(8,168), /*quotedbl*/ +N(8,176), /*quotedbl*/ N(12,516), /*quotedblbase*/ N(12,528), /*quotedblleft*/ N(13,273), /*quotedblright*/ @@ -4719,41 +4731,41 @@ N(14,364), /*quotesinglbase*/ N(11,539), /*quotesingle*/ N(1,43), /*r*/ N(10,310), /*registered*/ -N(4,460), /*ring*/ +N(4,468), /*ring*/ N(1,44), /*s*/ -N(6,630), /*scaron*/ -N(7,266), /*section*/ +N(6,636), /*scaron*/ +N(7,301), /*section*/ N(9,414), /*semicolon*/ -N(5,150), /*seven*/ +N(5,165), /*seven*/ N(3,288), /*six*/ -N(5,160), /*slash*/ -N(5,165), /*space*/ -N(8,184), /*sterling*/ +N(5,175), /*slash*/ +N(5,180), /*space*/ +N(8,192), /*sterling*/ N(1,45), /*t*/ -N(5,180), /*thorn*/ -N(5,185), /*three*/ +N(5,195), /*thorn*/ +N(5,200), /*three*/ N(13,364), /*threequarters*/ N(13,377), /*threesuperior*/ -N(5,190), /*tilde*/ +N(5,205), /*tilde*/ N(9,450), /*trademark*/ N(3,294), /*two*/ N(11,605), /*twosuperior*/ N(1,46), /*u*/ -N(6,660), /*uacute*/ +N(6,666), /*uacute*/ N(11,616), /*ucircumflex*/ N(9,477), /*udieresis*/ -N(6,666), /*ugrave*/ +N(6,672), /*ugrave*/ N(10,320), /*underscore*/ N(1,47), /*v*/ N(1,48), /*w*/ N(1,49), /*x*/ N(1,50), /*y*/ -N(6,672), /*yacute*/ +N(6,678), /*yacute*/ N(9,495), /*ydieresis*/ N(3,297), /*yen*/ N(1,51), /*z*/ -N(6,684), /*zcaron*/ -N(4,464), /*zero*/ +N(6,690), /*zcaron*/ +N(4,472), /*zero*/ 0}; static const ushort gs_c_known_encoding_reverse_8[] = { 1, /* N(1,0): A*/ @@ -4820,385 +4832,385 @@ static const ushort gs_c_known_encoding_reverse_8[] = { 192, /* N(1,43): r*/ 195, /* N(1,44): s*/ 204, /* N(1,45): t*/ -48, /* N(5,45): Thorn*/ 52, /* N(9,45): Udieresis*/ 213, /* N(1,46): u*/ 160, /* N(2,46): oe*/ 219, /* N(1,47): v*/ 220, /* N(1,48): w*/ -73, /* N(8,48): asterisk*/ 221, /* N(1,49): x*/ 222, /* N(1,50): y*/ 226, /* N(1,51): z*/ 59, /* N(9,54): Ydieresis*/ -65, /* N(5,55): acute*/ 15, /* N(11,55): Ecircumflex*/ -88, /* N(8,56): ccedilla*/ +73, /* N(8,56): asterisk*/ +48, /* N(5,60): Thorn*/ 66, /* N(9,63): adieresis*/ -95, /* N(8,64): currency*/ +88, /* N(8,64): ccedilla*/ +65, /* N(5,70): acute*/ 14, /* N(6,72): Eacute*/ -100, /* N(8,72): dieresis*/ +95, /* N(8,72): currency*/ 69, /* N(9,72): ampersand*/ -70, /* N(5,75): aring*/ -83, /* N(5,80): breve*/ -104, /* N(8,80): dotlessi*/ +100, /* N(8,80): dieresis*/ 17, /* N(6,84): Egrave*/ -87, /* N(5,85): caron*/ -111, /* N(8,88): ellipsis*/ +104, /* N(8,88): dotlessi*/ 24, /* N(11,88): Icircumflex*/ -92, /* N(5,90): colon*/ -93, /* N(5,95): comma*/ -124, /* N(8,104): fraction*/ -110, /* N(5,105): eight*/ -114, /* N(5,110): equal*/ +70, /* N(5,90): aring*/ +83, /* N(5,95): breve*/ +111, /* N(8,96): ellipsis*/ +87, /* N(5,100): caron*/ +92, /* N(5,105): colon*/ +93, /* N(5,110): comma*/ +124, /* N(8,112): fraction*/ +110, /* N(5,120): eight*/ 23, /* N(6,120): Iacute*/ -127, /* N(5,125): grave*/ +114, /* N(5,125): equal*/ 26, /* N(6,126): Igrave*/ 72, /* N(10,130): asciitilde*/ -89, /* N(7,133): cedilla*/ 77, /* N(9,135): backslash*/ -151, /* N(8,136): multiply*/ -149, /* N(5,140): minus*/ +127, /* N(5,140): grave*/ 80, /* N(10,140): braceright*/ +151, /* N(8,144): multiply*/ 79, /* N(9,144): braceleft*/ -199, /* N(5,150): seven*/ 84, /* N(9,153): brokenbar*/ 37, /* N(11,154): Ocircumflex*/ -201, /* N(5,160): slash*/ -182, /* N(8,160): question*/ +149, /* N(5,155): minus*/ 91, /* N(10,160): circumflex*/ -202, /* N(5,165): space*/ +199, /* N(5,165): seven*/ 30, /* N(6,168): Lslash*/ -184, /* N(8,168): quotedbl*/ -205, /* N(5,180): thorn*/ +89, /* N(7,168): cedilla*/ +182, /* N(8,168): question*/ +201, /* N(5,175): slash*/ +184, /* N(8,176): quotedbl*/ +202, /* N(5,180): space*/ 94, /* N(9,180): copyright*/ 117, /* N(10,180): exclamdown*/ -203, /* N(8,184): sterling*/ -206, /* N(5,185): three*/ -128, /* N(7,189): greater*/ 98, /* N(9,189): daggerdbl*/ -209, /* N(5,190): tilde*/ +203, /* N(8,192): sterling*/ 82, /* N(12,192): bracketright*/ +205, /* N(5,195): thorn*/ 103, /* N(9,198): dotaccent*/ +206, /* N(5,200): three*/ 126, /* N(10,200): germandbls*/ -33, /* N(6,204): Ntilde*/ +209, /* N(5,205): tilde*/ 129, /* N(13,208): guillemotleft*/ -36, /* N(6,210): Oacute*/ -39, /* N(6,216): Ograve*/ +33, /* N(6,210): Ntilde*/ +36, /* N(6,216): Oacute*/ 108, /* N(9,216): edieresis*/ 131, /* N(13,221): guilsinglleft*/ -40, /* N(6,222): Oslash*/ +39, /* N(6,222): Ograve*/ +128, /* N(7,224): greater*/ +40, /* N(6,228): Oslash*/ 51, /* N(11,231): Ucircumflex*/ -41, /* N(6,234): Otilde*/ 139, /* N(9,234): idieresis*/ -164, /* N(7,238): onehalf*/ 130, /* N(14,238): guillemotright*/ -175, /* N(7,245): percent*/ +41, /* N(6,240): Otilde*/ 145, /* N(10,250): logicalnot*/ 132, /* N(14,252): guilsinglright*/ 78, /* N(3,255): bar*/ 115, /* N(3,264): eth*/ -197, /* N(7,266): section*/ 155, /* N(10,270): numbersign*/ +164, /* N(7,273): onehalf*/ 187, /* N(13,273): quotedblright*/ 64, /* N(11,275): acircumflex*/ 163, /* N(3,276): one*/ -46, /* N(6,276): Scaron*/ +175, /* N(7,280): percent*/ 165, /* N(10,280): onequarter*/ +46, /* N(6,282): Scaron*/ 200, /* N(3,288): six*/ 174, /* N(10,290): parenright*/ 211, /* N(3,294): two*/ 225, /* N(3,297): yen*/ -50, /* N(6,300): Uacute*/ 189, /* N(10,300): quoteright*/ -53, /* N(6,306): Ugrave*/ +197, /* N(7,301): section*/ +50, /* N(6,306): Uacute*/ 71, /* N(11,308): asciicircum*/ 177, /* N(14,308): periodcentered*/ 193, /* N(10,310): registered*/ +53, /* N(6,312): Ugrave*/ 159, /* N(9,315): odieresis*/ 218, /* N(10,320): underscore*/ -58, /* N(6,336): Yacute*/ 134, /* N(12,336): hungarumlaut*/ 81, /* N(11,341): bracketleft*/ -61, /* N(6,354): Zcaron*/ +58, /* N(6,342): Yacute*/ +61, /* N(6,360): Zcaron*/ 172, /* N(9,360): paragraph*/ 107, /* N(11,363): ecircumflex*/ 207, /* N(13,364): threequarters*/ 190, /* N(14,364): quotesinglbase*/ -63, /* N(6,366): aacute*/ 173, /* N(9,369): parenleft*/ +63, /* N(6,372): aacute*/ 208, /* N(13,377): threesuperior*/ -68, /* N(6,378): agrave*/ 180, /* N(9,378): plusminus*/ -75, /* N(6,384): atilde*/ +68, /* N(6,384): agrave*/ 188, /* N(9,387): quoteleft*/ -85, /* N(6,390): bullet*/ -97, /* N(6,408): dagger*/ +75, /* N(6,390): atilde*/ +85, /* N(6,396): bullet*/ +97, /* N(6,414): dagger*/ 198, /* N(9,414): semicolon*/ 138, /* N(11,418): icircumflex*/ -90, /* N(4,424): cent*/ -99, /* N(6,426): degree*/ 158, /* N(11,429): ocircumflex*/ -120, /* N(4,432): five*/ -101, /* N(6,432): divide*/ +90, /* N(4,432): cent*/ +99, /* N(6,432): degree*/ 168, /* N(12,432): ordmasculine*/ -123, /* N(4,436): four*/ -102, /* N(6,438): dollar*/ -144, /* N(4,444): less*/ -106, /* N(6,444): eacute*/ -153, /* N(4,448): nine*/ +101, /* N(6,438): divide*/ +120, /* N(4,440): five*/ +123, /* N(4,444): four*/ +102, /* N(6,444): dollar*/ +106, /* N(6,450): eacute*/ 210, /* N(9,450): trademark*/ -179, /* N(4,456): plus*/ -109, /* N(6,456): egrave*/ -194, /* N(4,460): ring*/ -112, /* N(6,462): emdash*/ +144, /* N(4,452): less*/ +153, /* N(4,456): nine*/ +109, /* N(6,462): egrave*/ 166, /* N(11,462): onesuperior*/ -228, /* N(4,464): zero*/ -113, /* N(6,468): endash*/ +179, /* N(4,464): plus*/ +194, /* N(4,468): ring*/ +112, /* N(6,468): emdash*/ +228, /* N(4,472): zero*/ 167, /* N(11,473): ordfeminine*/ -116, /* N(6,474): exclam*/ +113, /* N(6,474): endash*/ 216, /* N(9,477): udieresis*/ -122, /* N(6,480): florin*/ -135, /* N(6,492): hyphen*/ +116, /* N(6,480): exclam*/ +122, /* N(6,486): florin*/ 224, /* N(9,495): ydieresis*/ -137, /* N(6,498): iacute*/ -140, /* N(6,504): igrave*/ +135, /* N(6,498): hyphen*/ +137, /* N(6,504): iacute*/ 183, /* N(12,504): questiondown*/ +140, /* N(6,510): igrave*/ 185, /* N(12,516): quotedblbase*/ -146, /* N(6,528): lslash*/ 178, /* N(11,528): perthousand*/ 186, /* N(12,528): quotedblleft*/ -148, /* N(6,534): macron*/ +146, /* N(6,534): lslash*/ 191, /* N(11,539): quotesingle*/ -154, /* N(6,558): ntilde*/ -157, /* N(6,564): oacute*/ -161, /* N(6,570): ogonek*/ -162, /* N(6,576): ograve*/ -169, /* N(6,588): oslash*/ -170, /* N(6,594): otilde*/ -176, /* N(6,600): period*/ +148, /* N(6,540): macron*/ +154, /* N(6,564): ntilde*/ +157, /* N(6,570): oacute*/ +161, /* N(6,576): ogonek*/ +162, /* N(6,582): ograve*/ +169, /* N(6,594): oslash*/ +170, /* N(6,600): otilde*/ 212, /* N(11,605): twosuperior*/ +176, /* N(6,606): period*/ 215, /* N(11,616): ucircumflex*/ -196, /* N(6,630): scaron*/ -214, /* N(6,660): uacute*/ -217, /* N(6,666): ugrave*/ -223, /* N(6,672): yacute*/ -227, /* N(6,684): zcaron*/ +196, /* N(6,636): scaron*/ +214, /* N(6,666): uacute*/ +217, /* N(6,672): ugrave*/ +223, /* N(6,678): yacute*/ +227, /* N(6,690): zcaron*/ 0}; /* AdobeLatinExtensionGlyphEncoding */ static const ushort gs_c_known_encoding_9[] = { N(6,6), /*Abreve*/ -N(7,14), /*Amacron*/ -N(7,21), /*Aogonek*/ +N(7,42), /*Amacron*/ +N(7,49), /*Aogonek*/ N(6,36), /*Cacute*/ N(6,42), /*Ccaron*/ N(6,54), /*Dcaron*/ N(6,60), /*Dcroat*/ -N(5,15), /*Delta*/ +N(5,20), /*Delta*/ N(6,78), /*Ecaron*/ N(10,40), /*Edotaccent*/ -N(7,28), /*Emacron*/ -N(7,35), /*Eogonek*/ +N(7,56), /*Emacron*/ +N(7,63), /*Eogonek*/ N(6,102), /*Gbreve*/ N(12,12), /*Gcommaaccent*/ N(10,60), /*Idotaccent*/ -N(7,49), /*Imacron*/ -N(7,56), /*Iogonek*/ +N(7,77), /*Imacron*/ +N(7,84), /*Iogonek*/ N(12,24), /*Kcommaaccent*/ N(6,150), /*Lacute*/ N(6,162), /*Lcaron*/ N(12,36), /*Lcommaaccent*/ -N(6,186), /*Nacute*/ -N(6,192), /*Ncaron*/ +N(6,192), /*Nacute*/ +N(6,198), /*Ncaron*/ N(12,48), /*Ncommaaccent*/ N(13,26), /*Ohungarumlaut*/ -N(7,70), /*Omacron*/ -N(6,252), /*Racute*/ -N(6,258), /*Rcaron*/ +N(7,98), /*Omacron*/ +N(6,258), /*Racute*/ +N(6,264), /*Rcaron*/ N(12,60), /*Rcommaaccent*/ -N(6,270), /*Sacute*/ +N(6,276), /*Sacute*/ N(8,32), /*Scedilla*/ N(12,72), /*Scommaaccent*/ -N(6,288), /*Tcaron*/ +N(6,294), /*Tcaron*/ N(12,84), /*Tcommaaccent*/ N(13,39), /*Uhungarumlaut*/ -N(7,84), /*Umacron*/ -N(7,91), /*Uogonek*/ -N(5,50), /*Uring*/ -N(6,348), /*Zacute*/ +N(7,119), /*Umacron*/ +N(7,126), /*Uogonek*/ +N(5,65), /*Uring*/ +N(6,354), /*Zacute*/ N(10,90), /*Zdotaccent*/ -N(6,372), /*abreve*/ -N(7,105), /*amacron*/ -N(7,112), /*aogonek*/ -N(6,396), /*cacute*/ -N(6,402), /*ccaron*/ +N(6,378), /*abreve*/ +N(7,140), /*amacron*/ +N(7,147), /*aogonek*/ +N(6,402), /*cacute*/ +N(6,408), /*ccaron*/ N(11,352), /*commaaccent*/ -N(6,414), /*dcaron*/ -N(6,420), /*dcroat*/ -N(6,450), /*ecaron*/ +N(6,420), /*dcaron*/ +N(6,426), /*dcroat*/ +N(6,456), /*ecaron*/ N(10,170), /*edotaccent*/ -N(7,168), /*emacron*/ -N(7,175), /*eogonek*/ -N(6,486), /*gbreve*/ +N(7,203), /*emacron*/ +N(7,210), /*eogonek*/ +N(6,492), /*gbreve*/ N(12,312), /*gcommaaccent*/ N(12,324), /*greaterequal*/ -N(7,196), /*imacron*/ -N(7,203), /*iogonek*/ +N(7,231), /*imacron*/ +N(7,238), /*iogonek*/ N(12,360), /*kcommaaccent*/ -N(6,510), /*lacute*/ -N(6,522), /*lcaron*/ +N(6,516), /*lacute*/ +N(6,528), /*lcaron*/ N(12,372), /*lcommaaccent*/ N(9,261), /*lessequal*/ -N(7,210), /*lozenge*/ -N(6,546), /*nacute*/ -N(6,552), /*ncaron*/ +N(7,245), /*lozenge*/ +N(6,552), /*nacute*/ +N(6,558), /*ncaron*/ N(12,384), /*ncommaaccent*/ -N(8,144), /*notequal*/ +N(8,152), /*notequal*/ N(13,234), /*ohungarumlaut*/ -N(7,224), /*omacron*/ +N(7,259), /*omacron*/ N(11,517), /*partialdiff*/ -N(6,606), /*racute*/ -N(7,259), /*radical*/ -N(6,612), /*rcaron*/ +N(6,612), /*racute*/ +N(7,294), /*radical*/ +N(6,618), /*rcaron*/ N(12,540), /*rcommaaccent*/ -N(6,624), /*sacute*/ -N(8,176), /*scedilla*/ +N(6,630), /*sacute*/ +N(8,184), /*scedilla*/ N(12,576), /*scommaaccent*/ N(9,432), /*summation*/ -N(6,648), /*tcaron*/ +N(6,654), /*tcaron*/ N(12,600), /*tcommaaccent*/ N(13,403), /*uhungarumlaut*/ -N(7,280), /*umacron*/ -N(7,287), /*uogonek*/ -N(5,200), /*uring*/ -N(6,678), /*zacute*/ +N(7,315), /*umacron*/ +N(7,322), /*uogonek*/ +N(5,215), /*uring*/ +N(6,684), /*zacute*/ N(10,330), /*zdotaccent*/ 0}; static const ushort gs_c_known_encoding_reverse_9[] = { 0, /* N(6,6): Abreve*/ 13, /* N(12,12): Gcommaaccent*/ -1, /* N(7,14): Amacron*/ -7, /* N(5,15): Delta*/ -2, /* N(7,21): Aogonek*/ +7, /* N(5,20): Delta*/ 17, /* N(12,24): Kcommaaccent*/ 24, /* N(13,26): Ohungarumlaut*/ -10, /* N(7,28): Emacron*/ 30, /* N(8,32): Scedilla*/ -11, /* N(7,35): Eogonek*/ 3, /* N(6,36): Cacute*/ 20, /* N(12,36): Lcommaaccent*/ 34, /* N(13,39): Uhungarumlaut*/ 9, /* N(10,40): Edotaccent*/ 4, /* N(6,42): Ccaron*/ +1, /* N(7,42): Amacron*/ 23, /* N(12,48): Ncommaaccent*/ -15, /* N(7,49): Imacron*/ -37, /* N(5,50): Uring*/ +2, /* N(7,49): Aogonek*/ 5, /* N(6,54): Dcaron*/ -16, /* N(7,56): Iogonek*/ +10, /* N(7,56): Emacron*/ 6, /* N(6,60): Dcroat*/ 14, /* N(10,60): Idotaccent*/ 28, /* N(12,60): Rcommaaccent*/ -25, /* N(7,70): Omacron*/ +11, /* N(7,63): Eogonek*/ +37, /* N(5,65): Uring*/ 31, /* N(12,72): Scommaaccent*/ +15, /* N(7,77): Imacron*/ 8, /* N(6,78): Ecaron*/ -35, /* N(7,84): Umacron*/ +16, /* N(7,84): Iogonek*/ 33, /* N(12,84): Tcommaaccent*/ 39, /* N(10,90): Zdotaccent*/ -36, /* N(7,91): Uogonek*/ +25, /* N(7,98): Omacron*/ 12, /* N(6,102): Gbreve*/ -41, /* N(7,105): amacron*/ -42, /* N(7,112): aogonek*/ -66, /* N(8,144): notequal*/ +35, /* N(7,119): Umacron*/ +36, /* N(7,126): Uogonek*/ +41, /* N(7,140): amacron*/ +42, /* N(7,147): aogonek*/ 18, /* N(6,150): Lacute*/ +66, /* N(8,152): notequal*/ 19, /* N(6,162): Lcaron*/ -50, /* N(7,168): emacron*/ 49, /* N(10,170): edotaccent*/ -51, /* N(7,175): eogonek*/ -75, /* N(8,176): scedilla*/ -21, /* N(6,186): Nacute*/ -22, /* N(6,192): Ncaron*/ -55, /* N(7,196): imacron*/ -83, /* N(5,200): uring*/ -56, /* N(7,203): iogonek*/ -62, /* N(7,210): lozenge*/ -68, /* N(7,224): omacron*/ +75, /* N(8,184): scedilla*/ +21, /* N(6,192): Nacute*/ +22, /* N(6,198): Ncaron*/ +50, /* N(7,203): emacron*/ +51, /* N(7,210): eogonek*/ +83, /* N(5,215): uring*/ +55, /* N(7,231): imacron*/ 67, /* N(13,234): ohungarumlaut*/ -26, /* N(6,252): Racute*/ -27, /* N(6,258): Rcaron*/ -71, /* N(7,259): radical*/ +56, /* N(7,238): iogonek*/ +62, /* N(7,245): lozenge*/ +26, /* N(6,258): Racute*/ +68, /* N(7,259): omacron*/ 61, /* N(9,261): lessequal*/ -29, /* N(6,270): Sacute*/ -81, /* N(7,280): umacron*/ -82, /* N(7,287): uogonek*/ -32, /* N(6,288): Tcaron*/ +27, /* N(6,264): Rcaron*/ +29, /* N(6,276): Sacute*/ +32, /* N(6,294): Tcaron*/ +71, /* N(7,294): radical*/ 53, /* N(12,312): gcommaaccent*/ +81, /* N(7,315): umacron*/ +82, /* N(7,322): uogonek*/ 54, /* N(12,324): greaterequal*/ 85, /* N(10,330): zdotaccent*/ -38, /* N(6,348): Zacute*/ 45, /* N(11,352): commaaccent*/ +38, /* N(6,354): Zacute*/ 57, /* N(12,360): kcommaaccent*/ -40, /* N(6,372): abreve*/ 60, /* N(12,372): lcommaaccent*/ +40, /* N(6,378): abreve*/ 65, /* N(12,384): ncommaaccent*/ -43, /* N(6,396): cacute*/ -44, /* N(6,402): ccaron*/ +43, /* N(6,402): cacute*/ 80, /* N(13,403): uhungarumlaut*/ -46, /* N(6,414): dcaron*/ -47, /* N(6,420): dcroat*/ +44, /* N(6,408): ccaron*/ +46, /* N(6,420): dcaron*/ +47, /* N(6,426): dcroat*/ 77, /* N(9,432): summation*/ -48, /* N(6,450): ecaron*/ -52, /* N(6,486): gbreve*/ -58, /* N(6,510): lacute*/ +48, /* N(6,456): ecaron*/ +52, /* N(6,492): gbreve*/ +58, /* N(6,516): lacute*/ 69, /* N(11,517): partialdiff*/ -59, /* N(6,522): lcaron*/ +59, /* N(6,528): lcaron*/ 73, /* N(12,540): rcommaaccent*/ -63, /* N(6,546): nacute*/ -64, /* N(6,552): ncaron*/ +63, /* N(6,552): nacute*/ +64, /* N(6,558): ncaron*/ 76, /* N(12,576): scommaaccent*/ 79, /* N(12,600): tcommaaccent*/ -70, /* N(6,606): racute*/ -72, /* N(6,612): rcaron*/ -74, /* N(6,624): sacute*/ -78, /* N(6,648): tcaron*/ -84, /* N(6,678): zacute*/ +70, /* N(6,612): racute*/ +72, /* N(6,618): rcaron*/ +74, /* N(6,630): sacute*/ +78, /* N(6,654): tcaron*/ +84, /* N(6,684): zacute*/ 0}; /* CFFStandardStrings */ static const ushort gs_c_known_encoding_10[] = { N(7,0), /*.notdef*/ -N(5,165), /*space*/ -N(6,474), /*exclam*/ -N(8,168), /*quotedbl*/ +N(5,180), /*space*/ +N(6,480), /*exclam*/ +N(8,176), /*quotedbl*/ N(10,270), /*numbersign*/ -N(6,438), /*dollar*/ -N(7,245), /*percent*/ +N(6,444), /*dollar*/ +N(7,280), /*percent*/ N(9,72), /*ampersand*/ N(10,300), /*quoteright*/ N(9,369), /*parenleft*/ N(10,290), /*parenright*/ -N(8,48), /*asterisk*/ -N(4,456), /*plus*/ -N(5,95), /*comma*/ -N(6,492), /*hyphen*/ -N(6,600), /*period*/ -N(5,160), /*slash*/ -N(4,464), /*zero*/ +N(8,56), /*asterisk*/ +N(4,464), /*plus*/ +N(5,110), /*comma*/ +N(6,498), /*hyphen*/ +N(6,606), /*period*/ +N(5,175), /*slash*/ +N(4,472), /*zero*/ N(3,276), /*one*/ N(3,294), /*two*/ -N(5,185), /*three*/ -N(4,436), /*four*/ -N(4,432), /*five*/ +N(5,200), /*three*/ +N(4,444), /*four*/ +N(4,440), /*five*/ N(3,288), /*six*/ -N(5,150), /*seven*/ -N(5,105), /*eight*/ -N(4,448), /*nine*/ -N(5,90), /*colon*/ +N(5,165), /*seven*/ +N(5,120), /*eight*/ +N(4,456), /*nine*/ +N(5,105), /*colon*/ N(9,414), /*semicolon*/ -N(4,444), /*less*/ -N(5,110), /*equal*/ -N(7,189), /*greater*/ -N(8,160), /*question*/ +N(4,452), /*less*/ +N(5,125), /*equal*/ +N(7,224), /*greater*/ +N(8,168), /*question*/ N(2,34), /*at*/ N(1,0), /*A*/ N(1,1), /*B*/ @@ -5263,13 +5275,13 @@ N(3,255), /*bar*/ N(10,140), /*braceright*/ N(10,130), /*asciitilde*/ N(10,180), /*exclamdown*/ -N(4,424), /*cent*/ -N(8,184), /*sterling*/ -N(8,104), /*fraction*/ +N(4,432), /*cent*/ +N(8,192), /*sterling*/ +N(8,112), /*fraction*/ N(3,297), /*yen*/ -N(6,480), /*florin*/ -N(7,266), /*section*/ -N(8,64), /*currency*/ +N(6,486), /*florin*/ +N(7,301), /*section*/ +N(8,72), /*currency*/ N(11,539), /*quotesingle*/ N(12,528), /*quotedblleft*/ N(13,208), /*guillemotleft*/ @@ -5277,43 +5289,43 @@ N(13,221), /*guilsinglleft*/ N(14,252), /*guilsinglright*/ N(2,38), /*fi*/ N(2,40), /*fl*/ -N(6,468), /*endash*/ -N(6,408), /*dagger*/ +N(6,474), /*endash*/ +N(6,414), /*dagger*/ N(9,189), /*daggerdbl*/ N(14,308), /*periodcentered*/ N(9,360), /*paragraph*/ -N(6,390), /*bullet*/ +N(6,396), /*bullet*/ N(14,364), /*quotesinglbase*/ N(12,516), /*quotedblbase*/ N(13,273), /*quotedblright*/ N(14,238), /*guillemotright*/ -N(8,88), /*ellipsis*/ +N(8,96), /*ellipsis*/ N(11,528), /*perthousand*/ N(12,504), /*questiondown*/ -N(5,125), /*grave*/ -N(5,55), /*acute*/ +N(5,140), /*grave*/ +N(5,70), /*acute*/ N(10,160), /*circumflex*/ -N(5,190), /*tilde*/ -N(6,534), /*macron*/ -N(5,80), /*breve*/ +N(5,205), /*tilde*/ +N(6,540), /*macron*/ +N(5,95), /*breve*/ N(9,198), /*dotaccent*/ -N(8,72), /*dieresis*/ -N(4,460), /*ring*/ -N(7,133), /*cedilla*/ +N(8,80), /*dieresis*/ +N(4,468), /*ring*/ +N(7,168), /*cedilla*/ N(12,336), /*hungarumlaut*/ -N(6,570), /*ogonek*/ -N(5,85), /*caron*/ -N(6,462), /*emdash*/ +N(6,576), /*ogonek*/ +N(5,100), /*caron*/ +N(6,468), /*emdash*/ N(2,0), /*AE*/ N(11,473), /*ordfeminine*/ N(6,168), /*Lslash*/ -N(6,222), /*Oslash*/ +N(6,228), /*Oslash*/ N(2,8), /*OE*/ N(12,432), /*ordmasculine*/ N(2,32), /*ae*/ -N(8,80), /*dotlessi*/ -N(6,528), /*lslash*/ -N(6,588), /*oslash*/ +N(8,88), /*dotlessi*/ +N(6,534), /*lslash*/ +N(6,594), /*oslash*/ N(2,46), /*oe*/ N(10,200), /*germandbls*/ N(11,462), /*onesuperior*/ @@ -5321,20 +5333,20 @@ N(10,250), /*logicalnot*/ N(2,42), /*mu*/ N(9,450), /*trademark*/ N(3,6), /*Eth*/ -N(7,238), /*onehalf*/ +N(7,273), /*onehalf*/ N(9,378), /*plusminus*/ -N(5,45), /*Thorn*/ +N(5,60), /*Thorn*/ N(10,280), /*onequarter*/ -N(6,432), /*divide*/ +N(6,438), /*divide*/ N(9,153), /*brokenbar*/ -N(6,426), /*degree*/ -N(5,180), /*thorn*/ +N(6,432), /*degree*/ +N(5,195), /*thorn*/ N(13,364), /*threequarters*/ N(11,605), /*twosuperior*/ N(10,310), /*registered*/ -N(5,140), /*minus*/ +N(5,155), /*minus*/ N(3,264), /*eth*/ -N(8,136), /*multiply*/ +N(8,144), /*multiply*/ N(13,377), /*threesuperior*/ N(9,180), /*copyright*/ N(6,0), /*Aacute*/ @@ -5352,49 +5364,49 @@ N(6,120), /*Iacute*/ N(11,88), /*Icircumflex*/ N(9,18), /*Idieresis*/ N(6,126), /*Igrave*/ -N(6,204), /*Ntilde*/ -N(6,210), /*Oacute*/ +N(6,210), /*Ntilde*/ +N(6,216), /*Oacute*/ N(11,154), /*Ocircumflex*/ N(9,27), /*Odieresis*/ -N(6,216), /*Ograve*/ -N(6,234), /*Otilde*/ -N(6,276), /*Scaron*/ -N(6,300), /*Uacute*/ +N(6,222), /*Ograve*/ +N(6,240), /*Otilde*/ +N(6,282), /*Scaron*/ +N(6,306), /*Uacute*/ N(11,231), /*Ucircumflex*/ N(9,45), /*Udieresis*/ -N(6,306), /*Ugrave*/ -N(6,336), /*Yacute*/ +N(6,312), /*Ugrave*/ +N(6,342), /*Yacute*/ N(9,54), /*Ydieresis*/ -N(6,354), /*Zcaron*/ -N(6,366), /*aacute*/ +N(6,360), /*Zcaron*/ +N(6,372), /*aacute*/ N(11,275), /*acircumflex*/ N(9,63), /*adieresis*/ -N(6,378), /*agrave*/ -N(5,75), /*aring*/ -N(6,384), /*atilde*/ -N(8,56), /*ccedilla*/ -N(6,444), /*eacute*/ +N(6,384), /*agrave*/ +N(5,90), /*aring*/ +N(6,390), /*atilde*/ +N(8,64), /*ccedilla*/ +N(6,450), /*eacute*/ N(11,363), /*ecircumflex*/ N(9,216), /*edieresis*/ -N(6,456), /*egrave*/ -N(6,498), /*iacute*/ +N(6,462), /*egrave*/ +N(6,504), /*iacute*/ N(11,418), /*icircumflex*/ N(9,234), /*idieresis*/ -N(6,504), /*igrave*/ -N(6,558), /*ntilde*/ -N(6,564), /*oacute*/ +N(6,510), /*igrave*/ +N(6,564), /*ntilde*/ +N(6,570), /*oacute*/ N(11,429), /*ocircumflex*/ N(9,315), /*odieresis*/ -N(6,576), /*ograve*/ -N(6,594), /*otilde*/ -N(6,630), /*scaron*/ -N(6,660), /*uacute*/ +N(6,582), /*ograve*/ +N(6,600), /*otilde*/ +N(6,636), /*scaron*/ +N(6,666), /*uacute*/ N(11,616), /*ucircumflex*/ N(9,477), /*udieresis*/ -N(6,666), /*ugrave*/ -N(6,672), /*yacute*/ +N(6,672), /*ugrave*/ +N(6,678), /*yacute*/ N(9,495), /*ydieresis*/ -N(6,684), /*zcaron*/ +N(6,690), /*zcaron*/ N(11,385), /*exclamsmall*/ N(17,0), /*Hungarumlautsmall*/ N(14,210), /*dollaroldstyle*/ @@ -5452,23 +5464,23 @@ N(6,132), /*Ismall*/ N(6,138), /*Jsmall*/ N(6,144), /*Ksmall*/ N(6,174), /*Lsmall*/ -N(6,180), /*Msmall*/ -N(6,198), /*Nsmall*/ -N(6,228), /*Osmall*/ -N(6,240), /*Psmall*/ -N(6,246), /*Qsmall*/ -N(6,264), /*Rsmall*/ -N(6,282), /*Ssmall*/ -N(6,294), /*Tsmall*/ -N(6,312), /*Usmall*/ -N(6,318), /*Vsmall*/ -N(6,324), /*Wsmall*/ -N(6,330), /*Xsmall*/ -N(6,342), /*Ysmall*/ -N(6,360), /*Zsmall*/ +N(6,186), /*Msmall*/ +N(6,204), /*Nsmall*/ +N(6,234), /*Osmall*/ +N(6,246), /*Psmall*/ +N(6,252), /*Qsmall*/ +N(6,270), /*Rsmall*/ +N(6,288), /*Ssmall*/ +N(6,300), /*Tsmall*/ +N(6,318), /*Usmall*/ +N(6,324), /*Vsmall*/ +N(6,330), /*Wsmall*/ +N(6,336), /*Xsmall*/ +N(6,348), /*Ysmall*/ +N(6,366), /*Zsmall*/ N(13,117), /*colonmonetary*/ N(9,333), /*onefitted*/ -N(6,618), /*rupiah*/ +N(6,624), /*rupiah*/ N(10,80), /*Tildesmall*/ N(15,15), /*exclamdownsmall*/ N(12,216), /*centoldstyle*/ @@ -5490,7 +5502,7 @@ N(9,324), /*oneeighth*/ N(12,612), /*threeeighths*/ N(11,407), /*fiveeighths*/ N(12,588), /*seveneighths*/ -N(8,152), /*onethird*/ +N(8,160), /*onethird*/ N(9,468), /*twothirds*/ N(12,648), /*zerosuperior*/ N(12,300), /*foursuperior*/ @@ -5519,7 +5531,7 @@ N(16,0), /*Acircumflexsmall*/ N(11,33), /*Atildesmall*/ N(14,0), /*Adieresissmall*/ N(10,10), /*Aringsmall*/ -N(7,7), /*AEsmall*/ +N(7,35), /*AEsmall*/ N(13,0), /*Ccedillasmall*/ N(11,66), /*Egravesmall*/ N(11,44), /*Eacutesmall*/ @@ -5536,7 +5548,7 @@ N(11,143), /*Oacutesmall*/ N(16,48), /*Ocircumflexsmall*/ N(11,198), /*Otildesmall*/ N(14,56), /*Odieresissmall*/ -N(7,63), /*OEsmall*/ +N(7,91), /*OEsmall*/ N(11,187), /*Oslashsmall*/ N(11,242), /*Ugravesmall*/ N(11,220), /*Uacutesmall*/ @@ -5545,6 +5557,18 @@ N(14,70), /*Udieresissmall*/ N(11,253), /*Yacutesmall*/ N(10,70), /*Thornsmall*/ N(14,84), /*Ydieresissmall*/ +N(7,7), /*001.000*/ +N(7,14), /*001.001*/ +N(7,21), /*001.002*/ +N(7,28), /*001.003*/ +N(5,15), /*Black*/ +N(4,4), /*Bold*/ +N(4,8), /*Book*/ +N(5,35), /*Light*/ +N(6,180), /*Medium*/ +N(7,112), /*Regular*/ +N(5,45), /*Roman*/ +N(8,40), /*Semibold*/ 0}; static const ushort gs_c_known_encoding_reverse_10[] = { 34, /* N(1,0): A*/ @@ -5566,13 +5590,15 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 36, /* N(1,2): C*/ 37, /* N(1,3): D*/ 38, /* N(1,4): E*/ +384, /* N(4,4): Bold*/ 39, /* N(1,5): F*/ 40, /* N(1,6): G*/ 154, /* N(3,6): Eth*/ 41, /* N(1,7): H*/ -353, /* N(7,7): AEsmall*/ +379, /* N(7,7): 001.000*/ 42, /* N(1,8): I*/ 142, /* N(2,8): OE*/ +385, /* N(4,8): Book*/ 363, /* N(8,8): Ethsmall*/ 43, /* N(1,9): J*/ 180, /* N(9,9): Edieresis*/ @@ -5586,8 +5612,10 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 47, /* N(1,13): N*/ 309, /* N(13,13): Dieresissmall*/ 48, /* N(1,14): O*/ +380, /* N(7,14): 001.001*/ 312, /* N(14,14): Dotaccentsmall*/ 49, /* N(1,15): P*/ +383, /* N(5,15): Black*/ 304, /* N(15,15): exclamdownsmall*/ 50, /* N(1,16): Q*/ 357, /* N(16,16): Ecircumflexsmall*/ @@ -5601,6 +5629,7 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 54, /* N(1,20): U*/ 310, /* N(10,20): Brevesmall*/ 55, /* N(1,21): V*/ +381, /* N(7,21): 001.002*/ 56, /* N(1,22): W*/ 347, /* N(11,22): Agravesmall*/ 57, /* N(1,23): X*/ @@ -5611,6 +5640,7 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 67, /* N(1,27): b*/ 189, /* N(9,27): Odieresis*/ 68, /* N(1,28): c*/ +382, /* N(7,28): 001.003*/ 358, /* N(14,28): Edieresissmall*/ 69, /* N(1,29): d*/ 70, /* N(1,30): e*/ @@ -5626,6 +5656,8 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 33, /* N(2,34): at*/ 235, /* N(17,34): parenleftsuperior*/ 75, /* N(1,35): j*/ +386, /* N(5,35): Light*/ +353, /* N(7,35): AEsmall*/ 76, /* N(1,36): k*/ 266, /* N(2,36): ff*/ 317, /* N(9,36): Ringsmall*/ @@ -5635,6 +5667,7 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 79, /* N(1,39): n*/ 80, /* N(1,40): o*/ 110, /* N(2,40): fl*/ +390, /* N(8,40): Semibold*/ 81, /* N(1,41): p*/ 82, /* N(1,42): q*/ 152, /* N(2,42): mu*/ @@ -5643,14 +5676,13 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 84, /* N(1,44): s*/ 356, /* N(11,44): Eacutesmall*/ 85, /* N(1,45): t*/ -157, /* N(5,45): Thorn*/ +389, /* N(5,45): Roman*/ 195, /* N(9,45): Udieresis*/ 86, /* N(1,46): u*/ 148, /* N(2,46): oe*/ 87, /* N(1,47): v*/ 88, /* N(1,48): w*/ 276, /* N(6,48): Csmall*/ -11, /* N(8,48): asterisk*/ 367, /* N(16,48): Ocircumflexsmall*/ 89, /* N(1,49): x*/ 90, /* N(1,50): y*/ @@ -5658,125 +5690,127 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 91, /* N(1,51): z*/ 319, /* N(17,51): questiondownsmall*/ 198, /* N(9,54): Ydieresis*/ -125, /* N(5,55): acute*/ 179, /* N(11,55): Ecircumflex*/ -206, /* N(8,56): ccedilla*/ +11, /* N(8,56): asterisk*/ 369, /* N(14,56): Odieresissmall*/ -370, /* N(7,63): OEsmall*/ +157, /* N(5,60): Thorn*/ 202, /* N(9,63): adieresis*/ -103, /* N(8,64): currency*/ +206, /* N(8,64): ccedilla*/ 374, /* N(16,64): Ucircumflexsmall*/ 277, /* N(6,66): Dsmall*/ 355, /* N(11,66): Egravesmall*/ +125, /* N(5,70): acute*/ 377, /* N(10,70): Thornsmall*/ 375, /* N(14,70): Udieresissmall*/ 178, /* N(6,72): Eacute*/ -131, /* N(8,72): dieresis*/ +103, /* N(8,72): currency*/ 7, /* N(9,72): ampersand*/ -204, /* N(5,75): aring*/ 360, /* N(11,77): Iacutesmall*/ -129, /* N(5,80): breve*/ -145, /* N(8,80): dotlessi*/ +131, /* N(8,80): dieresis*/ 303, /* N(10,80): Tildesmall*/ 181, /* N(6,84): Egrave*/ 378, /* N(14,84): Ydieresissmall*/ -136, /* N(5,85): caron*/ -121, /* N(8,88): ellipsis*/ +145, /* N(8,88): dotlessi*/ 183, /* N(11,88): Icircumflex*/ -27, /* N(5,90): colon*/ +204, /* N(5,90): aring*/ 278, /* N(6,90): Esmall*/ -13, /* N(5,95): comma*/ +370, /* N(7,91): OEsmall*/ +129, /* N(5,95): breve*/ 279, /* N(6,96): Fsmall*/ +121, /* N(8,96): ellipsis*/ 233, /* N(14,98): ampersandsmall*/ 359, /* N(11,99): Igravesmall*/ -99, /* N(8,104): fraction*/ -25, /* N(5,105): eight*/ +136, /* N(5,100): caron*/ +27, /* N(5,105): colon*/ 280, /* N(6,108): Gsmall*/ -30, /* N(5,110): equal*/ +13, /* N(5,110): comma*/ 306, /* N(11,110): Lslashsmall*/ +388, /* N(7,112): Regular*/ +99, /* N(8,112): fraction*/ 281, /* N(6,114): Hsmall*/ 300, /* N(13,117): colonmonetary*/ +25, /* N(5,120): eight*/ 182, /* N(6,120): Iacute*/ 313, /* N(11,121): Macronsmall*/ -124, /* N(5,125): grave*/ +30, /* N(5,125): equal*/ 185, /* N(6,126): Igrave*/ 253, /* N(9,126): asuperior*/ 95, /* N(10,130): asciitilde*/ 346, /* N(13,130): commainferior*/ 282, /* N(6,132): Ismall*/ 364, /* N(11,132): Ntildesmall*/ -133, /* N(7,133): cedilla*/ 61, /* N(9,135): backslash*/ -168, /* N(8,136): multiply*/ 283, /* N(6,138): Jsmall*/ -166, /* N(5,140): minus*/ +124, /* N(5,140): grave*/ 94, /* N(10,140): braceright*/ 366, /* N(11,143): Oacutesmall*/ 249, /* N(13,143): commasuperior*/ 284, /* N(6,144): Ksmall*/ +168, /* N(8,144): multiply*/ 92, /* N(9,144): braceleft*/ -24, /* N(5,150): seven*/ -324, /* N(8,152): onethird*/ 160, /* N(9,153): brokenbar*/ 188, /* N(11,154): Ocircumflex*/ -16, /* N(5,160): slash*/ -32, /* N(8,160): question*/ +166, /* N(5,155): minus*/ +324, /* N(8,160): onethird*/ 126, /* N(10,160): circumflex*/ 254, /* N(9,162): bsuperior*/ -1, /* N(5,165): space*/ +24, /* N(5,165): seven*/ 316, /* N(11,165): Ogoneksmall*/ 140, /* N(6,168): Lslash*/ -3, /* N(8,168): quotedbl*/ +133, /* N(7,168): cedilla*/ +32, /* N(8,168): question*/ 341, /* N(13,169): eightinferior*/ 285, /* N(6,174): Lsmall*/ +16, /* N(5,175): slash*/ +3, /* N(8,176): quotedbl*/ 365, /* N(11,176): Ogravesmall*/ -162, /* N(5,180): thorn*/ -286, /* N(6,180): Msmall*/ +1, /* N(5,180): space*/ +387, /* N(6,180): Medium*/ 170, /* N(9,180): copyright*/ 96, /* N(10,180): exclamdown*/ 247, /* N(13,182): eightoldstyle*/ -98, /* N(8,184): sterling*/ -20, /* N(5,185): three*/ +286, /* N(6,186): Msmall*/ 371, /* N(11,187): Oslashsmall*/ -31, /* N(7,189): greater*/ 113, /* N(9,189): daggerdbl*/ -127, /* N(5,190): tilde*/ 314, /* N(10,190): figuredash*/ +98, /* N(8,192): sterling*/ 62, /* N(12,192): bracketright*/ +162, /* N(5,195): thorn*/ 331, /* N(13,195): eightsuperior*/ 344, /* N(14,196): dollarinferior*/ -287, /* N(6,198): Nsmall*/ 130, /* N(9,198): dotaccent*/ 368, /* N(11,198): Otildesmall*/ +20, /* N(5,200): three*/ 149, /* N(10,200): germandbls*/ -186, /* N(6,204): Ntilde*/ +287, /* N(6,204): Nsmall*/ 343, /* N(12,204): centinferior*/ +127, /* N(5,205): tilde*/ 256, /* N(9,207): dsuperior*/ 106, /* N(13,208): guillemotleft*/ 307, /* N(11,209): Scaronsmall*/ -187, /* N(6,210): Oacute*/ +186, /* N(6,210): Ntilde*/ 231, /* N(14,210): dollaroldstyle*/ -190, /* N(6,216): Ograve*/ +187, /* N(6,216): Oacute*/ 209, /* N(9,216): edieresis*/ 305, /* N(12,216): centoldstyle*/ 373, /* N(11,220): Uacutesmall*/ 107, /* N(13,221): guilsinglleft*/ -141, /* N(6,222): Oslash*/ +190, /* N(6,222): Ograve*/ +31, /* N(7,224): greater*/ 232, /* N(14,224): dollarsuperior*/ 257, /* N(9,225): esuperior*/ -288, /* N(6,228): Osmall*/ +141, /* N(6,228): Oslash*/ 255, /* N(12,228): centsuperior*/ 194, /* N(11,231): Ucircumflex*/ -191, /* N(6,234): Otilde*/ +288, /* N(6,234): Osmall*/ 213, /* N(9,234): idieresis*/ -155, /* N(7,238): onehalf*/ 120, /* N(14,238): guillemotright*/ -289, /* N(6,240): Psmall*/ +191, /* N(6,240): Otilde*/ 338, /* N(12,240): fiveinferior*/ 372, /* N(11,242): Ugravesmall*/ -6, /* N(7,245): percent*/ -290, /* N(6,246): Qsmall*/ +289, /* N(6,246): Psmall*/ 151, /* N(10,250): logicalnot*/ +290, /* N(6,252): Qsmall*/ 258, /* N(9,252): isuperior*/ 244, /* N(12,252): fiveoldstyle*/ 108, /* N(14,252): guilsinglright*/ @@ -5784,147 +5818,149 @@ static const ushort gs_c_known_encoding_reverse_10[] = { 93, /* N(3,255): bar*/ 252, /* N(13,260): questionsmall*/ 167, /* N(3,264): eth*/ -291, /* N(6,264): Rsmall*/ 308, /* N(11,264): Zcaronsmall*/ 328, /* N(12,264): fivesuperior*/ -102, /* N(7,266): section*/ 315, /* N(14,266): hypheninferior*/ 267, /* N(3,267): ffi*/ 268, /* N(3,270): ffl*/ +291, /* N(6,270): Rsmall*/ 4, /* N(10,270): numbersign*/ +155, /* N(7,273): onehalf*/ 119, /* N(13,273): quotedblright*/ 201, /* N(11,275): acircumflex*/ 18, /* N(3,276): one*/ -192, /* N(6,276): Scaron*/ 337, /* N(12,276): fourinferior*/ 259, /* N(9,279): lsuperior*/ +6, /* N(7,280): percent*/ 158, /* N(10,280): onequarter*/ 272, /* N(14,280): hyphensuperior*/ -292, /* N(6,282): Ssmall*/ +192, /* N(6,282): Scaron*/ 23, /* N(3,288): six*/ +292, /* N(6,288): Ssmall*/ 260, /* N(9,288): msuperior*/ 243, /* N(12,288): fouroldstyle*/ 10, /* N(10,290): parenright*/ 19, /* N(3,294): two*/ -293, /* N(6,294): Tsmall*/ 238, /* N(14,294): onedotenleader*/ 100, /* N(3,297): yen*/ 340, /* N(13,299): seveninferior*/ -193, /* N(6,300): Uacute*/ +293, /* N(6,300): Tsmall*/ 8, /* N(10,300): quoteright*/ 327, /* N(12,300): foursuperior*/ -196, /* N(6,306): Ugrave*/ +102, /* N(7,301): section*/ +193, /* N(6,306): Uacute*/ 261, /* N(9,306): nsuperior*/ 63, /* N(11,308): asciicircum*/ 114, /* N(14,308): periodcentered*/ 165, /* N(10,310): registered*/ -294, /* N(6,312): Usmall*/ +196, /* N(6,312): Ugrave*/ 246, /* N(13,312): sevenoldstyle*/ 218, /* N(9,315): odieresis*/ -295, /* N(6,318): Vsmall*/ +294, /* N(6,318): Usmall*/ 64, /* N(10,320): underscore*/ 345, /* N(14,322): periodinferior*/ -296, /* N(6,324): Wsmall*/ +295, /* N(6,324): Vsmall*/ 320, /* N(9,324): oneeighth*/ 330, /* N(13,325): sevensuperior*/ -297, /* N(6,330): Xsmall*/ +296, /* N(6,330): Wsmall*/ 301, /* N(9,333): onefitted*/ -197, /* N(6,336): Yacute*/ +297, /* N(6,336): Xsmall*/ 134, /* N(12,336): hungarumlaut*/ 251, /* N(14,336): periodsuperior*/ 336, /* N(13,338): threeinferior*/ 60, /* N(11,341): bracketleft*/ -298, /* N(6,342): Ysmall*/ +197, /* N(6,342): Yacute*/ 262, /* N(9,342): osuperior*/ +298, /* N(6,348): Ysmall*/ 242, /* N(13,351): threeoldstyle*/ -199, /* N(6,354): Zcaron*/ -299, /* N(6,360): Zsmall*/ +199, /* N(6,360): Zcaron*/ 115, /* N(9,360): paragraph*/ 208, /* N(11,363): ecircumflex*/ 163, /* N(13,364): threequarters*/ 117, /* N(14,364): quotesinglbase*/ -200, /* N(6,366): aacute*/ +299, /* N(6,366): Zsmall*/ 9, /* N(9,369): parenleft*/ +200, /* N(6,372): aacute*/ 169, /* N(13,377): threesuperior*/ -203, /* N(6,378): agrave*/ 156, /* N(9,378): plusminus*/ -205, /* N(6,384): atilde*/ +203, /* N(6,384): agrave*/ 229, /* N(11,385): exclamsmall*/ 65, /* N(9,387): quoteleft*/ -116, /* N(6,390): bullet*/ +205, /* N(6,390): atilde*/ +116, /* N(6,396): bullet*/ 342, /* N(12,396): nineinferior*/ 263, /* N(9,405): rsuperior*/ 237, /* N(14,406): twodotenleader*/ 322, /* N(11,407): fiveeighths*/ -112, /* N(6,408): dagger*/ 248, /* N(12,408): nineoldstyle*/ +112, /* N(6,414): dagger*/ 28, /* N(9,414): semicolon*/ 212, /* N(11,418): icircumflex*/ 332, /* N(12,420): ninesuperior*/ 264, /* N(9,423): ssuperior*/ -97, /* N(4,424): cent*/ -161, /* N(6,426): degree*/ 217, /* N(11,429): ocircumflex*/ -22, /* N(4,432): five*/ -159, /* N(6,432): divide*/ +97, /* N(4,432): cent*/ +161, /* N(6,432): degree*/ 143, /* N(12,432): ordmasculine*/ -21, /* N(4,436): four*/ -5, /* N(6,438): dollar*/ +159, /* N(6,438): divide*/ +22, /* N(4,440): five*/ 334, /* N(11,440): oneinferior*/ -29, /* N(4,444): less*/ -207, /* N(6,444): eacute*/ -26, /* N(4,448): nine*/ +21, /* N(4,444): four*/ +5, /* N(6,444): dollar*/ +207, /* N(6,450): eacute*/ 153, /* N(9,450): trademark*/ 240, /* N(11,451): oneoldstyle*/ -12, /* N(4,456): plus*/ -210, /* N(6,456): egrave*/ +29, /* N(4,452): less*/ +26, /* N(4,456): nine*/ 265, /* N(9,459): tsuperior*/ -132, /* N(4,460): ring*/ -137, /* N(6,462): emdash*/ +210, /* N(6,462): egrave*/ 150, /* N(11,462): onesuperior*/ -17, /* N(4,464): zero*/ -111, /* N(6,468): endash*/ +12, /* N(4,464): plus*/ +132, /* N(4,468): ring*/ +137, /* N(6,468): emdash*/ 325, /* N(9,468): twothirds*/ +17, /* N(4,472): zero*/ 139, /* N(11,473): ordfeminine*/ -2, /* N(6,474): exclam*/ +111, /* N(6,474): endash*/ 224, /* N(9,477): udieresis*/ -101, /* N(6,480): florin*/ -14, /* N(6,492): hyphen*/ +2, /* N(6,480): exclam*/ +101, /* N(6,486): florin*/ 227, /* N(9,495): ydieresis*/ -211, /* N(6,498): iacute*/ -214, /* N(6,504): igrave*/ +14, /* N(6,498): hyphen*/ +211, /* N(6,504): iacute*/ 123, /* N(12,504): questiondown*/ +214, /* N(6,510): igrave*/ 118, /* N(12,516): quotedblbase*/ -146, /* N(6,528): lslash*/ 122, /* N(11,528): perthousand*/ 105, /* N(12,528): quotedblleft*/ -128, /* N(6,534): macron*/ +146, /* N(6,534): lslash*/ 104, /* N(11,539): quotesingle*/ +128, /* N(6,540): macron*/ 339, /* N(11,550): sixinferior*/ -215, /* N(6,558): ntilde*/ 245, /* N(11,561): sixoldstyle*/ -216, /* N(6,564): oacute*/ -135, /* N(6,570): ogonek*/ +215, /* N(6,564): ntilde*/ +216, /* N(6,570): oacute*/ 329, /* N(11,572): sixsuperior*/ -219, /* N(6,576): ograve*/ +135, /* N(6,576): ogonek*/ +219, /* N(6,582): ograve*/ 335, /* N(11,583): twoinferior*/ -147, /* N(6,588): oslash*/ 323, /* N(12,588): seveneighths*/ -220, /* N(6,594): otilde*/ +147, /* N(6,594): oslash*/ 241, /* N(11,594): twooldstyle*/ -15, /* N(6,600): period*/ +220, /* N(6,600): otilde*/ 164, /* N(11,605): twosuperior*/ +15, /* N(6,606): period*/ 321, /* N(12,612): threeeighths*/ 223, /* N(11,616): ucircumflex*/ -302, /* N(6,618): rupiah*/ +302, /* N(6,624): rupiah*/ 333, /* N(12,624): zeroinferior*/ -221, /* N(6,630): scaron*/ +221, /* N(6,636): scaron*/ 239, /* N(12,636): zerooldstyle*/ 326, /* N(12,648): zerosuperior*/ -222, /* N(6,660): uacute*/ -225, /* N(6,666): ugrave*/ -226, /* N(6,672): yacute*/ -228, /* N(6,684): zcaron*/ +222, /* N(6,666): uacute*/ +225, /* N(6,672): ugrave*/ +226, /* N(6,678): yacute*/ +228, /* N(6,690): zcaron*/ 0}; const ushort *const gs_c_known_encodings[] = { @@ -5957,6 +5993,6 @@ const ushort *const gs_c_known_encodings_reverse[] = { }; const ushort gs_c_known_encoding_lengths[] = { -256,256,256,256,256,256,256,258,229,86,379,0}; +256,256,256,256,256,256,256,258,229,86,391,0}; const ushort gs_c_known_encoding_reverse_lengths[] = { -149,205,189,188,224,208,165,257,228,86,378,0}; +149,205,189,188,224,208,165,257,228,86,390,0}; diff --git a/base/gscedata.h b/base/gscedata.h index 4f67aac1..47c034c0 100644 --- a/base/gscedata.h +++ b/base/gscedata.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscencs.c b/base/gscencs.c index 2b05289c..6853a22d 100644 --- a/base/gscencs.c +++ b/base/gscencs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscencs.h b/base/gscencs.h index 6c0c4aad..565283da 100644 --- a/base/gscencs.h +++ b/base/gscencs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gschar.c b/base/gschar.c index c01019d8..a41b5802 100644 --- a/base/gschar.c +++ b/base/gschar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -187,7 +187,7 @@ show_n_begin(gs_show_enum *penum, gs_gstate *pgs, int code, gs_text_enum_t *pte) dev_proc_text_begin((*text_begin)) = dev_proc(dev, text_begin); text = pte->text; - gs_text_release(pte, "show_n_begin"); + gs_text_release(NULL, pte, "show_n_begin"); /* Temporarily reset the text_begin procedure to the default. */ set_dev_proc(dev, text_begin, gx_default_text_begin); code = gs_text_begin(pgs, &text, mem, &pte); diff --git a/base/gschar.h b/base/gschar.h index a856860b..6d60af99 100644 --- a/base/gschar.h +++ b/base/gschar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gschar0.c b/base/gschar0.c index 935d7c53..2a4f30ed 100644 --- a/base/gschar0.c +++ b/base/gschar0.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscicach.c b/base/gscicach.c index b524feb1..fb910cf5 100644 --- a/base/gscicach.c +++ b/base/gscicach.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -31,7 +31,7 @@ typedef struct gs_color_index_cache_elem_s gs_color_index_cache_elem_t; struct gs_color_index_cache_elem_s { union _color { gx_color_index cindex; - ushort devn[GS_CLIENT_COLOR_MAX_COMPONENTS]; + ushort devn[GS_CLIENT_COLOR_MAX_COMPONENTS]; } color; gx_device_color_type color_type; uint chain; @@ -189,7 +189,7 @@ include_into_touch_list(gs_color_index_cache_t *self, uint i) } static int -get_color_index_cache_elem(gs_color_index_cache_t *self, +get_color_index_cache_elem(gs_color_index_cache_t *self, const float *paint_values, uint *pi) { int client_num_components = self->client_num_components; @@ -199,7 +199,7 @@ get_color_index_cache_elem(gs_color_index_cache_t *self, if (i != MYNULL) { uint tries = 16; /* Arbitrary. */ - if (!memcmp(paint_values, self->paint_values + i * client_num_components, + if (!memcmp(paint_values, self->paint_values + i * client_num_components, sizeof(*paint_values) * client_num_components)) { if (self->recent_touch != i) { exclude_from_touch_list(self, i); @@ -209,7 +209,7 @@ get_color_index_cache_elem(gs_color_index_cache_t *self, return 1; } for (j = self->buf[i].next; tries -- && j != i; j = self->buf[j].next) { - if (!memcmp(paint_values, self->paint_values + j * client_num_components, + if (!memcmp(paint_values, self->paint_values + j * client_num_components, sizeof(*paint_values) * client_num_components)) { exclude_from_chain(self, j); include_into_chain(self, j, c); @@ -251,15 +251,15 @@ compute_frac_values(gs_color_index_cache_t *self, uint i) for (j = 0; j < device_num_components; j++) { int shift = cinfo->comp_shift[j]; int bits = cinfo->comp_bits[j]; - self->frac_values[i * device_num_components + j] = - ((c >> shift) & ((1 << bits) - 1)) << + self->frac_values[i * device_num_components + j] = + ((c >> shift) & ((1 << bits) - 1)) << (sizeof(frac31) * 8 - 1 - bits); } self->buf[i].frac_values_done = true; } else { /* Must be devn */ for (j = 0; j < device_num_components; j++) { - self->frac_values[i * device_num_components + j] = + self->frac_values[i * device_num_components + j] = cv2frac31(self->buf[i].color.devn[j]); } self->buf[i].frac_values_done = true; @@ -267,7 +267,7 @@ compute_frac_values(gs_color_index_cache_t *self, uint i) } int -gs_cached_color_index(gs_color_index_cache_t *self, const float *paint_values, +gs_cached_color_index(gs_color_index_cache_t *self, const float *paint_values, gx_device_color *pdevc, frac31 *frac_values) { /* Must return 2 if the color is not pure. @@ -283,7 +283,7 @@ gs_cached_color_index(gs_color_index_cache_t *self, const float *paint_values, if (self->buf[i].color_type == &gx_dc_type_data_pure) { pdevc->colors.pure = self->buf[i].color.cindex; pdevc->type = &gx_dc_type_data_pure; - memcpy(pdevc->ccolor.paint.values, paint_values, + memcpy(pdevc->ccolor.paint.values, paint_values, sizeof(*paint_values) * client_num_components); } else { /* devn case */ @@ -291,7 +291,7 @@ gs_cached_color_index(gs_color_index_cache_t *self, const float *paint_values, pdevc->colors.devn.values[j] = self->buf[i].color.devn[j]; } pdevc->type = &gx_dc_type_data_devn; - memcpy(pdevc->ccolor.paint.values, paint_values, + memcpy(pdevc->ccolor.paint.values, paint_values, sizeof(*paint_values) * client_num_components); } pdevc->ccolor_valid = true; @@ -304,11 +304,11 @@ gs_cached_color_index(gs_color_index_cache_t *self, const float *paint_values, if (pdevc == NULL) pdevc = &devc_local; - memcpy(self->paint_values + i * client_num_components, paint_values, + memcpy(self->paint_values + i * client_num_components, paint_values, sizeof(*paint_values) * client_num_components); - memcpy(fcc.paint.values, paint_values, + memcpy(fcc.paint.values, paint_values, sizeof(*paint_values) * client_num_components); - code = pcs->type->remap_color(&fcc, pcs, pdevc, self->pgs, + code = pcs->type->remap_color(&fcc, pcs, pdevc, self->pgs, self->trans_dev, gs_color_select_texture); if (code < 0) return code; @@ -328,7 +328,7 @@ gs_cached_color_index(gs_color_index_cache_t *self, const float *paint_values, self->buf[i].frac_values_done = false; } if (frac_values != NULL) - memcpy(frac_values, self->frac_values + i * device_num_components, + memcpy(frac_values, self->frac_values + i * device_num_components, sizeof(*frac_values) * device_num_components); return 0; } diff --git a/base/gscicach.h b/base/gscicach.h index de3f926f..51fb0b09 100644 --- a/base/gscicach.h +++ b/base/gscicach.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscie.c b/base/gscie.c index f7a45765..982b6b08 100644 --- a/base/gscie.c +++ b/base/gscie.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscie.h b/base/gscie.h index 9c022df2..77d082c9 100644 --- a/base/gscie.h +++ b/base/gscie.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsciemap.c b/base/gsciemap.c index 0374ca0e..43c162a8 100644 --- a/base/gsciemap.c +++ b/base/gsciemap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscindex.h b/base/gscindex.h index c45e168e..03af293f 100644 --- a/base/gscindex.h +++ b/base/gscindex.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsclipsr.c b/base/gsclipsr.c index a5d2e9bb..cb5c7343 100644 --- a/base/gsclipsr.c +++ b/base/gsclipsr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsclipsr.h b/base/gsclipsr.h index 88daa189..8d57562d 100644 --- a/base/gsclipsr.h +++ b/base/gsclipsr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscms.h b/base/gscms.h index dfface69..caedcb90 100644 --- a/base/gscms.h +++ b/base/gscms.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -86,7 +86,7 @@ typedef struct gsicc_bufferdesc_s { unsigned char bytes_per_chan; bool has_alpha; bool alpha_first; - bool little_endian; + bool endian_swap; bool is_planar; int plane_stride; int row_stride; @@ -264,6 +264,19 @@ struct gsicc_namelist_s { do our first mapping */ }; +/* Overprint (overprint_control) + * /enable is the default + * /disable turns off overprint + * /simulate performs overprint simulation for all devices + */ +typedef enum { + gs_overprint_control_enable = 0, /* Overprint for CMYK devices (default) */ + gs_overprint_control_disable = 1, /* No overprint for any devices */ + gs_overprint_control_simulate = 2 /* Simulate overprint for RGB and Gray devices */ +} gs_overprint_control_t; +#define gs_overprint_control_names\ + "enable", "disable", "simulate" + /* Destination profiles for different objects */ struct cmm_dev_profile_s { cmm_profile_t *device_profile[NUM_DEVICE_PROFILES]; @@ -277,8 +290,9 @@ struct cmm_dev_profile_s { bool graydetection; /* Device param for monitoring for gray only page */ bool pageneutralcolor; /* Only valid if graydetection true */ bool usefastcolor; /* Used when we want to use no cm */ + bool blacktext; /* Force text to be pure black */ bool supports_devn; /* If the target handles devn colors */ - bool sim_overprint; /* Indicates we want to do overprint blending */ + gs_overprint_control_t overprint_control; /* enable is the default */ gsicc_namelist_t *spotnames; /* If our device profiles are devn */ bool prebandthreshold; /* Used to indicate use of HT pre-clist */ gs_memory_t *memory; diff --git a/base/gscolor.c b/base/gscolor.c index 477b7648..74b80a48 100644 --- a/base/gscolor.c +++ b/base/gscolor.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscolor.h b/base/gscolor.h index a330a8e3..78d233f9 100644 --- a/base/gscolor.h +++ b/base/gscolor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscolor1.c b/base/gscolor1.c index 9ba3da02..3c3cf387 100644 --- a/base/gscolor1.c +++ b/base/gscolor1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscolor1.h b/base/gscolor1.h index 573d4c82..08c920dd 100644 --- a/base/gscolor1.h +++ b/base/gscolor1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscolor2.c b/base/gscolor2.c index 08bdfc27..85238bf4 100644 --- a/base/gscolor2.c +++ b/base/gscolor2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -218,7 +218,7 @@ const gs_color_space_type gs_color_space_type_Indexed = { }; /* To keep things vectorized and avoid an if test during the remap proc we - have another set of procedures to use for indexed color spaces when + have another set of procedures to use for indexed color spaces when someone has specified a named color profile and the base space of the index color space is DeviceN or Separation */ const gs_color_space_type gs_color_space_type_Indexed_Named = { diff --git a/base/gscolor2.h b/base/gscolor2.h index 939630e7..8a05fb3a 100644 --- a/base/gscolor2.h +++ b/base/gscolor2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscolor3.c b/base/gscolor3.c index f63161c3..66cadecd 100644 --- a/base/gscolor3.c +++ b/base/gscolor3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscolor3.h b/base/gscolor3.h index 116fe1be..27dc4ce8 100644 --- a/base/gscolor3.h +++ b/base/gscolor3.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscompt.h b/base/gscompt.h index 191708f1..861cc0a9 100644 --- a/base/gscompt.h +++ b/base/gscompt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscoord.c b/base/gscoord.c index e5e8cc82..8343a091 100644 --- a/base/gscoord.c +++ b/base/gscoord.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscoord.h b/base/gscoord.h index df8b0d3d..0c18f6c6 100644 --- a/base/gscoord.h +++ b/base/gscoord.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscparam.c b/base/gscparam.c index 6fc65582..1b4522a8 100644 --- a/base/gscparam.c +++ b/base/gscparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscpixel.c b/base/gscpixel.c index 345a191a..e1855c61 100644 --- a/base/gscpixel.c +++ b/base/gscpixel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscpixel.h b/base/gscpixel.h index 7edc14ca..7a340c3e 100644 --- a/base/gscpixel.h +++ b/base/gscpixel.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscpm.h b/base/gscpm.h index 6e9bff0a..fb0d338a 100644 --- a/base/gscpm.h +++ b/base/gscpm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscrd.c b/base/gscrd.c index 5ab156cc..f5dc5289 100644 --- a/base/gscrd.c +++ b/base/gscrd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscrd.h b/base/gscrd.h index b8ba96bc..9e645fae 100644 --- a/base/gscrd.h +++ b/base/gscrd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscrdp.c b/base/gscrdp.c index 119558f5..c3521a3f 100644 --- a/base/gscrdp.c +++ b/base/gscrdp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscrdp.h b/base/gscrdp.h index 549e6f08..c07df47d 100644 --- a/base/gscrdp.h +++ b/base/gscrdp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscrypt1.c b/base/gscrypt1.c index 2b464700..03caecbb 100644 --- a/base/gscrypt1.c +++ b/base/gscrypt1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscrypt1.h b/base/gscrypt1.h index 6072239e..eb9cfaa0 100644 --- a/base/gscrypt1.h +++ b/base/gscrypt1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscscie.c b/base/gscscie.c index 76824cac..3bc94aed 100644 --- a/base/gscscie.c +++ b/base/gscscie.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscsel.h b/base/gscsel.h index 1642ffd7..7f6dd127 100644 --- a/base/gscsel.h +++ b/base/gscsel.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscsepr.c b/base/gscsepr.c index 5afa4dea..34118988 100644 --- a/base/gscsepr.c +++ b/base/gscsepr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscsepr.h b/base/gscsepr.h index 790443be..e4268c28 100644 --- a/base/gscsepr.h +++ b/base/gscsepr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscspace.c b/base/gscspace.c index e847b383..81baac9a 100644 --- a/base/gscspace.c +++ b/base/gscspace.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -429,6 +429,15 @@ void cs_adjust_counts_icc(gs_gstate *pgs, int delta) } } +void cs_adjust_swappedcounts_icc(gs_gstate *pgs, int delta) +{ + gs_color_space *pcs = gs_swappedcolorspace_inline(pgs); + + if (pcs) { + cs_adjust_swappedcounts(pgs, delta); + } +} + /* ------ Other implementation procedures ------ */ /* Null color space installation procedure. */ @@ -497,7 +506,7 @@ gx_set_no_overprint(gs_gstate* pgs) /* Retain all the spot colorants and not the process colorants. This occurs if we have a process color - mismatch between the source and the destination but + mismatch between the source and the destination but the output device supports spot colors */ int gx_set_spot_only_overprint(gs_gstate* pgs) @@ -597,25 +606,25 @@ check_cmyk_color_model_comps(gx_device * dev) dev, "Cyan", sizeof("Cyan") - 1, - NO_COMP_NAME_TYPE )) < 0 || + NO_COMP_NAME_TYPE_OP)) < 0 || cyan_c == GX_DEVICE_COLOR_MAX_COMPONENTS || (magenta_c = dev_proc(dev, get_color_comp_index)( dev, "Magenta", sizeof("Magenta") - 1, - NO_COMP_NAME_TYPE )) < 0 || + NO_COMP_NAME_TYPE_OP)) < 0 || magenta_c == GX_DEVICE_COLOR_MAX_COMPONENTS || (yellow_c = dev_proc(dev, get_color_comp_index)( dev, "Yellow", sizeof("Yellow") - 1, - NO_COMP_NAME_TYPE )) < 0 || + NO_COMP_NAME_TYPE_OP)) < 0 || yellow_c == GX_DEVICE_COLOR_MAX_COMPONENTS || (black_c = dev_proc(dev, get_color_comp_index)( dev, "Black", sizeof("Black") - 1, - NO_COMP_NAME_TYPE )) < 0 || + NO_COMP_NAME_TYPE_OP)) < 0 || black_c == GX_DEVICE_COLOR_MAX_COMPONENTS ) return 0; @@ -724,8 +733,7 @@ int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_gstate * pgs) /* correct for any zero'ed color components. But only if profiles match AND pgs->overprint_mode is true */ if (pcs->cmm_icc_profile_data != NULL && output_profile != NULL) { - if (output_profile->hashcode == - pcs->cmm_icc_profile_data->hashcode) { + if (gsicc_profiles_equal(output_profile, pcs->cmm_icc_profile_data)) { profile_ok = true; } } @@ -759,13 +767,13 @@ int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_gstate * pgs) space has to be CMYK. Trick is that we do need to worry about the colorant order on the target device */ num_colorant[0] = (dev_proc(dev, get_color_comp_index))\ - (dev, "Cyan", strlen("Cyan"), NO_COMP_NAME_TYPE); + (dev, "Cyan", strlen("Cyan"), NO_COMP_NAME_TYPE_OP); num_colorant[1] = (dev_proc(dev, get_color_comp_index))\ - (dev, "Magenta", strlen("Magenta"), NO_COMP_NAME_TYPE); + (dev, "Magenta", strlen("Magenta"), NO_COMP_NAME_TYPE_OP); num_colorant[2] = (dev_proc(dev, get_color_comp_index))\ - (dev, "Yellow", strlen("Yellow"), NO_COMP_NAME_TYPE); + (dev, "Yellow", strlen("Yellow"), NO_COMP_NAME_TYPE_OP); num_colorant[3] = (dev_proc(dev, get_color_comp_index))\ - (dev, "Black", strlen("Black"), NO_COMP_NAME_TYPE); + (dev, "Black", strlen("Black"), NO_COMP_NAME_TYPE_OP); nz_comps = 0; one = 1; colorant_ok = true; diff --git a/base/gscspace.h b/base/gscspace.h index 0c07ccef..9804efe2 100644 --- a/base/gscspace.h +++ b/base/gscspace.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -341,7 +341,7 @@ struct gs_color_space_s { gs_color_space *gs_cspace_new_DeviceGray(gs_memory_t *mem); gs_color_space *gs_cspace_new_DeviceRGB(gs_memory_t *mem); gs_color_space *gs_cspace_new_DeviceCMYK(gs_memory_t *mem); -gs_color_space *gs_cspace_new_ICC(gs_memory_t *pmem, gs_gstate * pgs, +gs_color_space *gs_cspace_new_ICC(gs_memory_t *pmem, gs_gstate * pgs, int components); gs_color_space *gs_cspace_new_scrgb(gs_memory_t *pmem, gs_gstate * pgs); @@ -397,6 +397,8 @@ void rc_decrement_only_cs(gs_color_space *pcs, const char *cname); void cs_adjust_counts_icc(gs_gstate *pgs, int delta); +void cs_adjust_swappedcounts_icc(gs_gstate *pgs, int delta); + /* backwards compatibility */ #define gs_color_space_indexed_base_space(pcspace)\ gs_cspace_base_space(pcspace) diff --git a/base/gscssub.c b/base/gscssub.c index 7891a4e3..fed15545 100644 --- a/base/gscssub.c +++ b/base/gscssub.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gscssub.h b/base/gscssub.h index 0835c00c..95572161 100644 --- a/base/gscssub.h +++ b/base/gscssub.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsdcolor.h b/base/gsdcolor.h index 778da76b..367dcd48 100644 --- a/base/gsdcolor.h +++ b/base/gsdcolor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsdevice.c b/base/gsdevice.c index ac78af93..630ed493 100644 --- a/base/gsdevice.c +++ b/base/gsdevice.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -32,6 +32,7 @@ #include "gxcmap.h" #include "gxdevice.h" #include "gxdevmem.h" +#include "gxdevsop.h" #include "gxiodev.h" #include "gxcspace.h" #include "gsicc_manage.h" @@ -70,6 +71,10 @@ gx_device_finalize(const gs_memory_t *cmem, void *vptr) rc_decrement(dev->PageList, "gx_device_finalize(PageList)"); dev->PageList = 0; } + if (dev->NupControl) { + rc_decrement(dev->NupControl, "gx_device_finalize(NupControl)"); + dev->NupControl = 0; + } if (dev->finalize) dev->finalize(dev); @@ -201,7 +206,7 @@ gs_output_page(gs_gstate * pgs, int num_copies, int flush) ((code = gs_fill(pgs)) < 0)) { gs_grestore(pgs); - return code; + return code; } code = gs_grestore(pgs); if (code < 0) @@ -645,6 +650,7 @@ gs_make_null_device(gx_device_null *dev_null, gx_device *dev, { gx_device_init((gx_device *)dev_null, (const gx_device *)&gs_null_device, mem, true); + gx_device_fill_in_procs((gx_device *)dev_null); gx_device_set_target((gx_device_forward *)dev_null, dev); if (dev) { /* The gx_device_copy_color_params() call below should @@ -786,7 +792,10 @@ gx_device_raster(const gx_device * dev, bool pad) int l2align; if (dev->is_planar) - bits /= dev->color_info.num_components; + { + int has_tags = device_encodes_tags(dev); + bits /= (dev->color_info.num_components + has_tags); + } raster = (uint)((bits + 7) >> 3); if (!pad) @@ -869,9 +878,21 @@ gx_device_set_hwsize_from_media(gx_device *dev) int rot = (dev->LeadingEdge & 1); double rot_media_x = rot ? dev->MediaSize[1] : dev->MediaSize[0]; double rot_media_y = rot ? dev->MediaSize[0] : dev->MediaSize[1]; + gx_device *parent = dev; + int hwsize[2]; - dev->width = (int)(rot_media_x * dev->HWResolution[0] / 72.0 + 0.5); - dev->height = (int)(rot_media_y * dev->HWResolution[1] / 72.0 + 0.5); + /* Try the spec_op to give the device to control it */ + hwsize[0] = (int)(rot_media_x * dev->HWResolution[0] / 72.0 + 0.5); + hwsize[1] = (int)(rot_media_y * dev->HWResolution[1] / 72.0 + 0.5); + + while (parent->parent != NULL) { + parent = parent->parent; + } + if (dev_proc(parent, dev_spec_op)(parent, gxdso_set_HWSize, &hwsize, sizeof(hwsize)) <= 0) { + /* just do the default setting */ + dev->width = hwsize[0]; + dev->height = hwsize[1]; + } } static void @@ -1155,7 +1176,7 @@ int gx_device_delete_output_file(const gx_device * dev, const char *fname) if (pfname == NULL) { code = gs_note_error(gs_error_VMerror); - goto done; + goto done; } code = gx_parse_output_file_name(&parsed, &fmt, fname, strlen(fname), @@ -1214,7 +1235,7 @@ gx_device_open_output_file(const gx_device * dev, char *fname, if (pfname == NULL) { code = gs_note_error(gs_error_VMerror); - goto done; + goto done; } if (strlen(fname) == 0) { @@ -1230,8 +1251,8 @@ gx_device_open_output_file(const gx_device * dev, char *fname, if (parsed.iodev && !strcmp(parsed.iodev->dname, "%stdout%")) { if (parsed.fname) { code = gs_note_error(gs_error_undefinedfilename); - goto done; - } + goto done; + } *pfile = gp_file_FILE_alloc(dev->memory); if (*pfile == NULL) { code = gs_note_error(gs_error_VMerror); @@ -1240,7 +1261,7 @@ gx_device_open_output_file(const gx_device * dev, char *fname, gp_file_FILE_set(*pfile, dev->memory->gs_lib_ctx->core->fstdout, noclose); /* Force stdout to binary. */ code = gp_setmode_binary_impl(dev->memory->gs_lib_ctx->core->fstdout, true); - goto done; + goto done; } else if (parsed.iodev && !strcmp(parsed.iodev->dname, "%pipe%")) { positionable = false; } @@ -1267,8 +1288,8 @@ gx_device_open_output_file(const gx_device * dev, char *fname, if (!parsed.fname) { code = gs_note_error(gs_error_undefinedfilename); - goto done; - } + goto done; + } strcpy(fmode, gp_fmode_wb); if (positionable) strcat(fmode, "+"); diff --git a/base/gsdevice.h b/base/gsdevice.h index 35f1e38c..f913c20f 100644 --- a/base/gsdevice.h +++ b/base/gsdevice.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsdevmem.c b/base/gsdevmem.c index 78443bfd..fec67ee4 100644 --- a/base/gsdevmem.c +++ b/base/gsdevmem.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsdll.h b/base/gsdll.h index 8f0137cb..901845b3 100644 --- a/base/gsdll.h +++ b/base/gsdll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsdllwin.h b/base/gsdllwin.h index f04dad46..d537ff7f 100644 --- a/base/gsdllwin.h +++ b/base/gsdllwin.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsdparam.c b/base/gsdparam.c index a07a7c33..b86dcfb4 100644 --- a/base/gsdparam.c +++ b/base/gsdparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -20,14 +20,23 @@ #include "gserrors.h" #include "gsdevice.h" /* for prototypes */ #include "gsparam.h" +#include "gsparamx.h" /* for param_put_enum */ #include "gxdevice.h" +#include "gxdevsop.h" #include "gxfixed.h" #include "gsicc_manage.h" +#include "gdevnup.h" /* to install N-up subclass device */ +extern gx_device_nup gs_nup_device; /* Define whether we accept PageSize as a synonym for MediaSize. */ /* This is for backward compatibility only. */ #define PAGESIZE_IS_MEDIASIZE +/* Names corresponding to gs_overprint_control_t enum */ +static const char *const overprint_control_names[] = { + gs_overprint_control_names, 0 +}; + /* ================ Getting parameters ================ */ /* Forward references */ @@ -87,7 +96,9 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) bool devicegraytok = true; /* Default if device profile stuct not set */ bool graydetection = false; bool usefastcolor = false; /* set for unmanaged color */ - bool sim_overprint = true; /* By default simulate overprinting (only valid with cmyk devices) */ + bool blacktext = false; + /* By default overprinting only valid with cmyk devices */ + gs_overprint_control_t overprint_control = gs_overprint_control_enable; bool prebandthreshold = true, temp_bool = false; if(strcmp(Param, "OutputDevice") == 0){ @@ -221,6 +232,9 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) if (strcmp(Param, "PageUsesTransparency") == 0) { return param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency); } + if (strcmp(Param, "PageUsesOverprint") == 0) { + return param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint); + } if (strcmp(Param, "MaxBitmap") == 0) { return param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap)); } @@ -340,7 +354,8 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) devicegraytok = dev_profile->devicegraytok; graydetection = dev_profile->graydetection; usefastcolor = dev_profile->usefastcolor; - sim_overprint = dev_profile->sim_overprint; + blacktext = dev_profile->blacktext; + overprint_control = dev_profile->overprint_control; prebandthreshold = dev_profile->prebandthreshold; /* With respect to Output profiles that have non-standard colorants, we rely upon the default profile to give us the colorants if they do @@ -380,8 +395,15 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) if (strcmp(Param, "UseFastColor") == 0) { return param_write_bool(plist, "UseFastColor", &usefastcolor); } - if (strcmp(Param, "SimulateOverprint") == 0) { - return param_write_bool(plist, "SimulateOverprint", &sim_overprint); + if (strcmp(Param, "BlackText") == 0) { + return param_write_bool(plist, "BlackText", &blacktext); + } + if (strcmp(Param, "Overprint") == 0) { + gs_param_string opc_name; + const char *s = overprint_control_names[(int)overprint_control]; + + param_string_from_string(opc_name, s); + return param_write_name(plist, "Overprint", &opc_name); } if (strcmp(Param, "PreBandThreshold") == 0) { return param_write_bool(plist, "PreBandThreshold", &prebandthreshold); @@ -462,6 +484,17 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) temp_bool = dev->DisablePageHandler; return param_write_bool(plist, "DisablePageHandler", &temp_bool); } + if (strcmp(Param, "NupControl") == 0){ + gs_param_string nupcontrol; + + if (dev->NupControl) { + gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl; + param_string_from_string(nupcontrol, p->nupcontrol_str); + } + else + param_string_from_string(nupcontrol, null_str); + return param_write_string(plist, "NupControl", &nupcontrol); + } if (strcmp(Param, "PageList") == 0){ gs_param_string pagelist; if (dev->PageList) { @@ -498,7 +531,7 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) bool seprs = false; gs_param_string dns, pcms, profile_array[NUM_DEVICE_PROFILES]; - gs_param_string blend_profile, postren_profile, pagelist; + gs_param_string blend_profile, postren_profile, pagelist, nuplist; gs_param_string proof_profile, link_profile, icc_colorants; gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES]; gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES]; @@ -506,7 +539,9 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) bool devicegraytok = true; /* Default if device profile stuct not set */ bool graydetection = false; bool usefastcolor = false; /* set for unmanaged color */ - bool sim_overprint = true; /* By default simulate overprinting */ + bool blacktext = false; + /* By default, only overprint if the device supports it */ + gs_overprint_control_t overprint_control = gs_overprint_control_enable; bool prebandthreshold = true, temp_bool; int k; int color_accuracy = MAX_COLOR_ACCURACY; @@ -619,7 +654,8 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) devicegraytok = dev_profile->devicegraytok; graydetection = dev_profile->graydetection; usefastcolor = dev_profile->usefastcolor; - sim_overprint = dev_profile->sim_overprint; + blacktext = dev_profile->blacktext; + overprint_control = dev_profile->overprint_control; prebandthreshold = dev_profile->prebandthreshold; /* With respect to Output profiles that have non-standard colorants, we rely upon the default profile to give us the colorants if they do @@ -679,7 +715,7 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) (code = param_write_bool(plist, "DeviceGrayToK", &devicegraytok)) < 0 || (code = param_write_bool(plist, "GrayDetection", &graydetection)) < 0 || (code = param_write_bool(plist, "UseFastColor", &usefastcolor)) < 0 || - (code = param_write_bool(plist, "SimulateOverprint", &sim_overprint)) < 0 || + (code = param_write_bool(plist, "BlackText", &blacktext)) < 0 || (code = param_write_bool(plist, "PreBandThreshold", &prebandthreshold)) < 0 || (code = param_write_string(plist,"OutputICCProfile", &(profile_array[0]))) < 0 || (code = param_write_string(plist,"GraphicICCProfile", &(profile_array[1]))) < 0 || @@ -721,6 +757,7 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) (code = param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams)) < 0 || (code = param_write_size_t(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 || (code = param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency)) < 0 || + (code = param_write_bool(plist, "PageUsesOverprint", &dev->page_uses_overprint)) < 0 || (code = param_write_size_t(plist, "MaxBitmap", &(dev->space_params.MaxBitmap))) < 0 || (code = param_write_size_t(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace)) < 0 || (code = param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight)) < 0 || @@ -729,7 +766,13 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) (code = param_write_int(plist, "InterpolateControl", &dev->interpolate_control)) < 0 ) return code; + { + gs_param_string opc_name; + const char *s = overprint_control_names[(int)overprint_control]; + param_string_from_string(opc_name, s); + param_write_name(plist, "Overprint", &opc_name); + } /* If LeadingEdge was set explicitly, report it here. */ if (dev->LeadingEdge & LEADINGEDGE_SET_MASK) { int leadingedge = dev->LeadingEdge & LEADINGEDGE_MASK; @@ -748,12 +791,21 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) if ((code = param_write_bool(plist, "DisablePageHandler", &temp_bool)) < 0) return code; + if (dev->NupControl) { + gdev_nupcontrol *p = (gdev_nupcontrol *)dev->NupControl; + param_string_from_string(nuplist, p->nupcontrol_str); + } else { + param_string_from_string(nuplist, null_str); + } + if ((code = param_write_string(plist, "NupControl", &nuplist)) < 0) + return code; + if (dev->PageList) { gdev_pagelist *p = (gdev_pagelist *)dev->PageList; param_string_from_string(pagelist, p->Pages); - } - else + } else { param_string_from_string(pagelist, null_str); + } if ((code = param_write_string(plist, "PageList", &pagelist)) < 0) return code; @@ -1002,6 +1054,8 @@ gs_putdeviceparams(gx_device * dev, gs_param_list * plist) bool was_open = dev->is_open; int code; + /* gs_param_list_dump(plist); */ + gx_device_set_procs(dev); fill_dev_proc(dev, put_params, gx_default_put_params); fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); @@ -1028,7 +1082,7 @@ gx_default_put_graydetection(bool graydetection, gx_device * dev) may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); } dev->icc_struct->graydetection = graydetection; dev->icc_struct->pageneutralcolor = graydetection; @@ -1036,7 +1090,7 @@ gx_default_put_graydetection(bool graydetection, gx_device * dev) code = dev_proc(dev, get_profile)(dev, &profile_struct); if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); profile_struct = dev->icc_struct; } profile_struct->graydetection = graydetection; @@ -1064,7 +1118,7 @@ gx_default_put_graytok(bool graytok, gx_device * dev) may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1073,7 +1127,7 @@ gx_default_put_graytok(bool graytok, gx_device * dev) code = dev_proc(dev, get_profile)(dev, &profile_struct); if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); profile_struct = dev->icc_struct; if (profile_struct == NULL) return_error(gs_error_VMerror); @@ -1102,7 +1156,7 @@ gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev) may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1111,7 +1165,7 @@ gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev) code = dev_proc(dev, get_profile)(dev, &profile_struct); if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); profile_struct = dev->icc_struct; if (profile_struct == NULL) return_error(gs_error_VMerror); @@ -1140,7 +1194,7 @@ gx_default_put_usefastcolor(bool fastcolor, gx_device * dev) may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1149,7 +1203,7 @@ gx_default_put_usefastcolor(bool fastcolor, gx_device * dev) code = dev_proc(dev, get_profile)(dev, &profile_struct); if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); profile_struct = dev->icc_struct; if (profile_struct == NULL) return_error(gs_error_VMerror); @@ -1160,7 +1214,34 @@ gx_default_put_usefastcolor(bool fastcolor, gx_device * dev) } static int -gx_default_put_simulateoverprint(bool sim_overprint, gx_device * dev) +gx_default_put_blacktext(bool blacktext, gx_device* dev) +{ + int code = 0; + cmm_dev_profile_t* profile_struct; + + if (dev_proc(dev, get_profile) == NULL) { + if (dev->icc_struct == NULL) { + dev->icc_struct = gsicc_new_device_profile_array(dev); + if (dev->icc_struct == NULL) + return_error(gs_error_VMerror); + } + dev->icc_struct->blacktext = blacktext; + } else { + code = dev_proc(dev, get_profile)(dev, &profile_struct); + if (profile_struct == NULL) { + /* Create now */ + dev->icc_struct = gsicc_new_device_profile_array(dev); + profile_struct = dev->icc_struct; + if (profile_struct == NULL) + return_error(gs_error_VMerror); + } + profile_struct->blacktext = blacktext; + } + return code; +} + +static int +gx_default_put_overprint_control(gs_overprint_control_t overprint_control, gx_device * dev) { int code = 0; cmm_dev_profile_t *profile_struct; @@ -1178,21 +1259,21 @@ gx_default_put_simulateoverprint(bool sim_overprint, gx_device * dev) may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } - dev->icc_struct->sim_overprint = sim_overprint; + dev->icc_struct->overprint_control = overprint_control; } else { code = dev_proc(dev, get_profile)(dev, &profile_struct); if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); profile_struct = dev->icc_struct; if (profile_struct == NULL) return_error(gs_error_VMerror); } - profile_struct->sim_overprint = sim_overprint; + profile_struct->overprint_control = overprint_control; } return code; } @@ -1215,7 +1296,7 @@ gx_default_put_intent(gsicc_rendering_intents_t icc_intent, gx_device * dev, the target device */ if (dev->icc_struct == NULL) { /* Intializes the device structure. Not the profile though for index */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1226,7 +1307,7 @@ gx_default_put_intent(gsicc_rendering_intents_t icc_intent, gx_device * dev, return code; if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1253,7 +1334,7 @@ gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * de the target device */ if (dev->icc_struct == NULL) { /* Intializes the device structure. Not the profile though for index */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1264,7 +1345,7 @@ gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * de return code; if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1294,7 +1375,7 @@ gx_default_put_blackptcomp(gsicc_blackptcomp_t blackptcomp, gx_device * dev, the target device */ if (dev->icc_struct == NULL) { /* Intializes the device structure. Not the profile though for index */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1305,7 +1386,7 @@ gx_default_put_blackptcomp(gsicc_blackptcomp_t blackptcomp, gx_device * dev, return code; if (profile_struct == NULL) { /* Create now */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); if (dev->icc_struct == NULL) return_error(gs_error_VMerror); } @@ -1363,6 +1444,19 @@ gx_default_put_icc(gs_param_string *icc_pro, gx_device * dev, return code; } +void rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname); /* silence warning */ +/* Exported for use by nup_put_params in gdevnup.c */ +void +rc_free_NupControl(gs_memory_t * mem, void *ptr_in, client_name_t cname) +{ + gdev_nupcontrol *pnupc = (gdev_nupcontrol *)ptr_in; + + if (pnupc->rc.ref_count <= 1) { + gs_free(mem->non_gc_memory, pnupc->nupcontrol_str, 1, strlen(pnupc->nupcontrol_str), "free nupcontrol string"); + gs_free(mem->non_gc_memory, pnupc, 1, sizeof(gdev_nupcontrol), "free structure to hold nupcontrol string"); + } +} + static void rc_free_pages_list(gs_memory_t * mem, void *ptr_in, client_name_t cname) { @@ -1409,19 +1503,21 @@ gx_default_put_params(gx_device * dev, gs_param_list * plist) size_t mpbm = dev->MaxPatternBitmap; int ic = dev->interpolate_control; bool page_uses_transparency = dev->page_uses_transparency; + bool page_uses_overprint = dev->page_uses_overprint; gdev_space_params sp = dev->space_params; gdev_space_params save_sp = dev->space_params; int rend_intent[NUM_DEVICE_PROFILES]; int blackptcomp[NUM_DEVICE_PROFILES]; int blackpreserve[NUM_DEVICE_PROFILES]; - gs_param_string cms, pagelist; + gs_param_string cms, pagelist, nuplist; int leadingedge = dev->LeadingEdge; int k; int color_accuracy; bool devicegraytok = true; bool graydetection = false; bool usefastcolor = false; - bool sim_overprint = true; + bool blacktext = false; + gs_overprint_control_t overprint_control = gs_overprint_control_enable; bool prebandthreshold = false; bool use_antidropout = dev->color_info.use_antidropout_downscaler; bool temp_bool; @@ -1440,8 +1536,9 @@ gx_default_put_params(gx_device * dev, gs_param_list * plist) graydetection = dev->icc_struct->graydetection; devicegraytok = dev->icc_struct->devicegraytok; usefastcolor = dev->icc_struct->usefastcolor; + blacktext = dev->icc_struct->blacktext; prebandthreshold = dev->icc_struct->prebandthreshold; - sim_overprint = dev->icc_struct->sim_overprint; + overprint_control = dev->icc_struct->overprint_control; } else { for (k = 0; k < NUM_DEVICE_PROFILES; k++) { rend_intent[k] = gsRINOTSPECIFIED; @@ -1750,8 +1847,13 @@ nce: ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_bool(plist, (param_name = "SimulateOverprint"), - &sim_overprint)) < 0) { + if ((code = param_read_bool(plist, (param_name = "BlackText"), + &blacktext)) < 0) { + ecode = code; + param_signal_error(plist, param_name, ecode); + } + if ((code = param_put_enum(plist, "Overprint", + (int*)&overprint_control, overprint_control_names, ecode)) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); } @@ -1779,6 +1881,11 @@ nce: ecode = code; param_signal_error(plist, param_name, ecode); } + if ((code = param_read_bool(plist, (param_name = "PageUsesOverprint"), + &page_uses_overprint)) < 0) { + ecode = code; + param_signal_error(plist, param_name, ecode); + } if ((code = param_read_size_t(plist, "MaxBitmap", &sp.MaxBitmap)) < 0) ecode = code; @@ -1925,6 +2032,61 @@ label:\ if (code == 0) dev->DisablePageHandler = temp_bool; + /* If we have an NupControl subclass device (N-up) installed, this param will have */ + /* been handled there, so the check for different will be false, meaning that this */ + /* code won't end up doing anything. This will catch the first occurence and needs */ + /* to install the N-up subclass device. */ + code = param_read_string(plist, "NupControl", &nuplist); + if (code < 0) + ecode = code; + if (code == 0) { + if (dev->NupControl && ( + nuplist.size == 0 || + (strncmp(dev->NupControl->nupcontrol_str, (const char *)nuplist.data, nuplist.size) != 0))) { + /* There was a NupControl, but this one is different -- no longer use the old one */ + rc_decrement(dev->NupControl, "default put_params NupControl"); + dev->NupControl = NULL; + } + } + if (dev->NupControl == NULL && code == 0 && nuplist.size > 0) { + gx_device *next_dev; + + dev->NupControl = (gdev_nupcontrol *)gs_alloc_bytes(dev->memory->non_gc_memory, + sizeof(gdev_nupcontrol), "structure to hold nupcontrol_str"); + if (dev->NupControl == NULL) + return gs_note_error(gs_error_VMerror); + dev->NupControl->nupcontrol_str = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, + nuplist.size + 1, "nupcontrol string"); + if (dev->NupControl->nupcontrol_str == NULL){ + gs_free(dev->memory->non_gc_memory, dev->NupControl, 1, sizeof(gdev_nupcontrol), + "free structure to hold nupcontrol string"); + dev->NupControl = 0; + return gs_note_error(gs_error_VMerror); + } + memset(dev->NupControl->nupcontrol_str, 0x00, nuplist.size + 1); + memcpy(dev->NupControl->nupcontrol_str, nuplist.data, nuplist.size); + rc_init_free(dev->NupControl, dev->memory->non_gc_memory, 1, rc_free_NupControl); + + /* Propagate the new NupControl struct to children */ + next_dev = dev->child; + while (next_dev != NULL) { + if (next_dev->NupControl) + rc_decrement(next_dev->NupControl, "nup_put_params"); + next_dev->NupControl = dev->NupControl; + rc_increment(dev->NupControl); + next_dev = next_dev->child; + } + /* Propagate the new NupControl struct to parents */ + next_dev = dev->parent; + while (next_dev != NULL) { + if (next_dev->NupControl) + rc_decrement(next_dev->NupControl, "nup_put_params"); + next_dev->NupControl = dev->NupControl; + rc_increment(dev->NupControl); + next_dev = next_dev->parent; + } + } + code = param_read_string(plist, "PageList", &pagelist); if (code < 0) ecode = code; @@ -2079,6 +2241,7 @@ label:\ dev->interpolate_control = ic; dev->space_params = sp; dev->page_uses_transparency = page_uses_transparency; + dev->page_uses_overprint = page_uses_overprint; gx_device_decache_colors(dev); /* Take care of the rendering intents and blackpts. For those that @@ -2130,7 +2293,10 @@ label:\ code = gx_default_put_usefastcolor(usefastcolor, dev); if (code < 0) return code; - code = gx_default_put_simulateoverprint(sim_overprint, dev); + code = gx_default_put_blacktext(blacktext, dev); + if (code < 0) + return code; + code = gx_default_put_overprint_control(overprint_control, dev); if (code < 0) return code; code = gx_default_put_graydetection(graydetection, dev); diff --git a/base/gsdps1.c b/base/gsdps1.c index 84980d4b..640853d5 100644 --- a/base/gsdps1.c +++ b/base/gsdps1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -196,7 +196,7 @@ gs_rectfill(gs_gstate * pgs, const gs_rect * pr, uint count) const gs_gstate *pgs2 = (const gs_gstate *)pgs; bool hl_color_available = gx_hld_is_hl_color_available(pgs2, pdc); bool hl_color = (hl_color_available && - dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_hlcolor, + dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_hlcolor, NULL, 0)); bool center_of_pixel = (pgs->fill_adjust.x == 0 && pgs->fill_adjust.y == 0); @@ -206,7 +206,12 @@ gs_rectfill(gs_gstate * pgs, const gs_rect * pr, uint count) code = gx_set_dev_color(pgs); if (code != 0) return code; - if ((is_fzero2(pgs->ctm.xy, pgs->ctm.yx) || + + if ( !(pgs->device->page_uses_transparency || + dev_proc(pgs->device, dev_spec_op)(pgs->device, + gxdso_is_pdf14_device, &(pgs->device), + sizeof(pgs->device))) && + (is_fzero2(pgs->ctm.xy, pgs->ctm.yx) || is_fzero2(pgs->ctm.xx, pgs->ctm.yy)) && gx_effective_clip_path(pgs, &pcpath) >= 0 && clip_list_is_rectangle(gx_cpath_list(pcpath)) && diff --git a/base/gsdsrc.c b/base/gsdsrc.c index fcfb9d58..4b5ddad2 100644 --- a/base/gsdsrc.c +++ b/base/gsdsrc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsdsrc.h b/base/gsdsrc.h index a9afae66..8807384d 100644 --- a/base/gsdsrc.h +++ b/base/gsdsrc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsequivc.c b/base/gsequivc.c index fabcd331..e89e23ab 100644 --- a/base/gsequivc.c +++ b/base/gsequivc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -441,7 +441,7 @@ cmap_separation_capture_cmyk_color(frac all, gx_device_color * pdc, dmprintf(pgs->memory, "cmap_separation_capture_cmyk_color - this routine should not be executed\n"); } -/* The call to this is actually going to occur if we happen to be using a +/* The call to this is actually going to occur if we happen to be using a named color profile and doing a replacement. Since the destination profile will have been CMYK based during the swap out to find the equivalent color, we can go ahead and just grab the cmyk portion */ @@ -478,8 +478,8 @@ capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_gstate * pgs, 0 /* blend_profile */, 0 /* postren_profile */, { {0} } /* rendercond[] */, 0 /* devicegraytok */, 0 /* graydection */, 0 /* pageneutralcolor */, - 0 /* usefastcolor */, 0 /* supports_devn */, - 0 /* sim_overprint */, 0 /* spotnames */, + 0 /* usefastcolor */, 0 /* blacktext */, 0 /* supports_devn */, + 0 /* overprint_control */, 0 /* spotnames */, 0 /* prebandthreshold */, 0 /* memory */, { 0 } /* rc_header */ }; @@ -487,6 +487,14 @@ capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_gstate * pgs, dev_proc(pdev, get_profile)(pdev, &dev_profile); gsicc_extract_profile(pdev->graphics_type_tag, dev_profile, &(curr_output_profile), &render_cond); + + /* If the output profile is not CMYK based (which can happen during overprint + simulation. In particular when the blending space is RGB or Gray based. + Think of the case where the file has transparency and we are in an RGB + page group), then just use DefaultCMYK */ + if (curr_output_profile->data_cs != gsCMYK) + curr_output_profile = pgs->icc_manager->default_cmyk; + /* * Create a temp device. The primary purpose of this device is pass the * separation number and a pointer to the original device's equivalent @@ -499,6 +507,7 @@ capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_gstate * pgs, temp_device.memory = pgs->memory; temp_profile.usefastcolor = false; /* This avoids a few headaches */ + temp_profile.blacktext = false; temp_profile.prebandthreshold = true; temp_profile.supports_devn = false; temp_profile.rendercond[0] = render_cond; @@ -518,10 +527,10 @@ capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_gstate * pgs, for the CMYK + OG values. */ if (curr_output_profile->data_cs == gsNCHANNEL) { - temp_profile.device_profile[GS_DEFAULT_DEVICE_PROFILE] = + temp_profile.device_profile[GS_DEFAULT_DEVICE_PROFILE] = temp_state.icc_manager->default_cmyk; } else { - temp_profile.device_profile[GS_DEFAULT_DEVICE_PROFILE] = + temp_profile.device_profile[GS_DEFAULT_DEVICE_PROFILE] = curr_output_profile; } set_dev_proc(&temp_device, get_profile, gx_default_get_profile); diff --git a/base/gsequivc.h b/base/gsequivc.h index 7fddce58..0ea3ead4 100644 --- a/base/gsequivc.h +++ b/base/gsequivc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -45,7 +45,7 @@ typedef struct cmyk_color_s { } cmyk_color; /* if you make any additions/changes to the equivalent_cmyk_color_params or the - cmyk_color structrs you need to make the appropriate additions/changes + cmyk_color structrs you need to make the appropriate additions/changes to the compare_equivalent_cmyk_color_params() function in gdevdevn.c */ /* diff --git a/base/gserrors.h b/base/gserrors.h index d27b1c56..1bdbb8a0 100644 --- a/base/gserrors.h +++ b/base/gserrors.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsexit.h b/base/gsexit.h index 226942d9..f523bdec 100644 --- a/base/gsexit.h +++ b/base/gsexit.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfcid.c b/base/gsfcid.c index 1dfd2a9b..198a3420 100644 --- a/base/gsfcid.c +++ b/base/gsfcid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -112,9 +112,9 @@ subst_CID_on_WMode_finalize(const gs_memory_t *cmem, void *data) gs_subst_CID_on_WMode_t *subst = (gs_subst_CID_on_WMode_t *)data; (void)cmem; /* unused */ - gs_free_object(subst->rc.memory, subst->data + 0, "subst_CID_on_WMode_finalize"); + gs_free_object(subst->rc.memory, subst->data[0], "subst_CID_on_WMode_finalize"); subst->data[0] = NULL; - gs_free_object(subst->rc.memory, subst->data + 1, "subst_CID_on_WMode_finalize"); + gs_free_object(subst->rc.memory, subst->data[1], "subst_CID_on_WMode_finalize"); subst->data[1] = NULL; } diff --git a/base/gsfcid2.c b/base/gsfcid2.c index fe23b070..4e73dd5d 100644 --- a/base/gsfcid2.c +++ b/base/gsfcid2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfcmap.c b/base/gsfcmap.c index 32a32fdf..f378d544 100644 --- a/base/gsfcmap.c +++ b/base/gsfcmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -643,6 +643,19 @@ gs_cmap_ToUnicode_realloc(gs_memory_t *mem, int new_value_size, gs_cmap_t **ppcm return 0; } +int gs_cmap_ToUnicode_check_pair(gs_cmap_t *pcmap, int code0) +{ + gs_cmap_ToUnicode_t *cmap = (gs_cmap_ToUnicode_t *)pcmap; + uchar *map = pcmap->glyph_name_data; + const int num_codes = ((gs_cmap_ToUnicode_t *)pcmap)->num_codes; + + if (code0 >= num_codes) + return 0; + if(map[code0 * (cmap->value_size + 2)] == 0 && map[code0 * (cmap->value_size + 2) + 1] == 0) + return 0; + return 1; +} + /* * Write a code pair to ToUnicode CMap. */ diff --git a/base/gsfcmap.h b/base/gsfcmap.h index 73516c3e..161e982c 100644 --- a/base/gsfcmap.h +++ b/base/gsfcmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -66,4 +66,6 @@ int gs_cmap_ToUnicode_realloc(gs_memory_t *mem, int new_value_size, gs_cmap_t ** */ void gs_cmap_ToUnicode_add_pair(gs_cmap_t *pcmap, int code0, ushort *unicode, unsigned int length); +int gs_cmap_ToUnicode_check_pair(gs_cmap_t *pcmap, int code0); + #endif /* gsfcmap_INCLUDED */ diff --git a/base/gsfcmap1.c b/base/gsfcmap1.c index 7fc3403e..0add2c74 100644 --- a/base/gsfcmap1.c +++ b/base/gsfcmap1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsflip.c b/base/gsflip.c index b86dcf41..83024c6c 100644 --- a/base/gsflip.c +++ b/base/gsflip.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsflip.h b/base/gsflip.h index 9bbe8908..cf49674b 100644 --- a/base/gsflip.h +++ b/base/gsflip.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfname.c b/base/gsfname.c index 37acd07c..5ae10046 100644 --- a/base/gsfname.c +++ b/base/gsfname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfname.h b/base/gsfname.h index dcc5f359..2594d289 100644 --- a/base/gsfname.h +++ b/base/gsfname.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfont.c b/base/gsfont.c index ba2e90ef..b8335c1d 100644 --- a/base/gsfont.c +++ b/base/gsfont.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfont.h b/base/gsfont.h index 0c5298e0..f7f4c61a 100644 --- a/base/gsfont.h +++ b/base/gsfont.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfont0.c b/base/gsfont0.c index 875a93a5..544163f4 100644 --- a/base/gsfont0.c +++ b/base/gsfont0.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfont0c.c b/base/gsfont0c.c index 6d1d1585..99c93e93 100644 --- a/base/gsfont0c.c +++ b/base/gsfont0c.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsform1.h b/base/gsform1.h index 26f3353c..7d09c94a 100644 --- a/base/gsform1.h +++ b/base/gsform1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsftopts.h b/base/gsftopts.h index bcfcb9da..7fcacac2 100644 --- a/base/gsftopts.h +++ b/base/gsftopts.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfunc.c b/base/gsfunc.c index c45b652e..7a3ace5e 100644 --- a/base/gsfunc.c +++ b/base/gsfunc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfunc.h b/base/gsfunc.h index 59f51464..24f28a5e 100644 --- a/base/gsfunc.h +++ b/base/gsfunc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfunc0.c b/base/gsfunc0.c index 133c097f..897e4aaa 100644 --- a/base/gsfunc0.c +++ b/base/gsfunc0.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfunc0.h b/base/gsfunc0.h index 7b7bb4f8..abf8214b 100644 --- a/base/gsfunc0.h +++ b/base/gsfunc0.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfunc3.c b/base/gsfunc3.c index eee07a95..11968efd 100644 --- a/base/gsfunc3.c +++ b/base/gsfunc3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfunc3.h b/base/gsfunc3.h index 068de58c..f2fb2834 100644 --- a/base/gsfunc3.h +++ b/base/gsfunc3.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsfunc4.c b/base/gsfunc4.c index 7f8da5d1..d5daf9ce 100644 --- a/base/gsfunc4.c +++ b/base/gsfunc4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -232,7 +232,6 @@ fn_PtCr_evaluate(const gs_function_t *pfn_common, const float *in, float *out) for (; ; ) { int code, n; - sw: switch (op_defn_table[*p++].opcode[(vsp[-1].type << 2) + vsp->type]) { /* Miscellaneous */ @@ -246,20 +245,16 @@ fn_PtCr_evaluate(const gs_function_t *pfn_common, const float *in, float *out) case PtCr_int_to_float: store_float(vsp, (double)vsp->value.i); - --p; goto sw; + --p; continue; case PtCr_int2_to_float: store_float(vsp, (double)vsp->value.i); /* fall through */ case PtCr_2nd_int_to_float: store_float(vsp - 1, (double)vsp[-1].value.i); - --p; goto sw; + --p; continue; /* Arithmetic operators */ - case PtCr_abs_int: - if (vsp->value.i < 0) - goto neg_int; - continue; case PtCr_abs: vsp->value.f = fabs(vsp->value.f); continue; @@ -359,8 +354,11 @@ fn_PtCr_evaluate(const gs_function_t *pfn_common, const float *in, float *out) case PtCr_mul: vsp[-1].value.f *= vsp->value.f; --vsp; continue; + case PtCr_abs_int: + if (vsp->value.i >= 0) + continue; + /* fallthrough */ case PtCr_neg_int: - neg_int: if (vsp->value.i == min_int) store_float(vsp, (double)vsp->value.i); /* =self negated */ else @@ -415,11 +413,6 @@ fn_PtCr_evaluate(const gs_function_t *pfn_common, const float *in, float *out) case PtCr_eq_int: DO_REL(==, i); goto rel; - case PtCr_eq: - DO_REL(==, f); - rel: - vsp[-1].type = CVT_BOOL; - --vsp; continue; case PtCr_ge_int: DO_REL(>=, i); goto rel; @@ -450,6 +443,11 @@ fn_PtCr_evaluate(const gs_function_t *pfn_common, const float *in, float *out) case PtCr_ne: DO_REL(!=, f); goto rel; + case PtCr_eq: + DO_REL(==, f); + rel: + vsp[-1].type = CVT_BOOL; + --vsp; continue; #undef DO_REL diff --git a/base/gsfunc4.h b/base/gsfunc4.h index 2df906a4..ec98deeb 100644 --- a/base/gsfunc4.h +++ b/base/gsfunc4.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsgc.h b/base/gsgc.h index 481009ab..a02899cf 100644 --- a/base/gsgc.h +++ b/base/gsgc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsgcache.c b/base/gsgcache.c index c7a35dbe..6310adf2 100644 --- a/base/gsgcache.c +++ b/base/gsgcache.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsgcache.h b/base/gsgcache.h index aca563d8..b8c2d711 100644 --- a/base/gsgcache.h +++ b/base/gsgcache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsgdata.c b/base/gsgdata.c index 8d254464..28dab849 100644 --- a/base/gsgdata.c +++ b/base/gsgdata.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsgdata.h b/base/gsgdata.h index 76617310..27e7c5b7 100644 --- a/base/gsgdata.h +++ b/base/gsgdata.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsgstate.c b/base/gsgstate.c index d74a6f09..6eb9b817 100644 --- a/base/gsgstate.c +++ b/base/gsgstate.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -140,8 +140,15 @@ gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem) if (pgs->devicergb_cs == NULL || pgs->devicecmyk_cs == NULL) return_error(gs_error_VMerror); pgs->icc_link_cache = gsicc_cache_new(pgs->memory); + if (pgs->icc_link_cache == NULL) + return_error(gs_error_VMerror); pgs->icc_manager = gsicc_manager_new(pgs->memory); + if (pgs->icc_manager == NULL) + return_error(gs_error_VMerror); pgs->icc_profile_cache = gsicc_profilecache_new(pgs->memory); + if (pgs->icc_profile_cache == NULL) + return_error(gs_error_VMerror); + pgs->black_text_state = NULL; #if ENABLE_CUSTOM_COLOR_CALLBACK pgs->custom_color_callback = INIT_CUSTOM_COLOR_PTR; #endif @@ -168,6 +175,7 @@ gs_gstate_copied(gs_gstate * pgs) rc_increment(pgs->icc_link_cache); rc_increment(pgs->icc_profile_cache); rc_increment(pgs->icc_manager); + rc_increment(pgs->black_text_state); } /* Adjust reference counts before assigning one gs_gstate to another. */ @@ -195,6 +203,7 @@ gs_gstate_pre_assign(gs_gstate *pto, const gs_gstate *pfrom) RCCOPY(icc_link_cache); RCCOPY(icc_profile_cache); RCCOPY(icc_manager); + RCCOPY(black_text_state); #undef RCCOPY } @@ -231,5 +240,6 @@ gs_gstate_release(gs_gstate * pgs) RCDECR(icc_link_cache); RCDECR(icc_profile_cache); RCDECR(icc_manager); + RCDECR(black_text_state); #undef RCDECR } diff --git a/base/gsgstate.h b/base/gsgstate.h index 780a561f..ab0c30f1 100644 --- a/base/gsgstate.h +++ b/base/gsgstate.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gshsb.c b/base/gshsb.c index 78f623ef..1b92133e 100644 --- a/base/gshsb.c +++ b/base/gshsb.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gshsb.h b/base/gshsb.h index 61f251b2..04de52a1 100644 --- a/base/gshsb.h +++ b/base/gshsb.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsht.c b/base/gsht.c index 5b27b623..bc72f0e1 100644 --- a/base/gsht.c +++ b/base/gsht.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -27,6 +27,9 @@ #include "gxdevice.h" /* for gzht.h */ #include "gzht.h" #include "gxfmap.h" /* For effective transfer usage in threshold */ +#include "gp.h" + +#define DUMP_SCREENS 0 /* Forward declarations */ void gx_set_effective_transfer(gs_gstate *); @@ -384,12 +387,20 @@ gx_ht_alloc_threshold_order(gx_ht_order * porder, uint width, uint height, uint num_levels, gs_memory_t * mem) { gx_ht_order order; - uint num_bits = width * height; - const gx_ht_order_procs_t *procs = - (num_bits > 2000 && num_bits <= max_ushort ? - &ht_order_procs_short : &ht_order_procs_default); + + unsigned long num_bits = bitmap_raster(width) * 8 * height; + const gx_ht_order_procs_t *procs; int code; + if (num_bits <= 2000) + procs = &ht_order_procs_default; + else if (num_bits <= max_ushort + 1) /* We can index 0 to 65535 so a size of 65536 (max_ushort + 1) is OK */ + procs = &ht_order_procs_short; + else if (num_bits <= max_uint) + procs = &ht_order_procs_uint; + else + return_error(gs_error_VMerror); /* At this point in history, this is way too large of a screen */ + order = *porder; gx_compute_cell_values(&order.params); code = gx_ht_alloc_ht_order(&order, width, height, num_levels, @@ -636,10 +647,10 @@ gs_color_name_component_number(gx_device * dev, const char * pname, int num_colorant; #define check_colorant_name(dev, name) \ - ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), NO_COMP_NAME_TYPE)) + ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), NO_COMP_NAME_TYPE_HT)) #define check_colorant_name_length(dev, name, length) \ - ((*dev_proc(dev, get_color_comp_index)) (dev, name, length, NO_COMP_NAME_TYPE)) + ((*dev_proc(dev, get_color_comp_index)) (dev, name, length, NO_COMP_NAME_TYPE_HT)) #define check_name(str, pname, length) \ ((strlen(str) == length) && (strncmp(pname, str, length) == 0)) @@ -1440,13 +1451,34 @@ gx_ht_construct_threshold( gx_ht_order *d_order, gx_device *dev, } #ifdef DEBUG if ( gs_debug_c('h') ) { - for( i=0; i<(int)d_order->height; i++ ) { - dmprintf1(memory, "threshold array row %3d= ", i); - for( j=0; j<(int)(d_order->width); j++ ) - dmprintf1(memory, "%3d ", *(thresh+j+(i*d_order->width)) ); - dmprintf(memory, "\n"); + dmprintf3(memory, "threshold array component %d [ %d x %d ]:\n", + plane_index, (int)(d_order->full_height), (int)(d_order->width)); + for( i=0; i<(int)d_order->full_height; i++ ) { + dmprintf1(memory, "row %3d= ", i); + for( j=0; j<(int)(d_order->width); j++ ) { + dmprintf1(memory, "%02x ", *(thresh+j+(i*d_order->width)) ); + if ((j&31) == 31) + dmprintf(memory, "\n "); + } + if ((j&31) != 0) + dmprintf(memory, "\n"); } } #endif +/* Large screens are easier to see as images */ +#if DUMP_SCREENS + { + char file_name[50]; + gp_file *fid; + + snprintf(file_name, 50, "Screen_From_Tiles_%dx%d.raw", d_order->width, d_order->full_height); + fid = gp_fopen(memory, file_name, "wb"); + if (fid) { + gp_fwrite(thresh, sizeof(unsigned char), d_order->width * d_order->full_height, fid); + gp_fclose(fid); + } + } +#endif + return 0; } diff --git a/base/gsht.h b/base/gsht.h index ae40bdc0..05857f9f 100644 --- a/base/gsht.h +++ b/base/gsht.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsht1.c b/base/gsht1.c index 918fb229..05fceb54 100644 --- a/base/gsht1.c +++ b/base/gsht1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -252,6 +252,17 @@ gs_sethalftone_prepare(gs_gstate * pgs, gs_halftone * pht, for (i = 0; i < count; i++, phc++) { gx_ht_order_component *poc; + if (gs_debug['h']) { + int i; + byte* pname; + uint name_size; + + pht->params.multiple.get_colorname_string(pgs, phc->cname, &pname, &name_size); + dmprintf(mem, "Colorant: "); + for (i = 0; i < name_size; i++) + dmprintf1(mem, "%c", pname[i]); + dmprintf(mem, "\n"); + } if (phc->comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) { if (have_Default) { /* Duplicate Default */ diff --git a/base/gsht1.h b/base/gsht1.h index 90cba95d..9cd6ff08 100644 --- a/base/gsht1.h +++ b/base/gsht1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gshtscr.c b/base/gshtscr.c index ab3f5fba..34ca1240 100644 --- a/base/gshtscr.c +++ b/base/gshtscr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gshtx.c b/base/gshtx.c index ea7d2e20..c42f19ba 100644 --- a/base/gshtx.c +++ b/base/gshtx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gshtx.h b/base/gshtx.h index 8a2d94b6..a6e688bc 100644 --- a/base/gshtx.h +++ b/base/gshtx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc.c b/base/gsicc.c index e44fa120..f77d7028 100644 --- a/base/gsicc.c +++ b/base/gsicc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc.h b/base/gsicc.h index 8fa86877..d1ca99bb 100644 --- a/base/gsicc.h +++ b/base/gsicc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc_blacktext.c b/base/gsicc_blacktext.c new file mode 100644 index 00000000..82699233 --- /dev/null +++ b/base/gsicc_blacktext.c @@ -0,0 +1,108 @@ +/* Copyright (C) 2001-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Handling of color spaces stored during replacement of all + * text with black. +*/ + +#include "gsmemory.h" +#include "gsstruct.h" +#include "gzstate.h" +#include "gsicc_blacktext.h" + +/* gsicc_blacktext_state_t is going to be storing GCed items + (color spaces and client colors) and so will need to be GCed */ +gs_private_st_ptrs4(st_blacktext_state, gsicc_blacktext_state_t, + "gsicc_blacktext_state", blacktext_state_enum_ptrs, + blacktext_state_reloc_ptrs, pcs[0], pcs[1], pcc[0], pcc[1]); + +static void +rc_gsicc_blacktext_state_free(gs_memory_t *mem, void *ptr_in, + client_name_t cname) +{ + gsicc_blacktext_state_t *state = (gsicc_blacktext_state_t*)ptr_in; + + rc_decrement_cs(state->pcs[0], "rc_gsicc_blacktext_state_free"); + rc_decrement_cs(state->pcs[1], "rc_gsicc_blacktext_state_free"); + + gs_free_object(mem->stable_memory, state, + "rc_gsicc_blacktext_state_free"); +} + +gsicc_blacktext_state_t* +gsicc_blacktext_state_new(gs_memory_t *memory) +{ + gsicc_blacktext_state_t *result; + + result = gs_alloc_struct(memory->stable_memory, gsicc_blacktext_state_t, + &st_blacktext_state, "gsicc_blacktext_state_new"); + if (result == NULL) + return NULL; + rc_init_free(result, memory->stable_memory, 1, rc_gsicc_blacktext_state_free); + result->memory = memory; + result->pcs[0] = NULL; + result->pcs[1] = NULL; + result->pcc[0] = NULL; + result->pcc[1] = NULL; + + return result; +} + +void +gsicc_restore_black_text(gs_gstate *pgs) +{ + gsicc_blacktext_state_t *state = pgs->black_text_state; + int code; + + if (state == NULL) + return; + + /* Make sure state and original are same fill_color condition */ + if (state->rc.ref_count == 1) { + if ((state->is_fill && pgs->is_fill_color) || + (!state->is_fill && !pgs->is_fill_color)) { + + if ((code = gs_setcolorspace_only(pgs, pgs->black_text_state->pcs[0])) >= 0) { + /* current client color is gray. no need to decrement */ + pgs->color[0].ccolor = pgs->black_text_state->pcc[0]; + pgs->color[0].ccolor->paint.values[0] = pgs->black_text_state->value[0]; + } + gs_swapcolors_quick(pgs); + if ((code = gs_setcolorspace_only(pgs, pgs->black_text_state->pcs[1])) >= 0) { + pgs->color[0].ccolor = pgs->black_text_state->pcc[1]; + pgs->color[0].ccolor->paint.values[0] = pgs->black_text_state->value[1]; + + } + gs_swapcolors_quick(pgs); + + } else { + + if ((code = gs_setcolorspace_only(pgs, pgs->black_text_state->pcs[1])) >= 0) { + pgs->color[0].ccolor = pgs->black_text_state->pcc[1]; + pgs->color[0].ccolor->paint.values[0] = pgs->black_text_state->value[1]; + } + gs_swapcolors_quick(pgs); + if ((code = gs_setcolorspace_only(pgs, pgs->black_text_state->pcs[0])) >= 0) { + pgs->color[0].ccolor = pgs->black_text_state->pcc[0]; + pgs->color[0].ccolor->paint.values[0] = pgs->black_text_state->value[0]; + } + gs_swapcolors_quick(pgs); + } + gx_unset_dev_color(pgs); + gx_unset_alt_dev_color(pgs); + } + rc_decrement(state, "gsicc_restore_black_text"); + pgs->black_text_state = NULL; +} \ No newline at end of file diff --git a/base/gsicc_blacktext.h b/base/gsicc_blacktext.h new file mode 100644 index 00000000..09d541a5 --- /dev/null +++ b/base/gsicc_blacktext.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2001-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#ifndef gsicc_blacktext_INCLUDED +# define gsicc_blacktext_INCLUDED + +typedef struct gsicc_blacktext_state_s gsicc_blacktext_state_t; + +struct gsicc_blacktext_state_s { + gs_memory_t *memory; + rc_header rc; + bool is_fill; /* Needed for proper color restore */ + gs_color_space *pcs[2]; /* If doing black text, color spaces to restore */ + gs_client_color *pcc[2]; /* If doing black text, client colors to restore */ + float value[2]; /* DeviceGray setting blows away the client color + zero value */ +}; + +gsicc_blacktext_state_t* gsicc_blacktext_state_new(gs_memory_t *memory); +void gsicc_restore_black_text(gs_gstate *pgs); + +#endif diff --git a/base/gsicc_cache.c b/base/gsicc_cache.c index df51e88b..fda958aa 100644 --- a/base/gsicc_cache.c +++ b/base/gsicc_cache.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -373,6 +373,19 @@ gsicc_mash_hash(gsicc_hashlink_t *hash) (hash->des_hash >> 1) ^ (hash->rend_hash) ^ (hash->src_hash); } +static void +gsicc_set_hash(cmm_profile_t *profile) +{ + if (!profile->hash_is_valid) { + int64_t hash; + + gsicc_get_icc_buff_hash(profile->buffer, &hash, profile->buffer_size); + profile->hashcode = hash; + profile->hash_is_valid = true; + } + return; +} + int64_t gsicc_get_hash(cmm_profile_t *profile) { @@ -386,6 +399,23 @@ gsicc_get_hash(cmm_profile_t *profile) return profile->hashcode; } +bool +gsicc_profiles_equal(cmm_profile_t *profile1, cmm_profile_t *profile2) { + + if (profile1 == NULL || profile2 == NULL) + return false; + + if (!(profile1->hash_is_valid)) { + gsicc_set_hash(profile1); + } + + if (!(profile1->hash_is_valid)) { + gsicc_set_hash(profile2); + } + + return profile1->hashcode == profile2->hashcode; +} + void gsicc_get_icc_buff_hash(unsigned char *buffer, int64_t *hash, unsigned int buff_size) { @@ -1048,7 +1078,9 @@ gsicc_get_link_profile(const gs_gstate *pgs, gx_device *dev, cms_input_profile = gs_input_profile->profile_handle; /* Check if the source was generated from a PS CIE color space. If yes, then we need to make sure that the CMM does not do something like - force a white point mapping like lcms does */ + force a white point mapping like lcms does. This is also the source + of the issue with the flower picture that has the hand made ICC + profile that is highly nonlinear at the whitepoint */ if (gsicc_profile_from_ps(gs_input_profile)) { cms_flags = cms_flags | gscms_avoid_white_fix_flag(memory); } @@ -1788,12 +1820,7 @@ gsicc_init_buffer(gsicc_bufferdesc_t *buffer_desc, unsigned char num_chan, unsig buffer_desc->row_stride = row_stride; buffer_desc->num_rows = num_rows; buffer_desc->pixels_per_row = pixels_per_row; - -#if ARCH_IS_BIG_ENDIAN - buffer_desc->little_endian = false; -#else - buffer_desc->little_endian = true; -#endif + buffer_desc->endian_swap = false; } /* Return the proper component numbers based upon the profiles of the device. diff --git a/base/gsicc_cache.h b/base/gsicc_cache.h index c9b9d0ab..7aa87a43 100644 --- a/base/gsicc_cache.h +++ b/base/gsicc_cache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -37,7 +37,7 @@ void gsicc_init_buffer(gsicc_bufferdesc_t *buffer_desc, unsigned char num_chan, unsigned char bytes_per_chan, bool has_alpha, bool alpha_first, bool is_planar, int plane_stride, int row_stride, int num_rows, int pixels_per_row); -bool gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, +bool gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, gsicc_link_t **ret_link, gsicc_hashlink_t hash, bool include_softproof, bool include_devlink); gsicc_link_t* gsicc_get_link(const gs_gstate * pgs, gx_device *dev, @@ -52,10 +52,11 @@ gsicc_link_t* gsicc_get_link_profile(const gs_gstate *pgs, gx_device *dev, gs_memory_t *memory, bool devicegraytok); void gsicc_release_link(gsicc_link_t *icclink); void gsicc_link_free(gsicc_link_t *icc_link, const gs_memory_t *memory); +bool gsicc_profiles_equal(cmm_profile_t *profile1, cmm_profile_t *profile2); void gsicc_get_icc_buff_hash(unsigned char *buffer, int64_t *hash, unsigned int buff_size); int64_t gsicc_get_hash(cmm_profile_t *profile); int gsicc_transform_named_color(const float tint_values[], - gsicc_namedcolor_t color_names[], + gsicc_namedcolor_t color_names[], uint num_names, gx_color_value device_values[], const gs_gstate *pgs, gx_device *dev, diff --git a/base/gsicc_cms.h b/base/gsicc_cms.h index 9a067093..9d271f19 100644 --- a/base/gsicc_cms.h +++ b/base/gsicc_cms.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc_create.c b/base/gsicc_create.c index 3fc8492b..8c2283ef 100644 --- a/base/gsicc_create.c +++ b/base/gsicc_create.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -169,7 +169,7 @@ typedef struct cielab_s { } cielab_t; static const char desc_name[] = "Ghostscript Internal Profile"; -static const char copy_right[] = "Copyright Artifex Software 2009"; +static const char copy_right[] = "Copyright Artifex Software 2009-2021"; typedef struct { icTagSignature sig; /* The tag signature */ @@ -463,8 +463,8 @@ save_profile(const gs_memory_t *mem, unsigned char *buffer, char filename[], int gs_sprintf(full_file_name,"%d)Profile_%s.icc",icc_debug_index,filename); fid = gp_fopen(mem, full_file_name,"wb"); - fwrite(buffer,sizeof(unsigned char),buffer_size,fid); - fclose(fid); + gp_fwrite(buffer,sizeof(unsigned char),buffer_size,fid); + gp_fclose(fid); icc_debug_index++; } #endif @@ -2350,8 +2350,9 @@ getsize_lut16Type(int tablesize, int num_inputs, int num_outputs) { int clutsize; - /* Header plus linear curves (2 points each of 2 bytes) */ - int size = 52 + 4 * num_inputs + 4 * num_outputs; + /* Header (-8 as we already include the type later) + plus linear curves (2 points each of 2 bytes) */ + int size = 52 - 8 + 4 * num_inputs + 4 * num_outputs; clutsize = (int) pow(tablesize, num_inputs) * num_outputs * 2; return size + clutsize; } @@ -2361,8 +2362,9 @@ getsize_lut8Type(int tablesize, int num_inputs, int num_outputs) { int clutsize; - /* Header plus linear curves (2 points each of 2 bytes) */ - int size = 48 + 256 * num_inputs + 256 * num_outputs; + /* Header (-8 as we already include the type later) + plus linear curves (2 points each of 2 bytes) */ + int size = 48 - 8 + 256 * num_inputs + 256 * num_outputs; clutsize = (int)pow(tablesize, num_inputs) * num_outputs; return size + clutsize; } @@ -2589,7 +2591,7 @@ create_clut_v2(gsicc_clut *clut, gsicc_link_t *link, int num_in, /* Here we write out the lut16Type or lut8Type data V2. Curves are always linear, matrix is the identity. Table data is unique and could be a forward or inverse table */ -static void +static byte* add_lutType(byte *input_ptr, gsicc_clut *lut) { byte *curr_ptr; @@ -2665,12 +2667,13 @@ add_lutType(byte *input_ptr, gsicc_clut *lut) for (j = 0; j < 256; j++) *curr_ptr++ = j; } + return curr_ptr; } static int create_write_table_intent(const gs_gstate *pgs, gsicc_rendering_intents_t intent, cmm_profile_t *src_profile, cmm_profile_t *des_profile, byte *curr_ptr, - int table_size, int bit_depth) + int table_size, int bit_depth, int padding) { gsicc_link_t *link; int code; @@ -2681,7 +2684,8 @@ create_write_table_intent(const gs_gstate *pgs, gsicc_rendering_intents_t intent des_profile->num_comps, table_size, pgs->memory, bit_depth); if (code < 0) return code; - add_lutType(curr_ptr, &clut); + curr_ptr = add_lutType(curr_ptr, &clut); + memset(curr_ptr, 0, padding); clean_lut(&clut, pgs->memory); gsicc_release_link(link); return 0; @@ -2748,7 +2752,8 @@ gsicc_create_v2input(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src_ } /* Now write it out */ - add_lutType(curr_ptr, &clut); + curr_ptr = add_lutType(curr_ptr, &clut); + memset(curr_ptr, 0, tag_list[last_tag].byte_padding); /* padding */ /* Clean up */ gsicc_release_link(link); @@ -2837,15 +2842,18 @@ gsicc_create_v2output(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src /* A2B0 */ if (create_write_table_intent(pgs, gsPERCEPTUAL, src_profile, lab_profile, - curr_ptr, FORWARD_V2_TABLE_SIZE, 2) < 0) { + curr_ptr, FORWARD_V2_TABLE_SIZE, 2, + tag_list[tag_location].byte_padding) < 0) { gs_free_object(memory, tag_list, "gsicc_create_v2output"); return; } curr_ptr += tag_list[tag_location].size; tag_location++; + /* B2A0 */ if (create_write_table_intent(pgs, gsPERCEPTUAL, lab_profile, src_profile, - curr_ptr, BACKWARD_V2_TABLE_SIZE, 1) < 0) { + curr_ptr, BACKWARD_V2_TABLE_SIZE, 1, + tag_list[tag_location].byte_padding) < 0) { gs_free_object(memory, tag_list, "gsicc_create_v2output"); return; } @@ -2854,15 +2862,18 @@ gsicc_create_v2output(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src /* A2B1 */ if (create_write_table_intent(pgs, gsRELATIVECOLORIMETRIC, src_profile, - lab_profile, curr_ptr, FORWARD_V2_TABLE_SIZE, 2) < 0) { + lab_profile, curr_ptr, FORWARD_V2_TABLE_SIZE, 2, + tag_list[tag_location].byte_padding) < 0) { gs_free_object(memory, tag_list, "gsicc_create_v2output"); return; } curr_ptr += tag_list[tag_location].size; tag_location++; + /* B2A1 */ if (create_write_table_intent(pgs, gsRELATIVECOLORIMETRIC, lab_profile, - src_profile, curr_ptr, BACKWARD_V2_TABLE_SIZE, 1) < 0) { + src_profile, curr_ptr, BACKWARD_V2_TABLE_SIZE, 1, + tag_list[tag_location].byte_padding) < 0) { gs_free_object(memory, tag_list, "gsicc_create_v2output"); return; } @@ -2871,15 +2882,18 @@ gsicc_create_v2output(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src /* A2B2 */ if (create_write_table_intent(pgs, gsSATURATION, src_profile, lab_profile, - curr_ptr, FORWARD_V2_TABLE_SIZE, 2) < 0) { + curr_ptr, FORWARD_V2_TABLE_SIZE, 2, + tag_list[tag_location].byte_padding) < 0) { gs_free_object(memory, tag_list, "gsicc_create_v2output"); return; } curr_ptr += tag_list[tag_location].size; tag_location++; + /* B2A2 */ if (create_write_table_intent(pgs, gsSATURATION, lab_profile, src_profile, - curr_ptr, BACKWARD_V2_TABLE_SIZE, 1) < 0) { + curr_ptr, BACKWARD_V2_TABLE_SIZE, 1, + tag_list[tag_location].byte_padding) < 0) { gs_free_object(memory, tag_list, "gsicc_create_v2output"); return; } @@ -2892,12 +2906,15 @@ gsicc_create_v2output(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src gs_free_object(memory, tag_list, "gsicc_create_v2output"); return; } + /* Now write it out */ - add_lutType(curr_ptr, &gamutlut); + curr_ptr = add_lutType(curr_ptr, &gamutlut); + memset(curr_ptr, 0, tag_list[tag_location].byte_padding); /* Done */ gs_free_object(memory, tag_list, "gsicc_create_v2output"); - clean_lut(&gamutlut, pgs->memory); + clean_lut(&gamutlut, pgs->memory); + /* Save the v2 data */ src_profile->v2_data = buffer; src_profile->v2_size = profile_size; @@ -2984,7 +3001,7 @@ gsicc_create_v2displaygray(const gs_gstate *pgs, icHeader *header, cmm_profile_t #if SAVEICCPROFILE /* Dump the buffer to a file for testing if its a valid ICC profile */ - save_profile(buffer, "V2FromGray", profile_size); + save_profile(memory, buffer, "V2FromGray", profile_size); #endif } diff --git a/base/gsicc_create.h b/base/gsicc_create.h index ca84eb3a..a992d09f 100644 --- a/base/gsicc_create.h +++ b/base/gsicc_create.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -42,6 +42,6 @@ cmm_profile_t* gsicc_create_from_cal(float *white, float *black, float *gamma, float *matrix, gs_memory_t *memory, int num_colors); byte* gsicc_getv2buffer(cmm_profile_t *srcprofile, int *size); -byte* gsicc_create_getv2buffer(const gs_gstate *pgs, +byte* gsicc_create_getv2buffer(const gs_gstate *pgs, cmm_profile_t *srcprofile, int *size); #endif diff --git a/base/gsicc_lcms2.c b/base/gsicc_lcms2.c index 43a7a93a..5e9355e6 100644 --- a/base/gsicc_lcms2.c +++ b/base/gsicc_lcms2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -308,7 +308,7 @@ gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, { cmsHTRANSFORM hTransform = (cmsHTRANSFORM)icclink->link_handle; cmsUInt32Number dwInputFormat, dwOutputFormat, num_src_lcms, num_des_lcms; - int planar,numbytes, big_endian, hasalpha, k; + int planar,numbytes, swap_endian, hasalpha, k; unsigned char *inputpos, *outputpos; #if DUMP_CMS_BUFFER gp_file *fid_in, *fid_out; @@ -340,10 +340,10 @@ gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, dwOutputFormat = dwOutputFormat | BYTES_SH(numbytes); /* endian */ - big_endian = !input_buff_desc->little_endian; - dwInputFormat = dwInputFormat | ENDIAN16_SH(big_endian); - big_endian = !output_buff_desc->little_endian; - dwOutputFormat = dwOutputFormat | ENDIAN16_SH(big_endian); + swap_endian = input_buff_desc->endian_swap; + dwInputFormat = dwInputFormat | ENDIAN16_SH(swap_endian); + swap_endian = output_buff_desc->endian_swap; + dwOutputFormat = dwOutputFormat | ENDIAN16_SH(swap_endian); /* number of channels. This should not really be changing! */ num_src_lcms = T_CHANNELS(cmsGetTransformInputFormat(hTransform)); @@ -524,9 +524,7 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, when we use the transformation. */ src_data_type = (COLORSPACE_SH(lcms_src_color_space)| CHANNELS_SH(src_nChannels)|BYTES_SH(2)); -#if 0 - src_data_type = src_data_type | ENDIAN16_SH(1); -#endif + if (lcms_deshandle != NULL) { des_color_space = cmsGetColorSpace(lcms_deshandle); } else { @@ -538,10 +536,7 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, des_nChannels = cmsChannelsOf(des_color_space); des_data_type = (COLORSPACE_SH(lcms_des_color_space)| CHANNELS_SH(des_nChannels)|BYTES_SH(2)); - /* endian */ -#if 0 - des_data_type = des_data_type | ENDIAN16_SH(1); -#endif + /* Set up the flags */ flag = cmsFLAGS_HIGHRESPRECALC; if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON diff --git a/base/gsicc_lcms2mt.c b/base/gsicc_lcms2mt.c index dbb9c4b2..eb621b96 100644 --- a/base/gsicc_lcms2mt.c +++ b/base/gsicc_lcms2mt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -40,10 +40,10 @@ #define LCMS_BYTES_MASK T_BYTES(-1) /* leaves only mask for the BYTES (currently 7) */ #define LCMS_ENDIAN16_MASK T_ENDIAN16(-1) /* similarly, for ENDIAN16 bit */ -#define gsicc_link_flags(hasalpha, planarIN, planarOUT, bigendianIN, bigendianOUT, bytesIN, bytesOUT) \ +#define gsicc_link_flags(hasalpha, planarIN, planarOUT, endianswapIN, endianswapOUT, bytesIN, bytesOUT) \ ((hasalpha != 0) << 2 | \ (planarIN != 0) << 5 | (planarOUT != 0) << 4 | \ - (bigendianIN != 0) << 3 | (bigendianOUT != 0) << 2 | \ + (endianswapIN != 0) << 3 | (endianswapOUT != 0) << 2 | \ (bytesIN == 1) << 1 | (bytesOUT == 1)) typedef struct gsicc_lcms2mt_link_list_s { @@ -338,7 +338,7 @@ gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, gsicc_lcms2mt_link_list_t *link_handle = (gsicc_lcms2mt_link_list_t *)(icclink->link_handle); cmsHTRANSFORM hTransform = (cmsHTRANSFORM)link_handle->hTransform; cmsUInt32Number dwInputFormat, dwOutputFormat, num_src_lcms, num_des_lcms; - int hasalpha, planarIN, planarOUT, numbytesIN, numbytesOUT, big_endianIN, big_endianOUT; + int hasalpha, planarIN, planarOUT, numbytesIN, numbytesOUT, swap_endianIN, swap_endianOUT; int needed_flags = 0; unsigned char *inputpos, *outputpos; cmsContext ctx = gs_lib_ctx_get_cms_context(icclink->memory); @@ -349,7 +349,7 @@ gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, /* Although little CMS does make assumptions about data types in its transformations we can change it after the fact by cloning from any other transform. We always create [0] which is no_alpha, chunky IN/OUT, - little_endian IN/OUT, 2-bytes_per_component IN/OUT. */ + no endian swap IN/OUT, 2-bytes_per_component IN/OUT. */ /* Set us to the proper output type */ /* Note, we could speed this up by passing back the encoded data type to the caller so that we could avoid having to go through this @@ -368,8 +368,8 @@ gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, return_error(gs_error_rangecheck); /* TODO: we don't support float */ /* endian */ - big_endianIN = !input_buff_desc->little_endian; - big_endianOUT = !output_buff_desc->little_endian; + swap_endianIN = input_buff_desc->endian_swap; + swap_endianOUT = output_buff_desc->endian_swap; /* alpha, which is passed through unmolested */ /* TODO: Right now we always must have alpha last */ @@ -377,7 +377,7 @@ gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, hasalpha = input_buff_desc->has_alpha; needed_flags = gsicc_link_flags(hasalpha, planarIN, planarOUT, - big_endianIN, big_endianOUT, + swap_endianIN, swap_endianOUT, numbytesIN, numbytesOUT); while (link_handle->flags != needed_flags) { if (link_handle->next == NULL) { @@ -418,8 +418,8 @@ gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, dwOutputFormat = dwOutputFormat | EXTRA_SH(hasalpha); dwInputFormat = dwInputFormat | PLANAR_SH(planarIN); dwOutputFormat = dwOutputFormat | PLANAR_SH(planarOUT); - dwInputFormat = dwInputFormat | ENDIAN16_SH(big_endianIN); - dwOutputFormat = dwOutputFormat | ENDIAN16_SH(big_endianOUT); + dwInputFormat = dwInputFormat | ENDIAN16_SH(swap_endianIN); + dwOutputFormat = dwOutputFormat | ENDIAN16_SH(swap_endianOUT); dwInputFormat = dwInputFormat | BYTES_SH(numbytesIN); dwOutputFormat = dwOutputFormat | BYTES_SH(numbytesOUT); @@ -608,9 +608,7 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, when we use the transformation. */ src_data_type = (COLORSPACE_SH(lcms_src_color_space)| CHANNELS_SH(src_nChannels)|BYTES_SH(2)); -#if 0 - src_data_type = src_data_type | ENDIAN16_SH(1); -#endif + if (lcms_deshandle != NULL) { des_color_space = cmsGetColorSpace(ctx, lcms_deshandle); } else { @@ -623,10 +621,7 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, des_nChannels = cmsChannelsOf(ctx, des_color_space); des_data_type = (COLORSPACE_SH(lcms_des_color_space)| CHANNELS_SH(des_nChannels)|BYTES_SH(2)); - /* endian */ -#if 0 - des_data_type = des_data_type | ENDIAN16_SH(1); -#endif + /* Set up the flags */ flag = gscms_get_accuracy(memory); if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON @@ -679,7 +674,7 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, return NULL; } link_handle->next = NULL; - link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, little-endian */ + link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, no endian swap */ sizeof(gx_color_value), sizeof(gx_color_value)); return link_handle; /* cmsFLAGS_HIGHRESPRECALC) cmsFLAGS_NOTPRECALC cmsFLAGS_LOWRESPRECALC*/ @@ -714,7 +709,7 @@ gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, if (link_handle == NULL) return NULL; link_handle->next = NULL; - link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, little-endian */ + link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, no endian swap */ sizeof(gx_color_value), sizeof(gx_color_value)); /* Check if the rendering intent is something other than relative colorimetric and if we have a proofing profile. In this case we need to create the @@ -1028,7 +1023,7 @@ gscms_get_name2device_link(gsicc_link_t *icclink, cmsDeleteTransform(ctx, hTransformNew); return; /* bail */ } - link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, little-endian */ + link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, no endian swap */ sizeof(gx_color_value), sizeof(gx_color_value)); link_handle->hTransform = hTransformNew; link_handle->next = NULL; diff --git a/base/gsicc_manage.c b/base/gsicc_manage.c index 8d28bcf1..4cf82e0c 100644 --- a/base/gsicc_manage.c +++ b/base/gsicc_manage.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1421,10 +1421,11 @@ rc_free_profile_array(gs_memory_t * mem, void *ptr_in, client_name_t cname) /* Allocate device icc structure. The actual profiles are in this structure */ cmm_dev_profile_t* -gsicc_new_device_profile_array(gs_memory_t *memory) +gsicc_new_device_profile_array(gx_device *dev) { cmm_dev_profile_t *result; int k; + gs_memory_t *memory = dev->memory; if_debug0m(gs_debug_flag_icc,memory,"[icc] Allocating device profile struct\n"); result = (cmm_dev_profile_t *) gs_alloc_bytes(memory->non_gc_memory, @@ -1453,9 +1454,10 @@ gsicc_new_device_profile_array(gs_memory_t *memory) result->graydetection = false; result->pageneutralcolor = false; result->usefastcolor = false; /* Default is to not use fast color */ + result->blacktext = false; result->prebandthreshold = true; result->supports_devn = false; - result->sim_overprint = true; /* Default is to simulate overprint */ + result->overprint_control = gs_overprint_control_enable; /* Default overprint if the device can */ rc_init_free(result, memory->non_gc_memory, 1, rc_free_profile_array); return result; } @@ -1773,7 +1775,7 @@ gsicc_init_device_profile_struct(gx_device * dev, } else { /* We have no profile structure at all. Allocate the structure in non-GC memory. */ - dev->icc_struct = gsicc_new_device_profile_array(dev->memory); + dev->icc_struct = gsicc_new_device_profile_array(dev); profile_struct = dev->icc_struct; if (profile_struct == NULL) return_error(gs_error_VMerror); diff --git a/base/gsicc_manage.h b/base/gsicc_manage.h index a4bde945..437db045 100644 --- a/base/gsicc_manage.h +++ b/base/gsicc_manage.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -120,7 +120,7 @@ void gsicc_adjust_profile_rc(cmm_profile_t *profile_data, int delta, const char const char* dirname, int dir_namelen, stream **stmp); /* Device related */ -cmm_dev_profile_t* gsicc_new_device_profile_array(gs_memory_t *memory); +cmm_dev_profile_t* gsicc_new_device_profile_array(gx_device *); int gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, char *file_name, gsicc_profile_types_t defaulttype); char* gsicc_get_dev_icccolorants(cmm_dev_profile_t *dev_profile); diff --git a/base/gsicc_monitorcm.c b/base/gsicc_monitorcm.c index 2e305e9d..0451797c 100644 --- a/base/gsicc_monitorcm.c +++ b/base/gsicc_monitorcm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc_nocm.c b/base/gsicc_nocm.c index 6d23382f..efea6c1c 100644 --- a/base/gsicc_nocm.c +++ b/base/gsicc_nocm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc_profilecache.c b/base/gsicc_profilecache.c index adb4ad1d..db2e8ae4 100644 --- a/base/gsicc_profilecache.c +++ b/base/gsicc_profilecache.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc_profilecache.h b/base/gsicc_profilecache.h index 8a344770..4130f101 100644 --- a/base/gsicc_profilecache.h +++ b/base/gsicc_profilecache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsicc_replacecm.c b/base/gsicc_replacecm.c index 906f2ebb..e7cc7706 100644 --- a/base/gsicc_replacecm.c +++ b/base/gsicc_replacecm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsimage.c b/base/gsimage.c index d62c76eb..b3aefb93 100644 --- a/base/gsimage.c +++ b/base/gsimage.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -408,7 +408,12 @@ gs_image_common_init(gs_image_enum * penum, gx_image_enum_common_t * pie, int i; if (pim->Width == 0 || pim->Height == 0) { + gx_device *cdev = pie->dev; + gx_image_end(pie, false); + if (dev_proc(cdev, dev_spec_op)(cdev, + gxdso_pattern_is_cpath_accum, NULL, 0)) + gx_device_retain((gx_device *)cdev, false); return 1; } image_enum_init(penum); @@ -701,7 +706,11 @@ gs_image_cleanup(gs_image_enum * penum, gs_gstate *pgs) int gs_image_cleanup_and_free_enum(gs_image_enum * penum, gs_gstate *pgs) { - int code = gs_image_cleanup(penum, pgs); + int code; + + if (penum == NULL) + return 0; + code = gs_image_cleanup(penum, pgs); gs_free_object(penum->memory, penum, "gs_image_cleanup_and_free_enum"); return code; diff --git a/base/gsimage.h b/base/gsimage.h index 29cf9f81..0f8a79ac 100644 --- a/base/gsimage.h +++ b/base/gsimage.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsimpath.c b/base/gsimpath.c index 073dffe4..8f4b3dbb 100644 --- a/base/gsimpath.c +++ b/base/gsimpath.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsinit.c b/base/gsinit.c index e80353d7..20d48b12 100644 --- a/base/gsinit.c +++ b/base/gsinit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsio.h b/base/gsio.h index 8857bb09..0ae1ed8a 100644 --- a/base/gsio.h +++ b/base/gsio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiodev.c b/base/gsiodev.c index 7b405947..ef5e9ce5 100644 --- a/base/gsiodev.c +++ b/base/gsiodev.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiodevs.c b/base/gsiodevs.c index 1e459701..eec1dd62 100644 --- a/base/gsiodevs.c +++ b/base/gsiodevs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiodisk.c b/base/gsiodisk.c index 5a127e1b..24c50ada 100644 --- a/base/gsiodisk.c +++ b/base/gsiodisk.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -239,7 +239,7 @@ iodev_diskn_fopen(gx_io_device * iodev, const char *fname, const char *access, } code = iodev_os_gp_fopen(iodev_default(pstate->memory), realname, access, pfile, rfname, rnamelen); - + done: if (realname != NULL) gs_free_object(pstate->memory, realname, "iodev_diskn_fopen(realname)"); @@ -359,7 +359,7 @@ diskn_enumerate_files(gs_memory_t * mem, gx_io_device * iodev, const char *pat, uint patlen) { diskn_state * pstate = (diskn_state *)iodev->state; - + return (file_enum *)map_file_enum_init(mem, (char *)pstate->root, pat, patlen); } @@ -630,7 +630,7 @@ MapFileRename(gs_memory_t *mem, const char * rootpath, const char * newfilename, oldfullname = (char *)gs_alloc_bytes(mem, ototlen, "MapFileRename(oldfullname)"); newfullname = (char *)gs_alloc_bytes(mem, ntotlen, "MapFileRename(newfullname)"); - if (oldfullname && newfullname) { + if (oldfullname && newfullname) { gs_sprintf(oldfullname, "%s%s", rootpath, oldfilename); gs_sprintf(newfullname, "%s%s", rootpath, newfilename); rename(oldfullname, newfullname); diff --git a/base/gsioram.c b/base/gsioram.c index 40cdb91e..b5f04ee1 100644 --- a/base/gsioram.c +++ b/base/gsioram.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiorom.c b/base/gsiorom.c index 767a35cf..fb06ac78 100644 --- a/base/gsiorom.c +++ b/base/gsiorom.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiorom.h b/base/gsiorom.h index 90f9ef02..a4ad8331 100644 --- a/base/gsiorom.h +++ b/base/gsiorom.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsipar3x.h b/base/gsipar3x.h index 2cf6e3d9..e0538f0a 100644 --- a/base/gsipar3x.h +++ b/base/gsipar3x.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiparam.h b/base/gsiparam.h index 8fc9172c..365c625a 100644 --- a/base/gsiparam.h +++ b/base/gsiparam.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiparm3.h b/base/gsiparm3.h index 14a249ec..760cfbf8 100644 --- a/base/gsiparm3.h +++ b/base/gsiparm3.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsiparm4.h b/base/gsiparm4.h index c9f0e704..2b3ad801 100644 --- a/base/gsiparm4.h +++ b/base/gsiparm4.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsjconf.h b/base/gsjconf.h index 18de9026..e4376432 100644 --- a/base/gsjconf.h +++ b/base/gsjconf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsjmorec.h b/base/gsjmorec.h index 2d2cb051..3a90347d 100644 --- a/base/gsjmorec.h +++ b/base/gsjmorec.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gslib.c b/base/gslib.c index ee21b5d8..ef426b45 100644 --- a/base/gslib.c +++ b/base/gslib.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gslib.h b/base/gslib.h index 2291fbca..881403bf 100644 --- a/base/gslib.h +++ b/base/gslib.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gslibctx.c b/base/gslibctx.c index 63dfbe2e..6dfed6cd 100644 --- a/base/gslibctx.c +++ b/base/gslibctx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -629,7 +629,18 @@ rewrite_percent_specifiers(char *s) *s == 'X') { /* Success! */ memset(match_start, '*', s - match_start + 1); - return; + } + /* If we have escaped percents ("%%") so the percent + will survive a call to sprintf and co, then we need + to drop the extra one here, because the validation + code will see the string *after* it's been sprintf'ed. + */ + else if (*s == '%') { + char *s0 = s; + while (*s0) { + *s0 = *(s0 + 1); + s0++; + } } } } @@ -825,13 +836,13 @@ gs_add_control_path_len_flags(const gs_memory_t *mem, gs_path_control_t type, co int gs_add_control_path(const gs_memory_t *mem, gs_path_control_t type, const char *path) { - return gs_add_control_path_len_flags(mem, type, path, strlen(path), 0); + return gs_add_control_path_len_flags(mem, type, path, path ? strlen(path) : 0, 0); } int gs_add_control_path_flags(const gs_memory_t *mem, gs_path_control_t type, const char *path, int flags) { - return gs_add_control_path_len_flags(mem, type, path, strlen(path), flags); + return gs_add_control_path_len_flags(mem, type, path, path ? strlen(path) : 0, flags); } int @@ -1104,13 +1115,35 @@ gs_lib_ctx_stash_sanitized_arg(gs_lib_ctx_t *ctx, const char *arg) switch (arg[1]) { case 0: /* We can let - through unchanged */ + case '-': /* Need to check for permitted file lists */ + /* By default, we want to keep the key, but lose the value */ + p = arg+2; + while (*p && *p != '=') + p++; + if (*p == '=') + p++; + if (*p == 0) + break; /* No value to elide */ + /* Check for our blocked values here */ +#define ARG_MATCHES(STR, ARG, LEN) \ + (strlen(STR) == LEN && !memcmp(STR, ARG, LEN)) + if (ARG_MATCHES("permit-file-read", arg+2, p-arg-3)) + elide=1; + if (ARG_MATCHES("permit-file-write", arg+2, p-arg-3)) + elide=1; + if (ARG_MATCHES("permit-file-control", arg+2, p-arg-3)) + elide=1; + if (ARG_MATCHES("permit-file-all", arg+2, p-arg-3)) + elide=1; +#undef ARG_MATCHES + /* Didn't match a blocked value, so allow it. */ + break; case 'd': /* We can let -dFoo= through unchanged */ case 'D': /* We can let -DFoo= through unchanged */ case 'r': /* We can let -r through unchanged */ case 'Z': /* We can let -Z through unchanged */ case 'g': /* We can let -g through unchanged */ case 'P': /* We can let -P through unchanged */ - case '-': /* We can let -- through unchanged */ case '+': /* We can let -+ through unchanged */ case '_': /* We can let -_ through unchanged */ case 'u': /* We can let -u through unchanged */ @@ -1148,6 +1181,8 @@ gs_lib_ctx_stash_sanitized_arg(gs_lib_ctx_t *ctx, const char *arg) break; if (ARG_MATCHES("ColorConversionStrategy", arg+2, p-arg-3)) break; + if (ARG_MATCHES("NupControl", arg+2, p-arg-3)) + break; if (ARG_MATCHES("PageList", arg+2, p-arg-3)) break; if (ARG_MATCHES("ProcessColorModel", arg+2, p-arg-3)) diff --git a/base/gslibctx.h b/base/gslibctx.h index 9f814b5c..0acb520c 100644 --- a/base/gslibctx.h +++ b/base/gslibctx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsline.c b/base/gsline.c index 5107e5db..3e8362fa 100644 --- a/base/gsline.c +++ b/base/gsline.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsline.h b/base/gsline.h index b2fa402b..ebf0854b 100644 --- a/base/gsline.h +++ b/base/gsline.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gslparam.h b/base/gslparam.h index c4245bf2..ce42aabc 100644 --- a/base/gslparam.h +++ b/base/gslparam.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmalloc.c b/base/gsmalloc.c index 58047c9b..e5eae62e 100644 --- a/base/gsmalloc.c +++ b/base/gsmalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -450,17 +450,23 @@ gs_heap_stable(gs_memory_t *mem) /* * NB: In a multi-threaded application, this is only a 'snapshot' * since other threads may change the heap_status. The heap_available() - * probe is just an approximation anyway. + * probe is just an approximation anyway. To pacify helgrind, we lock + * around the modificatons to the gs_memory_status that is returned. */ static void gs_heap_status(gs_memory_t * mem, gs_memory_status_t * pstat) { gs_malloc_memory_t *mmem = (gs_malloc_memory_t *) mem; + long avail_snapshot = heap_available(); - pstat->allocated = mmem->used + heap_available(); + if (mmem->monitor) + gx_monitor_enter(mmem->monitor); + pstat->allocated = mmem->used + avail_snapshot; pstat->used = mmem->used; pstat->max_used = mmem->max_used; pstat->is_thread_safe = true; /* this allocator has a mutex (monitor) and IS thread safe */ + if (mmem->monitor) + gx_monitor_leave(mmem->monitor); /* Done with exclusive access */ } static void gs_heap_enable_free(gs_memory_t * mem, bool enable) diff --git a/base/gsmalloc.h b/base/gsmalloc.h index 44374c03..a4b10f00 100644 --- a/base/gsmalloc.h +++ b/base/gsmalloc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmatrix.c b/base/gsmatrix.c index 6e70fa6e..b7780207 100644 --- a/base/gsmatrix.c +++ b/base/gsmatrix.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmatrix.h b/base/gsmatrix.h index ba365da1..4c94a61d 100644 --- a/base/gsmatrix.h +++ b/base/gsmatrix.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -26,7 +26,7 @@ /* transformation matrices. */ /* if you make any additions/changes to the gs_matrix_s structure or the - _matrix_body macro you need to make the appropriate additions/changes + _matrix_body macro you need to make the appropriate additions/changes to the gs_matrix_compare() function in gsmatrix.c */ /* Structure for a transformation matrix. */ #define _matrix_body\ diff --git a/base/gsmchunk.c b/base/gsmchunk.c index 33c45cd4..1fec7acd 100644 --- a/base/gsmchunk.c +++ b/base/gsmchunk.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -141,8 +141,8 @@ typedef struct chunk_obj_node_s { unsigned int sequence; #endif struct chunk_obj_node_s *defer_next; - uint size; /* Actual size of block */ - uint padding; /* Actual size - requested size */ + size_t size; /* Actual size of block */ + size_t padding; /* Actual size - requested size */ } chunk_obj_node_t; typedef struct chunk_free_node_s { @@ -150,7 +150,7 @@ typedef struct chunk_free_node_s { struct chunk_free_node_s *right_loc; struct chunk_free_node_s *left_size; struct chunk_free_node_s *right_size; - uint size; /* size of entire freelist block */ + size_t size; /* size of entire freelist block */ } chunk_free_node_t; /* @@ -169,9 +169,9 @@ typedef struct gs_memory_chunk_s { chunk_free_node_t *free_loc; /* free tree */ chunk_obj_node_t *defer_finalize_list; chunk_obj_node_t *defer_free_list; - unsigned long used; - unsigned long max_used; - unsigned long total_free; + size_t used; + size_t max_used; + size_t total_free; #ifdef DEBUG_SEQ unsigned int sequence; #endif @@ -755,12 +755,12 @@ static void remove_free(gs_memory_chunk_t *cmem, chunk_free_node_t *node) /* All of the allocation routines reduce to this function */ static byte * -chunk_obj_alloc(gs_memory_t *mem, uint size, gs_memory_type_ptr_t type, client_name_t cname) +chunk_obj_alloc(gs_memory_t *mem, size_t size, gs_memory_type_ptr_t type, client_name_t cname) { gs_memory_chunk_t *cmem = (gs_memory_chunk_t *)mem; chunk_free_node_t **ap, **okp; chunk_free_node_t *a, *b, *c; - uint newsize; + size_t newsize; chunk_obj_node_t *obj = NULL; newsize = round_up_to_align(size + SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); /* space we will need */ @@ -778,10 +778,10 @@ chunk_obj_alloc(gs_memory_t *mem, uint size, gs_memory_type_ptr_t type, client_n #ifdef DEBUG_CHUNK_PRINT #ifdef DEBUG_SEQ - dmlprintf4(cmem->target, "Event %x: malloc(chunk="PRI_INTPTR", size=%x, cname=%s)\n", + dmlprintf4(cmem->target, "Event %x: malloc(chunk="PRI_INTPTR", size="PRIxSIZE", cname=%s)\n", cmem->sequence, (intptr_t)cmem, newsize, cname); #else - dmlprintf3(cmem->target, "malloc(chunk="PRI_INTPTR", size=%x, cname=%s)\n", + dmlprintf3(cmem->target, "malloc(chunk="PRI_INTPTR", size="PRIxSIZE", cname=%s)\n", (intptr_t)cmem, newsize, cname); #endif #endif @@ -951,14 +951,14 @@ chunk_obj_alloc(gs_memory_t *mem, uint size, gs_memory_type_ptr_t type, client_n obj->sequence = cmem->sequence; #endif if (gs_debug_c('A')) - dmlprintf3(mem, "[a+]chunk_obj_alloc (%s)(%u) = "PRI_INTPTR": OK.\n", + dmlprintf3(mem, "[a+]chunk_obj_alloc (%s)(%"PRIuSIZE") = "PRI_INTPTR": OK.\n", client_name_string(cname), size, (intptr_t) obj); #ifdef DEBUG_CHUNK_PRINT #ifdef DEBUG_SEQ - dmlprintf5(cmem->target, "Event %x: malloced(chunk="PRI_INTPTR", addr="PRI_INTPTR", size=%x, cname=%s)\n", + dmlprintf5(cmem->target, "Event %x: malloced(chunk="PRI_INTPTR", addr="PRI_INTPTR", size=%"PRIxSIZE", cname=%s)\n", obj->sequence, (intptr_t)cmem, (intptr_t)obj, obj->size, cname); #else - dmlprintf4(cmem->target, "malloced(chunk="PRI_INTPTR", addr="PRI_INTPTR", size=%x, cname=%s)\n", + dmlprintf4(cmem->target, "malloced(chunk="PRI_INTPTR", addr="PRI_INTPTR", size=%"PRI_xSIZE", cname=%s)\n", (intptr_t)cmem, (intptr_t)obj, obj->size, cname); #endif #endif diff --git a/base/gsmchunk.h b/base/gsmchunk.h index 50200e7a..2ecf7de8 100644 --- a/base/gsmchunk.h +++ b/base/gsmchunk.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmd5.c b/base/gsmd5.c index db8c6ed8..b190cafa 100644 --- a/base/gsmd5.c +++ b/base/gsmd5.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1999-2020 Artifex Software, Inc. + Copyright (C) 1999-2021 Artifex Software, Inc. All rights reserved. This software is provided 'as-is', without any express or implied diff --git a/base/gsmd5.h b/base/gsmd5.h index 61305928..9715ce83 100644 --- a/base/gsmd5.h +++ b/base/gsmd5.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1999-2020 Artifex Software, Inc. + Copyright (C) 1999-2021 Artifex Software, Inc. All rights reserved. This software is provided 'as-is', without any express or implied diff --git a/base/gsmdebug.h b/base/gsmdebug.h index 5c9c8762..197107d0 100644 --- a/base/gsmdebug.h +++ b/base/gsmdebug.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmemory.c b/base/gsmemory.c index 99a801f5..87eeed77 100644 --- a/base/gsmemory.c +++ b/base/gsmemory.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -231,6 +231,8 @@ rc_object_type_name(const void *vp, const rc_header *prc) if (prc->memory == 0) return "(unknown)"; pstype = gs_object_type(prc->memory, vp); + if ((uintptr_t)pstype < 10000) + return ("?????"); if (prc->free != rc_free_struct_only) { /* * This object might be stack-allocated or have other unusual memory @@ -242,7 +244,7 @@ rc_object_type_name(const void *vp, const rc_header *prc) dist = (const char *)&dist - (const char *)vp; if (dist < 10000 && dist > -10000) return "(on stack)"; - if ((uintptr_t)pstype < 0x10000 || (uintptr_t)pstype < 0) + if ((uintptr_t)pstype < 0x10000) return "(anomalous)"; } return client_name_string(gs_struct_type_name(pstype)); diff --git a/base/gsmemory.h b/base/gsmemory.h index 375c2fb7..5be297ea 100644 --- a/base/gsmemory.h +++ b/base/gsmemory.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmemraw.h b/base/gsmemraw.h index 7782ca07..ab5d9bc1 100644 --- a/base/gsmemraw.h +++ b/base/gsmemraw.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmemret.c b/base/gsmemret.c index 505f1f40..adc86b3c 100644 --- a/base/gsmemret.c +++ b/base/gsmemret.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmemret.h b/base/gsmemret.h index c689bcfb..330e630f 100644 --- a/base/gsmemret.h +++ b/base/gsmemret.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsmisc.c b/base/gsmisc.c index f0604ef3..db73c007 100644 --- a/base/gsmisc.c +++ b/base/gsmisc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -198,9 +198,11 @@ eprintf_program_ident(const char *program_name, if (program_name) { epf((revision_number ? "%s " : "%s"), program_name); if (revision_number) { - int fpart = revision_number % 100; + int major = (int)(revision_number / 1000); + int minor = (int)(revision_number - (major * 1000)) / 10; + int patch = revision_number % 10; - epf("%d.%02d", (int)(revision_number / 100), fpart); + epf("%d.%02d.%d", major, minor, patch); } epf(": "); } diff --git a/base/gsnamecl.c b/base/gsnamecl.c index 6de40ac1..2af52384 100644 --- a/base/gsnamecl.c +++ b/base/gsnamecl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsnamecl.h b/base/gsnamecl.h index d9acfb7a..556d6835 100644 --- a/base/gsnamecl.h +++ b/base/gsnamecl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsncdummy.c b/base/gsncdummy.c index 352f9379..631bf2c4 100644 --- a/base/gsncdummy.c +++ b/base/gsncdummy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsncdummy.h b/base/gsncdummy.h index 2b9acd59..0a9bd5bc 100644 --- a/base/gsncdummy.h +++ b/base/gsncdummy.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsnogc.c b/base/gsnogc.c index 717179ee..8edb35ff 100644 --- a/base/gsnogc.c +++ b/base/gsnogc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsnogc.h b/base/gsnogc.h index 7c61bafb..04017ea1 100644 --- a/base/gsnogc.h +++ b/base/gsnogc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsnotify.c b/base/gsnotify.c index f4544073..c4c917c5 100644 --- a/base/gsnotify.c +++ b/base/gsnotify.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsnotify.h b/base/gsnotify.h index 608a2c20..f1a04c51 100644 --- a/base/gsnotify.h +++ b/base/gsnotify.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsovrc.c b/base/gsovrc.c index 38ad867c..16cd729c 100644 --- a/base/gsovrc.c +++ b/base/gsovrc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1426,6 +1426,19 @@ overprint_dev_spec_op(gx_device* pdev, int dev_spec_op, if (dev_spec_op == gxdso_overprint_active) return !opdev->is_idle; + if (dev_spec_op == gxdso_device_child) { + gxdso_device_child_request *d = (gxdso_device_child_request *)data; + if (d->target == pdev) { + d->target = tdev; + return 1; + } + } + if (dev_spec_op == gxdso_device_insert_child) { + opdev->target = (gx_device *)data; + rc_increment(opdev->target); + rc_decrement_only(tdev, "overprint_dev_spec_op"); + return 0; + } return dev_proc(tdev, dev_spec_op)(tdev, dev_spec_op, data, size); } @@ -1473,6 +1486,7 @@ c_overprint_create_default_compositor( const gs_overprint_t * ovrpct = (const gs_overprint_t *)pct; overprint_device_t * opdev = 0; gs_overprint_params_t params; + int code; /* see if there is anything to do */ if ( !ovrpct->params.retain_any_comps) { @@ -1525,5 +1539,8 @@ c_overprint_create_default_compositor( opdev->retain_none_stroke = true; /* set up the overprint parameters */ - return update_overprint_params(opdev, ¶ms); + code = update_overprint_params(opdev, ¶ms); + if (code < 0) + return code; + return 1; } diff --git a/base/gsovrc.h b/base/gsovrc.h index 39f0e890..790fcaf5 100644 --- a/base/gsovrc.h +++ b/base/gsovrc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspaint.c b/base/gspaint.c index a4dc31d8..70ff0ce6 100644 --- a/base/gspaint.c +++ b/base/gspaint.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -712,10 +712,10 @@ static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart) abits = 0; { gx_device_color *col_fill = gs_currentdevicecolor_inline(pgs); - gx_device_color *col_stroke = gs_altdevicecolor_inline(pgs); + gx_device_color *col_stroke = gs_swappeddevicecolor_inline(pgs); devn = color_is_devn(col_fill) && color_is_devn(col_stroke); /* could be devn and masked_devn */ - if (color_is_pure(col_fill) || color_is_pure(col_stroke) || devn) + if ((color_is_pure(col_fill) && color_is_pure(col_stroke)) || devn) abits = alpha_buffer_bits(pgs); } if (abits > 1) { @@ -778,11 +778,11 @@ static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart) } } out: - if (gx_dc_is_pattern1_color(gs_altdevicecolor_inline(pgs))) { + if (gx_dc_is_pattern1_color(gs_swappeddevicecolor_inline(pgs))) { gs_id id; - if (gs_altdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) { - id = gs_altdevicecolor_inline(pgs)->colors.pattern.p_tile->id; + if (gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) { + id = gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile->id; rcode = gx_pattern_cache_entry_set_lock(pgs, id, false); if (rcode < 0) return rcode; /* unlock failed -- shouldn't be possible */ diff --git a/base/gspaint.h b/base/gspaint.h index 214c6e52..81be10b6 100644 --- a/base/gspaint.h +++ b/base/gspaint.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsparam.c b/base/gsparam.c index a5741565..e8a2f0c5 100644 --- a/base/gsparam.c +++ b/base/gsparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -200,7 +200,7 @@ param_coerce_typed(gs_param_typed_value * pvalue, gs_param_type req_type, } case gs_param_type_float: { - float fl = (float)pvalue->value.l; + float fl = (float)pvalue->value.i; pvalue->value.f = fl; goto ok; } @@ -274,9 +274,9 @@ param_coerce_typed(gs_param_typed_value * pvalue, gs_param_type req_type, } case gs_param_type_int: { - int int1 = (int)pvalue->value.l; + int int1 = (int)pvalue->value.i64; #if ARCH_SIZEOF_INT < 8 /* sizeof(int64_t) */ - if (pvalue->value.i64 != (int)int1) + if (pvalue->value.i64 != (int64_t)int1) return_error(gs_error_rangecheck); #endif pvalue->value.i = int1; @@ -309,9 +309,9 @@ param_coerce_typed(gs_param_typed_value * pvalue, gs_param_type req_type, } case gs_param_type_long: { - long l = (long)pvalue->value.i64; + long l = (long)pvalue->value.z; #if ARCH_SIZEOF_LONG < 8 /* sizeof(int64_t) */ - if (pvalue->value.i64 != (int64_t)l) + if (pvalue->value.z != (size_t)l) return_error(gs_error_rangecheck); #endif pvalue->value.l = l; @@ -319,9 +319,9 @@ param_coerce_typed(gs_param_typed_value * pvalue, gs_param_type req_type, } case gs_param_type_int: { - int int1 = (int)pvalue->value.l; + int int1 = (int)pvalue->value.z; #if ARCH_SIZEOF_INT < 8 /* sizeof(int64_t) */ - if (pvalue->value.i64 != (int)int1) + if (pvalue->value.z != (size_t)int1) return_error(gs_error_rangecheck); #endif pvalue->value.i = int1; @@ -329,7 +329,7 @@ param_coerce_typed(gs_param_typed_value * pvalue, gs_param_type req_type, } case gs_param_type_float: { - float fl = (float)pvalue->value.i64; + float fl = (float)pvalue->value.z; pvalue->value.f = fl; goto ok; } diff --git a/base/gsparam.h b/base/gsparam.h index 3b0aaa21..43cc92d8 100644 --- a/base/gsparam.h +++ b/base/gsparam.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -577,4 +577,8 @@ int gs_param_list_add_parsed_value(gs_param_list *plist, gs_param_name key, cons * address pointed to be len. */ int gs_param_list_to_string(gs_param_list *plist, gs_param_name key, char *value, int *len); +/* Debug function to dump a list of params. Do NOT use in production + * code! */ +int gs_param_list_dump(gs_param_list *plist); + #endif /* gsparam_INCLUDED */ diff --git a/base/gsparam2.c b/base/gsparam2.c index cafd9041..949acf9a 100644 --- a/base/gsparam2.c +++ b/base/gsparam2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsparaml.c b/base/gsparaml.c index d7e5fcdb..3516a157 100644 --- a/base/gsparaml.c +++ b/base/gsparaml.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1046,3 +1046,31 @@ int gs_param_list_to_string(gs_param_list *plist, gs_param_name key, char *value *value = 0; return to_string(plist, key, &out); } + +int gs_param_list_dump(gs_param_list *plist) +{ + gs_param_enumerator_t enumerator; + gs_param_key_t key; + int code; + char buffer[4096]; + int len; + + param_init_enumerator(&enumerator); + while ((code = param_get_next_key(plist, &enumerator, &key)) == 0) { + char string_key[256]; /* big enough for any reasonable key */ + + if (key.size > sizeof(string_key) - 1) { + code = gs_note_error(gs_error_rangecheck); + break; + } + memcpy(string_key, key.data, key.size); + string_key[key.size] = 0; + dlprintf1("%s ", string_key); + code = gs_param_list_to_string(plist, string_key, buffer, &len); + if (code < 0) + break; + dlprintf1("%s ", buffer); + } + dlprintf("\n"); + return code; +} diff --git a/base/gsparams.c b/base/gsparams.c index b7c06251..cc68ce1a 100644 --- a/base/gsparams.c +++ b/base/gsparams.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsparams.h b/base/gsparams.h index 676e5743..0ad4b0d6 100644 --- a/base/gsparams.h +++ b/base/gsparams.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsparamx.c b/base/gsparamx.c index 266da47f..2893253a 100644 --- a/base/gsparamx.c +++ b/base/gsparamx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsparamx.h b/base/gsparamx.h index f73cc18c..0bc785d2 100644 --- a/base/gsparamx.h +++ b/base/gsparamx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspath.c b/base/gspath.c index 02d4c54b..a18278e8 100644 --- a/base/gspath.c +++ b/base/gspath.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -324,7 +324,7 @@ static int common_clip(gs_gstate *, int); /* Figure out the bbox for a path and a clip path with adjustment if we are also doing a stroke. This is used by the xps interpeter to deteremine - how big of a transparency group or softmask should be pushed. Often in + how big of a transparency group or softmask should be pushed. Often in xps we fill a path with a particular softmask and some other graphic object. The transparency group will be the intersection of the path and clipping path */ diff --git a/base/gspath.h b/base/gspath.h index 0d1ac9e8..ddf47968 100644 --- a/base/gspath.h +++ b/base/gspath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspath1.c b/base/gspath1.c index 96d19d5d..e9b91b06 100644 --- a/base/gspath1.c +++ b/base/gspath1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspath2.h b/base/gspath2.h index b0cf8bb3..325ce7e8 100644 --- a/base/gspath2.h +++ b/base/gspath2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspcolor.c b/base/gspcolor.c index 7efa2900..4fb53680 100644 --- a/base/gspcolor.c +++ b/base/gspcolor.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspcolor.h b/base/gspcolor.h index 5673fae8..abd43052 100644 --- a/base/gspcolor.h +++ b/base/gspcolor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspenum.h b/base/gspenum.h index b021acd8..bdba5dad 100644 --- a/base/gspenum.h +++ b/base/gspenum.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspmdrv.c b/base/gspmdrv.c index 78281b17..759d5e60 100644 --- a/base/gspmdrv.c +++ b/base/gspmdrv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspmdrv.h b/base/gspmdrv.h index e0c20c6e..e1837396 100644 --- a/base/gspmdrv.h +++ b/base/gspmdrv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gspmdrv.rc b/base/gspmdrv.rc index de6eae11..09e41830 100644 --- a/base/gspmdrv.rc +++ b/base/gspmdrv.rc @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -27,7 +27,7 @@ BEGIN ICON ID_GSPMDRV, ID_GSPMDRV, 8, 56, 20, 16, WS_GROUP LTEXT "Ghostscript Presentation Manager Driver", -1, 34, 64, 210, 8 LTEXT GSPMDRV_VERSION, -1, 34, 56, 210, 8 - LTEXT "Copyright (C) 1992, 1993, 2001-2020 Artifex Software Inc.", -1, 34, 48, 210, 8 + LTEXT "Copyright (C) 1992, 1993, 2001-2021 Artifex Software Inc.", -1, 34, 48, 210, 8 LTEXT "All rights reserved", -1, 34, 40, 210, 8 PUSHBUTTON "OK", DID_OK, 105, 8, 40, 14 END diff --git a/base/gsptype1.c b/base/gsptype1.c index 92b1f278..c4589488 100644 --- a/base/gsptype1.c +++ b/base/gsptype1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -119,10 +119,10 @@ gs_pattern1_init(gs_pattern1_template_t * ppat) /* Make an instance of a PatternType 1 pattern. */ static int compute_inst_matrix(gs_pattern1_instance_t *pinst, - gs_gstate *saved, - gs_rect *pbbox, - int width, int height, + gs_rect *pbbox, int width, int height, float *bbw, float *bbh); +static int fix_bbox_after_matrix_adjustment(gs_pattern1_instance_t *pinst, + gs_rect *pbbox); int gs_makepattern(gs_client_color * pcc, const gs_pattern1_template_t * pcp, const gs_matrix * pmat, gs_gstate * pgs, gs_memory_t * mem) @@ -185,7 +185,7 @@ gs_pattern1_make_pattern(gs_client_color * pcc, goto fsaved; } inst.templat = *pcp; - code = compute_inst_matrix(&inst, saved, &bbox, dev_width, dev_height, &bbw, &bbh); + code = compute_inst_matrix(&inst, &bbox, dev_width, dev_height, &bbw, &bbh); if (code < 0) goto fsaved; @@ -194,22 +194,11 @@ gs_pattern1_make_pattern(gs_client_color * pcc, to detect this since blending is expensive and we would like to avoid it if possible. Note that any skew or rotation matrix will make it neccessary to perform blending */ - - { float width = inst.templat.BBox.q.x - inst.templat.BBox.p.x; - float height = inst.templat.BBox.q.y - inst.templat.BBox.p.y; - - if ( inst.templat.XStep < width || inst.templat.YStep < height || ctm_only(saved).xy != 0 || - ctm_only(saved).yx != 0 ){ - - inst.has_overlap = true; - - } else { - - inst.has_overlap = false; - - } - - } + inst.has_overlap = + (inst.templat.XStep < inst.templat.BBox.q.x - inst.templat.BBox.p.x || + inst.templat.YStep < inst.templat.BBox.q.y - inst.templat.BBox.p.y || + ctm_only(saved).xy != 0 || + ctm_only(saved).yx != 0 ); #define mat inst.step_matrix if_debug6m('t', mem, "[t]step_matrix=[%g %g %g %g %g %g]\n", @@ -217,140 +206,168 @@ gs_pattern1_make_pattern(gs_client_color * pcc, inst.step_matrix.yy, inst.step_matrix.tx, inst.step_matrix.ty); if_debug5m('t', mem, "[t]bbox=(%g,%g),(%g,%g), uses_transparency=%d\n", bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y, inst.templat.uses_transparency); - { - /* If the step and the size agree to within 1/2 pixel, */ - /* make them the same. */ - if (ADJUST_SCALE_BY_GS_TRADITION) { - inst.size.x = (int)(bbw + 0.8); /* 0.8 is arbitrary */ - inst.size.y = (int)(bbh + 0.8); - } else { - inst.size.x = (int)ceil(bbw); - inst.size.y = (int)ceil(bbh); - } - if (inst.size.x == 0 || inst.size.y == 0) { - /* - * The pattern is empty: the stepping matrix doesn't matter. - */ - gs_make_identity(&inst.step_matrix); - bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0; - } else { - /* Check for singular stepping matrix. */ - if (fabs(inst.step_matrix.xx * inst.step_matrix.yy - inst.step_matrix.xy * inst.step_matrix.yx) < 1.0e-9) { - code = gs_note_error(gs_error_rangecheck); - goto fsaved; + /* If the step and the size agree to within 1/2 pixel, */ + /* make them the same. */ + if (ADJUST_SCALE_BY_GS_TRADITION) { + inst.size.x = (int)(bbw + 0.8); /* 0.8 is arbitrary */ + inst.size.y = (int)(bbh + 0.8); + } else if (inst.templat.TilingType == 2) { + /* Always round up for TilingType 2, as we don't want any + * content to be lost. */ + inst.size.x = (int)ceil(bbw); + inst.size.y = (int)ceil(bbh); + } else { + /* For TilingType's other than 2 allow us to round up or down + * to whatever is nearer. The scale we do later prevents us + * losing content. */ + inst.size.x = (int)floor(bbw+0.5); + inst.size.y = (int)floor(bbh+0.5); + /* Ensure we never round down to 0. */ + if (bbw > 0 && inst.size.x == 0) + inst.size.x = 1; + if (bbh > 0 && inst.size.y == 0) + inst.size.y = 1; + } + + /* After compute_inst_matrix above, we are guaranteed that + * inst.step_matrix.xx > 0 and inst.step_matrix.yy > 0. + * Similarly, we are guaranteed that inst.size.x >= 0 and + * inst.size.y >= 0. */ + if (inst.size.x == 0 || inst.size.y == 0) { + /* The pattern is empty: the stepping matrix doesn't matter. */ + gs_make_identity(&inst.step_matrix); + bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0; + } else if (fabs(inst.step_matrix.xx * inst.step_matrix.yy - + inst.step_matrix.xy * inst.step_matrix.yx) < 1.0e-9) { + /* Singular stepping matrix. */ + code = gs_note_error(gs_error_rangecheck); + goto fsaved; + } else if (ADJUST_SCALE_BY_GS_TRADITION && + inst.step_matrix.xy == 0 && inst.step_matrix.yx == 0 && + fabs(inst.step_matrix.xx - bbw) < 0.5 && + fabs(inst.step_matrix.yy - bbh) < 0.5) { + gs_scale(saved, inst.size.x / inst.step_matrix.xx, + inst.size.y / inst.step_matrix.yy); + if (ADJUST_SCALE_FOR_THIN_LINES) { + /* To allow thin lines at a cell boundary to be painted + * inside the cell, we adjust the scale so that the scaled + * width is in fixed_1 smaller. */ + gs_scale(saved, (inst.size.x - 1.0 / fixed_scale) / inst.size.x, + (inst.size.y - 1.0 / fixed_scale) / inst.size.y); + } + code = compute_inst_matrix(&inst, &bbox, + dev_width, dev_height, &bbw, &bbh); + if (code < 0) + goto fsaved; + if_debug2m('t', mem, + "[t]adjusted XStep & YStep to size=(%d,%d)\n", + inst.size.x, inst.size.y); + if_debug4m('t', mem, "[t]bbox=(%g,%g),(%g,%g)\n", + bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); + } else if ((ADJUST_AS_ADOBE) && (inst.templat.TilingType != 2)) { + if (inst.step_matrix.xy == 0 && inst.step_matrix.yx == 0 && + fabs(inst.step_matrix.xx - bbw) < 0.5 && + fabs(inst.step_matrix.yy - bbh) < 0.5) { + if (inst.step_matrix.xx <= 2) { + /* Prevent a degradation - see -r72 mspro.pdf */ + gs_scale(saved, fabs(inst.size.x / inst.step_matrix.xx), 1); + inst.step_matrix.xx = (float)inst.size.x; + } else { + float cx, ox, dx; + /* We adjust the step matrix to an integer (as we + * can't quickly tile non-integer tiles). We bend + * the contents of the tile slightly so that they + * completely fill the tile (rather than potentially + * leaving gaps around the edge). + * To allow thin lines at a cell boundary to be painted + * inside the cell, we adjust the scale so that the + * scaled width is fixed_1 smaller. */ + gs_scale(saved, + (inst.size.x - 1.0 / fixed_scale) / inst.step_matrix.xx, + 1); + /* We want the point in the centre of the displayed + region of this pattern not to move. We don't know + where the displayed region of the pattern is, so + we take the centre of the pattern bbox as a guess. + We call this (cx,cy). Let's suppose that this point + is the image of (ox,oy) under transformation. + + (a 0 0) + (0 d 0) + (x y 1) + (ox oy 1)(ox.a+x oy.d+y 1) + + Thus cx = ox.a + x, cy = oy.d + y + So ox = (cx - x)/a, oy = (cy - y)/d + + We want to adjust the matrix to use A and D instead + of a and d, and also adjust x and y so that the image + of (ox,oy) is the same. + + i.e. (A 0 0) + (0 D 0) + (X Y 1) + (ox oy 1)(ox.A+X oy.D+Y 1) + + i.e. cx = ox.A+X, cy = oy.D+Y + So X = cx - ox.A + x = cx - ox.a + x-X = -ox.a + ox.A + = ox.(A-a) + + BUT we've been at pains already to make sure that the + origin of the 0th tile falls on pixel boundaries. So + clamp our correction to whole pixels. + */ + cx = (bbox.p.x + bbox.q.x)/2; + ox = (cx - inst.step_matrix.tx) / inst.step_matrix.xx; + dx = ox * (inst.size.x - inst.step_matrix.xx); + dx = floor(dx+0.5); /* Whole pixels! */ + inst.step_matrix.xx = (float)inst.size.x; + inst.saved->ctm.tx -= dx; } - if (ADJUST_SCALE_BY_GS_TRADITION && - inst.step_matrix.xy == 0 && inst.step_matrix.yx == 0 && - fabs(fabs(inst.step_matrix.xx) - bbw) < 0.5 && - fabs(fabs(inst.step_matrix.yy) - bbh) < 0.5 - ) { - gs_scale(saved, fabs(inst.size.x / inst.step_matrix.xx), - fabs(inst.size.y / inst.step_matrix.yy)); - code = compute_inst_matrix(&inst, saved, &bbox, - dev_width, dev_height, &bbw, &bbh); - if (code < 0) - goto fsaved; - if (ADJUST_SCALE_FOR_THIN_LINES) { - /* To allow thin lines at a cell boundary - to be painted inside the cell, - we adjust the scale so that - the scaled width is in fixed_1 smaller */ - gs_scale(saved, (fabs(inst.size.x) - 1.0 / fixed_scale) / fabs(inst.size.x), - (fabs(inst.size.y) - 1.0 / fixed_scale) / fabs(inst.size.y)); - } - if_debug2m('t', mem, - "[t]adjusted XStep & YStep to size=(%d,%d)\n", - inst.size.x, inst.size.y); - if_debug4m('t', mem, "[t]bbox=(%g,%g),(%g,%g)\n", - bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); - } else if ((ADJUST_AS_ADOBE) && (inst.templat.TilingType != 2)) { - if (inst.step_matrix.xy == 0 && inst.step_matrix.yx == 0 && - fabs(fabs(inst.step_matrix.xx) - bbw) < 0.5 && - fabs(fabs(inst.step_matrix.yy) - bbh) < 0.5 - ) { - if (inst.step_matrix.xx <= 2) { - /* Prevent a degradation - see -r72 mspro.pdf */ - gs_scale(saved, fabs(inst.size.x / inst.step_matrix.xx), 1); - inst.step_matrix.xx = (float)inst.size.x; - } else { -#if 0 - /* New code from RJW, currently disabled. While - * investigating an XPS pattern problem (caused by - * a pattern with step 7.5 being rendered into an 8x8 - * tile with a fill adjust of 0 having empty edges), - * I considered the following changed code, which seems - * like the right thing to do. It produces many image - * diffs, but none obscenely bad. We leave this - * disabled for now, as the XPS problem has moved by - * dint of us now using TilingType 2 instead. */ - /* We adjust the step matrix to an integer (as we - * can't quickly tile non-integer tiles). We bend - * the contents of the tile slightly so that they - * completely fill the tile (rather than potentially - * leaving gaps around the edge). - * To allow thin lines at a cell boundary to be painted - * inside the cell, we adjust the scale so that the - * scaled width is fixed_1 smaller. */ - float newscale = (float)floor(inst.step_matrix.xx + 0.5); - gs_scale(saved, - (newscale - 1.0 / fixed_scale) / inst.step_matrix.xx, - 1); - inst.step_matrix.xx = newscale; -#else - inst.step_matrix.xx = (float)floor(inst.step_matrix.xx + 0.5); - /* To allow thin lines at a cell boundary - to be painted inside the cell, - we adjust the scale so that - the scaled width is in fixed_1 smaller */ - if (bbw >= inst.size.x - 1.0 / fixed_scale) - gs_scale(saved, (fabs(inst.size.x) - 1.0 / fixed_scale) / fabs(inst.size.x), 1); -#endif - } - if (inst.step_matrix.yy <= 2) { - gs_scale(saved, 1, fabs(inst.size.y / inst.step_matrix.yy)); - inst.step_matrix.yy = (float)inst.size.y; - } else { -#if 0 - /* See above comment for explaination */ - float newscale = (float)floor(inst.step_matrix.yy + 0.5); - gs_scale(saved, - 1, - (newscale - 1.0 / fixed_scale) / inst.step_matrix.yy); - inst.step_matrix.yy = newscale; -#else - inst.step_matrix.yy = (float)floor(inst.step_matrix.yy + 0.5); - if (bbh >= inst.size.y - 1.0 / fixed_scale) - gs_scale(saved, 1, (fabs(inst.size.y) - 1.0 / fixed_scale) / fabs(inst.size.y)); -#endif - } - code = gs_bbox_transform(&inst.templat.BBox, &ctm_only(saved), &bbox); - if (code < 0) - goto fsaved; - } - } else if ((inst.templat.TilingType == 2) && - ((pgs->fill_adjust.x | pgs->fill_adjust.y) == 0)) { - /* RJW: This codes with non-rotated cases (with or without a - * skew), but won't cope with rotated ones. Find an example. */ - float shiftx = ((inst.step_matrix.yx == 0 && - fabs(fabs(inst.step_matrix.xx) - bbw) <= 0.5) ? - (bbw - inst.size.x)/2 : 0); - float shifty = ((inst.step_matrix.xy == 0 && - fabs(fabs(inst.step_matrix.yy) - bbh) <= 0.5) ? - (bbh - inst.size.y)/2 : 0); - gs_translate_untransformed(saved, shiftx, shifty); - code = gs_bbox_transform(&inst.templat.BBox, &ctm_only(saved), &bbox); - if (code < 0) - goto fsaved; + if (inst.step_matrix.yy <= 2) { + gs_scale(saved, 1, inst.size.y / inst.step_matrix.yy); + inst.step_matrix.yy = (float)inst.size.y; + } else { + float cy, oy, dy; + /* See above comment for explanation */ + gs_scale(saved, + 1, + (inst.size.y - 1.0 / fixed_scale) / inst.step_matrix.yy); + cy = (bbox.p.y + bbox.q.y)/2; + oy = (cy - inst.step_matrix.ty) / inst.step_matrix.yy; + dy = oy * (inst.size.y - inst.step_matrix.yy); + dy = floor(dy+0.5); /* Whole pixels! */ + inst.step_matrix.yy = (float)inst.size.y; + inst.saved->ctm.ty -= dy; } + code = fix_bbox_after_matrix_adjustment(&inst, &bbox); + if (code < 0) + goto fsaved; } + } else if ((inst.templat.TilingType == 2) && + ((pgs->fill_adjust.x | pgs->fill_adjust.y) == 0)) { + /* RJW: This codes with non-rotated cases (with or without a + * skew), but won't cope with rotated ones. Find an example. */ + float shiftx = ((inst.step_matrix.yx == 0 && + fabs(inst.step_matrix.xx - bbw) <= 0.5) ? + (bbw - inst.size.x)/2 : 0); + float shifty = ((inst.step_matrix.xy == 0 && + fabs(inst.step_matrix.yy - bbh) <= 0.5) ? + (bbh - inst.size.y)/2 : 0); + gs_translate_untransformed(saved, shiftx, shifty); + code = fix_bbox_after_matrix_adjustment(&inst, &bbox); + if (code < 0) + goto fsaved; } if ((code = gs_bbox_transform_inverse(&bbox, &inst.step_matrix, &inst.bbox)) < 0) goto fsaved; if_debug4m('t', mem, "[t]ibbox=(%g,%g),(%g,%g)\n", inst.bbox.p.x, inst.bbox.p.y, inst.bbox.q.x, inst.bbox.q.y); - inst.is_simple = (fabs(inst.step_matrix.xx) == inst.size.x && inst.step_matrix.xy == 0 && - inst.step_matrix.yx == 0 && fabs(inst.step_matrix.yy) == inst.size.y); + inst.is_simple = (inst.step_matrix.xx == inst.size.x && inst.step_matrix.xy == 0 && + inst.step_matrix.yx == 0 && inst.step_matrix.yy == inst.size.y); if_debug6m('t', mem, "[t]is_simple? xstep=(%g,%g) ystep=(%g,%g) size=(%d,%d)\n", inst.step_matrix.xx, inst.step_matrix.xy, @@ -526,15 +543,50 @@ clamp_pattern_bbox(gs_pattern1_instance_t * pinst, gs_rect * pbbox, return 0; } +static int +adjust_bbox_to_pixel_origin(gs_pattern1_instance_t *pinst, gs_rect *pbbox) +{ + gs_gstate * saved = pinst->saved; + float dx, dy; + int code = 0; + + /* + * Adjust saved.ctm to map the bbox origin to pixels. + */ + dx = pbbox->p.x - floor(pbbox->p.x + 0.5); + dy = pbbox->p.y - floor(pbbox->p.y + 0.5); + if (dx != 0 || dy != 0) { + pbbox->p.x -= dx; + pbbox->p.y -= dy; + pbbox->q.x -= dx; + pbbox->q.y -= dy; + + if (saved->ctm.txy_fixed_valid) { + code = gx_translate_to_fixed(saved, float2fixed_rounded(saved->ctm.tx - dx), + float2fixed_rounded(saved->ctm.ty - dy)); + } else { /* the ctm didn't fit in a fixed. Just adjust the float values */ + saved->ctm.tx -= dx; + saved->ctm.ty -= dy; + /* not sure if this is needed for patterns, but lifted from gx_translate_to_fixed */ + code = gx_path_translate(saved->path, float2fixed(-dx), float2fixed(-dy)); + } + } + pinst->step_matrix.tx = saved->ctm.tx; + pinst->step_matrix.ty = saved->ctm.ty; + + return code; +} + /* Compute the stepping matrix and device space instance bounding box */ /* from the step values and the saved matrix. */ static int -compute_inst_matrix(gs_pattern1_instance_t * pinst, gs_gstate * saved, +compute_inst_matrix(gs_pattern1_instance_t * pinst, gs_rect * pbbox, int width, int height, float *pbbw, float *pbbh) { - float xx, xy, yx, yy, dx, dy, temp; + float xx, xy, yx, yy, temp; int code; + gs_gstate * saved = pinst->saved; gs_matrix m = ctm_only(saved); /* Bug 702124: Due to the limited precision of floats, we find that @@ -554,24 +606,8 @@ compute_inst_matrix(gs_pattern1_instance_t * pinst, gs_gstate * saved, pbbox->p.y += ctm_only(saved).ty; pbbox->q.x += ctm_only(saved).tx; pbbox->q.y += ctm_only(saved).ty; - /* - * Adjust saved.ctm to map the bbox origin to pixels. - */ - dx = pbbox->p.x - floor(pbbox->p.x + 0.5); - dy = pbbox->p.y - floor(pbbox->p.y + 0.5); - pbbox->p.x -= dx; - pbbox->p.y -= dy; - pbbox->q.x -= dx; - pbbox->q.y -= dy; - if (saved->ctm.txy_fixed_valid) { - code = gx_translate_to_fixed(saved, float2fixed_rounded(saved->ctm.tx - dx), - float2fixed_rounded(saved->ctm.ty - dy)); - } else { /* the ctm didn't fit in a fixed. Just adjust the float values */ - saved->ctm.tx -= dx; - saved->ctm.ty -= dy; - /* not sure if this is needed for patterns, but lifted from gx_translate_to_fixed */ - code = gx_path_translate(saved->path, float2fixed(-dx), float2fixed(-dy)); - } + + code = adjust_bbox_to_pixel_origin(pinst, pbbox); if (code < 0) return code; @@ -595,8 +631,7 @@ compute_inst_matrix(gs_pattern1_instance_t * pinst, gs_gstate * saved, pinst->step_matrix.xy = xy; pinst->step_matrix.yx = yx; pinst->step_matrix.yy = yy; - pinst->step_matrix.tx = saved->ctm.tx; - pinst->step_matrix.ty = saved->ctm.ty; + /* * Some applications produce patterns that are larger than the page. * If the bounding box for the pattern is larger than the page. clamp @@ -609,6 +644,23 @@ compute_inst_matrix(gs_pattern1_instance_t * pinst, gs_gstate * saved, return code; } +static int +fix_bbox_after_matrix_adjustment(gs_pattern1_instance_t *pinst, gs_rect *pbbox) +{ + int code; + gs_gstate * saved = pinst->saved; + + code = gs_bbox_transform(&pinst->templat.BBox, &ctm_only(saved), pbbox); + if (code < 0) + return code; + + code = adjust_bbox_to_pixel_origin(pinst, pbbox); + if (code < 0) + return code; + + return code; +} + /* Test whether a PatternType 1 pattern uses a base space. */ static bool gs_pattern1_uses_base_space(const gs_pattern_template_t *ptemp) @@ -822,8 +874,9 @@ mask_PaintProc(const gs_client_color * pcolor, gs_gstate * pgs) gs_image_t_init_mask(&mask, true); mask.Width = pbitmap->size.x; mask.Height = pbitmap->size.y; - gs_image_init(pen, &mask, false, false, pgs); - code = bitmap_paint(pen, (gs_data_image_t *) & mask, pbitmap, pgs); + code = gs_image_init(pen, &mask, false, false, pgs); + if (code >= 0) + code = bitmap_paint(pen, (gs_data_image_t *) & mask, pbitmap, pgs); gs_free_object(gs_gstate_memory(pgs), pen, "mask_PaintProc"); return code; } diff --git a/base/gsptype1.h b/base/gsptype1.h index f1602d36..304d95da 100644 --- a/base/gsptype1.h +++ b/base/gsptype1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsptype2.c b/base/gsptype2.c index 1181fccc..878fbe64 100644 --- a/base/gsptype2.c +++ b/base/gsptype2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsptype2.h b/base/gsptype2.h index fb8ae014..79bafc19 100644 --- a/base/gsptype2.h +++ b/base/gsptype2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsrect.h b/base/gsrect.h index 5aa9bd0e..95b3ccea 100644 --- a/base/gsrect.h +++ b/base/gsrect.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsrefct.h b/base/gsrefct.h index a88c19a4..bfdb1a6f 100644 --- a/base/gsrefct.h +++ b/base/gsrefct.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsromfs0.c b/base/gsromfs0.c index fc30e3bc..83843932 100644 --- a/base/gsromfs0.c +++ b/base/gsromfs0.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsrop.c b/base/gsrop.c index f78ae09c..e2e28044 100644 --- a/base/gsrop.c +++ b/base/gsrop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsrop.h b/base/gsrop.h index 2cbf5201..f7035be9 100644 --- a/base/gsrop.h +++ b/base/gsrop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsroprun.c b/base/gsroprun.c index 3b65cddb..e4f7091e 100644 --- a/base/gsroprun.c +++ b/base/gsroprun.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsroprun1.h b/base/gsroprun1.h index e44b77ad..5a1ee5f6 100644 --- a/base/gsroprun1.h +++ b/base/gsroprun1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsroprun24.h b/base/gsroprun24.h index 0afd02d8..a966e4aa 100644 --- a/base/gsroprun24.h +++ b/base/gsroprun24.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsroprun8.h b/base/gsroprun8.h index fdc1e5e2..e3de6d39 100644 --- a/base/gsroprun8.h +++ b/base/gsroprun8.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsropt.h b/base/gsropt.h index 65c6da87..82980d22 100644 --- a/base/gsropt.h +++ b/base/gsropt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsroptab.c b/base/gsroptab.c index d768dd04..885c048c 100644 --- a/base/gsroptab.c +++ b/base/gsroptab.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsserial.c b/base/gsserial.c index 4eda39d1..21f824f4 100644 --- a/base/gsserial.c +++ b/base/gsserial.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsserial.h b/base/gsserial.h index c30407b1..85826a7b 100644 --- a/base/gsserial.h +++ b/base/gsserial.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsshade.c b/base/gsshade.c index 50c72216..e6421f95 100644 --- a/base/gsshade.c +++ b/base/gsshade.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsshade.h b/base/gsshade.h index 55d7a46b..b0993c05 100644 --- a/base/gsshade.h +++ b/base/gsshade.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gssprintf.c b/base/gssprintf.c index aab4051f..2b24580e 100644 --- a/base/gssprintf.c +++ b/base/gssprintf.c @@ -116,13 +116,13 @@ static const char null_string[] = "(null)"; #define NDIG 80 /* buf must have at least NDIG bytes */ -static char *apr_cvt(double arg, int ndigits, int *decpt, int *sign, +static char *apr_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf) { register int r2; double fi, fj; register char *p, *p1; - + if (ndigits >= NDIG - 1) ndigits = NDIG - 2; r2 = 0; @@ -387,7 +387,7 @@ static char *conv_10(register apr_int32_t num, register int is_unsigned, *is_negative = (num < 0); /* - * On a 2's complement machine, negating the most negative integer + * On a 2's complement machine, negating the most negative integer * results in a number that cannot be represented as a signed integer. * Here is what we do to obtain the number's magnitude: * a. add 1 to the number @@ -402,7 +402,7 @@ static char *conv_10(register apr_int32_t num, register int is_unsigned, } /* - * We use a do-while loop so that we write at least 1 digit + * We use a do-while loop so that we write at least 1 digit */ do { register apr_uint32_t new_magnitude = magnitude / 10; @@ -439,7 +439,7 @@ static char *conv_10_quad(apr_int64_t num, register int is_unsigned, *is_negative = (num < 0); /* - * On a 2's complement machine, negating the most negative integer + * On a 2's complement machine, negating the most negative integer * results in a number that cannot be represented as a signed integer. * Here is what we do to obtain the number's magnitude: * a. add 1 to the number @@ -454,7 +454,7 @@ static char *conv_10_quad(apr_int64_t num, register int is_unsigned, } /* - * We use a do-while loop so that we write at least 1 digit + * We use a do-while loop so that we write at least 1 digit */ do { apr_uint64_t new_magnitude = magnitude / 10; @@ -885,7 +885,7 @@ static int apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *), (sizeof(APR_INT64_T_FMT) == 3 && fmt[0] == APR_INT64_T_FMT[0]) || (sizeof(APR_INT64_T_FMT) > 4 && - strncmp(fmt, APR_INT64_T_FMT, + strncmp(fmt, APR_INT64_T_FMT, sizeof(APR_INT64_T_FMT) - 2) == 0)) { /* Need to account for trailing 'd' and null in sizeof() */ var_type = IS_QUAD; @@ -1413,7 +1413,7 @@ static int apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *), } /* - * Print the string s. + * Print the string s. */ if (print_something == YES) { for (i = s_len; i != 0; i--) { diff --git a/base/gssprintf.h b/base/gssprintf.h index e71fa434..0b5f6d3d 100644 --- a/base/gssprintf.h +++ b/base/gssprintf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsstate.c b/base/gsstate.c index 898b879e..e8077d07 100644 --- a/base/gsstate.c +++ b/base/gsstate.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -44,8 +44,10 @@ /* Forward references */ static gs_gstate *gstate_alloc(gs_memory_t *, client_name_t, const gs_gstate *); -static gs_gstate *gstate_clone(gs_gstate *, gs_memory_t *, client_name_t, - gs_gstate_copy_reason_t); +static gs_gstate *gstate_clone_for_gsave(gs_gstate *, + client_name_t); +static gs_gstate *gstate_clone_for_gstate(const gs_gstate *, gs_memory_t *, + client_name_t); static void gstate_free_contents(gs_gstate *); static int gstate_copy(gs_gstate *, const gs_gstate *, gs_gstate_copy_reason_t, client_name_t); @@ -161,7 +163,7 @@ extern_st(st_gs_gstate); /* for gstate_alloc() */ /* Copy client data, using the copy_for procedure if available, */ /* the copy procedure otherwise. */ static int -gstate_copy_client_data(gs_gstate * pgs, void *dto, void *dfrom, +gstate_copy_client_data(const gs_gstate * pgs, void *dto, void *dfrom, gs_gstate_copy_reason_t reason) { return (pgs->client_procs.copy_for != 0 ? @@ -301,10 +303,9 @@ gs_gstate_free(gs_gstate * pgs) int gs_gsave(gs_gstate * pgs) { - gs_gstate *pnew = gstate_clone(pgs, pgs->memory, "gs_gsave", - copy_for_gsave); + gs_gstate *pnew = gstate_clone_for_gsave(pgs, "gs_gsave"); - if (pnew == 0) + if (pnew == NULL) return_error(gs_error_VMerror); /* As of PLRM3, the interaction between gsave and the clip stack is * now clear. gsave stores the clip stack into the saved graphics @@ -314,10 +315,11 @@ gs_gsave(gs_gstate * pgs) * on pgs->clip_stack, but gstate_clone() has an exception for * the clip_stack field. */ - pgs->clip_stack = 0; + pgs->clip_stack = NULL; pgs->saved = pnew; if (pgs->show_gstate == pgs) pgs->show_gstate = pnew->show_gstate = pnew; + pgs->trans_flags.xstate_change = false; pgs->level++; if_debug2m('g', pgs->memory, "[g]gsave -> "PRI_INTPTR", level = %d\n", (intptr_t)pnew, pgs->level); @@ -461,27 +463,23 @@ gs_grestoreall(gs_gstate * pgs) /* Allocate and return a new graphics state. */ gs_gstate * -gs_gstate_copy(gs_gstate * pgs, gs_memory_t * mem) +gs_gstate_copy(const gs_gstate * pgs, gs_memory_t * mem) { gs_gstate *pnew; - /* Prevent 'capturing' the view clip path. */ - gx_clip_path *view_clip = pgs->view_clip; - pgs->view_clip = 0; - pnew = gstate_clone(pgs, mem, "gs_gstate", copy_for_gstate); - if (pnew == 0) - return 0; + pnew = gstate_clone_for_gstate(pgs, mem, "gs_gstate"); + if (pnew == NULL) + return NULL; clip_stack_rc_adjust(pnew->clip_stack, 1, "gs_gstate_copy"); - pgs->view_clip = view_clip; - pnew->saved = 0; + pnew->saved = NULL; /* * Prevent dangling references from the show_gstate pointer. If * this context is its own show_gstate, set the pointer in the clone * to point to the clone; otherwise, set the pointer in the clone to - * 0, and let gs_setgstate fix it up. + * NULL, and let gs_setgstate fix it up. */ pnew->show_gstate = - (pgs->show_gstate == pgs ? pnew : 0); + (pgs->show_gstate == pgs ? pnew : NULL); return pnew; } @@ -593,7 +591,7 @@ gs_gstate_update_overprint(gs_gstate * pgs, const gs_overprint_params_t * pparam pgs->memory, NULL); if (code >= 0 || code == gs_error_handled){ - if (ovptdev != dev) { + if (code == 1) { gx_set_device_only(pgs, ovptdev); /* Get rid of extra reference */ rc_decrement(ovptdev, "gs_gstate_update_overprint(ovptdev)"); @@ -641,7 +639,7 @@ gs_do_set_overprint(gs_gstate * pgs) gs_color_space_index pcs_index = gs_color_space_get_index(pcs); dev_proc(dev, get_profile)(dev, &dev_profile); - if (!dev_profile->sim_overprint) + if (dev_profile->overprint_control == gs_overprint_control_disable) return code; /* Transparency device that supports spots and where we have @@ -665,9 +663,12 @@ gs_do_set_overprint(gs_gstate * pgs) return code; } } - } + /* If we have a CIE-based space, use the ICC equivalent space */ + if (gs_color_space_is_PSCIE(pcs) && pcs->icc_equivalent != NULL) + pcs = pcs->icc_equivalent; + /* The spaces that do not allow opm (e.g. ones that are not ICC or DeviceCMYK) will blow away any true setting later. But we have to be prepared in case this is a CMYK ICC space for example. Hence we set effective mode @@ -847,6 +848,8 @@ gs_initgraphics(gs_gstate * pgs) const gs_gstate gstate_initial = { gs_gstate_initial(1.0) }; + gs_matrix m; + gs_make_identity(&m); gs_initmatrix(pgs); if ((code = gs_newpath(pgs)) < 0 || @@ -980,7 +983,13 @@ gs_initgraphics(gs_gstate * pgs) if (code < 0) goto exit; - return 0; + code = gs_settextmatrix(pgs, &m); + if (code < 0) + goto exit; + + code = gs_settextlinematrix(pgs, &m); + if (code < 0) + goto exit; exit: return code; } @@ -1210,6 +1219,16 @@ gstate_free_parts(gs_gstate * parts, gs_memory_t * mem, client_name_t cname) } } +static inline void +gstate_parts_init_dev_color(gx_device_color *dc) +{ + gx_device_color_type dct = dc->type; + gs_graphics_type_tag_t gtt = dc->tag; + memset(dc, 0x00, sizeof(gx_device_color)); + dc->type = dct; + dc->tag = gtt; +} + /* Allocate the privately allocated parts of a gstate. */ static int gstate_alloc_parts(gs_gstate * parts, const gs_gstate * shared, @@ -1254,6 +1273,8 @@ gstate_alloc_parts(gs_gstate * parts, const gs_gstate * shared, gstate_free_parts(parts, mem, cname); return_error(gs_error_VMerror); } + gstate_parts_init_dev_color(parts->color[0].dev_color); + gstate_parts_init_dev_color(parts->color[1].dev_color); return 0; } @@ -1289,77 +1310,114 @@ gstate_copy_dash(gs_memory_t *mem, gx_dash_params *dash , const gs_gstate * pfro pfrom->line_params.dash.offset, mem); } -/* Clone an existing graphics state. */ -/* Return 0 if the allocation fails. */ -/* If reason is for_gsave, the clone refers to the old contents, */ -/* and we switch the old state to refer to the new contents. */ +typedef struct { + gs_gstate_parts parts; + gx_dash_params dash; +} gs_gstate_clone_data; + static gs_gstate * -gstate_clone(gs_gstate * pfrom, gs_memory_t * mem, client_name_t cname, - gs_gstate_copy_reason_t reason) +gstate_clone_core(const gs_gstate *pfrom, + client_name_t cname, + gs_gstate_clone_data *clone_data, + gs_gstate_copy_reason_t reason) { + gs_memory_t *mem = pfrom->memory; gs_gstate *pgs = gstate_alloc(mem, cname, pfrom); - gs_gstate_parts parts; void *pdata = NULL; - gx_dash_params dash; if (pgs == NULL) - return 0; - GSTATE_ASSIGN_PARTS(&parts, pgs); + return NULL; if (pfrom->client_data != NULL) { pdata = (*pfrom->client_procs.alloc) (mem); if (pdata == NULL || - gstate_copy_client_data(pfrom, pdata, pfrom->client_data, reason) < 0 - ) + gstate_copy_client_data(pfrom, pdata, pfrom->client_data, + reason) < 0) goto fail; } /* Copy the dash and dash pattern if necessary. */ - dash = gs_currentlineparams_inline(pfrom)->dash; - if (pfrom->line_params.dash.pattern) { + clone_data->dash = gs_currentlineparams_inline(pfrom)->dash; + if (clone_data->dash.pattern) { int code; - dash.pattern = NULL; /* Ensures a fresh allocation */ - code = gstate_copy_dash(mem, &dash, pfrom); + clone_data->dash.pattern = NULL; /* Ensures a fresh allocation */ + code = gstate_copy_dash(mem, &clone_data->dash, pfrom); if (code < 0) goto fail; } + /* Some records within pgs are allocated. We copy pfrom into pgs + * wholesale (to avoid problems with the structure being updated and + * us having to keep it in sync), so we copy those allocated regions + * out first. The caller of this routine will then put them back + * into either pgs or pfrom as appropriate. */ + GSTATE_ASSIGN_PARTS(&clone_data->parts, pgs); *pgs = *pfrom; pgs->client_data = pdata; - gs_currentlineparams_inline(pgs)->dash = dash; - pgs->memory = mem; gs_gstate_copied(pgs); /* Don't do anything to clip_stack. */ rc_increment(pgs->device); - *parts.color[0].ccolor = *pfrom->color[0].ccolor; - *parts.color[0].dev_color = *pfrom->color[0].dev_color; - *parts.color[1].ccolor = *pfrom->color[1].ccolor; - *parts.color[1].dev_color = *pfrom->color[1].dev_color; - if (reason == copy_for_gsave) { - float *dfrom = pfrom->line_params.dash.pattern; - float *dto = pgs->line_params.dash.pattern; - - GSTATE_ASSIGN_PARTS(pfrom, &parts); - pgs->line_params.dash.pattern = dfrom; - pfrom->line_params.dash.pattern = dto; - } else { - GSTATE_ASSIGN_PARTS(pgs, &parts); - } - gs_swapcolors_quick(pgs); - cs_adjust_counts_icc(pgs, 1); - gs_swapcolors_quick(pgs); + *clone_data->parts.color[0].ccolor = *pgs->color[0].ccolor; + *clone_data->parts.color[0].dev_color = *pgs->color[0].dev_color; + *clone_data->parts.color[1].ccolor = *pgs->color[1].ccolor; + *clone_data->parts.color[1].dev_color = *pgs->color[1].dev_color; cs_adjust_counts_icc(pgs, 1); + cs_adjust_swappedcounts_icc(pgs, 1); + return pgs; + fail: if (pdata != NULL) (*pfrom->client_procs.free) (pdata, mem, pgs); - memset(pgs->color, 0, 2*sizeof(gs_gstate_color)); - gs_free_object(mem, pgs->line_params.dash.pattern, cname); - GSTATE_ASSIGN_PARTS(pgs, &parts); + gs_free_object(mem, clone_data->dash.pattern, cname); gstate_free_parts(pgs, mem, cname); gs_free_object(mem, pgs, cname); - return 0; + + return NULL; +} + + +/* Clone an existing graphics state for use in gsave. The clone refers + * to the old contents, and the old state refers to the new contents. */ +/* Return NULL if the allocation fails. */ +static gs_gstate * +gstate_clone_for_gsave(gs_gstate *pfrom, + client_name_t cname) +{ + gs_gstate_clone_data clone_data; + gs_gstate *pgs = gstate_clone_core(pfrom, cname, &clone_data, + copy_for_gsave); + + if (pgs == NULL) + return NULL; + + /* Newly allocated parts go back into pfrom, not pgs! */ + GSTATE_ASSIGN_PARTS(pfrom, &clone_data.parts); + gs_currentlineparams_inline(pfrom)->dash = clone_data.dash; + + return pgs; +} + +/* Clone an existing graphics state. The view_clip is not copied. */ +/* Return NULL if the allocation fails. */ +static gs_gstate * +gstate_clone_for_gstate(const gs_gstate *pfrom, + gs_memory_t *mem, + client_name_t cname) +{ + gs_gstate_clone_data clone_data; + gs_gstate *pgs = gstate_clone_core(pfrom, cname, &clone_data, + copy_for_gstate); + + if (pgs == NULL) + return NULL; + GSTATE_ASSIGN_PARTS(pgs, &clone_data.parts); + pgs->view_clip = NULL; + gs_currentlineparams_inline(pgs)->dash = clone_data.dash; + pgs->memory = mem; + + return pgs; } /* Adjust reference counters for the whole clip stack */ diff --git a/base/gsstate.h b/base/gsstate.h index 4a4fe260..b786dde4 100644 --- a/base/gsstate.h +++ b/base/gsstate.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -33,7 +33,7 @@ int gs_gsave(gs_gstate *), gs_grestore(gs_gstate *), gs_grestoreall(gs_gstate *) int gs_grestore_only(gs_gstate *); int gs_gsave_for_save(gs_gstate *, gs_gstate **), gs_grestoreall_for_restore(gs_gstate *, gs_gstate *); -gs_gstate *gs_gstate_copy(gs_gstate *, gs_memory_t *); +gs_gstate *gs_gstate_copy(const gs_gstate *, gs_memory_t *); int gs_copygstate(gs_gstate * /*to */ , const gs_gstate * /*from */ ), gs_currentgstate(gs_gstate * /*to */ , const gs_gstate * /*from */ ), gs_setgstate(gs_gstate * /*to */ , const gs_gstate * /*from */ ); diff --git a/base/gsstrl.h b/base/gsstrl.h index 4b745e22..3ea00623 100644 --- a/base/gsstrl.h +++ b/base/gsstrl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsstrtok.h b/base/gsstrtok.h index 8dded3d3..a50ab3a1 100644 --- a/base/gsstrtok.h +++ b/base/gsstrtok.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsstruct.h b/base/gsstruct.h index a517a62d..663940d9 100644 --- a/base/gsstruct.h +++ b/base/gsstruct.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsstype.h b/base/gsstype.h index c3548fdd..7584ecc1 100644 --- a/base/gsstype.h +++ b/base/gsstype.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gstext.c b/base/gstext.c index bb258d39..e8373295 100644 --- a/base/gstext.c +++ b/base/gstext.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -32,6 +32,8 @@ #include "gzstate.h" #include "gsutil.h" #include "gxdevsop.h" +#include "gscspace.h" +#include "gsicc_blacktext.h" /* GC descriptors */ public_st_gs_text_params(); @@ -212,6 +214,7 @@ gs_text_enum_init(gs_text_enum_t *pte, const gs_text_enum_procs_t *procs, pte->log2_scale.x = pte->log2_scale.y = 0; /* init_dynamic sets index, xy_index, fstack */ code = gs_text_enum_init_dynamic(pte, font); + pte->k_text_release = 0; if (code >= 0) rc_increment(dev); return code; @@ -278,6 +281,23 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, (pgs->text_rendering_mode == 0)); bool text_op_stroke = ((pgs->stroke_overprint || (!pgs->stroke_overprint && op_active)) && (pgs->text_rendering_mode == 1)); + bool type3 = (pgs->font->FontType == ft_user_defined || + pgs->font->FontType == ft_PDF_user_defined || + pgs->font->FontType == ft_PCL_user_defined || + pgs->font->FontType == ft_MicroType || + pgs->font->FontType == ft_GL2_stick_user_defined || + pgs->font->FontType == ft_GL2_531); + bool in_smask = + (dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_in_smask_construction, NULL, 0)) > 0; + bool black_text = (text->operation & (TEXT_DO_DRAW | TEXT_DO_ANY_CHARPATH)) && + !type3 && !in_smask; + cmm_dev_profile_t *icc_struct; + + code = dev_proc(pgs->device, get_profile)((gx_device *)pgs->device, &icc_struct); + if (code < 0) + black_text = 0; + else + black_text = black_text && icc_struct->blacktext; /* * Detect nocurrentpoint now, even if the string is empty, for Adobe @@ -311,9 +331,40 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, /* Processing a text object operation */ ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ + if (black_text && pgs->black_text_state == NULL) { + gs_color_space *pcs_curr = gs_currentcolorspace_inline(pgs); + gs_color_space *pcs_alt = gs_swappedcolorspace_inline(pgs); + + pgs->black_text_state = gsicc_blacktext_state_new(pgs->memory); + if (pgs->black_text_state == NULL) + return gs_error_VMerror; + + rc_increment_cs(pcs_curr); + rc_increment_cs(pcs_alt); + pgs->black_text_state->pcs[0] = pcs_curr; + pgs->black_text_state->pcs[1] = pcs_alt; + + pgs->black_text_state->pcc[0] = pgs->color[0].ccolor; + cs_adjust_color_count(pgs, 1); /* The set_gray will do a decrement */ + pgs->black_text_state->value[0] = pgs->color[0].ccolor->paint.values[0]; + gs_setgray(pgs, 0.0); + + gs_swapcolors_quick(pgs); + + pgs->black_text_state->pcc[1] = pgs->color[0].ccolor; + cs_adjust_color_count(pgs, 1); + pgs->black_text_state->value[1] = pgs->color[0].ccolor->paint.values[0]; + gs_setgray(pgs, 0.0); + + gs_swapcolors_quick(pgs); + + pgs->black_text_state->is_fill = pgs->is_fill_color; + } + code = gx_set_dev_color(pgs); if (code != 0) return code; + code = gs_gstate_color_load(pgs); if (code < 0) return code; @@ -340,7 +391,7 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, cmm_dev_profile_t* dev_profile; dev_proc(dev, get_profile)(dev, &dev_profile); - if (dev_profile->sim_overprint && + if ((dev_profile->overprint_control != gs_overprint_control_disable) && (dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs == gsCMYK || dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs == gsNCHANNEL)) { if (pgs->text_rendering_mode == 0) { @@ -354,10 +405,30 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, } pgs->device->sgr.stroke_stored = false; - return gx_device_text_begin(pgs->device, pgs, + code = gx_device_text_begin(pgs->device, pgs, text, pgs->font, pgs->path, gs_currentdevicecolor_inline(pgs), pcpath, mem, ppte); + + /* we need to know if we are doing a highlevel device. + Also we need to know if we are doing any stroke + or stroke fill operations. This determines when + we need to release the black_text_state structure. */ + if (code >= 0 && *ppte != NULL) { + if (black_text) { + if (!((*ppte)->k_text_release)) { + /* Not a high level device */ + if (pgs->text_rendering_mode == 0 || + pgs->text_rendering_mode == 4) { + /* No stroke */ + (*ppte)->k_text_release = 1; + } + } + } else + (*ppte)->k_text_release = 0; + } + + return code; } /* @@ -762,8 +833,10 @@ rc_free_text_enum(gs_memory_t * mem, void *obj, client_name_t cname) rc_free_struct_only(mem, obj, cname); } void -gs_text_release(gs_text_enum_t * pte, client_name_t cname) +gs_text_release(gs_gstate *pgs, gs_text_enum_t * pte, client_name_t cname) { + if (pgs != NULL && pgs->black_text_state != NULL) + gsicc_restore_black_text(pgs); rc_decrement_only(pte, cname); } diff --git a/base/gstext.h b/base/gstext.h index a3317d0a..e8de9fea 100644 --- a/base/gstext.h +++ b/base/gstext.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -215,8 +215,6 @@ gs_show_begin(gs_gstate *, const byte *, uint, gs_charboxpath_begin(gs_gstate *, const byte *, uint, bool, gs_memory_t *, gs_text_enum_t **); -/* Compute the number of characters in a text. */ -int gs_text_size(gs_gstate * pgs, gs_text_params_t *text, gs_memory_t * mem); /* Retrieve text params from enumerator. */ gs_text_params_t *gs_get_text_params(gs_text_enum_t *pte); @@ -301,7 +299,7 @@ int int gs_text_retry(gs_text_enum_t *pte); /* Release the text processing structures. */ -void gs_text_release(gs_text_enum_t *pte, client_name_t cname); +void gs_text_release(gs_gstate *pgs, gs_text_enum_t *pte, client_name_t cname); /* Compute the number of characters in a text. */ int gs_text_count_chars(gs_gstate * pgs, gs_text_params_t *text, gs_memory_t * mem); diff --git a/base/gstiffio.c b/base/gstiffio.c index 5482d783..004f9feb 100644 --- a/base/gstiffio.c +++ b/base/gstiffio.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -293,6 +293,21 @@ _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) return (memcmp(p1, p2, (size_t) c)); } +#if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF) +#include "gssprintf.h" +int +_TIFF_snprintf_f(char* buf, size_t size, const char* format, ...) +{ + int count; + va_list args; + + va_start(args, format); + count = gs_vsnprintf(buf, size, format, args); + va_end(args); + return count; +} +#endif + /* We supply our own warning/error handlers when we invoke libtiff */ TIFFErrorHandler _TIFFwarningHandler = NULL; TIFFErrorHandler _TIFFerrorHandler = NULL; diff --git a/base/gstiffio.h b/base/gstiffio.h index d71ec81e..405e0fac 100644 --- a/base/gstiffio.h +++ b/base/gstiffio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gstparam.h b/base/gstparam.h index 44093bc9..d4bb833c 100644 --- a/base/gstparam.h +++ b/base/gstparam.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gstrans.c b/base/gstrans.c index cb3f2ce6..cb201eba 100644 --- a/base/gstrans.c +++ b/base/gstrans.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -30,6 +30,7 @@ #include "gxarith.h" #include "gxclist.h" #include "gsicc_manage.h" +#include "gsicc_cache.h" /* ------ Transparency-related graphics state elements ------ */ @@ -144,9 +145,10 @@ gs_gstate_update_pdf14trans2(gs_gstate * pgs, gs_pdf14trans_params_t * pparams, * If we created a new PDF 1.4 compositor device then we need to install it * into the graphics state. */ - if (pdf14dev != dev) { + if (code == 1) { gx_set_device_only(pgs, pdf14dev); gx_device_retain(pdf14dev, retain_on_create); + code = 0; } /* If we had a color space change and we are in overprint, then we need to @@ -270,7 +272,7 @@ gs_begin_transparency_group(gs_gstate *pgs, blend_color_space->cmm_icc_profile_data->num_comps; /* Get the ICC profile */ params.iccprofile = blend_color_space->cmm_icc_profile_data; - params.icc_hash = blend_color_space->cmm_icc_profile_data->hashcode; + params.icc_hash = gsicc_get_hash(blend_color_space->cmm_icc_profile_data); } else { /* Color space was NOT ICC based. PS CIE space and DeviceN are the only other option. Use the ICC default based upon the component count. */ @@ -296,7 +298,7 @@ gs_begin_transparency_group(gs_gstate *pgs, params.group_color_type = ICC; params.group_color_numcomps = profile->num_comps; params.iccprofile = profile; - params.icc_hash = profile->hashcode; + params.icc_hash = gsicc_get_hash(profile); } } } @@ -348,7 +350,11 @@ gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev, tgp.group_opacity = pparams->opacity; tgp.group_shape = pparams->shape; - pgs->blend_mode = pparams->blend_mode; + if (tgp.Knockout && tgp.text_group == PDF14_TEXTGROUP_BT_PUSHED && + ((pgs->overprint && pgs->is_fill_color) || (pgs->stroke_overprint && !pgs->is_fill_color))) + pgs->blend_mode = BLEND_MODE_CompatibleOverprint; + else + pgs->blend_mode = pparams->blend_mode; bbox = pparams->bbox; #ifdef DEBUG if (gs_debug_c('v')) { @@ -632,7 +638,7 @@ gs_begin_transparency_mask(gs_gstate * pgs, * pdf14_update_device_color_procs_pop_c() */ params.iccprofile = blend_color_space->cmm_icc_profile_data; - params.icc_hash = blend_color_space->cmm_icc_profile_data->hashcode; + params.icc_hash = gsicc_get_hash(blend_color_space->cmm_icc_profile_data); } else { params.group_color_type = GRAY_SCALE; params.group_color_numcomps = 1; /* Need to check */ @@ -775,7 +781,8 @@ get_num_pdf14_spot_colors(gs_gstate * pgs) } int -gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern, bool retain) +gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern, bool retain, + int depth, int spot_color_count) { gs_pdf14trans_params_t params = { 0 }; cmm_profile_t *icc_profile; @@ -797,6 +804,12 @@ gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern, bool retain) */ params.num_spot_colors = get_num_pdf14_spot_colors(pgs); params.is_pattern = is_pattern; + + /* Information related to overprint simulation */ + params.num_spot_colors_int = spot_color_count; + if (depth < 0) + params.overprint_sim_push = true; + /* If we happen to be in a situation where we are going out to a device whose profile is CIELAB then we will need to make sure that we do our blending in RGB and convert to CIELAB when we do the put_image diff --git a/base/gstrans.h b/base/gstrans.h index a441bbef..d7bf1e0d 100644 --- a/base/gstrans.h +++ b/base/gstrans.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -91,6 +91,8 @@ struct gs_pdf14trans_params_s { /* The type of trasnparency operation */ pdf14_compositor_operations pdf14_op; int num_spot_colors; /* Only for devices which support spot colors. */ + int num_spot_colors_int; /* Number of spot colors reported by the interpreter */ + bool overprint_sim_push; /* If true, put_image will need special conversion */ /* Changed parameters flag */ int changed; /* Parameters from the gs_transparency_group_params_t structure */ @@ -165,7 +167,17 @@ bool gs_currenttextknockout(const gs_gstate *); * We have to abbreviate the procedure name because procedure names are * only unique to 23 characters on VMS. */ -int gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern, bool retain); +/* For the push_pdf14trans_device, depth is a estimate (not authoritative) of + * the transparency stack depth. Value 0 means "unknown". If the depth value + * is < 0, that means that this pdf14 device is being used for the overprint + * simulation, and ordiniarly the value will be -1, since overprint + * simulation only needs the page buffer. + * The spot_color_count is provided for PDF input files to define the number + * of Spot colorants beyond CMYK. Thus 0 means CMYK only. If unknown, such + * as with PostScript input, the value will be -1. + */ +int gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern, bool retain, + int depth, int spot_color_count); int gs_pop_pdf14trans_device(gs_gstate * pgs, bool is_pattern); diff --git a/base/gstrap.c b/base/gstrap.c index 7ae01e32..b93b8ded 100644 --- a/base/gstrap.c +++ b/base/gstrap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gstrap.h b/base/gstrap.h index 9a29fe74..8c2cc928 100644 --- a/base/gstrap.h +++ b/base/gstrap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gstype1.c b/base/gstype1.c index a8508623..870b2fb6 100644 --- a/base/gstype1.c +++ b/base/gstype1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -164,69 +164,27 @@ gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, if (cip == 0) return (gs_note_error(gs_error_invalidfont)); cipend = cip + pgd->bits.size; - call:state = crypt_charstring_seed; - if (encrypted) { - int skip = pdata->lenIV; - - /* Skip initial random bytes */ - for (; skip > 0; ++cip, --skip) - decrypt_skip_next(*cip, state); - } - goto top; - cont:if (ipsp < pcis->ipstack || ipsp->ip == 0) - return (gs_note_error(gs_error_invalidfont)); - cip = ipsp->ip; - cipend = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size; - state = ipsp->dstate; - top:for (;;) { + goto call; + for (;;) { uint c0 = *cip++; if (cip > cipend) return_error(gs_error_invalidfont); charstring_next(c0, state, c, encrypted); - if (c >= c_num1) { - /* This is a number, decode it and push it on the stack. */ - - if (c < c_pos2_0) { /* 1-byte number */ - decode_push_num1(csp, cstack, c); - } else if (c < cx_num4) { /* 2-byte number */ - decode_push_num2(csp, cstack, c, cip, state, encrypted); - } else if (c == cx_num4) { /* 4-byte number */ - long lw; - - decode_num4(lw, cip, state, encrypted); - CS_CHECK_PUSH(csp, cstack); - *++csp = int2fixed(lw); - if (lw != fixed2long(*csp)) { - /* - * The integer was too large to handle in fixed point. - * Handle this case specially. - */ - code = gs_type1_check_float(&state, encrypted, &cip, csp, lw); - if (code < 0) - return code; - } - } else /* not possible */ - return_error(gs_error_invalidfont); - pushed:if_debug3m('1', pfont->memory, "[1]%d: (%d) %f\n", - (int)(csp - cstack), c, fixed2float(*csp)); - continue; - } + if (c < c_num1) { #ifdef DEBUG - if (gs_debug['1']) { - static const char *const c1names[] = - {char1_command_names}; - - if (c1names[c] == 0) - dmlprintf2(pfont->memory, "[1]"PRI_INTPTR": %02x??\n", (intptr_t)(cip - 1), c); - else - dmlprintf3(pfont->memory, "[1]"PRI_INTPTR": %02x %s\n", (intptr_t)(cip - 1), c, - c1names[c]); - } + if (gs_debug['1']) { + static const char *const c1names[] = + {char1_command_names}; + + if (c1names[c] == 0) + dmlprintf2(pfont->memory, "[1]"PRI_INTPTR": %02x??\n", (intptr_t)(cip - 1), c); + else + dmlprintf3(pfont->memory, "[1]"PRI_INTPTR": %02x %s\n", (intptr_t)(cip - 1), c, + c1names[c]); + } #endif - switch ((char_command) c) { -#define cnext clear; goto top -#define inext goto top + switch ((char_command) c) { /* Commands with identical functions in Type 1 and Type 2, */ /* except for 'escape'. */ @@ -253,10 +211,16 @@ gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, gs_glyph_data_free(&ipsp->cs_data, "gs_type1_interpret"); CS_CHECK_IPSTACK(ipsp, pcis->ipstack); --ipsp; - goto cont; + cont: if (ipsp < pcis->ipstack || ipsp->ip == 0) + return (gs_note_error(gs_error_invalidfont)); + cip = ipsp->ip; + cipend = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size; + state = ipsp->dstate; + continue; case c_undoc15: /* See gstype1.h for information on this opcode. */ - cnext; + clear; + continue; /* Commands with similar but not identical functions */ /* in Type 1 and Type 2 charstrings. */ @@ -265,24 +229,18 @@ gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, code = t1_hinter__hstem(h, cs0, cs1); if (code < 0) return code; - cnext; + clear; + continue; case cx_vstem: code = t1_hinter__vstem(h, cs0, cs1); if (code < 0) return code; - cnext; + clear; + continue; case cx_vmoveto: cs1 = cs0; cs0 = 0; - move: /* cs0 = dx, cs1 = dy for hint checking. */ - code = t1_hinter__rmoveto(h, cs0, cs1); - goto cc; - case cx_rlineto: - line: /* cs0 = dx, cs1 = dy for hint checking. */ - code = t1_hinter__rlineto(h, cs0, cs1); - cc:if (code < 0) - return code; - cnext; + goto move; case cx_hlineto: cs1 = 0; goto line; @@ -290,6 +248,10 @@ gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, cs1 = cs0; cs0 = 0; goto line; + case cx_rlineto: + line: /* cs0 = dx, cs1 = dy for hint checking. */ + code = t1_hinter__rlineto(h, cs0, cs1); + goto cc; case cx_rrcurveto: code = t1_hinter__rcurveto(h, cs0, cs1, cs2, cs3, cs4, cs5); goto cc; @@ -336,7 +298,9 @@ gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, goto move; case cx_hmoveto: cs1 = 0; - goto move; + move: /* cs0 = dx, cs1 = dy for hint checking. */ + code = t1_hinter__rmoveto(h, cs0, cs1); + goto cc; case cx_vhcurveto: code = t1_hinter__rcurveto(h, 0, cs0, cs1, cs2, cs3, 0); goto cc; @@ -349,7 +313,10 @@ gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, case c1_closepath: code = t1_hinter__closepath(h); - goto cc; + cc: if (code < 0) + return code; + clear; + continue; case c1_hsbw: if (!pcis->seac_flag) { fixed sbx = cs0, sby = fixed_0, wx = cs1, wy = fixed_0; @@ -378,17 +345,7 @@ gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, return code; gs_type1_sbw(pcis, cs0, fixed_0, cs1, fixed_0); cs1 = fixed_0; -rsbw: /* Give the caller the opportunity to intervene. */ - pcis->os_count = 0; /* clear */ - ipsp->ip = cip, ipsp->dstate = state; - pcis->ips_count = ipsp - &pcis->ipstack[0] + 1; - /* If we aren't in a seac, do nothing else now; */ - /* finish_init will take care of the rest. */ - if (pcis->init_done < 0) { - /* Finish init when we return. */ - pcis->init_done = 0; - } - return type1_result_sbw; + goto rsbw; case cx_escape: charstring_next(*cip, state, c, encrypted); ++cip; @@ -412,17 +369,20 @@ rsbw: /* Give the caller the opportunity to intervene. */ code = t1_hinter__dotsection(h); if (code < 0) return code; - cnext; + clear; + continue; case ce1_vstem3: code = t1_hinter__vstem3(h, cs0, cs1, cs2, cs3, cs4, cs5); if (code < 0) return code; - cnext; + clear; + continue; case ce1_hstem3: code = t1_hinter__hstem3(h, cs0, cs1, cs2, cs3, cs4, cs5); if (code < 0) return code; - cnext; + clear; + continue; case ce1_seac: code = gs_type1_seac(pcis, cstack + 1, cstack[0], ipsp); @@ -433,7 +393,16 @@ rsbw: /* Give the caller the opportunity to intervene. */ clear; cip = ipsp->cs_data.bits.data; cipend = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size; - goto call; + call: + state = crypt_charstring_seed; + if (encrypted) { + int skip = pdata->lenIV; + + /* Skip initial random bytes */ + for (; skip > 0; ++cip, --skip) + decrypt_skip_next(*cip, state); + } + continue; case ce1_sbw: if (!pcis->seac_flag) code = t1_hinter__sbw(h, cs0, cs1, cs2, cs3); @@ -442,7 +411,18 @@ rsbw: /* Give the caller the opportunity to intervene. */ if (code < 0) return code; gs_type1_sbw(pcis, cs0, cs1, cs2, cs3); - goto rsbw; + rsbw: + /* Give the caller the opportunity to intervene. */ + pcis->os_count = 0; /* clear */ + ipsp->ip = cip, ipsp->dstate = state; + pcis->ips_count = ipsp - &pcis->ipstack[0] + 1; + /* If we aren't in a seac, do nothing else now; */ + /* finish_init will take care of the rest. */ + if (pcis->init_done < 0) { + /* Finish init when we return. */ + pcis->init_done = 0; + } + return type1_result_sbw; case ce1_div: CS_CHECK_POP(&csp[-1], cstack); csp[-1] = float2fixed((double)csp[-1] / (double)*csp); @@ -450,7 +430,8 @@ rsbw: /* Give the caller the opportunity to intervene. */ goto pushed; case ce1_undoc15: /* See gstype1.h for information on this opcode. */ - cnext; + clear; + continue; case ce1_callothersubr: { int num_results; @@ -477,7 +458,7 @@ rsbw: /* Give the caller the opportunity to intervene. */ if (code < 0) return code; pcis->flex_count = flex_max; /* not inside flex */ - inext; + continue; case 1: CS_CHECK_POP(csp, cstack); code = t1_hinter__flex_beg(h); @@ -485,7 +466,7 @@ rsbw: /* Give the caller the opportunity to intervene. */ return code; pcis->flex_count = 1; csp -= 2; - inext; + continue; case 2: CS_CHECK_POP(csp, cstack); if (pcis->flex_count >= flex_max) @@ -494,7 +475,7 @@ rsbw: /* Give the caller the opportunity to intervene. */ if (code < 0) return code; csp -= 2; - inext; + continue; case 3: CS_CHECK_POP(csp, cstack); /* Assume the next opcode is a `pop'. */ @@ -505,22 +486,15 @@ rsbw: /* Give the caller the opportunity to intervene. */ if (code < 0) return code; csp -= 2; - inext; + continue; case 12: case 13: /* Counter control isn't implemented. */ - cnext; + clear; + continue; case 14: num_results = 1; - blend: - code = gs_type1_blend(pcis, csp, - num_results); - if (code < 0) - return code; - if (!CS_CHECK_CSTACK_BOUNDS(&csp[1 - code], cstack)) - return_error(gs_error_invalidfont); - csp -= code; - inext; + goto blend; case 15: num_results = 2; goto blend; @@ -532,7 +506,15 @@ rsbw: /* Give the caller the opportunity to intervene. */ goto blend; case 18: num_results = 6; - goto blend; + blend: + code = gs_type1_blend(pcis, csp, + num_results); + if (code < 0) + return code; + if (!CS_CHECK_CSTACK_BOUNDS(&csp[1 - code], cstack)) + return_error(gs_error_invalidfont); + csp -= code; + continue; } } /* Not a recognized othersubr, */ @@ -567,7 +549,7 @@ rsbw: /* Give the caller the opportunity to intervene. */ /* a known othersubr. */ if (pcis->ignore_pops != 0) { pcis->ignore_pops--; - inext; + continue; } CS_CHECK_PUSH(csp, cstack); ++csp; @@ -580,7 +562,8 @@ rsbw: /* Give the caller the opportunity to intervene. */ cs0 += pcis->adxy.x + pcis->origin_offset.x; cs1 += pcis->adxy.y + pcis->origin_offset.y; t1_hinter__setcurrentpoint(h, cs0, cs1); - cnext; + clear; + continue; default: return_error(gs_error_invalidfont); } @@ -591,6 +574,35 @@ rsbw: /* Give the caller the opportunity to intervene. */ case_c1_undefs: default: /* pacify compiler */ return_error(gs_error_invalidfont); + } + } else { + /* This is a number, decode it and push it on the stack. */ + + if (c < c_pos2_0) { /* 1-byte number */ + decode_push_num1(csp, cstack, c); + } else if (c < cx_num4) { /* 2-byte number */ + decode_push_num2(csp, cstack, c, cip, state, encrypted); + } else if (c == cx_num4) { /* 4-byte number */ + long lw; + + decode_num4(lw, cip, state, encrypted); + CS_CHECK_PUSH(csp, cstack); + *++csp = int2fixed(lw); + if (lw != fixed2long(*csp)) { + /* + * The integer was too large to handle in fixed point. + * Handle this case specially. + */ + code = gs_type1_check_float(&state, encrypted, &cip, csp, lw); + if (code < 0) + return code; + } + } else /* not possible */ + return_error(gs_error_invalidfont); + pushed: + if_debug3m('1', pfont->memory, "[1]%d: (%d) %f\n", + (int)(csp - cstack), c, fixed2float(*csp)); + continue; } } } diff --git a/base/gstype1.h b/base/gstype1.h index e88be5cc..71937b6e 100644 --- a/base/gstype1.h +++ b/base/gstype1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gstype2.c b/base/gstype2.c index 870e13dd..a4a44335 100644 --- a/base/gstype2.c +++ b/base/gstype2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -176,20 +176,8 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, cip = pgd->bits.data; if (cip == 0) return (gs_note_error(gs_error_invalidfont)); - call:state = crypt_charstring_seed; - if (encrypted) { - int skip = pdata->lenIV; - - /* Skip initial random bytes */ - for (; skip > 0; ++cip, --skip) - decrypt_skip_next(*cip, state); - } - goto top; - cont:if (ipsp < pcis->ipstack || ipsp->ip == 0) - return (gs_note_error(gs_error_invalidfont)); - cip = ipsp->ip; - state = ipsp->dstate; - top:for (;;) { + goto call; + for (;;) { uint c0 = *cip++; charstring_next(c0, state, c, encrypted); @@ -209,9 +197,7 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, *++csp = arith_rshift(lw, 16 - _fixed_shift); } else /* not possible */ return_error(gs_error_invalidfont); - pushed:if_debug3m('1', pfont->memory, "[1]%d: (%d) %f\n", - (int)(csp - cstack), c, fixed2float(*csp)); - continue; + goto pushed; } #ifdef DEBUG if (gs_debug['1']) { @@ -227,7 +213,6 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, } #endif switch ((char_command) c) { -#define cnext clear; goto top /* Commands with identical functions in Type 1 and Type 2, */ /* except for 'escape'. */ @@ -241,38 +226,27 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, c = fixed2int_var(*csp) + pdata->subroutineNumberBias; code = pdata->procs.subr_data (pfont, c, false, &ipsp[1].cs_data); - subr: - if (code < 0) { - /* Calling a Subr with an out-of-range index is clearly a error: - * the Adobe documentation says the results of doing this are - * undefined. However, we have seen a PDF file produced by Adobe - * PDF Library 4.16 that included a Type 2 font that called an - * out-of-range Subr, and Acrobat Reader did not signal an error. - * Therefore, we ignore such calls. - */ - cip++; - goto top; - } - --csp; - ipsp->ip = cip, ipsp->dstate = state; - ++ipsp; - cip = ipsp->cs_data.bits.data; - goto call; + goto subr; } else { /* Consider a missing index to be "out-of-range", and see above * comment. */ cip++; - goto top; + continue; } case c_return: gs_glyph_data_free(&ipsp->cs_data, "gs_type2_interpret"); --ipsp; - goto cont; + cont: if (ipsp < pcis->ipstack || ipsp->ip == 0) + return (gs_note_error(gs_error_invalidfont)); + cip = ipsp->ip; + state = ipsp->dstate; + continue; case c_undoc15: /* See gstype1.h for information on this opcode. */ - cnext; + clear; + continue; /* Commands with similar but not identical functions */ /* in Type 1 and Type 2 charstrings. */ @@ -285,11 +259,7 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { check_first_operator(csp > cstack); code = t1_hinter__rmoveto(h, 0, *csp); - move: - cc: - if (code < 0) - return code; - goto pp; + goto move; } else { return_error(gs_error_invalidfont); @@ -300,8 +270,7 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, if (code < 0) return code; } - pp: - cnext; + goto pp; case cx_hlineto: vertical = false; goto hvl; @@ -452,7 +421,8 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, pfont->data.WeightVector.values[i]); } else return gs_note_error(gs_error_invalidfont); - cnext; + clear; + continue; case c2_hstemhm: hstem: check_first_operator(!((csp - cstack) & 1)); { @@ -465,7 +435,8 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, } } pcis->num_hints += (csp + 1 - cstack) >> 1; - cnext; + clear; + continue; case c2_hintmask: /* * A hintmask at the beginning of the CharString is @@ -513,7 +484,8 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, type2_vstem(pcis, csp, cstack); }else return gs_note_error(gs_error_invalidfont); - cnext; + clear; + continue; case c2_rcurveline: for (ap = cstack; ap + 5 <= csp; ap += 6) { code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2], ap[3], @@ -531,7 +503,11 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, } code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]); - goto cc; + move: + cc: + if (code < 0) + return code; + goto pp; case c2_vvcurveto: ap = cstack; { @@ -561,7 +537,9 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, dya = 0; } } - goto pp; + pp: + clear; + continue; case c2_shortint: { int c1, c2; @@ -573,16 +551,43 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, CS_CHECK_PUSH(csp, cstack); *++csp = int2fixed((((c1 ^ 0x80) - 0x80) << 8) + c2); } - goto pushed; + pushed: if_debug3m('1', pfont->memory, "[1]%d: (%d) %f\n", + (int)(csp - cstack), c, fixed2float(*csp)); + continue; case c2_callgsubr: if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { c = fixed2int_var(*csp) + pdata->gsubrNumberBias; code = pdata->procs.subr_data (pfont, c, true, &ipsp[1].cs_data); - goto subr; + subr: + if (code < 0) { + /* Calling a Subr with an out-of-range index is clearly a error: + * the Adobe documentation says the results of doing this are + * undefined. However, we have seen a PDF file produced by Adobe + * PDF Library 4.16 that included a Type 2 font that called an + * out-of-range Subr, and Acrobat Reader did not signal an error. + * Therefore, we ignore such calls. + */ + cip++; + continue; + } + --csp; + ipsp->ip = cip, ipsp->dstate = state; + ++ipsp; + cip = ipsp->cs_data.bits.data; + call: + state = crypt_charstring_seed; + if (encrypted) { + int skip = pdata->lenIV; + + /* Skip initial random bytes */ + for (; skip > 0; ++cip, --skip) + decrypt_skip_next(*cip, state); + } + continue; } else { cip++; - goto top; + continue; } case cx_escape: charstring_next(*cip, state, c, encrypted); @@ -810,6 +815,34 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, if (!CS_CHECK_CSTACK_BOUNDS(&csp[-12], cstack)) return_error(gs_error_invalidfont); *csp /= 100; /* fd/100 */ + goto flex; + case ce2_hflex1: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-3], cstack)) + return_error(gs_error_invalidfont); + CS_CHECK_PUSHN(csp, cstack, 4); + csp[4] = fixed_half; /* fd/100 */ + csp[2] = *csp; /* dx6 */ + csp[3] = -(csp[-7] + csp[-5] + csp[-1]); /* dy6 */ + *csp = csp[-2], csp[1] = csp[-1]; /* dx5, dy5 */ + csp[-2] = csp[-3], csp[-1] = 0; /* dx4, dy4 */ + csp[-3] = 0; /* dy3 */ + csp += 4; + goto flex; + case ce2_flex1: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-10], cstack)) + return_error(gs_error_invalidfont); + CS_CHECK_PUSHN(csp, cstack, 2); + { + fixed dx = csp[-10] + csp[-8] + csp[-6] + csp[-4] + csp[-2]; + fixed dy = csp[-9] + csp[-7] + csp[-5] + csp[-3] + csp[-1]; + + if (any_abs(dx) > any_abs(dy)) + csp[1] = -dy; /* d6 is dx6 */ + else + csp[1] = *csp, *csp = -dx; /* d6 is dy6 */ + } + csp[2] = fixed_half; /* fd/100 */ + csp += 2; flex: { fixed x_join = csp[-12] + csp[-10] + csp[-8]; fixed y_join = csp[-11] + csp[-9] + csp[-7]; @@ -860,35 +893,8 @@ flex: { if (code < 0) return code; } - cnext; - case ce2_hflex1: - if (!CS_CHECK_CSTACK_BOUNDS(&csp[-3], cstack)) - return_error(gs_error_invalidfont); - CS_CHECK_PUSHN(csp, cstack, 4); - csp[4] = fixed_half; /* fd/100 */ - csp[2] = *csp; /* dx6 */ - csp[3] = -(csp[-7] + csp[-5] + csp[-1]); /* dy6 */ - *csp = csp[-2], csp[1] = csp[-1]; /* dx5, dy5 */ - csp[-2] = csp[-3], csp[-1] = 0; /* dx4, dy4 */ - csp[-3] = 0; /* dy3 */ - csp += 4; - goto flex; - case ce2_flex1: - if (!CS_CHECK_CSTACK_BOUNDS(&csp[-10], cstack)) - return_error(gs_error_invalidfont); - CS_CHECK_PUSHN(csp, cstack, 2); - { - fixed dx = csp[-10] + csp[-8] + csp[-6] + csp[-4] + csp[-2]; - fixed dy = csp[-9] + csp[-7] + csp[-5] + csp[-3] + csp[-1]; - - if (any_abs(dx) > any_abs(dy)) - csp[1] = -dy; /* d6 is dx6 */ - else - csp[1] = *csp, *csp = -dx; /* d6 is dy6 */ - } - csp[2] = fixed_half; /* fd/100 */ - csp += 2; - goto flex; + clear; + continue; } break; diff --git a/base/gstype42.c b/base/gstype42.c index 55889201..dab1b52c 100644 --- a/base/gstype42.c +++ b/base/gstype42.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -346,9 +346,10 @@ gs_type42_font_init(gs_font_type42 * pfont, int subfontID) code = gs_font_notify_register((gs_font *)pfont, gs_len_glyphs_release, (void *)pfont); if (code < 0) { gs_free_object(pfont->memory, pfont->data.len_glyphs, "gs_len_glyphs_release"); + pfont->data.len_glyphs = NULL; return code; } - + memset(pfont->data.len_glyphs, 0x00, loca_size * sizeof(uint)); /* The 'loca' may not be in order, so we construct a glyph length array */ /* Since 'loca' is usually sorted, first try the simple linear scan to */ /* avoid the need to perform the more expensive process. */ @@ -386,7 +387,7 @@ gs_type42_font_init(gs_font_type42 * pfont, int subfontID) gs_type42_font_init_sort_t *psortary = (gs_type42_font_init_sort_t *)gs_alloc_byte_array(pfont->memory, loca_size, sizeof(gs_type42_font_init_sort_t), "gs_type42_font_init(sort loca)"); - + if (psortary == 0) return_error(gs_error_VMerror); /* loca_size > 0 due to condition above, so we always have the 0th element. */ @@ -406,7 +407,7 @@ gs_type42_font_init(gs_font_type42 * pfont, int subfontID) return_error(gs_error_invalidfont); for (i = num_valid_loca_elm; i--;) { long old_length; - + psort = psortary + i; old_length = psort->glyph_length; if (old_length < 0 || old_length > 2000 /* arbitrary */) { diff --git a/base/gstypes.h b/base/gstypes.h index cd163b9d..cdfc31c4 100644 --- a/base/gstypes.h +++ b/base/gstypes.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsuid.h b/base/gsuid.h index 1f0632c7..11310963 100644 --- a/base/gsuid.h +++ b/base/gsuid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsutil.c b/base/gsutil.c index 3b7870f1..ee6c9c48 100644 --- a/base/gsutil.c +++ b/base/gsutil.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -24,16 +24,22 @@ #include "gsrect.h" /* for prototypes */ #include "gsuid.h" #include "gsutil.h" /* for prototypes */ +#include "gxsync.h" /* for gx_monitor_t */ /* ------ Unique IDs ------ */ +/* This is used by multiple threads, so lock around updates */ ulong gs_next_ids(const gs_memory_t *mem, uint count) { gs_lib_ctx_core_t *core = mem->gs_lib_ctx->core; - ulong id = core->gs_next_id; + ulong id; + gx_monitor_enter((gx_monitor_t *)(core->monitor)); + id = core->gs_next_id; core->gs_next_id += count; + gx_monitor_leave((gx_monitor_t *)(core->monitor)); + return id; } diff --git a/base/gsutil.h b/base/gsutil.h index e3269311..18cbe33f 100644 --- a/base/gsutil.h +++ b/base/gsutil.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gswin.rc b/base/gswin.rc index 5ba2d341..bdde58e1 100644 --- a/base/gswin.rc +++ b/base/gswin.rc @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gsxfont.h b/base/gsxfont.h index ef45a1a3..c8c5d747 100644 --- a/base/gsxfont.h +++ b/base/gsxfont.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gx.h b/base/gx.h index 60a411aa..ca2dc273 100644 --- a/base/gx.h +++ b/base/gx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxacpath.c b/base/gxacpath.c index fe9184ad..36ff8c3f 100644 --- a/base/gxacpath.c +++ b/base/gxacpath.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxalloc.h b/base/gxalloc.h index dd164756..1ea4f787 100644 --- a/base/gxalloc.h +++ b/base/gxalloc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxalpha.h b/base/gxalpha.h index de14cd89..4134d857 100644 --- a/base/gxalpha.h +++ b/base/gxalpha.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxarith.h b/base/gxarith.h index 3d4c7d9a..b2833178 100644 --- a/base/gxarith.h +++ b/base/gxarith.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxband.h b/base/gxband.h index 1af69cbf..6e13e9ea 100644 --- a/base/gxband.h +++ b/base/gxband.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxbcache.c b/base/gxbcache.c index adcd9b46..184c7647 100644 --- a/base/gxbcache.c +++ b/base/gxbcache.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -18,6 +18,7 @@ #include "memory_.h" #include "stdint_.h" #include "gx.h" +#include "gxobj.h" #include "gsmdebug.h" #include "gxbcache.h" @@ -59,8 +60,10 @@ gx_bits_cache_chunk_init(gx_bits_cache_chunk * bck, byte * data, uint size) /* If there isn't enough room, set *pcbh to an entry requiring freeing, */ /* or to 0 if we are at the end of the chunk, and return -1. */ int -gx_bits_cache_alloc(gx_bits_cache * bc, ulong lsize, gx_cached_bits_head ** pcbh) +gx_bits_cache_alloc(gx_bits_cache * bc, ulong lsize0, gx_cached_bits_head ** pcbh) { + ulong lsize = ROUND_UP(lsize0, obj_align_mod); + #define ssize ((uint)lsize) ulong lsize1 = lsize + sizeof(gx_cached_bits_head); diff --git a/base/gxbcache.h b/base/gxbcache.h index be601b69..be85bcc8 100644 --- a/base/gxbcache.h +++ b/base/gxbcache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxbitfmt.h b/base/gxbitfmt.h index 8cdc0bc0..134d02db 100644 --- a/base/gxbitfmt.h +++ b/base/gxbitfmt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxbitmap.h b/base/gxbitmap.h index 9f18a94b..c4cd64de 100644 --- a/base/gxbitmap.h +++ b/base/gxbitmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxbitops.h b/base/gxbitops.h index 8b1e9074..8ab1e2a2 100644 --- a/base/gxbitops.h +++ b/base/gxbitops.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxblend.c b/base/gxblend.c index 41059483..a7c22332 100644 --- a/base/gxblend.c +++ b/base/gxblend.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -402,7 +402,8 @@ void smask_copy(int num_rows, int num_cols, int row_stride, } } -void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, +int +smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, int row_stride, int plane_stride, byte *gs_restrict src, const byte *gs_restrict dst, gsicc_link_t *icclink, bool deep) { @@ -427,7 +428,7 @@ void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, false, false, true, plane_stride, row_stride, num_rows, num_cols); /* Transform the data */ - (icclink->procs.map_buffer)(dev, icclink, &input_buff_desc, &output_buff_desc, + return (icclink->procs.map_buffer)(dev, icclink, &input_buff_desc, &output_buff_desc, (void*) src, (void*) dst); } @@ -1244,7 +1245,7 @@ art_blend_pixel_8_inline(byte *gs_restrict dst, const byte *gs_restrict backdrop break; case BLEND_MODE_Hue: { - byte tmp[4]; + byte tmp[ART_MAX_CHAN]; pblend_procs->blend_luminosity(n_chan, tmp, src, backdrop); pblend_procs->blend_saturation(n_chan, dst, tmp, backdrop); @@ -1504,7 +1505,7 @@ art_blend_pixel_16_inline(uint16_t *gs_restrict dst, const uint16_t *gs_restrict break; case BLEND_MODE_Hue: { - uint16_t tmp[4]; + uint16_t tmp[ART_MAX_CHAN]; pblend_procs->blend_luminosity16(n_chan, tmp, src, backdrop); pblend_procs->blend_saturation16(n_chan, dst, tmp, backdrop); @@ -5165,10 +5166,11 @@ do_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, * Unpack the gx_color_index values. Complement the components for subtractive * color spaces. */ - if (has_tags) { - curr_tag = (color >> (num_comp*8)) & 0xff; - } + if (devn) { + if (has_tags) { + curr_tag = pdc->tag; + } if (additive) { for (j = 0; j < (num_comp - num_spots); j++) { src[j] = ((pdc->colors.devn.values[j]) >> shift & mask); @@ -5182,8 +5184,12 @@ do_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask); } } - } else + } else { + if (has_tags) { + curr_tag = (color >> (num_comp * 8)) & 0xff; + } pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src); + } src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5); if (has_shape) shape = (byte)floor (255 * pdev->shape + 0.5); @@ -5796,10 +5802,10 @@ do_mark_fill_rectangle16(gx_device * dev, int x, int y, int w, int h, * Unpack the gx_color_index values. Complement the components for subtractive * color spaces. */ - if (has_tags) { - curr_tag = (color >> (num_comp*16)) & 0xff; - } if (devn) { + if (has_tags) { + curr_tag = pdc->tag; + } if (additive) { for (j = 0; j < (num_comp - num_spots); j++) { src[j] = pdc->colors.devn.values[j]; @@ -5813,8 +5819,12 @@ do_mark_fill_rectangle16(gx_device * dev, int x, int y, int w, int h, src[j] = 65535 - pdc->colors.devn.values[j]; } } - } else + } else { + if (has_tags) { + curr_tag = (color >> (num_comp * 16)) & 0xff; + } pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src); + } src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5); if (has_shape) shape = (uint16_t)floor (65535 * pdev->shape + 0.5); diff --git a/base/gxblend.h b/base/gxblend.h index 0ac93877..a1f62e18 100644 --- a/base/gxblend.h +++ b/base/gxblend.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -100,7 +100,7 @@ void smask_blend(byte *gs_restrict src, int width, int height, int rowstride, void smask_copy(int num_rows, int num_cols, int row_stride, byte *gs_restrict src, const byte *gs_restrict des); -void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, +int smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, int row_stride, int plane_stride, byte *gs_restrict src, const byte *gs_restrict des, gsicc_link_t *icclink, bool deep); /* For spot colors, blend modes must be white preserving and separable */ @@ -389,7 +389,7 @@ void gx_build_blended_image_row16(const byte *gs_restrict buf_ptr, int planestri void gx_blend_image_buffer(byte *buf_ptr, int width, int height, int rowstride, int planestride, int num_comp, byte bg); void gx_blend_image_buffer16(byte *buf_ptr, int width, int height, - int rowstride, int planestride, int num_comp, uint16_t bg); + int rowstride, int planestride, int num_comp, uint16_t bg, bool keep_native); void gx_blend_image_buffer8to16(const byte *buf_ptr, unsigned short *buf_ptr_out, int width, int height, int rowstride, int planestride, int num_comp, byte bg); int gx_put_blended_image_custom(gx_device *target, byte *buf_ptr, diff --git a/base/gxblend1.c b/base/gxblend1.c index 6d42a094..c4f14e6c 100644 --- a/base/gxblend1.c +++ b/base/gxblend1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -226,6 +226,7 @@ pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile, int y0 = max(buf->rect.p.y, tos->rect.p.y); int y1 = min(buf->rect.q.y, tos->rect.q.y); bool deep = buf->deep; + int code; if (x0 < x1 && y0 < y1) { int width = x1 - x0; @@ -283,9 +284,11 @@ pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile, false, true, buf->planestride, buf->rowstride, height, width); /* Transform the data. */ - (icc_link->procs.map_buffer)(dev, icc_link, &input_buff_desc, + code = (icc_link->procs.map_buffer)(dev, icc_link, &input_buff_desc, &output_buff_desc, tos_plane, buf_plane); gsicc_release_link(icc_link); + if (code < 0) + return gs_throw(gs_error_unknownerror, "ICC transform failed. Trans backdrop"); } /* Copy the alpha data */ buf_plane += buf->planestride * (buf->n_chan - 1); @@ -840,7 +843,7 @@ gx_blend_image_buffer(byte *buf_ptr, int width, int height, int rowstride, void gx_blend_image_buffer16(byte *buf_ptr_, int width, int height, int rowstride, - int planestride, int num_comp, uint16_t bg) + int planestride, int num_comp, uint16_t bg, bool keep_native) { uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_; int x, y; @@ -870,10 +873,12 @@ gx_blend_image_buffer16(byte *buf_ptr_, int width, int height, int rowstride, } else if (a == 0xffff) { #if ARCH_IS_BIG_ENDIAN #else - for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[position + planestride * comp_num]; - ((byte *)&buf_ptr[position + planestride * comp_num])[0] = comp>>8; - ((byte *)&buf_ptr[position + planestride * comp_num])[1] = comp; + if (!keep_native) { + for (comp_num = 0; comp_num < num_comp; comp_num++) { + comp = buf_ptr[position + planestride * comp_num]; + ((byte *)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8; + ((byte *)&buf_ptr[position + planestride * comp_num])[1] = comp; + } } #endif } else { diff --git a/base/gxccache.c b/base/gxccache.c index e4f4364c..250d3896 100644 --- a/base/gxccache.c +++ b/base/gxccache.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxccman.c b/base/gxccman.c index b2d84305..b31b6959 100644 --- a/base/gxccman.c +++ b/base/gxccman.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -34,6 +34,7 @@ #include "gxxfont.h" #include "gxttfb.h" #include "gxfont42.h" +#include "gxobj.h" /* Define the descriptors for the cache structures. */ private_st_cached_fm_pair(); @@ -79,7 +80,7 @@ gx_char_cache_alloc(gs_memory_t * struct_mem, gs_memory_t * bits_mem, cache character memory before filling the table. The searching code uses an empty table entry as a sentinel. */ chsize = max(chsize, ROUND_UP(bmax, sizeof_cached_char) / sizeof_cached_char + 1); - + /* Round up chsize to a power of 2. */ while (chsize & (chsize + 1)) chsize |= chsize >> 1; @@ -932,8 +933,8 @@ alloc_char(gs_font_dir * dir, ulong icdsize, cached_char **pcc) gs_memory_t *mem = dir->ccache.bits_memory; char_cache_chunk *cck_prev = dir->ccache.chunks; char_cache_chunk *cck; - uint cksize = dir->ccache.bmax / 5 + 1; - uint tsize = dir->ccache.bmax - dir->ccache.bspace; + uint cksize = ROUND_UP(dir->ccache.bmax / 5 + 1, obj_align_mod); + uint tsize = ROUND_UP(dir->ccache.bmax - dir->ccache.bspace, obj_align_mod); byte *cdata; if (cksize > tsize) diff --git a/base/gxcdevn.h b/base/gxcdevn.h index 62ecb8db..61874118 100644 --- a/base/gxcdevn.h +++ b/base/gxcdevn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxchar.c b/base/gxchar.c index 7d6259d9..2332b70a 100644 --- a/base/gxchar.c +++ b/base/gxchar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxchar.h b/base/gxchar.h index 04ff7deb..4a26768f 100644 --- a/base/gxchar.h +++ b/base/gxchar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxchrout.c b/base/gxchrout.c index 87fcd43c..55aafdfd 100644 --- a/base/gxchrout.c +++ b/base/gxchrout.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxchrout.h b/base/gxchrout.h index 8bbb3524..6f31f043 100644 --- a/base/gxchrout.h +++ b/base/gxchrout.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcht.c b/base/gxcht.c index e4b47ce4..dc1064a1 100644 --- a/base/gxcht.c +++ b/base/gxcht.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -841,12 +841,12 @@ static const gx_const_strip_bitmap ht_no_bitmap = { /* Set the color value(s) and halftone mask for one plane. */ static inline void set_plane_color(int i, color_values_pair_t *pvp, const gx_device_color * pdc, - const gx_const_strip_bitmap * sbits[MAX_DCC], gx_ht_cache * caches[MAX_DCC], + const gx_const_strip_bitmap * sbits[MAX_DCC], gx_ht_cache * caches[MAX_DCC], gx_color_value max_color, bool invert) { uint q = pdc->colors.colored.c_base[i]; uint r = pdc->colors.colored.c_level[i]; - + pvp->values[0][i] = fractional_color(q, max_color); if (r == 0) pvp->values[1][i] = pvp->values[0][i], sbits[i] = &ht_no_bitmap; @@ -855,7 +855,7 @@ static inline void set_plane_color(int i, color_values_pair_t *pvp, const gx_dev sbits[i] = (const gx_const_strip_bitmap *) &gx_render_ht(caches[i], r)->tiles; } else { const gx_device_halftone *pdht = pdc->colors.colored.c_ht; - int nlevels = + int nlevels = (pdht->components ? pdht->components[i].corder.num_levels : pdht->order.num_levels); pvp->values[1][i] = pvp->values[0][i]; pvp->values[0][i] = fractional_color(q + 1, max_color); diff --git a/base/gxcid.h b/base/gxcid.h index c172b72c..8e8b2c5d 100644 --- a/base/gxcid.h +++ b/base/gxcid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcie.h b/base/gxcie.h index 860bf292..f9aab2dc 100644 --- a/base/gxcie.h +++ b/base/gxcie.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcindex.h b/base/gxcindex.h index 5e0d2761..e7e86cf6 100644 --- a/base/gxcindex.h +++ b/base/gxcindex.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclbits.c b/base/gxclbits.c index 519cdacb..9fd0990c 100644 --- a/base/gxclbits.c +++ b/base/gxclbits.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -95,28 +95,28 @@ cmd_compress_bitmap(stream_state * st, const byte * data, uint width_bits, uint mask = (0xff00>>(width_bits & 7)) & 0xff; uint padding = width_bytes - ((width_bits+7)>>3); - r.ptr = data - 1; if (raster == whole_bytes) { - r.limit = r.ptr + raster * height; + stream_cursor_read_init(&r, data, raster * (size_t)height); status = (*st->templat->process) (st, &r, pw, true); } else { /* Compress row-by-row. */ uint y; + stream_cursor_read_init(&r, data, whole_bytes); + for (y = height-1; (r.limit = r.ptr + whole_bytes), y > 0; y--) { status = go_process(st, &r, pw, false); if (status) break; if (mask) { byte b = r.ptr[1] & mask; - r2.limit = &b; - r2.ptr = r2.limit-1; + + stream_cursor_read_init(&r2, &b, 1); status = go_process(st, &r2, pw, false); if (status) break; } if (padding) { - r2.ptr = zeros - 1; - r2.limit = r2.ptr + padding; + stream_cursor_read_init(&r2, zeros, padding); status = go_process(st, &r2, pw, false); if (status) break; @@ -127,13 +127,12 @@ cmd_compress_bitmap(stream_state * st, const byte * data, uint width_bits, status = go_process(st, &r, pw, padding == 0 && mask == 0); if (status == 0 && mask) { byte b = r.ptr[1] & mask; - r2.limit = &b; - r2.ptr = r2.limit-1; + + stream_cursor_read_init(&r2, &b, 1); status = go_process(st, &r2, pw, padding == 0); } if (status == 0 && padding) { - r2.ptr = zeros - 1; - r2.limit = r2.ptr + padding; + stream_cursor_read_init(&r2, zeros, padding); status = go_process(st, &r2, pw, true); } } @@ -234,7 +233,7 @@ cmd_put_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint wcount = w.ptr - wbase; cmd_shorten_list_op(cldev, - (pcls ? &pcls->list : &cldev->band_range_list), + (pcls ? &pcls->list : cldev->band_range_list), try_size - (op_size + wcount)); *psize = op_size + wcount; goto out; @@ -246,7 +245,7 @@ cmd_put_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls, "[L]Uncompressed bits %u too large for buffer\n", uncompressed_size); cmd_shorten_list_op(cldev, - (pcls ? &pcls->list : &cldev->band_range_list), + (pcls ? &pcls->list : cldev->band_range_list), try_size); return_error(gs_error_limitcheck); } @@ -254,7 +253,7 @@ cmd_put_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls, if_debug2m('L',cldev->memory,"[L]Shortening bits from %u to %u\n", try_size, op_size + short_size); cmd_shorten_list_op(cldev, - (pcls ? &pcls->list : &cldev->band_range_list), + (pcls ? &pcls->list : cldev->band_range_list), try_size - (op_size + short_size)); *psize = op_size + short_size; } @@ -273,7 +272,7 @@ cmd_put_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls, if ((compression_mask & (1 << cmd_compress_const)) && (code = bytes_rectangle_is_const(data, raster, uncompressed_raster << 3, height)) >= 0) { cmd_shorten_list_op(cldev, - (pcls ? &pcls->list : &cldev->band_range_list), + (pcls ? &pcls->list : cldev->band_range_list), *psize - (op_size + 1)); *psize = op_size + 1; dp[op_size] = code; diff --git a/base/gxcldev.h b/base/gxcldev.h index 00dca1c8..290c6cda 100644 --- a/base/gxcldev.h +++ b/base/gxcldev.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -271,7 +271,7 @@ struct gx_clist_state_s { short clip_enabled; /* 0 = don't clip, 1 = do clip, */ /* -1 is used internally */ bool color_is_alpha; /* for copy_color_alpha */ - bool color_is_devn; /* more overload of copy_color_alpha for devn support */ + bool color_is_devn; /* more overload of copy_color_alpha for devn support */ uint known; /* flags for whether this band */ /* knows various misc. parameters */ /* We assign 'known' flags here from the high end; */ @@ -451,7 +451,7 @@ typedef struct { extern const clist_select_color_t clist_select_color0, clist_select_color1, clist_select_tile_color0, - clist_select_tile_color1, clist_select_devn_color0, + clist_select_tile_color1, clist_select_devn_color0, clist_select_devn_color1; /* See comments in gxclutil.c */ @@ -565,8 +565,8 @@ const byte *cmd_read_matrix(gs_matrix * pmat, const byte * cbp); int cmd_write_rect_cmd(gx_device_clist_writer * cldev, gx_clist_state * pcls, int op, int x, int y, int width, int height); /* Put out a fill with a devn color */ -int cmd_write_rect_hl_cmd(gx_device_clist_writer * cldev, - gx_clist_state * pcls, int op, int x, int y, +int cmd_write_rect_hl_cmd(gx_device_clist_writer * cldev, + gx_clist_state * pcls, int op, int x, int y, int width, int height, bool extended_command); /* Put out a fill or tile rectangle command for fillpage. */ int cmd_write_page_rect_cmd(gx_device_clist_writer * cldev, int op); @@ -689,6 +689,8 @@ int clist_writer_pop_cropping(gx_device_clist_writer *cdev); int clist_writer_check_empty_cropping_stack(gx_device_clist_writer *cdev); int clist_read_icctable(gx_device_clist_reader *crdev); int clist_read_color_usage_array(gx_device_clist_reader *crdev); +int clist_read_op_equiv_cmyk_colors(gx_device_clist_reader *crdev, + equivalent_cmyk_color_params *op_equiv); /* Special write out for the serialized icc profile table */ @@ -699,9 +701,9 @@ int cmd_write_icctable(gx_device_clist_writer * cldev, unsigned char *pbuf, int may later include compressed image data */ typedef enum { - COLOR_USAGE_OFFSET = 1, - ICC_TABLE_OFFSET = 2 + SPOT_EQUIV_COLORS = 2, + ICC_TABLE_OFFSET = 3 } psuedoband_offset; diff --git a/base/gxclfile.c b/base/gxclfile.c index 4476ef5c..f03646ec 100644 --- a/base/gxclfile.c +++ b/base/gxclfile.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclimag.c b/base/gxclimag.c index 9747c899..d638bea6 100644 --- a/base/gxclimag.c +++ b/base/gxclimag.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -478,6 +478,7 @@ clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, bool is_planar_dev = dev->is_planar; bool render_is_valid; int csi; + gx_clip_path *lpcpath = NULL; /* We can only handle a limited set of image types. */ switch ((gs_debug_c('`') ? -1 : pic->type->index)) { @@ -600,7 +601,19 @@ clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, pie->rect.q.x = pim->Width, pie->rect.q.y = pim->Height; } pie->pgs = pgs; - pie->pcpath = pcpath; + + if (pcpath) { + lpcpath = gx_cpath_alloc(mem, "clist_begin_typed_image(lpcpath)"); + if (!lpcpath) { + goto use_default; + } + code = gx_cpath_copy(pcpath, lpcpath); + if (code < 0) { + goto use_default; + } + } + pie->pcpath = lpcpath; + pie->buffer = NULL; pie->format = format; pie->bits_per_plane = bits_per_pixel / pie->num_planes; @@ -767,7 +780,7 @@ clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, gs_bbox_transform(&sbox, &mat, &dbox); if (cdev->disable_mask & clist_disable_complex_clip) - if (!check_rect_for_trivial_clip(pcpath, + if (!check_rect_for_trivial_clip(lpcpath, (int)floor(dbox.p.x), (int)floor(dbox.p.y), (int)ceil(dbox.q.x), (int)ceil(dbox.q.y))) goto use_default; @@ -797,7 +810,7 @@ clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, if (!indexed) { pie->monitor_color = true; /* Set up the unpacking proc for monitoring */ - get_unpack_proc((gx_image_enum_common_t*) pie, &(pie->decode), + get_unpack_proc((gx_image_enum_common_t*) pie, &(pie->decode), pim->format, pim->Decode); get_map(&(pie->decode), pim->format, pim->Decode); if (pie->decode.unpack == NULL) { @@ -874,10 +887,14 @@ clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, for (i = 0; i <= max_value; ++i) { /* Enumerate the indexed colors, or just Black (DeviceGray = 0) */ cc.paint.values[0] = (double)i; - remap_color(&cc, pcs, &dcolor, pgs, dev, + code = remap_color(&cc, pcs, &dcolor, pgs, dev, gs_color_select_source); + if (code < 0) + break; color_usage |= cmd_drawing_color_usage(cdev, &dcolor); } + if (code < 0) + goto use_default; } } pie->color_usage.or = color_usage; @@ -892,9 +909,9 @@ clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, int y0 = (int)floor(dbox.p.y - 0.51); /* adjust + rounding slop */ int y1 = (int)ceil(dbox.q.y + 0.51); /* ditto */ - if (pcpath) { + if (lpcpath) { gs_fixed_rect obox; - gx_cpath_outer_box(pcpath, &obox); + gx_cpath_outer_box(lpcpath, &obox); pie->ymin = max(0, max(y0, fixed2int(obox.p.y))); pie->ymax = min(min(y1, fixed2int(obox.q.y)), dev->height); } else { @@ -931,6 +948,9 @@ use_default: gs_free_object(mem, pie, "clist_begin_typed_image"); *pinfo = NULL; + if (lpcpath != NULL) + gx_cpath_free(lpcpath, "clist_begin_typed_image(lpcpath)"); + if (pgs->has_transparency){ return -1; } else { @@ -1258,6 +1278,9 @@ clist_image_end_image(gx_image_enum_common_t * info, bool draw_last) #endif code = write_image_end_all(dev, pie); cdev->image_enum_id = gs_no_id; + gx_cpath_free((gx_clip_path *)pie->pcpath, "clist_image_end_image(pie->pcpath)"); + cdev->clip_path = NULL; + cdev->clip_path_id = gs_no_id; gx_image_free_enum(&info); return code; } @@ -1278,6 +1301,7 @@ clist_create_compositor(gx_device * dev, int first_band = 0, no_of_bands = cdev->nbands; int code = pcte->type->procs.write(pcte, 0, &size, cdev); int temp_cropping_min, temp_cropping_max; + int newdev; CMD_CHECK_LAST_OP_BLOCK_DEFINED(cdev); @@ -1291,6 +1315,7 @@ clist_create_compositor(gx_device * dev, pcdev, pgs, mem); if (code < 0) return code; + newdev = code == 1; CMD_CHECK_LAST_OP_BLOCK_DEFINED(cdev); @@ -1356,6 +1381,9 @@ clist_create_compositor(gx_device * dev, /* serialize the remainder of the compositor */ if ((code = pcte->type->procs.write(pcte, dp + 3, &size_dummy, cdev)) < 0) ((gx_device_clist_writer *)dev)->cnext = dp; + + if (code >= 0 && newdev) + code = 1; /* Return 1 to indicate we created a new device. */ return code; } if (cropping_op == PUSHCROP) { @@ -1372,6 +1400,11 @@ clist_create_compositor(gx_device * dev, temp_cropping_min = cdev->cropping_min; temp_cropping_max = cdev->cropping_max; } + /* Adjust the lower and upper bound to allow for image gridfitting changing boundaries */ + if (temp_cropping_min > 0) + temp_cropping_min--; + if (temp_cropping_max < dev->height - 1) + temp_cropping_max++; if (temp_cropping_min < temp_cropping_max) { /* The pdf14 compositor could be applied only to bands covered by the pcte->params.bbox. */ @@ -1397,6 +1430,9 @@ clist_create_compositor(gx_device * dev, return code; } + if (newdev) + code = 1; /* Return 1 to indicate we created a new device. */ + return code; } @@ -2004,7 +2040,7 @@ cmd_image_plane_data_mon(gx_device_clist_writer * cldev, gx_clist_state * pcls, to see if we have any non-neutral colors */ int pdata_x; byte *data_ptr = (byte *)(planes[0].data + i * planes[0].raster + offsets[0] + offset); - byte *buffer = (byte *)(*pie_c->decode.unpack)(pie_c->buffer, &pdata_x, + byte *buffer = (byte *)(*pie_c->decode.unpack)(pie_c->buffer, &pdata_x, data_ptr, 0, dsize, pie_c->decode.map, pie_c->decode.spread, pie_c->decode.spp); diff --git a/base/gxclio.h b/base/gxclio.h index 9e2e28f9..8dcb8308 100644 --- a/base/gxclio.h +++ b/base/gxclio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclip.c b/base/gxclip.c index f566e09f..0b7939ef 100644 --- a/base/gxclip.c +++ b/base/gxclip.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -590,7 +590,7 @@ clip_fill_rectangle(gx_device * dev, int x, int y, int w, int h, } int -clip_call_fill_rectangle_hl_color(clip_callback_data_t * pccd, int xc, int yc, +clip_call_fill_rectangle_hl_color(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec) { gs_fixed_rect rect; @@ -1245,7 +1245,7 @@ clip_copy_alpha(gx_device * dev, } int -clip_call_copy_alpha_hl_color(clip_callback_data_t * pccd, int xc, int yc, +clip_call_copy_alpha_hl_color(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec) { return (*dev_proc(pccd->tdev, copy_alpha_hl_color)) @@ -1308,8 +1308,8 @@ clip_call_strip_tile_rect_devn(clip_callback_data_t * pccd, int xc, int yc, int static int clip_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, int x, int y, int w, int h, - const gx_drawing_color *pdcolor0, - const gx_drawing_color *pdcolor1, int phase_x, + const gx_drawing_color *pdcolor0, + const gx_drawing_color *pdcolor1, int phase_x, int phase_y) { gx_device_clip *rdev = (gx_device_clip *) dev; diff --git a/base/gxclip.h b/base/gxclip.h index 70640afc..5d44bc00 100644 --- a/base/gxclip.h +++ b/base/gxclip.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclip2.c b/base/gxclip2.c index 1b4d1558..38e79fab 100644 --- a/base/gxclip2.c +++ b/base/gxclip2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -155,7 +155,7 @@ tile_clip_set_phase(gx_device_tile_clip * cdev, int px, int py) /* Fill a rectangle with high level devn color by tiling with the mask. */ static int tile_clip_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_gstate *pgs, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_tile_clip *cdev = (gx_device_tile_clip *) dev; @@ -177,7 +177,7 @@ tile_clip_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, w = fixed2int(rect->q.x) - x; h = fixed2int(rect->q.y) - y; return (*dev_proc(tdev, strip_tile_rect_devn))(tdev, &cdev->tiles, - x, y, w, h, &dcolor0, &dcolor1, + x, y, w, h, &dcolor0, &dcolor1, cdev->phase.x, cdev->phase.y); } @@ -379,7 +379,7 @@ tile_clip_copy_alpha(gx_device * dev, static int tile_clip_copy_alpha_hl_color(gx_device * dev, const byte * data, int sourcex, int raster, gx_bitmap_id id, - int x, int y, int w, int h, const gx_drawing_color *pdcolor, + int x, int y, int w, int h, const gx_drawing_color *pdcolor, int depth) { gx_device_tile_clip *cdev = (gx_device_tile_clip *) dev; diff --git a/base/gxclip2.h b/base/gxclip2.h index 20ebf024..616c8ece 100644 --- a/base/gxclip2.h +++ b/base/gxclip2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclipm.c b/base/gxclipm.c index ec02ba9a..59f1e765 100644 --- a/base/gxclipm.c +++ b/base/gxclipm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -152,7 +152,7 @@ mask_clip_fill_rectangle_hl_color(gx_device *dev, /* It would be nice to have a higher level way to do this operation like a copy_mono_hl_color */ return (pdcolor->type->fill_masked) - (pdcolor, cdev->tiles.data + my0 * cdev->tiles.raster, mx0, + (pdcolor, cdev->tiles.data + my0 * cdev->tiles.raster, mx0, cdev->tiles.raster, cdev->tiles.id, mx0 - cdev->phase.x, my0 - cdev->phase.y, mx1 - mx0, my1 - my0, tdev, lop_default, false); @@ -404,7 +404,7 @@ mask_clip_copy_alpha(gx_device * dev, static int mask_clip_copy_alpha_hl_color(gx_device * dev, const byte * data, int sourcex, int raster, gx_bitmap_id id, - int x, int y, int w, int h, const gx_drawing_color *pdcolor, + int x, int y, int w, int h, const gx_drawing_color *pdcolor, int depth) { gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev; @@ -437,7 +437,7 @@ mask_clip_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, static int mask_clip_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, int x, int y, int w, int h, - const gx_drawing_color *pdcolor0, + const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y) { diff --git a/base/gxclipm.h b/base/gxclipm.h index dcae2baf..429f1595 100644 --- a/base/gxclipm.h +++ b/base/gxclipm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclipsr.h b/base/gxclipsr.h index 20e57011..716c0744 100644 --- a/base/gxclipsr.h +++ b/base/gxclipsr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclist.c b/base/gxclist.c index 9df5f7c9..7c7f0aa4 100644 --- a/base/gxclist.c +++ b/base/gxclist.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -31,6 +31,7 @@ #include "gsicc_manage.h" #include "gsicc_cache.h" #include "gxdevsop.h" +#include "gxobj.h" #include "valgrind.h" @@ -361,7 +362,7 @@ clist_minimum_buffer(int nbands) { /* * Initialize the allocation for the band states, which are used only - * when writing. Requires: nbands. Sets: states, cbuf, cend. + * when writing. Requires: nbands. Sets: states, cbuf, cend, band_range_list. */ static int clist_init_states(gx_device * dev, byte * init_data, uint data_size) @@ -378,7 +379,8 @@ clist_init_states(gx_device * dev, byte * init_data, uint data_size) cdev->cend = init_data + data_size; init_data += alignment; cdev->states = (gx_clist_state *) init_data; - cdev->cbuf = init_data + state_size; + cdev->band_range_list = (cmd_list *)(init_data + state_size); + cdev->cbuf = init_data + state_size + sizeof(cmd_list); return 0; } @@ -410,6 +412,8 @@ clist_init_data(gx_device * dev, byte * init_data, uint data_size) int code; int align = 1 << (target->log2_align_mod > log2_align_bitmap_mod ? target->log2_align_mod : log2_align_bitmap_mod); + align = align < obj_align_mod ? obj_align_mod : align; + /* the clist writer has its own color info that depends upon the transparency group color space (if transparency exists). The data that is used in the clist writing. Here it is initialized with @@ -540,7 +544,7 @@ clist_reset(gx_device * dev) sizeof(*cdev->tile_table)); cdev->cnext = cdev->cbuf; cdev->ccl = 0; - cdev->band_range_list.head = cdev->band_range_list.tail = 0; + cdev->band_range_list->head = cdev->band_range_list->tail = 0; cdev->band_range_min = 0; cdev->band_range_max = nbands - 1; { @@ -756,6 +760,17 @@ clist_close(gx_device *dev) gs_free_object(cdev->memory->thread_safe_memory, cdev->icc_cache_list, "clist_close"); cdev->icc_cache_list = NULL; + /* So despite the comment above, it seems necessary to free the cache_chunk here, + * if the device is not being retained. The code in gx_pattern_cache_free_entry() doesn't + * actually free it, in at least some cases. + * TODO: Is it sufficient to only free it here, and not in the places mentioned above? + */ + if (!cdev->retained) { + gs_free_object(cdev->memory->non_gc_memory, cdev->cache_chunk, + "clist_close(cache_chunk)"); + cdev->cache_chunk = NULL; + } + if (cdev->do_not_open_or_close_bandfiles) return 0; if (dev_proc(cdev, open_device) == pattern_clist_open_device) { @@ -848,6 +863,7 @@ clist_end_page(gx_device_clist_writer * cldev) clist_free_icc_table(cldev->icc_table, cldev->memory); cldev->icc_table = NULL; } + if (code >= 0) { code = clist_write_color_usage_array(cldev); if (code >= 0) { @@ -1205,6 +1221,17 @@ clist_write_color_usage_array(gx_device_clist_writer *cldev) return(0); } +/* This writes out the spot equivalent cmyk values for the page. + These are used for overprint simulation. Read back by the + pdf14 device during the put_image operation */ +int +clist_write_op_equiv_cmyk_colors(gx_device_clist_writer *cldev, + equivalent_cmyk_color_params *op_equiv_cmyk) +{ + return cmd_write_pseudo_band(cldev, (unsigned char *)op_equiv_cmyk, + sizeof(equivalent_cmyk_color_params), SPOT_EQUIV_COLORS); +} + /* Compute color_usage over a Y range while writing clist */ /* Sets color_usage fields and range_start. */ /* Returns range end (max dev->height) */ @@ -1351,7 +1378,7 @@ clist_make_accum_device(gs_memory_t *mem, gx_device *target, const char *dname, bool use_memory_clist, bool uses_transparency, gs_pattern1_instance_t *pinst) { - gx_device_clist *cdev = gs_alloc_struct(mem, gx_device_clist, + gx_device_clist *cdev = gs_alloc_struct(mem->stable_memory, gx_device_clist, &st_device_clist, "clist_make_accum_device"); gx_device_clist_writer *cwdev = (gx_device_clist_writer *)cdev; @@ -1361,10 +1388,10 @@ clist_make_accum_device(gs_memory_t *mem, gx_device *target, const char *dname, cwdev->params_size = sizeof(gx_device_clist); cwdev->static_procs = NULL; cwdev->dname = dname; - cwdev->memory = mem; + cwdev->memory = mem->stable_memory; cwdev->stype = &st_device_clist; cwdev->stype_is_dynamic = false; - rc_init(cwdev, mem, 1); + rc_init(cwdev, mem->stable_memory, 1); cwdev->retained = true; cwdev->is_open = false; cwdev->color_info = target->color_info; @@ -1447,3 +1474,116 @@ RELOC_PTRS_WITH(device_clist_mutatable_reloc_ptrs, gx_device_clist_mutatable *pd RELOC_PREFIX(st_device_forward); } RELOC_PTRS_END public_st_device_clist_mutatable(); + +int +clist_mutate_to_clist(gx_device_clist_mutatable *pdev, + gs_memory_t *buffer_memory, + byte **the_memory, + const gdev_space_params *space_params, + bool bufferSpace_is_exact, + const gx_device_buf_procs_t *buf_procs, + dev_proc_dev_spec_op(dev_spec_op), + uint min_buffer_space) +{ + gx_device *target = (gx_device *)pdev; + uint space; + int code; + gx_device_clist *const pclist_dev = (gx_device_clist *)pdev; + gx_device_clist_common * const pcldev = &pclist_dev->common; + bool reallocate = the_memory != NULL && *the_memory != NULL; + byte *base; + bool save_is_open = pdev->is_open; /* Save around temporary failure in open_c loop */ + + while (target->parent != NULL) { + target = target->parent; + gx_update_from_subclass(target); + } + + /* Try to allocate based simply on param-requested buffer size */ +#ifdef DEBUGGING_HACKS +#define BACKTRACE(first_arg)\ + BEGIN\ + ulong *fp_ = (ulong *)&first_arg - 2;\ + for (; fp_ && (fp_[1] & 0xff000000) == 0x08000000; fp_ = (ulong *)*fp_)\ + dmprintf2(buffer_memory, " fp="PRI_INTPTR" ip=0x%lx\n", (intptr_t)fp_, fp_[1]);\ + END +dmputs(buffer_memory, "alloc buffer:\n"); +BACKTRACE(pdev); +#endif /*DEBUGGING_HACKS*/ + for ( space = space_params->BufferSpace; ; ) { + base = (reallocate ? + (byte *)gs_resize_object(buffer_memory, *the_memory, space, + "cmd list buffer") : + gs_alloc_bytes(buffer_memory, space, + "cmd list buffer")); + if (base != NULL) + break; /* Allocation worked! Stop trying. */ + if (bufferSpace_is_exact) { + /* We wanted a specific size. Accept no substitutes. */ + break; + } + /* Let's try again for half the size. */ + if (space == min_buffer_space) + break; /* We already failed at the minimum size. */ + space >>= 1; + if (space < min_buffer_space) + space = min_buffer_space; + } + if (base == NULL) + return_error(gs_error_VMerror); + + /* Try opening the command list, to see if we allocated */ + /* enough buffer space. */ +open_c: + if (the_memory) + *the_memory = base; + pdev->buf = base; + pdev->buffer_space = space; + pclist_dev->common.orig_spec_op = dev_spec_op; + clist_init_io_procs(pclist_dev, pdev->BLS_force_memory); + clist_init_params(pclist_dev, base, space, target, + *buf_procs, + space_params->band, + false, /* do_not_open_or_close_bandfiles */ + (pdev->bandlist_memory == 0 ? pdev->memory->non_gc_memory: + pdev->bandlist_memory), + pdev->clist_disable_mask, + pdev->page_uses_transparency, + pdev->page_uses_overprint); + code = (*gs_clist_device_procs.open_device)( (gx_device *)pcldev ); + if (code < 0) { + /* If there wasn't enough room, and we haven't */ + /* already shrunk the buffer, try enlarging it. */ + if ( code == gs_error_rangecheck && + space >= space_params->BufferSpace && + !bufferSpace_is_exact + ) { + space += space / 8; + if (reallocate) { + base = gs_resize_object(buffer_memory, + *the_memory, space, + "cmd list buf(retry open)"); + } else { + gs_free_object(buffer_memory, base, + "cmd list buf(retry open)"); + base = gs_alloc_bytes(buffer_memory, space, + "cmd list buf(retry open)"); + if (the_memory != NULL) + *the_memory = base; + } + if (base != NULL) { + pdev->is_open = save_is_open; /* allow for success when we loop */ + goto open_c; + } + } + /* Failure. */ + if (!reallocate) { + gs_free_object(buffer_memory, base, "cmd list buf"); + pdev->buffer_space = 0; + if (the_memory != NULL) + *the_memory = NULL; + pdev->buf = NULL; + } + } + return code; +} diff --git a/base/gxclist.h b/base/gxclist.h index cdb0136f..a30331fb 100644 --- a/base/gxclist.h +++ b/base/gxclist.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -310,7 +310,7 @@ struct gx_device_clist_writer_s { byte *cnext; /* next slot in command buffer */ byte *cend; /* end of command buffer */ cmd_list *ccl; /* &clist_state.list of last command */ - cmd_list band_range_list; /* list of band-range commands */ + cmd_list *band_range_list; /* list of band-range commands */ int band_range_min, band_range_max; /* range for list */ uint tile_max_size; /* max size of a single tile (bytes) */ uint tile_max_count; /* max # of hash table entries */ @@ -418,7 +418,7 @@ extern_st(st_device_clist); #define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0) /* setup before opening clist device */ -#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xdisable, pageusestransparency)\ +#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xdisable, pageusestransparency, pageusesoverprint)\ BEGIN\ (xclist)->common.data = (xdata);\ (xclist)->common.data_size = (xdata_size);\ @@ -429,6 +429,7 @@ extern_st(st_device_clist); (xclist)->common.bandlist_memory = (xmemory);\ (xclist)->writer.disable_mask = (xdisable);\ (xclist)->writer.page_uses_transparency = (pageusestransparency);\ + (xclist)->writer.page_uses_overprint = (pageusesoverprint);\ (xclist)->writer.pinst = NULL;\ END @@ -493,6 +494,10 @@ int clist_put_data(const gx_device_clist *cdev, int select, int64_t offset, cons /* Write out the array of color usage entries (one per band) */ int clist_write_color_usage_array(gx_device_clist_writer *cldev); +/* Write out simulated overprint CMYK equiv. values for spot colors */ +int clist_write_op_equiv_cmyk_colors(gx_device_clist_writer *cldev, + equivalent_cmyk_color_params *op_equiv_cmyk); + /* get the color_usage summary over a Y range from the clist writer states */ /* Not expected to be used */ int clist_writer_color_usage(gx_device_clist_writer *cldev, int y, int height, @@ -661,4 +666,14 @@ extern_st(st_device_clist_mutatable); #define CLIST_MUTATABLE_HAS_MUTATED(pdev) \ (((gx_device_clist_mutatable *)(pdev))->buffer_space != 0) +int +clist_mutate_to_clist(gx_device_clist_mutatable *pdev, + gs_memory_t *buffer_memory, + byte **the_memory, + const gdev_space_params *space_params, + bool bufferSpace_is_exact, + const gx_device_buf_procs_t *buf_procs, + dev_proc_dev_spec_op(dev_spec_op), + uint min_buffer_space); + #endif /* gxclist_INCLUDED */ diff --git a/base/gxcllzw.c b/base/gxcllzw.c index 333d49d4..ad36e6de 100644 --- a/base/gxcllzw.c +++ b/base/gxcllzw.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclmem.c b/base/gxclmem.c index e4791152..832d1204 100644 --- a/base/gxclmem.c +++ b/base/gxclmem.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclmem.h b/base/gxclmem.h index 18fc9511..cf63160c 100644 --- a/base/gxclmem.h +++ b/base/gxclmem.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclpage.c b/base/gxclpage.c index 63573269..18ff9b81 100644 --- a/base/gxclpage.c +++ b/base/gxclpage.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclpage.h b/base/gxclpage.h index eaf8573c..c73b40b7 100644 --- a/base/gxclpage.h +++ b/base/gxclpage.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclpath.c b/base/gxclpath.c index c97379b9..5c757e36 100644 --- a/base/gxclpath.c +++ b/base/gxclpath.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclpath.h b/base/gxclpath.h index 962c5704..7a393730 100644 --- a/base/gxclpath.h +++ b/base/gxclpath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclrast.c b/base/gxclrast.c index 60c0ef77..f9f42d88 100644 --- a/base/gxclrast.c +++ b/base/gxclrast.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -475,7 +475,8 @@ read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem) int clist_playback_band(clist_playback_action playback_action, gx_device_clist_reader *cdev, stream *s, - gx_device *target, int x0, int y0, gs_memory_t * mem) + gx_device *target, int x0, int y0, + gs_memory_t * mem) /* lgtm [cpp/use-of-goto] */ { byte *cbuf_storage; command_buf_t cbuf; @@ -3095,18 +3096,11 @@ static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs, * change the target device. */ code = dev_proc(tdev, create_compositor)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev); - if (code >= 0 && tdev != *ptarget) { - /* If we created a new compositor here, then that new compositor should - * become the device to which we send all future drawing requests. If - * the above create_compositor call found an existing compositor - * already in the chain of devices (such as might happen when we are - * playing back a clist based pattern, and the top device is a clip - * device that forwards to a pdf14 device), then we'll just reuse - * that one. We do not want to send new drawing operations to the - * compositor, as that will sidestep the clipping. We therefore check - * the reference count to see if this is a new device or not. */ - if (tdev->rc.ref_count == 1) - *ptarget = tdev; + if (code == 1) { + /* A new compositor was created that wrapped tdev. This should + * be our new target. */ + *ptarget = tdev; + code = 0; } if (code < 0) return code; diff --git a/base/gxclread.c b/base/gxclread.c index f2ebf6b5..2323b68c 100644 --- a/base/gxclread.c +++ b/base/gxclread.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -377,7 +377,8 @@ clist_close_writer_and_init_reader(gx_device_clist *cldev) /* Used to find the command block information in the bfile that is related to extra information stored in a psuedo band. Currently application of this is storage of the ICC profile - table and the per-band color_usage array. We may eventually + table, the per-band color_usage array, and the spot equivalent + colors when doing overprint simulation. We may eventually use this for storing other information like compressed images. */ static int @@ -468,6 +469,23 @@ clist_read_color_usage_array(gx_device_clist_reader *crdev) return code; } +/* read the cmyk equivalent spot colors */ +int +clist_read_op_equiv_cmyk_colors(gx_device_clist_reader *crdev, + equivalent_cmyk_color_params *op_equiv_cmyk_colors) +{ + int code; + cmd_block cb; + + code = clist_find_pseudoband(crdev, crdev->nbands + SPOT_EQUIV_COLORS - 1, &cb); + if (code < 0) + return code; + + code = clist_read_chunk(crdev, cb.pos, sizeof(equivalent_cmyk_color_params), + (unsigned char *)op_equiv_cmyk_colors); + return code; +} + /* Unserialize the icc table information stored in the cfile and place it in the reader device */ static int diff --git a/base/gxclrect.c b/base/gxclrect.c index 6f71b61a..bbfb40d8 100644 --- a/base/gxclrect.c +++ b/base/gxclrect.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -24,8 +24,6 @@ #include "gxclpath.h" #include "gxdevsop.h" -extern dev_proc_dev_spec_op(gdev_prn_forwarding_dev_spec_op); - /* ---------------- Writing utilities ---------------- */ #define cmd_set_rect(rect)\ @@ -599,6 +597,10 @@ clist_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) return 1; if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path) return 1; + if (dev_spec_op == gxdso_copy_alpha_disabled) { + gx_device_clist_writer * const cdev = &((gx_device_clist *)pdev)->writer; + return (cdev->disable_mask & clist_disable_copy_alpha) != 0; + } if (dev_spec_op == gxdso_supports_devn || dev_spec_op == gxdso_skip_icc_component_validation) { cmm_dev_profile_t *dev_profile; @@ -619,10 +621,17 @@ clist_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) ibox->q.y = cwdev->cropping_max; return 0; } + if (dev_spec_op == gxdso_is_clist_device) + return 1; if (dev_spec_op == gxdso_overprint_active) { gx_device_clist_writer* cwdev = &((gx_device_clist*)pdev)->writer; return cwdev->op_fill_active || cwdev->op_stroke_active; } + /* This is a horrible hack. Accumulator devices have their procs + * overriden by clist ones in gdev_prn_open. */ + if (strncmp(pdev->dname, "pdf14-accum-", 12) == 0) { + return pdf14_accum_dev_spec_op(pdev, dev_spec_op, data, size); + } /* forward to the appropriate super class */ if (cdev->orig_spec_op) return cdev->orig_spec_op(pdev, dev_spec_op, data, size); diff --git a/base/gxclthrd.c b/base/gxclthrd.c index 64b6f530..088de2bf 100644 --- a/base/gxclthrd.c +++ b/base/gxclthrd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -119,7 +119,7 @@ setup_device_and_mem_for_thread(gs_memory_t *chunk_base_mem, gx_device *dev, boo OI_PROFILE, strlen(OI_PROFILE)) == 0) || (dev->icc_struct->proof_profile != NULL && strncmp(dev->icc_struct->proof_profile->name, OI_PROFILE, strlen(OI_PROFILE)) == 0)))) { - ndev->icc_struct = gsicc_new_device_profile_array(ndev->memory); + ndev->icc_struct = gsicc_new_device_profile_array(ndev); if (!ndev->icc_struct) { emprintf1(ndev->memory, "Error setting up device profile array, code=%d. Rendering threads not started.\n", diff --git a/base/gxclthrd.h b/base/gxclthrd.h index bc83c9bc..086e3325 100644 --- a/base/gxclthrd.h +++ b/base/gxclthrd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxclutil.c b/base/gxclutil.c index a66b37b6..055fbcf7 100644 --- a/base/gxclutil.c +++ b/base/gxclutil.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -268,7 +268,7 @@ cmd_write_buffer(gx_device_clist_writer * cldev, byte cmd_end) int band; int code = cmd_write_band(cldev, cldev->band_range_min, cldev->band_range_max, - &cldev->band_range_list, + cldev->band_range_list, cmd_opv_end_run); int warning = code; @@ -398,7 +398,7 @@ cmd_put_range_op(gx_device_clist_writer * cldev, int band_min, int band_max, if_debug4m('L', cldev->memory, "[L]band range(%d,%d): size=%u, left=%u", band_min, band_max, size, 0); if (cldev->ccl != 0 && - (cldev->ccl != &cldev->band_range_list || + (cldev->ccl != cldev->band_range_list || band_min != cldev->band_range_min || band_max != cldev->band_range_max) ) { @@ -408,7 +408,7 @@ cmd_put_range_op(gx_device_clist_writer * cldev, int band_min, int band_max, cldev->band_range_min = band_min; cldev->band_range_max = band_max; } - return cmd_put_list_op(cldev, &cldev->band_range_list, size); + return cmd_put_list_op(cldev, cldev->band_range_list, size); } /* Write a variable-size positive integer. */ @@ -799,7 +799,7 @@ cmd_put_params(gx_device_clist_writer *cldev, if (code < 0) { /* error serializing: back out by writing a 0-length parm list */ memset(dp - sizeof(unsigned), 0, sizeof(unsigned)); - cmd_shorten_list_op(cldev, &cldev->band_range_list, + cmd_shorten_list_op(cldev, cldev->band_range_list, old_param_length); } } else diff --git a/base/gxclzlib.c b/base/gxclzlib.c index d823f092..aaea9f57 100644 --- a/base/gxclzlib.c +++ b/base/gxclzlib.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcmap.c b/base/gxcmap.c index 7e92621d..cba4908e 100644 --- a/base/gxcmap.c +++ b/base/gxcmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -2276,7 +2276,9 @@ gx_get_cmapper(gx_cmapper_t *data, const gs_gstate *pgs, data->direct = 0; if (has_transfer && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) check_cmyk_color_model_comps(dev); - if (pgs->effective_transfer_non_identity_count == 0) + /* Per spec. Images with soft mask, and the mask, do not use transfer function */ + if (pgs->effective_transfer_non_identity_count == 0 || + (dev_proc(dev, dev_spec_op)(dev, gxdso_in_smask, NULL, 0)) > 0) has_transfer = 0; if (has_transfer) { if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { diff --git a/base/gxcmap.h b/base/gxcmap.h index fd3e9793..b626e632 100644 --- a/base/gxcmap.h +++ b/base/gxcmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -168,10 +168,13 @@ void gx_set_cmap_procs(gs_gstate *, const gx_device *); routines. Note: This information is currently being used by the routines for identifying when they are being given a separation name. Some devices automaticaly add separations to the device's components if the separation - is not previously known and there is room in the device. + is not previously known and there is room in the device. Overprint + simulation required a split of the NO_COMP_NAME_TYPE depending if we + are calling from the halftone setup or overprint setup. */ -#define NO_COMP_NAME_TYPE 0 -#define SEPARATION_NAME 1 +#define NO_COMP_NAME_TYPE_HT 0 +#define NO_COMP_NAME_TYPE_OP 1 +#define SEPARATION_NAME 2 /* Convert a color component name into a colorant index. diff --git a/base/gxcolor2.h b/base/gxcolor2.h index bb9376eb..8a3ca3f9 100644 --- a/base/gxcolor2.h +++ b/base/gxcolor2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcomp.h b/base/gxcomp.h index 2c741095..a3aef8d2 100644 --- a/base/gxcomp.h +++ b/base/gxcomp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -106,7 +106,7 @@ typedef struct gs_composite_type_procs_s { /* * Checks whether a next compositor operation closes this one. * Must set the 2nd argument with a pointer to the opening compositor operation. - * Return coides : <0 - error, 0 - not closing, + * Return codes : <0 - error, 0 - not closing, * 1 - closing with annihilation, 2 - execute immediately, * 3 - closing and replacing, 4 - replace one, 5 - drop queue. */ @@ -116,7 +116,7 @@ typedef struct gs_composite_type_procs_s { /* * Checks whether a next operation is friendly to the compositor - * so that it may commutate with the compositor operation. + * so that it may commute with the compositor operation. */ #define composite_is_friendly_proc(proc)\ bool proc(const gs_composite_t *this, byte cmd0, byte cmd1) diff --git a/base/gxcoord.h b/base/gxcoord.h index b8633928..24e560b7 100644 --- a/base/gxcoord.h +++ b/base/gxcoord.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcpath.c b/base/gxcpath.c index c9fde9d4..4cec26c7 100644 --- a/base/gxcpath.c +++ b/base/gxcpath.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcpath.h b/base/gxcpath.h index 9d1fdace..4633c945 100644 --- a/base/gxcpath.h +++ b/base/gxcpath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcspace.h b/base/gxcspace.h index 3218019c..40fbee16 100644 --- a/base/gxcspace.h +++ b/base/gxcspace.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -165,16 +165,30 @@ struct gs_color_space_type_s { #define cs_proc_adjust_color_count(proc)\ void proc(const gs_client_color *, const gs_color_space *, int) + + /* Adjust the color reference counts for the current space. */ #define cs_adjust_color_count(pgs, delta)\ (*gs_currentcolorspace_inline(pgs)->type->adjust_color_count)\ (gs_currentcolor_inline(pgs), gs_currentcolorspace_inline(pgs), delta) + /* Adjust the color reference counts for the swapped space (i.e. + * the one that is not current). */ +#define cs_adjust_swappedcolor_count(pgs, delta)\ + (*gs_swappedcolorspace_inline(pgs)->type->adjust_color_count)\ + (gs_swappedcolor_inline(pgs), gs_swappedcolorspace_inline(pgs), delta) + cs_proc_adjust_color_count((*adjust_color_count)); -/* Adjust both reference counts. */ +/* Adjust both reference counts for the current color/colorspace. */ #define cs_adjust_counts(pgs, delta)\ cs_adjust_color_count(pgs, delta); \ rc_adjust_const(gs_currentcolorspace_inline(pgs), delta, "cs_adjust_counts") +/* Adjust both reference counts for the swapped (i.e. non-current) + * color/colorspace. */ +#define cs_adjust_swappedcounts(pgs, delta)\ + cs_adjust_swappedcolor_count(pgs, delta); \ + rc_adjust_const(gs_swappedcolorspace_inline(pgs), delta, "cs_adjust_swappedcounts") + /* Serialization. */ /* * Note : We don't include *(pcs)->type into serialization, diff --git a/base/gxctable.c b/base/gxctable.c index 4662d090..349fbb71 100644 --- a/base/gxctable.c +++ b/base/gxctable.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxctable.h b/base/gxctable.h index a2fc8cad..392c5033 100644 --- a/base/gxctable.h +++ b/base/gxctable.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxcvalue.h b/base/gxcvalue.h index 92efa325..5d265262 100644 --- a/base/gxcvalue.h +++ b/base/gxcvalue.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdcconv.c b/base/gxdcconv.c index c492ec0b..67a027b0 100644 --- a/base/gxdcconv.c +++ b/base/gxdcconv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdcconv.h b/base/gxdcconv.h index 68803375..16f3b59f 100644 --- a/base/gxdcconv.h +++ b/base/gxdcconv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdcolor.c b/base/gxdcolor.c index b4178871..20116fd8 100644 --- a/base/gxdcolor.c +++ b/base/gxdcolor.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -540,7 +540,11 @@ gx_dc_devn_equal(const gx_device_color * pdevc1, const gx_device_color * pdevc2) /* * Utility to write a devn color into the clist. We should only be here * if the device can handle these colors (e.g. a separation device like - * tiffsep). TODO: Reduce the size of this by removing leading zeros in + * tiffsep). We can also be here if we are doing simulated overprint + * and the source document has spot colors in which case pdf14cmykspot + * device has been pushed and will handle devn colors. Because the target + * could be bitrgbtags we need to send the tag information along. + * TODO: Reduce the size of this by removing leading zeros in * the mask. * */ @@ -569,8 +573,8 @@ gx_devn_write_color( mask = comp_bits; num_bytes1 = sizeof(gx_color_index); - num_bytes = num_bytes1 + count * 2; - num_bytes_temp = num_bytes1; + num_bytes = num_bytes1 + count * 2 + 1; /* One for the tag byte */ + num_bytes_temp = num_bytes1 + 1; /* check for adequate space */ if (*psize < num_bytes) { @@ -578,12 +582,20 @@ gx_devn_write_color( return_error(gs_error_rangecheck); } *psize = num_bytes; + /* write out the mask */ mask_temp = mask; while (--num_bytes1 >= 0) { pdata[num_bytes1] = mask_temp & 0xff; mask_temp >>= 8; } + + /* Now the tag */ + if (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) + pdata[num_bytes_temp - 1] = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + else + pdata[num_bytes_temp - 1] = GS_UNTOUCHED_TAG; + /* Now the data */ for (i = 0; i < ncomps; i++) { if (mask & 1) { @@ -668,6 +680,7 @@ gx_dc_devn_write( static int gx_devn_read_color( ushort values[], + gs_graphics_type_tag_t * tag, const gx_device * dev, const byte * pdata, int size ) @@ -687,6 +700,12 @@ gx_devn_read_color( mask = (mask << 8) | pdata[i]; pos = i; num_bytes = i; + + /* Now the tag */ + *tag = pdata[pos]; + pos++; + num_bytes++; + /* Now the data */ for (i = 0; i < ncomps; i++) { if (mask & 1) { @@ -738,13 +757,14 @@ gx_dc_devn_read( const gs_gstate * pgs, /* ignored */ const gx_device_color * prior_devc, /* ignored */ const gx_device * dev, - int64_t offset, /* ignored */ + int64_t offset, /* ignored */ const byte * pdata, uint size, gs_memory_t * mem ) /* ignored */ { pdevc->type = gx_dc_type_devn; - return gx_devn_read_color(&(pdevc->colors.devn.values[0]), dev, pdata, size); + return gx_devn_read_color(&(pdevc->colors.devn.values[0]), &(pdevc->tag), + dev, pdata, size); } /* Remember these are 16 bit values. Also here we return the number of @@ -853,7 +873,7 @@ gx_dc_pure_fill_masked(const gx_device_color * pdevc, const byte * data, if (!rop3_uses_S(lop)) lop |= rop3_S; - + return (*dev_proc(dev, strip_copy_rop)) (dev, data, data_x, raster, id, scolors, NULL, tcolors, x, y, w, h, 0, 0, diff --git a/base/gxdcolor.h b/base/gxdcolor.h index 9e979b32..8a1f4135 100644 --- a/base/gxdcolor.h +++ b/base/gxdcolor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -302,10 +302,10 @@ int gx_remap_color(gs_gstate *); #define gx_unset_dev_color(pgs)\ color_unset(gs_currentdevicecolor_inline(pgs)) #define gx_unset_alt_dev_color(pgs)\ - color_unset(gs_altdevicecolor_inline(pgs)) + color_unset(gs_swappeddevicecolor_inline(pgs)) #define gx_unset_both_dev_colors(pgs)\ (color_unset(gs_currentdevicecolor_inline(pgs)),\ - color_unset(gs_altdevicecolor_inline(pgs))) + color_unset(gs_swappeddevicecolor_inline(pgs))) /* Load the halftone cache in preparation for drawing. */ #define gx_color_load_select(pdevc, pgs, dev, select)\ diff --git a/base/gxdda.h b/base/gxdda.h index ab577342..6c7c4e7a 100644 --- a/base/gxdda.h +++ b/base/gxdda.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdevbuf.h b/base/gxdevbuf.h index 8f5fd0a7..969454c3 100644 --- a/base/gxdevbuf.h +++ b/base/gxdevbuf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdevcli.h b/base/gxdevcli.h index 0bdf3c02..f41f8d11 100644 --- a/base/gxdevcli.h +++ b/base/gxdevcli.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -706,6 +706,11 @@ typedef struct gdev_space_params_s { int gdev_space_params_cmp(const gdev_space_params sp1, const gdev_space_params sp2); +typedef struct gdev_nupcontrol_s { + rc_header rc; + char *nupcontrol_str; /* NUL termintated string */ +} gdev_nupcontrol; + typedef struct gdev_pagelist_s { rc_header rc; char *Pages; @@ -759,6 +764,8 @@ typedef struct gdev_pagelist_s { bool DisablePageHandler; /* Can be set by the interpreter if it will process FirstPage and LastPage itself */\ int ObjectFilter; /* Bit field for which object filters to apply */\ bool ObjectHandlerPushed; /* Handles filtering of objects to devices */\ + gdev_nupcontrol *NupControl;\ + bool NupHandlerPushed; /* Handles Nup operations */\ long PageCount; /* number of pages written */\ long ShowpageCount; /* number of calls on showpage */\ int NumCopies;\ @@ -772,6 +779,7 @@ typedef struct gdev_pagelist_s { gx_stroked_gradient_recognizer_t sgr;\ size_t MaxPatternBitmap; /* Threshold for switching to pattern_clist mode */\ bool page_uses_transparency; /* PDF 1.4 transparency is used. */\ + bool page_uses_overprint; /* overprint is used. */\ gdev_space_params space_params;\ cmm_dev_profile_t *icc_struct; /* object dependent profiles */\ gs_graphics_type_tag_t graphics_type_tag; /* e.g. vector, image or text */\ @@ -1681,11 +1689,6 @@ typedef struct gx_image_plane_s { ((*dev_proc(dev, begin_typed_image))\ (dev, pgs, pmat, pim, prect, pdcolor, pcpath, memory, pinfo)) -/* - * The driver-like procedures gx_device_{image_data, image_plane_data, - * end_image} are now DEPRECATED and will eventually be removed. - * Their replacements no longer take an ignored dev argument. - */ int gx_image_data(gx_image_enum_common_t *info, const byte **planes, int data_x, uint raster, int height); /* @@ -1701,13 +1704,6 @@ int gx_image_flush(gx_image_enum_common_t *info); bool gx_image_planes_wanted(const gx_image_enum_common_t *info, byte *wanted); int gx_image_end(gx_image_enum_common_t *info, bool draw_last); -#define gx_device_image_data(dev, info, planes, data_x, raster, height)\ - gx_image_data(info, planes, data_x, raster, height) -#define gx_device_image_plane_data(dev, info, planes, height)\ - gx_image_plane_data(info, planes, height) -#define gx_device_end_image(dev, info, draw_last)\ - gx_image_end(info, draw_last) - /* * Get the anti-aliasing parameters for a device. This replaces the * obsolete get_alpha_bits device procedure. diff --git a/base/gxdevice.h b/base/gxdevice.h index e53f0b90..c757fa2d 100644 --- a/base/gxdevice.h +++ b/base/gxdevice.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -101,7 +101,7 @@ #define std_device_part1_(devtype, ptr_procs, dev_name, stype, open_init)\ sizeof(devtype), ptr_procs, dev_name,\ 0 /*memory*/, stype, 0 /*stype_is_dynamic*/, 0 /*finalize*/,\ - { 0 } /*rc*/, 0 /*retained*/, 0 /* parent */, 0 /* child */, 0 /* subclass_data */, 0, /* PageList */\ + { 0 } /*rc*/, 0 /*retained*/, 0 /* parent */, 0 /* child */, 0 /* subclass_data */, 0 /* PageList */,\ open_init() /*is_open, max_fill_band*/ /* color_info goes here */ /* @@ -119,12 +119,14 @@ /* offsets and margins go here */ #define std_device_part3_()\ - 0/*FirstPage*/, 0/*LastPage*/, 0/*PageHandlerPushed*/, 0/*DisablePageHandler*/, 0/* Object Filter*/, 0/*ObjectHandlerPushed*/,\ + 0/*FirstPage*/, 0/*LastPage*/, 0/*PageHandlerPushed*/, 0/*DisablePageHandler*/,\ + 0/* Object Filter*/, 0/*ObjectHandlerPushed*/,\ + 0, /* NupControl */ 0, /* NupHandlerPushed */\ 0/*PageCount*/, 0/*ShowpageCount*/, 1/*NumCopies*/, 0/*NumCopies_set*/,\ 0/*IgnoreNumCopies*/, 0/*UseCIEColor*/, 0/*LockSafetyParams*/,\ 0/*band_offset_x*/, 0/*band_offset_y*/, false /*BLS_force_memory*/, \ {false}/* sgr */,\ - 0/* MaxPatternBitmap */, 0/*page_uses_transparency*/,\ + 0/* MaxPatternBitmap */, 0/*page_uses_transparency*/, 0/*page_uses_overprint*/,\ { MAX_BITMAP, BUFFER_SPACE,\ { BAND_PARAMS_INITIAL_VALUES },\ 0/*false*/, /* params_are_read_only */\ diff --git a/base/gxdevmem.h b/base/gxdevmem.h index a5e2c6db..bb890a27 100644 --- a/base/gxdevmem.h +++ b/base/gxdevmem.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdevndi.c b/base/gxdevndi.c index 407226d0..29c6f3ea 100644 --- a/base/gxdevndi.c +++ b/base/gxdevndi.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdevrop.h b/base/gxdevrop.h index 93049fa1..10e502a1 100644 --- a/base/gxdevrop.h +++ b/base/gxdevrop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdevsop.h b/base/gxdevsop.h index f41a780a..a5af0f41 100644 --- a/base/gxdevsop.h +++ b/base/gxdevsop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -29,7 +29,7 @@ * ioctl is to unix file handles. * * Design features of this scheme ensure that: - * * Devices that support a given call call efficiently implement both + * * Devices that support a given call can efficiently implement both * input and output. * * Devices that do not support a given call can efficiently refuse it * (without having to know all the possible calls). @@ -366,7 +366,13 @@ enum { * 0 otherwise. */ gxdso_in_smask, - + /* gxdso_in_smask_construction: + * data = NULL + * size = 0 + * Returns 1 if we are within an smask construction, + * 0 otherwise. + */ + gxdso_in_smask_construction, /* Debug only dsos follow here */ #ifdef DEBUG /* Private dso used to check that a printer device properly forwards to the default */ @@ -395,6 +401,35 @@ enum { * for example). */ gxdso_skip_icc_component_validation, + + /* gxdso_copy_alpha_disabled: + * data = NULL + * size = 0 + * Returns 1 if the command list device sets clist_disable_copy_alpha flag, + * 0 otherwise. + */ + gxdso_copy_alpha_disabled, + + /* gxdso_set_HWSize: + * data = int[2], [0] is width [1] is height + * size = sizeof(int[2]) + * Returns 1 if the device controls dev->width, dev->height + * 0 otherwise. + * NB: caller should set dev->wdith and dev->height if return is <= 0 + */ + gxdso_set_HWSize, + + /* gxdso_device_insert_child: + * data = pointer to device to insert as child of the device + * handling this special op. + * size = 0 + * Returns 0 if completed successfully, negative otherwise. + */ + gxdso_device_insert_child, + + /* Determine if a given device is a clist one. Returns 1 if it is. */ + gxdso_is_clist_device, + /* Add new gxdso_ keys above this. */ gxdso_pattern__LAST }; diff --git a/base/gxdht.h b/base/gxdht.h index 8bb51c2c..d365606e 100644 --- a/base/gxdht.h +++ b/base/gxdht.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -188,11 +188,14 @@ typedef struct gx_ht_order_procs_s { } gx_ht_order_procs_t; /* * Define the procedure vectors for the supported implementations - * (in gxhtbit.c). + * (in gxhtbit.c). This defines the type of data that the turn-on-sequence (TOS) + * elements are pointing too. For the ushort and uint case, they are offsets + * into the address of the bitmap tiles. */ -extern const gx_ht_order_procs_t ht_order_procs_table[2]; +extern const gx_ht_order_procs_t ht_order_procs_table[3]; #define ht_order_procs_default ht_order_procs_table[0] /* bit_data is gx_ht_bit[] */ #define ht_order_procs_short ht_order_procs_table[1] /* bit_data is ushort[] */ +#define ht_order_procs_uint ht_order_procs_table[2] /* bit_data is uint[] */ /* For screen/spot halftones, we must record additional parameters. */ typedef struct gx_ht_order_screen_params_s { gs_matrix matrix; /* CTM when the function was sampled */ diff --git a/base/gxdhtres.h b/base/gxdhtres.h index 97734514..20a03dd4 100644 --- a/base/gxdhtres.h +++ b/base/gxdhtres.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdhtserial.c b/base/gxdhtserial.c index 63cab5a3..6f8bb18f 100644 --- a/base/gxdhtserial.c +++ b/base/gxdhtserial.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdhtserial.h b/base/gxdhtserial.h index 987fb1ec..ceb19051 100644 --- a/base/gxdhtserial.h +++ b/base/gxdhtserial.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdither.h b/base/gxdither.h index e6e27cd1..8484a3ea 100644 --- a/base/gxdither.h +++ b/base/gxdither.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdownscale.c b/base/gxdownscale.c index 1a348da5..fd51a695 100644 --- a/base/gxdownscale.c +++ b/base/gxdownscale.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdownscale.h b/base/gxdownscale.h index c9db668e..ed945b46 100644 --- a/base/gxdownscale.h +++ b/base/gxdownscale.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxdtfill.h b/base/gxdtfill.h index 7ee73003..ca6d028e 100644 --- a/base/gxdtfill.h +++ b/base/gxdtfill.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfapi.c b/base/gxfapi.c index e6bc445d..6b97d708 100644 --- a/base/gxfapi.c +++ b/base/gxfapi.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -285,7 +285,7 @@ recreate_multiple_master(gs_font_base *pbfont) changed = (memcmp(I->face.WeightVector.values, pfont1->data.WeightVector.values, pfont1->data.WeightVector.count * sizeof(pfont1->data.WeightVector.values[0])) != 0); } - + if (changed) { r = (I->set_mm_weight_vector(I, &I->ff, pfont1->data.WeightVector.values, pfont1->data.WeightVector.count) == gs_error_invalidaccess); I->face.WeightVector.count = pfont1->data.WeightVector.count; @@ -565,8 +565,8 @@ outline_char(gs_memory_t *mem, gs_fapi_server *I, int import_shift_v, gs_gstate *pgs = penum_s->pgs; olh.path = path; - olh.x0 = pgs->ctm.tx_fixed; - olh.y0 = pgs->ctm.ty_fixed; + olh.x0 = pgs->ctm.tx_fixed - float2fixed(penum_s->fapi_glyph_shift.x); + olh.y0 = pgs->ctm.ty_fixed - float2fixed(penum_s->fapi_glyph_shift.y); olh.close_path = close_path; olh.need_close = false; path_interface.olh = &olh; @@ -849,7 +849,7 @@ fapi_image_uncached_glyph(gs_font *pfont, gs_gstate *pgs, gs_show_enum *penum, code = gs_gstate_color_load(pgs); if (code < 0) return code; - + code = gx_image_fill_masked(dev, r, 0, dstr, gx_no_bitmap_id, (int)dx, (int)dy, rast->width, rast->height, @@ -872,7 +872,7 @@ fapi_image_uncached_glyph(gs_font *pfont, gs_gstate *pgs, gs_show_enum *penum, byte *bold_lines = NULL; byte *line = NULL; int ascent = 0; - + pie = gs_image_enum_alloc(mem, "image_char(image_enum)"); if (!pie) { return_error(gs_error_VMerror); @@ -943,7 +943,7 @@ fapi_image_uncached_glyph(gs_font *pfont, gs_gstate *pgs, gs_show_enum *penum, bits_merge(merged_line(y - kmask), merged_line(y - (kmask >> 1)), dest_bytes); } - } + } /* * As of this point in the loop, we maintain the following @@ -1695,7 +1695,7 @@ gs_fapi_do_char(gs_font *pfont, gs_gstate *pgs, gs_text_enum_t *penum, char *fon I->ff.fapi_set_cache(penum, pbfont, &enc_char_name_string, index, sbw + 2, &char_bbox, sbwp, &imagenow); } - + /* If we can render the glyph now, do so. * we may not be able to in the PS world if there's a CDevProc in the font * in which case gs_fapi_finish_render() will be called from the PS @@ -1746,12 +1746,12 @@ gs_fapi_passfont(gs_font *pfont, int subfont, char *font_file_path, int code = 0; gs_fapi_server *I, **list; bool free_params = false; - gs_memory_t *mem = pfont->memory; + gs_memory_t *mem = pfont->memory; const char *decodingID = NULL; bool do_restart = false; - + list = gs_fapi_get_server_list(mem); - + if (!list) /* Should never happen */ return_error(gs_error_unregistered); diff --git a/base/gxfapi.h b/base/gxfapi.h index a1a747b6..728630e6 100644 --- a/base/gxfapi.h +++ b/base/gxfapi.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -334,9 +334,9 @@ struct gs_fapi_server_s /* Used to use the stored 'OrigFont' entry but */ /* this did not change f a font was defined */ /* using an existing base font */ - - - + + + gs_fapi_retcode(*ensure_open) (gs_fapi_server *server, const char *param, int param_size); gs_fapi_retcode(*get_scaled_font) (gs_fapi_server *server, gs_fapi_font *ff, const gs_fapi_font_scale *scale, const char *xlatmap, gs_fapi_descendant_code dc); gs_fapi_retcode(*get_decodingID) (gs_fapi_server *server, gs_fapi_font *ff, const char **decodingID); @@ -352,7 +352,7 @@ struct gs_fapi_server_s gs_fapi_retcode(*get_char_outline_metrics) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, gs_fapi_metrics *metrics); gs_fapi_retcode(*get_char_outline) (gs_fapi_server *server, gs_fapi_path *p); gs_fapi_retcode(*release_char_data) (gs_fapi_server *server); - + gs_fapi_retcode(*release_typeface) (gs_fapi_server *server, void *server_font_data); gs_fapi_retcode(*check_cmap_for_GID) (gs_fapi_server *server, uint *index); gs_fapi_retcode(*get_font_info) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_font_info item, int index, void *data, int *datalen); @@ -442,7 +442,7 @@ gs_fapi_do_char(gs_font *pfont, gs_gstate *pgs, gs_text_enum_t *penum, char *fon * to hold the requested information - data == NULL, or data_len too * small will see data_len set to the required amount, and an error * returned. - */ + */ int gs_fapi_get_font_info(gs_font *pfont, gs_fapi_font_info item, int index, void *data, int *data_len); diff --git a/base/gxfapiu.c b/base/gxfapiu.c index 125b47f5..5268c6c2 100644 --- a/base/gxfapiu.c +++ b/base/gxfapiu.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfapiu.h b/base/gxfapiu.h index 16117c29..69fd33bd 100644 --- a/base/gxfapiu.h +++ b/base/gxfapiu.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfarith.h b/base/gxfarith.h index 7a3aefc3..e712b914 100644 --- a/base/gxfarith.h +++ b/base/gxfarith.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfcache.h b/base/gxfcache.h index b265f2f3..4001cd7f 100644 --- a/base/gxfcache.h +++ b/base/gxfcache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -261,7 +261,7 @@ struct gs_font_dir_s { /* User parameter GridFitTT. */ uint grid_fit_tt; gx_device_spot_analyzer *san; - int (*global_glyph_code)(const gs_memory_t *mem, gs_const_string *gstr, gs_glyph *pglyph); + int (*global_glyph_code)(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph); ulong text_enum_id; /* debug purpose only. */ }; diff --git a/base/gxfcid.h b/base/gxfcid.h index 5b42e3dc..bc95b3a0 100644 --- a/base/gxfcid.h +++ b/base/gxfcid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfcmap.h b/base/gxfcmap.h index 29c2b7a7..f7b815e9 100644 --- a/base/gxfcmap.h +++ b/base/gxfcmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfcmap1.h b/base/gxfcmap1.h index 496a97c3..a0f6d562 100644 --- a/base/gxfcmap1.h +++ b/base/gxfcmap1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfill.c b/base/gxfill.c index bde98416..921c2baf 100644 --- a/base/gxfill.c +++ b/base/gxfill.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfill.h b/base/gxfill.h index 4ca95cd3..c4616a09 100644 --- a/base/gxfill.h +++ b/base/gxfill.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfillsl.h b/base/gxfillsl.h index c479d01b..5d7de3ec 100644 --- a/base/gxfillsl.h +++ b/base/gxfillsl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfilltr.h b/base/gxfilltr.h index 0ac779bf..e44176d1 100644 --- a/base/gxfilltr.h +++ b/base/gxfilltr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfillts.h b/base/gxfillts.h index e693415b..0104e6ea 100644 --- a/base/gxfillts.h +++ b/base/gxfillts.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfixed.h b/base/gxfixed.h index 2049df03..d97f089b 100644 --- a/base/gxfixed.h +++ b/base/gxfixed.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfmap.h b/base/gxfmap.h index 32d21955..d877ad5e 100644 --- a/base/gxfmap.h +++ b/base/gxfmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfont.h b/base/gxfont.h index c277e0c1..c7a896eb 100644 --- a/base/gxfont.h +++ b/base/gxfont.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfont0.h b/base/gxfont0.h index bd72fbd1..892554d1 100644 --- a/base/gxfont0.h +++ b/base/gxfont0.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfont0c.h b/base/gxfont0c.h index f436e6b4..f8a4879d 100644 --- a/base/gxfont0c.h +++ b/base/gxfont0c.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfont1.h b/base/gxfont1.h index 51a4ecf1..f22429a0 100644 --- a/base/gxfont1.h +++ b/base/gxfont1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfont42.h b/base/gxfont42.h index 5cacf809..26377784 100644 --- a/base/gxfont42.h +++ b/base/gxfont42.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfrac.h b/base/gxfrac.h index 4af9cecc..6bbdcf75 100644 --- a/base/gxfrac.h +++ b/base/gxfrac.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxftype.h b/base/gxftype.h index 10d73275..55f618f0 100644 --- a/base/gxftype.h +++ b/base/gxftype.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxfunc.h b/base/gxfunc.h index eea2e8d9..fb715f56 100644 --- a/base/gxfunc.h +++ b/base/gxfunc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxgetbit.h b/base/gxgetbit.h index 54b13d1a..ea3e1afa 100644 --- a/base/gxgetbit.h +++ b/base/gxgetbit.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxgstate.h b/base/gxgstate.h index 2ab96a3f..a6309d89 100644 --- a/base/gxgstate.h +++ b/base/gxgstate.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -42,6 +42,7 @@ #include "gsccolor.h" #include "gsht1.h" #include "gxclipsr.h" +#include "gsicc_blacktext.h" /* @@ -201,7 +202,9 @@ typedef struct gs_xstate_trans_flags { #define gs_currentdevicecolor_inline(pgs) ((pgs)->color[0].dev_color) #define gs_currentcolor_inline(pgs) ((pgs)->color[0].ccolor) #define gs_currentcolorspace_inline(pgs) ((pgs)->color[0].color_space) -#define gs_altdevicecolor_inline(pgs) ((pgs)->color[1].dev_color) +#define gs_swappeddevicecolor_inline(pgs) ((pgs)->color[1].dev_color) +#define gs_swappedcolor_inline(pgs) ((pgs)->color[1].ccolor) +#define gs_swappedcolorspace_inline(pgs) ((pgs)->color[1].color_space) #define gs_currentcolor_eopm(pgs) ((pgs)->color[0].effective_opm) #define char_tm_only(pgs) *(gs_matrix *)&(pgs)->char_tm @@ -261,6 +264,8 @@ struct gs_gstate_s { gsicc_manager_t *icc_manager; /* ICC color manager, profile */ gsicc_link_cache_t *icc_link_cache; /* ICC linked transforms */ gsicc_profile_cache_t *icc_profile_cache; /* ICC profiles from PS. */ + gsicc_blacktext_state_t *black_text_state; /* Used to store and restore cs for black text */ + CUSTOM_COLOR_PTR /* Pointer to custom color callback struct */ const gx_color_map_procs * (*get_cmap_procs)(const gs_gstate *, const gx_device *); @@ -326,7 +331,7 @@ struct gs_gstate_s { lop_default, BLEND_MODE_Compatible,\ {0, 0}, 0, 1/*true*/, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 1.0, \ { fixed_half, fixed_half }, 0/*false*/, 1/*true*/, 0/*false*/, (float)0.02,\ - 1, 1/* bpt true */, 0, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \ + 1, 1/* bpt true */, 0, 0, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \ gx_default_get_cmap_procs #define GS_STATE_INIT_VALUES(s, scale) \ @@ -364,6 +369,7 @@ struct gs_gstate_s { s->icc_link_cache = __state_init.icc_link_cache; \ s->icc_profile_cache = __state_init.icc_profile_cache; \ s->get_cmap_procs = __state_init.get_cmap_procs; \ + s->black_text_state = NULL; \ s->show_gstate = NULL; \ s->is_fill_color = 1; \ s->strokeconstantalpha = 1.0; \ @@ -406,9 +412,10 @@ struct_proc_finalize(gs_gstate_finalize); m(16, color[1].dev_color)\ m(17, font) \ m(18, root_font) \ - m(19, show_gstate) + m(19, show_gstate) \ + m(20, black_text_state) -#define gs_gstate_num_ptrs 20 +#define gs_gstate_num_ptrs 21 /* The '+1' in the following is because gs_gstate.device * is handled specially @@ -430,7 +437,6 @@ void gs_gstate_pre_assign(gs_gstate *to, const gs_gstate *from); void gs_gstate_release(gs_gstate * pgs); int gs_currentscreenphase_pgs(const gs_gstate *, gs_int_point *, gs_color_select_t); - /* The following macro is used for development purpose for designating places where current point is changed. Clients must not use it. */ #define gx_setcurrentpoint(pgs, xx, yy)\ diff --git a/base/gxhintn.c b/base/gxhintn.c index 30847bcb..2b91c3f7 100644 --- a/base/gxhintn.c +++ b/base/gxhintn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxhintn.h b/base/gxhintn.h index 115c7582..72a1f262 100644 --- a/base/gxhintn.h +++ b/base/gxhintn.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxhintn1.c b/base/gxhintn1.c index ad579893..1c7d5074 100644 --- a/base/gxhintn1.c +++ b/base/gxhintn1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxhldevc.c b/base/gxhldevc.c index 9060590e..9188a029 100644 --- a/base/gxhldevc.c +++ b/base/gxhldevc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxhldevc.h b/base/gxhldevc.h index 60b275c0..bfe28426 100644 --- a/base/gxhldevc.h +++ b/base/gxhldevc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxht.c b/base/gxht.c index 77ea765a..aeb23362 100644 --- a/base/gxht.c +++ b/base/gxht.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxht.h b/base/gxht.h index f2b33f0d..b2743a5a 100644 --- a/base/gxht.h +++ b/base/gxht.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxht_thresh.c b/base/gxht_thresh.c index eb4d6edb..348307ec 100644 --- a/base/gxht_thresh.c +++ b/base/gxht_thresh.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxht_thresh.h b/base/gxht_thresh.h index 3ac7eab9..4c7028a7 100644 --- a/base/gxht_thresh.h +++ b/base/gxht_thresh.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxhtbit.c b/base/gxhtbit.c index 6cb6fdcb..243583e7 100644 --- a/base/gxhtbit.c +++ b/base/gxhtbit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -25,6 +25,9 @@ #include "gxtmap.h" #include "gxdht.h" #include "gxdhtres.h" +#include "gp.h" + +#define DUMP_TOS 0 extern_gx_device_halftone_list(); @@ -75,7 +78,6 @@ construct_ht_order_short(gx_ht_order *porder, const byte *thresholds) for (i = 0; i < size; i++) { uint value = max(1, thresholds[i]); - /* Adjust the bit index to account for padding. */ bits[levels[value]++] = i + (i / width * padding); } } @@ -114,10 +116,101 @@ construct_ht_order_short(gx_ht_order *porder, const byte *thresholds) } } } +#if DUMP_TOS +/* Lets look at the bit data which is the TOS level by level if I understand what the above + code is supposed to be doing */ + { + char file_name[50]; + gp_file *fid; + + snprintf(file_name, 50, "TOS_porder_%dx%d.raw", porder->width, porder->height); + fid = gp_fopen(porder->data_memory, file_name, "wb"); + if (fid) { + gp_fwrite(porder->bit_data, sizeof(unsigned short), size, fid); + gp_fclose(fid); + } + } +#endif + out: return 0; } +/* + * Construct a uint-representation order from a threshold array. + * Uses porder->width, num_levels, num_bits, levels, bit_data; + * sets porder->levels[], bit_data[]. + */ +static int +construct_ht_order_uint(gx_ht_order *porder, const byte *thresholds) +{ + uint size = porder->num_bits; + uint i; + uint *bits = (uint *)porder->bit_data; + uint *levels = porder->levels; + uint num_levels = porder->num_levels; + + memset(levels, 0, num_levels * sizeof(*levels)); + + /* Count the number of threshold elements with each value. */ + for (i = 0; i < size; i++) { + uint value = max(1, thresholds[i]); + + if (value + 1 < num_levels) + levels[value + 1]++; + } + for (i = 2; i < num_levels; ++i) + levels[i] += levels[i - 1]; + /* Now construct the actual order. */ + { + uint width = porder->width; + uint padding = bitmap_raster(width) * 8 - width; + + for (i = 0; i < size; i++) { + uint value = max(1, thresholds[i]); + + bits[levels[value]++] = i + (i / width * padding); + } + } + + /* Check whether this is a predefined halftone. */ + { + const gx_dht_proc *phtrp = gx_device_halftone_list; + + for (; *phtrp; ++phtrp) { + const gx_device_halftone_resource_t *const *pphtr = (*phtrp)(); + const gx_device_halftone_resource_t *phtr; + + while ((phtr = *pphtr++) != 0) { + if (phtr->Width == porder->width && + phtr->Height == porder->height && + phtr->elt_size == sizeof(uint) && + !memcmp(phtr->levels, levels, num_levels * sizeof(*levels)) && + !memcmp(phtr->bit_data, porder->bit_data, + (size_t)size * phtr->elt_size) + ) { + /* + * This is a predefined halftone. Free the levels and + * bit_data arrays, replacing them with the built-in ones. + */ + if (porder->data_memory) { + gs_free_object(porder->data_memory, porder->bit_data, + "construct_ht_order_uint(bit_data)"); + gs_free_object(porder->data_memory, porder->levels, + "construct_ht_order_uint(levels)"); + } + porder->data_memory = 0; + porder->levels = (uint *)phtr->levels; /* actually const */ + porder->bit_data = (void *)phtr->bit_data; /* actually const */ + goto out; + } + } + } + } +out: + return 0; +} + /* Return the bit coordinate using the standard representation. */ static int ht_bit_index_default(const gx_ht_order *porder, uint index, gs_int_point *ppt) @@ -145,6 +238,18 @@ ht_bit_index_short(const gx_ht_order *porder, uint index, gs_int_point *ppt) return 0; } +/* Return the bit coordinate using the uint representation. */ +static int +ht_bit_index_uint(const gx_ht_order *porder, uint index, gs_int_point *ppt) +{ + uint bit_index = ((const uint *)porder->bit_data)[index]; + uint bit_raster = porder->raster * 8; + + ppt->x = bit_index % bit_raster; + ppt->y = bit_index / bit_raster; + return 0; +} + /* Update a halftone tile using the default order representation. */ static int render_ht_default(gx_ht_tile *pbt, int level, const gx_ht_order *porder) @@ -264,10 +369,70 @@ render_ht_short(gx_ht_tile *pbt, int level, const gx_ht_order *porder) return 0; } +/* Update a halftone tile using the uint representation. */ +static int +render_ht_uint(gx_ht_tile *pbt, int level, const gx_ht_order *porder) +{ + int old_level = pbt->level; + register const uint *p = (const uint *)porder->bit_data + old_level; + register byte *data = pbt->tiles.data; + + /* Invert bits between the two levels. */ +#define INVERT_DATA(i)\ + BEGIN\ + uint bit_index = p[i];\ + byte *dp = &data[bit_index >> 3];\ + *dp ^= 0x80 >> (bit_index & 7);\ + END +#ifdef DEBUG +# define INVERT(i)\ + BEGIN\ + if_debug3('H', "[H]invert level=%d offset=%u mask=0x%x\n",\ + (int)(p + i - (const uint *)porder->bit_data),\ + p[i] >> 3, 0x80 >> (p[i] & 7));\ + INVERT_DATA(i);\ + END +#else +# define INVERT(i) INVERT_DATA(i) +#endif +sw:switch (level - old_level) { +default: + if (level > old_level) { + INVERT(0); INVERT(1); INVERT(2); INVERT(3); + p += 4; old_level += 4; + } + else { + INVERT(-1); INVERT(-2); INVERT(-3); INVERT(-4); + p -= 4; old_level -= 4; + } + goto sw; +case 7: INVERT(6); +case 6: INVERT(5); +case 5: INVERT(4); +case 4: INVERT(3); +case 3: INVERT(2); +case 2: INVERT(1); +case 1: INVERT(0); +case 0: break; /* Shouldn't happen! */ +case -7: INVERT(-7); +case -6: INVERT(-6); +case -5: INVERT(-5); +case -4: INVERT(-4); +case -3: INVERT(-3); +case -2: INVERT(-2); +case -1: INVERT(-1); +} +#undef INVERT_DATA +#undef INVERT +return 0; +} + /* Define the procedure vectors for the order data implementations. */ -const gx_ht_order_procs_t ht_order_procs_table[2] = { +const gx_ht_order_procs_t ht_order_procs_table[3] = { { sizeof(gx_ht_bit), construct_ht_order_default, ht_bit_index_default, render_ht_default }, { sizeof(ushort), construct_ht_order_short, ht_bit_index_short, - render_ht_short } + render_ht_short }, + { sizeof(uint), construct_ht_order_uint, ht_bit_index_uint, + render_ht_uint } }; diff --git a/base/gxhttile.h b/base/gxhttile.h index 6558784a..8c053921 100644 --- a/base/gxhttile.h +++ b/base/gxhttile.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxhttype.h b/base/gxhttype.h index d6605aeb..9a2c4f63 100644 --- a/base/gxhttype.h +++ b/base/gxhttype.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxi12bit.c b/base/gxi12bit.c index fdf56fb1..441e4a7e 100644 --- a/base/gxi12bit.c +++ b/base/gxi12bit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -666,19 +666,23 @@ image_render_icc16(gx_image_enum * penum, const byte * buffer, int data_x, (const unsigned short*) (psrc_decode+w), get_cie_range(penum->pcs)); } - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) psrc_decode, (void*) psrc_cm); gs_free_object(pgs->memory, (byte *)psrc_decode, "image_render_color_icc"); + if (code < 0) + return code; } else { /* CM only. No decode */ - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) psrc, (void*) psrc_cm); + if (code < 0) + return code; } } } diff --git a/base/gxi16bit.c b/base/gxi16bit.c index 7d2f7da3..300a2fdb 100644 --- a/base/gxi16bit.c +++ b/base/gxi16bit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxiclass.h b/base/gxiclass.h index 89721ae9..0db93784 100644 --- a/base/gxiclass.h +++ b/base/gxiclass.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxicolor.c b/base/gxicolor.c index 58ead88a..05820695 100644 --- a/base/gxicolor.c +++ b/base/gxicolor.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -566,19 +566,23 @@ image_color_icc_prep(gx_image_enum *penum_orig, const byte *psrc, uint w, decode_row_cie(penum, psrc, spp, psrc_decode, psrc_decode+w, get_cie_range(penum->pcs)); } - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) psrc_decode, (void*) *psrc_cm); gs_free_object(pgs->memory, psrc_decode, "image_color_icc_prep"); + if (code < 0) + return code; } else { /* CM only. No decode */ - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) psrc, (void*) *psrc_cm); + if (code < 0) + return code; } } } @@ -1134,6 +1138,14 @@ image_render_color_DeviceN(gx_image_enum *penum_orig, const byte *buffer, int da bits32 test = penum->mask_color.test; bool lab_case = false; + if (device_encodes_tags(dev)) { + devc1.tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + devc2.tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + } else { + devc1.tag = 0; + devc2.tag = 0; + } + if (h == 0) return 0; diff --git a/base/gxidata.c b/base/gxidata.c index 857d314d..8ce26a07 100644 --- a/base/gxidata.c +++ b/base/gxidata.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -208,7 +208,7 @@ gx_image1_plane_data(gx_image_enum_common_t * info, dmprintf1(dev->memory, "[b]image1 y=%d\n", y); if (gs_debug_c('B')) { int i, n = width_spp; - byte *buftemp = (buffer == NULL) ? penum->buffer : buffer; + byte *buftemp = (buffer == NULL) ? penum->buffer : (byte *)buffer; if (penum->bps > 8) n *= 2; @@ -521,6 +521,11 @@ gx_image1_end_image(gx_image_enum_common_t * info, bool draw_last) if (penum->clues != NULL) { gs_free_object(mem,penum->clues, "image clues"); } + + /* decrement this ref that was incremented in gx_image_enum_begin() */ + rc_decrement_only(penum->pcs, "pcs"); + penum->pcs = NULL; + gs_free_object(mem, penum->line, "image line"); gs_free_object(mem, penum->buffer, "image buffer"); diff --git a/base/gxifast.c b/base/gxifast.c index 97188230..b93c5861 100644 --- a/base/gxifast.c +++ b/base/gxifast.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -507,7 +507,11 @@ sw: if ((data = psrc[1]) != 0) { break; } end: + { +#ifdef PACIFY_VALGRIND VALGRIND_SET_VBITS(stop,&vbits,1); +#endif + } } /* Copy one rendered scan line to the device. */ diff --git a/base/gximag3x.c b/base/gximag3x.c index 1c39b487..3e6b4009 100644 --- a/base/gximag3x.c +++ b/base/gximag3x.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -144,6 +144,7 @@ gx_begin_image3x_generic(gx_device * dev, gs_int_point origin[2]; int code; int i; + gs_color_space *pmcs = NULL; /* Validate the parameters. */ if (pim->Height <= 0) @@ -207,9 +208,6 @@ gx_begin_image3x_generic(gx_device * dev, * The mask data has to be defined in a DevicePixel color space * of the correct depth so that no color mapping will occur. */ - /****** FREE COLOR SPACE ON ERROR OR AT END ******/ - gs_color_space *pmcs; - if (penum->mask[i].depth == 0) { /* mask not supplied */ midev[i] = 0; minfo[i] = 0; @@ -217,19 +215,19 @@ gx_begin_image3x_generic(gx_device * dev, } code = gs_cspace_new_DevicePixel(mem, &pmcs, penum->mask[i].depth); if (code < 0) - return code; + goto out1; mrect.p.x = mrect.p.y = 0; mrect.q.x = penum->mask[i].width; mrect.q.y = penum->mask[i].height; if ((code = gs_matrix_multiply(&mask[i].matrix, pmat, &mat)) < 0 || (code = gs_bbox_transform(&mrect, &mat, &mrect)) < 0 ) - return code; + goto out1; /* Bug 700438: If the rectangle is out of range, bail */ if (mrect.p.x >= (double)INT_MAX || mrect.q.x <= (double)INT_MIN || mrect.p.y >= (double)INT_MAX || mrect.q.y <= (double)INT_MIN) { - code = gs_note_error(gs_error_rangecheck); + code = gs_note_error(gs_error_rangecheck); goto out1; } @@ -292,6 +290,8 @@ gx_begin_image3x_generic(gx_device * dev, } midev[i] = mdev; minfo[i] = penum->mask[i].info; + rc_decrement_only(pmcs, "gx_begin_image3x_generic(pmcs)"); + pmcs = NULL; } gs_image_t_init(&pixel.image, pim->ColorSpace); { @@ -365,6 +365,7 @@ gx_begin_image3x_generic(gx_device * dev, "gx_begin_image3x(mask[0].mdev)"); } out1: + rc_decrement(pmcs, "gx_begin_image3x_generic(pmcs)"); gs_free_object(mem, penum->mask[0].data, "gx_begin_image3x(mask[0].data)"); gs_free_object(mem, penum->mask[1].data, "gx_begin_image3x(mask[1].data)"); gs_free_object(mem, penum->pixel.data, "gx_begin_image3x(pixel.data)"); diff --git a/base/gximag3x.h b/base/gximag3x.h index 989c80a9..865740d7 100644 --- a/base/gximag3x.h +++ b/base/gximag3x.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximage.c b/base/gximage.c index 74456b47..1d97ac26 100644 --- a/base/gximage.c +++ b/base/gximage.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximage.h b/base/gximage.h index ae492d29..189508f0 100644 --- a/base/gximage.h +++ b/base/gximage.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -216,7 +216,7 @@ struct gx_image_enum_s { irender_proc((*render)); int (*skip_next_line)(gx_image_enum *penum, gx_device *dev); const gs_gstate *pgs; - const gs_color_space *pcs; /* color space of image */ + gs_color_space *pcs; /* color space of image */ byte *buffer; /* for expanding samples to a */ /* byte or frac */ uint buffer_size; diff --git a/base/gximage1.c b/base/gximage1.c index a008fb54..787fb4a1 100644 --- a/base/gximage1.c +++ b/base/gximage1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximage3.c b/base/gximage3.c index 522c71ff..9fd47798 100644 --- a/base/gximage3.c +++ b/base/gximage3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -368,7 +368,10 @@ gx_begin_image3_generic(gx_device * dev, /* Bug 700438: If the rectangle is out of range, bail */ if (mrect.p.x >= (double)INT_MAX || mrect.q.x <= (double)INT_MIN || - mrect.p.y >= (double)INT_MAX || mrect.q.y <= (double)INT_MIN) { + mrect.p.y >= (double)INT_MAX || mrect.q.y <= (double)INT_MIN || + mrect.p.x <= (double)INT_MIN || mrect.q.x >= (double)INT_MAX || + mrect.p.y <= (double)INT_MIN || mrect.q.y >= (double)INT_MAX + ) { code = gs_note_error(gs_error_rangecheck); goto out1; } diff --git a/base/gximage3.h b/base/gximage3.h index dac31c3b..1c7a0e6c 100644 --- a/base/gximage3.h +++ b/base/gximage3.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximage4.c b/base/gximage4.c index 4bd9ddb2..1a3a4761 100644 --- a/base/gximage4.c +++ b/base/gximage4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximask.c b/base/gximask.c index d1c155b7..166ee4ba 100644 --- a/base/gximask.c +++ b/base/gximask.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximask.h b/base/gximask.h index 58807e64..00434e68 100644 --- a/base/gximask.h +++ b/base/gximask.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximdecode.c b/base/gximdecode.c index b41de6a0..e24c6c06 100644 --- a/base/gximdecode.c +++ b/base/gximdecode.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2020 Artifex Software, Inc. +/* Copyright (C) 2014-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -22,7 +22,7 @@ monitoring in clist and for creating TIFF files for xpswrite device */ /* We need to have the unpacking proc so that we can monitor the data for color or decode during xpswrite */ void -get_unpack_proc(gx_image_enum_common_t *pie, image_decode_t *imd, +get_unpack_proc(gx_image_enum_common_t *pie, image_decode_t *imd, gs_image_format_t format, const float *decode) { static sample_unpack_proc_t procs[2][6] = { diff --git a/base/gximdecode.h b/base/gximdecode.h index 2a21d973..d2ea23e7 100644 --- a/base/gximdecode.h +++ b/base/gximdecode.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2018 Artifex Software, Inc. +/* Copyright (C) 2014-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gximono.c b/base/gximono.c index 77fa700e..659a6ccb 100644 --- a/base/gximono.c +++ b/base/gximono.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -400,6 +400,7 @@ image_render_mono(gx_image_enum * penum, const byte * buffer, int data_x, code = (*remap_color)(&cc, pcs, pdevc, pgs, dev, gs_color_select_source);\ if (code < 0)\ goto err;\ + pdevc->tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS);\ }\ } else if (!color_is_pure(pdevc)) {\ code = gx_color_load_select(pdevc, pgs, dev, gs_color_select_source);\ diff --git a/base/gxiodev.h b/base/gxiodev.h index 704ab9ac..f33d8b61 100644 --- a/base/gxiodev.h +++ b/base/gxiodev.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxiparam.h b/base/gxiparam.h index 8d6083fb..0336ca8a 100644 --- a/base/gxiparam.h +++ b/base/gxiparam.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxipixel.c b/base/gxipixel.c index c6057577..2f367e14 100644 --- a/base/gxipixel.c +++ b/base/gxipixel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -270,7 +270,7 @@ gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs, const float *decode = pim->Decode; gs_matrix_double mat; int index_bps; - const gs_color_space *pcs = pim->ColorSpace; + gs_color_space *pcs = pim->ColorSpace; gs_logical_operation_t lop = (pgs ? pgs->log_op : lop_default); int code; int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac); @@ -630,6 +630,9 @@ gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs, penum->icolor0 = &(penum->icolor0_val); penum->icolor1 = &(penum->icolor1_val); } + penum->icolor0->tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + penum->icolor1->tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + if (masked) { /* This is imagemask. */ if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) { code = gs_error_rangecheck; @@ -806,6 +809,7 @@ gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs, image_skewed); penum->pgs = pgs; penum->pcs = pcs; + rc_increment_cs(pcs); /* Grab a ref (will decrement in gx_image1_end_image() */ penum->memory = mem; penum->buffer = buffer; penum->buffer_size = bsize; @@ -1100,11 +1104,11 @@ decode_range_needed(gx_image_enum *penum) bool scale = true; if (penum->map[0].decoding == sd_compute) { - if (!(gs_color_space_is_ICC(penum->pcs) || + if (!(gs_color_space_is_ICC(penum->pcs) || gs_color_space_is_PSCIE(penum->pcs))) { scale = false; - } - } + } + } return scale; } @@ -1133,6 +1137,7 @@ image_init_color_cache(gx_image_enum * penum, int bps, int spp) gsicc_bufferdesc_t input_buff_desc; gsicc_bufferdesc_t output_buff_desc; gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS]; + int code; if (penum->icc_link == NULL) { return gs_rethrow(-1, "ICC Link not created during image render color"); @@ -1265,10 +1270,13 @@ image_init_color_cache(gx_image_enum * penum, int bps, int spp) gsicc_init_buffer(&output_buff_desc, num_des_comp, 1, false, false, false, 0, num_entries * num_des_comp, 1, num_entries); - (penum->icc_link->procs.map_buffer)(penum->dev, penum->icc_link, - &input_buff_desc, &output_buff_desc, + code = (penum->icc_link->procs.map_buffer)(penum->dev, penum->icc_link, + &input_buff_desc, &output_buff_desc, (void*) temp_buffer, (void*) penum->color_cache->device_contone); + if (code < 0) + return gs_rethrow(code, "Failure to map color buffer"); + /* Check if we need to apply any transfer functions. If so then do it now */ if (has_transfer) { for (k = 0; k < num_entries; k++) { @@ -1439,12 +1447,12 @@ image_init_colors(gx_image_enum * penum, int bps, int spp, cc.paint.values[0] = real_decode[0]; code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor0, pgs, dev, gs_color_select_source); - if (code < 0) + if (code < 0) return code; cc.paint.values[0] = real_decode[1]; code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor1, pgs, dev, gs_color_select_source); - if (code < 0) + if (code < 0) return code; } } diff --git a/base/gxiscale.c b/base/gxiscale.c index 83427431..7cd34f9b 100644 --- a/base/gxiscale.c +++ b/base/gxiscale.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -145,10 +145,13 @@ static int mask_suitable_for_interpolation(gx_image_enum *penum) int code; int high_level_color = 1; - if (gx_device_must_halftone(penum->dev)) { + if (gx_device_must_halftone(penum->dev)) /* We don't interpolate when going to 1bpp outputs */ return -1; - } else if (gx_dc_is_pure(pdc1) && (pdc1)->colors.pure != gx_no_color_index && + if (dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_copy_alpha_disabled, NULL, 0) == 1) + /* The target device has copy_alpha() disabled. */ + return -1; + if (gx_dc_is_pure(pdc1) && (pdc1)->colors.pure != gx_no_color_index && dev_proc(penum->dev, copy_alpha) != NULL && dev_proc(penum->dev, copy_alpha) != gx_no_copy_alpha) { /* We have a 'pure' color, and a valid copy_alpha. We can work with that. */ @@ -173,6 +176,19 @@ static int mask_suitable_for_interpolation(gx_image_enum *penum) return high_level_color; } +/* + Helper function to take an int64_t, and "fixed2int_pixround_perfect" + it while testing for overflow. +*/ +static int +safe64fixed2int(int64_t v, int *overflow) +{ + if (v > (int)((1U<<(sizeof(int)*8-1))-128) || + v < 0) + *overflow = 1; + return fixed2int_pixround_perfect(v); +} + int gs_image_class_0_interpolate(gx_image_enum * penum, irender_proc_t *render_fn) { @@ -192,6 +208,7 @@ gs_image_class_0_interpolate(gx_image_enum * penum, irender_proc_t *render_fn) int interpolate_control = penum->dev->interpolate_control; int abs_interp_limit = max(1, any_abs(interpolate_control)); int limited_WidthOut, limited_HeightOut; + int overflow = 0; if (interpolate_control < 0) penum->interpolate = interp_on; /* not the same as "interp_force" -- threshold still used */ @@ -275,6 +292,7 @@ gs_image_class_0_interpolate(gx_image_enum * penum, irender_proc_t *render_fn) if(!gx_device_uses_std_cmap_procs(penum->dev, penum->pgs)) { use_icc = false; } + pol = cs_polarity(pcs); } /* * USE_CONSERVATIVE_INTERPOLATION_RULES is normally NOT defined since @@ -317,64 +335,63 @@ gs_image_class_0_interpolate(gx_image_enum * penum, irender_proc_t *render_fn) if (penum->posture == image_portrait) { fixed dw = any_abs(penum->dst_width); fixed dh = any_abs(penum->dst_height); - iss.WidthOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rect.x + penum->rect.w) * - dw / penum->Width)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rect.x * - dw / penum->Width)); - iss.HeightOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rect.y + penum->rect.h) * - dh / penum->Height)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rect.y * - dh / penum->Height)); - iss.EntireWidthOut = fixed2int_pixround(dw); - iss.EntireHeightOut = fixed2int_pixround(dh); - iss.TopMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y - penum->rect.y) * - dh / penum->Height)); - iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.h * - dh / penum->Height)) + iss.WidthOut = safe64fixed2int((int64_t)(penum->rect.x + penum->rect.w) * + dw / penum->Width, &overflow) + - safe64fixed2int((int64_t)penum->rect.x * + dw / penum->Width, &overflow); + iss.HeightOut = safe64fixed2int((int64_t)(penum->rect.y + penum->rect.h) * + dh / penum->Height, &overflow) + - safe64fixed2int((int64_t)penum->rect.y * + dh / penum->Height, &overflow); + iss.EntireWidthOut = safe64fixed2int(dw, &overflow); + iss.EntireHeightOut = safe64fixed2int(dh, &overflow); + iss.TopMarginOut = safe64fixed2int((int64_t)(penum->rrect.y - penum->rect.y) * + dh / penum->Height, &overflow); + iss.PatchHeightOut = safe64fixed2int((int64_t)penum->rrect.h * + dh / penum->Height, &overflow) - iss.TopMarginOut; - iss.PatchWidthOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x + penum->rrect.w) * - dw / penum->Width)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.x * - dw / penum->Width)); - iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x - penum->rect.x) * - dw / penum->Width)); - iss.TopMarginOut2 = fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.y * - dh / penum->Height)); - iss.PatchHeightOut2 = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y + penum->rrect.h) * - dh / penum->Height)) + iss.PatchWidthOut = safe64fixed2int((int64_t)(penum->rrect.x + penum->rrect.w) * + dw / penum->Width, &overflow) + - safe64fixed2int((int64_t)penum->rrect.x * + dw / penum->Width, &overflow); + iss.LeftMarginOut = safe64fixed2int((int64_t)(penum->rrect.x - penum->rect.x) * + dw / penum->Width, &overflow); + iss.TopMarginOut2 = safe64fixed2int((int64_t)penum->rrect.y * + dh / penum->Height, &overflow); + iss.PatchHeightOut2 = safe64fixed2int((int64_t)(penum->rrect.y + penum->rrect.h) * + dh / penum->Height, &overflow) - iss.TopMarginOut2; iss.pad_y = iss.TopMarginOut2 - - fixed2int_pixround_perfect( - (fixed)((int64_t)penum->rect.y * - dh / penum->Height)); + - safe64fixed2int((int64_t)penum->rect.y * + dh / penum->Height, &overflow); } else { fixed dw = any_abs(penum->dst_width); fixed dh = any_abs(penum->dst_height); - iss.WidthOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rect.x + penum->rect.w) * - dh / penum->Width)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rect.x * - dh / penum->Width)); - iss.HeightOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rect.y + penum->rect.h) * - dw / penum->Height)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rect.y * - dw / penum->Height)); - iss.EntireWidthOut = fixed2int_pixround(dh); - iss.EntireHeightOut = fixed2int_pixround(dw); - iss.TopMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y - penum->rect.y) * - dw / penum->Height)); - iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.h * - dw / penum->Height)) + iss.WidthOut = safe64fixed2int((int64_t)(penum->rect.x + penum->rect.w) * + dh / penum->Width, &overflow) + - safe64fixed2int((int64_t)penum->rect.x * + dh / penum->Width, &overflow); + iss.HeightOut = safe64fixed2int((int64_t)(penum->rect.y + penum->rect.h) * + dw / penum->Height, &overflow) + - safe64fixed2int((int64_t)penum->rect.y * + dw / penum->Height, &overflow); + iss.EntireWidthOut = safe64fixed2int(dh, &overflow); + iss.EntireHeightOut = safe64fixed2int(dw, &overflow); + iss.TopMarginOut = safe64fixed2int((int64_t)(penum->rrect.y - penum->rect.y) * + dw / penum->Height, &overflow); + iss.PatchHeightOut = safe64fixed2int((int64_t)penum->rrect.h * + dw / penum->Height, &overflow) - iss.TopMarginOut; - iss.PatchWidthOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x + penum->rrect.w) * - dh / penum->Width)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.x * - dh / penum->Width)); - iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x - penum->rect.x) * - dh / penum->Width)); - iss.TopMarginOut2 = fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.y * - dw / penum->Height)); - iss.PatchHeightOut2 = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y + penum->rrect.h) * - dw / penum->Height)) + iss.PatchWidthOut = safe64fixed2int((int64_t)(penum->rrect.x + penum->rrect.w) * + dh / penum->Width, &overflow) + - safe64fixed2int((int64_t)penum->rrect.x * + dh / penum->Width, &overflow); + iss.LeftMarginOut = safe64fixed2int((int64_t)(penum->rrect.x - penum->rect.x) * + dh / penum->Width, &overflow); + iss.TopMarginOut2 = safe64fixed2int((int64_t)penum->rrect.y * + dw / penum->Height, &overflow); + iss.PatchHeightOut2 = safe64fixed2int((int64_t)(penum->rrect.y + penum->rrect.h) * + dw / penum->Height, &overflow) - iss.TopMarginOut2; iss.pad_y = 0; } @@ -399,7 +416,7 @@ gs_image_class_0_interpolate(gx_image_enum * penum, irender_proc_t *render_fn) iss.LeftMarginOut = iss.WidthOut - iss.LeftMarginOut - iss.PatchWidthOut; /* For interpolator cores that don't set Active, have us always active */ iss.Active = 1; - if (iss.EntireWidthOut == 0 || iss.EntireHeightOut == 0) + if (iss.EntireWidthOut == 0 || iss.EntireHeightOut == 0 || overflow) { penum->interpolate = interp_off; return 0; @@ -2171,9 +2188,12 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer, 1, width_in); /* Do the transformation */ psrc = (byte*) (stream_r.ptr + 1); - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) psrc, (void*) p_cm_buff); + if (code < 0) + return code; + /* Re-set the reading stream to use the cm data */ stream_r.ptr = p_cm_buff - 1; stream_r.limit = stream_r.ptr + num_bytes_decode * width_in * spp_cm; @@ -2232,11 +2252,13 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer, pinterp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_decode; p_cm_interp = (unsigned short *) p_cm_buff; p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm; - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) pinterp, (void*) p_cm_interp); + if (code < 0) + return code; } code = irii_core(penum, xo, xe, spp_cm, p_cm_interp, dev, abs_interp_limit, bpp, raster, yo, dy, lop); if (code < 0) @@ -2660,9 +2682,12 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum, 1, width_in); /* Do the transformation */ psrc = (byte*) (stream_r.ptr + 1); - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) psrc, (void*) p_cm_buff); + if (code < 0) + return code; + /* Re-set the reading stream to use the cm data */ stream_r.ptr = p_cm_buff - 1; stream_r.limit = stream_r.ptr + num_bytes_decode * width_in * spp_cm; @@ -2728,18 +2753,20 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum, if (penum->icc_link->is_identity || pss->params.early_cm) { /* Fastest case. No CM needed */ p_cm_interp = (unsigned short *) pinterp; + p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm; } else { /* Transform */ pinterp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_decode; p_cm_interp = (unsigned short *) p_cm_buff; p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm; - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + code = (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) pinterp, (void*) p_cm_interp); + if (code < 0) + return code; } - p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm; for (x = xo; x < xe;) { #ifdef DEBUG if (gs_debug_c('B')) { diff --git a/base/gxline.h b/base/gxline.h index 1571e585..c7d90ef4 100644 --- a/base/gxline.h +++ b/base/gxline.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxlum.h b/base/gxlum.h index 38f3940d..4d809d49 100644 --- a/base/gxlum.h +++ b/base/gxlum.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxmatrix.h b/base/gxmatrix.h index 3a987694..3e18542e 100644 --- a/base/gxmatrix.h +++ b/base/gxmatrix.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxmclip.c b/base/gxmclip.c index 7e991416..b2b59e35 100644 --- a/base/gxmclip.c +++ b/base/gxmclip.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxmclip.h b/base/gxmclip.h index 926a72e3..8e690fc3 100644 --- a/base/gxmclip.h +++ b/base/gxmclip.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxobj.h b/base/gxobj.h index 376bab4f..927e1cdc 100644 --- a/base/gxobj.h +++ b/base/gxobj.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxoprect.c b/base/gxoprect.c index b04d9032..9b409e8c 100644 --- a/base/gxoprect.c +++ b/base/gxoprect.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxoprect.h b/base/gxoprect.h index 6a8d77df..a9f12d81 100644 --- a/base/gxoprect.h +++ b/base/gxoprect.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxp1fill.c b/base/gxp1fill.c index 80180972..dab8c333 100644 --- a/base/gxp1fill.c +++ b/base/gxp1fill.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxp1impl.h b/base/gxp1impl.h index 303319b4..0affb7c0 100644 --- a/base/gxp1impl.h +++ b/base/gxp1impl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxpaint.c b/base/gxpaint.c index f570334e..2e4955c1 100644 --- a/base/gxpaint.c +++ b/base/gxpaint.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -67,9 +67,16 @@ gx_stroke_fill(gx_path * ppath, gs_gstate * pgs) return code; params.flatness = (caching_an_outline_font(pgs) ? 0.0 : pgs->flatness); params.traditional = false; - return (*dev_proc(dev, stroke_path)) + + code = (*dev_proc(dev, stroke_path)) (dev, (const gs_gstate *)pgs, ppath, ¶ms, gs_currentdevicecolor_inline(pgs), pcpath); + + if (pgs->black_text_state) { + gsicc_restore_black_text(pgs); + } + + return code; } int @@ -89,11 +96,18 @@ gx_fill_stroke_path(gs_gstate * pgs, int rule) fill_params.flatness = (caching_an_outline_font(pgs) ? 0.0 : pgs->flatness); stroke_params.flatness = (caching_an_outline_font(pgs) ? 0.0 : pgs->flatness); stroke_params.traditional = false; - return (*dev_proc(dev, fill_stroke_path)) + + code = (*dev_proc(dev, fill_stroke_path)) (dev, (const gs_gstate *)pgs, pgs->path, &fill_params, gs_currentdevicecolor_inline(pgs), - &stroke_params, gs_altdevicecolor_inline(pgs), + &stroke_params, gs_swappeddevicecolor_inline(pgs), pcpath); + + if (pgs->black_text_state) { + gsicc_restore_black_text(pgs); + } + + return code; } int diff --git a/base/gxpaint.h b/base/gxpaint.h index 2dee3a66..f71440a4 100644 --- a/base/gxpaint.h +++ b/base/gxpaint.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxpath.c b/base/gxpath.c index ffdea761..5bbcf5d0 100644 --- a/base/gxpath.c +++ b/base/gxpath.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxpath.h b/base/gxpath.h index 01a04240..90d62bed 100644 --- a/base/gxpath.h +++ b/base/gxpath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -44,10 +44,10 @@ typedef enum { sn_dash_tail = 8, /* segment is followed by dash break */ } segment_notes; -/* - * Used by interpreters for optimizing bbox size for transparency groups. - * Depending upon the option we will return a bbox that may just included the - * clip path or may include the intersection of the current path and the clip +/* + * Used by interpreters for optimizing bbox size for transparency groups. + * Depending upon the option we will return a bbox that may just included the + * clip path or may include the intersection of the current path and the clip * path and may include an adjustement for the stroke width. */ typedef enum { @@ -311,7 +311,7 @@ int gx_default_clip_box(const gs_gstate *, gs_fixed_rect *); int gx_effective_clip_path(gs_gstate *, gx_clip_path **); int gx_curr_fixed_bbox(gs_gstate * pgs, gs_fixed_rect *bbox, gs_bbox_comp_t comp_type); int gx_curr_bbox(gs_gstate * pgs, gs_rect *bbox, gs_bbox_comp_t comp_type); - + /* Opaque type for a clip list. */ typedef struct gx_clip_list_s gx_clip_list; diff --git a/base/gxpath2.c b/base/gxpath2.c index d1bbe236..0f856f5a 100644 --- a/base/gxpath2.c +++ b/base/gxpath2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxpcache.h b/base/gxpcache.h index 8b37771e..33048664 100644 --- a/base/gxpcache.h +++ b/base/gxpcache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxpcmap.c b/base/gxpcmap.c index 356ec0f9..e6ec7b9a 100644 --- a/base/gxpcmap.c +++ b/base/gxpcmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1498,7 +1498,7 @@ gx_pattern_load(gx_device_color * pdc, const gs_gstate * pgs, goto fail; if (pinst->templat.uses_transparency) { if_debug0m('v', mem, "gx_pattern_load: pushing the pdf14 compositor device into this graphics state\n"); - if ((code = gs_push_pdf14trans_device(saved, true, false)) < 0) + if ((code = gs_push_pdf14trans_device(saved, true, false, 0, 0)) < 0) /* FIXME: do we need spot_color_count ??? */ return code; saved->device->is_open = true; } else { diff --git a/base/gxpcolor.h b/base/gxpcolor.h index 9d1856bd..197b7532 100644 --- a/base/gxpcolor.h +++ b/base/gxpcolor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxpcopy.c b/base/gxpcopy.c index 51abb19d..fdffe76b 100644 --- a/base/gxpcopy.c +++ b/base/gxpcopy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -330,7 +330,7 @@ adjust_point_to_tangent(segment * pseg, const segment * next, return; /* anomalous case */ if_debug1('2', "[2]adjusting vertical: DT = %g\n", fixed2float(DT)); - if ((DT ^ fD) > 0) + if ((DT ^ fD) > 0) /* lgtm [cpp/bitwise-sign-check] */ pseg->pt.y = DT + y0; } else if (fD == 0) { /* Horizontal tangent. */ @@ -338,7 +338,7 @@ adjust_point_to_tangent(segment * pseg, const segment * next, if_debug1('2', "[2]adjusting horizontal: CT = %g\n", fixed2float(CT)); - if ((CT ^ fC) > 0) + if ((CT ^ fC) > 0) /* lgtm [cpp/bitwise-sign-check] */ pseg->pt.x = CT + x0; } else { /* General case. */ diff --git a/base/gxpdash.c b/base/gxpdash.c index 2e45b3cd..281e23a2 100644 --- a/base/gxpdash.c +++ b/base/gxpdash.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxpflat.c b/base/gxpflat.c index fa90fc28..928a24c2 100644 --- a/base/gxpflat.c +++ b/base/gxpflat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxrplane.h b/base/gxrplane.h index 38694e89..e931f832 100644 --- a/base/gxrplane.h +++ b/base/gxrplane.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxsample.c b/base/gxsample.c index 519abd82..33f96417 100644 --- a/base/gxsample.c +++ b/base/gxsample.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxsample.h b/base/gxsample.h index 25db3174..00c3ccf7 100644 --- a/base/gxsample.h +++ b/base/gxsample.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxsamplp.h b/base/gxsamplp.h index c6f6c0ae..143b240c 100644 --- a/base/gxsamplp.h +++ b/base/gxsamplp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxscanc.c b/base/gxscanc.c index 7776d486..9842b2c3 100644 --- a/base/gxscanc.c +++ b/base/gxscanc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -3627,7 +3627,9 @@ no_merge: } else if (sx < ex) { /* Lines increasing in x. (Rightwards, rising) */ int phase1_x_steps, phase3_x_steps; - fixed x_steps = ex - sx; + /* Use unsigned int here, to allow for extreme cases like + * ex = 0x7fffffff, sx = 0x80000000 */ + unsigned int x_steps = ex - sx; /* Phase 1: */ if (phase1_y_steps) { @@ -3693,7 +3695,9 @@ no_merge: } else { /* Lines decreasing in x. (Leftwards, rising) */ int phase1_x_steps, phase3_x_steps; - fixed x_steps = sx - ex; + /* Use unsigned int here, to allow for extreme cases like + * sx = 0x7fffffff, ex = 0x80000000 */ + unsigned int x_steps = sx - ex; /* Phase 1: */ if (phase1_y_steps) { @@ -3813,7 +3817,9 @@ endFallingLeftOnEdgeOfPixel: } else if (sx < ex) { /* Lines increasing in x. (Rightwards, falling) */ int phase1_x_steps, phase3_x_steps; - fixed x_steps = ex - sx; + /* Use unsigned int here, to allow for extreme cases like + * ex = 0x7fffffff, sx = 0x80000000 */ + unsigned int x_steps = ex - sx; /* Phase 1: */ if (phase1_y_steps) { @@ -3878,7 +3884,9 @@ endFallingRightOnEdgeOfPixel: } else { /* Lines decreasing in x. (Falling) */ int phase1_x_steps, phase3_x_steps; - fixed x_steps = sx - ex; + /* Use unsigned int here, to allow for extreme cases like + * sx = 0x7fffffff, ex = 0x80000000 */ + unsigned int x_steps = sx - ex; /* Phase 1: */ if (phase1_y_steps) { diff --git a/base/gxscanc.h b/base/gxscanc.h index a585ef44..7bf71be3 100644 --- a/base/gxscanc.h +++ b/base/gxscanc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxshade.c b/base/gxshade.c index 27413ac1..80e3b742 100644 --- a/base/gxshade.c +++ b/base/gxshade.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxshade.h b/base/gxshade.h index 19a0aa38..4990b25e 100644 --- a/base/gxshade.h +++ b/base/gxshade.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxshade1.c b/base/gxshade1.c index 4b86d138..c105f6cf 100644 --- a/base/gxshade1.c +++ b/base/gxshade1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -343,7 +343,7 @@ gs_shading_A_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, * For the purposes of explanation, we shall label the octants as below: * * \2|1/ and Quadrants as: | - * 3\|/0 Q1 | Q0 + * 3\|/0 Q1 | Q0 * ---+--- ----+---- * 4/|\7 Q2 | Q3 * /5|6\ | @@ -351,7 +351,7 @@ gs_shading_A_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, * We find (dx,dy), the difference between the centres of the circles. * We look to see which octant this falls in. Firstly, this tells us which * quadrant of the circle we need to draw first (Octant n, starts with - * Quadrant floor(n/2)). Secondly, it tells us which direction to form the + * Quadrant floor(n/2)). Secondly, it tells us which direction to form the * tensor patch in; we always want to draw from the side 'closest' to * dx/dy to the side further away. This ensures that we don't overwrite * pixels in the incorrect order as the patch decomposes. diff --git a/base/gxshade4.c b/base/gxshade4.c index 86cc1a57..f2058b98 100644 --- a/base/gxshade4.c +++ b/base/gxshade4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxshade4.h b/base/gxshade4.h index 973a43c9..e5113c92 100644 --- a/base/gxshade4.h +++ b/base/gxshade4.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxshade6.c b/base/gxshade6.c index e48bcfb4..e8f9349b 100644 --- a/base/gxshade6.c +++ b/base/gxshade6.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1482,6 +1482,13 @@ constant_color_trapezoid(patch_fill_state_t *pfs, gs_fixed_edge *le, gs_fixed_ed code = patch_color_to_device_color_inline(pfs, c, &dc, NULL); if (code < 0) return code; + + if (device_encodes_tags(pfs->dev)) { + dc.tag = (pfs->dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + } else { + dc.tag = 0; + } + return dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, le, re, ybot, ytop, swap_axes, &dc, pfs->pgs->log_op); } @@ -2539,6 +2546,12 @@ constant_color_quadrangle_aux(patch_fill_state_t *pfs, const quadrangle_patch *p gx_device_color dc; bool orient; + if (device_encodes_tags(pfs->dev)) { + dc.tag = (pfs->dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS); + } else { + dc.tag = 0; + } + patch_interpolate_color(c[1], p->p[0][0]->c, p->p[0][1]->c, pfs, 0.5); patch_interpolate_color(c[2], p->p[1][0]->c, p->p[1][1]->c, pfs, 0.5); patch_interpolate_color(c[0], c[1], c[2], pfs, 0.5); diff --git a/base/gxstate.h b/base/gxstate.h index 2d67efb8..cf61b297 100644 --- a/base/gxstate.h +++ b/base/gxstate.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxstdio.h b/base/gxstdio.h index 0956c560..a2f4a51c 100644 --- a/base/gxstdio.h +++ b/base/gxstdio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxstroke.c b/base/gxstroke.c index e99497b6..87def483 100644 --- a/base/gxstroke.c +++ b/base/gxstroke.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxsync.c b/base/gxsync.c index 7f41a273..ad054111 100644 --- a/base/gxsync.c +++ b/base/gxsync.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxsync.h b/base/gxsync.h index 762fb2fe..c2c9017d 100644 --- a/base/gxsync.h +++ b/base/gxsync.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxtext.h b/base/gxtext.h index afe0bc89..e6836ae7 100644 --- a/base/gxtext.h +++ b/base/gxtext.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -126,6 +126,7 @@ rc_free_proc(rc_free_text_enum); int bytes_decoded; \ gs_point FontBBox_as_Metrics2; /* used with FontType 9,11 && WMode 1 */\ ulong text_enum_id; /* debug purpose only - not used by algorythm. */\ + bool k_text_release; /* Set at time of gs_text_begin to know to do release of black_text_state */\ /* The following is controlled by a device. */\ bool device_disabled_grid_fitting;\ /* Following two members moved from the show enumerator */\ @@ -168,7 +169,7 @@ rc_free_proc(rc_free_text_enum); show_width_status width_status; \ /*gs_log2_scale_point log2_scale;*/ \ int (*continue_proc) (gs_show_enum *) /* continuation procedure */ - + /* The typedef is in gstext.h. */ struct gs_text_enum_s { gs_text_enum_common; diff --git a/base/gxtmap.h b/base/gxtmap.h index 994c38e5..676b4906 100644 --- a/base/gxtmap.h +++ b/base/gxtmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxttf.h b/base/gxttf.h index ab683ba9..a53065e3 100644 --- a/base/gxttf.h +++ b/base/gxttf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxttfb.c b/base/gxttfb.c index d0a8c882..582c05c8 100644 --- a/base/gxttfb.c +++ b/base/gxttfb.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxttfb.h b/base/gxttfb.h index 487ac941..97c93f1c 100644 --- a/base/gxttfb.h +++ b/base/gxttfb.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxtype1.c b/base/gxtype1.c index 3169751f..44dfab43 100644 --- a/base/gxtype1.c +++ b/base/gxtype1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxtype1.h b/base/gxtype1.h index 6519f113..86911386 100644 --- a/base/gxtype1.h +++ b/base/gxtype1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gxxfont.h b/base/gxxfont.h index b239cd27..c446de36 100644 --- a/base/gxxfont.h +++ b/base/gxxfont.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzacpath.h b/base/gzacpath.h index 4670b478..1f135f51 100644 --- a/base/gzacpath.h +++ b/base/gzacpath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzcpath.h b/base/gzcpath.h index da5d2758..726864bf 100644 --- a/base/gzcpath.h +++ b/base/gzcpath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzht.h b/base/gzht.h index 1adb06d0..9c1e0fe8 100644 --- a/base/gzht.h +++ b/base/gzht.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzline.h b/base/gzline.h index 919b3ad6..80293597 100644 --- a/base/gzline.h +++ b/base/gzline.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzpath.h b/base/gzpath.h index 1c78caf8..39416894 100644 --- a/base/gzpath.h +++ b/base/gzpath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzspotan.c b/base/gzspotan.c index 46fd35bf..847f3c9d 100644 --- a/base/gzspotan.c +++ b/base/gzspotan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzspotan.h b/base/gzspotan.h index 4a60b19e..fd95825b 100644 --- a/base/gzspotan.h +++ b/base/gzspotan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/gzstate.h b/base/gzstate.h index 648534c3..5a1f456f 100644 --- a/base/gzstate.h +++ b/base/gzstate.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/icc34.h b/base/icc34.h index a58b0b9d..be36c272 100644 --- a/base/icc34.h +++ b/base/icc34.h @@ -2,55 +2,55 @@ #ifndef ICC_H #define ICC_H -/***************************************************************** +/***************************************************************** Copyright (c) 1994-1996 SunSoft, Inc. Rights Reserved -Permission is hereby granted, free of charge, to any person +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restrict- -ion, including without limitation the rights to use, copy, modify, -merge, publish distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +files (the "Software"), to deal in the Software without restrict- +ion, including without limitation the rights to use, copy, modify, +merge, publish distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- -INFRINGEMENT. IN NO EVENT SHALL SUNSOFT, INC. OR ITS PARENT -COMPANY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of SunSoft, Inc. -shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without written -authorization from SunSoft Inc. +INFRINGEMENT. IN NO EVENT SHALL SUNSOFT, INC. OR ITS PARENT +COMPANY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of SunSoft, Inc. +shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without written +authorization from SunSoft Inc. ******************************************************************/ /* * This version of the header file corresponds to the profile * specification version 3.4. * - * All header file entries are pre-fixed with "ic" to help + * All header file entries are pre-fixed with "ic" to help * avoid name space collisions. Signatures are pre-fixed with * icSig. * * The structures defined in this header file were created to * represent a description of an ICC profile on disk. Rather - * than use pointers a technique is used where a single byte array + * than use pointers a technique is used where a single byte array * was placed at the end of each structure. This allows us in "C" * to extend the structure by allocating more data than is needed * to account for variable length structures. * * This also ensures that data following is allocated * contiguously and makes it easier to write and read data from - * the file. + * the file. * * For example to allocate space for a 256 count length UCR * and BG array, and fill the allocated data. Note strlen + 1 @@ -62,20 +62,20 @@ authorization from SunSoft Inc. char ucr_string[100], *ucr_char; strcpy(ucr_string, "Example ucrBG curves"); - ucr_nbytes = sizeof(icUInt32Number) + + ucr_nbytes = sizeof(icUInt32Number) + (UCR_CURVE_SIZE * sizeof(icUInt16Number)); - bg_nbytes = sizeof(icUInt32Number) + + bg_nbytes = sizeof(icUInt32Number) + (BG_CURVE_SIZE * sizeof(icUInt16Number)); string_bytes = strlen(ucr_string) + 1; ucrBgWrite = (icUcrBg *)malloc( (ucr_nbytes + bg_nbytes + string_bytes)); - + ucrCurve = (icUcrBgCurve *)ucrBgWrite->data; ucrCurve->count = UCR_CURVE_SIZE; for (i=0; icount; i++) ucrCurve->curve[i] = (icUInt16Number)i; - + bgCurve = (icUcrBgCurve *)((char *)ucrCurve + ucr_nbytes); bgCurve->count = BG_CURVE_SIZE; for (i=0; icount; i++) @@ -106,7 +106,7 @@ authorization from SunSoft Inc. #define icLinesPerInch 0x00000002L /* Bit pos 1 */ #define icLinesPerCm 0x00000000L /* Bit pos 1 */ -/* +/* * Device attributes, currently defined values correspond * to the low 4 bytes of the 8 byte attribute quantity, see * the header for their location. @@ -126,10 +126,10 @@ authorization from SunSoft Inc. #define icUseWithEmbeddedDataOnly 0x00000002L /* Bit pos 1 */ /* Ascii or Binary data */ -#define icAsciiData 0x00000000L +#define icAsciiData 0x00000000L #define icBinaryData 0x00000001L -/* +/* * Define used to indicate that this is a variable length array */ #define icAny 1 @@ -147,8 +147,8 @@ authorization from SunSoft Inc. #ifdef PACKAGE_NAME /* June 9, 2003, Adapted for use with configure by Bob Friesenhahn - Added the stupid check for autoconf by Marti Maria. - PACKAGE_NAME is defined if autoconf is being used + Added the stupid check for autoconf by Marti Maria. + PACKAGE_NAME is defined if autoconf is being used */ typedef @UINT8_T@ icUInt8Number; @@ -163,7 +163,7 @@ typedef @INT32_T@ icInt64Number[2]; #elif defined (__digital__) && defined (__unix__) -/* +/* *Apr-17-2002: Modified by Marti Maria in order to provide wider portability. */ @@ -267,16 +267,16 @@ typedef icUInt32Number icU16Fixed16Number; /*------------------------------------------------------------------------*/ /* public tags and sizes */ typedef enum { - icSigAToB0Tag = 0x41324230L, /* 'A2B0' */ + icSigAToB0Tag = 0x41324230L, /* 'A2B0' */ icSigAToB1Tag = 0x41324231L, /* 'A2B1' */ - icSigAToB2Tag = 0x41324232L, /* 'A2B2' */ + icSigAToB2Tag = 0x41324232L, /* 'A2B2' */ icSigBlueColorantTag = 0x6258595AL, /* 'bXYZ' */ icSigBlueTRCTag = 0x62545243L, /* 'bTRC' */ icSigBToA0Tag = 0x42324130L, /* 'B2A0' */ icSigBToA1Tag = 0x42324131L, /* 'B2A1' */ icSigBToA2Tag = 0x42324132L, /* 'B2A2' */ icSigCalibrationDateTimeTag = 0x63616C74L, /* 'calt' */ - icSigCharTargetTag = 0x74617267L, /* 'targ' */ + icSigCharTargetTag = 0x74617267L, /* 'targ' */ icSigCopyrightTag = 0x63707274L, /* 'cprt' */ icSigCrdInfoTag = 0x63726469L, /* 'crdi' */ icSigDeviceMfgDescTag = 0x646D6E64L, /* 'dmnd' */ @@ -289,7 +289,7 @@ typedef enum { icSigMeasurementTag = 0x6D656173L, /* 'meas' */ icSigMediaBlackPointTag = 0x626B7074L, /* 'bkpt' */ icSigMediaWhitePointTag = 0x77747074L, /* 'wtpt' */ - icSigNamedColorTag = 0x6E636f6CL, /* 'ncol' + icSigNamedColorTag = 0x6E636f6CL, /* 'ncol' * OBSOLETE, use ncl2 */ icSigNamedColor2Tag = 0x6E636C32L, /* 'ncl2' */ icSigPreview0Tag = 0x70726530L, /* 'pre0' */ @@ -311,7 +311,7 @@ typedef enum { icSigUcrBgTag = 0x62666420L, /* 'bfd ' */ icSigViewingCondDescTag = 0x76756564L, /* 'vued' */ icSigViewingConditionsTag = 0x76696577L, /* 'view' */ - icMaxEnumTag = 0xFFFFFFFFL + icMaxEnumTag = 0xFFFFFFFFL } icTagSignature; /* technology signature descriptions */ @@ -319,7 +319,7 @@ typedef enum { icSigDigitalCamera = 0x6463616DL, /* 'dcam' */ icSigFilmScanner = 0x6673636EL, /* 'fscn' */ icSigReflectiveScanner = 0x7273636EL, /* 'rscn' */ - icSigInkJetPrinter = 0x696A6574L, /* 'ijet' */ + icSigInkJetPrinter = 0x696A6574L, /* 'ijet' */ icSigThermalWaxPrinter = 0x74776178L, /* 'twax' */ icSigElectrophotographicPrinter = 0x6570686FL, /* 'epho' */ icSigElectrostaticPrinter = 0x65737461L, /* 'esta' */ @@ -338,7 +338,7 @@ typedef enum { icSigOffsetLithography = 0x6F666673L, /* 'offs' */ icSigSilkscreen = 0x73696C6BL, /* 'silk' */ icSigFlexography = 0x666C6578L, /* 'flex' */ - icMaxEnumTechnology = 0xFFFFFFFFL + icMaxEnumTechnology = 0xFFFFFFFFL } icTechnologySignature; /* type signatures */ @@ -349,7 +349,7 @@ typedef enum { icSigLut16Type = 0x6d667432L, /* 'mft2' */ icSigLut8Type = 0x6d667431L, /* 'mft1' */ icSigMeasurementType = 0x6D656173L, /* 'meas' */ - icSigNamedColorType = 0x6E636f6CL, /* 'ncol' + icSigNamedColorType = 0x6E636f6CL, /* 'ncol' * OBSOLETE, use ncl2 */ icSigProfileSequenceDescType = 0x70736571L, /* 'pseq' */ icSigS15Fixed16ArrayType = 0x73663332L, /* 'sf32' */ @@ -368,14 +368,14 @@ typedef enum { icSigXYZArrayType = 0x58595A20L, /* 'XYZ ' */ icSigNamedColor2Type = 0x6E636C32L, /* 'ncl2' */ icSigCrdInfoType = 0x63726469L, /* 'crdi' */ - icMaxEnumType = 0xFFFFFFFFL + icMaxEnumType = 0xFFFFFFFFL } icTagTypeSignature; -/* +/* * Color Space Signatures * Note that only icSigXYZData and icSigLabData are valid * Profile Connection Spaces (PCSs) - */ + */ typedef enum { icSigXYZData = 0x58595A20L, /* 'XYZ ' */ icSigLabData = 0x4C616220L, /* 'Lab ' */ @@ -402,7 +402,7 @@ typedef enum { icSig13colorData = 0x44434C52L, /* 'DCLR' */ icSig14colorData = 0x45434C52L, /* 'ECLR' */ icSig15colorData = 0x46434C52L, /* 'FCLR' */ - icMaxEnumData = 0xFFFFFFFFL + icMaxEnumData = 0xFFFFFFFFL } icColorSpaceSignature; /* profileClass enumerations */ @@ -414,7 +414,7 @@ typedef enum { icSigAbstractClass = 0x61627374L, /* 'abst' */ icSigColorSpaceClass = 0x73706163L, /* 'spac' */ icSigNamedColorClass = 0x6e6d636cL, /* 'nmcl' */ - icMaxEnumClass = 0xFFFFFFFFL + icMaxEnumClass = 0xFFFFFFFFL } icProfileClassSignature; /* Platform Signatures */ @@ -424,7 +424,7 @@ typedef enum { icSigSolaris = 0x53554E57L, /* 'SUNW' */ icSigSGI = 0x53474920L, /* 'SGI ' */ icSigTaligent = 0x54474E54L, /* 'TGNT' */ - icMaxEnumPlatform = 0xFFFFFFFFL + icMaxEnumPlatform = 0xFFFFFFFFL } icPlatformSignature; /*------------------------------------------------------------------------*/ @@ -436,7 +436,7 @@ typedef enum { typedef enum { icFlare0 = 0x00000000L, /* 0% flare */ icFlare100 = 0x00000001L, /* 100% flare */ - icMaxFlare = 0xFFFFFFFFL + icMaxFlare = 0xFFFFFFFFL } icMeasurementFlare; /* Measurement Geometry, used in the measurmentType tag */ @@ -444,7 +444,7 @@ typedef enum { icGeometryUnknown = 0x00000000L, /* Unknown */ icGeometry045or450 = 0x00000001L, /* 0/45, 45/0 */ icGeometry0dord0 = 0x00000002L, /* 0/d or d/0 */ - icMaxGeometry = 0xFFFFFFFFL + icMaxGeometry = 0xFFFFFFFFL } icMeasurementGeometry; /* Rendering Intents, used in the profile header */ @@ -453,7 +453,7 @@ typedef enum { icRelativeColorimetric = 1, icSaturation = 2, icAbsoluteColorimetric = 3, - icMaxEnumIntent = 0xFFFFFFFFL + icMaxEnumIntent = 0xFFFFFFFFL } icRenderingIntent; /* Different Spot Shapes currently defined, used for screeningType */ @@ -466,7 +466,7 @@ typedef enum { icSpotShapeLine = 5, icSpotShapeSquare = 6, icSpotShapeCross = 7, - icMaxEnumSpot = 0xFFFFFFFFL + icMaxEnumSpot = 0xFFFFFFFFL } icSpotShape; /* Standard Observer, used in the measurmentType tag */ @@ -474,7 +474,7 @@ typedef enum { icStdObsUnknown = 0x00000000L, /* Unknown */ icStdObs1931TwoDegrees = 0x00000001L, /* 2 deg */ icStdObs1964TenDegrees = 0x00000002L, /* 10 deg */ - icMaxStdObs = 0xFFFFFFFFL + icMaxStdObs = 0xFFFFFFFFL } icStandardObserver; /* Pre-defined illuminants, used in measurement and viewing conditions type */ @@ -486,15 +486,15 @@ typedef enum { icIlluminantF2 = 0x00000004L, icIlluminantD55 = 0x00000005L, icIlluminantA = 0x00000006L, - icIlluminantEquiPowerE = 0x00000007L, - icIlluminantF8 = 0x00000008L, - icMaxEnumIluminant = 0xFFFFFFFFL + icIlluminantEquiPowerE = 0x00000007L, + icIlluminantF8 = 0x00000008L, + icMaxEnumIluminant = 0xFFFFFFFFL } icIlluminant; /*------------------------------------------------------------------------*/ /* - * Arrays of numbers + * Arrays of numbers */ /* Int8 Array */ @@ -536,7 +536,7 @@ typedef struct { typedef struct { icInt64Number data[icAny]; /* Variable array of values */ } icInt64Array; - + /* u16Fixed16 Array */ typedef struct { icU16Fixed16Number data[icAny]; /* Variable array of values */ @@ -592,13 +592,13 @@ typedef struct { icUInt8Number clutPoints; /* Number of grid points */ icInt8Number pad; /* Padding for byte alignment */ icS15Fixed16Number e00; /* e00 in the 3 * 3 */ - icS15Fixed16Number e01; /* e01 in the 3 * 3 */ + icS15Fixed16Number e01; /* e01 in the 3 * 3 */ icS15Fixed16Number e02; /* e02 in the 3 * 3 */ icS15Fixed16Number e10; /* e10 in the 3 * 3 */ - icS15Fixed16Number e11; /* e11 in the 3 * 3 */ - icS15Fixed16Number e12; /* e12 in the 3 * 3 */ + icS15Fixed16Number e11; /* e11 in the 3 * 3 */ + icS15Fixed16Number e12; /* e12 in the 3 * 3 */ icS15Fixed16Number e20; /* e20 in the 3 * 3 */ - icS15Fixed16Number e21; /* e21 in the 3 * 3 */ + icS15Fixed16Number e21; /* e21 in the 3 * 3 */ icS15Fixed16Number e22; /* e22 in the 3 * 3 */ icUInt16Number inputEnt; /* Num of in-table entries */ icUInt16Number outputEnt; /* Num of out-table entries */ @@ -607,7 +607,7 @@ typedef struct { * Data that follows is of this form * * icUInt16Number inputTable[inputChan][icAny]; * The in-table - * icUInt16Number clutTable[icAny]; * The clut + * icUInt16Number clutTable[icAny]; * The clut * icUInt16Number outputTable[outputChan][icAny]; * The out-table */ } icLut16; @@ -619,20 +619,20 @@ typedef struct { icUInt8Number clutPoints; /* Num of grid points */ icInt8Number pad; icS15Fixed16Number e00; /* e00 in the 3 * 3 */ - icS15Fixed16Number e01; /* e01 in the 3 * 3 */ + icS15Fixed16Number e01; /* e01 in the 3 * 3 */ icS15Fixed16Number e02; /* e02 in the 3 * 3 */ icS15Fixed16Number e10; /* e10 in the 3 * 3 */ - icS15Fixed16Number e11; /* e11 in the 3 * 3 */ - icS15Fixed16Number e12; /* e12 in the 3 * 3 */ + icS15Fixed16Number e11; /* e11 in the 3 * 3 */ + icS15Fixed16Number e12; /* e12 in the 3 * 3 */ icS15Fixed16Number e20; /* e20 in the 3 * 3 */ - icS15Fixed16Number e21; /* e21 in the 3 * 3 */ + icS15Fixed16Number e21; /* e21 in the 3 * 3 */ icS15Fixed16Number e22; /* e22 in the 3 * 3 */ icUInt8Number data[icAny]; /* Data follows see spec */ /* * Data that follows is of this form * * icUInt8Number inputTable[inputChan][256]; * The in-table - * icUInt8Number clutTable[icAny]; * The clut + * icUInt8Number clutTable[icAny]; * The clut * icUInt8Number outputTable[outputChan][256]; * The out-table */ } icLut8; @@ -649,7 +649,7 @@ typedef struct { /* Named color */ /* - * icNamedColor2 takes the place of icNamedColor + * icNamedColor2 takes the place of icNamedColor */ typedef struct { icUInt32Number vendorFlag; /* Bottom 16 bits for IC use */ @@ -670,16 +670,16 @@ typedef struct { * : * : * Repeat for name and PCS and device color coordinates up to (count-1) - * - * NOTES: + * + * NOTES: * PCS and device space can be determined from the header. * - * PCS coordinates are icUInt16 numbers and are described in Annex A of - * the ICC spec. Only 16 bit L*a*b* and XYZ are allowed. The number of + * PCS coordinates are icUInt16 numbers and are described in Annex A of + * the ICC spec. Only 16 bit L*a*b* and XYZ are allowed. The number of * coordinates is consistent with the headers PCS. * * Device coordinates are icUInt16 numbers where 0x0000 represents - * the minimum value and 0xFFFF represents the maximum value. + * the minimum value and 0xFFFF represents the maximum value. * If the nDeviceCoords value is 0 this field is not given. */ } icNamedColor2; @@ -693,7 +693,7 @@ typedef struct { icInt8Number data[icAny]; /* Desc text follows */ /* * Data that follows is of this form, this is an icInt8Number - * to avoid problems with a compiler generating bad code as + * to avoid problems with a compiler generating bad code as * these arrays are variable in length. * * icTextDescription deviceMfgDesc; * Manufacturer text @@ -753,7 +753,7 @@ typedef struct { icInt8Number data[icAny]; /* The Ucr BG data */ /* * Data that follows is of this form, this is a icInt8Number - * to avoid problems with a compiler generating bad code as + * to avoid problems with a compiler generating bad code as * these arrays are variable in length. * * icUcrBgCurve ucr; * Ucr curve @@ -900,7 +900,7 @@ typedef struct { icTagBase base; /* Signature, "ui64" */ icUInt64Array data; /* Variable array of values */ } icUInt64ArrayType; - + /* uInt8Type */ typedef struct { icTagBase base; /* Signature, "ui08" */ @@ -927,11 +927,11 @@ typedef struct { icCrdInfo info; /* 5 sets of counts & strings */ }icCrdInfoType; /* icCrdInfo productName; PS product count/string */ - /* icCrdInfo CRDName0; CRD name for intent 0 */ - /* icCrdInfo CRDName1; CRD name for intent 1 */ - /* icCrdInfo CRDName2; CRD name for intent 2 */ + /* icCrdInfo CRDName0; CRD name for intent 0 */ + /* icCrdInfo CRDName1; CRD name for intent 1 */ + /* icCrdInfo CRDName2; CRD name for intent 2 */ /* icCrdInfo CRDName3; CRD name for intent 3 */ - + /*------------------------------------------------------------------------*/ /* @@ -941,8 +941,8 @@ typedef struct { /* A tag */ typedef struct { icTagSignature sig; /* The tag signature */ - icUInt32Number offset; /* Start of tag relative to - * start of header, Spec + icUInt32Number offset; /* Start of tag relative to + * start of header, Spec * Clause 5 */ icUInt32Number size; /* Size in bytes */ } icTag; @@ -974,8 +974,8 @@ typedef struct { icInt8Number reserved[44]; /* Reserved */ } icHeader; -/* - * A profile, +/* + * A profile, * we can't use icTagList here because its not at the end of the structure */ typedef struct { @@ -985,10 +985,10 @@ typedef struct { /* * Data that follows is of the form * - * icTag tagTable[icAny]; * The tag table - * icInt8Number tagData[icAny]; * The tag data + * icTag tagTable[icAny]; * The tag table + * icInt8Number tagData[icAny]; * The tag data */ -} icProfile; +} icProfile; /*------------------------------------------------------------------------*/ /* Obsolete entries */ @@ -1001,12 +1001,12 @@ typedef struct { /* * Data that follows is of this form * - * icInt8Number prefix[icAny]; * Prefix - * icInt8Number suffix[icAny]; * Suffix - * icInt8Number root1[icAny]; * Root name - * icInt8Number coords1[icAny]; * Color coordinates - * icInt8Number root2[icAny]; * Root name - * icInt8Number coords2[icAny]; * Color coordinates + * icInt8Number prefix[icAny]; * Prefix + * icInt8Number suffix[icAny]; * Suffix + * icInt8Number root1[icAny]; * Root name + * icInt8Number coords1[icAny]; * Color coordinates + * icInt8Number root2[icAny]; * Root name + * icInt8Number coords2[icAny]; * Color coordinates * : * : * Repeat for root name and color coordinates up to (count-1) diff --git a/base/ijs.mak b/base/ijs.mak index 557dae5b..fe249c55 100644 --- a/base/ijs.mak +++ b/base/ijs.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -36,8 +36,8 @@ IJSO_=$(O_)$(IJSOBJ) # IJSI_ and IJSF_ are defined in gs.mak (why?) # as are IJSGENDIR and IJSOBJDIR above. IJS_INCL=$(I_)$(IJSI_)$(_I) -IJS_CCFLAGS=$(IJS_INCL) $(IJSF_) -IJS_CC=$(CC_) $(IJS_CCFLAGS) +IJS_CCFLAGS=$(IJS_INCL) $(IJSF_) +IJS_CC=$(CC) $(IJS_CCFLAGS) $(CCFLAGS) # Define the name of this makefile. IJS_MAK=$(GLSRC)ijs.mak $(TOP_MAKEFILES) diff --git a/base/instcopy b/base/instcopy index ef1e260d..acaef63e 100755 --- a/base/instcopy +++ b/base/instcopy @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/jbig2.mak b/base/jbig2.mak index 2ec14d94..7e37b0de 100644 --- a/base/jbig2.mak +++ b/base/jbig2.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -93,7 +93,7 @@ jbig2.config-clean : JBIG2DEP=$(AK) -JBIG2_CC=$(CC_) $(CFLAGS) $(I_)$(JBIG2GENDIR) $(II)$(JB2I_)$(_I) $(JB2CF_) -DJBIG_EXTERNAL_MEMENTO_H=\"../base/memento.h\" +JBIG2_CC=$(CC) $(I_)$(JBIG2GENDIR) $(II)$(JB2I_)$(_I) $(JB2CF_) -DJBIG_EXTERNAL_MEMENTO_H=\"../base/memento.h\" $(CCFLAGS) JBIG2O_=$(O_)$(JBIG2OBJ) # switch in the version of libjbig2.dev we're actually using @@ -109,7 +109,7 @@ $(JBIG2GEN)jbig2dec_0.dev : $(JBIG2_MAK) $(ECHOGS_XE) $(libjbig2_OBJS) $(JBIG2_M $(SETMOD) $(JBIG2GEN)jbig2dec_0 $(libjbig2_OBJS1) $(ADDMOD) $(JBIG2GEN)jbig2dec_0 $(libjbig2_OBJS2) -# explicit rules for building the source files. +# explicit rules for building the source files. $(JBIG2OBJ)snprintf.$(OBJ) : $(JBIG2SRC)snprintf.c $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)snprintf.$(OBJ) $(C_) $(JBIG2SRC)snprintf.c @@ -137,7 +137,7 @@ $(JBIG2OBJ)jbig2_generic.$(OBJ) : $(JBIG2SRC)jbig2_generic.c $(libjbig2_HDRS) $( $(JBIG2OBJ)jbig2_refinement.$(OBJ) : $(JBIG2SRC)jbig2_refinement.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_refinement.$(OBJ) $(C_) $(JBIG2SRC)jbig2_refinement.c - + $(JBIG2OBJ)jbig2_huffman.$(OBJ) : $(JBIG2SRC)jbig2_huffman.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_huffman.$(OBJ) $(C_) $(JBIG2SRC)jbig2_huffman.c diff --git a/base/jerror_.h b/base/jerror_.h index dafcf480..297ae610 100644 --- a/base/jerror_.h +++ b/base/jerror_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/jmemcust.c b/base/jmemcust.c index bdcbb7ec..79490f56 100644 --- a/base/jmemcust.c +++ b/base/jmemcust.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/jmemcust.h b/base/jmemcust.h index 8d2f97d5..c9862cdf 100644 --- a/base/jmemcust.h +++ b/base/jmemcust.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/jpeg.mak b/base/jpeg.mak index c1929e63..eea6ce10 100644 --- a/base/jpeg.mak +++ b/base/jpeg.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -107,7 +107,7 @@ jpeg.config-clean : # JI_ and JF_ are defined in gs.mak. # See below for why we need to include GLGENDIR here. -JCC=$(CC_) $(I_)$(GLGENDIR) $(II)$(JI_)$(_I) $(JF_) +JCC=$(CC) $(I_)$(GLGENDIR) $(II)$(JI_)$(_I) $(JF_) $(CCFLAGS) # We need our own version of jconfig.h, and our own "wrapper" for # jmorecfg.h. @@ -125,9 +125,9 @@ jmorecf__h=$(GLGEN)jmorecf_.h # We use our own jconfig.h and jmorecfg.h iff we aren't sharing the library. # The library itself may need copies of them. - jconfig_h=$(GLGEN)jconfig.h jmorecfg_h=$(GLGEN)jmorecfg.h +jmemcust_h=$(GLSRC)jmemcust.h $(jconfig_h) $(GLGEN)jconfig_.h : $(GLGEN)jconfig$(SHARE_JPEG).h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(GLGEN)jconfig$(SHARE_JPEG).h $(GLGEN)jconfig_.h diff --git a/base/jpegxr.mak b/base/jpegxr.mak index daa5f62f..73aa632f 100644 --- a/base/jpegxr.mak +++ b/base/jpegxr.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -31,7 +31,7 @@ JPEGXR_GEN=$(JPEGXR_GENDIR)$(D) JPEGXR_OBJ=$(JPEGXR_OBJDIR)$(D) JPEGXR_O_=$(O_)$(JPEGXR_OBJ) -JPEGXR_CC=$(CC_) $(JPEGXR_CFLAGS) $(D_)JXR_DLL_EXPORTS=1$(_D) $(D_)NDEBUG$(_D) +JPEGXR_CC=$(CC) $(JPEGXR_CFLAGS) $(D_)JXR_DLL_EXPORTS=1$(_D) $(D_)NDEBUG$(_D) $(CCFLAGS) jpegxr.clean : jpegxr.config-clean jpegxr.clean-not-config-clean diff --git a/base/lcms2.mak b/base/lcms2.mak index a4224675..f53d6f70 100644 --- a/base/lcms2.mak +++ b/base/lcms2.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/lcms2mt.mak b/base/lcms2mt.mak index 68974579..e03e7e34 100644 --- a/base/lcms2mt.mak +++ b/base/lcms2mt.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/lcups.mak b/base/lcups.mak index e5974625..5189fe71 100644 --- a/base/lcups.mak +++ b/base/lcups.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -30,7 +30,7 @@ LCUPSO_=$(O_)$(LIBCUPSOBJ) # NB: we can't use the normal $(CC_) here because msvccmd.mak # adds /Za which conflicts with the cups source. -LCUPS_CC=$(CUPS_CC) $(I_)$(LIBCUPSSRC) $(I_)$(LIBCUPSGEN)$(D)cups $(I_)$(LCUPSSRCDIR)$(D)libs +LCUPS_CC=$(CUPS_CC) $(I_)$(LIBCUPSSRC) $(I_)$(LIBCUPSGEN)$(D)cups $(I_)$(LCUPSSRCDIR)$(D)libs # Define the name of this makefile. LCUPS_MAK=$(GLSRC)lcups.mak $(TOP_MAKEFILES) @@ -79,7 +79,7 @@ LIBCUPS_OBJS =\ $(LIBCUPSOBJ)cups_snpf.$(OBJ) \ $(LIBCUPSOBJ)usersys.$(OBJ) \ $(LIBCUPSOBJ)ppd-cache.$(OBJ) \ - $(LIBCUPSOBJ)thread.$(OBJ) + $(LIBCUPSOBJ)thread.$(OBJ) # $(LIBCUPSOBJ)sidechannel.$(OBJ) \ # $(LIBCUPSOBJ)getifaddrs.$(OBJ) \ # $(LIBCUPSOBJ)pwg-ppd.$(OBJ) \ @@ -138,12 +138,12 @@ $(LIBCUPSGEN)lcups_0.dev : $(ECHOGS_XE) $(LIBCUPS_OBJS) $(LIBCUPS_DEPS) $(LIBCUPSGEN)$(D)cups$(D)config.h : $(LCUPSSRCDIR)$(D)libs$(D)config$(LCUPSBUILDTYPE).h $(LIBCUPS_DEPS) $(CP_) $(LCUPSSRCDIR)$(D)libs$(D)config$(LCUPSBUILDTYPE).h $(LIBCUPSGEN)$(D)cups$(D)config.h -$(LIBCUPSOBJ)adminutil.$(OBJ) : $(LIBCUPSSRC)adminutil.c $(LIBCUPSGEN)$(D)cups$(D)config.h $(LIBCUPS_DEPS) +$(LIBCUPSOBJ)adminutil.$(OBJ) : $(LIBCUPSSRC)adminutil.c $(LIBCUPSGEN)$(D)cups$(D)config.h $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)adminutil.$(OBJ) $(C_) $(LIBCUPSSRC)adminutil.c - + $(LIBCUPSOBJ)array.$(OBJ) : $(LIBCUPSSRC)array.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)array.$(OBJ) $(C_) $(LIBCUPSSRC)array.c - + $(LIBCUPSOBJ)attr.$(OBJ) : $(LIBCUPSSRC)attr.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)attr.$(OBJ) $(C_) $(LIBCUPSSRC)attr.c diff --git a/base/lcupsi.mak b/base/lcupsi.mak index 5b861174..f2ec1c04 100644 --- a/base/lcupsi.mak +++ b/base/lcupsi.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -32,7 +32,7 @@ LCUPSIO_=$(O_)$(LIBCUPSIOBJ) # NB: we can't use the normal $(CC_) here because msvccmd.mak # adds /Za which conflicts with the cups source. LCUPSI_CC=$(CUPS_CC) $(I_)$(LIBCUPSISRC) $(I_)$(LIBCUPSIGEN)$(D)cups $(I_)$(LCUPSISRCDIR)$(D)libs $(I_)$(GLGENDIR) \ - $(I_)$(ZSRCDIR) $(I_)$(PNGSRCDIR) $(I_)$(TIFFSRCDIR) $(I_)$(TIFFCONFDIR) $(I_)$(TI_) + $(I_)$(ZSRCDIR) $(I_)$(PNGSRCDIR) $(I_)$(TIFFSRCDIR) $(I_)$(TIFFCONFDIR) $(I_)$(TI_) # Define the name of this makefile. LCUPSI_MAK=$(GLSRC)lcupsi.mak $(TOP_MAKEFILES) @@ -77,49 +77,49 @@ $(LIBCUPSIOBJ)image-bmp.$(OBJ) : $(LIBCUPSISRC)image-bmp.c $(LIBCUPSI_DEPS) $(LIBCUPSIOBJ)image-colorspace.$(OBJ) : $(LIBCUPSISRC)image-colorspace.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-colorspace.$(OBJ) $(C_) $(LIBCUPSISRC)image-colorspace.c - + $(LIBCUPSIOBJ)image-gif.$(OBJ) : $(LIBCUPSISRC)image-gif.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-gif.$(OBJ) $(C_) $(LIBCUPSISRC)image-gif.c - + $(LIBCUPSIOBJ)image-jpeg.$(OBJ) : $(LIBCUPSISRC)image-jpeg.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-jpeg.$(OBJ) $(C_) $(LIBCUPSISRC)image-jpeg.c - + $(LIBCUPSIOBJ)image-photocd.$(OBJ) : $(LIBCUPSISRC)image-photocd.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-photocd.$(OBJ) $(C_) $(LIBCUPSISRC)image-photocd.c - + $(LIBCUPSIOBJ)image-pix.$(OBJ) : $(LIBCUPSISRC)image-pix.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-pix.$(OBJ) $(C_) $(LIBCUPSISRC)image-pix.c - + $(LIBCUPSIOBJ)image-png.$(OBJ) : $(LIBCUPSISRC)image-png.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-png.$(OBJ) $(C_) $(LIBCUPSISRC)image-png.c - + $(LIBCUPSIOBJ)image-pnm.$(OBJ) : $(LIBCUPSISRC)image-pnm.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-pnm.$(OBJ) $(C_) $(LIBCUPSISRC)image-pnm.c - + $(LIBCUPSIOBJ)image-sgi.$(OBJ) : $(LIBCUPSISRC)image-sgi.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-sgi.$(OBJ) $(C_) $(LIBCUPSISRC)image-sgi.c - + $(LIBCUPSIOBJ)image-sgilib.$(OBJ) : $(LIBCUPSISRC)image-sgilib.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-sgilib.$(OBJ) $(C_) $(LIBCUPSISRC)image-sgilib.c - + $(LIBCUPSIOBJ)image-sun.$(OBJ) : $(LIBCUPSISRC)image-sun.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-sun.$(OBJ) $(C_) $(LIBCUPSISRC)image-sun.c - + $(LIBCUPSIOBJ)image-tiff.$(OBJ) : $(LIBCUPSISRC)image-tiff.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-tiff.$(OBJ) $(C_) $(LIBCUPSISRC)image-tiff.c - + $(LIBCUPSIOBJ)image-zoom.$(OBJ) : $(LIBCUPSISRC)image-zoom.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-zoom.$(OBJ) $(C_) $(LIBCUPSISRC)image-zoom.c - + $(LIBCUPSIOBJ)image.$(OBJ) : $(LIBCUPSISRC)image.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image.$(OBJ) $(C_) $(LIBCUPSISRC)image.c - + $(LIBCUPSIOBJ)error.$(OBJ) : $(LIBCUPSISRC)error.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)error.$(OBJ) $(C_) $(LIBCUPSISRC)error.c - + $(LIBCUPSIOBJ)interpret.$(OBJ) : $(LIBCUPSISRC)interpret.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)interpret.$(OBJ) $(C_) $(LIBCUPSISRC)interpret.c - + $(LIBCUPSIOBJ)cupsraster.$(OBJ) : $(LIBCUPSISRC)cupsraster.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)cupsraster.$(OBJ) $(C_) $(LIBCUPSISRC)cupsraster.c - + diff --git a/base/ldf_jb2.mak b/base/ldf_jb2.mak deleted file mode 100644 index 5005d80a..00000000 --- a/base/ldf_jb2.mak +++ /dev/null @@ -1,497 +0,0 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. -# All Rights Reserved. -# -# This software is provided AS-IS with no warranty, either express or -# implied. -# -# This software is distributed under license and may not be copied, -# modified or distributed except as expressly authorized under the terms -# of the license contained in the file LICENSE in this distribution. -# -# Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, -# CA 94945, U.S.A., +1(415)492-9861, for further information. -# - -# makefile for Luratech ldf_jb2 library code. -# Users of this makefile must define the following: -# SHARE_JBIG2 - whether to compile in or link to the library -# JBIG2SRCDIR - the library source directory -# -# gs.mak and friends define the following: -# JBIG2OBJDIR - the output obj directory -# JBIG2GENDIR - generated (.dev) file directory -# LDF_JB2I_ - include path for the library -# JB2CF_ - cflags for building the library -# -# We define the ldf_jb2.dev target and its dependencies -# -# This partial makefile compiles the ldf_jb2 library for use in -# Ghostscript. - -LDF_JB2_MAK=$(GLSRC)ldf_jb2.mak $(TOP_MAKEFILES) - -LDF_JB2_SRC=$(JBIG2SRCDIR)$(D) -LDF_JB2_GEN=$(JBIG2OBJDIR)$(D) -LDF_JB2_OBJ=$(JBIG2OBJDIR)$(D) - -# paths to source directories -LDF_JB2_COMMON=$(JBIG2SRCDIR)$(D)source$(D)common$(D) -LDF_JB2_COMPRESS=$(JBIG2SRCDIR)$(D)source$(D)compress$(D) - - -# source files to build from the CSDK source - -ldf_jb2_common_OBJS = \ - $(LDF_JB2_OBJ)jb2_adt_cache.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_context_buffer.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_context_decoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_context_ref_buffer.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_context_ref_decoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_decoder_collective_bitmap.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_decoder_generic_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_decoder_halftone_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_decoder_pattern_dict.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_decoder_symbol_dict.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_decoder_text_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_external_cache.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_file.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_file_extras.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_handle_document.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_huffman_decoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_huffman_table.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_huffman_table_standard.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_huffman_table_symbol.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_huffman_table_user_defined.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_huffman_tree.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_location.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_memory.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_message.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_mmr_decoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_mmr_tables.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_mq_decoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_mq_state.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_pattern_dict.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_pdf_file.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_pdf_stream.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_props_decompress.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_read_bit_buffer.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_read_data.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_render_common.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_render_generic_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_render_halftone_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_render_text_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_array.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_end_of_stripe.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_generic_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_halftone_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_page_info.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_pattern_dict.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_symbol_dict.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_table.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_text_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_segment_types.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_symbol.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_symbol_dict.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_symbol_instance.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_write_bits.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_write_data.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_write_pdf.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_common.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_license_dummy.$(OBJ) - -ldf_jb2_compress_OBJS = \ - $(LDF_JB2_OBJ)jb2_adt_component.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_component_class.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_component_group.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_component_match.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_context_encoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_context_ref_encoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_encoder_generic_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_encoder_symbol_dict.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_encoder_text_region.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_handle_compress.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_huffman_encoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_mmr_encoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_mq_encoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_props_compress.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_run_array.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_stack.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_stripe_clean_up.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_stripe_encoder.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_stripe_half_tone.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_stripe_preprocessing.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_stripe_text.$(OBJ) \ - $(LDF_JB2_OBJ)jb2_adt_symbol_unify.$(OBJ) - -ldf_jb2_common_HDRS = \ - $(LDF_JB2_COMMON)jb2_adt_cache.h \ - $(LDF_JB2_COMMON)jb2_adt_context_buffer.h \ - $(LDF_JB2_COMMON)jb2_adt_context_decoder.h \ - $(LDF_JB2_COMMON)jb2_adt_context_ref_buffer.h \ - $(LDF_JB2_COMMON)jb2_adt_context_ref_decoder.h \ - $(LDF_JB2_COMMON)jb2_adt_decoder_collective_bitmap.h \ - $(LDF_JB2_COMMON)jb2_adt_decoder_generic_region.h \ - $(LDF_JB2_COMMON)jb2_adt_decoder_halftone_region.h \ - $(LDF_JB2_COMMON)jb2_adt_decoder_pattern_dict.h \ - $(LDF_JB2_COMMON)jb2_adt_decoder_symbol_dict.h \ - $(LDF_JB2_COMMON)jb2_adt_decoder_text_region.h \ - $(LDF_JB2_COMMON)jb2_adt_external_cache.h \ - $(LDF_JB2_COMMON)jb2_adt_file.h \ - $(LDF_JB2_COMMON)jb2_adt_file_extras.h \ - $(LDF_JB2_COMMON)jb2_adt_huffman_decoder.h \ - $(LDF_JB2_COMMON)jb2_adt_huffman_table.h \ - $(LDF_JB2_COMMON)jb2_adt_huffman_table_entry.h \ - $(LDF_JB2_COMMON)jb2_adt_huffman_table_standard.h \ - $(LDF_JB2_COMMON)jb2_adt_huffman_table_symbol.h \ - $(LDF_JB2_COMMON)jb2_adt_huffman_table_user_defined.h \ - $(LDF_JB2_COMMON)jb2_adt_huffman_tree.h \ - $(LDF_JB2_COMMON)jb2_adt_location.h \ - $(LDF_JB2_COMMON)jb2_adt_memory.h \ - $(LDF_JB2_COMMON)jb2_adt_message.h \ - $(LDF_JB2_COMMON)jb2_adt_mmr_decoder.h \ - $(LDF_JB2_COMMON)jb2_adt_mmr_tables.h \ - $(LDF_JB2_COMMON)jb2_adt_mq_decoder.h \ - $(LDF_JB2_COMMON)jb2_adt_mq_ids.h \ - $(LDF_JB2_COMMON)jb2_adt_mq_state.h \ - $(LDF_JB2_COMMON)jb2_adt_pattern_dict.h \ - $(LDF_JB2_COMMON)jb2_adt_pdf_file.h \ - $(LDF_JB2_COMMON)jb2_adt_pdf_stream.h \ - $(LDF_JB2_COMMON)jb2_adt_props_decompress.h \ - $(LDF_JB2_COMMON)jb2_adt_read_bit_buffer.h \ - $(LDF_JB2_COMMON)jb2_adt_read_data.h \ - $(LDF_JB2_COMMON)jb2_adt_render_common.h \ - $(LDF_JB2_COMMON)jb2_adt_render_generic_region.h \ - $(LDF_JB2_COMMON)jb2_adt_render_halftone_region.h \ - $(LDF_JB2_COMMON)jb2_adt_render_text_region.h \ - $(LDF_JB2_COMMON)jb2_adt_segment.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_array.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_end_of_file.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_end_of_page.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_end_of_stripe.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_generic_region.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_halftone_region.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_page_info.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_pattern_dict.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_region.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_symbol_dict.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_table.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_text_region.h \ - $(LDF_JB2_COMMON)jb2_adt_segment_types.h \ - $(LDF_JB2_COMMON)jb2_adt_symbol.h \ - $(LDF_JB2_COMMON)jb2_adt_symbol_array.h \ - $(LDF_JB2_COMMON)jb2_adt_symbol_dict.h \ - $(LDF_JB2_COMMON)jb2_adt_symbol_instance.h \ - $(LDF_JB2_COMMON)jb2_adt_symbol_instance_array.h \ - $(LDF_JB2_COMMON)jb2_adt_write_bits.h \ - $(LDF_JB2_COMMON)jb2_adt_write_data.h \ - $(LDF_JB2_COMMON)jb2_adt_write_pdf.h \ - $(LDF_JB2_COMMON)jb2_common.h \ - $(LDF_JB2_COMMON)jb2_defines.h \ - $(LDF_JB2_COMMON)jb2_license.h - -ldf_jb2_compress_HDRS = \ - $(LDF_JB2_COMPRESS)jb2_adt_run_array.h \ - $(LDF_JB2_COMPRESS)jb2_adt_encoder_text_region.h \ - $(LDF_JB2_COMPRESS)jb2_adt_context_ref_encoder.h \ - $(LDF_JB2_COMPRESS)jb2_adt_encoder_generic_region.h \ - $(LDF_JB2_COMPRESS)jb2_adt_props_compress.h \ - $(LDF_JB2_COMPRESS)jb2_adt_component_match.h \ - $(LDF_JB2_COMPRESS)jb2_adt_symbol_unify.h \ - $(LDF_JB2_COMPRESS)jb2_adt_huffman_encoder.h \ - $(LDF_JB2_COMPRESS)jb2_adt_stripe_half_tone.h \ - $(LDF_JB2_COMPRESS)jb2_adt_component.h \ - $(LDF_JB2_COMPRESS)jb2_adt_stripe_clean_up.h \ - $(LDF_JB2_COMPRESS)jb2_adt_run.h \ - $(LDF_JB2_COMPRESS)jb2_adt_stripe_text.h \ - $(LDF_JB2_COMPRESS)jb2_adt_stack.h \ - $(LDF_JB2_COMPRESS)jb2_adt_component_group.h \ - $(LDF_JB2_COMPRESS)jb2_adt_encoder_symbol_dict.h \ - $(LDF_JB2_COMPRESS)jb2_adt_context_encoder.h \ - $(LDF_JB2_COMPRESS)jb2_adt_component_array.h \ - $(LDF_JB2_COMPRESS)jb2_adt_mq_encoder.h \ - $(LDF_JB2_COMPRESS)jb2_adt_mmr_encoder.h \ - $(LDF_JB2_COMPRESS)jb2_adt_stripe_preprocessing.h \ - $(LDF_JB2_COMPRESS)jb2_adt_component_class.h \ - $(LDF_JB2_COMPRESS)jb2_adt_stripe_encoder.h - - -ldf_jb2_OBJS=$(ldf_jb2_common_OBJS) $(ldf_jb2_compress_OBJS) -ldf_jb2_HDRS=$(ldf_jb2_common_HDRS) $(ldf_jb2_compress_HDRS) - -# switch in the selected library .dev -$(LDF_JB2_GEN)ldf_jb2.dev : $(LDF_JB2_GEN)ldf_jb2_$(SHARE_JBIG2).dev \ - $(LDF_JB2_MAK) $(MAKEDIRS) - $(CP_) $(LDF_JB2_GEN)ldf_jb2_$(SHARE_JBIG2).dev $(LDF_JB2_GEN)ldf_jb2.dev - -# external link .dev -$(LDF_JB2_GEN)ldf_jb2_1.dev : $(ECHOGS_XE) \ - $(LDF_JB2_MAK) $(MAKEDIRS) - $(SETMOD) $(LDF_JB2_GEN)ldf_jb2_1 -lib ldf_jb2 - -# compile our own .dev -$(LDF_JB2_GEN)ldf_jb2_0.dev : $(ECHOGS_XE) $(ldf_jb2_OBJS) \ - $(LDF_JB2_MAK) $(MAKEDIRS) - $(SETMOD) $(LDF_JB2_GEN)ldf_jb2_0 $(ldf_jb2_common_OBJS) - $(ADDMOD) $(LDF_JB2_GEN)ldf_jb2_0 $(ldf_jb2_compress_OBJS) - -# define our specific compiler -LDF_JB2_CC=$(CC_) $(I_)$(LDF_JB2I_) $(II)$(LDF_JB2_COMMON) $(II)$(LDF_JB2_COMPRESS)$(_I) $(JB2CF_) -LDF_JB2_O=$(O_)$(LDF_JB2_OBJ) - -LDF_JB2_DEP=$(AK) $(LDF_JB2_MAK) $(MAKEDIRS) - - -# explicit rules for building each source file -# for simplicity we have every source file depend on all headers - -$(LDF_JB2_OBJ)jb2_adt_cache.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_cache.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_cache.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_cache.c - -$(LDF_JB2_OBJ)jb2_adt_context_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_buffer.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_buffer.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_buffer.c - -$(LDF_JB2_OBJ)jb2_adt_context_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_decoder.c - -$(LDF_JB2_OBJ)jb2_adt_context_ref_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_ref_buffer.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_ref_buffer.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_ref_buffer.c - -$(LDF_JB2_OBJ)jb2_adt_context_ref_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_ref_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_ref_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_ref_decoder.c - -$(LDF_JB2_OBJ)jb2_adt_decoder_collective_bitmap.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_collective_bitmap.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_collective_bitmap.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_collective_bitmap.c - -$(LDF_JB2_OBJ)jb2_adt_decoder_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_generic_region.c - -$(LDF_JB2_OBJ)jb2_adt_decoder_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_halftone_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_halftone_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_halftone_region.c - -$(LDF_JB2_OBJ)jb2_adt_decoder_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_pattern_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_pattern_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_pattern_dict.c - -$(LDF_JB2_OBJ)jb2_adt_decoder_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_symbol_dict.c - -$(LDF_JB2_OBJ)jb2_adt_decoder_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_text_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_text_region.c - -$(LDF_JB2_OBJ)jb2_adt_external_cache.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_external_cache.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_external_cache.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_external_cache.c - -$(LDF_JB2_OBJ)jb2_adt_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_file.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_file.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_file.c - -$(LDF_JB2_OBJ)jb2_adt_file_extras.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_file_extras.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_file_extras.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_file_extras.c - -$(LDF_JB2_OBJ)jb2_adt_handle_document.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_handle_document.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_handle_document.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_handle_document.c - -$(LDF_JB2_OBJ)jb2_adt_huffman_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_decoder.c - -$(LDF_JB2_OBJ)jb2_adt_huffman_table.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table.c - -$(LDF_JB2_OBJ)jb2_adt_huffman_table_standard.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_standard.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table_standard.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table_standard.c - -$(LDF_JB2_OBJ)jb2_adt_huffman_table_symbol.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_symbol.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table_symbol.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table_symbol.c - -$(LDF_JB2_OBJ)jb2_adt_huffman_table_user_defined.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_user_defined.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table_user_defined.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table_user_defined.c - -$(LDF_JB2_OBJ)jb2_adt_huffman_tree.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_tree.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_tree.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_tree.c - -$(LDF_JB2_OBJ)jb2_adt_location.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_location.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_location.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_location.c - -$(LDF_JB2_OBJ)jb2_adt_memory.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_memory.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_memory.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_memory.c - -$(LDF_JB2_OBJ)jb2_adt_message.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_message.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_message.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_message.c - -$(LDF_JB2_OBJ)jb2_adt_mmr_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mmr_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mmr_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mmr_decoder.c - -$(LDF_JB2_OBJ)jb2_adt_mmr_tables.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mmr_tables.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mmr_tables.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mmr_tables.c - -$(LDF_JB2_OBJ)jb2_adt_mq_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mq_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mq_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mq_decoder.c - -$(LDF_JB2_OBJ)jb2_adt_mq_state.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mq_state.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mq_state.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mq_state.c - -$(LDF_JB2_OBJ)jb2_adt_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pattern_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_pattern_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_pattern_dict.c - -$(LDF_JB2_OBJ)jb2_adt_pdf_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pdf_file.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_pdf_file.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_pdf_file.c - -$(LDF_JB2_OBJ)jb2_adt_pdf_stream.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pdf_stream.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_pdf_stream.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_pdf_stream.c - -$(LDF_JB2_OBJ)jb2_adt_props_decompress.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_props_decompress.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_props_decompress.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_props_decompress.c - -$(LDF_JB2_OBJ)jb2_adt_read_bit_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_read_bit_buffer.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_read_bit_buffer.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_read_bit_buffer.c - -$(LDF_JB2_OBJ)jb2_adt_read_data.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_read_data.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_read_data.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_read_data.c - -$(LDF_JB2_OBJ)jb2_adt_render_common.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_common.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_common.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_common.c - -$(LDF_JB2_OBJ)jb2_adt_render_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_generic_region.c - -$(LDF_JB2_OBJ)jb2_adt_render_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_halftone_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_halftone_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_halftone_region.c - -$(LDF_JB2_OBJ)jb2_adt_render_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_text_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_text_region.c - -$(LDF_JB2_OBJ)jb2_adt_segment.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment.c - -$(LDF_JB2_OBJ)jb2_adt_segment_array.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_array.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_array.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_array.c - -$(LDF_JB2_OBJ)jb2_adt_segment_end_of_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_file.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_end_of_file.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_end_of_file.c - -$(LDF_JB2_OBJ)jb2_adt_segment_end_of_page.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_page.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_end_of_page.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_end_of_page.c - -$(LDF_JB2_OBJ)jb2_adt_segment_end_of_stripe.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_stripe.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_end_of_stripe.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_end_of_stripe.c - -$(LDF_JB2_OBJ)jb2_adt_segment_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_generic_region.c - -$(LDF_JB2_OBJ)jb2_adt_segment_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_halftone_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_halftone_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_halftone_region.c - -$(LDF_JB2_OBJ)jb2_adt_segment_page_info.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_page_info.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_page_info.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_page_info.c - -$(LDF_JB2_OBJ)jb2_adt_segment_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_pattern_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_pattern_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_pattern_dict.c - -$(LDF_JB2_OBJ)jb2_adt_segment_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_region.c - -$(LDF_JB2_OBJ)jb2_adt_segment_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_symbol_dict.c - -$(LDF_JB2_OBJ)jb2_adt_segment_table.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_table.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_table.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_table.c - -$(LDF_JB2_OBJ)jb2_adt_segment_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_text_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_text_region.c - -$(LDF_JB2_OBJ)jb2_adt_segment_types.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_types.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_types.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_types.c - -$(LDF_JB2_OBJ)jb2_adt_symbol.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_symbol.c - -$(LDF_JB2_OBJ)jb2_adt_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_symbol_dict.c - -$(LDF_JB2_OBJ)jb2_adt_symbol_instance.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol_instance.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol_instance.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_symbol_instance.c - -$(LDF_JB2_OBJ)jb2_adt_write_bits.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_bits.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_write_bits.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_write_bits.c - -$(LDF_JB2_OBJ)jb2_adt_write_data.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_data.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_write_data.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_write_data.c - -$(LDF_JB2_OBJ)jb2_adt_write_pdf.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_pdf.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_write_pdf.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_write_pdf.c - -$(LDF_JB2_OBJ)jb2_common.$(OBJ) : $(LDF_JB2_COMMON)jb2_common.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_common.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_common.c - -$(LDF_JB2_OBJ)jb2_license_dummy.$(OBJ) : $(LDF_JB2_COMMON)jb2_license_dummy.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_license_dummy.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_license_dummy.c - -$(LDF_JB2_OBJ)jb2_adt_component.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component.c - -$(LDF_JB2_OBJ)jb2_adt_component_class.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_class.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component_class.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component_class.c - -$(LDF_JB2_OBJ)jb2_adt_component_group.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_group.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component_group.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component_group.c - -$(LDF_JB2_OBJ)jb2_adt_component_match.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_match.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component_match.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component_match.c - -$(LDF_JB2_OBJ)jb2_adt_context_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_context_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_context_encoder.c - -$(LDF_JB2_OBJ)jb2_adt_context_ref_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_context_ref_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_ref_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_context_ref_encoder.c - -$(LDF_JB2_OBJ)jb2_adt_encoder_generic_region.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_encoder_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_encoder_generic_region.c - -$(LDF_JB2_OBJ)jb2_adt_encoder_symbol_dict.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_encoder_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_encoder_symbol_dict.c - -$(LDF_JB2_OBJ)jb2_adt_encoder_text_region.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_encoder_text_region.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_encoder_text_region.c - -$(LDF_JB2_OBJ)jb2_adt_handle_compress.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_handle_compress.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_handle_compress.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_handle_compress.c - -$(LDF_JB2_OBJ)jb2_adt_huffman_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_huffman_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_huffman_encoder.c - -$(LDF_JB2_OBJ)jb2_adt_mmr_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_mmr_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mmr_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_mmr_encoder.c - -$(LDF_JB2_OBJ)jb2_adt_mq_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_mq_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mq_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_mq_encoder.c - -$(LDF_JB2_OBJ)jb2_adt_props_compress.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_props_compress.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_props_compress.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_props_compress.c - -$(LDF_JB2_OBJ)jb2_adt_run_array.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_run_array.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_run_array.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_run_array.c - -$(LDF_JB2_OBJ)jb2_adt_stack.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stack.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stack.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stack.c - -$(LDF_JB2_OBJ)jb2_adt_stripe_clean_up.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_clean_up.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_clean_up.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_clean_up.c - -$(LDF_JB2_OBJ)jb2_adt_stripe_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_encoder.c - -$(LDF_JB2_OBJ)jb2_adt_stripe_half_tone.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_half_tone.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_half_tone.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_half_tone.c - -$(LDF_JB2_OBJ)jb2_adt_stripe_preprocessing.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_preprocessing.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_preprocessing.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_preprocessing.c - -$(LDF_JB2_OBJ)jb2_adt_stripe_text.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_text.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_text.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_text.c - -$(LDF_JB2_OBJ)jb2_adt_symbol_unify.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_symbol_unify.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) - $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol_unify.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_symbol_unify.c - - -# end of file diff --git a/base/leptonica.mak b/base/leptonica.mak index 0929e376..df72241d 100644 --- a/base/leptonica.mak +++ b/base/leptonica.mak @@ -108,9 +108,6 @@ $(LEPTOBJ)classapp.$(OBJ) : $(LEPTONICADIR)/src/classapp.c $(LEPTDEPS) $(LEPTOBJ)colorcontent.$(OBJ) : $(LEPTONICADIR)/src/colorcontent.c $(LEPTDEPS) $(LEPTCC) $(LEPTO_)colorcontent.$(OBJ) $(C_) $(LEPTONICADIR)/src/colorcontent.c -$(LEPTOBJ)colorinfo.$(OBJ) : $(LEPTONICADIR)/src/colorinfo.c $(LEPTDEPS) - $(LEPTCC) $(LEPTO_)colorinfo.$(OBJ) $(C_) $(LEPTONICADIR)/src/colorinfo.c - $(LEPTOBJ)coloring.$(OBJ) : $(LEPTONICADIR)/src/coloring.c $(LEPTDEPS) $(LEPTCC) $(LEPTO_)coloring.$(OBJ) $(C_) $(LEPTONICADIR)/src/coloring.c @@ -515,7 +512,6 @@ LEPTONICA_OBJS=\ $(LEPTOBJ)ccbord.$(OBJ)\ $(LEPTOBJ)classapp.$(OBJ)\ $(LEPTOBJ)colorcontent.$(OBJ)\ - $(LEPTOBJ)colorinfo.$(OBJ)\ $(LEPTOBJ)coloring.$(OBJ)\ $(LEPTOBJ)colormap.$(OBJ)\ $(LEPTOBJ)colormorph.$(OBJ)\ diff --git a/base/lib.mak b/base/lib.mak index 0c2dffb9..f6845c97 100644 --- a/base/lib.mak +++ b/base/lib.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -44,14 +44,17 @@ GLINCLUDES=$(I_)$(GLI_)$(_I) GLCCFLAGS=$(GLINCLUDES) $(GLF_) $(D_)WHICH_CMS="$(WHICH_CMS)"$(_D) GLCC=$(CC_) $(GLCCFLAGS) GLCCAUX=$(CCAUX_) $(GLCCFLAGS) -GLJCC=$(CC_) $(I_)$(GLI_) $(II)$(JI_)$(_I) $(JCF_) $(GLF_) -GLZCC=$(CC_) $(I_)$(GLI_) $(II)$(ZI_)$(_I) $(ZCF_) $(GLF_) -GLJBIG2CC=$(CC_) $(I_)$(GLI_) $(II)$(JB2I_)$(_I) $(JB2CF_) $(GLF_) -GLJASCC=$(CC_) $(I_)$(JPXI_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_) GLLDFJB2CC=$(CC_) $(I_)$(LDF_JB2I_) $(II)$(GLI_)$(_I) $(JB2CF_) $(GLF_) GLLWFJPXCC=$(CC_) $(I_)$(LWF_JPXI_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_) -GLJPXOPJCC=$(CC_) $(I_)$(JPX_OPENJPEG_I_)$(D).. $(I_)$(JPX_OPENJPEG_I_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_) GLCCSHARED=$(CC_SHARED) $(GLCCFLAGS) + +GLJCC=$(CC) $(I_)$(GLI_) $(II)$(JI_)$(_I) $(JCF_) $(GLF_) $(CCFLAGS) +GLZCC=$(CC) $(I_)$(GLI_) $(II)$(ZI_)$(_I) $(ZCF_) $(GLF_) $(CCFLAGS) +GLJBIG2CC=$(CC) $(I_)$(GLI_) $(II)$(JB2I_)$(_I) $(JB2CF_) $(GLF_) $(CCFLAGS) +GLJASCC=$(CC) $(I_)$(JPXI_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_) $(CCFLAGS) +GLJPXOPJCC=$(CC) $(I_)$(JPX_OPENJPEG_I_)$(D).. $(I_)$(JPX_OPENJPEG_I_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_) $(CCFLAGS) +GLFTCC=$(CC) $(FT_CFLAGS) $(D_)FT_CONFIG_OPTIONS_H=\"$(FTCONFH)\"$(_D) $(CCFLAGS) $(GLCCFLAGS) + # We can't use $(CC_) for GLLCMS2MTCC because that includes /Za on # msvc builds, and lcms configures itself to depend on msvc extensions # (inline asm, including windows.h) when compiled under msvc. @@ -383,7 +386,7 @@ $(GLOBJ)gsserial.$(OBJ) : $(GLSRC)gsserial.c $(stdpre_h) $(gstypes_h)\ $(GLOBJ)gsutil.$(OBJ) : $(GLSRC)gsutil.c $(AK) $(memory__h)\ $(string__h) $(gstypes_h) $(gserrors_h) $(gsmemory_h)\ - $(gsrect_h) $(gsuid_h) $(gsutil_h) $(LIB_MAK) $(MAKEDIRS) + $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gxsync_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsutil.$(OBJ) $(C_) $(GLSRC)gsutil.c $(AUX)gsutil.$(OBJ) : $(GLSRC)gsutil.c $(AK) $(memory__h) $(string__h)\ @@ -594,8 +597,6 @@ smd5_h=$(GLSRC)smd5.h sarc4_h=$(GLSRC)sarc4.h saes_h=$(GLSRC)saes.h sjbig2_h=$(GLSRC)sjbig2.h -sjbig2_luratech_h=$(GLSRC)sjbig2_luratech.h $(scommon_h) -sjpx_luratech_h=$(GLSRC)sjpx_luratech.h $(scommon_h) sjpx_openjpeg_h=$(GLSRC)sjpx_openjpeg.h $(scommon_h) $(openjpeg_h) spdiffx_h=$(GLSRC)spdiffx.h spngpx_h=$(GLSRC)spngpx.h @@ -644,6 +645,8 @@ gdevdevnprn_h=$(GLSRC)gdevdevnprn.h gdevoflt_h=$(GLSRC)gdevoflt.h +gdevnup_h=$(GLSRC)gdevnup.h + png__h=$(GLSRC)png_.h $(MAKEFILE) x__h=$(GLSRC)x_.h @@ -676,8 +679,8 @@ $(GLOBJ)gxacpath.$(OBJ) : $(GLSRC)gxacpath.c $(AK) $(gx_h)\ $(gzacpath_h) $(gzcpath_h) $(gzpath_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxacpath.$(OBJ) $(C_) $(GLSRC)gxacpath.c -$(GLOBJ)gxbcache.$(OBJ) : $(GLSRC)gxbcache.c $(AK) $(gx_h) $(memory__h)\ - $(gsmdebug_h) $(gxbcache_h) $(LIB_MAK) $(MAKEDIRS) +$(GLOBJ)gxbcache.$(OBJ) : $(GLSRC)gxbcache.c $(AK) $(gx_h) $(gxobj_h) \ + $(memory__h) $(gsmdebug_h) $(gxbcache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxbcache.$(OBJ) $(C_) $(GLSRC)gxbcache.c $(GLOBJ)gxccache.$(OBJ) : $(GLSRC)gxccache.c $(AK) $(gx_h)\ @@ -693,7 +696,8 @@ $(GLOBJ)gxccman.$(OBJ) : $(GLSRC)gxccman.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gpcheck_h)\ $(gsbitops_h) $(gsstruct_h) $(gsutil_h) $(gxfixed_h) $(gxmatrix_h)\ $(gxdevice_h) $(gxdevmem_h) $(gxfont_h) $(gxfcache_h) $(gxchar_h)\ - $(gxpath_h) $(gxxfont_h) $(gzstate_h) $(gxttfb_h) $(gxfont42_h) $(LIB_MAK) $(MAKEDIRS) + $(gxpath_h) $(gxxfont_h) $(gzstate_h) $(gxttfb_h) $(gxfont42_h) $(gxobj_h) \ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxccman.$(OBJ) $(C_) $(GLSRC)gxccman.c $(GLOBJ)gxchar.$(OBJ) : $(GLSRC)gxchar.c $(AK) $(gx_h) $(gserrors_h)\ @@ -765,7 +769,7 @@ $(GLOBJ)gxht.$(OBJ) : $(GLSRC)gxht.c $(AK) $(gx_h) $(gserrors_h)\ $(GLOBJ)gxhtbit.$(OBJ) : $(GLSRC)gxhtbit.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsbitops_h) $(gscdefs_h)\ - $(gxbitmap_h) $(gxdht_h) $(gxdhtres_h) $(gxhttile_h) $(gxtmap_h) $(LIB_MAK) $(MAKEDIRS) + $(gxbitmap_h) $(gxdht_h) $(gxdhtres_h) $(gxhttile_h) $(gxtmap_h) $(gp_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxhtbit.$(OBJ) $(C_) $(GLSRC)gxhtbit.c $(GLOBJ)gxht_thresh.$(OBJ) : $(GLSRC)gxht_thresh.c $(AK) $(memory__h)\ @@ -983,7 +987,7 @@ $(GLOBJ)gsdevmem.$(OBJ) : $(GLSRC)gsdevmem.c $(AK) $(gx_h)\ $(GLOBJ)gsdparam.$(OBJ) : $(GLSRC)gsdparam.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(string__h)\ - $(gsdevice_h) $(gsparam_h) $(gxdevice_h) $(gxfixed_h)\ + $(gsdevice_h) $(gsparam_h) $(gsparamx_h) $(gxdevice_h) $(gxfixed_h)\ $(gsicc_manage_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsdparam.$(OBJ) $(C_) $(GLSRC)gsdparam.c @@ -1009,7 +1013,7 @@ $(GLOBJ)gsgcache.$(OBJ) : $(GLSRC)gsgcache.c $(AK) $(gx_h)\ $(GLOBJ)gsht.$(OBJ) : $(GLSRC)gsht.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxarith_h)\ - $(gxdevice_h) $(gzht_h) $(gzstate_h) $(gxfmap_h) $(LIB_MAK) $(MAKEDIRS) + $(gxdevice_h) $(gzht_h) $(gzstate_h) $(gxfmap_h) $(gp_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsht.$(OBJ) $(C_) $(GLSRC)gsht.c $(GLOBJ)gshtscr.$(OBJ) : $(GLSRC)gshtscr.c $(AK) $(gx_h) $(gserrors_h)\ @@ -1065,7 +1069,6 @@ $(GLOBJ)gsparam.$(OBJ) : $(GLSRC)gsparam.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gsparam_h) $(gsstruct_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsparam.$(OBJ) $(C_) $(GLSRC)gsparam.c -# gsparamx is not included in the base configuration. $(GLOBJ)gsparamx.$(OBJ) : $(AK) $(GLSRC)gsparamx.c $(string__h)\ $(gserrors_h) $(gsmemory_h) $(gsparam_h) $(gsparamx_h)\ $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) @@ -1102,7 +1105,8 @@ $(GLOBJ)gsstate.$(OBJ) : $(GLSRC)gsstate.c $(AK) $(gx_h) $(gserrors_h)\ $(GLOBJ)gstext.$(OBJ) : $(GLSRC)gstext.c $(AK) $(memory__h) $(gdebug_h)\ $(gserrors_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h)\ $(gxfcache_h) $(gxdevcli_h) $(gxdcolor_h) $(gxfont_h) $(gxpath_h)\ - $(gxtext_h) $(gzstate_h) $(gsutil_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) + $(gxtext_h) $(gzstate_h) $(gsutil_h) $(gxdevsop_h)\ + $(gscspace_h) $(gsicc_blacktext_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gstext.$(OBJ) $(C_) $(GLSRC)gstext.c # We make gsiodevs a separate module so the PS interpreter can replace it. @@ -1326,7 +1330,7 @@ $(GLOBJ)fapi_ft_0.$(OBJ) : $(GLSRC)fapi_ft.c $(AK)\ $(gsmemory_h) $(gsmalloc_h) $(gxfixed_h) $(gdebug_h) $(gxbitmap_h)\ $(gsmchunk_h) $(stream_h) $(gxiodev_h) $(gsfname_h) $(gxfapi_h) $(gxfont1_h)\ $(gxfont_h) $(BASEFTCONFH) $(LIB_MAK) $(MAKEDIRS) - $(GLCC) $(FT_CFLAGS) $(D_)FT_CONFIG_OPTIONS_H=\"$(FTCONFH)\"$(_D) $(GLO_)fapi_ft_0.$(OBJ) $(C_) $(GLSRC)fapi_ft.c + $(GLFTCC) $(FT_CFLAGS) $(D_)FT_CONFIG_OPTIONS_H=\"$(FTCONFH)\"$(_D) $(GLO_)fapi_ft_0.$(OBJ) $(C_) $(GLSRC)fapi_ft.c $(GLOBJ)fapi_ft_1.$(OBJ) : $(GLSRC)fapi_ft.c $(AK)\ $(stdio__h) $(malloc__h) $(write_t1_h) $(write_t2_h) $(math__h) $(gserrors_h)\ @@ -1414,7 +1418,7 @@ $(GLOBJ)gxdownscale.$(OBJ) : $(GLOBJ)gxdownscale_$(WITH_CAL).$(OBJ) $(AK) $(gp_h LIB0s=$(GLOBJ)gpmisc.$(OBJ) $(GLOBJ)stream.$(OBJ) $(GLOBJ)strmio.$(OBJ) LIB1s=$(GLOBJ)gsalloc.$(OBJ) $(GLOBJ)gxdownscale.$(OBJ) $(downscale_) $(GLOBJ)gdevprn.$(OBJ) $(GLOBJ)gdevflp.$(OBJ) $(GLOBJ)gdevkrnlsclass.$(OBJ) $(GLOBJ)gdevepo.$(OBJ) -LIB2s=$(GLOBJ)gdevmplt.$(OBJ) $(GLOBJ)gsbitcom.$(OBJ) $(GLOBJ)gsbitops.$(OBJ) $(GLOBJ)gsbittab.$(OBJ) $(GLOBJ)gdevoflt.$(OBJ) $(GLOBJ)gdevsclass.$(OBJ) +LIB2s=$(GLOBJ)gdevmplt.$(OBJ) $(GLOBJ)gsbitcom.$(OBJ) $(GLOBJ)gsbitops.$(OBJ) $(GLOBJ)gsbittab.$(OBJ) $(GLOBJ)gdevoflt.$(OBJ) $(GLOBJ)gdevnup.$(OBJ) $(GLOBJ)gdevsclass.$(OBJ) # Note: gschar.c is no longer required for a standard build; # we include it only for backward compatibility for library clients. LIB3s=$(GLOBJ)gscedata.$(OBJ) $(GLOBJ)gscencs.$(OBJ) $(GLOBJ)gschar.$(OBJ) $(GLOBJ)gscolor.$(OBJ) @@ -1849,22 +1853,6 @@ $(GLOBJ)snojbig2.$(OBJ) : $(GLSRC)snojbig2.c $(AK) \ $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLJBIG2CC) $(GLO_)snojbig2.$(OBJ) $(C_) $(GLSRC)snojbig2.c -# luratech version -sjbig2_luratech=$(GLOBJ)sjbig2_luratech.$(OBJ) - -$(GLD)sjbig2_luratech.dev : $(LIB_MAK) $(ECHOGS_XE) \ - $(GLD)ldf_jb2.dev $(sjbig2_luratech) - $(SETMOD) $(GLD)sjbig2_luratech $(sjbig2_luratech) - $(ADDMOD) $(GLD)sjbig2_luratech -include $(GLD)ldf_jb2.dev - -# ldf_jb2.dev is defined in jbig2_luratech.mak - -$(GLOBJ)sjbig2_luratech.$(OBJ) : $(GLSRC)sjbig2_luratech.c $(AK) \ - $(memory__h) $(malloc__h) $(gserrors_h) $(gdebug_h) \ - $(strimpl_h) $(sjbig2_luratech_h) $(LIB_MAK) $(MAKEDIRS) - $(GLLDFJB2CC) $(GLO_)sjbig2_luratech.$(OBJ) \ - $(C_) $(GLSRC)sjbig2_luratech.c - # ---------------- JPEG 2000 compression filter ---------------- # $(GLD)sjpx.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLD)sjpx_$(JPX_LIB).dev $(LIB_MAK) $(MAKEDIRS) @@ -1875,22 +1863,6 @@ $(GLOBJ)sjpx.$(OBJ) : $(GLSRC)sjpx.c $(AK) \ $(gdebug_h) $(strimpl_h) $(sjpx_h) $(LIB_MAK) $(MAKEDIRS) $(GLJASCC) $(GLO_)sjpx.$(OBJ) $(C_) $(GLSRC)sjpx.c -# luratech version -sjpx_luratech=$(GLOBJ)sjpx_luratech.$(OBJ) -$(GLD)sjpx_luratech.dev : $(LIB_MAK) $(ECHOGS_XE) \ - $(GLD)lwf_jp2.dev $(sjpx_luratech) $(LIB_MAK) $(MAKEDIRS) - $(SETMOD) $(GLD)sjpx_luratech $(sjpx_luratech) - $(ADDMOD) $(GLD)sjpx_luratech -include $(GLD)lwf_jp2.dev - -$(GLD)luratech_jp2.dev : $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) - $(SETMOD) $(GLD)luratech_jp2 $(GLD)liblwf_jp2.a - -$(GLOBJ)sjpx_luratech.$(OBJ) : $(GLSRC)sjpx_luratech.c $(AK) \ - $(memory__h) $(gserrors_h) \ - $(gdebug_h) $(strimpl_h) $(sjpx_luratech_h) $(LIB_MAK) $(MAKEDIRS) - $(GLLWFJPXCC) $(GLO_)sjpx_luratech.$(OBJ) \ - $(C_) $(GLSRC)sjpx_luratech.c - # openjpeg version sjpx_openjpeg=$(GLOBJ)sjpx_openjpeg.$(OBJ) $(GLD)sjpx_openjpeg.dev : $(LIB_MAK) $(ECHOGS_XE) \ @@ -2079,7 +2051,7 @@ gdevprn_h=$(GLSRC)gdevprn.h gdevmplt_h=$(GLSRC)gdevmplt.h page_=$(GLOBJ)gdevprn.$(OBJ) $(GLOBJ)gdevppla.$(OBJ) $(GLOBJ)gdevmplt.$(OBJ) $(GLOBJ)gdevflp.$(OBJ)\ - $(downscale_) $(GLOBJ)gdevoflt.$(OBJ) $(GLOBJ)gdevsclass.$(OBJ) $(GLOBJ)gdevepo.$(OBJ) + $(downscale_) $(GLOBJ)gdevoflt.$(OBJ) $(GLOBJ)gdevnup.$(OBJ) $(GLOBJ)gdevsclass.$(OBJ) $(GLOBJ)gdevepo.$(OBJ) $(GLD)page.dev : $(LIB_MAK) $(ECHOGS_XE) $(page_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)page $(page_) @@ -2118,6 +2090,12 @@ $(GLOBJ)gdevoflt.$(OBJ) : $(GLSRC)gdevoflt.c $(gdevoflt_h) $(gdevp14_h)\ $(gximage_h) $(gxiparam_h) $(gxpaint_h) $(gxpath_h) $(math__h) $(memory__h) $(GLCC) $(GLO_)gdevoflt.$(OBJ) $(C_) $(GLSRC)gdevoflt.c +$(GLOBJ)gdevnup.$(OBJ) : $(GLSRC)gdevnup.c $(gdevnup_h) $(gdevp14_h)\ + $(gdevprn_h) $(gdevsclass_h) $(gsdevice_h) $(gserrors_h) $(gsparam_h)\ + $(gsstype_h) $(gx_h) $(gxdevice_h)\ + $(math__h) $(memory__h) + $(GLCC) $(GLO_)gdevnup.$(OBJ) $(C_) $(GLSRC)gdevnup.c + $(GLOBJ)gdevsclass.$(OBJ) : $(GLSRC)gdevsclass.c $(gdevsclass_h) $(gdevp14_h)\ $(gdevprn_h) $(gsdevice_h) $(gserrors_h) $(gsparam_h) $(gsstype_h) $(gx_h)\ $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h) $(gxgstate_h)\ @@ -2174,7 +2152,7 @@ gxclpath_h=$(GLSRC)gxclpath.h clbase1_=$(GLOBJ)gxclist.$(OBJ) $(GLOBJ)gxclbits.$(OBJ) $(GLOBJ)gxclpage.$(OBJ) clbase2_=$(GLOBJ)gxclrast.$(OBJ) $(GLOBJ)gxclread.$(OBJ) $(GLOBJ)gxclrect.$(OBJ) -clbase3_=$(GLOBJ)gxclutil.$(OBJ) $(GLOBJ)gsparams.$(OBJ) $(GLOBJ)gsparaml.$(OBJ) $(GLOBJ)gxshade6.$(OBJ) +clbase3_=$(GLOBJ)gxclutil.$(OBJ) $(GLOBJ)gsparams.$(OBJ) $(GLOBJ)gsparaml.$(OBJ) $(GLOBJ)gsparamx.$(OBJ) $(GLOBJ)gxshade6.$(OBJ) # gxclrect.c requires rop_proc_table, so we need gsroptab here. clbase4_=$(GLOBJ)gsroptab.$(OBJ) $(GLOBJ)gsroprun.$(OBJ) $(GLOBJ)stream.$(OBJ) clpath_=$(GLOBJ)gxclimag.$(OBJ) $(GLOBJ)gxclpath.$(OBJ) $(GLOBJ)gxdhtserial.$(OBJ) @@ -2203,7 +2181,8 @@ $(GLD)clist.dev : $(LIB_MAK) $(ECHOGS_XE) $(clist_)\ $(GLOBJ)gxclist.$(OBJ) : $(GLSRC)gxclist.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gp_h) $(gpcheck_h) $(gsparams_h) $(valgrind_h)\ $(gxcldev_h) $(gxclpath_h) $(gxdevice_h) $(gxdevmem_h) $(gxdcolor_h)\ - $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) + $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h) $(gxdevsop_h) $(gxobj_h) \ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclist.$(OBJ) $(C_) $(GLSRC)gxclist.c $(GLOBJ)gxclbits.$(OBJ) : $(GLSRC)gxclbits.c $(AK) $(gx_h)\ @@ -2954,7 +2933,8 @@ $(GLOBJ)gxctable.$(OBJ) : $(GLSRC)gxctable.c $(AK) $(gx_h)\ gsicc_=$(GLOBJ)gsicc_manage.$(OBJ) $(GLOBJ)gsicc_cache.$(OBJ)\ $(GLOBJ)gsicc_$(WHICH_CMS).$(OBJ) $(GLOBJ)gsicc_profilecache.$(OBJ)\ $(GLOBJ)gsicc_create.$(OBJ) $(GLOBJ)gsicc_nocm.$(OBJ)\ - $(GLOBJ)gsicc_replacecm.$(OBJ) $(GLOBJ)gsicc_monitorcm.$(OBJ) + $(GLOBJ)gsicc_replacecm.$(OBJ) $(GLOBJ)gsicc_monitorcm.$(OBJ)\ + $(GLOBJ)gsicc_blacktext.$(OBJ) sicclib_=$(GLOBJ)gsicc.$(OBJ) $(GLD)sicclib.dev : $(LIB_MAK) $(ECHOGS_XE) $(sicclib_) $(gsicc_) $(md5_)\ @@ -2975,6 +2955,7 @@ gsicc_cms_h=$(GLSRC)gsicc_cms.h gsicc_manage_h=$(GLSRC)gsicc_manage.h gsicc_cache_h=$(GLSRC)gsicc_cache.h gsicc_profilecache_h=$(GLSRC)gsicc_profilecache.h +gsicc_blacktext_h=$(GLSRC)gsicc_blacktext.h $(GLOBJ)gsicc_monitorcm.$(OBJ) : $(GLSRC)gsicc_monitorcm.c $(AK) $(std_h)\ $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gxdevcli_h)\ @@ -3015,6 +2996,11 @@ $(GLOBJ)gsicc_profilecache.$(OBJ) : $(GLSRC)gsicc_profilecache.c $(AK)\ $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc_profilecache.$(OBJ) $(C_) $(GLSRC)gsicc_profilecache.c +$(GLOBJ)gsicc_blacktext.$(OBJ) : $(GLSRC)gsicc_blacktext.c $(AK)\ + $(gsmemory_h) $(gsstruct_h) $(gzstate_h) $(gsicc_blacktext_h)\ + $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)gsicc_blacktext.$(OBJ) $(C_) $(GLSRC)gsicc_blacktext.c + $(GLOBJ)gsicc_lcms2mt_1_0.$(OBJ) : $(GLSRC)gsicc_lcms2mt.c\ $(memory__h) $(gsicc_cms_h) $(gslibctx_h) $(gserrors_h) $(gxdevice_h) $(LIB_MAK) $(MAKEDIRS) $(GLLCMS2MTCC) $(GLO_)gsicc_lcms2mt_1_0.$(OBJ) $(C_) $(GLSRC)gsicc_lcms2mt.c @@ -3187,7 +3173,7 @@ gxblend_h=$(GLSRC)gxblend.h gdevp14_h=$(GLSRC)gdevp14.h $(GLOBJ)gstrans.$(OBJ) : $(GLSRC)gstrans.c $(AK) $(gx_h) $(gserrors_h)\ - $(math__h) $(memory__h) $(gdevp14_h) $(gstrans_h)\ + $(math__h) $(memory__h) $(gdevp14_h) $(gstrans_h) $(gsicc_cache_h)\ $(gsutil_h) $(gxdevcli_h) $(gzstate_h) $(gscspace_h)\ $(gxclist_h) $(gsicc_manage_h) $(gdevdevn_h) $(gxarith_h) $(gxblend_h)\ $(LIB_MAK) $(MAKEDIRS) @@ -3327,7 +3313,7 @@ $(GLD)shadelib.dev : $(LIB_MAK) $(ECHOGS_XE) $(shadelib_)\ $(ADDMOD) $(GLD)shadelib -include $(GLD)funclib $(GLD)patlib $(GLOBJ)gen_ordered.$(OBJ) : $(GLSRC)gen_ordered.c $(GLSRC)gen_ordered.h\ - $(std_h) $(gsmemory_h) $(math__h) $(string__h) $(LIB_MAK) $(MAKEDIRS) + $(std_h) $(gsmemory_h) $(math__h) $(string__h) $(gp_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gen_ordered.$(OBJ) $(C_) $(D_)GS_LIB_BUILD$(_D) \ $(GLSRC)gen_ordered.c @@ -3346,7 +3332,7 @@ $(GLD)romfs0.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) $(GLGEN)gsromfs1_.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(LIB_MAK) $(MAKEDIRS) $(EXP)$(MKROMFS_XE) -o $(GLGEN)gsromfs1_.c \ $(MKROMFS_FLAGS) -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ - $(PS_ROMFS_ARGS) $(PS_FONT_ROMFS_ARGS) $(GL_ROMFS_ARGS) $(TESS_ROMFS_ARGS) + $(TESS_ROMFS_ARGS) $(PS_ROMFS_ARGS) $(PS_FONT_ROMFS_ARGS) $(GL_ROMFS_ARGS) $(GLGEN)gsromfs1_1.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(LIB_MAK) $(MAKEDIRS) $(EXP)$(MKROMFS_XE) -o $(GLGEN)gsromfs1_1.c \ @@ -4376,6 +4362,7 @@ $(GLSRC)gdevflp.h:$(GLGEN)arch.h $(GLSRC)gdevflp.h:$(GLSRC)gs_dll_call.h $(GLSRC)gdevkrnlsclass.h:$(GLSRC)gdevflp.h $(GLSRC)gdevkrnlsclass.h:$(GLSRC)gdevoflt.h +$(GLSRC)gdevkrnlsclass.h:$(GLSRC)gdevnup.h $(GLSRC)gdevkrnlsclass.h:$(GLSRC)gxdevice.h $(GLSRC)gdevkrnlsclass.h:$(GLSRC)gxdevcli.h $(GLSRC)gdevkrnlsclass.h:$(GLSRC)gxcmap.h @@ -10264,6 +10251,64 @@ $(GLSRC)gdevoflt.h:$(GLSRC)std.h $(GLSRC)gdevoflt.h:$(GLSRC)stdpre.h $(GLSRC)gdevoflt.h:$(GLGEN)arch.h $(GLSRC)gdevoflt.h:$(GLSRC)gs_dll_call.h +$(GLSRC)gdevnup.h:$(GLSRC)gxdevice.h +$(GLSRC)gdevnup.h:$(GLSRC)gxdevcli.h +$(GLSRC)gdevnup.h:$(GLSRC)gsnamecl.h +$(GLSRC)gdevnup.h:$(GLSRC)gstparam.h +$(GLSRC)gdevnup.h:$(GLSRC)gxfmap.h +$(GLSRC)gdevnup.h:$(GLSRC)gsmalloc.h +$(GLSRC)gdevnup.h:$(GLSRC)gscsel.h +$(GLSRC)gdevnup.h:$(GLSRC)gxbcache.h +$(GLSRC)gdevnup.h:$(GLSRC)gxdda.h +$(GLSRC)gdevnup.h:$(GLSRC)gxpath.h +$(GLSRC)gdevnup.h:$(GLSRC)gxfrac.h +$(GLSRC)gdevnup.h:$(GLSRC)gxtmap.h +$(GLSRC)gdevnup.h:$(GLSRC)gxftype.h +$(GLSRC)gdevnup.h:$(GLSRC)gsrect.h +$(GLSRC)gdevnup.h:$(GLSRC)gslparam.h +$(GLSRC)gdevnup.h:$(GLSRC)gsdevice.h +$(GLSRC)gdevnup.h:$(GLSRC)gscpm.h +$(GLSRC)gdevnup.h:$(GLSRC)gsgstate.h +$(GLSRC)gdevnup.h:$(GLSRC)gxstdio.h +$(GLSRC)gdevnup.h:$(GLSRC)gsxfont.h +$(GLSRC)gdevnup.h:$(GLSRC)gsdsrc.h +$(GLSRC)gdevnup.h:$(GLSRC)gsio.h +$(GLSRC)gdevnup.h:$(GLSRC)gsiparam.h +$(GLSRC)gdevnup.h:$(GLSRC)gxfixed.h +$(GLSRC)gdevnup.h:$(GLSRC)gscompt.h +$(GLSRC)gdevnup.h:$(GLSRC)gsmatrix.h +$(GLSRC)gdevnup.h:$(GLSRC)gspenum.h +$(GLSRC)gdevnup.h:$(GLSRC)gsparam.h +$(GLSRC)gdevnup.h:$(GLSRC)gp.h +$(GLSRC)gdevnup.h:$(GLSRC)memento.h +$(GLSRC)gdevnup.h:$(GLSRC)memory_.h +$(GLSRC)gdevnup.h:$(GLSRC)gsuid.h +$(GLSRC)gdevnup.h:$(GLSRC)gsstruct.h +$(GLSRC)gdevnup.h:$(GLSRC)gxsync.h +$(GLSRC)gdevnup.h:$(GLSRC)gxbitmap.h +$(GLSRC)gdevnup.h:$(GLSRC)srdline.h +$(GLSRC)gdevnup.h:$(GLSRC)scommon.h +$(GLSRC)gdevnup.h:$(GLSRC)gsfname.h +$(GLSRC)gdevnup.h:$(GLSRC)gsbitmap.h +$(GLSRC)gdevnup.h:$(GLSRC)gsccolor.h +$(GLSRC)gdevnup.h:$(GLSRC)gxarith.h +$(GLSRC)gdevnup.h:$(GLSRC)stat_.h +$(GLSRC)gdevnup.h:$(GLSRC)gpsync.h +$(GLSRC)gdevnup.h:$(GLSRC)gsstype.h +$(GLSRC)gdevnup.h:$(GLSRC)gsmemory.h +$(GLSRC)gdevnup.h:$(GLSRC)gpgetenv.h +$(GLSRC)gdevnup.h:$(GLSRC)gscdefs.h +$(GLSRC)gdevnup.h:$(GLSRC)gslibctx.h +$(GLSRC)gdevnup.h:$(GLSRC)gxcindex.h +$(GLSRC)gdevnup.h:$(GLSRC)stdio_.h +$(GLSRC)gdevnup.h:$(GLSRC)gsccode.h +$(GLSRC)gdevnup.h:$(GLSRC)stdint_.h +$(GLSRC)gdevnup.h:$(GLSRC)gssprintf.h +$(GLSRC)gdevnup.h:$(GLSRC)gstypes.h +$(GLSRC)gdevnup.h:$(GLSRC)std.h +$(GLSRC)gdevnup.h:$(GLSRC)stdpre.h +$(GLSRC)gdevnup.h:$(GLGEN)arch.h +$(GLSRC)gdevnup.h:$(GLSRC)gs_dll_call.h $(GLSRC)gxfapi.h:$(GLSRC)gstext.h $(GLSRC)gxfapi.h:$(GLSRC)gsfont.h $(GLSRC)gxfapi.h:$(GLSRC)gsdcolor.h diff --git a/base/locale_.h b/base/locale_.h index 9bfeaf9a..19f52f91 100644 --- a/base/locale_.h +++ b/base/locale_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/lwf_jp2.mak b/base/lwf_jp2.mak deleted file mode 100644 index bfe67747..00000000 --- a/base/lwf_jp2.mak +++ /dev/null @@ -1,397 +0,0 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. -# All Rights Reserved. -# -# This software is provided AS-IS with no warranty, either express or -# implied. -# -# This software is distributed under license and may not be copied, -# modified or distributed except as expressly authorized under the terms -# of the license contained in the file LICENSE in this distribution. -# -# Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, -# CA 94945, U.S.A., +1(415)492-9861, for further information. -# - -# makefile for Luratech lwf_jp2 library code. -# Users of this makefile must define the following: -# SHARE_JPX - whether to compile in or link to the library -# JPXSRCDIR - the library source directory -# -# gs.mak and friends define the following: -# JPXOBJDIR - the output obj directory -# JPXGENDIR - generated (.dev) file directory -# LWF_JPXI_ - include path for the library headers -# JPXCF_ - cflags for building the library -# -# We define the lwf_jp2.dev target and its dependencies -# -# This partial makefile compiles the lwf_jp2 library for use in -# Ghostscript. - -LWF_JP2_MAK=$(GLSRC)lwf_jp2.mak $(TOP_MAKEFILES) - -LWF_JP2_SRC=$(JPXSRCDIR)$(D)library$(D)source$(D) -LWF_JP2_GEN=$(JPXOBJDIR)$(D) -LWF_JP2_OBJ=$(JPXOBJDIR)$(D) - -# source files to build from the CSDK source - -lwf_jp2_OBJS = \ - $(LWF_JP2_OBJ)jp2_adt_band_array.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_band_buffer.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_block_array.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_cache.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_comp.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_component_array.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_decomp.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_ebcot_decoder.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_external_cache.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_image.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_memory.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_mq_decoder.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_mq_state.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_packet_decoder.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_precinct_array.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_rate.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_rate_list.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_read_bits.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_read_data.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_reader_requirements.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_resolution_array.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_tile_array.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_tlm_marker_array.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_adt_write_data.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_buffer.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_code_cb.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_coder.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_codestream.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_file_format.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_format.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_memory.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_code_cb.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_common.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_progression.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_quant.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_wavelet.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_wavelet_lifting.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_wavelet_lifting_mmx.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_weights.$(OBJ) \ - $(LWF_JP2_OBJ)jp2c_write.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_codestream.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_decoder.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_file_format.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_format.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_image.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_memory.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_partial_decoding.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_progression.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_quant.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_scale.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_wavelet.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_wavelet_lifting.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_wavelet_lifting_mmx.$(OBJ) \ - $(LWF_JP2_OBJ)jp2d_write.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_icc.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_license.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_packet.$(OBJ) \ - $(LWF_JP2_OBJ)jp2_tag_tree.$(OBJ) \ - $(LWF_JP2_OBJ)jp2t_codestream.$(OBJ) \ - $(LWF_JP2_OBJ)jp2t_file_format.$(OBJ) \ - $(LWF_JP2_OBJ)jp2t_image.$(OBJ) \ - $(LWF_JP2_OBJ)jp2t_memory.$(OBJ) \ - $(LWF_JP2_OBJ)jp2t_progression.$(OBJ) \ - $(LWF_JP2_OBJ)jp2t_transcoder.$(OBJ) - -lwf_jp2_HDRS = \ - $(LWF_JP2_SRC)jp2_adt_band_array.h \ - $(LWF_JP2_SRC)jp2_adt_band_buffer.h \ - $(LWF_JP2_SRC)jp2_adt_block_array.h \ - $(LWF_JP2_SRC)jp2_adt_cache.h \ - $(LWF_JP2_SRC)jp2_adt_comp.h \ - $(LWF_JP2_SRC)jp2_adt_component_array.h \ - $(LWF_JP2_SRC)jp2_adt_decomp.h \ - $(LWF_JP2_SRC)jp2_adt_ebcot_decoder.h \ - $(LWF_JP2_SRC)jp2_adt_external_cache.h \ - $(LWF_JP2_SRC)jp2_adt_image.h \ - $(LWF_JP2_SRC)jp2_adt_memory.h \ - $(LWF_JP2_SRC)jp2_adt_mq_decoder.h \ - $(LWF_JP2_SRC)jp2_adt_mq_state.h \ - $(LWF_JP2_SRC)jp2_adt_packet_decoder.h \ - $(LWF_JP2_SRC)jp2_adt_precinct_array.h \ - $(LWF_JP2_SRC)jp2_adt_rate.h \ - $(LWF_JP2_SRC)jp2_adt_rate_list.h \ - $(LWF_JP2_SRC)jp2_adt_read_bits.h \ - $(LWF_JP2_SRC)jp2_adt_read_data.h \ - $(LWF_JP2_SRC)jp2_adt_reader_requirements.h \ - $(LWF_JP2_SRC)jp2_adt_resolution_array.h \ - $(LWF_JP2_SRC)jp2_adt_tile_array.h \ - $(LWF_JP2_SRC)jp2_adt_tlm_marker_array.h \ - $(LWF_JP2_SRC)jp2_adt_write_data.h \ - $(LWF_JP2_SRC)jp2_assembly.h \ - $(LWF_JP2_SRC)jp2_buffer.h \ - $(LWF_JP2_SRC)jp2c_coder.h \ - $(LWF_JP2_SRC)jp2c_codestream.h \ - $(LWF_JP2_SRC)jp2c_file_format.h \ - $(LWF_JP2_SRC)jp2c_format.h \ - $(LWF_JP2_SRC)jp2c_memory.h \ - $(LWF_JP2_SRC)jp2_code_cb.h \ - $(LWF_JP2_SRC)jp2_codestream.h \ - $(LWF_JP2_SRC)jp2_common.h \ - $(LWF_JP2_SRC)jp2c_progression.h \ - $(LWF_JP2_SRC)jp2c_quant.h \ - $(LWF_JP2_SRC)jp2c_wavelet.h \ - $(LWF_JP2_SRC)jp2c_wavelet_lifting.h \ - $(LWF_JP2_SRC)jp2c_wavelet_lifting_mmx.h \ - $(LWF_JP2_SRC)jp2c_weights.h \ - $(LWF_JP2_SRC)jp2c_write.h \ - $(LWF_JP2_SRC)jp2d_codestream.h \ - $(LWF_JP2_SRC)jp2d_decoder.h \ - $(LWF_JP2_SRC)jp2d_file_format.h \ - $(LWF_JP2_SRC)jp2d_format.h \ - $(LWF_JP2_SRC)jp2d_image.h \ - $(LWF_JP2_SRC)jp2d_memory.h \ - $(LWF_JP2_SRC)jp2d_partial_decoding.h \ - $(LWF_JP2_SRC)jp2d_progression.h \ - $(LWF_JP2_SRC)jp2d_quant.h \ - $(LWF_JP2_SRC)jp2d_scale.h \ - $(LWF_JP2_SRC)jp2d_wavelet.h \ - $(LWF_JP2_SRC)jp2d_wavelet_lifting.h \ - $(LWF_JP2_SRC)jp2d_wavelet_lifting_mmx.h \ - $(LWF_JP2_SRC)jp2d_write.h \ - $(LWF_JP2_SRC)jp2_file_format.h \ - $(LWF_JP2_SRC)jp2_icc.h \ - $(LWF_JP2_SRC)jp2_image.h \ - $(LWF_JP2_SRC)jp2_license.h \ - $(LWF_JP2_SRC)jp2_mac_carbon.h \ - $(LWF_JP2_SRC)jp2_packet.h \ - $(LWF_JP2_SRC)jp2_tag_tree.h \ - $(LWF_JP2_SRC)jp2t_codestream.h \ - $(LWF_JP2_SRC)jp2t_file_format.h \ - $(LWF_JP2_SRC)jp2t_image.h \ - $(LWF_JP2_SRC)jp2t_memory.h \ - $(LWF_JP2_SRC)jp2t_progression.h \ - $(LWF_JP2_SRC)jp2t_transcoder.h \ - $(LWF_JP2_SRC)lwf_jp2.h - -# switch in the selected library .dev -$(LWF_JP2_GEN)lwf_jp2.dev : $(LWF_JP2_GEN)lwf_jp2_$(SHARE_JPX).dev \ - $(LWF_JP2_MAK) $(MAKEDIRS) - $(CP_) $(LWF_JP2_GEN)lwf_jp2_$(SHARE_JPX).dev $(LWF_JP2_GEN)lwf_jp2.dev - -# external link .dev -$(LWF_JP2_GEN)lwf_jp2_1.dev : $(LWF_JP2_MAK) $(ECHOGS_XE) \ - $(MAKEDIRS) - $(SETMOD) $(LWF_JP2_GEN)lwf_jp2_1 -lib lwf_jp2 - -# compile our own .dev -$(LWF_JP2_GEN)lwf_jp2_0.dev : $(LWF_JP2_MAK) $(ECHOGS_XE) $(lwf_jp2_OBJS) \ - $(MAKEDIRS) - $(SETMOD) $(LWF_JP2_GEN)lwf_jp2_0 $(lwf_jp2_OBJS) - -# define our specific compiler -LWF_JP2_CC=$(CC_) $(CFLAGS) $(I_)$(LWF_JPXI_)$(_I) $(JPXCF_) -LWF_JP2_O=$(O_)$(LWF_JP2_OBJ) - -LWF_JP2_DEP=$(AK) $(LWF_JP2_MAK) $(MAKEDIRS) - -# explicit rules for building each source file -# for simplicity we have every source file depend on all headers - -$(LWF_JP2_OBJ)jp2_adt_band_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_band_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_band_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_band_array.c - -$(LWF_JP2_OBJ)jp2_adt_band_buffer.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_band_buffer.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_band_buffer.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_band_buffer.c - -$(LWF_JP2_OBJ)jp2_adt_block_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_block_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_block_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_block_array.c - -$(LWF_JP2_OBJ)jp2_adt_cache.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_cache.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_cache.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_cache.c - -$(LWF_JP2_OBJ)jp2_adt_comp.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_comp.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_comp.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_comp.c - -$(LWF_JP2_OBJ)jp2_adt_component_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_component_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_component_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_component_array.c - -$(LWF_JP2_OBJ)jp2_adt_decomp.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_decomp.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_decomp.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_decomp.c - -$(LWF_JP2_OBJ)jp2_adt_ebcot_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_ebcot_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_ebcot_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_ebcot_decoder.c - -$(LWF_JP2_OBJ)jp2_adt_external_cache.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_external_cache.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_external_cache.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_external_cache.c - -$(LWF_JP2_OBJ)jp2_adt_image.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_image.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_image.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_image.c - -$(LWF_JP2_OBJ)jp2_adt_memory.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_memory.c - -$(LWF_JP2_OBJ)jp2_adt_mq_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_mq_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_mq_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_mq_decoder.c - -$(LWF_JP2_OBJ)jp2_adt_mq_state.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_mq_state.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_mq_state.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_mq_state.c - -$(LWF_JP2_OBJ)jp2_adt_packet_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_packet_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_packet_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_packet_decoder.c - -$(LWF_JP2_OBJ)jp2_adt_precinct_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_precinct_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_precinct_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_precinct_array.c - -$(LWF_JP2_OBJ)jp2_adt_rate.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_rate.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_rate.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_rate.c - -$(LWF_JP2_OBJ)jp2_adt_rate_list.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_rate_list.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_rate_list.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_rate_list.c - -$(LWF_JP2_OBJ)jp2_adt_read_bits.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_read_bits.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_read_bits.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_read_bits.c - -$(LWF_JP2_OBJ)jp2_adt_read_data.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_read_data.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_read_data.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_read_data.c - -$(LWF_JP2_OBJ)jp2_adt_reader_requirements.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_reader_requirements.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_reader_requirements.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_reader_requirements.c - -$(LWF_JP2_OBJ)jp2_adt_resolution_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_resolution_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_resolution_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_resolution_array.c - -$(LWF_JP2_OBJ)jp2_adt_tile_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_tile_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_tile_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_tile_array.c - -$(LWF_JP2_OBJ)jp2_adt_tlm_marker_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_tlm_marker_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_tlm_marker_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_tlm_marker_array.c - -$(LWF_JP2_OBJ)jp2_adt_write_data.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_write_data.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_write_data.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_write_data.c - -$(LWF_JP2_OBJ)jp2_buffer.$(OBJ) : $(LWF_JP2_SRC)jp2_buffer.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_buffer.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_buffer.c - -$(LWF_JP2_OBJ)jp2c_code_cb.$(OBJ) : $(LWF_JP2_SRC)jp2c_code_cb.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_code_cb.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_code_cb.c - -$(LWF_JP2_OBJ)jp2c_coder.$(OBJ) : $(LWF_JP2_SRC)jp2c_coder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_coder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_coder.c - -$(LWF_JP2_OBJ)jp2c_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2c_codestream.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_codestream.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_codestream.c - -$(LWF_JP2_OBJ)jp2c_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2c_file_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_file_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_file_format.c - -$(LWF_JP2_OBJ)jp2c_format.$(OBJ) : $(LWF_JP2_SRC)jp2c_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_format.c - -$(LWF_JP2_OBJ)jp2c_memory.$(OBJ) : $(LWF_JP2_SRC)jp2c_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_memory.c - -$(LWF_JP2_OBJ)jp2_code_cb.$(OBJ) : $(LWF_JP2_SRC)jp2_code_cb.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_code_cb.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_code_cb.c - -$(LWF_JP2_OBJ)jp2_common.$(OBJ) : $(LWF_JP2_SRC)jp2_common.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_common.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_common.c - -$(LWF_JP2_OBJ)jp2c_progression.$(OBJ) : $(LWF_JP2_SRC)jp2c_progression.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_progression.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_progression.c - -$(LWF_JP2_OBJ)jp2c_quant.$(OBJ) : $(LWF_JP2_SRC)jp2c_quant.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_quant.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_quant.c - -$(LWF_JP2_OBJ)jp2c_wavelet.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_wavelet.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_wavelet.c - -$(LWF_JP2_OBJ)jp2c_wavelet_lifting.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet_lifting.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_wavelet_lifting.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_wavelet_lifting.c - -$(LWF_JP2_OBJ)jp2c_wavelet_lifting_mmx.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet_lifting_mmx.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_wavelet_lifting_mmx.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_wavelet_lifting_mmx.c - -$(LWF_JP2_OBJ)jp2c_weights.$(OBJ) : $(LWF_JP2_SRC)jp2c_weights.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_weights.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_weights.c - -$(LWF_JP2_OBJ)jp2c_write.$(OBJ) : $(LWF_JP2_SRC)jp2c_write.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_write.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_write.c - -$(LWF_JP2_OBJ)jp2d_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2d_codestream.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_codestream.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_codestream.c - -$(LWF_JP2_OBJ)jp2d_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2d_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_decoder.c - -$(LWF_JP2_OBJ)jp2_demo.$(OBJ) : $(LWF_JP2_SRC)jp2_demo.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_demo.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_demo.c - -$(LWF_JP2_OBJ)jp2d_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2d_file_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_file_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_file_format.c - -$(LWF_JP2_OBJ)jp2d_format.$(OBJ) : $(LWF_JP2_SRC)jp2d_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_format.c - -$(LWF_JP2_OBJ)jp2d_image.$(OBJ) : $(LWF_JP2_SRC)jp2d_image.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_image.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_image.c - -$(LWF_JP2_OBJ)jp2d_memory.$(OBJ) : $(LWF_JP2_SRC)jp2d_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_memory.c - -$(LWF_JP2_OBJ)jp2d_partial_decoding.$(OBJ) : $(LWF_JP2_SRC)jp2d_partial_decoding.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_partial_decoding.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_partial_decoding.c - -$(LWF_JP2_OBJ)jp2d_progression.$(OBJ) : $(LWF_JP2_SRC)jp2d_progression.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_progression.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_progression.c - -$(LWF_JP2_OBJ)jp2d_quant.$(OBJ) : $(LWF_JP2_SRC)jp2d_quant.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_quant.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_quant.c - -$(LWF_JP2_OBJ)jp2d_scale.$(OBJ) : $(LWF_JP2_SRC)jp2d_scale.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_scale.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_scale.c - -$(LWF_JP2_OBJ)jp2d_wavelet.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_wavelet.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_wavelet.c - -$(LWF_JP2_OBJ)jp2d_wavelet_lifting.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet_lifting.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_wavelet_lifting.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_wavelet_lifting.c - -$(LWF_JP2_OBJ)jp2d_wavelet_lifting_mmx.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet_lifting_mmx.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_wavelet_lifting_mmx.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_wavelet_lifting_mmx.c - -$(LWF_JP2_OBJ)jp2d_write.$(OBJ) : $(LWF_JP2_SRC)jp2d_write.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_write.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_write.c - -$(LWF_JP2_OBJ)jp2_icc.$(OBJ) : $(LWF_JP2_SRC)jp2_icc.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_icc.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_icc.c - -$(LWF_JP2_OBJ)jp2_license.$(OBJ) : $(LWF_JP2_SRC)jp2_license.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_license.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_license.c - -$(LWF_JP2_OBJ)jp2_packet.$(OBJ) : $(LWF_JP2_SRC)jp2_packet.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_packet.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_packet.c - -$(LWF_JP2_OBJ)jp2_tag_tree.$(OBJ) : $(LWF_JP2_SRC)jp2_tag_tree.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2_tag_tree.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_tag_tree.c - -$(LWF_JP2_OBJ)jp2t_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2t_codestream.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_codestream.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_codestream.c - -$(LWF_JP2_OBJ)jp2t_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2t_file_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_file_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_file_format.c - -$(LWF_JP2_OBJ)jp2t_image.$(OBJ) : $(LWF_JP2_SRC)jp2t_image.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_image.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_image.c - -$(LWF_JP2_OBJ)jp2t_memory.$(OBJ) : $(LWF_JP2_SRC)jp2t_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_memory.c - -$(LWF_JP2_OBJ)jp2t_progression.$(OBJ) : $(LWF_JP2_SRC)jp2t_progression.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_progression.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_progression.c - -$(LWF_JP2_OBJ)jp2t_transcoder.$(OBJ) : $(LWF_JP2_SRC)jp2t_transcoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) - $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_transcoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_transcoder.c - - -# end of file diff --git a/base/malloc_.h b/base/malloc_.h index 0bc61776..dacd7f24 100644 --- a/base/malloc_.h +++ b/base/malloc_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/math_.h b/base/math_.h index 34af3f8d..fd1bcc20 100644 --- a/base/math_.h +++ b/base/math_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/memento.c b/base/memento.c index ff37b492..fddb17fe 100644 --- a/base/memento.c +++ b/base/memento.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2020 Artifex Software, Inc. +/* Copyright (C) 2009-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -39,7 +39,11 @@ #include "memory_.h" int atexit(void (*)(void)); #else +#ifdef MEMENTO_MUPDF_HACKS +#include "mupdf/memento.h" +#else #include "memento.h" +#endif #include #endif #ifndef _MSC_VER @@ -58,6 +62,19 @@ int atexit(void (*)(void)); #include #endif +/* Workaround VS2012 (and earlier) missing va_copy. */ +#ifdef _MSC_VER +# if _MSC_VER < 1800 /* Prior to 2013 */ +# ifndef va_copy +# ifdef __va_copy +# define va_copy(dst,src) __va_copy(dst,src) +# else +# define va_copy(dst,src) memcpy(&dst, &src, sizeof(va_list)) +# endif /* __va_copy */ +# endif /* va_copy */ +# endif +#endif + /* Hacks to portably print large sizes */ #ifdef _MSC_VER #define FMTZ "%llu" @@ -190,7 +207,7 @@ windows_fprintf(FILE *file, const char *fmt, ...) #endif #endif -#if defined(__linux__) +#if defined(__linux__) || defined(__OpenBSD__) #define MEMENTO_HAS_FORK #elif defined(__APPLE__) && defined(__MACH__) #define MEMENTO_HAS_FORK @@ -271,7 +288,10 @@ enum { Memento_EventType_deleteArray = 7, Memento_EventType_takeRef = 8, Memento_EventType_dropRef = 9, - Memento_EventType_reference = 10 + Memento_EventType_reference = 10, + Memento_EventType_strdup = 11, + Memento_EventType_asprintf = 12, + Memento_EventType_vasprintf = 13 }; static const char *eventType[] = @@ -286,7 +306,10 @@ static const char *eventType[] = "delete[]", "takeRef", "dropRef", - "reference" + "reference", + "strdup", + "asprintf", + "vasprintf" }; /* When we list leaked blocks at the end of execution, we search for pointers @@ -430,6 +453,9 @@ static struct { int nextPattern; int patternBit; int leaking; + int hideMultipleReallocs; + int abortOnLeak; + int abortOnCorruption; size_t maxMemory; size_t alloc; size_t peakAlloc; @@ -509,10 +535,16 @@ static void *current_addr; static void error2_cb(void *data, const char *msg, int errnum) { + (void)data; + (void)msg; + (void)errnum; } static void syminfo_cb(void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize) { + (void)data; + (void)symval; + (void)symsize; if (sizeof(void *) == 4) fprintf(stderr, " 0x%08lx %s\n", pc, symname?symname:"?"); else @@ -521,6 +553,9 @@ static void syminfo_cb(void *data, uintptr_t pc, const char *symname, uintptr_t static void error_cb(void *data, const char *msg, int errnum) { + (void)data; + (void)msg; + (void)errnum; backtrace_syminfo(my_backtrace_state, (uintptr_t)current_addr, syminfo_cb, @@ -530,6 +565,7 @@ static void error_cb(void *data, const char *msg, int errnum) static int full_cb(void *data, uintptr_t pc, const char *fname, int line, const char *fn) { + (void)data; if (sizeof(void *) == 4) fprintf(stderr, " 0x%08lx %s(%s:%d)\n", pc, fn?fn:"?", fname?fname:"?", line); else @@ -943,8 +979,8 @@ static void Memento_storeDetails(Memento_BlkHeader *head, int type) if (count) memcpy(&details->stack, &stack[skip], count * sizeof(void *)); - details->type = type; - details->count = count; + details->type = (char)type; + details->count = (char)count; details->sequence = memento.sequence; details->next = NULL; VALGRIND_MAKE_MEM_DEFINED(&head->details_tail, sizeof(head->details_tail)); @@ -1291,6 +1327,7 @@ static int Memento_appBlock(Memento_Blocks *blks, Memento_BlkHeader *b) { int result; + (void)blks; VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader)); VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(b), b->rawsize + Memento_PostSize); @@ -1421,12 +1458,14 @@ int Memento_listBlocksNested(void) /* Now, calculate tree */ for (b = memento.used.head; b; b = b->next) { char *p = MEMBLK_TOBLK(b); - int end = (b->rawsize < MEMENTO_PTRSEARCH ? b->rawsize : MEMENTO_PTRSEARCH); + size_t end = (b->rawsize < MEMENTO_PTRSEARCH ? b->rawsize : MEMENTO_PTRSEARCH); + size_t z; VALGRIND_MAKE_MEM_DEFINED(p, end); end -= sizeof(void *)-1; - for (i = MEMENTO_SEARCH_SKIP; i < end; i += sizeof(void *)) { - void *q = *(void **)(&p[i]); + for (z = MEMENTO_SEARCH_SKIP; z < end; z += sizeof(void *)) { + void *q = *(void **)(&p[z]); void **r; + /* Do trivial checks on pointer */ if ((mask & (intptr_t)q) != mask || q < minptr || q > maxptr) continue; @@ -1552,18 +1591,24 @@ static int showInfo(Memento_BlkHeader *b, void *arg) { Memento_BlkDetails *details; + (void)arg; + fprintf(stderr, FMTP":(size="FMTZ",num=%d)", MEMBLK_TOBLK(b), (FMTZ_CAST)b->rawsize, b->sequence); if (b->label) fprintf(stderr, " (%s)", b->label); fprintf(stderr, "\nEvents:\n"); - details = b->details; - while (details) + for (details = b->details; details; details = details->next) { + if (memento.hideMultipleReallocs && + details->type == Memento_EventType_realloc && + details->next && + details->next->type == Memento_EventType_realloc) { + continue; + } fprintf(stderr, " Event %d (%s)\n", details->sequence, eventType[(int)details->type]); Memento_showStacktrace(details->stack, details->count); - details = details->next; } return 0; } @@ -1579,6 +1624,25 @@ void Memento_listBlockInfo(void) #endif } +#ifdef MEMENTO_DETAILS +static int +showBlockInfo(Memento_BlkHeader *b, void *arg) +{ + if (arg < MEMBLK_TOBLK(b) || (void *)MEMBLK_POSTPTR(b) <= arg) + return 0; + return showInfo(b, NULL); +} +#endif + +void Memento_blockInfo(void *p) +{ +#ifdef MEMENTO_DETAILS + MEMENTO_LOCK(); + Memento_appBlocks(&memento.used, showBlockInfo, p); + MEMENTO_UNLOCK(); +#endif +} + static int Memento_nonLeakBlocksLeaked(void) { Memento_BlkHeader *blk = memento.used.head; @@ -1630,64 +1694,68 @@ void Memento_fin(void) fprintf(stderr, "MEMENTO_NEXTFAILAT=%d\n", memento.nextFailAt); fprintf(stderr, "MEMENTO_NEXTPATTERN=%d\n", memento.nextPattern); } + if (Memento_nonLeakBlocksLeaked() && memento.abortOnLeak) { + fprintf(stderr, "Calling abort() because blocks were leaked and MEMENTO_ABORT_ON_LEAK is set.\n"); + abort(); + } } /* Reads number from using strtol(). - -Params: - text: - text to read. - out: - pointer to output value. - relative: - *relative set to 1 if starts with '+' or '-', else set to 0. - end: - *end is set to point to next unread character after number. - -Returns 0 on success, else -1. -*/ + * + * Params: + * text: + * text to read. + * out: + * pointer to output value. + * relative: + * *relative set to 1 if starts with '+' or '-', else set to 0. + * end: + * *end is set to point to next unread character after number. + * + * Returns 0 on success, else -1. + */ static int read_number(const char *text, int *out, int *relative, char **end) { - if (text[0] == '+' || text[0] == '-') { + if (text[0] == '+' || text[0] == '-') *relative = 1; - } - else { + else *relative = 0; - } errno = 0; - *out = strtol(text, end, 0 /*base*/); - if (errno || *end == text) { + *out = (int)strtol(text, end, 0 /*base*/); + if (errno || *end == text) + { fprintf(stderr, "Failed to parse number at start of '%s'.\n", text); return -1; } - if (0) fprintf(stderr, "text='%s': *out=%i *relative=%i\n", - text, *out, *relative); + if (0) + fprintf(stderr, "text='%s': *out=%i *relative=%i\n", + text, *out, *relative); return 0; } /* Reads number plus optional delta value from . - -Evaluates or [+|-]. E.g. text='1234+2' sets *out=1236, -text='1234-1' sets *out=1233. - -Params: - text: - text to read. - out: - pointer to output value. - end: - *end is set to point to next unread character after number. - -Returns 0 on success, else -1. -*/ + * + * Evaluates or [+|-]. E.g. text='1234+2' sets *out=1236, + * text='1234-1' sets *out=1233. + * + * Params: + * text: + * text to read. + * out: + * pointer to output value. + * end: + * *end is set to point to next unread character after number. + * + * Returns 0 on success, else -1. + */ static int read_number_delta(const char *text, int *out, char **end) { int e; int relative; + e = read_number(text, out, &relative, end); - if (e) { + if (e) return e; - } if (relative) { fprintf(stderr, "Base number should not start with '+' or '-' at start of '%s'.\n", text); @@ -1697,57 +1765,53 @@ static int read_number_delta(const char *text, int *out, char **end) if (**end == '-' || **end == '+') { int delta; e = read_number(*end, &delta, &relative, end); - if (e) { + if (e) return e; - } *out += delta; } } - if (0) fprintf(stderr, "text='%s': *out=%i\n", text, *out); + if (0) fprintf(stderr, "text='%s': *out=%i\n", text, *out); + return 0; } /* Reads range. - -E.g.: - text='115867-2' sets *begin=115865 *end=115866. - text='115867-1..+3' sets *begin=115866 *end=115869. - -Supported patterns for text: - - - returns *begin=value *end=*begin+1. - .. - returns *begin=value1 *end=value2. - ..+ - returns *begin=value *end=*begin+number. - - - + - - - - : [0-9]+ - -If not specified, *end defaults to *begin+1. - -Returns 0 on success, else -1, with *string_end pointing to first unused -character. -*/ + * + * E.g.: + * text='115867-2' sets *begin=115865 *end=115866. + * text='115867-1..+3' sets *begin=115866 *end=115869. + * + * Supported patterns for text: + * + * - returns *begin=value *end=*begin+1. + * .. - returns *begin=value1 *end=value2. + * ..+ - returns *begin=value *end=*begin+number. + * + * + * + + * - + * + * : [0-9]+ + * + * If not specified, *end defaults to *begin+1. + * + * Returns 0 on success, else -1, with *string_end pointing to first unused + * character. + */ static int read_number_range(const char *text, int *begin, int *end, char **string_end) { int e; e = read_number_delta(text, begin, string_end); - if (e) { + if (e) return e; - } if (string_end && (*string_end)[0] == '.' && (*string_end)[1] == '.') { int relative; e = read_number((*string_end) + 2, end, &relative, string_end); - if (e) { + if (e) return e; - } - if (relative) { + if (relative) *end += *begin; - } - } - else { + } else { *end = *begin + 1; } if (*end < *begin) { @@ -1755,18 +1819,18 @@ static int read_number_range(const char *text, int *begin, int *end, char **stri *begin, *end, text); return -1; } - if (0) fprintf(stderr, "text='%s': *begin=%i *end=%i\n", text, *begin, *end); + if (0) fprintf(stderr, "text='%s': *begin=%i *end=%i\n", text, *begin, *end); + return 0; } -/* -Format: [,]+ - -For description of , see read_number_range() above. - -E.g.: - MEMENTO_SQUEEZES=1234-2..+4,2345,2350..+2 -*/ +/* Format: [,]+ + * + * For description of , see read_number_range() above. + * + * E.g.: + * MEMENTO_SQUEEZES=1234-2..+4,2345,2350..+2 + */ static int Memento_add_squeezes(const char *text) { int e = 0; @@ -1774,20 +1838,18 @@ static int Memento_add_squeezes(const char *text) int begin; int end; char *string_end; - if (!*text) { + if (!*text) break; - } e = read_number_range(text, &begin, &end, &string_end); - if (e) { + if (e) break; - } if (*string_end && *string_end != ',') { fprintf(stderr, "Expecting comma at start of '%s'.\n", string_end); e = -1; break; } fprintf(stderr, "Adding squeeze range %i..%i.\n", - begin, end, string_end-text); + begin, end); memento.squeezes_num += 1; memento.squeezes = MEMENTO_UNDERLYING_REALLOC( memento.squeezes, @@ -1802,11 +1864,11 @@ static int Memento_add_squeezes(const char *text) memento.squeezes[memento.squeezes_num-1].begin = begin; memento.squeezes[memento.squeezes_num-1].end = end; - if (*string_end == 0) { + if (*string_end == 0) break; - } text = string_end + 1; } + return e; } @@ -1842,6 +1904,18 @@ static void Memento_init(void) env = getenv("MEMENTO_SQUEEZEAT"); memento.squeezeAt = (env ? atoi(env) : 0); + env = getenv("MEMENTO_PATTERN"); + memento.pattern = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_HIDE_MULTIPLE_REALLOCS"); + memento.hideMultipleReallocs = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_ABORT_ON_LEAK"); + memento.abortOnLeak = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_ABORT_ON_CORRUPTION"); + memento.abortOnCorruption = (env ? atoi(env) : 0); + env = getenv("MEMENTO_SQUEEZES"); if (env) { int e; @@ -1853,9 +1927,6 @@ static void Memento_init(void) } } - env = getenv("MEMENTO_PATTERN"); - memento.pattern = (env ? atoi(env) : 0); - env = getenv("MEMENTO_MAXMEMORY"); memento.maxMemory = (env ? atoi(env) : 0); @@ -1976,7 +2047,9 @@ static int squeeze(void) for (i = 0; i < OPEN_MAX; i++) { if (stashed_map[i] == 0) { int j = dup(i); - stashed_map[j] = i+1; + if (j >= 0) { + stashed_map[j] = i+1; + } } } @@ -1986,6 +2059,15 @@ static int squeeze(void) if (pid == 0) { /* Child */ signal(SIGSEGV, Memento_signal); + /* Close the dup-licated fds to avoid them getting corrupted by faulty + * code. */ + for (i = 0; i < OPEN_MAX; i++) { + if (stashed_map[i] != 0) { + /* We close duplicated fds, just in case child has some bad + * code that modifies/closes random fds. */ + close(i); + } + } /* In the child, we always fail the next allocation. */ if (memento.patternBit == 0) { memento.patternBit = 1; @@ -1994,7 +2076,7 @@ static int squeeze(void) memento.squeezing = 1; /* This is necessary to allow Memento_failThisEventLocked() near the - end to do 'return squeeze();'. */ + * end to do 'return squeeze();'. */ memento.squeezes_num = 0; return 1; @@ -2011,7 +2093,7 @@ static int squeeze(void) int timeout = 30 * 1000 * 1000; /* time out in microseconds! */ while (waitpid(pid, &status, WNOHANG) == 0) { nanosleep(&tm, NULL); - timeout -= (tm.tv_nsec/1000); + timeout -= (int)(tm.tv_nsec/1000); tm.tv_nsec *= 2; if (tm.tv_nsec > 999999999) tm.tv_nsec = 999999999; @@ -2187,16 +2269,9 @@ static int Memento_failThisEventLocked(void) if (!memento.squeezing && memento.squeezes_num) { /* Move to next relevant squeeze region if appropriate. */ - for(;;) { - if (memento.squeezes_pos == memento.squeezes_num) { + for ( ; memento.squeezes_pos != memento.squeezes_num; memento.squeezes_pos++) { + if (memento.sequence < memento.squeezes[memento.squeezes_pos].end) break; - } - if (memento.sequence >= memento.squeezes[memento.squeezes_pos].end) { - memento.squeezes_pos += 1; - } - else { - break; - } } /* See whether memento.sequence is within this squeeze region. */ @@ -2221,12 +2296,8 @@ static int Memento_failThisEventLocked(void) if ((memento.sequence >= memento.failAt) && (memento.failAt != 0)) Memento_startFailing(); - if (memento.squeezes_num==0 - && (memento.sequence >= memento.squeezeAt) - && (memento.squeezeAt != 0) - ) { + if ((memento.squeezes_num==0) && (memento.sequence >= memento.squeezeAt) && (memento.squeezeAt != 0)) return squeeze(); - } if (!memento.failing) return 0; @@ -2266,16 +2337,22 @@ static void *do_malloc(size_t s, int eventType) Memento_BlkHeader *memblk; size_t smem = MEMBLK_SIZE(s); - if (Memento_failThisEventLocked()) + (void)eventType; + + if (Memento_failThisEventLocked()) { + errno = ENOMEM; return NULL; + } if (s == 0) return NULL; memento.numMallocs++; - if (memento.maxMemory != 0 && memento.alloc + s > memento.maxMemory) + if (memento.maxMemory != 0 && memento.alloc + s > memento.maxMemory) { + errno = ENOMEM; return NULL; + } memblk = MEMENTO_UNDERLYING_MALLOC(smem); if (memblk == NULL) @@ -2298,7 +2375,7 @@ static void *do_malloc(size_t s, int eventType) #ifdef MEMENTO_DETAILS memblk->details = NULL; memblk->details_tail = &memblk->details; - Memento_storeDetails(memblk, Memento_EventType_malloc); + Memento_storeDetails(memblk, eventType); #endif /* MEMENTO_DETAILS */ Memento_addBlockHead(&memento.used, memblk, 0); @@ -2308,6 +2385,83 @@ static void *do_malloc(size_t s, int eventType) return MEMBLK_TOBLK(memblk); } +char *Memento_strdup(const char *text) +{ + size_t len = strlen(text) + 1; + char *ret; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + ret = do_malloc(len, Memento_EventType_strdup); + MEMENTO_UNLOCK(); + + if (ret != NULL) + memcpy(ret, text, len); + + return ret; +} + +#if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS) +int Memento_asprintf(char **ret, const char *format, ...) +{ + va_list va; + int n; + int n2; + + if (!memento.inited) + Memento_init(); + + va_start(va, format); + n = vsnprintf(NULL, 0, format, va); + va_end(va); + if (n < 0) + return n; + + MEMENTO_LOCK(); + *ret = do_malloc(n+1, Memento_EventType_asprintf); + MEMENTO_UNLOCK(); + if (*ret == NULL) + return -1; + + va_start(va, format); + n2 = vsnprintf(*ret, n + 1, format, va); + va_end(va); + + return n2; +} + +int Memento_vasprintf(char **ret, const char *format, va_list ap) +{ + int n; + va_list ap2; + va_copy(ap2, ap); + + if (!memento.inited) + Memento_init(); + + n = vsnprintf(NULL, 0, format, ap); + if (n < 0) { + va_end(ap2); + return n; + } + + MEMENTO_LOCK(); + *ret = do_malloc(n+1, Memento_EventType_vasprintf); + MEMENTO_UNLOCK(); + if (*ret == NULL) { + va_end(ap2); + return -1; + } + + n = vsnprintf(*ret, n + 1, format, ap2); + va_end(ap2); + + return n; +} +#endif + void *Memento_malloc(size_t s) { void *ret; @@ -2318,6 +2472,7 @@ void *Memento_malloc(size_t s) MEMENTO_LOCK(); ret = do_malloc(s, Memento_EventType_malloc); MEMENTO_UNLOCK(); + return ret; } @@ -2330,9 +2485,10 @@ void *Memento_calloc(size_t n, size_t s) MEMENTO_LOCK(); block = do_malloc(n*s, Memento_EventType_calloc); + MEMENTO_UNLOCK(); if (block) memset(block, 0, n*s); - MEMENTO_UNLOCK(); + return block; } @@ -2373,7 +2529,7 @@ int Memento_checkBytePointerOrNull(void *blk) return 0; Memento_checkPointerOrNull(blk); - i = *(unsigned int *)blk; + i = *(unsigned char *)blk; if (i == MEMENTO_PREFILL_UBYTE) fprintf(stderr, "Prefill value found - buffer underrun?\n"); @@ -2715,6 +2871,8 @@ static void do_free(void *blk, int eventType) { Memento_BlkHeader *memblk; + (void)eventType; + if (Memento_event()) Memento_breakpointLocked(); if (blk == NULL) @@ -2723,10 +2881,16 @@ static void do_free(void *blk, int eventType) memblk = MEMBLK_FROMBLK(blk); VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); if (checkBlock(memblk, "free")) + { + if (memento.abortOnCorruption) { + fprintf(stderr, "*** memblk corrupted, calling abort()\n"); + abort(); + } return; + } #ifdef MEMENTO_DETAILS - Memento_storeDetails(memblk, Memento_EventType_free); + Memento_storeDetails(memblk, eventType); #endif VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); @@ -2769,13 +2933,17 @@ static void *do_realloc(void *blk, size_t newsize, int type) size_t newsizemem; int flags; - if (Memento_failThisEventLocked()) + if (Memento_failThisEventLocked()) { + errno = ENOMEM; return NULL; + } memblk = MEMBLK_FROMBLK(blk); VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); - if (checkBlock(memblk, "realloc")) + if (checkBlock(memblk, "realloc")) { + errno = ENOMEM; return NULL; + } #ifdef MEMENTO_DETAILS Memento_storeDetails(memblk, type); @@ -2786,8 +2954,10 @@ static void *do_realloc(void *blk, size_t newsize, int type) Memento_breakpointLocked(); VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); - if (memento.maxMemory != 0 && memento.alloc - memblk->rawsize + newsize > memento.maxMemory) + if (memento.maxMemory != 0 && memento.alloc - memblk->rawsize + newsize > memento.maxMemory) { + errno = ENOMEM; return NULL; + } newsizemem = MEMBLK_SIZE(newsize); Memento_removeBlock(&memento.used, memblk); @@ -2839,6 +3009,7 @@ void *Memento_realloc(void *blk, size_t newsize) MEMENTO_LOCK(); ret = do_malloc(newsize, Memento_EventType_realloc); MEMENTO_UNLOCK(); + if (!ret) errno = ENOMEM; return ret; } if (newsize == 0) { @@ -2851,6 +3022,7 @@ void *Memento_realloc(void *blk, size_t newsize) MEMENTO_LOCK(); ret = do_realloc(blk, newsize, Memento_EventType_realloc); MEMENTO_UNLOCK(); + if (!ret) errno = ENOMEM; return ret; } @@ -3306,6 +3478,9 @@ void *(Memento_reference)(void *a) #undef Memento_free #undef Memento_realloc #undef Memento_calloc +#undef Memento_strdup +#undef Memento_asprintf +#undef Memento_vasprintf void *Memento_malloc(size_t size) { @@ -3327,6 +3502,70 @@ void *Memento_calloc(size_t n, size_t s) return MEMENTO_UNDERLYING_CALLOC(n, s); } +#if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS) +/* Avoid calling strdup, in case our compiler doesn't support it. + * Yes, I'm looking at you, early Visual Studios. */ +char *Memento_strdup(const char *s) +{ + size_t len = strlen(s)+1; + char *ret = MEMENTO_UNDERLYING_MALLOC(len); + if (ret != NULL) + memcpy(ret, s, len); + return ret; +} + +/* Avoid calling asprintf, in case our compiler doesn't support it. + * Vaguely unhappy about relying on vsnprintf, but... */ +int Memento_asprintf(char **ret, const char *format, ...) +{ + va_list va; + int n; + int n2; + + va_start(va, format); + n = vsnprintf(NULL, 0, format, va); + va_end(va); + if (n < 0) + return n; + + *ret = MEMENTO_UNDERLYING_MALLOC(n+1); + if (*ret == NULL) + return -1; + + va_start(va, format); + n2 = vsnprintf(*ret, n + 1, format, va); + va_end(va); + + return n2; +} + +/* Avoid calling vasprintf, in case our compiler doesn't support it. + * Vaguely unhappy about relying on vsnprintf, but... */ +int Memento_vasprintf(char **ret, const char *format, va_list ap) +{ + int n; + va_list ap2; + va_copy(ap2, ap); + + n = vsnprintf(NULL, 0, format, ap); + if (n < 0) { + va_end(ap2); + return n; + } + + *ret = MEMENTO_UNDERLYING_MALLOC(n+1); + if (*ret == NULL) { + va_end(ap2); + return -1; + } + + n = vsnprintf(*ret, n + 1, format, ap2); + va_end(ap2); + + return n; +} +#endif + void (Memento_listBlocks)(void) { } @@ -3357,6 +3596,10 @@ void (Memento_listBlockInfo)(void) { } +void (Memento_blockInfo)(void *ptr) +{ +} + void (Memento_startLeaking)(void) { } diff --git a/base/memento.h b/base/memento.h index d4ff811d..c9994b10 100644 --- a/base/memento.h +++ b/base/memento.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2020 Artifex Software, Inc. +/* Copyright (C) 2009-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -185,6 +185,7 @@ #ifndef MEMENTO_H #include +#include #define MEMENTO_H @@ -237,9 +238,15 @@ void *Memento_malloc(size_t s); void *Memento_realloc(void *, size_t s); void Memento_free(void *); void *Memento_calloc(size_t, size_t); +char *Memento_strdup(const char*); +#if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS) +int Memento_asprintf(char **ret, const char *format, ...); +int Memento_vasprintf(char **ret, const char *format, va_list ap); +#endif void Memento_info(void *addr); void Memento_listBlockInfo(void); +void Memento_blockInfo(void *blk); void *Memento_takeByteRef(void *blk); void *Memento_dropByteRef(void *blk); void *Memento_takeShortRef(void *blk); @@ -259,8 +266,10 @@ int Memento_checkIntPointerOrNull(void *blk); void Memento_startLeaking(void); void Memento_stopLeaking(void); +/* Returns number of allocation events so far. */ int Memento_sequence(void); +/* Returns non-zero if our process was forked by Memento squeeze. */ int Memento_squeezing(void); void Memento_fin(void); @@ -270,18 +279,28 @@ void Memento_bt(void); #ifdef MEMENTO #ifndef COMPILING_MEMENTO_C -#define malloc Memento_malloc -#define free Memento_free -#define realloc Memento_realloc -#define calloc Memento_calloc +#define malloc Memento_malloc +#define free Memento_free +#define realloc Memento_realloc +#define calloc Memento_calloc +#define strdup Memento_strdup +#if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS) +#define asprintf Memento_asprintf +#define vasprintf Memento_vasprintf +#endif #endif #else -#define Memento_malloc MEMENTO_UNDERLYING_MALLOC -#define Memento_free MEMENTO_UNDERLYING_FREE -#define Memento_realloc MEMENTO_UNDERLYING_REALLOC -#define Memento_calloc MEMENTO_UNDERLYING_CALLOC +#define Memento_malloc MEMENTO_UNDERLYING_MALLOC +#define Memento_free MEMENTO_UNDERLYING_FREE +#define Memento_realloc MEMENTO_UNDERLYING_REALLOC +#define Memento_calloc MEMENTO_UNDERLYING_CALLOC +#define Memento_strdup strdup +#if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS) +#define Memento_asprintf asprintf +#define Memento_vasprintf vasprintf +#endif #define Memento_checkBlock(A) 0 #define Memento_checkAllMemory() 0 @@ -303,6 +322,7 @@ void Memento_bt(void); #define Memento_label(A,B) (A) #define Memento_info(A) do {} while (0) #define Memento_listBlockInfo() do {} while (0) +#define Memento_blockInfo(A) do {} while (0) #define Memento_takeByteRef(A) (A) #define Memento_dropByteRef(A) (A) #define Memento_takeShortRef(A) (A) diff --git a/base/memory_.h b/base/memory_.h index 7fb6f7ab..4429bb87 100644 --- a/base/memory_.h +++ b/base/memory_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/mkromfs.c b/base/mkromfs.c index 7a04139e..08fbb27d 100644 --- a/base/mkromfs.c +++ b/base/mkromfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -159,6 +159,18 @@ int gp_stat_impl(const gs_memory_t *mem, const char *path, struct _stat64 *buf) (void)buf; return 0; } +#ifdef MEMENTO +#undef malloc +#undef free +void* Memento_malloc(size_t s) +{ + return malloc(s); +} +void Memento_free(void* blk) +{ + free(blk); +} +#endif #endif int @@ -200,8 +212,7 @@ int outprintf(const gs_memory_t *mem, const char *fmt, ...) return count; } -#ifndef GS_THREADSAFE -int errprintf_nomem(const char *fmt, ...) +int errprintf(const gs_memory_t *mem, const char *fmt, ...) { int count; char buf[PRINTF_BUF_LENGTH]; @@ -218,9 +229,8 @@ int errprintf_nomem(const char *fmt, ...) va_end(args); return count; } -#endif -int errprintf(const gs_memory_t *mem, const char *fmt, ...) +int errprintf_nomem(const char *fmt, ...) { int count; char buf[PRINTF_BUF_LENGTH]; @@ -238,19 +248,18 @@ int errprintf(const gs_memory_t *mem, const char *fmt, ...) return count; } - #ifndef GS_THREADSAFE #if __LINE__ /* compiler provides it */ void lprintf_file_and_line(const char *file, int line) { - epf("%s(%d): ", file, line); + errprintf(NULL, "%s(%d): ", file, line); } #else void lprintf_file_only(FILE * f, const char *file) { - epf("%s(?): ", file); + errprintf(NULL, "%s(?): ", file); } #endif @@ -259,13 +268,13 @@ eprintf_program_ident(const char *program_name, long revision_number) { if (program_name) { - epf((revision_number ? "%s " : "%s"), program_name); + errprintf(NULL, (revision_number ? "%s " : "%s"), program_name); if (revision_number) { int fpart = revision_number % 100; - epf("%d.%02d", (int)(revision_number / 100), fpart); + errprintf(NULL, "%d.%02d", (int)(revision_number / 100), fpart); } - epf(": "); + errprintf(NULL, ": "); } } #endif @@ -290,9 +299,9 @@ int gs_log_error(int err, const char *file, int line) { if (file == NULL) - errprintf_nomem("Returning error %d.\n", err); + errprintf(NULL, "Returning error %d.\n", err); else - errprintf_nomem("%s(%d): Returning error %d.\n", + errprintf(NULL, "%s(%d): Returning error %d.\n", (const char *)file, line, err); return err; } @@ -343,6 +352,22 @@ minimal_free_string(gs_memory_t * mem, byte * data, size_t nbytes, client_name_t return; } +/* Minimal thread functions (needed by gs_next_ids */ +int gp_monitor_enter(gp_monitor *); +int gp_monitor_leave(gp_monitor *); + +int +gp_monitor_enter(gp_monitor * mon) +{ + return 0; +} + +int +gp_monitor_leave(gp_monitor * mon) +{ + return 0; +} + void basic_enum_ptrs(void); void basic_reloc_ptrs(void); diff --git a/base/msvccmd.mak b/base/msvccmd.mak index 7d5980e8..39169e20 100644 --- a/base/msvccmd.mak +++ b/base/msvccmd.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -220,6 +220,12 @@ MSINCFLAGS=-I"$(INCDIR64A)" -I"$(INCDIR64B)" MSINCFLAGS= !endif +!if "$(SANITIZE)" == "1" +SANITIZECFLAGS=/fsanitize=address +!else +SANITIZECFLAGS= +!endif + # Specify output object name CCOBJNAME=-Fo @@ -233,8 +239,8 @@ COMPILE_FOR_CONSOLE_EXE= GENOPT=$(CP) $(CD) $(CT) $(CS) $(WARNOPT) $(VC8WARN) /nologo $(CMT) CCFLAGS=$(PLATOPT) $(FPFLAGS) $(CPFLAGS) $(CFLAGS) $(XCFLAGS) $(MSINCFLAGS) $(SBRFLAGS) -CC=$(COMP) /c $(CCFLAGS) $(COMPILE_FULL_OPTIMIZED) @$(GLGENDIR)\ccf32.tr -CXX=$(CXX) /c $(CCFLAGS) $(COMPILE_FULL_OPTIMIZED) @$(GLGENDIR)\ccf32.tr +CC=$(COMP) /c $(CCFLAGS) $(COMPILE_FULL_OPTIMIZED) $(SANITIZECFLAGS) @$(GLGENDIR)\ccf32.tr +CXX=$(CXX) /c $(CCFLAGS) $(COMPILE_FULL_OPTIMIZED) $(SANITIZECFLAGS) @$(GLGENDIR)\ccf32.tr CPP=$(COMPCPP) /c $(CCFLAGS) @$(GLGENDIR)\ccf32.tr !if $(MAKEDLL) WX=$(COMPILE_FOR_DLL) diff --git a/base/msvclib.mak b/base/msvclib.mak index c0396232..dbf49296 100644 --- a/base/msvclib.mak +++ b/base/msvclib.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -14,7 +14,7 @@ # # makefile for Microsoft Visual C++ 4.1 or later, Windows NT or Windows 95 LIBRARY. # -# All configurable options are surrounded by !ifndef/!endif to allow +# All configurable options are surrounded by !ifndef/!endif to allow # preconfiguration from within another makefile. # If we are building MEMENTO=1, then adjust default debug flags @@ -387,48 +387,15 @@ TIFFPLATFORM=win32 TIFF_CFLAGS=-DJPEG_SUPPORT -DOJPEG_SUPPORT -DJPEG_LIB_MK1_OR_12BIT=0 !endif -# Define which jbig2 library to use -!if !defined(JBIG2_LIB) && (!defined(NO_LURATECH) || "$(NO_LURATECH)" != "1") -!if exist("luratech\ldf_jb2") -JBIG2_LIB=luratech -!endif -!endif - !ifndef JBIG2_LIB JBIG2_LIB=jbig2dec !endif -!if "$(JBIG2_LIB)" == "luratech" || "$(JBIG2_LIB)" == "ldf_jb2" -# Set defaults for using the Luratech JB2 implementation -!ifndef JBIG2SRCDIR -# CSDK source code location -JBIG2SRCDIR=luratech\ldf_jb2 -!endif -!ifndef JBIG2_CFLAGS -# required compiler flags -!ifdef WIN64 -JBIG2_CFLAGS=-DUSE_LDF_JB2 -DWIN64 -!else -JBIG2_CFLAGS=-DUSE_LDF_JB2 -DWIN32 -!endif -!endif -!else # Use jbig2dec by default. See jbig2.mak for more information. !ifndef JBIG2SRCDIR # location of included jbig2dec library source JBIG2SRCDIR=jbig2dec !endif -!endif - -# Alternatively, you can build a separate DLL -# and define SHARE_JBIG2=1 in src/winlib.mak - -# Define which jpeg2k library to use -!if !defined(JPX_LIB) && (!defined(NO_LURATECH) || "$(NO_LURATECH)" != "1") -!if exist("luratech\lwf_jp2") -JPX_LIB=luratech -!endif -!endif # Alternatively, you can build a separate DLL # and define SHARE_JPX=1 in src/winlib.mak @@ -612,6 +579,37 @@ MS_TOOLSET_VERSION=14.26.28806 !if "$(_NMAKE_VER)" == "14.27.29111.0" # VS2019 (Toolset v142) MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.27.29111 +!endif +!if "$(_NMAKE_VER)" == "14.27.29112.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.27.29112 +!endif +!if "$(_NMAKE_VER)" == "14.28.29333.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 +!endif +!if "$(_NMAKE_VER)" == "14.28.29334.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 +!endif +!if "$(_NMAKE_VER)" == "14.28.29335.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 +!endif +!if "$(_NMAKE_VER)" == "14.28.29336.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 +!endif +!if "$(_NMAKE_VER)" == "14.28.29910.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 !endif !endif @@ -905,20 +903,55 @@ LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" /LIBPATH:"$(COMPBASE)\PlatformSDK\L !endif !if $(MSVC_VERSION) == 15 +! ifndef DEVSTUDIO +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\$(MS_TOOLSET_VERSION) +! endif ! if "$(DEVSTUDIO)"=="" COMPBASE= SHAREDBASE= ! else -!MESSAGE Compilation is unlikely to work like this. Build from VS solution for now. +! if $(BUILD_SYSTEM) == 64 +DEVSTUDIO_HOST=Hostx64 +! else +DEVSTUDIO_HOST=Hostx86 +! endif +! ifdef WIN64 +DEVSTUDIO_TARGET=x64 +! else +DEVSTUDIO_TARGET=x86 +! endif +COMPDIR=$(DEVSTUDIO)\bin\$(DEVSTUDIO_HOST)\$(DEVSTUDIO_TARGET) +RCDIR= +LINKLIBPATH=/LIBPATH:"$(DEVSTUDIO)\lib\$(DEVSTUDIO_TARGET)" ! endif !endif !if $(MSVC_VERSION) == 16 +! ifndef DEVSTUDIO +! if exist("C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional") +DEVSTUDIO_VARIANT=Professional +! else +DEVSTUDIO_VARIANT=Community +! endif +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio\2019\$(DEVSTUDIO_VARIANT)\VC\Tools\MSVC\$(MS_TOOLSET_VERSION) +! endif ! if "$(DEVSTUDIO)"=="" COMPBASE= SHAREDBASE= ! else -!MESSAGE Compilation is unlikely to work like this. Build from VS solution for now. +! if $(BUILD_SYSTEM) == 64 +DEVSTUDIO_HOST=Hostx64 +! else +DEVSTUDIO_HOST=Hostx86 +! endif +! ifdef WIN64 +DEVSTUDIO_TARGET=x64 +! else +DEVSTUDIO_TARGET=x86 +! endif +COMPDIR=$(DEVSTUDIO)\bin\$(DEVSTUDIO_HOST)\$(DEVSTUDIO_TARGET) +RCDIR= +LINKLIBPATH=/LIBPATH:"$(DEVSTUDIO)\lib\$(DEVSTUDIO_TARGET)" ! endif !endif @@ -1114,24 +1147,6 @@ JPX_SSE_CFLAGS= SYNC=winsync !endif -# Luratech jp2 flags depend on the compiler version -# -!if "$(JPX_LIB)" == "luratech" || "$(JPX_LIB)" == "lwf_jp2" -# Set defaults for using the Luratech JP2 implementation -!ifndef JPXSRCDIR -# CSDK source code location -JPXSRCDIR=luratech\lwf_jp2 -!endif -!ifndef JPX_CFLAGS -# required compiler flags -!ifdef WIN64 -JPX_CFLAGS=-DUSE_LWF_JP2 -DWIN64 -DNO_ASSEMBLY -!else -JPX_CFLAGS=-DUSE_LWF_JP2 -DWIN32 -DNO_ASSEMBLY -!endif -!endif -!endif - # OpenJPEG compiler flags # !if "$(JPX_LIB)" == "openjpeg" diff --git a/base/msvctail.mak b/base/msvctail.mak index 9f6f2c5e..e2d81a9a 100644 --- a/base/msvctail.mak +++ b/base/msvctail.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/ocr.mak b/base/ocr.mak index 9d58d008..3c9e2787 100644 --- a/base/ocr.mak +++ b/base/ocr.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -28,7 +28,7 @@ $(GLGEN)libocr.dev : $(LIBOCR_MAK) $(ECHOGS_XE)$(MAKEDIRS)\ # Tesseract veneer. $(GLGEN)tessocr.$(OBJ) : $(GLSRC)tessocr.cpp $(GLSRC)tessocr.h $(LIBOCR_MAK) \ $(gsmemory_h) $(gxiodev_h) $(stream_h) $(TESSDEPS) - $(GLCC) $(D_)LEPTONICA_INTERCEPT_MALLOC=1$(_D) $(TESSINCLUDES) $(I_)$(LEPTONICADIR)$(D)src$(_I) $(GLO_)tessocr.$(OBJ) $(C_) $(GLSRC)tessocr.cpp + $(TESSCXX) $(D_)LEPTONICA_INTERCEPT_MALLOC=1$(_D) $(I_)$(LEPTONICADIR)$(D)src$(_I) $(GLO_)tessocr.$(OBJ) $(C_) $(D_)TESSDATA="$(TESSDATA)"$(_D) $(GLSRC)tessocr.cpp # 0 = No version. diff --git a/base/openjpeg.mak b/base/openjpeg.mak index bb75f0f9..5d44622c 100644 --- a/base/openjpeg.mak +++ b/base/openjpeg.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -64,7 +64,7 @@ open_jpeg_OBJS = \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)thix_manager.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tpix_manager.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)thread.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)sparse_array.$(OBJ) + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)sparse_array.$(OBJ) open_jpeg_HDRS = \ $(OPEN_JPEG_SRC)bio.h \ @@ -115,7 +115,9 @@ $(OPEN_JPEG_GEN)openjpeg_0.dev : $(ECHOGS_XE) $(open_jpeg_OBJS) \ $(SETMOD) $(OPEN_JPEG_GEN)openjpeg_0 $(open_jpeg_OBJS) # define our specific compiler -OPEN_JPEG_CC=$(CC) $(CFLAGS) $(D_)OPJ_STATIC$(_D) $(I_)$(OPEN_JPEG_GEN)$(_I) $(I_)$(JPX_OPENJPEG_I_)$(_I) $(I_)$(JPX_OPENJPEG_I_)$(D)..$(_I) $(JPXCF_) +OPEN_JPEG_CC=$(CC) $(D_)OPJ_STATIC$(_D) $(I_)$(OPEN_JPEG_GEN)$(_I) $(I_)$(JPX_OPENJPEG_I_)$(_I) \ +$(I_)$(JPX_OPENJPEG_I_)$(D)..$(_I) $(JPXCF_) $(CCFLAGS) + OPEN_JPEG_O=$(O_)$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX) OPEN_JPEG_DEP=$(AK) $(OPEN_JPEG_MAK) $(MAKEDIRS) diff --git a/base/openvms.mak b/base/openvms.mak index 8152b944..2260033e 100644 --- a/base/openvms.mak +++ b/base/openvms.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/openvms.mmk b/base/openvms.mmk index 65c2c65f..0b19ff1c 100644 --- a/base/openvms.mmk +++ b/base/openvms.mmk @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/pack_ps.c b/base/pack_ps.c index 2ab4117c..c506b71a 100644 --- a/base/pack_ps.c +++ b/base/pack_ps.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -439,7 +439,7 @@ main(int argc, char *argv[]) #endif /* Display processing statistics. */ - printf(" Processed %d lines of PostScript data.\n", total_code_lines); + printf(" Processed %d lines of PostScript data.\n", total_code_lines); printf(" %d bytes of PostScript data packed down to %d bytes.\n", total_input_length, total_output_length); #if STRIP_PDFR_DEBUG_CALLS printf(" %d PDFR_DEBUG calls removed from the code.\n", pdfr_debug_start_count); diff --git a/base/pcwin.mak b/base/pcwin.mak index 462db460..f0d1598e 100644 --- a/base/pcwin.mak +++ b/base/pcwin.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/pipe_.h b/base/pipe_.h index e6dce031..ad8fda55 100644 --- a/base/pipe_.h +++ b/base/pipe_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/png.mak b/base/png.mak index 2d7b3806..31bcb975 100644 --- a/base/png.mak +++ b/base/png.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -60,7 +60,7 @@ PZGEN=$(ZGENDIR)$(D) # PI_ and PF_ are defined in gs.mak. # NB: we can't use the normal $(CC_) here because msvccmd.mak # adds /Za which conflicts with the libpng 1.5.x source. -PNGCC=$(CC) $(CFLAGS) $(PNG_CFLAGS) $(I_)$(PI_)$(_I) $(I_)$(PNGGENDIR)$(_I) $(PF_) \ +PNGCC=$(CC) $(I_)$(PI_)$(_I) $(I_)$(PNGGENDIR)$(_I) $(PF_) $(CCFLAGS) $(PNG_CFLAGS) \ $(D_)PNG_NO_ASSEMBLER_CODE$(_D) $(D_)PNG_INTEL_SSE_OPT=0$(_D) \ $(D_)PNG_INTEL_SSE_IMPLEMENTATION=0$(_D) $(D_)PNG_ARM_NEON_IMPLEMENTATION=0$(_D) diff --git a/base/png_.h b/base/png_.h index 836f6e83..50a8bafa 100644 --- a/base/png_.h +++ b/base/png_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ramfs.c b/base/ramfs.c index 66893075..88d21552 100644 --- a/base/ramfs.c +++ b/base/ramfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ramfs.h b/base/ramfs.h index 09816ba1..1eaf3174 100644 --- a/base/ramfs.h +++ b/base/ramfs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sa85d.c b/base/sa85d.c index f9fa57fe..4e51e89a 100644 --- a/base/sa85d.c +++ b/base/sa85d.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -135,9 +135,9 @@ s_A85D_process(stream_state * st, stream_cursor_read * pr, * So we allow CR/LF between them. */ /* PDF further relaxes the requirements and accepts bare '~'. */ - while ((p[i] == 13 || p[i] == 10) && (p+i <= rlimit)) + while ((p + i <= rlimit) && (p[i] == 13 || p[i] == 10)) i++; - if (p[i] != '>') { + if (p + i <= rlimit && p[i] != '>') { if (ss->pdf_rules) { if (p[i] == 13 || p[i] == 10) { if (!last) @@ -146,7 +146,7 @@ s_A85D_process(stream_state * st, stream_cursor_read * pr, p--; } } else { - if (p+i == rlimit) { + if (p + i == rlimit) { if (last) status = ERRC; else diff --git a/base/sa85d.h b/base/sa85d.h index 32efeb8d..8b9619dd 100644 --- a/base/sa85d.h +++ b/base/sa85d.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sa85x.h b/base/sa85x.h index aec328c1..cf638590 100644 --- a/base/sa85x.h +++ b/base/sa85x.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/saes.c b/base/saes.c index c580b849..75e1146c 100644 --- a/base/saes.c +++ b/base/saes.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/saes.h b/base/saes.h index 7cf9a5b7..799da357 100644 --- a/base/saes.h +++ b/base/saes.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sarc4.c b/base/sarc4.c index 12c9fe59..d2c85e97 100644 --- a/base/sarc4.c +++ b/base/sarc4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sarc4.h b/base/sarc4.h index 75decd14..b1f63b9c 100644 --- a/base/sarc4.h +++ b/base/sarc4.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sbcp.c b/base/sbcp.c index f61db1b1..979ae099 100644 --- a/base/sbcp.c +++ b/base/sbcp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sbcp.h b/base/sbcp.h index 2c20e1f1..f0e427e5 100644 --- a/base/sbcp.h +++ b/base/sbcp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sbtx.h b/base/sbtx.h index 82850766..d9df3f15 100644 --- a/base/sbtx.h +++ b/base/sbtx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scanchar.h b/base/scanchar.h index ca5ec289..c9f58487 100644 --- a/base/scanchar.h +++ b/base/scanchar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scantab.c b/base/scantab.c index 7240d736..4a652520 100644 --- a/base/scantab.c +++ b/base/scantab.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scf.h b/base/scf.h index 9ee9fa45..dbcb33d3 100644 --- a/base/scf.h +++ b/base/scf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scfd.c b/base/scfd.c index 97fa96b6..1ad2b5ad 100644 --- a/base/scfd.c +++ b/base/scfd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -56,6 +56,9 @@ s_CFD_init(stream_state * st) ROUND_UP((ss->Columns + 7) >> 3, ss->DecodedByteAlign); byte white = (ss->BlackIs1 ? 0 : 0xff); + if (raster < 0) + return ERRC; + s_hcd_init_inline(ss); /* Because skip_white_pixels can look as many as 4 bytes ahead, */ /* we need to allow 4 extra bytes at the end of the row buffers. */ @@ -211,7 +214,7 @@ static inline int invert_data(stream_CFD_state *ss, stream_cursor_read *pr, int if (q >= ss->lbuf + ss->raster + CFD_BUFFER_SLOP) { return(-1); } - + if ( (*rlen) > qbit ) { if (q + ((*rlen - qbit) >> 3) > ss->lbuf + ss->raster + CFD_BUFFER_SLOP) { @@ -536,103 +539,105 @@ cf_decode_1d(stream_CFD_state * ss, stream_cursor_read * pr) cfd_load_state(); if_debug1m('w', ss->memory, "[w1]entry run_color = %d\n", ss->run_color); - if (ss->run_color > 0) + if (run_color > 0) goto db; else goto dw; #define q_at_stop() (q >= stop && (qbit <= end_bit || q > stop)) - top:run_color = 0; - if (q_at_stop()) - goto done; - dw: /* Decode a white run. */ + while (1) + { + run_color = 0; + if (q_at_stop()) + goto done; - cfd_store_state(); - status = get_run(ss, pr, cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits, - &bcnt, "[w1]white"); - cfd_load_state(); - if (status < 0) { - goto out0; - } + dw: /* Decode a white run. */ + do { + cfd_store_state(); + status = get_run(ss, pr, cf_white_decode, cfd_white_initial_bits, + cfd_white_min_bits, &bcnt, "[w1]white"); + cfd_load_state(); + if (status < 0) { + /* We already set run_color to 0 or -1. */ + status = 0; + goto out; + } - if (bcnt < 0) { /* exceptional situation */ - switch (bcnt) { - case run_uncompressed: /* Uncompressed data. */ - cfd_store_state(); - bcnt = cf_decode_uncompressed(ss, pr); - if (bcnt < 0) - return bcnt; - cfd_load_state(); - if (bcnt) - goto db; - else - goto dw; - /*case run_error: */ - /*case run_zeros: *//* Premature end-of-line. */ - default: + if (bcnt < 0) { /* exceptional situation */ + switch (bcnt) { + case run_uncompressed: /* Uncompressed data. */ + cfd_store_state(); + bcnt = cf_decode_uncompressed(ss, pr); + if (bcnt < 0) + return bcnt; + cfd_load_state(); + if (bcnt) + goto db; + else + continue; /* Restart decoding white */ + /*case run_error: */ + /*case run_zeros: *//* Premature end-of-line. */ + default: + status = ERRC; + goto out; + } + } + + cfd_store_state(); + status = skip_data(ss, pr, bcnt); + cfd_load_state(); + if (status < 0) { + /* If we run out of data after a makeup code, */ + /* note that we are still processing a white run. */ + run_color = -1; + } + } while (status < 0); + + if (q_at_stop()) { + run_color = 0; /* not inside a run */ + done: + if (q > stop || qbit < end_bit) status = ERRC; - goto out; + else + status = 1; + break; } - } + run_color = 1; - cfd_store_state(); - status = skip_data(ss, pr, bcnt); - cfd_load_state(); - if (status < 0) { - goto dwx; - } - - if (q_at_stop()) { - run_color = 0; /* not inside a run */ - goto done; - } - run_color = 1; - db: /* Decode a black run. */ + db: /* Decode a black run. */ + do { + cfd_store_state(); + status = get_run(ss, pr, cf_black_decode, cfd_black_initial_bits, + cfd_black_min_bits, &bcnt, "[w1]black"); + cfd_load_state(); + if (status < 0) { + /* We already set run_color to 1 or 2. */ + status = 0; + goto out; + } - cfd_store_state(); - status = get_run(ss, pr, cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits, - &bcnt, "[w1]black"); - cfd_load_state(); - if (status < 0) { - goto out1; - } + if (bcnt < 0) { /* All exceptional codes are invalid here. */ + /****** WRONG, uncompressed IS ALLOWED ******/ + status = ERRC; + goto out; + } - if (bcnt < 0) { /* All exceptional codes are invalid here. */ - /****** WRONG, uncompressed IS ALLOWED ******/ - status = ERRC; - goto out; + /* Invert bits designated by black run. */ + cfd_store_state(); + status = invert_data(ss, pr, &bcnt, black_byte); + cfd_load_state(); + if (status < 0) { + /* If we run out of data after a makeup code, */ + /* note that we are still processing a black run. */ + run_color = 2; + } + } while (status < 0); } - /* Invert bits designated by black run. */ +out: cfd_store_state(); - status = invert_data(ss, pr, &bcnt, black_byte); - cfd_load_state(); - if (status < 0) { - goto dbx; - } - - goto top; - dwx: /* If we run out of data after a makeup code, */ - /* note that we are still processing a white run. */ - run_color = -1; - goto dw; - dbx: /* If we run out of data after a makeup code, */ - /* note that we are still processing a black run. */ - run_color = 2; - goto db; - done:if (q > stop || qbit < end_bit) - status = ERRC; - else - status = 1; - out:cfd_store_state(); ss->run_color = run_color; if_debug1m('w', ss->memory, "[w1]exit run_color = %d\n", run_color); return status; - out0: /* We already set run_color to 0 or -1. */ - status = 0; - goto out; - out1: /* We already set run_color to 1 or 2. */ - status = 0; - goto out; } /* Decode a 2-D scan line. */ @@ -673,35 +678,45 @@ cf_decode_2d(stream_CFD_state * ss, stream_cursor_read * pr) goto hbb; /*case 0: */ } - top:if (count <= end_count) { - status = (count < end_count ? ERRC : 1); - goto out; - } - /* If invert == invert_white, white and black have their */ - /* correct meanings; if invert == ~invert_white, */ - /* black and white are interchanged. */ - if_debug1m('W', ss->memory, "[w2]%4d:\n", count); -#ifdef DEBUG - /* Check the invariant between q, qbit, and count. */ + + /* top of decode loop */ + while (1) { - int pcount = (endptr - q) * 8 + qbit; + if (count <= end_count) { + status = (count < end_count ? ERRC : 1); + goto out; + } + /* If invert == invert_white, white and black have their */ + /* correct meanings; if invert == ~invert_white, */ + /* black and white are interchanged. */ + if_debug1m('W', ss->memory, "[w2]%4d:\n", count); +#ifdef DEBUG + /* Check the invariant between q, qbit, and count. */ + { + int pcount = (endptr - q) * 8 + qbit; - if (pcount != count) - dmlprintf2(ss->memory, "[w2]Error: count=%d pcount=%d\n", - count, pcount); - } + if (pcount != count) + dmlprintf2(ss->memory, "[w2]Error: count=%d pcount=%d\n", + count, pcount); + } #endif - /* - * We could just use get_run here, but we can do better. However, - * we must be careful to handle the case where the very last codes - * in the input stream are 1-bit "vertical 0" codes: we can't just - * use ensure_bits(3, ...) and go to get more data if it fails. - */ - ensure_bits(3, out3); + /* + * We could just use get_run here, but we can do better. However, + * we must be careful to handle the case where the very last codes + * in the input stream are 1-bit "vertical 0" codes: we can't just + * use ensure_bits(3, ...) and go to get more data if it fails. + */ + ensure_bits(3, out3); #define vertical_0 (countof(cf2_run_vertical) / 2) - switch (peek_bits(3)) { + switch (peek_bits(3)) { default /*4..7*/ : /* vertical(0) */ -v0: skip_bits(1); + if (0) { + out3: + /* Unless it's a 1-bit "vertical 0" code, exit. */ + if (!(bits_left > 0 && peek_bits(1))) + goto out0; + } + skip_bits(1); rlen = vertical_0; break; case 2: /* vertical(+1) */ @@ -714,14 +729,111 @@ v0: skip_bits(1); break; case 1: /* horizontal */ skip_bits(3); - if (invert == invert_white) - goto hww; - else - goto hbb; + if (invert == invert_white) { + /* We handle horizontal decoding here, so that we can + * branch back into it if we run out of input data. */ + /* White, then black. */ + hww: + do { + cfd_store_state(); + status = get_run(ss, pr, cf_white_decode, + cfd_white_initial_bits, + cfd_white_min_bits, &rlen, " white"); + cfd_load_state(); + if (status < 0) { + ss->run_color = -2; + goto out0; + } + + if ((count -= rlen) < end_count) { + status = ERRC; + goto out; + } + if (rlen < 0) goto rlen_lt_zero; + + cfd_store_state(); + status = skip_data(ss, pr, rlen); + cfd_load_state(); + } while (status < 0); + + /* Handle the second half of a white-black horizontal code. */ + hwb: + do { + cfd_store_state(); + status = get_run(ss, pr, cf_black_decode, + cfd_black_initial_bits, + cfd_black_min_bits, &rlen, " black"); + cfd_load_state(); + if (status < 0){ + ss->run_color = 1; + goto out0; + } + + if ((count -= rlen) < end_count) { + status = ERRC; + goto out; + } + if (rlen < 0) goto rlen_lt_zero; + + cfd_store_state(); + status = invert_data(ss, pr, &rlen, black_byte); + cfd_load_state(); + } while (status < 0); + } else { + /* Black, then white. */ + hbb: + do { + cfd_store_state(); + status = get_run(ss, pr, cf_black_decode, + cfd_black_initial_bits, + cfd_black_min_bits, &rlen, " black"); + cfd_load_state(); + if (status < 0) { + ss->run_color = 2; + goto out0; + } + + if ((count -= rlen) < end_count) { + status = ERRC; + goto out; + } + if (rlen < 0) goto rlen_lt_zero; + + cfd_store_state(); + status = invert_data(ss, pr, &rlen, black_byte); + cfd_load_state(); + } + while (status < 0); + + /* Handle the second half of a black-white horizontal code. */ + hbw: + do { + cfd_store_state(); + status = get_run(ss, pr, cf_white_decode, + cfd_white_initial_bits, + cfd_white_min_bits, &rlen, " white"); + cfd_load_state(); + if (status < 0) { + ss->run_color = -1; + goto out0; + } + + if ((count -= rlen) < end_count) { + status = ERRC; + goto out; + } + if (rlen < 0) goto rlen_lt_zero; + + cfd_store_state(); + status = skip_data(ss, pr, rlen); + cfd_load_state(); + } while (status < 0); + } + continue; /* jump back to top of decode loop */ case 0: /* everything else */ cfd_store_state(); - status = get_run(ss, pr, cf_2d_decode, cfd_2d_initial_bits, cfd_2d_min_bits, - &rlen, "[w2]"); + status = get_run(ss, pr, cf_2d_decode, cfd_2d_initial_bits, + cfd_2d_min_bits, &rlen, "[w2]"); cfd_load_state(); if (status < 0) { goto out0; @@ -729,105 +841,102 @@ v0: skip_bits(1); /* rlen may be run2_pass, run_uncompressed, or */ /* 0..countof(cf2_run_vertical)-1. */ + if (rlen < 0) { rlen_lt_zero: - if (rlen < 0) switch (rlen) { - case run2_pass: - break; - case run_uncompressed: - { - int which; - - cfd_store_state(); - which = cf_decode_uncompressed(ss, pr); - if (which < 0) { - status = which; - goto out; - } - cfd_load_state(); -/****** ADJUST count ******/ - invert = (which ? ~invert_white : invert_white); - } - goto top; - default: /* run_error, run_zeros */ - status = ERRC; + case run2_pass: + break; + case run_uncompressed: + { + int which; + + cfd_store_state(); + which = cf_decode_uncompressed(ss, pr); + if (which < 0) { + status = which; goto out; + } + cfd_load_state(); +/****** ADJUST count ******/ + invert = (which ? ~invert_white : invert_white); + continue; /* jump back to top of decode loop */ } - } - /* Interpreting the run requires scanning the */ - /* previous ('reference') line. */ - { - int prev_count = count; - byte prev_data; - int dlen; - static const byte count_bit[8] = - {0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40}; - byte *prev_q = prev_q01 + (q - q0); - int plen; - - if (!(count & 7)) - prev_q++; /* because of skip macros */ - prev_data = prev_q[-1] ^ invert; - /* Find the b1 transition. */ - if ((prev_data & count_bit[prev_count & 7]) && - (prev_count < init_count || invert != invert_white) - ) { /* Look for changing white first. */ - if_debug1m('W', ss->memory, " data=0x%x", prev_data); - skip_black_pixels(prev_data, prev_q, - prev_count, invert, plen); - if (prev_count < end_count) /* overshot */ - prev_count = end_count; - if_debug1m('W', ss->memory, " b1 other=%d", prev_count); - } - if (prev_count != end_count) { - if_debug1m('W', ss->memory, " data=0x%x", prev_data); - skip_white_pixels(prev_data, prev_q, - prev_count, invert, plen); - if (prev_count < end_count) /* overshot */ - prev_count = end_count; - if_debug1m('W', ss->memory, " b1 same=%d", prev_count); + default: /* run_error, run_zeros */ + status = ERRC; + goto out; + } + } } - /* b1 = prev_count; */ - if (rlen == run2_pass) { /* Pass mode. Find b2. */ - if (prev_count != end_count) { + /* Interpreting the run requires scanning the */ + /* previous ('reference') line. */ + { + int prev_count = count; + byte prev_data; + int dlen; + static const byte count_bit[8] = + {0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40}; + byte *prev_q = prev_q01 + (q - q0); + int plen; + + if (!(count & 7)) + prev_q++; /* because of skip macros */ + prev_data = prev_q[-1] ^ invert; + /* Find the b1 transition. */ + if ((prev_data & count_bit[prev_count & 7]) && + (prev_count < init_count || invert != invert_white) + ) { /* Look for changing white first. */ if_debug1m('W', ss->memory, " data=0x%x", prev_data); skip_black_pixels(prev_data, prev_q, prev_count, invert, plen); - if (prev_count < end_count) /* overshot */ + if (prev_count < end_count) /* overshot */ prev_count = end_count; + if_debug1m('W', ss->memory, " b1 other=%d", prev_count); } - /* b2 = prev_count; */ - if_debug2m('W', ss->memory, " b2=%d, pass %d\n", - prev_count, count - prev_count); - } else { /* Vertical coding. */ - /* Remember that count counts *down*. */ - prev_count += rlen - vertical_0; /* a1 */ - if_debug2m('W', ss->memory, " vertical %d -> %d\n", - (int)(rlen - vertical_0), prev_count); - } - /* Now either invert or skip from count */ - /* to prev_count, and reset count. */ - if (invert == invert_white) { /* Skip data bits. */ - q = endptr - (prev_count >> 3); - qbit = prev_count & 7; - } else { /* Invert data bits. */ - dlen = count - prev_count; + if (prev_count != end_count) { + if_debug1m('W', ss->memory, " data=0x%x", prev_data); + skip_white_pixels(prev_data, prev_q, + prev_count, invert, plen); + if (prev_count < end_count) /* overshot */ + prev_count = end_count; + if_debug1m('W', ss->memory, " b1 same=%d", prev_count); + } + /* b1 = prev_count; */ + if (rlen == run2_pass) { /* Pass mode. Find b2. */ + if (prev_count != end_count) { + if_debug1m('W', ss->memory, " data=0x%x", prev_data); + skip_black_pixels(prev_data, prev_q, + prev_count, invert, plen); + if (prev_count < end_count) /* overshot */ + prev_count = end_count; + } + /* b2 = prev_count; */ + if_debug2m('W', ss->memory, " b2=%d, pass %d\n", + prev_count, count - prev_count); + } else { /* Vertical coding. */ + /* Remember that count counts *down*. */ + prev_count += rlen - vertical_0; /* a1 */ + if_debug2m('W', ss->memory, " vertical %d -> %d\n", + (int)(rlen - vertical_0), prev_count); + } + /* Now either invert or skip from count */ + /* to prev_count, and reset count. */ + if (invert == invert_white) { /* Skip data bits. */ + q = endptr - (prev_count >> 3); + qbit = prev_count & 7; + } else { /* Invert data bits. */ + dlen = count - prev_count; - cfd_store_state(); - (void)invert_data(ss, pr, &dlen, black_byte); - cfd_load_state(); + cfd_store_state(); + (void)invert_data(ss, pr, &dlen, black_byte); + cfd_load_state(); + } + count = prev_count; + if (rlen >= 0) /* vertical mode */ + invert = ~invert; /* polarity changes */ } - count = prev_count; - if (rlen >= 0) /* vertical mode */ - invert = ~invert; /* polarity changes */ - } - goto top; - out3: - if (bits_left > 0 && peek_bits(1)) { - /* This is a 1-bit "vertical 0" code, which we can still process. */ - goto v0; + /* jump back to top of decode loop */ } - /* falls through */ + out0:status = 0; /* falls through */ out:cfd_store_state(); @@ -837,116 +946,6 @@ rlen_lt_zero: if (status == ERRC && ss->Rows > 0 && ss->row > ss->Rows) status = EOFC; return status; - /* - * We handle horizontal decoding here, so that we can - * branch back into it if we run out of input data. - */ - /* White, then black. */ - hww: - - cfd_store_state(); - status = get_run(ss, pr, cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits, - &rlen, " white"); - cfd_load_state(); - if (status < 0) { - goto outww; - } - - if ((count -= rlen) < end_count) { - status = ERRC; - goto out; - } - if (rlen < 0) goto rlen_lt_zero; - - cfd_store_state(); - status = skip_data(ss, pr, rlen); - cfd_load_state(); - if (status < 0) { - goto hww; - } - - /* Handle the second half of a white-black horizontal code. */ - hwb: - - cfd_store_state(); - status = get_run(ss, pr, cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits, - &rlen, " black"); - cfd_load_state(); - if (status < 0){ - goto outwb; - } - - if ((count -= rlen) < end_count) { - status = ERRC; - goto out; - } - if (rlen < 0) goto rlen_lt_zero; - - cfd_store_state(); - status = invert_data(ss, pr, &rlen, black_byte); - cfd_load_state(); - if (status < 0) { - goto hwb; - } - - goto top; - outww:ss->run_color = -2; - goto out0; - outwb:ss->run_color = 1; - goto out0; - /* Black, then white. */ - hbb: - - cfd_store_state(); - status = get_run(ss, pr, cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits, - &rlen, " black"); - cfd_load_state(); - if (status < 0) { - goto outbb; - } - - if ((count -= rlen) < end_count) { - status = ERRC; - goto out; - } - if (rlen < 0) goto rlen_lt_zero; - - cfd_store_state(); - status = invert_data(ss, pr, &rlen, black_byte); - cfd_load_state(); - if (status < 0) { - goto hbb; - } - - /* Handle the second half of a black-white horizontal code. */ - hbw: - - cfd_store_state(); - status = get_run(ss, pr, cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits, - &rlen, " white"); - cfd_load_state(); - if (status < 0) { - goto outbw; - } - - if ((count -= rlen) < end_count) { - status = ERRC; - goto out; - } - if (rlen < 0) goto rlen_lt_zero; - - cfd_store_state(); - status = skip_data(ss, pr, rlen); - cfd_load_state(); - if (status < 0) { - goto hbw; - } - - goto top; - outbb:ss->run_color = 2; - goto out0; - outbw:ss->run_color = -1; - goto out0; } #if 1 /*************** */ diff --git a/base/scfdgen.c b/base/scfdgen.c index ff67c6a5..263cf75a 100644 --- a/base/scfdgen.c +++ b/base/scfdgen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scfdtab.c b/base/scfdtab.c index a3d14d2f..16a11bb0 100644 --- a/base/scfdtab.c +++ b/base/scfdtab.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scfe.c b/base/scfe.c index 43723520..13e56fe7 100644 --- a/base/scfe.c +++ b/base/scfe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scfetab.c b/base/scfetab.c index d0501030..27a07c5f 100644 --- a/base/scfetab.c +++ b/base/scfetab.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scfparam.c b/base/scfparam.c index 559bbe51..d95ae98d 100644 --- a/base/scfparam.c +++ b/base/scfparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scfx.h b/base/scfx.h index 5efd021a..a9e1e741 100644 --- a/base/scfx.h +++ b/base/scfx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/scommon.h b/base/scommon.h index 6e41259b..d8bdda8c 100644 --- a/base/scommon.h +++ b/base/scommon.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -108,6 +108,43 @@ typedef union stream_cursor_s { stream_cursor_write w; } stream_cursor; +/* The following two inline functions are here to keep the nasty + * cursor initialisation (that ptr is initialised to one byte + * /before/ the beginning of the buffer) in the one place, + * rather than everywhere that uses short lived streams. + * This allows localized disabling of the "array bounds" compiler + * warning for this one specific case. + */ +static inline void +stream_cursor_read_init(stream_cursor_read *r, const byte *buf, size_t length) +{ +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + /* starting pos for pointer is always one position back */ + r->ptr = buf - 1; + r->limit = r->ptr + length; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif +} + +static inline void +stream_cursor_write_init(stream_cursor_write *w, const byte *buf, size_t length) +{ +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + /* starting pos for pointer is always one position back */ + w->ptr = (byte *)buf - 1; + w->limit = (byte *)w->ptr + length; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif +} + /* * Define the prototype for the procedures known to both the generic * stream code and the stream implementations. diff --git a/base/sdcparam.c b/base/sdcparam.c index a4ae9048..18f663e4 100644 --- a/base/sdcparam.c +++ b/base/sdcparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sdcparam.h b/base/sdcparam.h index 722a9eb2..8786c194 100644 --- a/base/sdcparam.h +++ b/base/sdcparam.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sdct.h b/base/sdct.h index 57e9e87a..11a98a31 100644 --- a/base/sdct.h +++ b/base/sdct.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sdctc.c b/base/sdctc.c index 5a1679d3..8fe3d401 100644 --- a/base/sdctc.c +++ b/base/sdctc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -65,6 +65,7 @@ stream_dct_finalize(const gs_memory_t *cmem, void *vptr) st->templat = &s_DCTE_template; } else { + stream_dct_end_passthrough(ss->data.decompress); gs_jpeg_destroy(ss); if (ss->data.decompress != NULL) { if (ss->data.decompress->scanline_buffer != NULL) { @@ -87,10 +88,11 @@ stream_dct_end_passthrough(jpeg_decompress_data *jddp) { char EOI[2] = {0xff, 0xD9}; - if (jddp->PassThrough && jddp->PassThroughfn) { + if (jddp != NULL && jddp->PassThrough != 0 && jddp->PassThroughfn != NULL) { (jddp->PassThroughfn)(jddp->device, (byte *)EOI, 2); (jddp->PassThroughfn)(jddp->device, NULL, 0); jddp->PassThrough = 0; jddp->PassThroughfn = NULL; + jddp->StartedPassThrough = 0; } } diff --git a/base/sdctd.c b/base/sdctd.c index ec54a9e2..635aa6fc 100644 --- a/base/sdctd.c +++ b/base/sdctd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -239,8 +239,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, u.c = pr->ptr+1; update_jpeg_header_height(u.u, src->bytes_in_buffer, ss->data.common->Height); } - if ((code = gs_jpeg_read_header(ss, TRUE)) < 0) - return ERRC; + if ((code = gs_jpeg_read_header(ss, TRUE)) < 0) { + code = ERRC; + goto error_out; + } pr->ptr = (jddp->faked_eoi ? pr->limit : src->next_input_byte - 1); switch (code) { @@ -251,7 +253,7 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, /*case JPEG_HEADER_OK: */ } - /* + /* * Default the color transform if not set and check for * the Adobe marker and use Adobe's transform if the * marker is set. @@ -262,10 +264,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, else ss->ColorTransform = 0; } - + if (jddp->dinfo.saw_Adobe_marker) ss->ColorTransform = jddp->dinfo.Adobe_transform; - + switch (jddp->dinfo.num_components) { case 3: jddp->dinfo.jpeg_color_space = @@ -281,8 +283,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, ss->phase = 2; /* falls through */ case 2: /* start_decompress */ - if ((code = gs_jpeg_start_decompress(ss)) < 0) - return ERRC; + if ((code = gs_jpeg_start_decompress(ss)) < 0) { + code = ERRC; + goto error_out; + } pr->ptr = (jddp->faked_eoi ? pr->limit : src->next_input_byte - 1); if (code == 0) { @@ -302,8 +306,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, gs_alloc_bytes_immovable(gs_memory_stable(jddp->memory), ss->scan_line_size, "s_DCTD_process(scanline_buffer)"); - if (jddp->scanline_buffer == NULL) - return ERRC; + if (jddp->scanline_buffer == NULL) { + code = ERRC; + goto error_out; + } } jddp->bytes_in_scanline = 0; ss->phase = 3; @@ -357,8 +363,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, samples = pw->ptr + 1; } read = gs_jpeg_read_scanlines(ss, &samples, 1); - if (read < 0) - return ERRC; + if (read < 0) { + code = ERRC; + goto error_out; + } if_debug3m('w', ss->memory, "[wdd]read returns %d, used=%u, faked_eoi=%d\n", read, (uint) (src->next_input_byte - 1 - pr->ptr), @@ -380,8 +388,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, * buffer can be grown as required. */ if ((src->next_input_byte-1 == pr->ptr) && (pr->limit - pr->ptr >= ss->templat->min_in_size) && - (compact_jpeg_buffer(pr) == 0)) - return ERRC; + (compact_jpeg_buffer(pr) == 0)) { + code = ERRC; + goto error_out; + } if (jddp->PassThrough && jddp->PassThroughfn) { (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); } @@ -398,8 +408,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, case 4: /* end of image; scan for EOI */ if (jddp->PassThrough && jddp->PassThroughfn) (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); - if ((code = gs_jpeg_finish_decompress(ss)) < 0) - return ERRC; + if ((code = gs_jpeg_finish_decompress(ss)) < 0) { + code = ERRC; + goto error_out; + } pr->ptr = (jddp->faked_eoi ? pr->limit : src->next_input_byte - 1); if (code == 0) @@ -411,6 +423,10 @@ s_DCTD_process(stream_state * st, stream_cursor_read * pr, } /* Default case can't happen.... */ return ERRC; + +error_out: + stream_dct_end_passthrough(jddp); + return code; } /* Stream template */ diff --git a/base/sdcte.c b/base/sdcte.c index ecbaf655..1fd16a49 100644 --- a/base/sdcte.c +++ b/base/sdcte.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -25,7 +25,7 @@ #include "sdct.h" #include "sjpeg.h" -#define ICC_OVERHEAD 16 +#define ICC_OVERHEAD 16 #define MAX_MARKER_DATA_SIZE (65535 - ICC_OVERHEAD) public_st_jpeg_compress_data(); @@ -135,9 +135,9 @@ s_DCTE_process(stream_state * st, stream_cursor_read * pr, dest->free_in_buffer = pw->limit - pw->ptr; ss->phase = 3; /* falls through */ - case 3: + case 3: /* If we have it, then write out the ICC profile */ - /* Due to size limitations allowed in APP0 markers, the profile + /* Due to size limitations allowed in APP0 markers, the profile may have to be written in mutiple markers */ if (ss->icc_profile != NULL) { static const char marker[2] = {0xFF, 0xE2}; /* JPEG_APP0 + 2 */ @@ -156,7 +156,7 @@ s_DCTE_process(stream_state * st, stream_cursor_read * pr, if (size > MAX_MARKER_DATA_SIZE) size = MAX_MARKER_DATA_SIZE; - /* In this case we are just getting started with the + /* In this case we are just getting started with the header of the marker. Write that portion out */ if (ss->icc_position == -1) { byte length_byte[2]; diff --git a/base/sddparam.c b/base/sddparam.c index deff93b9..63c07d05 100644 --- a/base/sddparam.c +++ b/base/sddparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sdeparam.c b/base/sdeparam.c index 5d269028..8eaf44cd 100644 --- a/base/sdeparam.c +++ b/base/sdeparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/seexec.c b/base/seexec.c index 4f86d554..f3eb4cfe 100644 --- a/base/seexec.c +++ b/base/seexec.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/setjmp_.h b/base/setjmp_.h index 4ba2faa9..a61ff07c 100644 --- a/base/setjmp_.h +++ b/base/setjmp_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sfilter.h b/base/sfilter.h index 4ba8dd63..1b42d948 100644 --- a/base/sfilter.h +++ b/base/sfilter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sfilter1.c b/base/sfilter1.c index c6fac79e..68785d2b 100644 --- a/base/sfilter1.c +++ b/base/sfilter1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sfilter2.c b/base/sfilter2.c index 86be1d86..2f6c89ac 100644 --- a/base/sfilter2.c +++ b/base/sfilter2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -83,92 +83,95 @@ s_A85E_process(stream_state * st, stream_cursor_read * pr, uint v2 = v3 / 85; /* max 85^2 */ uint v1 = v2 / 85; /* max 85 */ -put: if (q + 5 > qn) { - if (q >= wlimit) { + while (1) { + /* Put some bytes */ + while (q + 5 > qn) { + if (q >= wlimit) { + status = 1; + goto end; + } + *++q = prev = '\n'; + qn = q + LINE_LIMIT; + if_debug1m('w', ss->memory, "[w85]EOL at %d bytes written\n", + (int)(q - pw->ptr)); + } + if (wlimit - q < 5) { status = 1; - break; + goto end; } - *++q = prev = '\n'; - qn = q + LINE_LIMIT; - if_debug1m('w', ss->memory, "[w85]EOL at %d bytes written\n", - (int)(q - pw->ptr)); - goto put; - } - if (wlimit - q < 5) { - status = 1; - break; - } - q[1] = (byte) v1 + '!'; - q[2] = (byte) (v2 - v1 * 85) + '!'; - q[3] = (byte) ((uint) v3 - v2 * 85) + '!'; - q[4] = (byte) ((uint) v4 - (uint) v3 * 85) + '!'; - q[5] = (byte) ((uint) word - (uint) v4 * 85) + '!'; - /* - * '%%' or '%!' at the beginning of the line will confuse some - * document managers: insert (an) EOL(s) if necessary to prevent - * this. - */ - if (q[1] == '%') { - if (prev == '%') { - if (qn - q == LINE_LIMIT - 1) { - /* A line would begin with %%. */ - *++q = prev = '\n'; - qn = q + LINE_LIMIT; - if_debug1m('w', ss->memory, - "[w85]EOL for %%%% at %d bytes written\n", - (int)(q - pw->ptr)); - goto put; - } - } else if (prev == '\n' && (q[2] == '%' || q[2] == '!')) { - /* - * We may have to insert more than one EOL if - * there are more than two %s in a row. - */ - int extra = - (q[2] == '!' ? 1 : /* else q[2] == '%' */ - q[3] == '!' ? 2 : - q[3] != '%' ? 1 : - q[4] == '!' ? 3 : - q[4] != '%' ? 2 : - q[5] == '!' ? 4 : - q[5] != '%' ? 3 : 4); + q[1] = (byte) v1 + '!'; + q[2] = (byte) (v2 - v1 * 85) + '!'; + q[3] = (byte) ((uint) v3 - v2 * 85) + '!'; + q[4] = (byte) ((uint) v4 - (uint) v3 * 85) + '!'; + q[5] = (byte) ((uint) word - (uint) v4 * 85) + '!'; + /* + * '%%' or '%!' at the beginning of the line will confuse some + * document managers: insert (an) EOL(s) if necessary to prevent + * this. + */ + if (q[1] == '%') { + if (prev == '%') { + if (qn - q == LINE_LIMIT - 1) { + /* A line would begin with %%. */ + *++q = prev = '\n'; + qn = q + LINE_LIMIT; + if_debug1m('w', ss->memory, + "[w85]EOL for %%%% at %d bytes written\n", + (int)(q - pw->ptr)); + continue; /* Put some more bytes */ + } + } else if (prev == '\n' && (q[2] == '%' || q[2] == '!')) { + /* + * We may have to insert more than one EOL if + * there are more than two %s in a row. + */ + int extra = + (q[2] == '!' ? 1 : /* else q[2] == '%' */ + q[3] == '!' ? 2 : + q[3] != '%' ? 1 : + q[4] == '!' ? 3 : + q[4] != '%' ? 2 : + q[5] == '!' ? 4 : + q[5] != '%' ? 3 : 4); - if (wlimit - q < 5 + extra) { - status = 1; - break; + if (wlimit - q < 5 + extra) { + status = 1; + goto end; + } + if_debug6m('w', ss->memory, "[w]%c%c%c%c%c extra = %d\n", + q[1], q[2], q[3], q[4], q[5], extra); + switch (extra) { + case 4: + q[9] = q[5], q[8] = '\n'; + goto e3; + case 3: + q[8] = q[5]; + e3:q[7] = q[4], q[6] = '\n'; + goto e2; + case 2: + q[7] = q[5], q[6] = q[4]; + e2:q[5] = q[3], q[4] = '\n'; + goto e1; + case 1: + q[6] = q[5], q[5] = q[4], q[4] = q[3]; + e1:q[3] = q[2], q[2] = '\n'; + } + if_debug1m('w', ss->memory, "[w85]EOL at %d bytes written\n", + (int)(q + 2 * extra - pw->ptr)); + qn = q + 2 * extra + LINE_LIMIT; + q += extra; } - if_debug6m('w', ss->memory, "[w]%c%c%c%c%c extra = %d\n", - q[1], q[2], q[3], q[4], q[5], extra); - switch (extra) { - case 4: - q[9] = q[5], q[8] = '\n'; - goto e3; - case 3: - q[8] = q[5]; - e3:q[7] = q[4], q[6] = '\n'; - goto e2; - case 2: - q[7] = q[5], q[6] = q[4]; - e2:q[5] = q[3], q[4] = '\n'; - goto e1; - case 1: - q[6] = q[5], q[5] = q[4], q[4] = q[3]; - e1:q[3] = q[2], q[2] = '\n'; - } - if_debug1m('w', ss->memory, "[w85]EOL at %d bytes written\n", - (int)(q + 2 * extra - pw->ptr)); - qn = q + 2 * extra + LINE_LIMIT; - q += extra; + } else if (q[1] == '!' && prev == '%' && + qn - q == LINE_LIMIT - 1 + ) { + /* A line would begin with %!. */ + *++q = prev = '\n'; + qn = q + LINE_LIMIT; + if_debug1m('w', ss->memory, "[w85]EOL for %%! at %d bytes written\n", + (int)(q - pw->ptr)); + continue; /* Put some more bytes */ } - } else if (q[1] == '!' && prev == '%' && - qn - q == LINE_LIMIT - 1 - ) { - /* A line would begin with %!. */ - *++q = prev = '\n'; - qn = q + LINE_LIMIT; - if_debug1m('w', ss->memory, "[w85]EOL for %%! at %d bytes written\n", - (int)(q - pw->ptr)); - goto put; + break; } prev = *(q += 5); } diff --git a/base/sfxboth.c b/base/sfxboth.c index 02982ab3..7b782478 100644 --- a/base/sfxboth.c +++ b/base/sfxboth.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sfxcommon.c b/base/sfxcommon.c index bc2285d9..e506bd64 100644 --- a/base/sfxcommon.c +++ b/base/sfxcommon.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sfxfd.c b/base/sfxfd.c index 7f9d204c..caa00d09 100644 --- a/base/sfxfd.c +++ b/base/sfxfd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sfxstdio.c b/base/sfxstdio.c index 6201ddf9..8fc88256 100644 --- a/base/sfxstdio.c +++ b/base/sfxstdio.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/shc.c b/base/shc.c index 60b117dd..2439c831 100644 --- a/base/shc.c +++ b/base/shc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/shc.h b/base/shc.h index 36dcf1a0..b7ae66d1 100644 --- a/base/shc.h +++ b/base/shc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sidscale.c b/base/sidscale.c index 9415d854..57c2b37c 100644 --- a/base/sidscale.c +++ b/base/sidscale.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -240,9 +240,9 @@ s_ISpecialDownScale_init(stream_state * st) ss->sizeofPixelIn = ss->params.BitsPerComponentIn / 8; ss->sizeofPixelOut = ss->params.BitsPerComponentOut / 8; - ss->src_size = + ss->src_size = ss->params.WidthIn * ss->sizeofPixelIn * ss->params.spp_interp; - ss->dst_size = + ss->dst_size = ss->params.WidthOut * ss->sizeofPixelOut * ss->params.spp_interp; /* Initialize destination DDAs. */ @@ -254,14 +254,14 @@ s_ISpecialDownScale_init(stream_state * st) dda_init(ss->dda_y, 0, ss->params.HeightOut, ss->params.HeightIn); /* create intermediate image to hold horizontal zoom */ - ss->tmp = + ss->tmp = gs_alloc_byte_array(mem, (size_t)ss->params.WidthOut * ss->params.spp_interp, ss->sizeofPixelIn, "image_scale tmp"); /* Allocate buffers for 1 row of source and destination. */ - ss->dst = + ss->dst = gs_alloc_byte_array(mem, (size_t)ss->params.WidthOut * ss->params.spp_interp, ss->sizeofPixelOut, "image_scale dst"); - ss->src = + ss->src = gs_alloc_byte_array(mem, (size_t)ss->params.WidthIn * ss->params.spp_interp, ss->sizeofPixelIn, "image_scale src"); if (ss->tmp == 0 || ss->dst == 0 || ss->src == 0) { diff --git a/base/sidscale.h b/base/sidscale.h index e74fb399..08b28f81 100644 --- a/base/sidscale.h +++ b/base/sidscale.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/siinterp.c b/base/siinterp.c index 591de4c8..1eae896e 100644 --- a/base/siinterp.c +++ b/base/siinterp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/siinterp.h b/base/siinterp.h index 84dc76d3..30f95724 100644 --- a/base/siinterp.h +++ b/base/siinterp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/simscale.c b/base/simscale.c index e01b352c..4b544b68 100644 --- a/base/simscale.c +++ b/base/simscale.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/simscale.h b/base/simscale.h index e6ad7e46..8726a891 100644 --- a/base/simscale.h +++ b/base/simscale.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/simscale_foo.c b/base/simscale_foo.c index bae9d5c7..67fda0d8 100644 --- a/base/simscale_foo.c +++ b/base/simscale_foo.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Artifex Software, Inc. +/* Copyright (C) 2020-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -123,7 +123,7 @@ unsigned int imscale_foo(unsigned int v5x5) { unsigned int r3 = ( v5x5 >> 20 ) & 0x1f; unsigned int r4 = ( v5x5 >> 25 ) & 0x1f; #endif - + switch(v3x3) { case 0: case 1: diff --git a/base/simscale_foo.h b/base/simscale_foo.h index 8d52a139..471fe4fa 100644 --- a/base/simscale_foo.h +++ b/base/simscale_foo.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Artifex Software, Inc. +/* Copyright (C) 2020-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/siscale.c b/base/siscale.c index cc575d20..5bf212c1 100644 --- a/base/siscale.c +++ b/base/siscale.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -930,7 +930,7 @@ do_init(stream_state *st, ss->sizeofPixelOut = ss->params.BitsPerComponentOut / 8; ss->src_y = 0; - ss->src_size = + ss->src_size = ss->params.WidthIn * ss->sizeofPixelIn * ss->params.spp_interp; ss->src_offset = 0; ss->dst_y = 0; @@ -965,10 +965,10 @@ do_init(stream_state *st, ss->max_support*2, sizeof(CONTRIB), "image_scale contrib_dst[*]"); /* Allocate buffers for 1 row of source and destination. */ - ss->dst = + ss->dst = gs_alloc_byte_array(mem, (size_t)limited_WidthOut * ss->params.spp_interp, ss->sizeofPixelOut, "image_scale dst"); - ss->src = + ss->src = gs_alloc_byte_array(mem, (size_t)ss->params.WidthIn * ss->params.spp_interp, ss->sizeofPixelIn, "image_scale src"); if (ss->tmp == 0 || ss->contrib == 0 || ss->items == 0 || diff --git a/base/siscale.h b/base/siscale.h index 3f691471..c7c33255 100644 --- a/base/siscale.h +++ b/base/siscale.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/siscale_cal.c b/base/siscale_cal.c index 0bb68181..39329336 100644 --- a/base/siscale_cal.c +++ b/base/siscale_cal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sisparam.h b/base/sisparam.h index 69713797..b2431918 100644 --- a/base/sisparam.h +++ b/base/sisparam.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sjbig2.c b/base/sjbig2.c index 55b39356..915269db 100644 --- a/base/sjbig2.c +++ b/base/sjbig2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sjbig2.h b/base/sjbig2.h index 4c6e7032..7c2034bc 100644 --- a/base/sjbig2.h +++ b/base/sjbig2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sjbig2_luratech.c b/base/sjbig2_luratech.c deleted file mode 100644 index 9a3e0c54..00000000 --- a/base/sjbig2_luratech.c +++ /dev/null @@ -1,627 +0,0 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, - CA 94945, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* jbig2decode filter implementation -- hooks in luratech JBIG2 */ - -#include "memory_.h" -#include "malloc_.h" /* should use a gs mem pointer */ -#include "gserrors.h" -#include "gdebug.h" -#include "strimpl.h" -#include "sjbig2_luratech.h" - -#include - -/* JBIG2Decode stream implementation using the Luratech library */ - -/* if linking against a SDK build that requires a separate license key, - you can change the following undefs to defines and set them here. */ -/*** -#ifndef JB2_LICENSE_NUM_1 -# undef JB2_LICENSE_NUM_1 -#endif -#ifndef JB2_LICENSE_NUM_2 -# undef JB2_LICENSE_NUM_2 -#endif -***/ - -/* The /JBIG2Decode filter is a fairly memory intensive one to begin with, - Furthermore, as a PDF 1.4 feature, we can assume a fairly large - (host-level) machine. We therefore dispense with the normal - Ghostscript memory discipline and let the library allocate all its - resources on the heap. The pointers to these are not enumerated and - so will not be garbage collected. We rely on our release() proc being - called to deallocate state. - */ - /* TODO: check allocations for integer overflow */ - -/* create a gc object for our state, defined in sjbig2_luratech.h */ -private_st_jbig2decode_state(); - -#define JBIG2_BUFFER_SIZE 4096 - -/* our implementation of the "parsed" /JBIG2Globals filter parameter */ -typedef struct s_jbig2decode_global_data_s { - gs_memory_t *mem; - unsigned char *data; - unsigned long size; -} s_jbig2decode_global_data; - -/* create a global data struct and copy data into it */ -int -s_jbig2decode_make_global_data(gs_memory_t *mem, byte *data, uint size, void **result) -{ - s_jbig2decode_global_data *global = NULL; - - global = (s_jbig2decode_global_data *)gs_alloc_bytes(mem, sizeof (*global), - "s_jbig2decode_make_global_data(global)"); - if (global == NULL) return_error(gs_error_VMerror); - - global->mem = mem; - - global->data = gs_alloc_bytes(global->mem, size, "s_jbig2decode_make_global_data(global_data)"); - if (global->data == NULL) { - gs_free_object(global->mem, global, "s_jbig2decode_make_global_data(global)"); - return_error(gs_error_VMerror); - } - - memcpy(global->data, data, size); - global->size = size; - - *result = global; - return 0; -} - -/* free a global data struct and its data */ -void -s_jbig2decode_free_global_data(void *data) -{ - s_jbig2decode_global_data *global = (s_jbig2decode_global_data*)data; - - if (global->size && global->data) { - gs_free_object(global->mem, global->data, "s_jbig2decode_free_global_data(global_data)"); - global->size = 0; - } - - gs_free_object(global->mem, global, "s_jbig2decode_free_global_data(global)"); -} - -/* store a global ctx pointer in our state structure. - * If "gd" is NULL, then this library must free the global context. - * If not-NULL, then it will be memory managed by caller, for example, - * garbage collected in the case of the PS interpreter. - * Currently gpdf will use NULL, and the PDF implemented in the gs interpreter would use - * the garbage collection. - */ -int -s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gd, void *global_ctx) -{ - stream_jbig2decode_state *state = (stream_jbig2decode_state*)ss; - if (state == NULL) - return_error(gs_error_VMerror); - - state->global_struct = gd; - if (global_ctx != NULL) { - s_jbig2decode_global_data *global = global_ctx; - state->global_data = global->data; - state->global_size = global->size; - } else { - state->global_data = NULL; - state->global_size = 0; - } - return 0; -} - -/* invert the bits in a buffer */ -/* jbig2 and postscript have different senses of what pixel - value is black, so we must invert the image */ -static void -s_jbig2_invert_buffer(unsigned char *buf, int length) -{ - int i; - - for (i = 0; i < length; i++) - *buf++ ^= 0xFF; -} - -/** callbacks passed to the luratech library */ - -/* memory allocator */ -static void * JB2_Callback -s_jbig2_alloc(unsigned long size, void *userdata) -{ - gs_memory_t *mem = (gs_memory_t *) userdata; - return gs_alloc_bytes(mem, size, "s_jbig2_alloc"); -} - -/* memory release */ -static JB2_Error JB2_Callback -s_jbig2_free(void *ptr, void *userdata) -{ - gs_memory_t *mem = (gs_memory_t *) userdata; - gs_free_object(mem, ptr, "s_jbig2_free"); - return cJB2_Error_OK; -} - -/* error callback for jbig2 codec */ -static void JB2_Callback -s_jbig2_message(const char *message, JB2_Message_Level level, void *userdata) -{ - stream_jbig2decode_state *const state = (stream_jbig2decode_state *) userdata; - const char *type; - - if (message == NULL) return; - if (message[0] == '\0') return; - - switch (level) { - case cJB2_Message_Information: - type = "info"; break;; - case cJB2_Message_Warning: - type = "WARNING"; break;; - case cJB2_Message_Error: - type = "ERROR"; break;; - default: - type = "unknown message"; break;; - } - - if (level == cJB2_Message_Error) { - dmprintf2(state->memory, "Luratech JBIG2 %s %s\n", type, message); - } else { - if_debug2m('w', state->memory, "[w]Luratech JBIG2 %s %s\n", type, message); - } - - return; -} - -/* compressed read callback for jbig2 codec */ -static JB2_Size_T JB2_Callback -s_jbig2_read(unsigned char *buffer, - JB2_Size_T offset, JB2_Size_T size, void *userdata) -{ - stream_jbig2decode_state *const state = (stream_jbig2decode_state *) userdata; - long available; - - /* return data from the Globals stream */ - if (offset < state->global_size) { - available = state->global_size - offset; - if (available > size) available = size; - memcpy(buffer, state->global_data + offset, available); - return available; - } - - /* else return data from the image stream */ - offset -= state->global_size; - if (state->infill <= offset) - return 0; - available = state->infill - offset; - if (available > size) - available = size; - - memcpy(buffer, state->inbuf + offset, available); - return available; -} - -/* uncompressed write callback for jbig2 codec */ -static JB2_Error JB2_Callback -s_jbig2_write(unsigned char *buffer, - unsigned long row, unsigned long width, - unsigned long bbp, void *userdata) -{ - stream_jbig2decode_state *const state = (stream_jbig2decode_state *) userdata; - unsigned char *line = state->image + row*state->stride; - long available = ((width - 1) >> 3) + 1; - - if (row >= state->height) { - dmlprintf2(state->memory, "jbig2decode: output for row index %lu of %lu called!\n", row, state->height); - return cJB2_Error_Invalid_Index; - } - - memcpy(line, buffer, available); - s_jbig2_invert_buffer(line, available); - - return cJB2_Error_OK; -} - -static int -s_jbig2decode_inbuf(stream_jbig2decode_state *state, stream_cursor_read * pr) -{ - long in_size = pr->limit - pr->ptr; - - /* allocate the input buffer if needed */ - if (state->inbuf == NULL) { - state->inbuf = malloc(JBIG2_BUFFER_SIZE); - if (state->inbuf == NULL) return_error(gs_error_VMerror); - state->insize = JBIG2_BUFFER_SIZE; - state->infill = 0; - } - - /* grow the input buffer if needed */ - while (state->insize < state->infill + in_size) { - unsigned char *new; - unsigned long new_size = state->insize; - - while (new_size < state->infill + in_size) - new_size = new_size << 1; - - if_debug1m('s', state->memory, "[s]jbig2decode growing input buffer to %lu bytes\n", - new_size); - new = realloc(state->inbuf, new_size); - if (new == NULL) return_error(gs_error_VMerror); - - state->inbuf = new; - state->insize = new_size; - } - - /* copy the available input into our buffer */ - /* note that the gs stream library uses offset-by-one - indexing of its buffers while we use zero indexing */ - memcpy(state->inbuf + state->infill, pr->ptr + 1, in_size); - state->infill += in_size; - pr->ptr += in_size; - - return 0; -} - -/* initialize the steam. */ -static int -s_jbig2decode_init(stream_state * ss) -{ - stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss; - - state->doc = NULL; - state->inbuf = NULL; - state->insize = 0; - state->infill = 0; - state->image = NULL; - state->width = 0; - state->height = 0; - state->row = 0; - state->stride = 0; - state->error = 0; - state->offset = 0; - - return 0; -} - -/* process a section of the input and return any decoded data. - see strimpl.h for return codes. - */ -static int -s_jbig2decode_process(stream_state * ss, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss; - long in_size = pr->limit - pr->ptr; - long out_size = pw->limit - pw->ptr; - long available; - JB2_Error error; - JB2_Scaling_Factor scale = {1,1}; - JB2_Rect rect = {0,0,0,0}; - ulong result; - int status = last; - - if (in_size > 0) { - /* buffer all available input for the decoder */ - result = s_jbig2decode_inbuf(state, pr); - if (result) return ERRC; - } - - if (last && out_size > 0) { - - if (state->doc == NULL) { - - /* initialize the codec state and pass our callbacks */ - error = JB2_Document_Start( &(state->doc), - s_jbig2_alloc, ss->memory->non_gc_memory, /* alloc and its data */ - s_jbig2_free, ss->memory->non_gc_memory, /* free and its data */ - s_jbig2_read, ss, /* read callback and data */ - s_jbig2_message, ss); /* message callback and data */ - if (error != cJB2_Error_OK) return ERRC; - -#if defined(JB2_LICENSE_NUM_1) && defined(JB2_LICENSE_NUM_2) - /* set the license keys if appropriate */ - error = JB2_Document_Set_License(state->doc, - JB2_LICENSE_NUM_1, JB2_LICENSE_NUM_2); - if (error != cJB2_Error_OK) return ERRC; -#endif - /* decode relevent image parameters */ - error = JB2_Document_Set_Page(state->doc, 0); - if (error != cJB2_Error_OK) return ERRC; - error = JB2_Document_Get_Property(state->doc, - cJB2_Prop_Page_Width, &result); - state->width = result; - error = JB2_Document_Get_Property(state->doc, - cJB2_Prop_Page_Height, &result); - if (error != cJB2_Error_OK) return ERRC; - state->height = result; - state->stride = ((state->width - 1) >> 3) + 1; - if_debug2m('w', state->memory, "[w]jbig2decode page is %ldx%ld; allocating image\n", state->width, state->height); - state->image = malloc(state->height*state->stride); - - /* start image decode */ - error = JB2_Document_Decompress_Page(state->doc, scale, rect, - s_jbig2_write, ss); - if (error != cJB2_Error_OK) return ERRC; - - } - - /* copy any buffered image data out */ - available = state->stride*state->height - state->offset; - if (available > 0) { - out_size = (out_size > available) ? available : out_size; - memcpy(pw->ptr+1, state->image + state->offset, out_size); - state->offset += out_size; - pw->ptr += out_size; - } - /* more data to output? */ - available = state->stride*state->height - state->offset; - if (available > 0) return 1; - else return EOFC; - } - - /* handle fatal decoding errors reported through our callback */ - if (state->error) return ERRC; - - return status; -} - -/* stream release. free all our decoder state. */ -static void -s_jbig2decode_release(stream_state *ss) -{ - stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss; - - if (state->doc) { - JB2_Document_End(&(state->doc)); - if (state->inbuf) free(state->inbuf); - if (state->image) free(state->image); - } - if (state->global_struct != NULL) { - /* the interpreter calls jbig2decode_free_global_data() separately */ - } else { - /* We are responsible for freeing global context */ - if (state->global_data) { - s_jbig2decode_free_global_data(state->global_data); - state->global_data = NULL; - state->global_size = 0; - } - } -} - -/* stream template */ -const stream_template s_jbig2decode_template = { - &st_jbig2decode_state, - s_jbig2decode_init, - s_jbig2decode_process, - 1, 1, /* min in and out buffer sizes we can handle --should be ~32k,64k for efficiency? */ - s_jbig2decode_release -}; - -/** encode support **/ - -/* we provide a C-only encode filter for generating embedded JBIG2 image - data */ - -/* create a gc object for our state, defined in sjbig2_luratech.h */ -private_st_jbig2encode_state(); - -/* helper - start up the compression context */ -static int -s_jbig2encode_start(stream_jbig2encode_state *state) -{ - JB2_Error err; - - /* initialize the compression handle */ - err = JB2_Compress_Start(&(state->cmp), - s_jbig2_alloc, state->memory, /* alloc and its parameter data */ - s_jbig2_free, state->memory, /* free callback */ - s_jbig2_message, state);/* message callback */ - if (err != cJB2_Error_OK) return err; - - /* set the license keys if appropriate */ -#if defined(JB2_LICENSE_NUM_1) && defined(JB2_LICENSE_NUM_2) - err = JB2_Document_Set_License(state->cmp, - JB2_LICENSE_NUM_1, JB2_LICENSE_NUM_2); - if (err != cJB2_Error_OK) return err; -#endif - - /* set the image properties */ - err = JB2_Compress_Set_Property(state->cmp, - cJB2_Prop_Page_Width, state->width); - - err = JB2_Compress_Set_Property(state->cmp, - cJB2_Prop_Page_Height, state->height); - if (err != cJB2_Error_OK) return err; - - /* we otherwise use the default compression parameters */ - - return cJB2_Error_OK; -} - -/* callback for compressed data output */ -static JB2_Size_T JB2_Callback -s_jbig2encode_write(const unsigned char *buffer, - JB2_Size_T pos, JB2_Size_T size, void *userdata) -{ - stream_jbig2encode_state *state = (stream_jbig2encode_state *)userdata; - - /* allocate the output buffer if necessary */ - if (state->outbuf == NULL) { - state->outbuf = malloc(JBIG2_BUFFER_SIZE); - if (state->outbuf == NULL) { - dmprintf(state->memory, "jbig2encode: failed to allocate output buffer\n"); - return 0; /* can't return an error! */ - } - state->outsize = JBIG2_BUFFER_SIZE; - } - - /* grow the output buffer if necessary */ - while (pos+size > state->outsize) { - unsigned char *new_ = realloc(state->outbuf, state->outsize*2); - if (new_ == NULL) { - dmprintf1(state->memory, "jbig2encode: failed to resize output buffer" - " beyond %lu bytes\n", state->outsize); - return 0; /* can't return an error! */ - } - state->outbuf = new_; - state->outsize *= 2; - } - - /* copy data into our buffer; there will now be enough room. */ - memcpy(state->outbuf + pos, buffer, size); - if (state->outfill < pos + size) state->outfill = pos + size; - - return size; -} - -/* initialize the steam. */ -static int -s_jbig2encode_init(stream_state * ss) -{ - stream_jbig2encode_state *state = (stream_jbig2encode_state *)ss; - - /* null library context handles */ - state->cmp = (JB2_Handle_Compress)NULL; - state->doc = (JB2_Handle_Document)NULL; - - /* width and height are set by the client */ - /* calculate a stride based on those values */ - state->stride = ((state->width - 1) >> 3) + 1; - - state->line = malloc(state->stride); - if (state->line == NULL) return ERRC; - state->linefill = 0; - - /* null output buffer */ - state->outbuf = NULL; - state->outsize = 0; - state->outfill = 0; - state->offset = 0; - state->jb2_encode = false; - - return 0; -} - -/* process a section of the input and return any encoded data. - see strimpl.h for return codes. - */ -static int -s_jbig2encode_process(stream_state * ss, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_jbig2encode_state *state = (stream_jbig2encode_state *)ss; - long in_size = pr->limit - pr->ptr; - long out_size = pw->limit - pw->ptr; - long available, segment; - JB2_Error err; - JB2_Export_Format format[] = {cJB2_Export_Format_Stream_For_PDF, cJB2_Export_Format_JB2}; - - /* Be greedy in filling our internal line buffer so we always - make read progress on a stream. */ - if (in_size > 0) { - /* initialize the encoder if necessary */ - if (state->cmp == (JB2_Handle_Compress)NULL) - s_jbig2encode_start(state); - - available = in_size; - - /* try to fill the line buffer */ - segment = state->stride - state->linefill; - if (segment > 0) { - segment = (segment < available) ? segment : available; - memcpy(state->line + state->linefill, pr->ptr+1, segment); - pr->ptr += segment; - available -= segment; - state->linefill += segment; - } - /* pass a full line buffer to the encoder library */ - if (state->linefill == state->stride) { - s_jbig2_invert_buffer(state->line, state->stride); - err = JB2_Compress_Line(state->cmp, state->line); - state->linefill = 0; - if (err != cJB2_Error_OK) return ERRC; - } - /* pass remaining full lines to the encoder library */ - while (available >= state->stride) { - memcpy(state->line, pr->ptr+1, state->stride); - s_jbig2_invert_buffer(state->line, state->stride); - err = JB2_Compress_Line(state->cmp, state->line); - pr->ptr += state->stride; - available = pr->limit - pr->ptr; - if (err != cJB2_Error_OK) return ERRC; - } - /* copy remaining data into the line buffer */ - if (available > 0) { - /* available is always < stride here */ - memcpy(state->line, pr->ptr+1, available); - pr->ptr += available; - state->linefill = available; - } - if (!last) return 0; /* request more data */ - } - - if (last && state->outbuf == NULL) { - /* convert the compression context to a document context */ - err = JB2_Compress_End(&(state->cmp), &(state->doc)); - if (err != cJB2_Error_OK) return ERRC; - /* dump the compressed data out through a callback; - unfortunately we can't serialize this across process calls */ - err = JB2_Document_Export_Document(state->doc, - s_jbig2encode_write, state, - format[state->jb2_encode]); - if (err != cJB2_Error_OK) return ERRC; - } - - if (state->outbuf != NULL) { - /* copy available output data */ - available = min(out_size, state->outfill - state->offset); - memcpy(pw->ptr + 1, state->outbuf + state->offset, available); - pw->ptr += available; - state->offset += available; - - /* need further output space? */ - if (state->outfill - state->offset > 0) return 1; - else return EOFC; /* all done */ - } - - /* no data. */ - if (in_size == 0 && !last) - return 0; - - /* something went wrong above. */ - return ERRC; -} - -/* stream release. free all our decoder state. - */ -static void -s_jbig2encode_release(stream_state *ss) -{ - stream_jbig2encode_state *state = (stream_jbig2encode_state *)ss; - - if (state->outbuf != NULL) free(state->outbuf); - if (state->line != NULL) free(state->line); -} - -/* stream template */ -const stream_template s_jbig2encode_template = { - &st_jbig2encode_state, - s_jbig2encode_init, - s_jbig2encode_process, - 1024, 1024, /* min in and out buffer sizes; could be smaller, but - this is more efficient */ - s_jbig2encode_release -}; diff --git a/base/sjbig2_luratech.h b/base/sjbig2_luratech.h deleted file mode 100644 index 0c0bcd2a..00000000 --- a/base/sjbig2_luratech.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, - CA 94945, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Definitions for jbig2decode filter - Luratech version */ -/* Requires scommon.h; strimpl.h if any templates are referenced */ - -#ifndef sjbig2_luratech_INCLUDED -# define sjbig2_luratech_INCLUDED - -#include "scommon.h" -#include - -/* See zfjbig2.c for details. */ -typedef struct s_jbig2_global_data_s { - void *data; -} s_jbig2_global_data_t; - -/* JBIG2Decode internal stream state */ -typedef struct stream_jbig2decode_state_s -{ - stream_state_common; /* inherit base object from scommon.h */ - JB2_Handle_Document doc; /* Luratech JBIG2 codec context */ - s_jbig2_global_data_t *global_struct; /* to protect it from freeing by GC */ - unsigned char *global_data; - unsigned long global_size; - unsigned char *inbuf; /* compressed image data */ - unsigned long insize, infill; - unsigned char *image; /* decoded image data */ - unsigned long width, height; - unsigned long row, stride; - unsigned long offset; /* next output byte to be returned */ - JB2_Error error; -} -stream_jbig2decode_state; - -#define private_st_jbig2decode_state() \ - gs_private_st_ptrs1(st_jbig2decode_state, stream_jbig2decode_state,\ - "jbig2decode filter state", jbig2decode_state_enum_ptrs,\ - jbig2decode_state_reloc_ptrs, global_struct) -extern const stream_template s_jbig2decode_template; - -/* call in to process the JBIG2Globals parameter */ -int -s_jbig2decode_make_global_data(gs_memory_t *mem, byte *data, uint size, void **result); -int -s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gs, void *global_ctx); -void -s_jbig2decode_free_global_data(void *data); - -/* JBIG2 encoder internal state */ -typedef struct stream_jbig2encode_state_s -{ - stream_state_common; /* inherit base object from scommon.h */ - JB2_Handle_Compress cmp; /* compression library context */ - JB2_Handle_Document doc; - unsigned long width, height; - unsigned long stride; /* line length in bytes */ - unsigned char *line; /* single line working buffer */ - unsigned long linefill; /* bytes in the working buffer */ - unsigned char *outbuf; /* output data buffer */ - unsigned long outsize; /* bytes available in the buffer */ - unsigned long outfill; /* bytes written to the buffer */ - unsigned long offset; /* bytes written from the buffer */ - bool jb2_encode; /* are we writing a jb2 file (true), or a stream for a PDF (false) */ - -} stream_jbig2encode_state; - -#define private_st_jbig2encode_state() \ - gs_private_st_simple(st_jbig2encode_state, stream_jbig2encode_state,\ - "jbig2encode filter state") - -extern const stream_template s_jbig2encode_template; - -#endif /* sjbig2_luratech_INCLUDED */ diff --git a/base/sjpeg.h b/base/sjpeg.h index 1a0877f9..d59a1a0c 100644 --- a/base/sjpeg.h +++ b/base/sjpeg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sjpegc.c b/base/sjpegc.c index bea397a3..fa220d75 100644 --- a/base/sjpegc.c +++ b/base/sjpegc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -173,7 +173,7 @@ static long gs_j_mem_init (j_common_ptr cinfo) if (gs_memory_chunk_wrap(&(cmem), mem) < 0) { return (-1); } - + (void)jpeg_cust_mem_set_private(GET_CUST_MEM_DATA(cinfo), cmem); return 0; @@ -229,7 +229,7 @@ gs_jpeg_mem_term(j_common_ptr cinfo) if (cinfo->client_data) { jpeg_cust_mem_data *custmptr = (jpeg_cust_mem_data *)cinfo->client_data; gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv); - + gs_free_object(mem, custmptr, "gs_jpeg_mem_term"); cinfo->client_data = NULL; } diff --git a/base/sjpegd.c b/base/sjpegd.c index 16b71df6..6eb0c648 100644 --- a/base/sjpegd.c +++ b/base/sjpegd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -39,7 +39,7 @@ gs_jpeg_create_decompress(stream_DCT_state * st) return_error(gs_jpeg_log_error(st)); jpeg_stream_data_common_init(st->data.decompress); - + if (gs_jpeg_mem_init (st->memory, (j_common_ptr)&st->data.decompress->dinfo) < 0) return_error(gs_error_VMerror); diff --git a/base/sjpege.c b/base/sjpege.c index 9663ca85..a598f762 100644 --- a/base/sjpege.c +++ b/base/sjpege.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sjpx_luratech.c b/base/sjpx_luratech.c deleted file mode 100644 index aa0d1131..00000000 --- a/base/sjpx_luratech.c +++ /dev/null @@ -1,1096 +0,0 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, - CA 94945, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* JPXDecode filter implementation -- hooks in the Luratech JPEG2K CSDK */ - -#include "memory_.h" -#include "gserrors.h" -#include "gdebug.h" -#include "strimpl.h" -#include "sjpx_luratech.h" - -#include - -/* JPXDecode stream implementation using the Luratech library */ - -/* if linking against a SDK build that requires a separate license key, - you can change the following undefs to defines and set them here. */ -/*** -#ifndef JP2_LICENSE_NUM_1 -# undef JP2_LICENSE_NUM_1 -#endif -#ifndef JP2_LICENSE_NUM_2 -# undef JP2_LICENSE_NUM_2 -#endif -***/ - -private_st_jpxd_state(); /* creates a gc object for our state, - defined in sjpx.h */ - -#define JPX_BUFFER_SIZE 1024 - -/** callback for the codec library */ - -/* memory allocation */ -static void * JP2_Callback_Conv -s_jpx_alloc(long size, JP2_Callback_Param param) -{ - return gs_alloc_byte_array((gs_memory_t *)param, size, 1, "s_jpx_alloc"); -} - -/* memory free */ -static JP2_Error JP2_Callback_Conv -s_jpx_free(void *ptr, JP2_Callback_Param param) -{ - gs_free_object((gs_memory_t *)param, ptr, "s_jpx_free"); - return cJP2_Error_OK; -} - -/* pass any available input to the library */ -static unsigned long JP2_Callback_Conv -s_jpxd_read_data(unsigned char *pucData, - unsigned long ulPos, unsigned long ulSize, - JP2_Callback_Param param) -{ - stream_jpxd_state *const state = (stream_jpxd_state *) param; - unsigned long copy_bytes = min(ulSize, state->inbuf_fill - ulPos); - - memcpy(pucData, state->inbuf + ulPos, copy_bytes); - - return copy_bytes; -} - -static unsigned long -jp2_get_value(JP2_Decomp_Handle *handle, - JP2_Property_Tag tag, - short comp, - unsigned long def) -{ - JP2_Property_Value v; - - if (JP2_Decompress_GetProp(handle, tag, &v, -1, comp) != cJP2_Error_OK) - return def; - - return (unsigned long)v; -} - -/* write decompressed data into our image buffer */ -static JP2_Error JP2_Callback_Conv -s_jpxd_write_data(unsigned char * pucData, - short sComponent, - unsigned long ulRow, - unsigned long ulStart, - unsigned long ulNum, - JP2_Callback_Param param) -{ - stream_jpxd_state *const state = (stream_jpxd_state *) param; - int comp = state->clut[sComponent]; - - /* check input */ - if (ulRow >= state->height) return cJP2_Error_Invalid_Height; - if (ulStart + ulNum >= state->width) ulNum = state->width - ulStart; - - /* Here we just copy a byte at a time into an image buffer, - interleaving with whatever data already exists. For multi- - component images, it would be more efficient to save rows - from each call in planar buffers and interleave a tile at - a time into a stipe buffer for output */ - - if (state->image_is_indexed && sComponent == 0 && !state->alpha) { - JP2_Palette_Params *pal; - JP2_Error err; - int i, c; - unsigned char *dst; - - err = JP2_Decompress_GetPalette(state->handle, &pal); - if (err != cJP2_Error_OK) - return err; - - if (state->colorspace != gs_jpx_cs_indexed) { - dst = &state->image[state->stride * ulRow + - state->ncomp * ulStart + comp]; - /* expand the data */ - for (i = 0; i < ulNum; i++) { - unsigned char v = pucData[i]; - - if (v >= pal->ulEntries) - return cJP2_Error_Invalid_Colorspace; - - for (c = 0; c < state->ncomp; c++) - *dst++ = (unsigned char)pal->ppulPalette[c][v]; - } - } else { - /* copy indexes */ - if (state->bpc == 4) { - int even = ulNum & ~1; - dst = &state->image[state->stride * ulRow + ulStart/2]; - for (i = 0; i < even; i += 2) - *dst++ = pucData[i] << 4 | pucData[i+1]; - if (ulNum & 1) - *dst++ = pucData[ulNum - 1] << 4; - } else { - dst = &state->image[state->stride * ulRow + ulStart + comp]; - memcpy(dst, pucData, ulNum); - } - } - } else if (state->ncomp == 1 && comp == 0) { - if (state->bpc == 8) { - memcpy(&state->image[state->stride*ulRow + state->ncomp*ulStart], - pucData, ulNum); - } else if (state->bpc > 8) { - unsigned long i; - unsigned short *src = (unsigned short *)pucData; - unsigned char *dst = &state->image[state->stride * ulRow + 2 * ulStart]; - unsigned int shift = 16 - state->bpc; - for (i = 0; i < ulNum; i++) { - unsigned short v = *src++ << shift; - *dst++ = (v >> 8) & 0xff; - *dst++ = v & 0xff; - } - } else if (state->bpc == 4) { - int i; - unsigned char *dst = &state->image[state->stride * ulRow + ulStart/2]; - int even = ulNum & ~1; - - for (i = 0; i < even; i+=2) - *dst++ = pucData[i] << 4 | pucData[i+1]; - if (ulNum & 1) - *dst++ = pucData[ulNum - 1] << 4; - } else - { - unsigned int bt=0; unsigned long i; - int bit_pos = state->bpc * ulStart; /* starting bit position to fill for this component */ - int bit_cnt; /* bit count for current byte */ - unsigned char *p = &state->image[state->stride * ulRow + bit_pos/8]; /* starting byte to fill */; - bit_cnt = bit_pos % 8; - for (i = 0; i < ulNum; i++) - { - bt <<= state->bpc; - bt |= pucData[i]; - bit_cnt += state->bpc; - if (bit_cnt >= 8) - { - *(p++) |= bt >> (bit_cnt-8); - bit_cnt -= 8; - bt &= (1< 0) - { - *p |= bt<<(8-bit_cnt); - bt = 0; - } - } - } - else if (comp >= 0) { - unsigned long cw, ch, i, hstep, vstep, x, y; - unsigned char *row; - - /* repeat subsampled pixels */ - cw = jp2_get_value(state->handle, cJP2_Prop_Width, comp, state->width); - ch = jp2_get_value(state->handle, cJP2_Prop_Height, comp, state->height); - hstep = state->width / cw; - vstep = state->height / ch; - - if (state->bpc == 8) { - row = &state->image[state->stride * ulRow * vstep + - state->ncomp * ulStart * hstep + comp]; - for (y = 0; y < vstep; y++) { - unsigned char *p = row; - for (i = 0; i < ulNum; i++) - for (x = 0; x < hstep; x++) { - *p = pucData[i]; - p += state->ncomp; - } - row += state->stride; - } - } else if (state->bpc > 8) { - int shift = 16 - state->bpc; - unsigned short *src = (unsigned short *)pucData; - row = &state->image[state->stride * ulRow * vstep + - 2 * state->ncomp * ulStart * hstep + 2 * comp]; - for (y = 0; y < vstep; y++) { - unsigned char *p = row; - for (i = 0; i < ulNum; i++) - for (x = 0; x < hstep; x++) { - unsigned short v = *src++ << shift; - p[0] = (v >> 8) & 0xff; - p[1] = v & 0xff; - p += 2 * state->ncomp; - } - row += state->stride; - } - } else { - unsigned int bt=0; - int bit_pos = state->bpc * state->ncomp * ulStart * hstep + state->bpc * comp; /* starting bit position to fill for this component */ - int bit_cnt; /* bit count for current byte */ - - row = &state->image[state->stride * ulRow * vstep + bit_pos/8]; /* starting byte to fill */ - for (y = 0; y < vstep; y++) { - unsigned char *p = row; - bit_cnt = bit_pos % 8; - for (i = 0; i < ulNum; i++) { - for (x = 0; x < hstep; x++) { - bt <<= state->bpc * state->ncomp; - bt |= pucData[i]; - bit_cnt += state->bpc; - while (bit_cnt >= 8) { - *(p++) |= bt >> (bit_cnt-8); - bit_cnt -= 8; - bt &= (1<bpc * (state->ncomp - 1); /* skip other components */ - } - } - /* end of row */ - bit_cnt -= state->bpc * (state->ncomp - 1); /* return the last extra count */ - if (bit_cnt > 0) { - *p |= bt<<(8-bit_cnt); - bt = 0; - } - row += state->stride; - } - } - } - return cJP2_Error_OK; -} - -/* convert state->image from YCrCb to RGBa */ -static int -s_jpxd_ycc_to_rgb(stream_jpxd_state *state) -{ - int i, y, x; - int is_signed[2]; /* Cr, Cb */ - - if (state->ncomp != 3) - return -1; - - for (i = 0; i < 2; i++) { - int comp = state->clut[i + 1]; /* skip Y */ - is_signed[i] = !jp2_get_value(state->handle, - cJP2_Prop_Signed_Samples, comp, 0); - } - - for (y = 0; y < state->height; y++) { - unsigned char *row = &state->image[y * state->stride]; - - for (x = 0; x < state->stride; x += 3) { - int p[3], q[3]; - - for (i = 0; i < 3; i++) - p[i] = (int)row[x + i]; - - if (is_signed[0]) - p[1] -= 0x80; - if (is_signed[1]) - p[2] -= 0x80; - - /* rotate to RGB */ -#ifdef JPX_USE_IRT - q[1] = p[0] - ((p[1] + p[2])>>2); - q[0] = p[1] + q[1]; - q[2] = p[2] + q[1]; -#else - q[0] = (int)((double)p[0] + 1.402 * p[2]); - q[1] = (int)((double)p[0] - 0.34413 * p[1] - 0.71414 * p[2]); - q[2] = (int)((double)p[0] + 1.772 * p[1]); -#endif - /* clamp */ - for (i = 0; i < 3; i++){ - if (q[i] < 0) q[i] = 0; - else if (q[i] > 0xFF) q[i] = 0xFF; - } - /* write out the pixel */ - for (i = 0; i < 3; i++) - row[x + i] = (unsigned char)q[i]; - } - } - - return 0; -} - -static int -s_jpxd_inbuf(stream_jpxd_state *state, stream_cursor_read * pr) -{ - long in_size = pr->limit - pr->ptr; - - /* allocate the input buffer if needed */ - if (state->inbuf == NULL) { - state->inbuf = s_jpx_alloc(JPX_BUFFER_SIZE, (JP2_Callback_Param)state->memory->non_gc_memory); - if (state->inbuf == NULL) return_error(gs_error_VMerror); - state->inbuf_size = JPX_BUFFER_SIZE; - state->inbuf_fill = 0; - } - - /* grow the input buffer if needed */ - if (state->inbuf_size < state->inbuf_fill + in_size) { - unsigned char *new; - unsigned long new_size = state->inbuf_size; - - while (new_size < state->inbuf_fill + in_size) - new_size = new_size << 1; - - if_debug1m('s', state->memory, "[s]jpxd growing input buffer to %lu bytes\n", - new_size); - - new = gs_resize_object(state->memory->non_gc_memory, state->inbuf, new_size, "s_jpxd_inbuf"); - if (new == NULL) return_error(gs_error_VMerror); - - state->inbuf = new; - state->inbuf_size = new_size; - } - - /* copy the available input into our buffer */ - /* note that the gs stream library uses offset-by-one - indexing of its buffers while we use zero indexing */ - memcpy(state->inbuf + state->inbuf_fill, pr->ptr + 1, in_size); - state->inbuf_fill += in_size; - pr->ptr += in_size; - - return 0; -} - -/* initialize the steam. - this involves allocating the stream and image structures, and - initializing the decoder. - */ -static int -s_jpxd_init(stream_state * ss) -{ - stream_jpxd_state *const state = (stream_jpxd_state *) ss; - - state->handle = (JP2_Decomp_Handle)NULL; - state->inbuf = NULL; - state->inbuf_size = 0; - state->inbuf_fill = 0; - - state->ncomp = 0; - state->bpc = 0; - state->clut = NULL; - state->width = 0; - state->height = 0; - state->stride = 0; - state->image = NULL; - state->offset = 0; - - return 0; -} - -/* Set the defaults */ -static void -s_jpxd_set_defaults(stream_state * ss) { - stream_jpxd_state *const state = (stream_jpxd_state *) ss; - - state->alpha = false; - state->image_is_indexed = false; - state->colorspace = gs_jpx_cs_rgb; -} - -/* write component mapping into 'clut' and return number of used components - */ -static int -map_components(JP2_Channel_Def_Params *chans, int nchans, int alpha, int clut[]) -{ - int i, cnt = 0; - - for (i = 0; i < nchans; i++) - clut[i] = -1; - - /* always write the alpha channel as first component */ - if (alpha) { - for (i = 0; i < nchans; i++) { - if (chans[i].ulType == cJP2_Channel_Type_Opacity) { - clut[i] = 0; - cnt++; - break; - } - } - } else { - for (i = 0; i < nchans; i++) { - if (chans[i].ulType == cJP2_Channel_Type_Color) { - int assoc = chans[i].ulAssociated -1; - if (assoc >= nchans) - return -1; - clut[i] = assoc; - cnt++; - } - } - } - return cnt; -} - -/* process a secton of the input and return any decoded data. - see strimpl.h for return codes. - */ -static int -s_jpxd_process(stream_state * ss, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_jpxd_state *const state = (stream_jpxd_state *) ss; - JP2_Error err; - JP2_Property_Value result; - long in_size = pr->limit - pr->ptr; - long out_size = pw->limit - pw->ptr; - JP2_Colorspace image_cs = cJP2_Colorspace_RGBa; - - if (in_size > 0) { - /* buffer available data */ - s_jpxd_inbuf(state, pr); - } - - if (last == 1) { - /* we have all the data, decode and return */ - - if (state->handle == (JP2_Decomp_Handle)NULL) { - int ncomp; - /* initialize decompressor */ - err = JP2_Decompress_Start(&state->handle, - /* memory allocator callbacks */ - s_jpx_alloc, (JP2_Callback_Param)state->memory->non_gc_memory, - s_jpx_free, (JP2_Callback_Param)state->memory->non_gc_memory, - /* our read callback */ - s_jpxd_read_data, (JP2_Callback_Param)state - ); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d starting decompression\n", (int)err); - return ERRC; - } -#if defined(JP2_LICENSE_NUM_1) && defined(JP2_LICENSE_NUM_2) - /* set the license keys if appropriate */ - err = JP2_Decompress_SetLicense(state->handle, - JP2_LICENSE_NUM_1, JP2_LICENSE_NUM_2); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting license\n", (int)err); - return ERRC; - } -#endif - /* parse image parameters */ - err = JP2_Decompress_GetProp(state->handle, - cJP2_Prop_Components, &result, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d decoding number of image components\n", (int)err); - return ERRC; - } - ncomp = result; - - { - JP2_Channel_Def_Params *chans = NULL; - unsigned long nchans = 0; - err = JP2_Decompress_GetChannelDefs(state->handle, &chans, &nchans); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d reading channel definitions\n", (int)err); - return ERRC; - } - state->clut = s_jpx_alloc(nchans * sizeof(int), (JP2_Callback_Param)state->memory->non_gc_memory); - state->ncomp = map_components(chans, nchans, state->alpha, state->clut); - if (state->ncomp < 0) { - dmlprintf(state->memory, "Luratech JP2 error decoding channel definitions\n"); - return ERRC; - } - } - - if_debug1m('w', state->memory, "[w]jpxd image has %d components\n", state->ncomp); - - state->bpc = 0; - { - const char *cspace = "unknown"; - err = JP2_Decompress_GetProp(state->handle, - cJP2_Prop_Extern_Colorspace, &result, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d decoding colorspace\n", (int)err); - return ERRC; - } - image_cs = (JP2_Colorspace)result; - switch (result) { - case cJP2_Colorspace_Gray: - cspace = "gray"; - state->colorspace = gs_jpx_cs_gray; - break; - case cJP2_Colorspace_RGBa: - cspace = "sRGB"; - state->colorspace = gs_jpx_cs_rgb; - break; - case cJP2_Colorspace_RGB_YCCa: - cspace = "sRGB YCrCb"; break; - state->colorspace = gs_jpx_cs_rgb; - break; - case cJP2_Colorspace_CIE_LABa: - cspace = "CIE Lab"; - state->colorspace = gs_jpx_cs_rgb; - break; - case cJP2_Colorspace_ICCa: - cspace = "ICC profile"; - state->colorspace = gs_jpx_cs_rgb; - break; - case cJP2_Colorspace_Palette_Gray: - cspace = "indexed gray"; - state->image_is_indexed = true; - break; - case cJP2_Colorspace_Palette_RGBa: - cspace = "indexed sRGB"; - state->image_is_indexed = true; - if (state->colorspace != gs_jpx_cs_indexed) - state->bpc = 8; - break; - case cJP2_Colorspace_Palette_RGB_YCCa: - cspace = "indexed sRGB YCrCb"; - state->image_is_indexed = true; - break; - case cJP2_Colorspace_Palette_CIE_LABa: - cspace = "indexed CIE Lab"; - state->image_is_indexed = true; - break; - case cJP2_Colorspace_Palette_ICCa: - cspace = "indexed with ICC profile"; - state->image_is_indexed = true; - break; - case cJP2_Colorspace_CMYKa: - cspace = "CMYK"; - state->colorspace = gs_jpx_cs_cmyk; - break; - case cJP2_Colorspace_Palette_CMYKa: - cspace = "indexed CMYK"; - state->image_is_indexed = true; - break; - } - if_debug1m('w', state->memory, "[w]jpxd image colorspace is %s\n", cspace); - } - - /* the library doesn't return the overall image dimensions - or depth, so we take the maximum of the component values */ - state->width = 0; - state->height = 0; - { - int comp; - int width, height; - int bits, is_signed; - for (comp = 0; comp < ncomp; comp++) { - err= JP2_Decompress_GetProp(state->handle, - cJP2_Prop_Width, &result, -1, (short)comp); - if (err != cJP2_Error_OK) { - dmlprintf2(state->memory, "Luratech JP2 error %d decoding " - "width for component %d\n", (int)err, comp); - return ERRC; - } - width = result; - err= JP2_Decompress_GetProp(state->handle, - cJP2_Prop_Height, &result, -1, (short)comp); - if (err != cJP2_Error_OK) { - dmlprintf2(state->memory, "Luratech JP2 error %d decoding " - "height for component %d\n", (int)err, comp); - return ERRC; - } - height = result; - err= JP2_Decompress_GetProp(state->handle, - cJP2_Prop_Bits_Per_Sample, &result, -1, (short)comp); - if (err != cJP2_Error_OK) { - dmlprintf2(state->memory, "Luratech JP2 error %d decoding " - "bits per sample for component %d\n", (int)err, comp); - return ERRC; - } - bits = result; - err= JP2_Decompress_GetProp(state->handle, - cJP2_Prop_Signed_Samples, &result, -1, (short)comp); - if (err != cJP2_Error_OK) { - dmlprintf2(state->memory, "Luratech JP2 error %d decoding " - "signedness of component %d\n", (int)err, comp); - return ERRC; - } - is_signed = result; - if_debug5m('w', state->memory, - "[w]jpxd image component %d has %dx%d %s %d bit samples\n", - comp, width, height, - is_signed ? "signed" : "unsigned", bits); - - /* update image maximums */ - if (state->width < width) state->width = width; - if (state->height < height) state->height = height; - if (state->bpc < bits) state->bpc = bits; - } - } - if_debug3m('w', state->memory, "[w]jpxd decoding image at %ldx%ld" - " with %d bits per component\n", - state->width, state->height, state->bpc); - } - - if (state->handle != (JP2_Decomp_Handle)NULL && - state->image == NULL) { - - /* allocate our output buffer */ - int real_bpc = state->bpc > 8 ? 16 : state->bpc; - if (state->image_is_indexed && state->colorspace == gs_jpx_cs_indexed) { - /* Don't expand indexed color space */ - state->stride = (state->width * real_bpc + 7) / 8; - state->image = s_jpx_alloc(state->stride*state->height, (JP2_Callback_Param)state->memory->non_gc_memory); - } else { - state->stride = (state->width * max(1, state->ncomp) * real_bpc + 7) / 8; - state->image = s_jpx_alloc(state->stride*state->height, (JP2_Callback_Param)state->memory->non_gc_memory); - } - if (state->image == NULL) - return ERRC; - if (state->ncomp == 0) /* make fully opaque mask */ - memset(state->image, 255, state->stride*state->height); - - /* attach our output callback */ - err = JP2_Decompress_SetProp(state->handle, - cJP2_Prop_Output_Parameter, (JP2_Property_Value)state); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting output parameter\n", (int)err); - return ERRC; - } - err = JP2_Decompress_SetProp(state->handle, - cJP2_Prop_Output_Function, - (JP2_Property_Value)s_jpxd_write_data); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting output function\n", (int)err); - return ERRC; - } - - /* decompress the image */ - err = JP2_Decompress_Image(state->handle); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d decoding image data\n", (int)err); - return ERRC; /* parsing error */ - } - - if (image_cs == cJP2_Colorspace_RGB_YCCa) { - s_jpxd_ycc_to_rgb(state); - } - } - - /* copy out available data */ - if (state->image != NULL && out_size > 0) { - /* copy some output data */ - long available = min(out_size, - state->stride*state->height - state->offset); - memcpy(pw->ptr + 1, state->image + state->offset, available); - state->offset += available; - pw->ptr += available; - /* more output to deliver? */ - if (state->offset == state->stride*state->height) - return EOFC; - else - return 1; - } - } - - /* ask for more data */ - return 0; -} - -/* stream release. - free all our decoder state. - */ -static void -s_jpxd_release(stream_state *ss) -{ - stream_jpxd_state *const state = (stream_jpxd_state *) ss; - - if (state) { - JP2_Decompress_End(state->handle); - if (state->inbuf) - gs_free_object(state->memory->non_gc_memory, state->inbuf, "s_jpxd_release.1"); - if (state->image) - gs_free_object(state->memory->non_gc_memory, state->image, "s_jpxd_release.2"); - if (state->clut) - gs_free_object(state->memory->non_gc_memory, state->clut, "s_jpxd_release.3"); - } -} - -/* stream template */ -const stream_template s_jpxd_template = { - &st_jpxd_state, - s_jpxd_init, - s_jpxd_process, - 1024, 1024, /* min in and out buffer sizes we can handle - should be ~32k,64k for efficiency? */ - s_jpxd_release, - s_jpxd_set_defaults, - 0 -}; - -/*** encode support **/ - -/* we provide a C-only encode filter for generating JPX image data - for embedding in PDF. */ - -/* create a gc object for our state, defined in sjpx_luratech.h */ -private_st_jpxe_state(); - -/* callback for uncompressed data input */ -static JP2_Error JP2_Callback_Conv -s_jpxe_read(unsigned char *buffer, short component, - unsigned long row, unsigned long start, - unsigned long num, JP2_Callback_Param param) -{ - stream_jpxe_state *state = (stream_jpxe_state *)param; - unsigned long available, sentinel; - unsigned char *p; - int i; - - if (component < 0 || component >= state->components) { - dmlprintf2(state->memory, - "Luratech JP2 requested image data for unknown component %d of %u\n", - (int)component, state->components); - return cJP2_Error_Invalid_Component_Index; - } - - /* todo: handle subsampled components and bpc != 8 */ - - /* clip to array bounds */ - sentinel = row*state->stride + (start + num)*state->components; - available = min(sentinel, state->infill); - num = min(num, available / state->components); - - p = state->inbuf + state->stride*row + state->components*start; - if (state->components == 1) - memcpy(buffer, p, num); - else for (i = 0; i < num; i++) { - buffer[i] = p[component]; - p += state->components; - } - - if (available < sentinel) return cJP2_Error_Failure_Read; - else return cJP2_Error_OK; -} - -/* callback for compressed data output */ -static JP2_Error JP2_Callback_Conv -s_jpxe_write(unsigned char *buffer, - unsigned long pos, unsigned long size, - JP2_Callback_Param param) -{ - stream_jpxe_state *state = (stream_jpxe_state *)param; - - /* verify state */ - if (state == NULL) return cJP2_Error_Invalid_Pointer; - - /* allocate the output buffer if necessary */ - if (state->outbuf == NULL) { - state->outbuf = s_jpx_alloc(JPX_BUFFER_SIZE, (JP2_Callback_Param)state->memory->non_gc_memory); - if (state->outbuf == NULL) { - dmprintf(state->memory, "jpx encode: failed to allocate output buffer.\n"); - return cJP2_Error_Failure_Malloc; - } - state->outsize = JPX_BUFFER_SIZE; - } - - /* grow the output buffer if necessary */ - while (pos+size > state->outsize) { - unsigned char *new = gs_resize_object(state->memory->non_gc_memory, state->outbuf, state->outsize*2, "s_jpxe_write"); - - if (new == NULL) { - dmprintf1(state->memory, "jpx encode: failed to resize output buffer" - " beyond %lu bytes.\n", state->outsize); - return cJP2_Error_Failure_Malloc; - } - state->outbuf = new; - state->outsize *= 2; - if_debug1m('s', state->memory, "[s] jpxe output buffer resized to %lu bytes\n", - state->outsize); - } - - /* copy data into our buffer; we've assured there is enough room. */ - memcpy(state->outbuf + pos, buffer, size); - /* update high water mark */ - if (state->outfill < pos + size) state->outfill = pos + size; - - return cJP2_Error_OK; -} - -/* set defaults for user-configurable parameters */ -static void -s_jpxe_set_defaults(stream_state *ss) -{ - stream_jpxe_state *state = (stream_jpxe_state *)ss; - - /* most common default colorspace */ - state->colorspace = gs_jpx_cs_rgb; - - /* default to lossy 60% quality */ - state->lossless = 0; - state->quality = 60; -} - -/* initialize the stream */ -static int -s_jpxe_init(stream_state *ss) -{ - stream_jpxe_state *state = (stream_jpxe_state *)ss; - unsigned long value; - JP2_Error err; - - /* width, height, bpc and colorspace are set by the client, - calculate the rest */ - switch (state->colorspace) { - case gs_jpx_cs_gray: state->components = 1; break; - case gs_jpx_cs_rgb: state->components = 3; break; - case gs_jpx_cs_cmyk: state->components = 4; break; - default: state->components = 0; break; - } - state->stride = state->width * state->components; - - if_debug3m('w', state->memory, "[w] jpxe init %lux%lu image with %d components\n", - state->width, state->height, state->components); - if_debug1m('w', state->memory, "[w] jpxe init image is %d bits per component\n", state->bpc); - - if (state->lossless) { - if_debug0m('w', state->memory, "[w] jpxe image using lossless encoding\n"); - state->quality = 100; /* implies lossless */ - } else { - if_debug1m('w', state->memory, "[w] jpxe image quality level %d\n", state->quality); - } - - /* null the input buffer */ - state->inbuf = NULL; - state->insize = 0; - state->infill = 0; - - /* null the output buffer */ - state->outbuf = NULL; - state->outsize = 0; - state->outfill = 0; - state->offset = 0; - - /* initialize the encoder */ - err = JP2_Compress_Start(&state->handle, - /* memory allocator callbacks */ - s_jpx_alloc, (JP2_Callback_Param)state->memory->non_gc_memory, - s_jpx_free, (JP2_Callback_Param)state->memory->non_gc_memory, - state->components); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d starting compressor\n", (int)err); - return ERRC; - } - -#if defined(JP2_LICENSE_NUM_1) && defined(JP2_LICENSE_NUM_2) - /* set license keys if appropriate */ - err = JP2_Compress_SetLicense(state->handle, - JP2_LICENSE_NUM_1, JP2_LICENSE_NUM_2); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting license\n", (int)err); - return ERRC; - } -#endif - - /* install our callbacks */ - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Input_Parameter, (JP2_Property_Value)state, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting input callback parameter.\n", (int)err); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Input_Function, (JP2_Property_Value)s_jpxe_read, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting input callback function.\n", (int)err); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Write_Parameter, (JP2_Property_Value)state, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting compressed output callback parameter.\n", (int)err); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Write_Function, (JP2_Property_Value)s_jpxe_write, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting compressed output callback function.\n", (int)err); - return ERRC; - } - - /* set image parameters - the same for all components */ - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Width, state->width, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting width\n", (int)err); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Height, state->height, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting height\n", (int)err); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Bits_Per_Sample, state->bpc, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting bits per sample\n", (int)err); - return ERRC; - } - - switch (state->colorspace) { - case gs_jpx_cs_gray: value = cJP2_Colorspace_Gray; break; - case gs_jpx_cs_rgb: value = cJP2_Colorspace_RGBa; break; - case gs_jpx_cs_cmyk: value = cJP2_Colorspace_CMYKa; break; - default: - dmlprintf1(state->memory, "Unknown colorspace %d initializing JP2 encoder\n", - (int)state->colorspace); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Extern_Colorspace, value, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting colorspace\n", (int)err); - return ERRC; - } - - if (state->lossless) { - /* the default encoding mode is lossless */ - return 0; - } - - /* otherwise, set 9,7 wavelets and quality-target mode */ - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Wavelet_Filter, cJP2_Wavelet_9_7, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting wavelet filter\n", (int)err); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Rate_Quality, state->quality, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting compression quality\n", (int)err); - return ERRC; - } - - /* we use the encoder's defaults for all other parameters */ - - return 0; -} - -/* process input and return any encoded data. - see strimpl.h for return codes. */ -static int -s_jpxe_process(stream_state *ss, stream_cursor_read *pr, - stream_cursor_write *pw, bool last) -{ - stream_jpxe_state *state = (stream_jpxe_state *)ss; - long in_size = pr->limit - pr->ptr; - long out_size = pw->limit - pw->ptr; - long available; - JP2_Error err; - - /* HACK -- reinstall our callbacks in case the GC has moved our state structure */ - /* this should be done instead from a pointer relocation callback, or initialization - moved entirely inside the process routine. */ - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Input_Parameter, (JP2_Property_Value)state, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting input callback parameter.\n", (int)err); - return ERRC; - } - err = JP2_Compress_SetProp(state->handle, - cJP2_Prop_Write_Parameter, (JP2_Property_Value)state, -1, -1); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d setting compressed output callback parameter.\n", (int)err); - return ERRC; - } - - if (in_size > 0) { - /* allocate our input buffer if necessary */ - if (state->inbuf == NULL) { - state->inbuf = s_jpx_alloc(JPX_BUFFER_SIZE, (JP2_Callback_Param)state->memory->non_gc_memory); - if (state->inbuf == NULL) { - dmprintf(state->memory, "jpx encode: failed to allocate input buffer.\n"); - return ERRC; - } - state->insize = JPX_BUFFER_SIZE; - } - - /* grow our input buffer if necessary */ - while (state->infill + in_size > state->insize) { - unsigned char *new = gs_resize_object(state->memory->non_gc_memory, state->inbuf, state->insize*2, "s_jpxe_process"); - if (new == NULL) { - dmprintf(state->memory, "jpx encode: failed to resize input buffer.\n"); - return ERRC; - } - state->inbuf = new; - state->insize *= 2; - } - - /* copy available input */ - memcpy(state->inbuf + state->infill, pr->ptr + 1, in_size); - state->infill += in_size; - pr->ptr += in_size; - } - - if (last && state->outbuf == NULL) { - /* We have all the data; call the compressor. - our callback will automatically allocate the output buffer */ - if_debug0m('w', state->memory, "[w] jpxe process compressing image data\n"); - err = JP2_Compress_Image(state->handle); - if (err != cJP2_Error_OK) { - dmlprintf1(state->memory, "Luratech JP2 error %d compressing image data.\n", (int)err); - return ERRC; - } - } - - if (state->outbuf != NULL) { - /* copy out any available output data */ - available = min(out_size, state->outfill - state->offset); - memcpy(pw->ptr + 1, state->outbuf + state->offset, available); - pw->ptr += available; - state->offset += available; - - /* do we have any more data? */ - if (state->outfill - state->offset > 0) return 1; - else return EOFC; /* all done */ - } - - /* something went wrong above */ - return last; -} - -/* stream release. free all our state. */ -static void -s_jpxe_release(stream_state *ss) -{ - stream_jpxe_state *state = (stream_jpxe_state *)ss; - JP2_Error err; - - /* close the library compression context */ - err = JP2_Compress_End(state->handle); - if (err != cJP2_Error_OK) { - /* we can't return an error, so only print on debug builds */ - if_debug1m('w', state->memory, "[w]jpxe Luratech JP2 error %d" - " closing compression context", (int)err); - } - - /* free our own storage */ - gs_free_object(state->memory->non_gc_memory, state->outbuf, "s_jpxe_release(outbuf)"); - gs_free_object(state->memory->non_gc_memory, state->inbuf, "s_jpxe_release(inbuf)"); -} - -int sjpxd_create(gs_memory_t *mem) -{ - return 0; -} - -void sjpxd_destroy(gs_memory_t *mem) -{ -} - -/* encoder stream template */ -const stream_template s_jpxe_template = { - &st_jpxe_state, - s_jpxe_init, - s_jpxe_process, - 1024, 1024, /* min in and out buffer sizes */ - s_jpxe_release, - s_jpxe_set_defaults -}; diff --git a/base/sjpx_luratech.h b/base/sjpx_luratech.h deleted file mode 100644 index 92c66c49..00000000 --- a/base/sjpx_luratech.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, - CA 94945, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Definitions for JPXDecode filter (JPEG 2000) */ -/* we link to the Luratech CSDK for the actual decoding */ - -#ifndef sjpx_luratech_INCLUDED -# define sjpx_luratech_INCLUDED - -/* Requires scommon.h; strimpl.h if any templates are referenced */ - -#include "scommon.h" -#include - -/* define colorspace enumeration for the decompressed image data */ -typedef enum { - gs_jpx_cs_unset, /* colorspace hasn't been set */ - gs_jpx_cs_gray, /* single component grayscale image */ - gs_jpx_cs_rgb, /* three component (s)RGB image */ - gs_jpx_cs_cmyk, /* four component CMYK image */ - gs_jpx_cs_indexed /* PDF image wants raw index values */ -} gs_jpx_cs; - -/* Stream state for the Luratech jp2 codec - * We rely on our finalization call to free the - * associated handle and pointers. - */ -typedef struct stream_jpxd_state_s -{ - stream_state_common; /* a define from scommon.h */ - JP2_Decomp_Handle handle; /* library decoder handle */ - unsigned char *inbuf; /* input data buffer */ - unsigned long inbuf_size; - unsigned long inbuf_fill; - gs_jpx_cs colorspace; /* requested output colorspace */ - bool alpha; /* return opacity channel */ - bool image_is_indexed; /* image is indexed, needs decoding */ - /* if colorspace != gs_jpx_cs_indexed */ - int ncomp; /* number of image components */ - int bpc; /* sample bits per component */ - int *clut; /* channel indices */ - unsigned long width, height; - unsigned long stride; - unsigned char *image; /* decoded image buffer */ - long offset; /* offset into the image buffer of the next - byte to be returned */ -} -stream_jpxd_state; - -#define private_st_jpxd_state() \ - gs_private_st_simple(st_jpxd_state, stream_jpxd_state,\ - "JPXDecode filter state") -extern const stream_template s_jpxd_template; - -/* JPX encoder internal state */ -typedef struct stream_jpxe_state_s { - stream_state_common; /* inherit base object from scommon.h */ - JP2_Comp_Handle handle; /* compression library context */ - - /* the following members must be set by the caller: */ - unsigned long width, height;/* image dimensions */ - gs_jpx_cs colorspace; /* colorspace of the input image data */ - unsigned int bpc; /* sample depth of each channel in bits */ - - /* the following members can be optionally set by the caller: */ - unsigned int quality; /* compressed image quality target; 1-100 - leave unset for the default */ - int lossless; /* set to 1 to specify lossless image - compression; overrides quality */ - - /* the remainder are handled internally: */ - unsigned int components; /* number of image channels */ - unsigned long stride; /* line length in bytes */ - unsigned char *inbuf; /* input image data buffer */ - unsigned long insize; /* allocated size of buffer */ - unsigned long infill; /* bytes written to the buffer */ - - unsigned char *outbuf; /* output data buffer */ - unsigned long outsize; /* size of the data buffer in bytes */ - unsigned long outfill; /* bytes written to the buffer */ - unsigned long offset; /* bytes written from the buffer */ -} stream_jpxe_state; - -#define private_st_jpxe_state() \ - gs_private_st_simple(st_jpxe_state, stream_jpxe_state, \ - "jpx encode filter state") - -extern const stream_template s_jpxe_template; - -#endif /* sjpx_luratech_INCLUDED */ diff --git a/base/sjpx_none.c b/base/sjpx_none.c index 38767618..a0758990 100644 --- a/base/sjpx_none.c +++ b/base/sjpx_none.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sjpx_openjpeg.c b/base/sjpx_openjpeg.c index f0db34e1..bac505dd 100644 --- a/base/sjpx_openjpeg.c +++ b/base/sjpx_openjpeg.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -435,25 +435,43 @@ static int decode_image(stream_jpxd_state * const state) { case OPJ_CLRSPC_GRAY: state->colorspace = gs_jpx_cs_gray; + if (numprimcomp > 1) { + dmprintf1(state->memory, "openjpeg warning: Ignoring extra components for %d component Gray data.\n", numprimcomp); + numprimcomp = 1; + } break; - case OPJ_CLRSPC_UNKNOWN: /* make the best guess based on number of channels */ - { - if (numprimcomp < 3) - { - state->colorspace = gs_jpx_cs_gray; + case OPJ_CLRSPC_SRGB: + case OPJ_CLRSPC_SYCC: + case OPJ_CLRSPC_EYCC: + state->colorspace = gs_jpx_cs_rgb; + if (numprimcomp > 3) { + dmprintf1(state->memory, "openjpeg warning: Ignoring extra components for %d component RGB data.\n", numprimcomp); + numprimcomp = 3; } - else if (numprimcomp == 4) - { + break; + case OPJ_CLRSPC_CMYK: + state->colorspace = gs_jpx_cs_cmyk; + if (numprimcomp > 4) { + dmprintf1(state->memory, "openjpeg warning: Ignoring extra components for %d component CMYK data.\n", numprimcomp); + numprimcomp = 4; + } + break; + default: + case OPJ_CLRSPC_UNSPECIFIED: + case OPJ_CLRSPC_UNKNOWN: + if (numprimcomp == 1) { + dmprintf1(state->memory, "openjpeg warning: unspec CS. %d component so assuming gray.\n", numprimcomp); + state->colorspace = gs_jpx_cs_gray; + } else if (numprimcomp == 4) { + dmprintf1(state->memory, "openjpeg warning: unspec CS. %d components so assuming CMYK.\n", numprimcomp); state->colorspace = gs_jpx_cs_cmyk; - } - else - { + } else { + /* Note, numprimcomp > 4 possible here. Bug 694909. + Trust that it is RGB though. Do not set numprimcomp */ + dmprintf1(state->memory, "openjpeg warning: unspec CS. %d components. Assuming data RGB.\n", numprimcomp); state->colorspace = gs_jpx_cs_rgb; } break; - } - default: /* OPJ_CLRSPC_SRGB, OPJ_CLRSPC_SYCC, OPJ_CLRSPC_EYCC */ - state->colorspace = gs_jpx_cs_rgb; } state->alpha_comp = -1; @@ -560,12 +578,12 @@ static int process_one_trunk(stream_jpxd_state * const state, stream_cursor_writ for (b=0; bpdata[compno]) << shift_bit) >> (8*(bytepp1-b-1)))) + (b==0 ? state->sign_comps[compno] : 0); /* split and shift input int to output bytes */ - state->pdata[compno]++; + state->pdata[compno]++; } } } else - { + { /* shift_bit = 0, bpp < 8 */ int bt=0; int bit_pos = 0; @@ -678,7 +696,7 @@ s_opjd_process(stream_state * ss, stream_cursor_read * pr, int locked = 0; int code; - if (in_size > 0) + if (in_size > 0) { /* buffer available data */ code = opj_lock(ss->memory); @@ -703,7 +721,7 @@ s_opjd_process(stream_state * ss, stream_cursor_read * pr, } } - if (last == 1) + if (last == 1) { if (state->image == NULL) { @@ -774,11 +792,11 @@ s_opjd_release(stream_state *ss) /* free image data structure */ if (state->image) opj_image_destroy(state->image); - + /* free stream */ if (state->stream) opj_stream_destroy(state->stream); - + /* free decoder handle */ if (state->codec) opj_destroy_codec(state->codec); diff --git a/base/sjpx_openjpeg.h b/base/sjpx_openjpeg.h index be129983..0ee57b64 100644 --- a/base/sjpx_openjpeg.h +++ b/base/sjpx_openjpeg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -72,4 +72,4 @@ typedef struct stream_jpxd_state_s extern const stream_template s_jpxd_template; -#endif +#endif diff --git a/base/slzwc.c b/base/slzwc.c index 91b2ec5c..c3d4c9a0 100644 --- a/base/slzwc.c +++ b/base/slzwc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/slzwd.c b/base/slzwd.c index 25ffd0dc..c5c49a21 100644 --- a/base/slzwd.c +++ b/base/slzwd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -167,225 +167,231 @@ s_LZWD_process(stream_state * st, stream_cursor_read * pr, } goto add; } - top:if (code_size > bits_left) { - if (bytes_left == 0) { - if (p == rlimit) - goto out; - bytes_left = *++p; - if_debug1m('W', ss->memory, "[W]block count %d\n", bytes_left); + while (1) /* Loop while we have data to handle */ + { + if (code_size > bits_left) { if (bytes_left == 0) { - status = EOFC; - goto out; - } - goto top; - } - if (low_order) - code = bits >> (8 - bits_left); - else - code = (uint) bits << (code_size - bits_left); - if (bits_left + 8 < code_size) { /* Need 2 more data bytes */ - if (bytes_left == 1) { - if (rlimit - p < 3) + if (p == rlimit) goto out; - bytes_left = p[2]; - if_debug1m('W', ss->memory, "[W]block count %d\n", - bytes_left); + bytes_left = *++p; + if_debug1m('W', ss->memory, "[W]block count %d\n", bytes_left); if (bytes_left == 0) { status = EOFC; goto out; } - bytes_left++; - bits = p[1]; - p++; + continue; + } + if (low_order) + code = bits >> (8 - bits_left); + else + code = (uint) bits << (code_size - bits_left); + if (bits_left + 8 < code_size) { /* Need 2 more data bytes */ + if (bytes_left == 1) { + if (rlimit - p < 3) + goto out; + bytes_left = p[2]; + if_debug1m('W', ss->memory, "[W]block count %d\n", + bytes_left); + if (bytes_left == 0) { + status = EOFC; + goto out; + } + bytes_left++; + bits = p[1]; + p++; + } else { + if (rlimit - p < 2) + goto out; + bits = p[1]; + } + if (low_order) + code += (uint) bits << bits_left; + else + code += (uint) bits << (code_size - 8 - bits_left); + bits_left += 8; + bits = p[2]; + p += 2; + bytes_left -= 2; } else { - if (rlimit - p < 2) + if (p == rlimit) goto out; - bits = p[1]; + bits = *++p; + bytes_left--; } if (low_order) - code += (uint) bits << bits_left; + code += (uint) bits << bits_left, + bits_left += 8 - code_size; else - code += (uint) bits << (code_size - 8 - bits_left); - bits_left += 8; - bits = p[2]; - p += 2; - bytes_left -= 2; + bits_left += 8 - code_size, + code += bits >> bits_left; } else { - if (p == rlimit) - goto out; - bits = *++p; - bytes_left--; + if (low_order) + code = bits >> (8 - bits_left), + bits_left -= code_size; + else + bits_left -= code_size, + code = bits >> bits_left; } - if (low_order) - code += (uint) bits << bits_left, - bits_left += 8 - code_size; - else - bits_left += 8 - code_size, - code += bits >> bits_left; - } else { - if (low_order) - code = bits >> (8 - bits_left), - bits_left -= code_size; - else - bits_left -= code_size, - code = bits >> bits_left; - } - code &= code_mask; - if_debug2m('W', ss->memory, "[W]reading 0x%x,%d\n", code, code_size); - /* - * There is an anomalous case where a code S is followed - * immediately by another occurrence of the S string. - * In this case, the next available code will be defined as - * S followed by the first character of S, and will be - * emitted immediately after the code S. We have to - * recognize this case specially, by noting that the code is - * equal to next_code. - */ - if (code >= next_code) { - if ((code > next_code) || (prev_code < 0)) { + code &= code_mask; + if_debug2m('W', ss->memory, "[W]reading 0x%x,%d\n", code, code_size); + /* + * There is an anomalous case where a code S is followed + * immediately by another occurrence of the S string. + * In this case, the next available code will be defined as + * S followed by the first character of S, and will be + * emitted immediately after the code S. We have to + * recognize this case specially, by noting that the code is + * equal to next_code. + */ + if (code >= next_code) { + if ((code > next_code) || (prev_code < 0)) { #ifdef DEBUG - mlprintf3(ss->memory, "[W]code = %d > next_code = %d or prev_code = %d < 0\n", - code, next_code, prev_code); + mlprintf3(ss->memory, "[W]code = %d > next_code = %d or prev_code = %d < 0\n", + code, next_code, prev_code); #endif - status = ERRC; - goto out; - } - /* Fabricate the entry for the code. It will be */ - /* overwritten immediately, of course. */ - for (c = prev_code; c != eod; c = table[c].prefix) - dc_next->datum = c; - len = prev_len + 1; - dc_next->len = min(len, 255); - dc_next->prefix = prev_code; - if_debug3m('w', ss->memory, "[w]decoding anomalous 0x%x=0x%x+%c\n", - next_code, prev_code, dc_next->datum); - } - /* See if there is enough room for the code. */ -reset: - len = table[code].len; - if (len == 255) { /* Check for special code (reset or end). */ - /* We set their lengths to 255 to avoid doing */ - /* an extra check in the normal case. */ - if (code == code_reset) { - if_debug1m('w', ss->memory, "[w]reset: next_code was %d\n", - next_code); - next_code = code_0; - dc_next = table + code_0; - code_size = ss->InitialCodeLength + 1; - set_code_size(); - prev_code = -1; - goto top; - } else if (code == eod) { - status = EOFC; - goto out; + status = ERRC; + goto out; + } + /* Fabricate the entry for the code. It will be */ + /* overwritten immediately, of course. */ + for (c = prev_code; c != eod; c = table[c].prefix) + dc_next->datum = c; + len = prev_len + 1; + dc_next->len = min(len, 255); + dc_next->prefix = prev_code; + if_debug3m('w', ss->memory, "[w]decoding anomalous 0x%x=0x%x+%c\n", + next_code, prev_code, dc_next->datum); } - /* The code length won't fit in a byte, */ - /* compute it the hard way. */ - for (c = code, len = 0; c != eod; len++) - c = table[c].prefix; - if_debug2m('w', ss->memory, "[w]long code %d, length=%d\n", code, len); - } - if (wlimit - q < len) { - ss->copy_code = code; - ss->copy_left = ss->copy_len = len; - status = 1; - goto out; - } - /* Copy the string to the buffer (back to front). */ - /* Optimize for short codes, which are the most frequent. */ - dc = &table[code]; - switch (len) { - default: - { - byte *q1 = q += len; + /* See if there is enough room for the code. */ + while (1) /* Loop while we have codes to handle */ + { + len = table[code].len; + if (len == 255) { /* Check for special code (reset or end). */ + /* We set their lengths to 255 to avoid doing */ + /* an extra check in the normal case. */ + if (code == code_reset) { + if_debug1m('w', ss->memory, "[w]reset: next_code was %d\n", + next_code); + next_code = code_0; + dc_next = table + code_0; + code_size = ss->InitialCodeLength + 1; + set_code_size(); + prev_code = -1; + goto loop; + } else if (code == eod) { + status = EOFC; + goto out; + } + /* The code length won't fit in a byte, */ + /* compute it the hard way. */ + for (c = code, len = 0; c != eod; len++) + c = table[c].prefix; + if_debug2m('w', ss->memory, "[w]long code %d, length=%d\n", code, len); + } + if (wlimit - q < len) { + ss->copy_code = code; + ss->copy_left = ss->copy_len = len; + status = 1; + goto out; + } + /* Copy the string to the buffer (back to front). */ + /* Optimize for short codes, which are the most frequent. */ + dc = &table[code]; + switch (len) { + default: + { + byte *q1 = q += len; - c = code; - do { - *q1-- = (dc = &table[c])->datum; + c = code; + do { + *q1-- = (dc = &table[c])->datum; + } + while ((c = dc->prefix) != eod); + b = q1[1]; + break; } - while ((c = dc->prefix) != eod); - b = q1[1]; + case 3: + q[3] = dc->datum; + dc = &table[dc->prefix]; + case 2: + q[2] = dc->datum; + dc = &table[dc->prefix]; + case 1: + q[1] = b = dc->datum; + q += len; } - break; - case 3: - q[3] = dc->datum; - dc = &table[dc->prefix]; - case 2: - q[2] = dc->datum; - dc = &table[dc->prefix]; - case 1: - q[1] = b = dc->datum; - q += len; - } add: /* Add a new entry to the table */ - if (prev_code >= 0) { - /* - * Unfortunately, we have to check for next_code == - * lzw_decode_max every time: just checking at power - * of 2 boundaries stops us one code too soon. - */ - if (!old_tiff && next_code == lzw_decode_max) { - /* - * A few anomalous files have one data item too many before the - * reset code. We think this is a bug in the application that - * produced the files, but Acrobat accepts the files, so we do - * too. - */ - if (!ss->BlockData) { /* don't do this for GIF */ - if (bits_left < 8 && p >= rlimit && last) { - /* We're at EOD. */ - goto out; - } - if (bits_left + ((rlimit - p) << 3) < code_size) { + if (prev_code >= 0) { + /* + * Unfortunately, we have to check for next_code == + * lzw_decode_max every time: just checking at power + * of 2 boundaries stops us one code too soon. + */ + if (!old_tiff && next_code == lzw_decode_max) { /* - * We need more data to decide whether a reset is next. - * Return an error if we cannot get more. + * A few anomalous files have one data item too many before the + * reset code. We think this is a bug in the application that + * produced the files, but Acrobat accepts the files, so we do + * too. */ - if (last) - status = ERRC; + if (!ss->BlockData) { /* don't do this for GIF */ + if (bits_left < 8 && p >= rlimit && last) { + /* We're at EOD. */ + goto out; + } + if (bits_left + ((rlimit - p) << 3) < code_size) { + /* + * We need more data to decide whether a reset is next. + * Return an error if we cannot get more. + */ + if (last) + status = ERRC; + goto out; + } + if (low_order) { + code = bits >> (8 - bits_left); + code += (bits = *++p) << bits_left; + if (bits_left + 8 < code_size) + code += (bits = *++p) << (bits_left + 8); + } else { + code = bits & ((1 << bits_left) - 1); + code = (code << 8) + (bits = *++p); + if (bits_left + 8 < code_size) + code = (code << 8) + (bits = *++p); + code >>= (bits_left - code_size) & 7; + } + bits_left = (bits_left - code_size) & 7; + if (code == code_reset) + continue; /* Loop back to handle the reset */ + } + status = ERRC; goto out; } - if (low_order) { - code = bits >> (8 - bits_left); - code += (bits = *++p) << bits_left; - if (bits_left + 8 < code_size) - code += (bits = *++p) << (bits_left + 8); - } else { - code = bits & ((1 << bits_left) - 1); - code = (code << 8) + (bits = *++p); - if (bits_left + 8 < code_size) - code = (code << 8) + (bits = *++p); - code >>= (bits_left - code_size) & 7; + if (next_code < lzw_decode_max) { + dc_next->datum = b; /* added char of string */ + dc_next->len = min(prev_len, 254) + 1; + dc_next->prefix = prev_code; + dc_next++; + if_debug4m('W', ss->memory, "[W]adding 0x%x=0x%x+%c(%d)\n", + next_code, prev_code, b, min(len, 255)); + } + if (++next_code == switch_code) { /* Crossed a power of 2. */ + /* We have to make a strange special check for */ + /* reaching the end of the code space. */ + if (next_code < lzw_decode_max - 1) { + code_size++; + set_code_size(); + if_debug2m('w', ss->memory, "[w]crossed power of 2: new code_size=%d, next_code=%d\n", + code_size, next_code); + } } - bits_left = (bits_left - code_size) & 7; - if (code == code_reset) - goto reset; - } - status = ERRC; - goto out; - } - if (next_code < lzw_decode_max) { - dc_next->datum = b; /* added char of string */ - dc_next->len = min(prev_len, 254) + 1; - dc_next->prefix = prev_code; - dc_next++; - if_debug4m('W', ss->memory, "[W]adding 0x%x=0x%x+%c(%d)\n", - next_code, prev_code, b, min(len, 255)); - } - if (++next_code == switch_code) { /* Crossed a power of 2. */ - /* We have to make a strange special check for */ - /* reaching the end of the code space. */ - if (next_code < lzw_decode_max - 1) { - code_size++; - set_code_size(); - if_debug2m('w', ss->memory, "[w]crossed power of 2: new code_size=%d, next_code=%d\n", - code_size, next_code); } + break; /* No more codes to handle */ } - } - prev_code = code; - prev_len = len; - goto top; + prev_code = code; + prev_len = len; + loop: {} + } /* Loop back to the top */ out:pr->ptr = p; pw->ptr = q; ss->code_size = code_size; diff --git a/base/slzwe.c b/base/slzwe.c index aab5091d..b01803ab 100644 --- a/base/slzwe.c +++ b/base/slzwe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/slzwx.h b/base/slzwx.h index 889950d3..d073dd92 100644 --- a/base/slzwx.h +++ b/base/slzwx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/smd5.c b/base/smd5.c index a4f70572..acf0251b 100644 --- a/base/smd5.c +++ b/base/smd5.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/smd5.h b/base/smd5.h index a7df7463..de2bdcfb 100644 --- a/base/smd5.h +++ b/base/smd5.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/smtf.h b/base/smtf.h index 83074a3d..40484933 100644 --- a/base/smtf.h +++ b/base/smtf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spdiff.c b/base/spdiff.c index 7ffc8aa9..c5df1bf0 100644 --- a/base/spdiff.c +++ b/base/spdiff.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spdiffx.h b/base/spdiffx.h index fa3c59d4..a53df06c 100644 --- a/base/spdiffx.h +++ b/base/spdiffx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spngp.c b/base/spngp.c index bc0d73ad..90fe7be8 100644 --- a/base/spngp.c +++ b/base/spngp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spngpx.h b/base/spngpx.h index ae75d0e3..f8733177 100644 --- a/base/spngpx.h +++ b/base/spngpx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spprint.c b/base/spprint.c index a72a0c30..c44e8bba 100644 --- a/base/spprint.c +++ b/base/spprint.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spprint.h b/base/spprint.h index a6ee7605..fb2efd44 100644 --- a/base/spprint.h +++ b/base/spprint.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spsdf.c b/base/spsdf.c index 9751fa3f..0993637a 100644 --- a/base/spsdf.c +++ b/base/spsdf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -94,12 +94,10 @@ s_write_ps_string(stream * s, const byte * str, uint size, int print_ok) stream_cursor_write w; int status; - r.ptr = str - 1; - r.limit = r.ptr + size; - w.limit = buf + sizeof(buf) - 1; + stream_cursor_read_init(&r, str, size); do { - /* One picky compiler complains if we initialize to buf - 1. */ - w.ptr = buf; w.ptr--; + stream_cursor_write_init(&w, buf, sizeof(buf)); + status = (*templat->process) (st, &r, &w, true); stream_write(s, buf, (uint) (w.ptr + 1 - buf)); } diff --git a/base/spsdf.h b/base/spsdf.h index 421155f1..a78ac6d7 100644 --- a/base/spsdf.h +++ b/base/spsdf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spwgd.c b/base/spwgd.c index cb04cb72..10d77ad4 100644 --- a/base/spwgd.c +++ b/base/spwgd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2018 Artifex Software, Inc. +/* Copyright (C) 2017-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/spwgx.h b/base/spwgx.h index 50d355d1..347c7375 100644 --- a/base/spwgx.h +++ b/base/spwgx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2018 Artifex Software, Inc. +/* Copyright (C) 2017-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/srdline.h b/base/srdline.h index d9229267..9473eae7 100644 --- a/base/srdline.h +++ b/base/srdline.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/srld.c b/base/srld.c index f2aea0d3..6a60d0b3 100644 --- a/base/srld.c +++ b/base/srld.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/srle.c b/base/srle.c index c54be127..39ca8189 100644 --- a/base/srle.c +++ b/base/srle.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/srlx.h b/base/srlx.h index d015d073..27e3755e 100644 --- a/base/srlx.h +++ b/base/srlx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ssha2.c b/base/ssha2.c index 896f44e7..29830cfd 100644 --- a/base/ssha2.c +++ b/base/ssha2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ssha2.h b/base/ssha2.h index 7495c565..fcd88a50 100644 --- a/base/ssha2.h +++ b/base/ssha2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/sstring.c b/base/sstring.c index 8edcc235..b638f9b9 100644 --- a/base/sstring.c +++ b/base/sstring.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -52,7 +52,7 @@ s_AXE_process(stream_state * st, stream_cursor_read * pr, if (last && ss->EndOfData) wcount--; /* leave room for '>' */ - wcount -= (wcount + pos * 2) / 65; /* leave room for \n */ + wcount -= (wcount + pos * 2) / 64; /* leave room for \n */ wcount >>= 1; /* 2 chars per input byte */ count = (wcount < rcount ? (status = 1, wcount) : rcount); while (--count >= 0) { @@ -389,72 +389,85 @@ s_hex_process(stream_cursor_read * pr, stream_cursor_write * pw, return 1; if (val1 <= 0xf) goto d2; - d1:if ((rcount = (rlimit - p) >> 1) == 0) - goto x1; - /* Set up a fast end-of-loop check, so we don't have to test */ - /* both p and q against their respective limits. */ - flimit = (rcount < wlimit - q ? q + rcount : wlimit); - f1:if ((val1 = decoder[p[1]]) <= 0xf && - (val2 = decoder[p[2]]) <= 0xf - ) { - p += 2; - *++q = (val1 << 4) + val2; - if (q < flimit) - goto f1; - if (q >= wlimit) - goto px; - } - x1:if (p >= rlimit) - goto end1; - if ((val1 = decoder[*++p]) > 0xf) { - if (val1 == ctype_space) { - switch (syntax) { - case hex_ignore_garbage: - case hex_ignore_whitespace: - goto x1; - case hex_ignore_leading_whitespace: - if (q == q0 && *odd_digit < 0) - goto x1; - /* pass through */ - case hex_break_on_whitespace: - --p; - code = 2; - goto end1; + do { + /* No digits read */ + if ((rcount = (rlimit - p) >> 1) != 0) + { + /* Set up a fast end-of-loop check, so we don't have to test */ + /* both p and q against their respective limits. */ + flimit = (rcount < wlimit - q ? q + rcount : wlimit); + while (1) { + if ((val1 = decoder[p[1]]) <= 0xf && + (val2 = decoder[p[2]]) <= 0xf) { + p += 2; + *++q = (val1 << 4) + val2; + if (q < flimit) + continue; + if (q >= wlimit) + goto px; + } + break; } - } else if (syntax == hex_ignore_garbage) - goto x1; - code = ERRC; - goto end1; - } - d2:if (p >= rlimit) { - *odd_digit = val1; - goto ended; - } - if ((val2 = decoder[*++p]) > 0xf) { - if (val2 == ctype_space) - switch (syntax) { - case hex_ignore_garbage: - case hex_ignore_whitespace: - goto d2; - case hex_ignore_leading_whitespace: - if (q == q0) - goto d2; - /* pass through */ - case hex_break_on_whitespace: - --p; - *odd_digit = val1; - code = 2; - goto ended; + } + /* About to read the first digit */ + while (1) { + if (p >= rlimit) + goto end1; + if ((val1 = decoder[*++p]) > 0xf) { + if (val1 == ctype_space) { + switch (syntax) { + case hex_ignore_garbage: + case hex_ignore_whitespace: + continue; + case hex_ignore_leading_whitespace: + if (q == q0 && *odd_digit < 0) + continue; + /* pass through */ + case hex_break_on_whitespace: + --p; + code = 2; + goto end1; + } + } else if (syntax == hex_ignore_garbage) + continue; + code = ERRC; + goto end1; } - if (syntax == hex_ignore_garbage) - goto d2; - *odd_digit = val1; - code = ERRC; - goto ended; - } - *++q = (val1 << 4) + val2; - if (q < wlimit) - goto d1; + break; + } + d2: + /* About to read the second hex digit of a pair */ + while (1) { + if (p >= rlimit) { + *odd_digit = val1; + goto ended; + } + if ((val2 = decoder[*++p]) > 0xf) { + if (val2 == ctype_space) + switch (syntax) { + case hex_ignore_garbage: + case hex_ignore_whitespace: + continue; + case hex_ignore_leading_whitespace: + if (q == q0) + continue; + /* pass through */ + case hex_break_on_whitespace: + --p; + *odd_digit = val1; + code = 2; + goto ended; + } + if (syntax == hex_ignore_garbage) + continue; + *odd_digit = val1; + code = ERRC; + goto ended; + } + break; + } + *++q = (val1 << 4) + val2; + } while (q < wlimit); px:code = 1; end1:*odd_digit = -1; ended:pr->ptr = p; diff --git a/base/sstring.h b/base/sstring.h index 28e5eae7..83cf319e 100644 --- a/base/sstring.h +++ b/base/sstring.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/stat_.h b/base/stat_.h index 5389e0d0..631294de 100644 --- a/base/stat_.h +++ b/base/stat_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/std.h b/base/std.h index aec4b42c..36025ba5 100644 --- a/base/std.h +++ b/base/std.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/stdint_.h b/base/stdint_.h index 537824bd..fd425b44 100644 --- a/base/stdint_.h +++ b/base/stdint_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/stdio_.h b/base/stdio_.h index 034d56ad..45c42926 100644 --- a/base/stdio_.h +++ b/base/stdio_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/stdpre.h b/base/stdpre.h index 84b4e40e..f2a2cf93 100644 --- a/base/stdpre.h +++ b/base/stdpre.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/stream.c b/base/stream.c index 30648bd5..2073a12a 100644 --- a/base/stream.c +++ b/base/stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -159,8 +159,13 @@ s_std_init(register stream * s, byte * ptr, uint len, const stream_procs * pp, { s->templat = &s_no_template; s->cbuf = ptr; - s->cursor.r.ptr = s->cursor.r.limit = s->cursor.w.ptr = ptr - 1; - s->cursor.w.limit = ptr - 1 + len; + + /* IMPORTANT: "read" MUST come before "write" - see comment in scommon.h about + * the layout of read/write cursor structures. + */ + stream_cursor_read_init(&s->cursor.r, ptr, 0); + stream_cursor_write_init(&s->cursor.w, ptr, len); + s->end_status = 0; s->foreign = 0; s->modes = modes; diff --git a/base/stream.h b/base/stream.h index a9fcf100..04ef117d 100644 --- a/base/stream.h +++ b/base/stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/strimpl.h b/base/strimpl.h index 166bccf4..1f51407a 100644 --- a/base/strimpl.h +++ b/base/strimpl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/string_.h b/base/string_.h index c4d56599..94698338 100644 --- a/base/string_.h +++ b/base/string_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/strmio.c b/base/strmio.c index aed84fb2..6f9aa77e 100644 --- a/base/strmio.c +++ b/base/strmio.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/strmio.h b/base/strmio.h index 5b43e00a..f61381cf 100644 --- a/base/strmio.h +++ b/base/strmio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/stub.mak b/base/stub.mak index b09a30fa..b61fd12a 100644 --- a/base/stub.mak +++ b/base/stub.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/szlibc.c b/base/szlibc.c index ee123fa1..0be33384 100644 --- a/base/szlibc.c +++ b/base/szlibc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/szlibd.c b/base/szlibd.c index b0f15a4c..e53b2266 100644 --- a/base/szlibd.c +++ b/base/szlibd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/szlibe.c b/base/szlibe.c index 028ed5e6..448b88f1 100644 --- a/base/szlibe.c +++ b/base/szlibe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/szlibx.h b/base/szlibx.h index 76a5aef0..f60b3dd1 100644 --- a/base/szlibx.h +++ b/base/szlibx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/szlibxx.h b/base/szlibxx.h index eae78b9f..fefb7440 100644 --- a/base/szlibxx.h +++ b/base/szlibxx.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/tesseract.mak b/base/tesseract.mak index 3dcc3ff0..9971c87b 100644 --- a/base/tesseract.mak +++ b/base/tesseract.mak @@ -24,7 +24,8 @@ TESSINCLUDES=\ # add -DDISABLED_LEGACY_ENGINE to TESSCXX # empty TESSERACT_LEGACY -TESSCXX = $(CXX) $(TESSINCLUDES) $(TESSCXXFLAGS) $(CCFLAGS) -DTESSERACT_IMAGEDATA_AS_PIX -DTESSERACT_DISABLE_DEBUG_FONTS -DGRAPHICS_DISABLED -DDISABLED_LEGACY_ENGINE +TESSCXX = $(CXX) $(TESSINCLUDES) $(TESSCXXFLAGS) $(CCFLAGS) -DTESSERACT_IMAGEDATA_AS_PIX -DTESSERACT_DISABLE_DEBUG_FONTS -DGRAPHICS_DISABLED +#-DDISABLED_LEGACY_ENGINE TESSOBJ = $(GLOBJDIR)$(D)tesseract_ TESSO_ = $(O_)$(TESSOBJ) @@ -32,21 +33,15 @@ TESSDEPS=\ $(arch_h)\ $(GLSRCDIR)/tesseract.mak\ $(GLGENDIR)/tesseract/version.h\ - $(TESSERACTDIR)/include/tesseract/apitypes.h\ $(TESSERACTDIR)/include/tesseract/baseapi.h\ $(TESSERACTDIR)/include/tesseract/capi.h\ - $(TESSERACTDIR)/include/tesseract/genericvector.h\ - $(TESSERACTDIR)/include/tesseract/helpers.h\ $(TESSERACTDIR)/include/tesseract/ltrresultiterator.h\ $(TESSERACTDIR)/include/tesseract/ocrclass.h\ $(TESSERACTDIR)/include/tesseract/osdetect.h\ $(TESSERACTDIR)/include/tesseract/pageiterator.h\ - $(TESSERACTDIR)/include/tesseract/platform.h\ $(TESSERACTDIR)/include/tesseract/publictypes.h\ $(TESSERACTDIR)/include/tesseract/renderer.h\ $(TESSERACTDIR)/include/tesseract/resultiterator.h\ - $(TESSERACTDIR)/include/tesseract/serialis.h\ - $(TESSERACTDIR)/include/tesseract/strngs.h\ $(TESSERACTDIR)/include/tesseract/thresholder.h\ $(TESSERACTDIR)/include/tesseract/unichar.h\ $(TESSERACTDIR)/src/arch/dotproduct.h\ @@ -108,13 +103,11 @@ TESSDEPS=\ $(TESSERACTDIR)/src/ccutil/bitvector.h\ $(TESSERACTDIR)/src/ccutil/ccutil.h\ $(TESSERACTDIR)/src/ccutil/clst.h\ - $(TESSERACTDIR)/src/ccutil/doubleptr.h\ $(TESSERACTDIR)/src/ccutil/elst.h\ $(TESSERACTDIR)/src/ccutil/elst2.h\ $(TESSERACTDIR)/src/ccutil/errcode.h\ $(TESSERACTDIR)/src/ccutil/fileerr.h\ $(TESSERACTDIR)/src/ccutil/genericheap.h\ - $(TESSERACTDIR)/src/ccutil/globaloc.h\ $(TESSERACTDIR)/src/ccutil/host.h\ $(TESSERACTDIR)/src/ccutil/indexmapbidi.h\ $(TESSERACTDIR)/src/ccutil/kdpair.h\ @@ -130,7 +123,6 @@ TESSDEPS=\ $(TESSERACTDIR)/src/ccutil/unicharmap.h\ $(TESSERACTDIR)/src/ccutil/unicharset.h\ $(TESSERACTDIR)/src/ccutil/unicity_table.h\ - $(TESSERACTDIR)/src/ccutil/unicodes.h\ $(TESSERACTDIR)/src/ccutil/universalambigs.h\ $(TESSERACTDIR)/src/classify/adaptive.h\ $(TESSERACTDIR)/src/classify/blobclass.h\ @@ -160,7 +152,6 @@ TESSDEPS=\ $(TESSERACTDIR)/src/classify/tessclassifier.h\ $(TESSERACTDIR)/src/classify/trainingsample.h\ $(TESSERACTDIR)/src/cutil/bitvec.h\ - $(TESSERACTDIR)/src/cutil/emalloc.h\ $(TESSERACTDIR)/src/cutil/oldlist.h\ $(TESSERACTDIR)/src/dict/dawg.h\ $(TESSERACTDIR)/src/dict/dawg_cache.h\ @@ -805,9 +796,6 @@ $(TESSOBJ)ccutil_elst.$(OBJ) : $(TESSERACTDIR)/src/ccutil/elst.cpp $(TESSDEPS) $(TESSOBJ)ccutil_errcode.$(OBJ) : $(TESSERACTDIR)/src/ccutil/errcode.cpp $(TESSDEPS) $(TESSCXX) $(TESSO_)ccutil_errcode.$(OBJ) $(C_) $(TESSERACTDIR)/src/ccutil/errcode.cpp -$(TESSOBJ)ccutil_globaloc.$(OBJ) : $(TESSERACTDIR)/src/ccutil/globaloc.cpp $(TESSDEPS) - $(TESSCXX) $(TESSO_)ccutil_globaloc.$(OBJ) $(C_) $(TESSERACTDIR)/src/ccutil/globaloc.cpp - $(TESSOBJ)ccutil_mainblk.$(OBJ) : $(TESSERACTDIR)/src/ccutil/mainblk.cpp $(TESSDEPS) $(TESSCXX) $(TESSO_)ccutil_mainblk.$(OBJ) $(C_) $(TESSERACTDIR)/src/ccutil/mainblk.cpp @@ -838,9 +826,6 @@ $(TESSOBJ)ccutil_unicharmap.$(OBJ) : $(TESSERACTDIR)/src/ccutil/unicharmap.cpp $ $(TESSOBJ)ccutil_unicharset.$(OBJ) : $(TESSERACTDIR)/src/ccutil/unicharset.cpp $(TESSDEPS) $(TESSCXX) $(TESSO_)ccutil_unicharset.$(OBJ) $(C_) $(TESSERACTDIR)/src/ccutil/unicharset.cpp -$(TESSOBJ)ccutil_unicodes.$(OBJ) : $(TESSERACTDIR)/src/ccutil/unicodes.cpp $(TESSDEPS) - $(TESSCXX) $(TESSO_)ccutil_unicodes.$(OBJ) $(C_) $(TESSERACTDIR)/src/ccutil/unicodes.cpp - $(TESSOBJ)ccutil_params.$(OBJ) : $(TESSERACTDIR)/src/ccutil/params.cpp $(TESSDEPS) $(TESSCXX) $(TESSO_)ccutil_params.$(OBJ) $(C_) $(TESSERACTDIR)/src/ccutil/params.cpp @@ -1057,7 +1042,6 @@ TESSERACT_OBJS_4=\ $(TESSOBJ)ccutil_elst2.$(OBJ)\ $(TESSOBJ)ccutil_elst.$(OBJ)\ $(TESSOBJ)ccutil_errcode.$(OBJ)\ - $(TESSOBJ)ccutil_globaloc.$(OBJ)\ $(TESSOBJ)ccutil_mainblk.$(OBJ)\ $(TESSOBJ)ccutil_serialis.$(OBJ)\ $(TESSOBJ)ccutil_strngs.$(OBJ)\ @@ -1068,7 +1052,6 @@ TESSERACT_OBJS_4=\ $(TESSOBJ)ccutil_unicharcompress.$(OBJ)\ $(TESSOBJ)ccutil_unicharmap.$(OBJ)\ $(TESSOBJ)ccutil_unicharset.$(OBJ)\ - $(TESSOBJ)ccutil_unicodes.$(OBJ)\ $(TESSOBJ)ccutil_params.$(OBJ)\ $(TESSOBJ)lstm_convolve.$(OBJ)\ $(TESSOBJ)lstm_fullyconnected.$(OBJ)\ @@ -1143,7 +1126,6 @@ TESSERACT_LEGACY_OBJS=\ $(TESSOBJ)classify_shapetable.$(OBJ)\ $(TESSOBJ)classify_tessclassifier.$(OBJ)\ $(TESSOBJ)classify_trainingsample.$(OBJ)\ - $(TESSOBJ)cutil_emalloc.$(OBJ)\ $(TESSOBJ)cutil_oldlist.$(OBJ)\ $(TESSOBJ)dict_hyphen.$(OBJ)\ $(TESSOBJ)textord_equationdetectbase.$(OBJ)\ @@ -1166,8 +1148,8 @@ TESSERACT_LEGACY_OBJS=\ $(TESSOBJ)wordrec_wordclass.$(OBJ) -#TESSERACT_LEGACY=$(TESSERACT_LEGACY_OBJS) -TESSERACT_LEGACY= +TESSERACT_LEGACY=$(TESSERACT_LEGACY_OBJS) +#TESSERACT_LEGACY= TESS_ROMFS_ARGS=\ - -c -d Resource/ -P .$(D)Resource$(D) Tesseract$(D)* + -c -P $(GLSRCDIR)$(D)..$(D) tessdata$(D)* diff --git a/base/tessocr.cpp b/base/tessocr.cpp index 26e5432c..fec5979d 100644 --- a/base/tessocr.cpp +++ b/base/tessocr.cpp @@ -1,6 +1,4 @@ #include "tesseract/baseapi.h" -#include "tesseract/genericvector.h" -#include "tesseract/serialis.h" extern "C" { @@ -13,6 +11,7 @@ extern "C" #include "gssprintf.h" #include "gxiodev.h" #include "stream.h" +#include #ifndef PATH_MAX #define PATH_MAX 4096 @@ -24,6 +23,19 @@ extern "C" static int event = 0; #endif +/* Hackily define prototypes for alloc routines for leptonica. */ +extern "C" void *leptonica_malloc(size_t blocksize); +extern "C" void *leptonica_calloc(size_t numelm, size_t elemsize); +extern "C" void *leptonica_realloc(void *ptr, size_t blocksize); +extern "C" void leptonica_free(void *ptr); + +typedef struct +{ + gs_memory_t *mem; + tesseract::TessBaseAPI *api; +} wrapped_api; + + void *leptonica_malloc(size_t blocksize) { void *ret = malloc(blocksize); @@ -108,43 +120,104 @@ static void my_leptonica_free(void *ptr) } static bool -load_file(const char* filename, GenericVector* data) { +load_file(const char* filename, std::vector* data) { bool result = false; - gp_file *fp = gp_fopen(leptonica_mem, filename, "rb"); + gp_file *fp; + int code; + int size; + + code = gs_add_control_path(leptonica_mem, gs_permit_file_reading, filename); + if (code < 0) + return false; + + fp = gp_fopen(leptonica_mem, filename, "rb"); if (fp == NULL) - return false; + goto fail; gp_fseek(fp, 0, SEEK_END); - int size = (int)gp_ftell(fp); + size = (int)gp_ftell(fp); gp_fseek(fp, 0, SEEK_SET); // Trying to open a directory on Linux sets size to LONG_MAX. Catch it here. if (size > 0 && size < LONG_MAX) { // reserve an extra byte in case caller wants to append a '\0' character data->reserve(size + 1); - data->resize_no_init(size); + data->resize(size); result = static_cast(gp_fread(&(*data)[0], 1, size, fp)) == size; } gp_fclose(fp); + +fail: + (void)gs_remove_control_path(leptonica_mem, gs_permit_file_reading, filename); + return result; } static bool -tess_file_reader(const char *fname, GenericVector *out) +load_file_from_path(const char *path, const char *file, std::vector *out) +{ + const char *sep = gp_file_name_directory_separator(); + size_t seplen = strlen(sep); + size_t bufsize = strlen(path) + seplen + strlen(file) + 1; + const char *s, *e; + bool ret = 0; + char *buf = (char *)gs_alloc_bytes(leptonica_mem, bufsize, "load_file_from_path"); + if (buf == NULL) + return 0; + + s = path; + do { + e = path; + while (*e && *e != gp_file_name_list_separator) + e++; + memcpy(buf, s, e-s); + memcpy(&buf[e-s], sep, seplen); + strcpy(&buf[e-s+seplen], file); + ret = load_file(buf, out); + if (ret) + break; + s = e; + while (*s == gp_file_name_list_separator) + s++; + } while (*s != 0); + + gs_free_object(leptonica_mem, buf, "load_file_from_path"); + + return ret; +} + +#ifndef TESSDATA +#define TESSDATA tessdata +#endif +#define STRINGIFY2(S) #S +#define STRINGIFY(S) STRINGIFY2(S) +static char *tessdata_prefix = STRINGIFY(TESSDATA); + +static bool +tess_file_reader(const char *fname, std::vector *out) { const char *file = fname; const char *s; char text[PATH_MAX]; int code = 0; + bool found; stream *ps; gx_io_device *iodev; + /* fname, as supplied to us by Tesseract has TESSDATA_PREFIX prepended + * to it. Check that first. */ + found = load_file(fname, out); + if (found) + return found; + + /* Find file, fname with any prefix removed, and use that in + * the rest of the searches. */ for (s = fname; *s; s++) if (*s == '\\' || *s == '/') file = s+1; - /* FIXME: Try loading 'file' from gs specific paths */ + /* Next look in romfs in the tessdata directory. */ iodev = gs_findiodevice(leptonica_mem, (const byte *)"%rom", 4); - gs_snprintf(text, sizeof(text), "Resource/Tesseract/%s", file); + gs_snprintf(text, sizeof(text), "tessdata/%s", file); if (iodev) { long size; long i; @@ -155,7 +228,7 @@ tess_file_reader(const char *fname, GenericVector *out) size = (long)romfs_file_len(leptonica_mem, text); if (size >= 0) { out->reserve(size + 1); - out->resize_no_init(size); + out->resize(size); code = iodev->procs.open_file(iodev, text, strlen(text), "rb", &ps, leptonica_mem); if (code < 0) return code; @@ -177,60 +250,105 @@ tess_file_reader(const char *fname, GenericVector *out) } } - /* Fall back to gp_file access, first under Resource/Tesseract */ - if (load_file(text, out)) - return true; + /* Fall back to gp_file access under our configured tessdata path. */ + found = load_file_from_path(tessdata_prefix, file, out); + if (found) + return found; - /* Then under TESSDATA */ - return load_file(fname, out); + /* If all else fails, look in the current directory. */ + return load_file(file, out); } int -ocr_init_api(gs_memory_t *mem, const char *language, void **state) +ocr_init_api(gs_memory_t *mem, const char *language, int engine, void **state) { - tesseract::TessBaseAPI *api; + enum tesseract::OcrEngineMode mode; + wrapped_api *wrapped; + int code = 0; + + if (mem->non_gc_memory != mem) { + dlprintf("ocr_init_api must not be called with gc controlled memory!\n"); + return_error(gs_error_unknownerror); + } + + wrapped = (wrapped_api *)(void *)gs_alloc_bytes(mem, sizeof(*wrapped), "ocr_init_api"); + if (wrapped == NULL) + return gs_error_VMerror; - leptonica_mem = mem->non_gc_memory; + leptonica_mem = mem; setPixMemoryManager(my_leptonica_malloc, my_leptonica_free); - api = new tesseract::TessBaseAPI(); + + wrapped->mem = mem; + wrapped->api = new tesseract::TessBaseAPI(); *state = NULL; - if (api == NULL) { - leptonica_mem = NULL; - setPixMemoryManager(malloc, free); - return_error(gs_error_VMerror); + if (wrapped->api == NULL) { + code = gs_error_VMerror; + goto fail; + } + + if (language == NULL || language[0] == 0) { + language = "eng"; + } + + switch (engine) + { + case OCR_ENGINE_DEFAULT: + mode = tesseract::OcrEngineMode::OEM_DEFAULT; + break; + case OCR_ENGINE_LSTM: + mode = tesseract::OcrEngineMode::OEM_LSTM_ONLY; + break; + case OCR_ENGINE_LEGACY: + mode = tesseract::OcrEngineMode::OEM_TESSERACT_ONLY; + break; + case OCR_ENGINE_BOTH: + mode = tesseract::OcrEngineMode::OEM_TESSERACT_LSTM_COMBINED; + break; + default: + code = gs_error_rangecheck; + goto fail; } // Initialize tesseract-ocr with English, without specifying tessdata path - if (api->Init(NULL, 0, /* data, data_size */ - language, - tesseract::OcrEngineMode::OEM_DEFAULT, - NULL, 0, /* configs, configs_size */ - NULL, NULL, /* vars_vec */ - false, /* set_only_non_debug_params */ - &tess_file_reader)) { - delete api; - leptonica_mem = NULL; - setPixMemoryManager(malloc, free); - return_error(gs_error_unknownerror); + if (wrapped->api->Init(NULL, 0, /* data, data_size */ + language, + mode, + NULL, 0, /* configs, configs_size */ + NULL, NULL, /* vars_vec */ + false, /* set_only_non_debug_params */ + &tess_file_reader)) { + code = gs_error_unknownerror; + goto fail; } - *state = (void *)api; + *state = (void *)wrapped; return 0; +fail: + if (wrapped->api) { + delete wrapped->api; + } + leptonica_mem = NULL; + setPixMemoryManager(malloc, free); + gs_free_object(wrapped->mem, wrapped, "ocr_init_api"); + return_error(code); } void ocr_fin_api(gs_memory_t *mem, void *api_) { - tesseract::TessBaseAPI *api = (tesseract::TessBaseAPI *)api_; + wrapped_api *wrapped = (wrapped_api *)api_; - if (api == NULL) + if (wrapped == NULL) return; - api->End(); - delete api; + if (wrapped->api) { + wrapped->api->End(); + delete wrapped->api; + } + gs_free_object(wrapped->mem, wrapped, "ocr_fin_api"); leptonica_mem = NULL; setPixMemoryManager(malloc, free); } @@ -261,46 +379,37 @@ ocr_clear_image(Pix *image) } static int -do_ocr_image(gs_memory_t *mem, +do_ocr_image(wrapped_api *wrapped, int w, int h, int bpp, int raster, int xres, int yres, void *data, int restore, int hocr, int pagecount, - const char *language, char **out) { char *outText; - tesseract::TessBaseAPI *api; int code; Pix *image; *out = NULL; - if (language == NULL || *language == 0) - language = "eng"; - code = ocr_init_api(mem, language, (void **)&api); - if (code < 0) - return code; - if (bpp == 8) w = convert2pix((l_uint32 *)data, w, h, raster); - image = ocr_set_image(api, w, h, data, xres, yres); + image = ocr_set_image(wrapped->api, w, h, data, xres, yres); if (image == NULL) { if (restore && bpp == 8) convert2pix((l_uint32 *)data, w, h, raster); - ocr_fin_api(mem, api); return_error(gs_error_VMerror); } // Get OCR result //pixWrite("test.pnm", image, IFF_PNM); if (hocr) { - api->SetVariable("hocr_font_info", "true"); - api->SetVariable("hocr_char_boxes", "true"); - outText = api->GetHOCRText(pagecount); + wrapped->api->SetVariable("hocr_font_info", "true"); + wrapped->api->SetVariable("hocr_char_boxes", "true"); + outText = wrapped->api->GetHOCRText(pagecount); } else - outText = api->GetUTF8Text(); + outText = wrapped->api->GetUTF8Text(); ocr_clear_image(image); @@ -312,35 +421,34 @@ do_ocr_image(gs_memory_t *mem, if (outText) { size_t len = strlen(outText)+1; - *out = (char *)(void *)gs_alloc_bytes(mem, len, "ocr_to_utf8"); + *out = (char *)(void *)gs_alloc_bytes(wrapped->mem, len, "ocr_to_utf8"); if (*out) memcpy(*out, outText, len); } delete [] outText; - // Destroy used object and release memory - ocr_fin_api(mem, api); - return 0; } -int ocr_image_to_hocr(gs_memory_t *mem, +int ocr_image_to_hocr(void *api, int w, int h, int bpp, int raster, int xres, int yres, void *data, int restore, - int pagecount, const char *language, char **out) + int pagecount, char **out) { - return do_ocr_image(mem, w, h, bpp, raster, xres, yres, data, - restore, 1, pagecount, language, out); + return do_ocr_image((wrapped_api *)api, + w, h, bpp, raster, xres, yres, data, + restore, 1, pagecount, out); } -int ocr_image_to_utf8(gs_memory_t *mem, +int ocr_image_to_utf8(void *api, int w, int h, int bpp, int raster, int xres, int yres, void *data, int restore, - const char *language, char **out) + char **out) { - return do_ocr_image(mem, w, h, bpp, raster, xres, yres, data, - restore, 0, 0, language, out); + return do_ocr_image((wrapped_api *)api, + w, h, bpp, raster, xres, yres, data, + restore, 0, 0, out); } int @@ -349,7 +457,7 @@ ocr_recognise(void *api_, int w, int h, void *data, int (*callback)(void *, const char *, const int *, const int *, const int *, int), void *arg) { - tesseract::TessBaseAPI *api = (tesseract::TessBaseAPI *)api_; + wrapped_api *wrapped = (wrapped_api *)api_; Pix *image; int code; int word_bbox[4]; @@ -359,17 +467,17 @@ ocr_recognise(void *api_, int w, int h, void *data, int pointsize, font_id; const char* font_name; - if (api == NULL) + if (wrapped == NULL || wrapped->api == NULL) return 0; - image = ocr_set_image(api, w, h, data, xres, yres); + image = ocr_set_image(wrapped->api, w, h, data, xres, yres); if (image == NULL) return_error(gs_error_VMerror); - code = api->Recognize(NULL); + code = wrapped->api->Recognize(NULL); if (code >= 0) { /* Bingo! */ - tesseract::ResultIterator *res_it = api->GetIterator(); + tesseract::ResultIterator *res_it = wrapped->api->GetIterator(); while (!res_it->Empty(tesseract::RIL_BLOCK)) { if (res_it->Empty(tesseract::RIL_WORD)) { @@ -417,6 +525,148 @@ ocr_recognise(void *api_, int w, int h, void *data, return code; } +static Pix * +ocr_set_bitmap(wrapped_api *wrapped, + int w, int h, + const unsigned char *data, int data_x, int raster, + int xres, int yres) +{ + /* Tesseract prefers a border around things, so we add an 8 pixel + * border all around. */ +#define BORDER_SIZE 8 + int r = (w+BORDER_SIZE*2+3)&~3; + Pix *image = pixCreateHeader(r, h+BORDER_SIZE*2, 8); + unsigned char *pdata, *d; + const unsigned char *s; + int x, y; + + if (image == NULL) + return NULL; + + pdata = gs_alloc_bytes(wrapped->mem, r * (h+BORDER_SIZE*2), "ocr_set_bitmap"); + if (pdata == NULL) { + pixDestroy(&image); + return NULL; + } + pixSetData(image, (l_uint32 *)pdata); + pixSetPadBits(image, 1); + pixSetXRes(image, xres); + pixSetYRes(image, yres); + + s = &data[data_x>>3] + raster*(h-1); + d = pdata; + memset(d, 255, r * (h+BORDER_SIZE*2)); + d += r*BORDER_SIZE + BORDER_SIZE; + for (y = 0; y < h; y++) { + int b = 128>>(data_x & 7); + for (x = 0; x < w; x++) { + if (s[x>>3] & b) + d[x^3] = 0; + else + d[x^3] = 255; + b >>= 1; + if (b == 0) + b = 128; + } + s -= raster; + d += r; + } + + wrapped->api->SetImage(image); +// pixWrite("test.pnm", image, IFF_PNM); + + return image; +} + +static void +ocr_clear_bitmap(wrapped_api *wrapped, Pix *image) +{ + gs_free_object(wrapped->mem, pixGetData(image), "ocr_clear_bitmap"); + pixSetData(image, NULL); + pixDestroy(&image); +} + +int ocr_bitmap_to_unicodes(void *state, + const void *data, int data_x, + int w, int h, int raster, + int xres, int yres, int *unicode, int *char_count) +{ + wrapped_api *wrapped = (wrapped_api *)state; + Pix *image; + int code, max_chars = *char_count, count = 0; + + if (wrapped == NULL || wrapped->api == NULL) + return 0; + + image = ocr_set_bitmap(wrapped, w, h, (const unsigned char *)data, + data_x, raster, xres, yres); + if (image == NULL) + return_error(gs_error_VMerror); + + code = wrapped->api->Recognize(NULL); + if (code >= 0) { + /* Bingo! */ + tesseract::ResultIterator *res_it = wrapped->api->GetIterator(); + + while (!res_it->Empty(tesseract::RIL_BLOCK)) { + if (res_it->Empty(tesseract::RIL_WORD)) { + res_it->Next(tesseract::RIL_WORD); + continue; + } + + do { +#if FUTURE_DEVELOPMENT + int word_bbox[4]; + int char_bbox[4]; + int line_bbox[4]; +#endif + + const unsigned char *graph = (unsigned char *)res_it->GetUTF8Text(tesseract::RIL_SYMBOL); + if (graph && graph[0] != 0) { + /* Quick and nasty conversion from UTF8 to unicode. */ + if (graph[0] < 0x80) + unicode[count] = graph[0]; + else { + unicode[count] = graph[1] & 0x3f; + if (graph[0] < 0xE0) + unicode[count] += (graph[0] & 0x1f)<<6; + else { + unicode[count] = (graph[2] & 0x3f) | (*unicode << 6); + if (graph[0] < 0xF0) { + unicode[count] += (graph[0] & 0x0F)<<6; + } else { + unicode[count] = (graph[3] & 0x3f) | (*unicode<<6); + unicode[count] += (graph[0] & 0x7); + } + } + } + count++; +#if FUTURE_DEVELOPMENT + res_it->BoundingBox(tesseract::RIL_TEXTLINE, + line_bbox,line_bbox + 1, + line_bbox + 2,line_bbox + 3); + res_it->BoundingBox(tesseract::RIL_WORD, + word_bbox,word_bbox + 1, + word_bbox + 2,word_bbox + 3); + res_it->BoundingBox(tesseract::RIL_SYMBOL, + char_bbox,char_bbox + 1, + char_bbox + 2,char_bbox + 3); +#endif + } + res_it->Next(tesseract::RIL_SYMBOL); + } while (!res_it->Empty(tesseract::RIL_BLOCK) && + !res_it->IsAtBeginningOf(tesseract::RIL_WORD) && count < max_chars); + } + delete res_it; + code = code; + } + + ocr_clear_bitmap(wrapped, image); + *char_count = count; + + return code; +} + }; /* Currently tesseract is the only C++ lib we have. diff --git a/base/tessocr.h b/base/tessocr.h index c5e7967b..5685cd3e 100644 --- a/base/tessocr.h +++ b/base/tessocr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Artifex Software, Inc. +/* Copyright (C) 2020-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -21,25 +21,63 @@ #include "gsmemory.h" -int ocr_image_to_utf8(gs_memory_t *mem, - int w, int h, int bpp, int raster, - int xres, int yres, - void *data, int restore_data, - const char *language, char **out); +enum +{ + OCR_ENGINE_DEFAULT = 0, + OCR_ENGINE_LSTM = 1, + OCR_ENGINE_LEGACY = 2, + OCR_ENGINE_BOTH = 3 +}; -int ocr_image_to_hocr(gs_memory_t *mem, - int w, int h, int bpp, int raster, - int xres, int yres, void *data, int restore, - int pagecount, const char *language, char **out); +int ocr_init_api(gs_memory_t *mem, + const char *language, + int engine, + void **state); -int ocr_init_api(gs_memory_t *mem, const char *language, void **state); +void ocr_fin_api(gs_memory_t *mem, + void *state); -void ocr_fin_api(gs_memory_t *mem, void *api_); - -int ocr_recognise(void *api_, int w, int h, void *data, - int xres, int yres, +int ocr_recognise(void *state, + int w, + int h, + void *data, + int xres, + int yres, int (*callback)(void *, const char *, const int *, const int *, const int *, int), void *arg); -#endif +int ocr_bitmap_to_unicodes(void *state, + const void *data, + int data_x, + int w, + int h, + int raster, + int xres, + int yres, + int *unicode, + int *char_count); + +int ocr_image_to_utf8(void *state, + int w, + int h, + int bpp, + int raster, + int xres, + int yres, + void *data, + int restore_data, + char **out); +int ocr_image_to_hocr(void *state, + int w, + int h, + int bpp, + int raster, + int xres, + int yres, + void *data, + int restore, + int pagecount, + char **out); + +#endif diff --git a/base/tiff.mak b/base/tiff.mak index 8345d818..6f1aecf0 100644 --- a/base/tiff.mak +++ b/base/tiff.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -33,7 +33,7 @@ TIFFCONF_H=$(TIFFCONF)libtiff$(D)tiffconf$(TIFFCONFIG_SUFFIX).h # Define the name of this makefile. LIBTIFF_MAK=$(GLSRC)tiff.mak $(TOP_MAKEFILES) -TIFFCC=$(CC_) $(TIFF_CFLAGS) $(I_)$(TI_) $(II)$(JI_)$(_I) $(PF_) +TIFFCC=$(CC) $(I_)$(TI_) $(II)$(JI_)$(_I) $(PF_) $(CCFLAGS) $(TIFF_CFLAGS) TIFFDEP = $(AK) $(TIFFGEN)tif_config.h $(TIFFGEN)tiffconf.h $(LIBTIFF_MAK) $(MAKEDIRS) gstiffio_h=$(GLSRC)gstiffio.h @@ -203,10 +203,10 @@ $(TIFFOBJ)gstiffio.$(OBJ) : $(TIFFOBJ)gstiffio_$(SHARE_LIBTIFF).$(OBJ) $(LIBTIFF $(TIFFGEN)tif_config.h: $(TIFFCONFIG_H) $(LIBTIFF_MAK) $(MAKEDIRS) $(CP_) $(TIFFCONFIG_H) $(TIFFGEN)tif_config.h - + $(TIFFGEN)tiffconf.h: $(TIFFCONF_H) $(LIBTIFF_MAK) $(MAKEDIRS) $(CP_) $(TIFFCONF_H) $(TIFFGEN)tiffconf.h - + # Define the version of libtiff.dev that we are actually using. $(TIFFGEN)libtiff.dev : $(TIFFGEN)libtiff_$(SHARE_LIBTIFF).dev $(LIBTIFF_MAK) $(MAKEDIRS) $(CP_) $(TIFFGEN)libtiff_$(SHARE_LIBTIFF).dev $(TIFFGEN)libtiff.dev diff --git a/base/time_.h b/base/time_.h index 25466c5e..856e4d0f 100644 --- a/base/time_.h +++ b/base/time_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttcalc.c b/base/ttcalc.c index a8f805a1..844fc274 100644 --- a/base/ttcalc.c +++ b/base/ttcalc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttcalc.h b/base/ttcalc.h index f70b983f..d7184917 100644 --- a/base/ttcalc.h +++ b/base/ttcalc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttcommon.h b/base/ttcommon.h index 7bef167a..58433dd0 100644 --- a/base/ttcommon.h +++ b/base/ttcommon.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttconf.h b/base/ttconf.h index 7dcd60aa..f07a429a 100644 --- a/base/ttconf.h +++ b/base/ttconf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttconfig.h b/base/ttconfig.h index 44744097..b23d5937 100644 --- a/base/ttconfig.h +++ b/base/ttconfig.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttfinp.c b/base/ttfinp.c index 5052bb92..128057f4 100644 --- a/base/ttfinp.c +++ b/base/ttfinp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttfinp.h b/base/ttfinp.h index 0a1a5e9e..d8cf6141 100644 --- a/base/ttfinp.h +++ b/base/ttfinp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttfmain.c b/base/ttfmain.c index 2fbcacc1..4ee5dfd8 100644 --- a/base/ttfmain.c +++ b/base/ttfmain.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttfmemd.c b/base/ttfmemd.c index 04e63075..e72b7a98 100644 --- a/base/ttfmemd.c +++ b/base/ttfmemd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttfmemd.h b/base/ttfmemd.h index bde57a47..aaabd371 100644 --- a/base/ttfmemd.h +++ b/base/ttfmemd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttfoutl.h b/base/ttfoutl.h index 507b2720..32dd8d22 100644 --- a/base/ttfoutl.h +++ b/base/ttfoutl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttfsfnt.h b/base/ttfsfnt.h index 78c02646..05122ada 100644 --- a/base/ttfsfnt.h +++ b/base/ttfsfnt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttinterp.c b/base/ttinterp.c index 125dc582..2ac1783b 100644 --- a/base/ttinterp.c +++ b/base/ttinterp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttinterp.h b/base/ttinterp.h index c1c8efaf..a33acb43 100644 --- a/base/ttinterp.h +++ b/base/ttinterp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttload.c b/base/ttload.c index 42c71973..e56a5e4c 100644 --- a/base/ttload.c +++ b/base/ttload.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttload.h b/base/ttload.h index 76799b32..f6100073 100644 --- a/base/ttload.h +++ b/base/ttload.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttmisc.h b/base/ttmisc.h index c26450d9..9d560731 100644 --- a/base/ttmisc.h +++ b/base/ttmisc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttobjs.c b/base/ttobjs.c index e01b99b1..75eacb9c 100644 --- a/base/ttobjs.c +++ b/base/ttobjs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ttobjs.h b/base/ttobjs.h index fa7dd09f..2703f58f 100644 --- a/base/ttobjs.h +++ b/base/ttobjs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/tttables.h b/base/tttables.h index 2ceeb2f6..818588ba 100644 --- a/base/tttables.h +++ b/base/tttables.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/tttype.h b/base/tttype.h index 80c5036e..91aac7d7 100644 --- a/base/tttype.h +++ b/base/tttype.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/tttypes.h b/base/tttypes.h index aa26d20e..91e36ce8 100644 --- a/base/tttypes.h +++ b/base/tttypes.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/ugcclib.mak b/base/ugcclib.mak index 423903bb..8b408061 100644 --- a/base/ugcclib.mak +++ b/base/ugcclib.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/unistd_.h b/base/unistd_.h index a1bdbc0a..0ac355c4 100644 --- a/base/unistd_.h +++ b/base/unistd_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/unix-aux.mak b/base/unix-aux.mak index 3532091e..bf99697b 100644 --- a/base/unix-aux.mak +++ b/base/unix-aux.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/unix-dll.mak b/base/unix-dll.mak index 64b7ca09..cae247ff 100644 --- a/base/unix-dll.mak +++ b/base/unix-dll.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -253,7 +253,7 @@ so-only: $(PCL_TARGET)-so-links-subtarget \ $(XPS_TARGET)-so-links-subtarget \ $(GPDL_TARGET)-so-links-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) - + so-only-stripped: $(MAKE) $(SUB_MAKE_OPTION) so-only-stripped-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) @@ -295,7 +295,28 @@ so-subtarget: so-only-subtarget CFLAGS='$(CFLAGS_STANDARD) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix)\ $(GSSOC_XE) $(GSSOX_XE) $(PCL_TARGET)-so-loader $(XPS_TARGET)-so-loader $(GPDL_TARGET)-so-loader -install-so: +install-so-gs: + $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + +install-so-gpcl6: + $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget-pcl BUILDDIRPREFIX=$(SODIRPREFIX) + +install-so-no_gpcl6: + $(NO_OP) + +install-so-gxps: + $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget-xps BUILDDIRPREFIX=$(SODIRPREFIX) + +install-so-no_gxps: + $(NO_OP) + +install-so-gpdl: + $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget-gpdl BUILDDIRPREFIX=$(SODIRPREFIX) + +install-so-no_gpdl: + $(NO_OP) + +install-so: install-so-$(PCL_SO_BASE) install-so-$(XPS_SO_BASE) install-so-$(GPDL_SO_BASE) $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) install-sodebug: @@ -321,6 +342,51 @@ install-so-subtarget: so-subtarget $(INSTALL_DATA) $(GLSRC)gserrors.h $(DESTDIR)$(gsincludedir)gserrors.h $(INSTALL_DATA) $(DEVSRC)gdevdsp.h $(DESTDIR)$(gsincludedir)gdevdsp.h +install-so-subtarget-pcl: so-subtarget + -mkdir -p $(DESTDIR)$(prefix) + -mkdir -p $(DESTDIR)$(bindir) + -mkdir -p $(DESTDIR)$(libdir) + -mkdir -p $(DESTDIR)$(gsincludedir) + $(INSTALL_PROGRAM) $(PCLSOC) $(DESTDIR)$(bindir)/$(PCLSOC_XENAME) + $(INSTALL_PROGRAM) $(BINDIR)/$(PCL_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(PCL_SONAME_MAJOR_MINOR) + $(RM_) $(DESTDIR)$(libdir)/$(PCL_SONAME) + ln -s $(PCL_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(PCL_SONAME) + $(RM_) $(DESTDIR)$(libdir)/$(PCL_SONAME_MAJOR) + ln -s $(PCL_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(PCL_SONAME_MAJOR) + $(INSTALL_DATA) $(PLSRC)plapi.h $(DESTDIR)$(gsincludedir)plapi.h + $(INSTALL_DATA) $(GLSRC)gserrors.h $(DESTDIR)$(gsincludedir)gserrors.h + $(INSTALL_DATA) $(DEVSRC)gdevdsp.h $(DESTDIR)$(gsincludedir)gdevdsp.h + +install-so-subtarget-xps: so-subtarget + -mkdir -p $(DESTDIR)$(prefix) + -mkdir -p $(DESTDIR)$(bindir) + -mkdir -p $(DESTDIR)$(libdir) + -mkdir -p $(DESTDIR)$(gsincludedir) + $(INSTALL_PROGRAM) $(XPSSOC) $(DESTDIR)$(bindir)/$(XPSSOC_XENAME) + $(INSTALL_PROGRAM) $(BINDIR)/$(XPS_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(XPS_SONAME_MAJOR_MINOR) + $(RM_) $(DESTDIR)$(libdir)/$(XPS_SONAME) + ln -s $(XPS_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(XPS_SONAME) + $(RM_) $(DESTDIR)$(libdir)/$(XPS_SONAME_MAJOR) + ln -s $(XPS_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(XPS_SONAME_MAJOR) + $(INSTALL_DATA) $(PLSRC)plapi.h $(DESTDIR)$(gsincludedir)plapi.h + $(INSTALL_DATA) $(GLSRC)gserrors.h $(DESTDIR)$(gsincludedir)gserrors.h + $(INSTALL_DATA) $(DEVSRC)gdevdsp.h $(DESTDIR)$(gsincludedir)gdevdsp.h + +install-so-subtarget-gpdl: so-subtarget + -mkdir -p $(DESTDIR)$(prefix) + -mkdir -p $(DESTDIR)$(bindir) + -mkdir -p $(DESTDIR)$(libdir) + -mkdir -p $(DESTDIR)$(gsincludedir) + $(INSTALL_PROGRAM) $(GPDLSOC) $(DESTDIR)$(bindir)/$(GPDLSOC_XENAME) + $(INSTALL_PROGRAM) $(BINDIR)/$(GPDL_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(GPDL_SONAME_MAJOR_MINOR) + $(RM_) $(DESTDIR)$(libdir)/$(GPDL_SONAME) + ln -s $(GPDL_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(GPDL_SONAME) + $(RM_) $(DESTDIR)$(libdir)/$(GPDL_SONAME_MAJOR) + ln -s $(GPDL_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(GPDL_SONAME_MAJOR) + $(INSTALL_DATA) $(PLSRC)plapi.h $(DESTDIR)$(gsincludedir)plapi.h + $(INSTALL_DATA) $(GLSRC)gserrors.h $(DESTDIR)$(gsincludedir)gserrors.h + $(INSTALL_DATA) $(DEVSRC)gdevdsp.h $(DESTDIR)$(gsincludedir)gdevdsp.h + soinstall: $(MAKE) $(SUB_MAKE_OPTION) soinstall-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) diff --git a/base/unix-end.mak b/base/unix-end.mak index 011ed2d4..d837d9ea 100644 --- a/base/unix-end.mak +++ b/base/unix-end.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/unix-gcc.mak b/base/unix-gcc.mak index 39685d2a..c8bc0659 100644 --- a/base/unix-gcc.mak +++ b/base/unix-gcc.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -265,15 +265,6 @@ SHARE_JBIG2=0 JBIG2SRCDIR=./jbig2dec JBIG2_CFLAGS=-DHAVE_STDINT_H=1 -# uncomment the following three lines and one of the last two to -# compile in the Luratech ldf_jb2 codec -#JBIG2_LIB=luratech -#SHARE_JBIG2=0 -#JBIG2SRCDIR=ldf_jb2 -#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DLINUX -#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD - - # Choose the library to use for (JPXDecode support) # whether to link to an external build or compile in from source # and source location and configuration flags for compiling in @@ -282,14 +273,6 @@ SHARE_JPX=0 JPXSRCDIR=./openjpeg JPX_CFLAGS= -DUSE_JPIP -DUSE_OPENJPEG_JP2 -DOPJ_HAVE_STDINT_H=1 -DOPJ_HAVE_INTTYPES_H=1 -DOPJ_HAVE_FSEEKO=1 -# uncomment the following three lines and one of the last two to -# compile in the Luratech lwf_jp2 codec -#JPX_LIB=luratech -#SHARE_JPX=0 -#JPXSRCDIR=lwf_jp2 -#JPX_CFLAGS=-DUSE_LWF_JP2 -DLINUX -#JPX_CFLAGS=-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD - # Uncomment the following 4 lines to to compile in OpenJPEG codec #JPX_LIB=openjpeg #SHARE_JPX=0 @@ -663,8 +646,6 @@ include $(GLSRCDIR)/zlib.mak include $(GLSRCDIR)/png.mak include $(GLSRCDIR)/tiff.mak include $(GLSRCDIR)/jbig2.mak -include $(GLSRCDIR)/ldf_jb2.mak -include $(GLSRCDIR)/lwf_jp2.mak include $(GLSRCDIR)/openjpeg.mak include $(GLSRCDIR)/cal.mak include $(GLSRCDIR)/ocr.mak diff --git a/base/unixansi.mak b/base/unixansi.mak index 093e617e..d8e11380 100644 --- a/base/unixansi.mak +++ b/base/unixansi.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/unixhead.mak b/base/unixhead.mak index adb430f1..adc94350 100644 --- a/base/unixhead.mak +++ b/base/unixhead.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/unixinst.mak b/base/unixinst.mak index 74bff55d..24483c93 100644 --- a/base/unixinst.mak +++ b/base/unixinst.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -83,7 +83,7 @@ install-data: install-libdata install-resdata$(COMPILE_INITS) install-iccdata$(C # There's no point in providing a complete dependency list: we include # one file from each subdirectory just as a sanity check. -install-libdata: +install-libdata: -mkdir -p $(DESTDIR)$(datadir) -mkdir -p $(DESTDIR)$(gsdir) -mkdir -p $(DESTDIR)$(gsdatadir) @@ -117,7 +117,7 @@ pdf2dsc.ps ;\ # install the default resource files # copy in every category (directory) but CVS -RES_CATEGORIES=`ls $(PSRESDIR) | grep -v CVS` +RES_CATEGORIES=`ls $(PSRESDIR) | grep -v CVS` install-resdata0 : $(PSRESDIR)/Decoding/Unicode -mkdir -p $(DESTDIR)$(datadir) -mkdir -p $(DESTDIR)$(gsdir) diff --git a/base/unixlink.mak b/base/unixlink.mak index 3f11e3a3..4c65229e 100644 --- a/base/unixlink.mak +++ b/base/unixlink.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or diff --git a/base/valgrind.h b/base/valgrind.h index 387e4855..0dc7d859 100644 --- a/base/valgrind.h +++ b/base/valgrind.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/version.mak b/base/version.mak index f2198432..88ea1634 100644 --- a/base/version.mak +++ b/base/version.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -14,10 +14,10 @@ # Major, minor and patch version numbers. GS_VERSION_MAJOR=9 -GS_VERSION_MINOR=53 -GS_VERSION_PATCH=1 +GS_VERSION_MINOR=54 +GS_VERSION_PATCH=0 # Revision date: year x 10000 + month x 100 + day. -GS_REVISIONDATE=20200914 +GS_REVISIONDATE=20210330 # Derived values GS_VERSION=$(GS_VERSION_MAJOR)$(GS_VERSION_MINOR)$(GS_VERSION_PATCH) GS_DOT_VERSION=$(GS_VERSION_MAJOR).$(GS_VERSION_MINOR).$(GS_VERSION_PATCH) diff --git a/base/vms_x_fix.h b/base/vms_x_fix.h index 2cacff54..472b5cb6 100644 --- a/base/vms_x_fix.h +++ b/base/vms_x_fix.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/vmsmath.h b/base/vmsmath.h index a8744d49..fea5d783 100644 --- a/base/vmsmath.h +++ b/base/vmsmath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/windows_.h b/base/windows_.h index c1f25578..5655b48c 100644 --- a/base/windows_.h +++ b/base/windows_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/winlib.mak b/base/winlib.mak index ece84f2d..5664a61b 100644 --- a/base/winlib.mak +++ b/base/winlib.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -44,14 +44,14 @@ SHARE_LCUPS=0 LCUPS_NAME= LCUPSSRCDIR=cups LCUPSBUILDTYPE=win -CUPS_CC=$(CC) $(CFLAGS) -DWIN32 +CUPS_CC=$(CC) $(CFLAGS) -DWIN32 !endif !ifndef LCUPSISRCDIR SHARE_LCUPSI=0 LCUPSI_NAME= LCUPSISRCDIR=cups -CUPS_CC=$(CC) $(CFLAGS) -DWIN32 +CUPS_CC=$(CC) $(CFLAGS) -DWIN32 !endif # Define the platform name. @@ -64,7 +64,7 @@ GSPLATFORM=mswin32_ !endif !endif -# Define the auxiliary program dependency. We use this to +# Define the auxiliary program dependency. We use this to # preconstruct ccf32.tr to get around the limit on the maximum # length of a command line. @@ -152,8 +152,6 @@ BEGINFILES=$(GLGENDIR)\ccf32.tr\ !include $(GLSRCDIR)\png.mak !include $(GLSRCDIR)\tiff.mak !include $(GLSRCDIR)\jbig2.mak -!include $(GLSRCDIR)\ldf_jb2.mak -!include $(GLSRCDIR)\lwf_jp2.mak !include $(GLSRCDIR)\openjpeg.mak !include $(GLSRCDIR)\cal.mak !include $(GLSRCDIR)\ocr.mak @@ -165,6 +163,7 @@ BEGINFILES=$(GLGENDIR)\ccf32.tr\ !include $(GLSRCDIR)\ijs.mak !include $(GLSRCDIR)\lcups.mak !include $(GLSRCDIR)\lcupsi.mak +!include $(DEVSRCDIR)\extract.mak !include $(DEVSRCDIR)\devs.mak !include $(DEVSRCDIR)\dcontrib.mak !include $(CONTRIBDIR)\contrib.mak diff --git a/base/winplat.mak b/base/winplat.mak index 4c42a53b..b53a5ec7 100644 --- a/base/winplat.mak +++ b/base/winplat.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -34,7 +34,7 @@ $(GLD)winplat1.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winplatxpsprint_) $(WINPLAT_M $(SETMOD) $(GLD)winplat1 $(winplatxpsprint_) $(GLD)winplat.dev : $(GLD)winplat$(XPSPRINT).dev - $(CP_) $(GLD)winplat$(XPSPRINT).dev $(GLD)winplat.dev + $(CP_) $(GLD)winplat$(XPSPRINT).dev $(GLD)winplat.dev $(GLOBJ)gp_ntfs.$(OBJ): $(GLSRC)gp_ntfs.c $(AK)\ $(dos__h) $(memory__h) $(stdio__h) $(string__h) $(windows__h)\ diff --git a/base/winrtsup.cpp b/base/winrtsup.cpp index c5104e52..ee22891d 100644 --- a/base/winrtsup.cpp +++ b/base/winrtsup.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/winrtsup.h b/base/winrtsup.h index 80a3169f..c3ee6ea0 100644 --- a/base/winrtsup.h +++ b/base/winrtsup.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/wrfont.c b/base/wrfont.c index d117e75a..6be5d0da 100644 --- a/base/wrfont.c +++ b/base/wrfont.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/wrfont.h b/base/wrfont.h index d8c2a06c..d1503a85 100644 --- a/base/wrfont.h +++ b/base/wrfont.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/write_t1.c b/base/write_t1.c index ae0d6eea..52902bea 100644 --- a/base/write_t1.c +++ b/base/write_t1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/write_t1.h b/base/write_t1.h index 0b16c387..c6fc5a3c 100644 --- a/base/write_t1.h +++ b/base/write_t1.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/write_t2.c b/base/write_t2.c index 9cf3883c..e56423d4 100644 --- a/base/write_t2.c +++ b/base/write_t2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -332,16 +332,15 @@ write_gsubrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output) for (i = 0; i < count; i++) { long buffer_size = a_output->m_limit - a_output->m_count < 0 ? 0 : a_output->m_limit - a_output->m_count; - int length = a_fapi_font->get_gsubr(a_fapi_font, i, a_output->m_pos, - (ushort) (buffer_size > 65535 ? 65535 : buffer_size)); + int length = a_fapi_font->get_gsubr(a_fapi_font, i, a_output->m_pos, buffer_size); if (length < 0) return length; if (a_output->m_pos) - WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length); - else - a_output->m_count += length; + a_output->m_pos += length; + + a_output->m_count += length; if (cur_offset) { long pos = a_output->m_pos - data_start + 1; @@ -387,16 +386,15 @@ write_subrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output) for (i = 0; i < count; i++) { long buffer_size = a_output->m_limit - a_output->m_count; - int length = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos, - (ushort) buffer_size); + int length = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos, buffer_size); if (length < 0) return length; if (a_output->m_pos) - WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length); - else - a_output->m_count += length; + a_output->m_pos += length; + + a_output->m_count += length; if (cur_offset) { long pos = a_output->m_pos - data_start + 1; diff --git a/base/write_t2.h b/base/write_t2.h index d3e4a30a..6c4d5a61 100644 --- a/base/write_t2.h +++ b/base/write_t2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/x_.h b/base/x_.h index 4d02d7a0..7ced6046 100644 --- a/base/x_.h +++ b/base/x_.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/base/zlib.mak b/base/zlib.mak index f697fdcc..5e66f922 100644 --- a/base/zlib.mak +++ b/base/zlib.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2020 Artifex Software, Inc. +# Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -53,9 +53,10 @@ ZAO_=$(O_)$(ZAUX) # syntax from other compilers. # ZI_ and ZF_ are defined in gs.mak. ZCCFLAGS=$(ZLIB_CFLAGS) $(I_)$(ZI_)$(_I) $(ZF_) $(D_)verbose$(_D_)-1$(_D) -ZCC=$(CC_) $(ZCCFLAGS) +ZCC=$(CC) $(ZCCFLAGS) $(CCFLAGS) + ZCCAUXFLAGS=$(ZLIB_CFLAGS) $(I_)$(ZI_)$(_I) $(ZF_) $(D_)verbose$(_D_)-1$(_D) -ZCCAUX=$(CCAUX_) $(ZCCAUXFLAGS) +ZCCAUX=$(CCAUX) $(ZCCAUXFLAGS) $(CCFLAGSAUX) # Define the name of this makefile. ZLIB_MAK=$(GLSRC)zlib.mak $(TOP_MAKEFILES) diff --git a/config.guess b/config.guess index f50dcdb6..0fc11edb 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2020 Free Software Foundation, Inc. -timestamp='2018-02-24' +timestamp='2020-11-07' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -32,7 +32,7 @@ timestamp='2018-02-24' # Please send patches to . -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -96,41 +94,47 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > "$dummy.c" ; - for c in cc gcc c89 c99 ; do - if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown +UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown +UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown +UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) @@ -138,7 +142,7 @@ Linux|GNU|GNU/*) # We could probably try harder. LIBC=gnu - eval "$set_cc_for_build" + set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) @@ -146,17 +150,15 @@ Linux|GNU|GNU/*) #elif defined(__dietlibc__) LIBC=dietlibc #else + #include + #ifdef __DEFINED_va_list + LIBC=musl + #else LIBC=gnu #endif + #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" - - # If ldd exists, use it to detect musl libc. - if command -v ldd >/dev/null && \ - ldd --version 2>&1 | grep -q ^musl - then - LIBC=musl - fi + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" ;; esac @@ -175,19 +177,20 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ - echo unknown)` + echo unknown)) case "$UNAME_MACHINE_ARCH" in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') + endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; @@ -199,7 +202,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -218,7 +221,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") ;; esac # The OS release @@ -231,24 +234,24 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in release='-gnu' ;; *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "$machine-${os}${release}${abi}" + echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) @@ -260,6 +263,9 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; @@ -269,26 +275,29 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; @@ -326,7 +335,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -360,7 +369,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then + if test "$( (/bin/universe) 2>/dev/null)" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd @@ -373,28 +382,28 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in + case $(/usr/bin/uname -p) in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval "$set_cc_for_build" + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null @@ -402,30 +411,30 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in SUN_ARCH=x86_64 fi fi - echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case "$(/usr/bin/arch -k)" in Series*|S4*) - UNAME_RELEASE=`uname -v` + UNAME_RELEASE=$(uname -v) ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case "`/bin/arch`" in + case "$(/bin/arch)" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; @@ -482,7 +491,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ @@ -505,8 +514,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && + dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && + SYSTEM_NAME=$("$dummy" "$dummyarg") && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; @@ -533,11 +542,11 @@ EOF exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + UNAME_PROCESSOR=$(/usr/bin/uname -p) + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then echo m88k-dg-dgux"$UNAME_RELEASE" else @@ -561,17 +570,17 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if test -x /usr/bin/oslevel ; then + IBM_REV=$(/usr/bin/oslevel) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -579,7 +588,7 @@ EOF exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include @@ -591,7 +600,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") then echo "$SYSTEM_NAME" else @@ -604,15 +613,15 @@ EOF fi exit ;; *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + if test -x /usr/bin/lslpp ; then + IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -640,14 +649,14 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + if test -x /usr/bin/getconf; then + sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) + sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 @@ -659,8 +668,8 @@ EOF esac ;; esac fi - if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" + if test "$HP_ARCH" = ""; then + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE @@ -694,13 +703,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ "$HP_ARCH" = hppa2.0w ] + if test "$HP_ARCH" = hppa2.0w then - eval "$set_cc_for_build" + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -722,11 +731,11 @@ EOF echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int @@ -752,7 +761,7 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; @@ -772,7 +781,7 @@ EOF echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then + if test -x /usr/sbin/sysversion ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 @@ -821,14 +830,14 @@ EOF echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -840,15 +849,26 @@ EOF *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=$(uname -p) + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf + fi + exit ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=$(/usr/bin/uname -p) case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin @@ -881,21 +901,21 @@ EOF echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; *:GNU:*:*) # the GNU system - echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" exit ;; - i*86:Minix:*:*) - echo "$UNAME_MACHINE"-pc-minix + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -905,7 +925,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -922,7 +942,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then @@ -971,23 +991,51 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" - test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1006,7 +1054,7 @@ EOF exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; @@ -1046,11 +1094,17 @@ EOF echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - if objdump -f /bin/sh | grep -q elf32-x86-64; then - echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 - else - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1090,7 +1144,7 @@ EOF echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else @@ -1099,19 +1153,19 @@ EOF exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in + case $(/bin/uname -X | grep "^Machine") in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 @@ -1161,7 +1215,7 @@ EOF 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1172,7 +1226,7 @@ EOF NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1205,7 +1259,7 @@ EOF exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=$( (uname -p) 2>/dev/null) echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv @@ -1239,7 +1293,7 @@ EOF echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then + if test -d /usr/nec; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" @@ -1287,44 +1341,48 @@ EOF *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval "$set_cc_for_build" - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=$(uname -p) + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc @@ -1362,6 +1420,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. + # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else @@ -1391,10 +1450,10 @@ EOF echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=$( (uname -p) 2>/dev/null) case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1404,7 +1463,7 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos @@ -1418,8 +1477,148 @@ EOF amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; esac +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null); + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in @@ -1442,6 +1641,12 @@ copies of config.guess and config.sub with the latest versions from: https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess and https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +EOF + +year=$(echo $timestamp | sed 's,-.*,,') +# shellcheck disable=SC2003 +if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then + cat >&2 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` +uname -m = $( (uname -m) 2>/dev/null || echo unknown) +uname -r = $( (uname -r) 2>/dev/null || echo unknown) +uname -s = $( (uname -s) 2>/dev/null || echo unknown) +uname -v = $( (uname -v) 2>/dev/null || echo unknown) -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` +/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) +/bin/uname -X = $( (/bin/uname -X) 2>/dev/null) -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` +hostinfo = $( (hostinfo) 2>/dev/null) +/bin/universe = $( (/bin/universe) 2>/dev/null) +/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) +/bin/arch = $( (/bin/arch) 2>/dev/null) +/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) +/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 # Local variables: -# eval: (add-hook 'write-file-functions 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config.sub b/config.sub index 1d8e98bc..c874b7a9 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2020 Free Software Foundation, Inc. -timestamp='2018-02-22' +timestamp='2020-11-07' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -50,7 +50,7 @@ timestamp='2018-02-22' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -89,7 +89,7 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) @@ -110,1223 +110,1167 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | cloudabi*-eabi* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo "$1" | sed 's/-[^-]*$//'` - if [ "$basic_machine" != "$1" ] - then os=`echo "$1" | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -lynx*) - os=-lynxos + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -ptx*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -psos*) - os=-psos + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | ba \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia16 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pru \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | wasm32 \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - leon|leon[3-9]) - basic_machine=sparc-$basic_machine - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + op50n) + cpu=hppa1.1 + vendor=oki ;; - ms1) - basic_machine=mt-unknown + op60c) + cpu=hppa1.1 + vendor=oki ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown + ibm*) + cpu=i370 + vendor=ibm ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none + orion105) + cpu=clipper + vendor=highlevel ;; - xscaleeb) - basic_machine=armeb-unknown + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; - - xscaleel) - basic_machine=armel-unknown + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | ba-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | e2k-* | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pru-* \ - | pyramid-* \ - | riscv32-* | riscv64-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | wasm32-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-pc - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - asmjs) - basic_machine=asmjs-unknown - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux + cpu=we32k + vendor=att ;; bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + cpu=powerpc + vendor=ibm + basic_os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + basic_os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx + cpu=m68k + vendor=motorola ;; dpx2*) - basic_machine=m68k-bull - os=-sysv3 - ;; - e500v[12]) - basic_machine=powerpc-unknown - os=$os"spe" - ;; - e500v[12]-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=$os"spe" - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + cpu=m68k + vendor=bull + basic_os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k3[2-9][0-9]) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm + cpu=hppa1.0 + vendor=hp ;; i*86v32) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv32 ;; i*86v4*) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv4 ;; i*86v) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv ;; i*86sol2) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-solaris2 + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=solaris2 ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - vsta) - basic_machine=i386-unknown - os=-vsta + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) + cpu=mips + vendor=sgi + case $basic_os in + irix*) ;; *) - os=-irix4 + basic_os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos + cpu=m68000 + vendor=convergent ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv + cpu=mips + vendor=sony + basic_os=newsos ;; next | m*-next) - basic_machine=m68k-next - case $os in - -nextstep* ) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + basic_os=nextstep2 ;; *) - os=-nextstep3 + basic_os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - nsv-tandem) - basic_machine=nsv-tandem - ;; - nsx-tandem) - basic_machine=nsx-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + basic_os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc + cpu=m68k + vendor=tti ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm + cpu=pn + vendor=gould ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + power) + cpu=power + vendor=ibm ;; - ppc64) basic_machine=powerpc64-unknown + ps2) + cpu=i386 + vendor=ibm ;; - ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + rm[46]00) + cpu=mips + vendor=siemens ;; - ppc64le | powerpc64little) - basic_machine=powerpc64le-unknown + rtpc | rtpc-*) + cpu=romp + vendor=ibm ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} ;; - ps2) - basic_machine=i386-ibm + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks ;; - pw32) - basic_machine=i586-unknown - os=-pw32 + tower | tower-32) + cpu=m68k + vendor=ncr ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - rdos32) - basic_machine=i386-pc - os=-rdos + w65) + cpu=w65 + vendor=wdc ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf ;; - rm[46]00) - basic_machine=mips-siemens + none) + cpu=none + vendor=none ;; - rtpc | rtpc-*) - basic_machine=romp-ibm + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine ;; - s390 | s390-*) - basic_machine=s390-ibm + leon-*|leon[3-9]-*) + cpu=sparc + vendor=$(echo "$basic_machine" | sed 's/-.*//') ;; - s390x | s390x-*) - basic_machine=s390x-ibm + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1334,203 +1278,213 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if test x$basic_os != x then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|') + ;; + os2-emx) + kernel=os2 + os=$(echo $basic_os | sed -e 's|os2-emx|emx|') + ;; + nto-qnx*) + kernel=nto + os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|') + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1543,258 +1497,356 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; pru-*) - os=-elf + os=elf ;; *-be) - os=-beos + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; *-next) - os=-nextstep + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-abi", so those need to count as OSes. + musl* | newlib* | uclibc*) + ;; + # Likewise for "kernel-libc" + eabi | eabihf | gnueabi | gnueabihf) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - -beos*) + *-beos*) vendor=be ;; - -hpux*) + *-hpux*) vendor=hp ;; - -mpeix*) + *-mpeix*) vendor=hp ;; - -hiux*) + *-hiux*) vendor=hitachi ;; - -unos*) + *-unos*) vendor=crds ;; - -dgux*) + *-dgux*) vendor=dg ;; - -luna*) + *-luna*) vendor=omron ;; - -genix*) + *-genix*) vendor=ns ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - -os400*) + s390-* | s390x-*) vendor=ibm ;; - -ptx*) + *-ptx*) vendor=sequent ;; - -tpf*) + *-tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - -aux*) + *-aux*) vendor=apple ;; - -hms*) + *-hms*) vendor=hitachi ;; - -mpw* | -macos*) + *-mpw* | *-macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - -vos*) + *-vos*) vendor=stratus ;; esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo "$basic_machine$os" +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: -# eval: (add-hook 'write-file-functions 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/configure b/configure index 3ace0a21..49b9a969 100755 --- a/configure +++ b/configure @@ -681,6 +681,7 @@ HAVE_MKSTEMP64 HAVE_FSEEKO HAVE_FILE64 HAVE_MKSTEMP +tessdata fontpath SO_LIB_VERSION_SEPARATOR DLL_EXT @@ -714,6 +715,7 @@ XPS_DEVS CUPS_DEVS F_DEVS P_DEVS +EXTRACT_DIR COMPILE_INITS GPDL_MAK GPDL_TARGET @@ -804,6 +806,7 @@ AUX_SHARED_ZLIB SHARE_ZLIB LIBJPEGDIR SHARE_LIBJPEG +FT_LIB_PATH FT_LIBS FT_CFLAGS FTSRCDIR @@ -924,6 +927,7 @@ enable_save_confaux enable_auxtools_only enable_contrib with_arch_h +with_sanitizer enable_sse2 enable_threadsafe with_large_color_index @@ -946,7 +950,6 @@ with_cups_serverbin with_cups_serverroot with_cups_datadir with_ijs -with_luratech with_jbig2dec enable_openjpeg with_urf @@ -960,10 +963,11 @@ with_gpdl enable_compile_inits with_drivers with_driversfile -with_openprinting +with_extract_dir enable_hidden_visibility enable_dynamic with_fontpath +with_tessdata with_memory_alignment enable_bswap32 enable_byteswap_h @@ -1640,6 +1644,9 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-arch_h= Use a custom arch.h (must be an absolute path) + --with-sanitizer=[address/memory] + Sanitizer for 'sanitize' target (defaults to + 'address') --without-tesseract do not try to use the Tesseract library for OCR --with-libiconv=[no/gnu/native] @@ -1659,8 +1666,6 @@ Optional Packages: --with-cups-serverroot override the "cups-config --serverroot" path --with-cups-datadir override the "cups-config --datadir" path --without-ijs disable IJS driver support - --without-luratech do not try to use the Luratech library for JBIG2 nor - JPX decoding --without-jbig2dec disable JBIG2 decode support --without-urf do not try to include URF support --without-cal do not try to use the CAL library for acceleration @@ -1704,7 +1709,10 @@ Optional Packages: have the same name). Default: ALL --with-driversfile=FILE Drivers to support from file, separated by newlines. + --with-extract-dir=EXTRACT_DIR + --with-fontpath set font search path for gs + --with-tessdata set tesseract data search path --with-memory-alignment Allows setting minimum alignment for the memory manager (4 or 8 bytes) --without-gnu-make disable GNU make features @@ -4065,7 +4073,7 @@ if test x"$host" != x"$build" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Begin recursive call to configure script (for auxiliary tools)" >&5 $as_echo "$as_me: Begin recursive call to configure script (for auxiliary tools)" >&6;} - "$absolute_source_path/configure" CC="$CCAUX" CFLAGS="$CFLAGSAUX" CPPFLAGS="$CPPFLAGSAUX" LDFLAGS="$LDFLAGSAUX" CCAUX= CFLAGSAUX= CFLAGSAUX= MAKEFILE=$AUXFLAGS_MAK --host=$build --build=$build --enable-auxtools_only --disable-hidden-visibility --with-local-zlib --without-libtiff --disable-contrib --disable-fontconfig --disable-dbus --disable-freetype --disable-fapi --disable-cups --disable-openjpeg --disable-gtk --with-libiconv=no --without-libidn --without-libpaper --without-pdftoraster --without-ijs --without-luratech --without-jbig2dec --without-x --with-drivers="" + "$absolute_source_path/configure" CC="$CCAUX" CFLAGS="$CFLAGSAUX" CPPFLAGS="$CPPFLAGSAUX" LDFLAGS="$LDFLAGSAUX" CCAUX= CFLAGSAUX= CFLAGSAUX= MAKEFILE=$AUXFLAGS_MAK --host=$build --build=$build --enable-auxtools_only --disable-hidden-visibility --with-local-zlib --without-libtiff --disable-contrib --disable-fontconfig --disable-dbus --disable-freetype --disable-fapi --disable-cups --disable-openjpeg --disable-gtk --with-libiconv=no --without-libidn --without-libpaper --without-pdftoraster --without-ijs --without-jbig2dec --without-x --with-drivers="" status=$? cp config.log "$olddir/configaux.log" if test $status -eq 0 ; then @@ -4896,12 +4904,20 @@ $as_echo " ...done." >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler/linker address santizer support" >&5 $as_echo_n "checking compiler/linker address santizer support... " >&6; } + +# Check whether --with-sanitizer was given. +if test "${with_sanitizer+set}" = set; then : + withval=$with_sanitizer; SANITIZER=$with_sanitizer +else + SANITIZER=address +fi + + CFLAGS_SANITIZE="" -CFLAGS_SANITIZE_TRY="-fsanitize=address -fno-omit-frame-pointer" +CFLAGS_SANITIZE_TRY="-fsanitize=$SANITIZER -fno-omit-frame-pointer" CFLAGS_SAVED="$CFLAGS" CFLAGS="$CFLAGS_SANITIZE_TRY" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -4918,7 +4934,14 @@ _ACEOF if ac_fn_c_try_link "$LINENO"; then : CFLAGS_SANITIZE="$CFLAGS" else - CFLAGS_SANITIZE="'****************ADDRESS_SANITIZER_NOT_SUPPORTED*********************'" + + if test x"$with_sanitizer" != x; then + as_fn_error $? "--with-sanitizer=$with_sanitizer not supported by compiler" "$LINENO" 5 + else + CFLAGS_SANITIZE="'****************ADDRESS_SANITIZER_NOT_SUPPORTED*********************'" + fi + + fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext @@ -7092,7 +7115,7 @@ return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : - HAVE_CXX_COMPILER=yes + HAVE_CXX_COMPILER=yes; else HAVE_CXX_COMPILER=no fi @@ -7100,11 +7123,46 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x$HAVE_CXX_COMPILER != xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Disabling tesseract as no working C++ compiler" >&5 $as_echo "$as_me: WARNING: Disabling tesseract as no working C++ compiler" >&2;} + elif test x$SYNC = xnosync ; then + as_fn_error $? "Threading disabled or not available. Tesseract OCR relies on threading. Rerun configure with \"--without-tesseract\" to exclude OCR from the build" "$LINENO" 5 else + + save_cxxflags="$CXXFLAGS" + cxxflags_to_try="-std=c++17 -stdlib=libstdc++" + CXXFLAGS_TO_USE="" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking supported C++ compiler flags" >&5 +$as_echo_n "checking supported C++ compiler flags... " >&6; } + for flag in $cxxflags_to_try ; do + CXXFLAGS="$CXXFLAGS $flag" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + + echo " $flag"; CXXFLAGS_TO_USE="$CXXFLAGS_TO_USE $flag" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + CXXFLAGS="$old_cflags" + done + + CXXFLAGS="$save_cxxflags $CXXFLAGS_TO_USE" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking sse4.1 support" >&5 $as_echo_n "checking sse4.1 support... " >&6; } save_cxxflags=$CXXFLAGS - TESS_CXXFLAGS="" + TESS_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -msse4.1" TESS_SSE4_1="" @@ -7544,6 +7602,7 @@ $as_echo_n "checking for libidn with pkg-config... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } LIBS="$LIBS `$PKGCONFIG --libs libidn`" + CFLAGS="$CFLAGS `$PKGCONFIG --cflags libidn`" HAVE_LIBIDN=-DHAVE_LIBIDN else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -7718,7 +7777,7 @@ $as_echo_n "checking for fontconfig with pkg-config... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } FONTCONFIG_CFLAGS="$CFLAGS `$PKGCONFIG --cflags fontconfig`" - FONTCONFIG_LIBS="`$PKGCONFIG --libs-only-l fontconfig`" + FONTCONFIG_LIBS="`$PKGCONFIG --libs fontconfig`" HAVE_FONTCONFIG=-DHAVE_FONTCONFIG else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -7993,9 +8052,16 @@ $as_echo_n "checking for system freetype2 >= 2.4.2 with pkg-config... " >&6; } if $PKGCONFIG --atleast-version=12.0.6 freetype2; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - FT_CFLAGS="$CFLAGS `$PKGCONFIG --cflags freetype2`" - FT_LIBS="`$PKGCONFIG --libs-only-l freetype2`" - FT_BRIDGE=1 + if test "x$FT_CFLAGS" = "x"; then + FT_CFLAGS="$CFLAGS `$PKGCONFIG --cflags freetype2`" + fi + if test "x$FT_LIBS" = "x"; then + FT_LIBS="`$PKGCONFIG --libs-only-l freetype2`" + fi + if test "x$FT_LIB_PATH" = "x"; then + FT_LIB_PATH="`$PKGCONFIG --libs-only-L freetype2`" + fi + FT_BRIDGE=1 SHARE_FT=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -8115,6 +8181,7 @@ fi + TIFF_JPEG_INCLUDE= if test x"$enable_auxtools_only" = x"yes" ; then @@ -8624,7 +8691,7 @@ XPSWRITEDEVICE='' LIBTIFFDIR='src' -LIBTIFFCONFDIR='' +LIBTIFFCONFDIR='src' TIFFCFLAGS='' TIFFDEVS_ALL='tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled tiffscaled4 tiffscaled8 tiffscaled24 tiffscaled32' @@ -8823,7 +8890,7 @@ esac # Skip this check for the recursive configure call. # Not relevant for AUX tools. if test x"$enable_auxtools_only" != x"yes" ; then - if test x"$SHARE_LIBTIFF" != x"$SHARE_LIBJPEG" ; then + if test x"$ENABLETIFF" != x"" && test x"$SHARE_LIBTIFF" != x"$SHARE_LIBJPEG" ; then as_fn_error $? "Mixing local libtiff with shared libjpeg not supported" "$LINENO" 5 fi fi @@ -9450,54 +9517,6 @@ SHARE_JBIG2=0 JBIG2DEVS='' JBIG2_AUTOCONF_CFLAGS= -LURATECHDIR=luratech - - -# Check whether --with-luratech was given. -if test "${with_luratech+set}" = set; then : - withval=$with_luratech; -fi - - - -if test x$with_luratech != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local Luratech JBIG2 library source" >&5 -$as_echo_n "checking for local Luratech JBIG2 library source... " >&6; } - if test -d $srcdir/luratech/ldf_jb2; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - JBIG2_DECODER=luratech - SHARE_JBIG2=0 - JBIG2DIR=$srcdir/luratech/ldf_jb2 - - if test x"$JBIG2_CFLAGS" != x""; then - JBIG2_AUTOCONF_CFLAGS="$JBIG2_CFLAGS" - else - case $host in - *-darwin*) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD -fsigned-char" - ;; - *-aix*) - if test $GCC = yes; then - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" - else - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -qchars=signed -DLINUX=1 -DFORTE" - fi - ;; - *) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" - ;; - esac - fi - - JBIG2FILEDEVS='$(DD)gdevjbig2.dev' - JBIG2DEVS='$(PSD)jbig2.dev' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi -fi - JB2_STDINT_TYPES_IN= JBIG2DEC_REQ=0.19 @@ -9673,42 +9692,6 @@ JPX_DECODER= JPX_AUTOCONF_CFLAGS= JPX_LRINTF_SUBST= -if test x$with_luratech != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local Luratech JPEG2K library source" >&5 -$as_echo_n "checking for local Luratech JPEG2K library source... " >&6; } - if test -d $srcdir/luratech/lwf_jp2; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - JPX_DECODER=luratech - SHARE_JPX=0 - JPXDIR=$srcdir/luratech/lwf_jp2 - - if test x"$JPX_CFLAGS" != x""; then - JPX_AUTOCONF_CFLAGS="$JPX_CFLAGS" - else - case $host in - *-darwin*) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD" - ;; - *-aix*) - if test $GCC = yes; then - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -fsigned-char -DLINUX=1 -DFORTE" - else - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -qchars=signed -DLINUX=1 -DFORTE" - fi - ;; - *) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX=1 -DFORTE" - ;; - esac - fi - JPXDEVS='$(PSD)jpx.dev' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi -fi - if test "x$ac_cv_header_stdint_h" = "xyes"; then CFLAGS_OPJ_HAVE_STDINT_H="-DOPJ_HAVE_STDINT_H=1" else @@ -11209,15 +11192,7 @@ IBM_DEVS='ibmpro jetp3852' OKI_DEVS='oki182 okiibm oki4w' JAPAN_DEVS='lips4 lips4v ljet4pjl lj4dithp dj505j picty180 lips2p bjc880j pr201 pr150 pr1000 pr1000_4 jj100 bj10v bj10vh mj700v2c mj500c mj6000c mj8000c fmpr fmlbp ml600 lbp310 lbp320 md50Mono md50Eco md1xMono escpage lp2000 npdl rpdl' MISC_PDEVS='uniprint ap3250 atx23 atx24 atx38 itk24i itk38 coslw2p coslwxl declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696 t4693d2 t4693d4 t4693d8 dl2100 la50 la70 la75 la75plus ln03 xes md2k md5k gdi samsunggdi' - - -# Check whether --with-openprinting was given. -if test "${with_openprinting+set}" = set; then : - withval=$with_openprinting; OPVP_DEVS='opvp oprp' -else - OPVP_DEVS='' -fi - +OPVP_DEVS='opvp oprp' ETS_HALFTONING_DEVS='rinkj' @@ -11230,6 +11205,41 @@ PCX_DEVS='pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk' PBM_DEVS='pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw pam pamcmyk4 pamcmyk32 plan plang planm planc plank' PS_DEVS='psdf psdcmyk psdrgb psdcmyk16 psdrgb16 pdfwrite ps2write eps2write bbox txtwrite inkcov ink_cov psdcmykog fpng pdfimage8 pdfimage24 pdfimage32 PCLm' +# Handle --with-extract-dir=EXTRACT_DIR - build extract library and docxwrite +# device. +# + +# Check whether --with-extract-dir was given. +if test "${with_extract_dir+set}" = set; then : + withval=$with_extract_dir; + EXTRACT_DIR="$withval" + if test x"$EXTRACT_DIR" != x"no"; then : + if test -e $EXTRACT_DIR; then : + PS_DEVS="$PS_DEVS docxwrite" +else + as_fn_error $? "EXTRACT_DIR does not exist: $EXTRACT_DIR" "$LINENO" 5 +fi +fi + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking Checking for \"extract\" in default location" >&5 +$as_echo_n "checking Checking for \"extract\" in default location... " >&6; } + EXTRACT_DIR="extract" + if test -e $EXTRACT_DIR; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; PS_DEVS="$PS_DEVS docxwrite" +else + EXTRACT_DIR=""; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi + + + + # the "display" device isn't an ideal fit in the list below, but it saves adding a "list" for just that one entry MISC_FDEVS='ccr cif inferno mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm bit bitrgb bitrgbtags bitcmyk devicen spotcmyk xcf plib plibg plibm plibc plibk display' @@ -11256,12 +11266,11 @@ while test -n "$drivers"; do PRINTERS) P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $APPLE_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS $URF_DEVS" IJS_DEVS0="$IJSDEVS" - if test x"$OPVP_DEVS" != x"" ; then - if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then - P_DEVS0="$P_DEVS0 $OPVP_DEVS" - else - as_fn_error $? "Unable to include opvp/oprp driver due to missing or disabled prerequisites..." "$LINENO" 5 - fi + if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then + P_DEVS0="$P_DEVS0 $OPVP_DEVS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&5 +$as_echo "$as_me: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&2;} fi ;; FILES) @@ -11606,6 +11615,7 @@ case $host in GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" DYNAMIC_LIBS="" SO_LIB_EXT=".so" ;; @@ -11781,6 +11791,21 @@ fi +# Check whether --with-tessdata was given. +if test "${with_tessdata+set}" = set; then : + withval=$with_tessdata; tessdata="$withval" +else + tessdata="" +fi + + +if test "x$tessdata" = "x"; then + tessdata="${datadir}/tessdata" +fi + + + + for ac_func in mkstemp do : ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp" diff --git a/configure.ac b/configure.ac index a5c55946..1532609f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -dnl Copyright (C) 2001-2020 Artifex Software, Inc. +dnl Copyright (C) 2001-2021 Artifex Software, Inc. dnl All Rights Reserved. dnl dnl This software is provided AS-IS with no warranty, either express or @@ -153,7 +153,7 @@ if test x"$host" != x"$build" ; then echo $AUXFLAGS_MAK_LINE07 >> $AUXFLAGS_MAK.in AC_MSG_NOTICE([Begin recursive call to configure script (for auxiliary tools)]) - "$absolute_source_path/configure" CC="$CCAUX" CFLAGS="$CFLAGSAUX" CPPFLAGS="$CPPFLAGSAUX" LDFLAGS="$LDFLAGSAUX" CCAUX= CFLAGSAUX= CFLAGSAUX= MAKEFILE=$AUXFLAGS_MAK --host=$build --build=$build --enable-auxtools_only --disable-hidden-visibility --with-local-zlib --without-libtiff --disable-contrib --disable-fontconfig --disable-dbus --disable-freetype --disable-fapi --disable-cups --disable-openjpeg --disable-gtk --with-libiconv=no --without-libidn --without-libpaper --without-pdftoraster --without-ijs --without-luratech --without-jbig2dec --without-x --with-drivers="" + "$absolute_source_path/configure" CC="$CCAUX" CFLAGS="$CFLAGSAUX" CPPFLAGS="$CPPFLAGSAUX" LDFLAGS="$LDFLAGSAUX" CCAUX= CFLAGSAUX= CFLAGSAUX= MAKEFILE=$AUXFLAGS_MAK --host=$build --build=$build --enable-auxtools_only --disable-hidden-visibility --with-local-zlib --without-libtiff --disable-contrib --disable-fontconfig --disable-dbus --disable-freetype --disable-fapi --disable-cups --disable-openjpeg --disable-gtk --with-libiconv=no --without-libidn --without-libpaper --without-pdftoraster --without-ijs --without-jbig2dec --without-x --with-drivers="" status=$? cp config.log "$olddir/configaux.log" if test $status -eq 0 ; then @@ -473,17 +473,28 @@ dnl check for sanitize support dnl ---------------------------- AC_MSG_CHECKING([compiler/linker address santizer support]) +AC_ARG_WITH([sanitizer], AC_HELP_STRING([--with-sanitizer=@<:@address/memory@:>@], + [Sanitizer for 'sanitize' target (defaults to 'address')]), + [SANITIZER=$with_sanitizer], [SANITIZER=address]) + CFLAGS_SANITIZE="" -CFLAGS_SANITIZE_TRY="-fsanitize=address -fno-omit-frame-pointer" +CFLAGS_SANITIZE_TRY="-fsanitize=$SANITIZER -fno-omit-frame-pointer" CFLAGS_SAVED="$CFLAGS" CFLAGS="$CFLAGS_SANITIZE_TRY" - AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [ return(0); ])], - [CFLAGS_SANITIZE="$CFLAGS"], [CFLAGS_SANITIZE="'****************ADDRESS_SANITIZER_NOT_SUPPORTED*********************'"]) + [CFLAGS_SANITIZE="$CFLAGS"], + [ + if test x"$with_sanitizer" != x; then + AC_MSG_ERROR([--with-sanitizer=$with_sanitizer not supported by compiler]) + else + CFLAGS_SANITIZE="'****************ADDRESS_SANITIZER_NOT_SUPPORTED*********************'" + fi + ] + ) CFLAGS="$CFLAGS_SAVED" @@ -837,17 +848,37 @@ if test x$with_tesseract != xno; then AC_LANG_PUSH(C++) AC_TRY_COMPILE([], [return 0;], - [HAVE_CXX_COMPILER=yes], + [HAVE_CXX_COMPILER=yes; AC_SUBST(CXX)], [HAVE_CXX_COMPILER=no]) if test x$HAVE_CXX_COMPILER != xyes; then AC_MSG_WARN([Disabling tesseract as no working C++ compiler]) + elif test x$SYNC = xnosync ; then + AC_MSG_ERROR([Threading disabled or not available. Tesseract OCR relies on threading. Rerun configure with "--without-tesseract" to exclude OCR from the build]) else + + save_cxxflags="$CXXFLAGS" + cxxflags_to_try="-std=c++17 -stdlib=libstdc++" + CXXFLAGS_TO_USE="" + + AC_MSG_CHECKING([supported C++ compiler flags]) + for flag in $cxxflags_to_try ; do + CXXFLAGS="$CXXFLAGS $flag" + + AC_TRY_COMPILE(, [return 0;], [ + echo " $flag"; CXXFLAGS_TO_USE="$CXXFLAGS_TO_USE $flag" + ]) + + CXXFLAGS="$old_cflags" + done + + CXXFLAGS="$save_cxxflags $CXXFLAGS_TO_USE" + dnl -------------------------------------------------- dnl check for sse4.1, avx, avx2 or fma dnl -------------------------------------------------- AC_MSG_CHECKING([sse4.1 support]) save_cxxflags=$CXXFLAGS - TESS_CXXFLAGS="" + TESS_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -msse4.1" TESS_SSE4_1="" @@ -1030,6 +1061,7 @@ if test x$with_libidn != xno; then if $PKGCONFIG --exists libidn; then AC_MSG_RESULT(yes) LIBS="$LIBS `$PKGCONFIG --libs libidn`" + CFLAGS="$CFLAGS `$PKGCONFIG --cflags libidn`" HAVE_LIBIDN=-DHAVE_LIBIDN else AC_MSG_RESULT(no) @@ -1102,7 +1134,7 @@ if test "$enable_fontconfig" != "no"; then if $PKGCONFIG --exists fontconfig; then AC_MSG_RESULT(yes) FONTCONFIG_CFLAGS="$CFLAGS `$PKGCONFIG --cflags fontconfig`" - FONTCONFIG_LIBS="`$PKGCONFIG --libs-only-l fontconfig`" + FONTCONFIG_LIBS="`$PKGCONFIG --libs fontconfig`" HAVE_FONTCONFIG=-DHAVE_FONTCONFIG else AC_MSG_RESULT(no) @@ -1241,9 +1273,16 @@ if test x"$enable_fapi" != xno; then # There is a table of corresponding ft2<->libtool numbers in freetype/docs/VERSION.DLL if $PKGCONFIG --atleast-version=12.0.6 freetype2; then AC_MSG_RESULT(yes) - FT_CFLAGS="$CFLAGS `$PKGCONFIG --cflags freetype2`" - FT_LIBS="`$PKGCONFIG --libs-only-l freetype2`" - FT_BRIDGE=1 + if test "x$FT_CFLAGS" = "x"; then + FT_CFLAGS="$CFLAGS `$PKGCONFIG --cflags freetype2`" + fi + if test "x$FT_LIBS" = "x"; then + FT_LIBS="`$PKGCONFIG --libs-only-l freetype2`" + fi + if test "x$FT_LIB_PATH" = "x"; then + FT_LIB_PATH="`$PKGCONFIG --libs-only-L freetype2`" + fi + FT_BRIDGE=1 SHARE_FT=1 else AC_MSG_RESULT(no) @@ -1297,6 +1336,7 @@ AC_SUBST(SHARE_FT) AC_SUBST(FTSRCDIR) AC_SUBST(FT_CFLAGS) AC_SUBST(FT_LIBS) +AC_SUBST(FT_LIB_PATH) TIFF_JPEG_INCLUDE= @@ -1527,7 +1567,7 @@ XPSWRITEDEVICE='' LIBTIFFDIR='src' -LIBTIFFCONFDIR='' +LIBTIFFCONFDIR='src' TIFFCFLAGS='' TIFFDEVS_ALL='tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled tiffscaled4 tiffscaled8 tiffscaled24 tiffscaled32' @@ -1620,7 +1660,7 @@ esac # Skip this check for the recursive configure call. # Not relevant for AUX tools. if test x"$enable_auxtools_only" != x"yes" ; then - if test x"$SHARE_LIBTIFF" != x"$SHARE_LIBJPEG" ; then + if test x"$ENABLETIFF" != x"" && test x"$SHARE_LIBTIFF" != x"$SHARE_LIBJPEG" ; then AC_MSG_ERROR([Mixing local libtiff with shared libjpeg not supported]) fi fi @@ -1918,48 +1958,6 @@ SHARE_JBIG2=0 JBIG2DEVS='' JBIG2_AUTOCONF_CFLAGS= -dnl Luratech detection -LURATECHDIR=luratech - -AC_ARG_WITH([luratech], AC_HELP_STRING([--without-luratech], - [do not try to use the Luratech library for JBIG2 nor JPX decoding])) - - -if test x$with_luratech != xno; then - AC_MSG_CHECKING([for local Luratech JBIG2 library source]) - if test -d $srcdir/luratech/ldf_jb2; then - AC_MSG_RESULT([yes]) - JBIG2_DECODER=luratech - SHARE_JBIG2=0 - JBIG2DIR=$srcdir/luratech/ldf_jb2 - - if test x"$JBIG2_CFLAGS" != x""; then - JBIG2_AUTOCONF_CFLAGS="$JBIG2_CFLAGS" - else - case $host in - *-darwin*) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD -fsigned-char" - ;; - *-aix*) - if test $GCC = yes; then - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" - else - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -qchars=signed -DLINUX=1 -DFORTE" - fi - ;; - *) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" - ;; - esac - fi - - JBIG2FILEDEVS='$(DD)gdevjbig2.dev' - JBIG2DEVS='$(PSD)jbig2.dev' - else - AC_MSG_RESULT([no]) - fi -fi - JB2_STDINT_TYPES_IN= JBIG2DEC_REQ=0.19 @@ -2066,39 +2064,6 @@ JPX_DECODER= JPX_AUTOCONF_CFLAGS= JPX_LRINTF_SUBST= -if test x$with_luratech != xno; then - AC_MSG_CHECKING([for local Luratech JPEG2K library source]) - if test -d $srcdir/luratech/lwf_jp2; then - AC_MSG_RESULT([yes]) - JPX_DECODER=luratech - SHARE_JPX=0 - JPXDIR=$srcdir/luratech/lwf_jp2 - - if test x"$JPX_CFLAGS" != x""; then - JPX_AUTOCONF_CFLAGS="$JPX_CFLAGS" - else - case $host in - *-darwin*) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD" - ;; - *-aix*) - if test $GCC = yes; then - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -fsigned-char -DLINUX=1 -DFORTE" - else - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -qchars=signed -DLINUX=1 -DFORTE" - fi - ;; - *) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX=1 -DFORTE" - ;; - esac - fi - JPXDEVS='$(PSD)jpx.dev' - else - AC_MSG_RESULT([no]) - fi -fi - if test "x$ac_cv_header_stdint_h" = "xyes"; then CFLAGS_OPJ_HAVE_STDINT_H="-DOPJ_HAVE_STDINT_H=1" else @@ -2618,8 +2583,7 @@ IBM_DEVS='ibmpro jetp3852' OKI_DEVS='oki182 okiibm oki4w' JAPAN_DEVS='lips4 lips4v ljet4pjl lj4dithp dj505j picty180 lips2p bjc880j pr201 pr150 pr1000 pr1000_4 jj100 bj10v bj10vh mj700v2c mj500c mj6000c mj8000c fmpr fmlbp ml600 lbp310 lbp320 md50Mono md50Eco md1xMono escpage lp2000 npdl rpdl' MISC_PDEVS='uniprint ap3250 atx23 atx24 atx38 itk24i itk38 coslw2p coslwxl declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696 t4693d2 t4693d4 t4693d8 dl2100 la50 la70 la75 la75plus ln03 xes md2k md5k gdi samsunggdi' - -AC_ARG_WITH([openprinting],, OPVP_DEVS='opvp oprp', OPVP_DEVS='') +OPVP_DEVS='opvp oprp' ETS_HALFTONING_DEVS='rinkj' @@ -2633,6 +2597,25 @@ PCX_DEVS='pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk' PBM_DEVS='pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw pam pamcmyk4 pamcmyk32 plan plang planm planc plank' PS_DEVS='psdf psdcmyk psdrgb psdcmyk16 psdrgb16 pdfwrite ps2write eps2write bbox txtwrite inkcov ink_cov psdcmykog fpng pdfimage8 pdfimage24 pdfimage32 PCLm' +# Handle --with-extract-dir=EXTRACT_DIR - build extract library and docxwrite +# device. +# +AC_ARG_WITH([extract-dir], + AC_HELP_STRING([--with-extract-dir=EXTRACT_DIR]), + [ + EXTRACT_DIR="$withval" + AS_IF([test x"$EXTRACT_DIR" != x"no"], + [AS_IF([test -e $EXTRACT_DIR],[ PS_DEVS="$PS_DEVS docxwrite"] ,AC_MSG_ERROR([EXTRACT_DIR does not exist: $EXTRACT_DIR]))]) + ], + [ + AC_MSG_CHECKING([Checking for "extract" in default location]) + EXTRACT_DIR="extract" + AS_IF([test -e $EXTRACT_DIR], [AC_MSG_RESULT(yes); PS_DEVS="$PS_DEVS docxwrite"], [EXTRACT_DIR=""; AC_MSG_RESULT(no)]) + ] +) + +AC_SUBST(EXTRACT_DIR) + # the "display" device isn't an ideal fit in the list below, but it saves adding a "list" for just that one entry MISC_FDEVS='ccr cif inferno mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm bit bitrgb bitrgbtags bitcmyk devicen spotcmyk xcf plib plibg plibm plibc plibk display' @@ -2659,12 +2642,10 @@ while test -n "$drivers"; do PRINTERS) P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $APPLE_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS $URF_DEVS" IJS_DEVS0="$IJSDEVS" - if test x"$OPVP_DEVS" != x"" ; then - if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then - P_DEVS0="$P_DEVS0 $OPVP_DEVS" - else - AC_MSG_ERROR(Unable to include opvp/oprp driver due to missing or disabled prerequisites...) - fi + if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then + P_DEVS0="$P_DEVS0 $OPVP_DEVS" + else + AC_MSG_WARN(Unable to include opvp/oprp driver due to missing or disabled prerequisites...) fi ;; FILES) @@ -3007,6 +2988,7 @@ case $host in GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" DYNAMIC_LIBS="" SO_LIB_EXT=".so" ;; @@ -3177,6 +3159,16 @@ fi AC_SUBST(fontpath) +dnl look for default tessdata... +AC_ARG_WITH([tessdata], AC_HELP_STRING([--with-tessdata], + [set tesseract data search path]), tessdata="$withval", tessdata="") + +if test "x$tessdata" = "x"; then + tessdata="${datadir}/tessdata" +fi + +AC_SUBST(tessdata) + dnl -------------------------------------------------- dnl Check for library functions dnl -------------------------------------------------- diff --git a/contrib/contrib.mak b/contrib/contrib.mak index 2edee7af..d7965dc9 100644 --- a/contrib/contrib.mak +++ b/contrib/contrib.mak @@ -23,7 +23,6 @@ CONTRIB_MAK=$(CONTRIBDIR)$(D)contrib.mak $(TOP_MAKEFILES) CONTRIBSRC=$(CONTRIBDIR)$(D) # Almost all device drivers depend on the following: -CONTDEVH=$(gserrors_h) $(gx_h) $(gxdevice_h) CONTDEV=$(AK) $(ECHOGS_XE) $(GDEVH) ###### --------------------------- Catalog -------------------------- ###### @@ -169,7 +168,7 @@ $(DD)iwlq.dev : $(appledmp_) $(DD)page.dev $(CONTDEV) $(CONTRIB_MAK) $(MAKEDIRS) ### ----------------- The BJC-210/240/250/250ex/265/1000 ---------------- ### -### +### ### For questions about the driver, mailto://szaszg@hu.inter.net ### http://bjc250gs.sourceforge.net ### @@ -264,7 +263,7 @@ $(DD)cdj970.dev : $(cdeskjet9_) $(DD)page.dev \ $(DEVOBJ)gdevdj9.$(OBJ) : $(CONTRIBSRC)gdevdj9.c $(PDEVH) $(math__h) $(string__h)\ $(gsparam_h) $(gxlum_h) $(gdevpcl_h) $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevdj9.$(OBJ) $(C_) $(CONTRIBSRC)gdevdj9.c - + ### -------------- cdnj500 - HP DesignJet 500 ------------- ### @@ -694,7 +693,7 @@ $(DD)md5k.dev : $(md2k_) $(DD)page.dev \ $(DEVOBJ)gdevmd2k.$(OBJ) : $(CONTRIBSRC)gdevmd2k.c $(PDEVH) $(gsparam_h) \ $(CONTDEV) $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevmd2k.$(OBJ) $(C_) $(CONTRIBSRC)gdevmd2k.c - + ### ----------------- The Okidata OkiPage 4w+ device ------------------- ### @@ -1080,7 +1079,7 @@ $(DEVOBJ)gdev10v.$(OBJ) : $(JAPSRC)gdev10v.c $(PDEVH) \ ## -## EPSON MachJet driver +## EPSON MachJet driver ## mj700v2c_=$(DEVOBJ)gdevmjc.$(OBJ) $(HPPCL) diff --git a/contrib/gdevadmp.c b/contrib/gdevadmp.c index 72fdcab6..6648dffe 100644 --- a/contrib/gdevadmp.c +++ b/contrib/gdevadmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/contrib/gdevdj9.c b/contrib/gdevdj9.c index 1800b3cb..efbeaef5 100644 --- a/contrib/gdevdj9.c +++ b/contrib/gdevdj9.c @@ -634,7 +634,7 @@ static int cdj970_get_params(gx_device * pdev, gs_param_list * plist) { int code; - + (void) ( (code = gdev_prn_get_params(pdev, plist)) < 0 || (code = param_write_int(plist, "Quality", &cdj970->quality)) < 0 || diff --git a/contrib/gdevlx32.c b/contrib/gdevlx32.c index b06c7ec1..7cbd2b97 100644 --- a/contrib/gdevlx32.c +++ b/contrib/gdevlx32.c @@ -903,9 +903,6 @@ lxm3200_put_params(gx_device *pdev, gs_param_list *plist) code = param_read_int(plist, "z31m", &z31m); /* What additional margin for the Z31 */ if(code < 0)return(code); - code = gdev_prn_put_params(pdev, plist); - if(code < 0)return code; - ((lxm_device *)pdev)->algnA = algnA; ((lxm_device *)pdev)->algnB = algnB; ((lxm_device *)pdev)->algnC = algnC; @@ -916,40 +913,54 @@ lxm3200_put_params(gx_device *pdev, gs_param_list *plist) ((lxm_device *)pdev)->model = model; /* Model selection: lxm3200, Z12, Z31. */ ((lxm_device *)pdev)->z31m = z31m; /* Additional margin for the Z31 */ - /* Depending on the selected rendering mode, change the - * driver's parameters that ghostscript needs for the - * dithering. We need to do it here because the "get_params" - * and "put_params" are the only routines in the driver that - * ghostscript calls before using the dithering parameters. - */ - switch(mode) - { - case LXM3200_M: - pdev->color_info.num_components = 1; - pdev->color_info.max_gray = 1; - pdev->color_info.max_color = 0; - pdev->color_info.dither_grays = 2; - pdev->color_info.dither_colors = 0; - break; + /* Depending on the selected rendering mode, change the + * driver's parameters that ghostscript needs for the + * dithering. We need to do it here because the "get_params" + * and "put_params" are the only routines in the driver that + * ghostscript calls before using the dithering parameters. + */ + { + int old_num = pdev->color_info.num_components; + + switch (mode) + { + case LXM3200_M: + pdev->color_info.num_components = 1; + pdev->color_info.max_gray = 1; + pdev->color_info.max_color = 0; + pdev->color_info.dither_grays = 2; + pdev->color_info.dither_colors = 0; + break; - case LXM3200_C: - pdev->color_info.num_components = 3; - pdev->color_info.max_gray = 1; - pdev->color_info.max_color = 1; - pdev->color_info.dither_grays = 2; - pdev->color_info.dither_colors = 2; - break; + case LXM3200_C: + pdev->color_info.num_components = 3; + pdev->color_info.max_gray = 1; + pdev->color_info.max_color = 1; + pdev->color_info.dither_grays = 2; + pdev->color_info.dither_colors = 2; + break; - case LXM3200_P: - pdev->color_info.num_components = 3; - pdev->color_info.max_gray = 1; - pdev->color_info.max_color = 2; - pdev->color_info.dither_grays = 2; - pdev->color_info.dither_colors = 3; - break; - } + case LXM3200_P: + pdev->color_info.num_components = 3; + pdev->color_info.max_gray = 1; + pdev->color_info.max_color = 2; + pdev->color_info.dither_grays = 2; + pdev->color_info.dither_colors = 3; + break; + } + /* The above is horrid. But, if we change the color model + the ICC profile needs to change too. Blow away the + current structure. A new one will be built when we + go to gdev_prn_put_params. */ + if (old_num != pdev->color_info.num_components) { + rc_decrement(pdev->icc_struct, "lxm3200_put_params"); + pdev->icc_struct = NULL; + } + } + + code = gdev_prn_put_params(pdev, plist); - return 0; + return code; } /* --------- Internal routines --------- */ diff --git a/contrib/lips4/gdevl4r.c b/contrib/lips4/gdevl4r.c index f5015b1d..d8bcec7e 100644 --- a/contrib/lips4/gdevl4r.c +++ b/contrib/lips4/gdevl4r.c @@ -647,7 +647,7 @@ lips4type_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int { if (!(lprn->CompBuf = gs_malloc(pdev->memory->non_gc_memory, bpl * 3 / 2 + 1, maxY, "(CompBuf)"))) return_error(gs_error_VMerror); - + /* This buffer is used by lips_rle_encode(), which can require double input size plus 2 bytes. */ if (!(lprn->CompBuf2 = gs_malloc(pdev->memory->non_gc_memory, bpl * 2 + 2, maxY, "(CompBuf2)"))) diff --git a/contrib/pcl3/eprn/gdeveprn.c b/contrib/pcl3/eprn/gdeveprn.c index d99895fd..4c9226c4 100644 --- a/contrib/pcl3/eprn/gdeveprn.c +++ b/contrib/pcl3/eprn/gdeveprn.c @@ -71,6 +71,7 @@ ghostscript's header files are not self-contained. Therefore, if this file does not compile because of undefined symbols, just add include directives until it does. */ +#include "gserrors.h" #include "iref.h" /* needed by icstate.h */ #include "gsmemraw.h" /* needed by icstate.h */ #include "gsmemory.h" /* needed by icstate.h */ diff --git a/cups/cups.mak b/cups/cups.mak index 8bb5ebe9..d1fd5eb9 100644 --- a/cups/cups.mak +++ b/cups/cups.mak @@ -3,7 +3,7 @@ # CUPS driver makefile for Ghostscript. # # Copyright 2001-2005 by Easy Software Products. -# Copyright 2007 Artifex Software, Inc. +# Copyright 2007-2021 Artifex Software, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/cups/gdevcups.c b/cups/gdevcups.c index aac6adae..84c535fc 100644 --- a/cups/gdevcups.c +++ b/cups/gdevcups.c @@ -4745,7 +4745,7 @@ cups_set_color_info(gx_device *pdev) /* I - Device info */ if (pdev->icc_struct) { rc_decrement(pdev->icc_struct, "cups_set_color_info"); } - pdev->icc_struct = gsicc_new_device_profile_array(pdev->memory); + pdev->icc_struct = gsicc_new_device_profile_array(pdev); code = gsicc_set_device_profile(pdev, pdev->memory, (char *)DEFAULT_RGB_ICC, gsDEFAULTPROFILE); @@ -4764,7 +4764,7 @@ cups_set_color_info(gx_device *pdev) /* I - Device info */ if (pdev->icc_struct) { rc_decrement(pdev->icc_struct, "cups_set_color_info"); } - pdev->icc_struct = gsicc_new_device_profile_array(pdev->memory); + pdev->icc_struct = gsicc_new_device_profile_array(pdev); code = gsicc_set_device_profile(pdev, pdev->memory->non_gc_memory, (char *)DEFAULT_GRAY_ICC, gsDEFAULTPROFILE); @@ -4785,7 +4785,7 @@ cups_set_color_info(gx_device *pdev) /* I - Device info */ if (pdev->icc_struct) { rc_decrement(pdev->icc_struct, "cups_set_color_info"); } - pdev->icc_struct = gsicc_new_device_profile_array(pdev->memory); + pdev->icc_struct = gsicc_new_device_profile_array(pdev); code = gsicc_set_device_profile(pdev, pdev->memory, (char *)DEFAULT_CMYK_ICC, gsDEFAULTPROFILE); diff --git a/cups/libs/images/color-wheel.png b/cups/libs/images/color-wheel.png new file mode 100644 index 00000000..f55e69f8 Binary files /dev/null and b/cups/libs/images/color-wheel.png differ diff --git a/cups/libs/images/cups-block-diagram.png b/cups/libs/images/cups-block-diagram.png new file mode 100644 index 00000000..d47052e2 Binary files /dev/null and b/cups/libs/images/cups-block-diagram.png differ diff --git a/cups/libs/images/cups-block-diagram.svg b/cups/libs/images/cups-block-diagram.svg new file mode 100644 index 00000000..3638f852 --- /dev/null +++ b/cups/libs/images/cups-block-diagram.svg @@ -0,0 +1,841 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Scheduler (cupsd) + + + + + Filter + PPD Filter + Backend + PortMonitor + + + + + + + JobFiles + Web Interface(CGI) + + + + + BerkeleyCommands + CUPSCommands + System VCommands + + + + + + + ConfigFiles + + + + + + + LogFiles + + Notifiers + EmailRSS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LPD Support(cups-lpd) + + + + Printer + + + + + + + + + + + + diff --git a/cups/libs/images/cups-command-chain.png b/cups/libs/images/cups-command-chain.png new file mode 100644 index 00000000..a7218e5c Binary files /dev/null and b/cups/libs/images/cups-command-chain.png differ diff --git a/cups/libs/images/cups-command-chain.svg b/cups/libs/images/cups-command-chain.svg new file mode 100644 index 00000000..7eb36174 --- /dev/null +++ b/cups/libs/images/cups-command-chain.svg @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + PPD + + + + OptionalCommandFilter + + + + + + + + + CommandFile + + + + + + Printer + + + + + OptionalPortMonitor + + + + + Backend + + + diff --git a/cups/libs/images/cups-icon.png b/cups/libs/images/cups-icon.png new file mode 100644 index 00000000..5c0f6ff2 Binary files /dev/null and b/cups/libs/images/cups-icon.png differ diff --git a/cups/libs/images/cups-postscript-chain.png b/cups/libs/images/cups-postscript-chain.png new file mode 100644 index 00000000..41f8bced Binary files /dev/null and b/cups/libs/images/cups-postscript-chain.png differ diff --git a/cups/libs/images/cups-postscript-chain.svg b/cups/libs/images/cups-postscript-chain.svg new file mode 100644 index 00000000..d1e2d3e8 --- /dev/null +++ b/cups/libs/images/cups-postscript-chain.svg @@ -0,0 +1,531 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + PPD + + + + + Printer + + + + + OptionalPortMonitor + + + + + Backend + + + + OptionalPostScriptFilter + + OptionalPostScriptFilter + + + + + + + + + + + + PrintFile + + + + + + + CUPSFilters + + + CUPSFilters + + + + + diff --git a/cups/libs/images/cups-raster-chain.png b/cups/libs/images/cups-raster-chain.png new file mode 100644 index 00000000..5349bd9f Binary files /dev/null and b/cups/libs/images/cups-raster-chain.png differ diff --git a/cups/libs/images/cups-raster-chain.svg b/cups/libs/images/cups-raster-chain.svg new file mode 100644 index 00000000..5130c819 --- /dev/null +++ b/cups/libs/images/cups-raster-chain.svg @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + PPD + + + + + Printer + + + + + OptionalPortMonitor + + + + + Backend + + + + OptionalPostScriptFilter + + + RequiredRasterFilter + + + + + + + + + + + + + PrintFile + + + + + + + CUPSFilters + + + CUPSFilters + + + + + diff --git a/cups/libs/images/cups.png b/cups/libs/images/cups.png new file mode 100644 index 00000000..5c0f6ff2 Binary files /dev/null and b/cups/libs/images/cups.png differ diff --git a/cups/libs/images/cups.svg b/cups/libs/images/cups.svg new file mode 100644 index 00000000..8d19c358 --- /dev/null +++ b/cups/libs/images/cups.svg @@ -0,0 +1,533 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + CUPS Icon + + + Michael Sweet + + + + + Apple Inc. + + + + + + + + + + + + + + + + + + + + diff --git a/cups/libs/images/left.gif b/cups/libs/images/left.gif new file mode 100644 index 00000000..e8200425 Binary files /dev/null and b/cups/libs/images/left.gif differ diff --git a/cups/libs/images/left.xcf.gz b/cups/libs/images/left.xcf.gz new file mode 100644 index 00000000..d403e78e Binary files /dev/null and b/cups/libs/images/left.xcf.gz differ diff --git a/cups/libs/images/raster-organization.png b/cups/libs/images/raster-organization.png new file mode 100644 index 00000000..c390f414 Binary files /dev/null and b/cups/libs/images/raster-organization.png differ diff --git a/cups/libs/images/raster-organization.svg b/cups/libs/images/raster-organization.svg new file mode 100644 index 00000000..442032f2 --- /dev/null +++ b/cups/libs/images/raster-organization.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + Synchronization Word + + + Page Header 1 Page Bitmap 1 + + + + Page Header N Page Bitmap N + + + + + + diff --git a/cups/libs/images/raster.png b/cups/libs/images/raster.png new file mode 100644 index 00000000..17ba3b23 Binary files /dev/null and b/cups/libs/images/raster.png differ diff --git a/cups/libs/images/raster.svg b/cups/libs/images/raster.svg new file mode 100644 index 00000000..58277e70 --- /dev/null +++ b/cups/libs/images/raster.svg @@ -0,0 +1,386 @@ + + + + + + + + + image/svg+xml + + + + + + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + Normalfalse + Normaltrue + ManualTumblefalse + ManualTumbletrue + Rotatedfalse + Rotatedtrue + Flippedfalse + Flippedtrue + + diff --git a/cups/libs/images/right.gif b/cups/libs/images/right.gif new file mode 100644 index 00000000..9ebe4643 Binary files /dev/null and b/cups/libs/images/right.gif differ diff --git a/cups/libs/images/sample-image.png b/cups/libs/images/sample-image.png new file mode 100644 index 00000000..f78760e0 Binary files /dev/null and b/cups/libs/images/sample-image.png differ diff --git a/cups/libs/images/sel.gif b/cups/libs/images/sel.gif new file mode 100644 index 00000000..36b16bf6 Binary files /dev/null and b/cups/libs/images/sel.gif differ diff --git a/cups/libs/images/smiley.jpg b/cups/libs/images/smiley.jpg new file mode 100644 index 00000000..0076fae2 Binary files /dev/null and b/cups/libs/images/smiley.jpg differ diff --git a/cups/libs/images/unsel.gif b/cups/libs/images/unsel.gif new file mode 100644 index 00000000..10477fe5 Binary files /dev/null and b/cups/libs/images/unsel.gif differ diff --git a/cups/libs/images/wait.gif b/cups/libs/images/wait.gif new file mode 100644 index 00000000..c18f421e Binary files /dev/null and b/cups/libs/images/wait.gif differ diff --git a/cups/libs/images/webinterface.png b/cups/libs/images/webinterface.png new file mode 100644 index 00000000..feca5d66 Binary files /dev/null and b/cups/libs/images/webinterface.png differ diff --git a/demos/c/Makefile b/demos/c/Makefile new file mode 100644 index 00000000..63dc4da5 --- /dev/null +++ b/demos/c/Makefile @@ -0,0 +1,12 @@ +api_test: api_test.c + (cd ../.. && ./autogen.sh) + (cd ../.. && make so XCFLAGS="-DCLUSTER") + pwd + gcc -fPIC -I../.. api_test.c -DGHOSTPDL=1 -lgpdl -L../../sobin -o api_test + +run_api_test: api_test + LD_LIBRARY_PATH=../../sobin ./api_test + +post_api_test: + md5sum apitest* + rm apitest* diff --git a/demos/c/api_test.c b/demos/c/api_test.c index 8cc61e78..2768c6bf 100644 --- a/demos/c/api_test.c +++ b/demos/c/api_test.c @@ -5,6 +5,11 @@ #define _WINDOWS_ #endif +/* We can't have pointers displayed in the test output, as that will + * change the output between runs. The following definition hides + * them. */ +#define HIDE_POINTERS + #include #include #include @@ -12,6 +17,7 @@ #include #include #include +#include #ifndef GHOSTPDL #define GHOSTPDL 1 @@ -72,6 +78,21 @@ typedef struct { const char *fname; } teststate_t; +#ifdef HIDE_POINTERS +void *hide_pointer(void *p) +{ + return (p == NULL) ? NULL : (void *)1; +} + +#define PTR(p) hide_pointer(p) + +#else + +#define PTR(p) p + +#endif + + /*--------------------------------------------------------------------*/ /* First off, we have a set of functions that cope with dumping lines * of rendered data to file. We use pnm formats for their simplicity. */ @@ -336,7 +357,7 @@ size(void *handle, void *device, int width, int height, SANITY_CHECK(ts); printf("size: w=%d h=%d r=%d f=%x m=%p\n", - width, height, raster, format, pimage); + width, height, raster, format, PTR(pimage)); ts->w = width; ts->h = height; ts->r = raster; @@ -429,7 +450,7 @@ memalloc(void *handle, void *device, size_t size) } ret = aligned_malloc(size, 64); - printf("memalloc: %"FMT_Z" -> %p\n", Z_CAST size, ret); + printf("memalloc: %"FMT_Z" -> %p\n", Z_CAST size, PTR(ret)); return ret; } @@ -440,7 +461,7 @@ memfree(void *handle, void *device, void *mem) teststate_t *ts = (teststate_t *)handle; SANITY_CHECK(ts); - printf("memfree: %p\n", mem); + printf("memfree: %p\n", PTR(mem)); aligned_free(mem); return 0; @@ -553,7 +574,7 @@ rectangle_request(void *handle, void *device, ts->mem = aligned_malloc(size, 64); *memory = ts->mem; - printf("x=%d y=%d w=%d h=%d mem=%p\n", *x, *y, *w, *h, *memory); + printf("x=%d y=%d w=%d h=%d mem=%p\n", *x, *y, *w, *h, PTR(*memory)); if (ts->mem == NULL) return -1; @@ -882,7 +903,7 @@ static int list_params(void *instance) { void *iter = NULL; - char *key; + const char *key; gs_set_param_type type; char buffer[1024]; int code; diff --git a/demos/csharp/api/ghostapi.cs b/demos/csharp/api/ghostapi.cs index b65aac9e..a3491fd7 100644 --- a/demos/csharp/api/ghostapi.cs +++ b/demos/csharp/api/ghostapi.cs @@ -22,7 +22,9 @@ namespace GhostAPI gs_spt_string = 5, /* void * is a char * */ gs_spt_long = 6, /* void * is a long * */ gs_spt_i64 = 7, /* void * is a int64_t * */ - gs_spt_size_t = 8 /* void * is a size_t * */ + gs_spt_size_t = 8, /* void * is a size_t * */ + gs_spt_parsed = 9, /* void * is a pointer to a char * to be parsed */ + gs_spt_more_to_come = 1 << 31 }; public enum gsEncoding @@ -63,7 +65,7 @@ namespace GhostAPI #endif #endif /* Callback proto for stdio */ - public delegate int gsStdIOHandler(IntPtr caller_handle, IntPtr buffer, int len); + public delegate int gs_stdio_handler(IntPtr caller_handle, IntPtr buffer, int len); /* Callback proto for poll function */ public delegate int gsPollHandler(IntPtr caller_handle); @@ -84,38 +86,43 @@ namespace GhostAPI CallingConvention = CallingConvention.StdCall)] public static extern void gsapi_delete_instance(IntPtr instance); - [DllImport(lib_dll, EntryPoint = "gsapi_init_with_args", CharSet = CharSet.Ansi, - CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_init_with_args(IntPtr instance, int argc, - IntPtr argv); - - [DllImport(lib_dll, EntryPoint = "gsapi_exit", CharSet = CharSet.Ansi, - CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_exit(IntPtr instance); - - [DllImport(lib_dll, EntryPoint = "gsapi_set_arg_encoding", CharSet = CharSet.Ansi, + [DllImport(lib_dll, EntryPoint = "gsapi_set_stdio_with_handle", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_set_arg_encoding(IntPtr instance, - int encoding); + public static extern int gsapi_set_stdio_with_handle(IntPtr instance, + gs_stdio_handler stdin, gs_stdio_handler stdout, gs_stdio_handler stderr, IntPtr caller_handle); [DllImport(lib_dll, EntryPoint = "gsapi_set_stdio", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern int gsapi_set_stdio(IntPtr instance, - gsStdIOHandler stdin, gsStdIOHandler stdout, gsStdIOHandler stderr); + gs_stdio_handler stdin, gs_stdio_handler stdout, gs_stdio_handler stderr); - [DllImport(lib_dll, EntryPoint = "gsapi_set_stdio_with_handle", CharSet = CharSet.Ansi, + [DllImport(lib_dll, EntryPoint = "gsapi_set_poll_with_handle", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_set_stdio_with_handle(IntPtr instance, - gsStdIOHandler stdin, gsStdIOHandler stdout, gsStdIOHandler stderr, IntPtr caller_handle); + public static extern int gsapi_set_poll_with_handle(IntPtr instance, gsPollHandler pollfn, + IntPtr caller_handle); [DllImport(lib_dll, EntryPoint = "gsapi_set_poll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern int gsapi_set_poll(IntPtr instance, gsPollHandler pollfn); - [DllImport(lib_dll, EntryPoint = "gsapi_set_poll_with_handle", CharSet = CharSet.Ansi, + [DllImport(lib_dll, EntryPoint = "gsapi_set_display_callback", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_set_poll_with_handle(IntPtr instance, gsPollHandler pollfn, - IntPtr caller_handle); + public static extern int gsapi_set_display_callback(IntPtr pinstance, IntPtr caller_handle); + + [DllImport(lib_dll, EntryPoint = "gsapi_register_callout", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_register_callout(IntPtr instance, gsCallOut callout, + IntPtr callout_handle); + + [DllImport(lib_dll, EntryPoint = "gsapi_deregister_callout", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_deregister_callout(IntPtr instance, gsCallOut callout, + IntPtr callout_handle); + + [DllImport(lib_dll, EntryPoint = "gsapi_set_arg_encoding", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_set_arg_encoding(IntPtr instance, + int encoding); [DllImport(lib_dll, EntryPoint = "gsapi_get_default_device_list", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] @@ -127,9 +134,19 @@ namespace GhostAPI public static extern int gsapi_set_default_device_list(IntPtr instance, IntPtr list, ref int listlen); - [DllImport(lib_dll, EntryPoint = "gsapi_run_string", CharSet = CharSet.Ansi, + [DllImport(lib_dll, EntryPoint = "gsapi_run_string_begin", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_run_string(IntPtr instance, IntPtr command, + public static extern int gsapi_run_string_begin(IntPtr instance, + int usererr, ref int exitcode); + + [DllImport(lib_dll, EntryPoint = "gsapi_run_string_continue", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_run_string_continue(IntPtr instance, + IntPtr command, int count, int usererr, ref int exitcode); + + [DllImport(lib_dll, EntryPoint = "gsapi_run_string_end", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_run_string_end(IntPtr instance, int usererr, ref int exitcode); [DllImport(lib_dll, EntryPoint = "gsapi_run_string_with_length", CharSet = CharSet.Ansi, @@ -137,29 +154,39 @@ namespace GhostAPI public static extern int gsapi_run_string_with_length(IntPtr instance, IntPtr command, uint length, int usererr, ref int exitcode); + [DllImport(lib_dll, EntryPoint = "gsapi_run_string", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_run_string(IntPtr instance, IntPtr command, + int usererr, ref int exitcode); + [DllImport(lib_dll, EntryPoint = "gsapi_run_file", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern int gsapi_run_file(IntPtr instance, IntPtr filename, int usererr, ref int exitcode); - [DllImport(lib_dll, EntryPoint = "gsapi_run_string_begin", CharSet = CharSet.Ansi, + [DllImport(lib_dll, EntryPoint = "gsapi_init_with_args", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_run_string_begin(IntPtr instance, - int usererr, ref int exitcode); + public static extern int gsapi_init_with_args(IntPtr instance, int argc, + IntPtr argv); - [DllImport(lib_dll, EntryPoint = "gsapi_run_string_continue", CharSet = CharSet.Ansi, - CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_run_string_continue(IntPtr instance, - IntPtr command, int count, int usererr, ref int exitcode); + [DllImport(lib_dll, EntryPoint = "gsapi_exit", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_exit(IntPtr instance); - [DllImport(lib_dll, EntryPoint = "gsapi_run_string_end", CharSet = CharSet.Ansi, + [DllImport(lib_dll, EntryPoint = "gsapi_set_param", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_run_string_end(IntPtr instance, - int usererr, ref int exitcode); + public static extern int gsapi_set_param(IntPtr instance, IntPtr param, IntPtr value, + gs_set_param_type type); - [DllImport(lib_dll, EntryPoint = "gsapi_set_display_callback", CharSet = CharSet.Ansi, + [DllImport(lib_dll, EntryPoint = "gsapi_get_param", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_set_display_callback(IntPtr pinstance, IntPtr caller_handle); + public static extern int gsapi_get_param(IntPtr instance, IntPtr param, IntPtr value, + gs_set_param_type type); + + [DllImport(lib_dll, EntryPoint = "gsapi_enumerate_params", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + public static extern int gsapi_enumerate_params(IntPtr instance, out IntPtr inter, + out IntPtr key, IntPtr type); [DllImport(lib_dll, EntryPoint = "gsapi_add_control_path", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] @@ -181,19 +208,7 @@ namespace GhostAPI CallingConvention = CallingConvention.StdCall)] public static extern int gsapi_is_path_control_active(IntPtr instance); - [DllImport(lib_dll, EntryPoint = "gsapi_set_param", CharSet = CharSet.Ansi, - CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_set_param(IntPtr instance, gs_set_param_type type, - IntPtr param, IntPtr value); - [DllImport(lib_dll, EntryPoint = "gsapi_register_callout", CharSet = CharSet.Ansi, - CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_register_callout(IntPtr instance, gsCallOut callout, - IntPtr callout_handle); - [DllImport(lib_dll, EntryPoint = "gsapi_deregister_callout", CharSet = CharSet.Ansi, - CallingConvention = CallingConvention.StdCall)] - public static extern int gsapi_deregister_callout(IntPtr instance, gsCallOut callout, - IntPtr callout_handle); } } diff --git a/demos/csharp/api/ghostnet.cs b/demos/csharp/api/ghostnet.cs index 9011768e..f033941f 100644 --- a/demos/csharp/api/ghostnet.cs +++ b/demos/csharp/api/ghostnet.cs @@ -4,9 +4,7 @@ using System.ComponentModel; /* Background threading */ using System.Collections.Generic; /* Use of List */ using System.IO; /* Use of path */ using GhostAPI; /* Use of Ghostscript API */ -#if WPF using ghostnet_wpf_example; /* For Print control */ -#endif namespace GhostNET { @@ -17,10 +15,10 @@ namespace GhostNET SAVE_RESULT, GET_PAGE_COUNT, GENERIC, - DISPLAY_DEV_THUMBS_NON_PDF, - DISPLAY_DEV_THUMBS_PDF, + DISPLAY_DEV_THUMBS, DISPLAY_DEV_NON_PDF, DISPLAY_DEV_PDF, + DISPLAY_DEV_RUN_FILE } public enum GS_Result_t { @@ -50,6 +48,8 @@ namespace GhostNET public List args; public int return_code; public double zoom; + public bool aa; + public bool is_valid; }; public class gsEventArgs : EventArgs @@ -86,37 +86,46 @@ public class gsEventArgs : EventArgs } } - /* Ghostscript display device callback delegates. */ + /* Ghostscript display device callback delegates. Make sure that + these are using Cdecl calling convention, which means gsdll + is doing the stack cleanup after the call */ /* New device has been opened */ /* This is the first event from this device. */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_open_del(IntPtr handle, IntPtr device); /* Device is about to be closed. */ /* Device will not be closed until this function returns. */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_preclose_del(IntPtr handle, IntPtr device); /* Device has been closed. */ /* This is the last event from this device. */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_close_del(IntPtr handle, IntPtr device); /* Device is about to be resized. */ /* Resize will only occur if this function returns 0. */ /* raster is byte count of a row. */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_presize_del(IntPtr handle, IntPtr device, int width, int height, int raster, uint format); /* Device has been resized. */ /* New pointer to raster returned in pimage */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_size_del(IntPtr handle, IntPtr device, int width, int height, int raster, uint format, IntPtr pimage); /* flushpage */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_sync_del(IntPtr handle, IntPtr device); /* showpage */ /* If you want to pause on showpage, then don't return immediately */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_page_del(IntPtr handle, IntPtr device, int copies, int flush); @@ -125,6 +134,7 @@ public class gsEventArgs : EventArgs * progressive update of the display. * This function pointer may be set to NULL if not required. */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_update_del(IntPtr handle, IntPtr device, int x, int y, int w, int h); @@ -135,10 +145,12 @@ public class gsEventArgs : EventArgs * image buffer. The first row will be placed at the address * returned by display_memalloc. */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_memalloc_del(IntPtr handle, IntPtr device, ulong size); /* Free memory for bitmap */ /* If this is NULL, the Ghostscript memory device will free the bitmap */ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int display_memfree_del(IntPtr handle, IntPtr device, IntPtr mem); private int display_size(IntPtr handle, IntPtr device, @@ -200,10 +212,6 @@ public class gsEventArgs : EventArgs return 0; } - /* Delegate for stdio */ - public delegate int gs_stdio_handler(IntPtr caller_handle, IntPtr buffer, - int len); - private int stdin_callback(IntPtr handle, IntPtr pointer, int count) { String output = Marshal.PtrToStringAnsi(pointer); @@ -231,7 +239,50 @@ public class gsEventArgs : EventArgs var mess = excep2.Message; } - return count; + /* Callback for progress on XPS creation */ + if (m_params.task == GS_Task_t.CREATE_XPS) + { + /* See if we have a page number */ + if (count >= 7 && output.Substring(0, 4) == "Page") + { + String page = output.Substring(5, count - 6); + int numVal; + try + { + double perc = 0.0; + numVal = System.Convert.ToInt32(page); + if (m_params.firstpage == -1 && m_params.lastpage == -1 && + m_params.pages == null) + { + /* Doing full document */ + perc = 100.0 * (double)numVal / (double)m_params.num_pages; + } + else + { + if (m_params.pages != null) + { + perc = 100.0 * ((double)numVal - m_params.currpage) / (double)m_params.num_pages; + m_params.currpage = m_params.currpage + 1; + } + else + { + /* continugous set of pages */ + perc = 100.0 * ((double)numVal - m_params.firstpage + 1) / (double)m_params.num_pages; + } + } + m_worker.ReportProgress((int)perc, m_params); + } + catch (FormatException) + { + Console.WriteLine("XPSPrint Error: Input string is not a sequence of digits."); + } + catch (OverflowException) + { + Console.WriteLine("XPSPrint Error: The number cannot fit in an Int32."); + } + } + } + return count; } private int stderr_callback(IntPtr handle, IntPtr pointer, int count) @@ -249,6 +300,8 @@ public class gsEventArgs : EventArgs int m_pagewidth; int m_pageheight; int m_pageraster; + gsParamState_t m_displaystate; + display_callback_t m_display_callback; IntPtr ptr_display_struct; @@ -267,13 +320,15 @@ public class gsEventArgs : EventArgs IntPtr data, gsParamState_t state); internal event gsCallBackPageRenderedMain gsPageRenderedMain; - + /* From my understanding you cannot pin delegates. These need to be declared * as members to keep a reference to the delegates and avoid their possible GC. - * since the C# GC has no idea that GS has a reference to these items. */ - readonly gs_stdio_handler raise_stdin; - readonly gs_stdio_handler raise_stdout; - readonly gs_stdio_handler raise_stderr; + * since the C# GC has no idea that GS has a reference to these items. While the + * methods themselves dont move, apparently the address of the translation code + * is what is passed, and one of these abstractions can be GC or relocated. */ + ghostapi.gs_stdio_handler raise_stdin; + ghostapi.gs_stdio_handler raise_stdout; + ghostapi.gs_stdio_handler raise_stderr; /* Ghostscript display callback struct */ public struct display_callback_t @@ -298,6 +353,10 @@ public class gsEventArgs : EventArgs gsInstance = IntPtr.Zero; dispInstance = IntPtr.Zero; + /* To keep track if we need to update any parameters */ + m_displaystate = new gsParamState_t(); + m_displaystate.is_valid = false; + /* Avoiding delegate GC during the life of this object */ raise_stdin = stdin_callback; raise_stdout = stdout_callback; @@ -371,10 +430,12 @@ public class gsEventArgs : EventArgs break; case GS_Task_t.DISPLAY_DEV_NON_PDF: case GS_Task_t.DISPLAY_DEV_PDF: - case GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF: - case GS_Task_t.DISPLAY_DEV_THUMBS_PDF: + case GS_Task_t.DISPLAY_DEV_THUMBS: m_worker.DoWork -= new DoWorkEventHandler(DisplayDeviceAsync); break; + case GS_Task_t.DISPLAY_DEV_RUN_FILE: + m_worker.DoWork -= new DoWorkEventHandler(DisplayDeviceRun); + break; default: m_worker.DoWork -= new DoWorkEventHandler(gsFileAsync); break; @@ -398,8 +459,7 @@ public class gsEventArgs : EventArgs private void gsProgressChanged(object sender, ProgressChangedEventArgs e) { /* Callback with progress */ - gsParamState_t Value = new gsParamState_t(); - gsEventArgs info = new gsEventArgs(false, e.ProgressPercentage, Value); + gsEventArgs info = new gsEventArgs(false, e.ProgressPercentage, (gsParamState_t) e.UserState); gsUpdateMain(info); } private gsParamState_t gsFileSync(gsParamState_t in_params) @@ -706,7 +766,7 @@ public class gsEventArgs : EventArgs total = total + count; perc = 100.0 * (double)total / (double)len; - worker.ReportProgress((int)perc); + worker.ReportProgress((int)perc, Params); if (worker.CancellationPending == true) { e.Cancel = true; @@ -785,46 +845,245 @@ public class gsEventArgs : EventArgs return; } - /* Worker task for using display device */ - private void DisplayDeviceAsync(object sender, DoWorkEventArgs e) + private void SetPageRange(int first, int last, bool delay) + { + int code; + + byte[] param_first = System.Text.Encoding.UTF8.GetBytes("FirstPage" + "\0"); + byte[] param_last = System.Text.Encoding.UTF8.GetBytes("LastPage" + "\0"); + + GCHandle pinParamFirst = GCHandle.Alloc(param_first, GCHandleType.Pinned); + GCHandle pinParamLast = GCHandle.Alloc(param_last, GCHandleType.Pinned); + GCHandle firstValue = GCHandle.Alloc(first, GCHandleType.Pinned); + GCHandle lastValue = GCHandle.Alloc(last, GCHandleType.Pinned); + code = ghostapi.gsapi_set_param(dispInstance, pinParamFirst.AddrOfPinnedObject(), + firstValue.AddrOfPinnedObject(), gs_set_param_type.gs_spt_int | gs_set_param_type.gs_spt_more_to_come); + if (code < 0) + { + pinParamFirst.Free(); + pinParamLast.Free(); + firstValue.Free(); + lastValue.Free(); + throw new GhostscriptException("SetPageRange: gsapi_set_param error"); + } + + if (delay) + code = ghostapi.gsapi_set_param(dispInstance, pinParamLast.AddrOfPinnedObject(), + lastValue.AddrOfPinnedObject(), gs_set_param_type.gs_spt_int | gs_set_param_type.gs_spt_more_to_come); + else + code = ghostapi.gsapi_set_param(dispInstance, pinParamLast.AddrOfPinnedObject(), + lastValue.AddrOfPinnedObject(), gs_set_param_type.gs_spt_int); + + pinParamFirst.Free(); + pinParamLast.Free(); + firstValue.Free(); + lastValue.Free(); + + if (code < 0) + { + throw new GhostscriptException("SetPageRange: gsapi_set_param error"); + } + } + + private void SetAA(bool aa, bool delay) + { + int code; + int value; + byte[] param_text = System.Text.Encoding.UTF8.GetBytes("TextAlphaBits" + "\0"); + byte[] param_graph = System.Text.Encoding.UTF8.GetBytes("GraphicsAlphaBits" + "\0"); + + if (aa) + value = 4; + else + value = 1; + + GCHandle pinParamText = GCHandle.Alloc(param_text, GCHandleType.Pinned); + GCHandle pinParamGraph = GCHandle.Alloc(param_graph, GCHandleType.Pinned); + GCHandle valueParam = GCHandle.Alloc(value, GCHandleType.Pinned); + + code = ghostapi.gsapi_set_param(dispInstance, pinParamText.AddrOfPinnedObject(), + valueParam.AddrOfPinnedObject(), gs_set_param_type.gs_spt_int | gs_set_param_type.gs_spt_more_to_come); + if (code < 0) + { + pinParamText.Free(); + pinParamGraph.Free(); + valueParam.Free(); + throw new GhostscriptException("SetAA: gsapi_set_param error"); + } + if (delay) + code = ghostapi.gsapi_set_param(dispInstance, pinParamGraph.AddrOfPinnedObject(), + valueParam.AddrOfPinnedObject(), gs_set_param_type.gs_spt_int | gs_set_param_type.gs_spt_more_to_come); + else + code = ghostapi.gsapi_set_param(dispInstance, pinParamGraph.AddrOfPinnedObject(), + valueParam.AddrOfPinnedObject(), gs_set_param_type.gs_spt_int); + + pinParamText.Free(); + pinParamGraph.Free(); + valueParam.Free(); + + if (code < 0) + { + throw new GhostscriptException("SetAA: gsapi_set_param error"); + } + } + + private void SetResolution(double zoom, bool delay) + { + int resolution = (int)(72.0 * zoom + 0.5); + int code; + + byte[] param = System.Text.Encoding.UTF8.GetBytes("HWResolution" + "\0"); + byte[] value = System.Text.Encoding.UTF8.GetBytes("[" + resolution + " " + resolution + "]\0"); + GCHandle pinParam = GCHandle.Alloc(param, GCHandleType.Pinned); + GCHandle valueParam = GCHandle.Alloc(value, GCHandleType.Pinned); + + if (delay) + code = ghostapi.gsapi_set_param(dispInstance, pinParam.AddrOfPinnedObject(), + valueParam.AddrOfPinnedObject(), gs_set_param_type.gs_spt_parsed | gs_set_param_type.gs_spt_more_to_come); + else + code = ghostapi.gsapi_set_param(dispInstance, pinParam.AddrOfPinnedObject(), + valueParam.AddrOfPinnedObject(), gs_set_param_type.gs_spt_parsed); + + pinParam.Free(); + valueParam.Free(); + + if (code < 0) + { + throw new GhostscriptException("SetResolution: gsapi_set_param error"); + } + } + + /* Worker task for running a file with a page range, aa and zoom level */ + private void DisplayDeviceRun(object sender, DoWorkEventArgs e) { int code = 0; gsParamState_t gsparams = (gsParamState_t)e.Argument; - GCHandle argPtrsStable = new GCHandle(); + int exitcode = 0; + gsparams.result = GS_Result_t.gsOK; - int num_params = gsparams.args.Count; - var argParam = new GCHandle[num_params]; - var argPtrs = new IntPtr[num_params]; - List CharacterArray = new List(num_params); - bool cleanup = true; + String fileName = gsparams.inputfile; + int firstpage = gsparams.firstpage; + int lastpage = gsparams.lastpage; gsparams.result = GS_Result_t.gsOK; + if (dispInstance == IntPtr.Zero) + { + gsparams.result = GS_Result_t.gsFAILED; + e.Result = gsparams; + gsDLLProblemMain("Failure: Display device not initialized"); + return; + } + try { - code = ghostapi.gsapi_new_instance(out dispInstance, IntPtr.Zero); - if (code < 0) + /* Set parameters if needed */ + if (!m_displaystate.is_valid) { - throw new GhostscriptException("DisplayDeviceAsync: gsapi_new_instance error"); - } + /* First time after thumbnails */ + if (gsparams.aa) + { + SetAA(gsparams.aa, true); + } - code = ghostapi.gsapi_set_stdio(dispInstance, stdin_callback, stdout_callback, stderr_callback); - if (code < 0) - { - throw new GhostscriptException("DisplayDeviceAsync: gsapi_set_stdio error"); + if (!(gsparams.firstpage == -1 && gsparams.lastpage == -1)) + { + SetResolution(gsparams.zoom, true); + SetPageRange(gsparams.firstpage, gsparams.lastpage, false); + } + else + { + SetResolution(gsparams.zoom, false); + } + m_displaystate.is_valid = true; } - - code = ghostapi.gsapi_set_arg_encoding(dispInstance, (int)gsEncoding.GS_ARG_ENCODING_UTF8); - if (code < 0) + else { - throw new GhostscriptException("DisplayDeviceAsync: gsapi_set_arg_encoding error"); + /* Rendering page range */ + if (!(gsparams.firstpage == -1 && gsparams.lastpage == -1)) + { + if (gsparams.aa != m_displaystate.aa) + SetAA(gsparams.aa, true); + if (gsparams.zoom != m_displaystate.zoom) + SetResolution(gsparams.zoom, true); + SetPageRange(gsparams.firstpage, gsparams.lastpage, false); + } + else + { + /* Rendering all pages */ + if (gsparams.aa != m_displaystate.aa) + { + if (gsparams.zoom != m_displaystate.zoom) + { + /* Zoom and AA change */ + SetAA(gsparams.aa, true); + SetResolution(gsparams.zoom, false); + } + else + { + /* AA change only */ + SetAA(gsparams.aa, false); + } + } + else + { + if (gsparams.zoom != m_displaystate.zoom) + { + /* Zoom change only */ + SetResolution(gsparams.zoom, false); + } + } + } } + m_displaystate.aa = gsparams.aa; + m_displaystate.zoom = gsparams.zoom; - code = ghostapi.gsapi_set_display_callback(dispInstance, ptr_display_struct); - if (code < 0) + byte[] fname = System.Text.Encoding.UTF8.GetBytes(fileName + "\0"); + GCHandle pinfname = GCHandle.Alloc(fname, GCHandleType.Pinned); + code = ghostapi.gsapi_run_file(dispInstance, pinfname.AddrOfPinnedObject(), 0, ref exitcode); + pinfname.Free(); + + if (exitcode < 0) { - throw new GhostscriptException("DisplayDeviceAsync: gsapi_set_display_callback error"); + throw new GhostscriptException("DisplayDeviceRun: gsapi_run_file error"); } + } + catch (GhostscriptException except) + { + gsparams.result = GS_Result_t.gsFAILED; + gsDLLProblemMain("Exception: " + except.Message); + } + finally + { + e.Result = gsparams; + } + } + + /* Worker task for using display device */ + private void DisplayDeviceAsync(object sender, DoWorkEventArgs e) + { + int code = 0; + gsParamState_t gsparams = (gsParamState_t)e.Argument; + GCHandle argPtrsStable = new GCHandle(); + + int num_params = gsparams.args.Count; + var argParam = new GCHandle[num_params]; + var argPtrs = new IntPtr[num_params]; + List CharacterArray = new List(num_params); + bool cleanup = true; + + gsparams.result = GS_Result_t.gsOK; + + if (dispInstance == IntPtr.Zero) + { + gsparams.result = GS_Result_t.gsFAILED; + e.Result = gsparams; + gsDLLProblemMain("Failure: Display device not initialized"); + return; + } + + try + { String fullcommand = ""; for (int k = 0; k < num_params; k++) @@ -863,17 +1122,11 @@ public class gsEventArgs : EventArgs { gsDLLProblemMain("Exception: " + except.Message); gsparams.result = GS_Result_t.gsFAILED; - if (dispInstance != IntPtr.Zero) - ghostapi.gsapi_delete_instance(dispInstance); - dispInstance = IntPtr.Zero; } catch (Exception except) { gsDLLProblemMain("Exception: " + except.Message); gsparams.result = GS_Result_t.gsFAILED; - if (dispInstance != IntPtr.Zero) - ghostapi.gsapi_delete_instance(dispInstance); - dispInstance = IntPtr.Zero; } finally { @@ -885,16 +1138,6 @@ public class gsEventArgs : EventArgs } argPtrsStable.Free(); e.Result = gsparams; - - if (gsparams.result == GS_Result_t.gsOK && (gsparams.task == GS_Task_t.DISPLAY_DEV_NON_PDF || - gsparams.task == GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF)) - { - gsParamState_t result = DisplayDeviceClose(); - if (gsparams.result == 0) - { - gsparams.result = result.result; - } - } } } return; @@ -927,10 +1170,12 @@ public class gsEventArgs : EventArgs break; case GS_Task_t.DISPLAY_DEV_NON_PDF: case GS_Task_t.DISPLAY_DEV_PDF: - case GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF: - case GS_Task_t.DISPLAY_DEV_THUMBS_PDF: + case GS_Task_t.DISPLAY_DEV_THUMBS: m_worker.DoWork += new DoWorkEventHandler(DisplayDeviceAsync); break; + case GS_Task_t.DISPLAY_DEV_RUN_FILE: + m_worker.DoWork += new DoWorkEventHandler(DisplayDeviceRun); + break; case GS_Task_t.SAVE_RESULT: case GS_Task_t.CREATE_XPS: default: @@ -993,9 +1238,6 @@ public class gsEventArgs : EventArgs gsparams.args.Add("gs"); gsparams.args.Add("-dNODISPLAY"); - gsparams.args.Add("-dNOPAUSE"); - gsparams.args.Add("-dBATCH"); - gsparams.args.Add("-I%rom%Resource/Init/"); //gsparams.args.Add("-q"); gsparams.args.Add("-sFile=\"" + fileName + "\""); gsparams.args.Add("--permit-file-read=\"" + fileName + "\""); @@ -1012,7 +1254,6 @@ public class gsEventArgs : EventArgs return -1; } -#if WPF /* Launch a thread to create XPS document for windows printing */ public gsStatus CreateXPS(String fileName, int resolution, int num_pages, Print printsettings, int firstpage, int lastpage) @@ -1022,13 +1263,10 @@ public class gsEventArgs : EventArgs gsparams.inputfile = fileName; gsparams.args.Add("gs"); - gsparams.args.Add("-dNOPAUSE"); - gsparams.args.Add("-dBATCH"); - gsparams.args.Add("-I%rom%Resource/Init/"); - gsparams.args.Add("-dSAFER"); gsparams.args.Add("-r" + resolution.ToString()); - gsparams.args.Add("-dNOCACHE"); gsparams.args.Add("-sDEVICE=xpswrite"); + gsparams.args.Add("-dNOPAUSE"); + gsparams.args.Add("-dBATCH"); gsparams.args.Add("-dFirstPage=" + firstpage.ToString()); gsparams.args.Add("-dLastPage=" + lastpage.ToString()); @@ -1064,10 +1302,10 @@ public class gsEventArgs : EventArgs gsparams.args.Add("-f"); gsparams.args.Add(fileName); gsparams.task = GS_Task_t.CREATE_XPS; + gsparams.num_pages = num_pages; return RunGhostscriptAsync(gsparams); } -#endif /* Launch a thread rendering all the pages with the display device * to distill an input PS file and save as a PDF. */ @@ -1078,10 +1316,6 @@ public class gsEventArgs : EventArgs gsparams.inputfile = fileName; gsparams.args.Add("gs"); - gsparams.args.Add("-dNOPAUSE"); - gsparams.args.Add("-dBATCH"); - gsparams.args.Add("-I%rom%Resource/Init/"); - gsparams.args.Add("-dSAFER"); gsparams.args.Add("-sDEVICE=pdfwrite"); gsparams.outputfile = Path.GetTempFileName(); gsparams.args.Add("-o" + gsparams.outputfile); @@ -1090,9 +1324,30 @@ public class gsEventArgs : EventArgs return RunGhostscriptAsync(gsparams); } + /* Run a file with the display device + * public gsStatus gsDsiplayDeviceRunFile() */ + public gsStatus gsDisplayDeviceRunFile(String fileName, double zoom, bool aa, int firstpage, int lastpage) + { + gsParamState_t gsparams = new gsParamState_t(); + + gsparams.inputfile = fileName; + gsparams.aa = aa; + gsparams.zoom = zoom; + gsparams.firstpage = firstpage; + gsparams.lastpage = lastpage; + if (firstpage > 0) + gsparams.currpage = firstpage - 1; + else + gsparams.currpage = 0; + + gsparams.task = GS_Task_t.DISPLAY_DEV_RUN_FILE; + + return RunGhostscriptAsync(gsparams); + } + /* Launch a thread rendering all the pages with the display device - * to collect thumbnail images or full resolution. */ - public gsStatus gsDisplayDeviceRenderAll(String fileName, double zoom, bool aa, GS_Task_t task) + * to collect thumbnail images via init_with_args. */ + public gsStatus gsDisplayDeviceRenderThumbs(String fileName, double zoom, bool aa, GS_Task_t task) { gsParamState_t gsparams = new gsParamState_t(); int format = (gsConstants.DISPLAY_COLORS_RGB | @@ -1102,10 +1357,7 @@ public class gsEventArgs : EventArgs gsparams.args = new List(); gsparams.args.Add("gs"); - gsparams.args.Add("-dNOPAUSE"); - gsparams.args.Add("-dBATCH"); - gsparams.args.Add("-I%rom%Resource/Init/"); - gsparams.args.Add("-dSAFER"); + gsparams.args.Add("-dFirstPage=1"); /* To ensure gdevflp is setup */ gsparams.args.Add("-r" + resolution); if (aa) { @@ -1122,7 +1374,6 @@ public class gsEventArgs : EventArgs return RunGhostscriptAsync(gsparams); } - /* Launch a thread rendering a set of pages with the display device. For use with languages that can be indexed via pages which include PDF and XPS */ public gsStatus gsDisplayDeviceRenderPages(String fileName, int first_page, int last_page, double zoom) @@ -1135,10 +1386,6 @@ public class gsEventArgs : EventArgs gsparams.args = new List(); gsparams.args.Add("gs"); - gsparams.args.Add("-dNOPAUSE"); - gsparams.args.Add("-dBATCH"); - gsparams.args.Add("-I%rom%Resource/Init/"); - gsparams.args.Add("-dSAFER"); gsparams.args.Add("-r" + resolution); gsparams.args.Add("-sDEVICE=display"); gsparams.args.Add("-dDisplayFormat=" + format); @@ -1152,6 +1399,72 @@ public class gsEventArgs : EventArgs return RunGhostscriptAsync(gsparams); } + /* Set up the display device ahead of time */ + public gsParamState_t DisplayDeviceOpen() + { + int code; + gsParamState_t gsparams = new gsParamState_t(); + gsparams.result = GS_Result_t.gsOK; + + if (dispInstance != IntPtr.Zero) + return gsparams; + + try + { + code = ghostapi.gsapi_new_instance(out dispInstance, IntPtr.Zero); + if (code < 0) + { + throw new GhostscriptException("DisplayDeviceOpen: gsapi_new_instance error"); + } + + code = ghostapi.gsapi_set_stdio(dispInstance, raise_stdin, raise_stdout, raise_stderr); + if (code < 0) + { + throw new GhostscriptException("DisplayDeviceOpen: gsapi_set_stdio error"); + } + + code = ghostapi.gsapi_set_arg_encoding(dispInstance, (int)gsEncoding.GS_ARG_ENCODING_UTF8); + if (code < 0) + { + throw new GhostscriptException("DisplayDeviceOpen: gsapi_set_arg_encoding error"); + } + + code = ghostapi.gsapi_set_display_callback(dispInstance, ptr_display_struct); + if (code < 0) + { + throw new GhostscriptException("DisplayDeviceOpen: gsapi_set_display_callback error"); + } + } + + catch (DllNotFoundException except) + { + gsDLLProblemMain("Exception: " + except.Message); + gsparams.result = GS_Result_t.gsFAILED; + } + catch (BadImageFormatException except) + { + gsDLLProblemMain("Exception: " + except.Message); + gsparams.result = GS_Result_t.gsFAILED; + } + catch (GhostscriptException except) + { + gsDLLProblemMain("Exception: " + except.Message); + gsparams.result = GS_Result_t.gsFAILED; + if (dispInstance != IntPtr.Zero) + ghostapi.gsapi_delete_instance(dispInstance); + dispInstance = IntPtr.Zero; + } + catch (Exception except) + { + gsDLLProblemMain("Exception: " + except.Message); + gsparams.result = GS_Result_t.gsFAILED; + if (dispInstance != IntPtr.Zero) + ghostapi.gsapi_delete_instance(dispInstance); + dispInstance = IntPtr.Zero; + } + return gsparams; + } + /* Close the display device and delete the instance */ public gsParamState_t DisplayDeviceClose() { @@ -1162,12 +1475,14 @@ public class gsEventArgs : EventArgs try { - int code1 = ghostapi.gsapi_exit(dispInstance); - if ((code == 0) || (code == gsConstants.E_QUIT)) - code = code1; + code = ghostapi.gsapi_exit(dispInstance); + if (code < 0) + { + out_params.result = GS_Result_t.gsFAILED; + throw new GhostscriptException("DisplayDeviceClose: gsapi_exit error"); + } ghostapi.gsapi_delete_instance(dispInstance); - dispInstance = IntPtr.Zero; } catch (Exception except) @@ -1176,6 +1491,8 @@ public class gsEventArgs : EventArgs out_params.result = GS_Result_t.gsFAILED; } + dispInstance = IntPtr.Zero; + m_displaystate.is_valid = false; return out_params; } diff --git a/demos/csharp/windows/ghostnet_wpf_example/DocPage.cs b/demos/csharp/windows/ghostnet_wpf_example/DocPage.cs index c28bd62d..93316d9d 100644 --- a/demos/csharp/windows/ghostnet_wpf_example/DocPage.cs +++ b/demos/csharp/windows/ghostnet_wpf_example/DocPage.cs @@ -10,6 +10,7 @@ namespace ghostnet_wpf_example private int height; private int width; private double zoom; + private bool aa; private BitmapSource bitmap; private String pagename; private int pagenum; @@ -41,6 +42,12 @@ namespace ghostnet_wpf_example set { zoom = value; } } + public bool AA + { + get { return aa; } + set { aa = value; } + } + public BitmapSource BitMap { get { return bitmap; } @@ -90,12 +97,13 @@ namespace ghostnet_wpf_example this.pagename = ""; } - public DocPage(int Height, int Width, double Zoom, BitmapSource BitMap, int PageNum) + public DocPage(int Height, int Width, double Zoom, BitmapSource BitMap, int PageNum, bool AA) { this.height = Height; this.width = Width; this.zoom = Zoom; this.bitmap = BitMap; + this.aa = AA; this.pagename = ("Page " + (pagenum + 1)); } }; diff --git a/demos/csharp/windows/ghostnet_wpf_example/MainPrint.cs b/demos/csharp/windows/ghostnet_wpf_example/MainPrint.cs index e1c7a1e3..40855ba0 100644 --- a/demos/csharp/windows/ghostnet_wpf_example/MainPrint.cs +++ b/demos/csharp/windows/ghostnet_wpf_example/MainPrint.cs @@ -6,6 +6,8 @@ using System.Windows.Xps.Packaging; using System.Printing; using System.Windows.Input; using System.IO; +using System.Diagnostics; +using System.ComponentModel; using GhostNET; namespace ghostnet_wpf_example @@ -14,6 +16,7 @@ namespace ghostnet_wpf_example { Print m_printcontrol = null; private xpsprint m_xpsprint = null; + PrintStatus m_printstatus = null; public void PrintDiagPrint(object PrintDiag) { @@ -38,14 +41,22 @@ namespace ghostnet_wpf_example case PrintPages_t.ALL: print_all = true; first_page = 1; - last_page = m_numpages + 1; + last_page = m_numpages; break; } + /* Show the progress bar dialog */ + m_printstatus = new PrintStatus(); + m_printstatus.Activate(); + m_printstatus.Show(); + string extension = System.IO.Path.GetExtension(m_currfile); + /* If file is already xps then gs need not do this */ - if (!(m_document_type == doc_t.XPS)) + /* We are doing this based on the extension but like should do + * it based upon the content */ + if ( !(String.Equals(extension.ToUpper(),"XPS") || String.Equals(extension.ToUpper(), "OXPS")) ) { - xaml_DistillProgress.Value = 0; + m_printstatus.xaml_PrintProgress.Value = 0; if (m_ghostscript.CreateXPS(m_currfile, Constants.DEFAULT_GS_RES, last_page - first_page + 1, m_printcontrol, first_page, last_page) == gsStatus.GS_BUSY) @@ -53,30 +64,41 @@ namespace ghostnet_wpf_example ShowMessage(NotifyType_t.MESS_STATUS, "GS currently busy"); return; } - else - { - xaml_CancelDistill.Visibility = System.Windows.Visibility.Collapsed; - xaml_DistillName.Text = "Convert to XPS"; - xaml_DistillName.FontWeight = FontWeights.Bold; - xaml_DistillGrid.Visibility = System.Windows.Visibility.Visible; - } } else PrintXPS(m_currfile, print_all, first_page, last_page, false); } + /* Printing is achieved using xpswrite device in ghostscript and + * pushing that file through the XPS print queue. Since we can + * only have one instance of gs, this occurs on a separate + * process compared to the viewer. */ private void PrintCommand(object sender, ExecutedRoutedEventArgs e) { - Print(sender, e); + if (m_viewer_state != ViewerState_t.DOC_OPEN) + return; + + /* Launch new process */ + string path = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; + try + { + string Arguments = m_currfile + " print " + m_currpage + " " + m_numpages; + Process.Start(path, Arguments); + } + catch (InvalidOperationException) + { + Console.WriteLine("InvalidOperationException"); + } + catch (Win32Exception) + { + Console.WriteLine("Win32 Exception: There was an error in opening the associated file. "); + } + return; } - /* Printing is achieved using xpswrite device in ghostscript and - * pushing that file through the XPS print queue */ - private void Print(object sender, ExecutedRoutedEventArgs e) + private void Print(string FileName) { - if (!m_file_open) - return; - + m_currfile = FileName; if (m_printcontrol == null) { m_printcontrol = new Print(this, m_numpages); @@ -110,8 +132,11 @@ namespace ghostnet_wpf_example m_xpsprint.PrintUpdate += PrintProgress; arguments.Add(m_xpsprint); - xaml_PrintGrid.Visibility = System.Windows.Visibility.Visible; - xaml_PrintProgress.Value = 0; + m_printstatus.xaml_PrintProgressText.Text = "Printing..."; + m_printstatus.xaml_PrintProgressText.FontWeight = FontWeights.Bold; + m_printstatus.xaml_PrintProgressGrid.Visibility = System.Windows.Visibility.Visible; + m_printstatus.xaml_PrintProgress.Value = 0; + m_viewer_state = ViewerState_t.PRINTING; PrintThread.Start(arguments); } @@ -151,33 +176,23 @@ namespace ghostnet_wpf_example switch (Information.Status) { case PrintStatus_t.PRINT_ERROR: - System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() => - { - ShowMessage(NotifyType_t.MESS_ERROR, "Printer Driver Error"); - xaml_PrintGrid.Visibility = System.Windows.Visibility.Collapsed; - })); - break; case PrintStatus_t.PRINT_CANCELLED: case PrintStatus_t.PRINT_READY: - System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() => - { - xaml_PrintGrid.Visibility = System.Windows.Visibility.Collapsed; - })); - break; case PrintStatus_t.PRINT_DONE: System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() => { - xaml_PrintGrid.Visibility = System.Windows.Visibility.Collapsed; - DeleteTempFile(Information.FileName); + if (File.Exists(Information.FileName)) + DeleteTempFile(Information.FileName); + System.Windows.Application.Current.Shutdown(); })); break; case PrintStatus_t.PRINT_BUSY: System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() => { - xaml_PrintProgress.Value = 100.0 * (double)(Information.Page - Information.PageStart) / (double)Information.NumPages; + m_printstatus.xaml_PrintProgress.Value = 100.0 * (double)(Information.Page - Information.PageStart) / (double)Information.NumPages; if (Information.Page == Information.NumPages) { - xaml_PrintGrid.Visibility = System.Windows.Visibility.Collapsed; + m_printstatus.xaml_PrintProgress.Visibility = System.Windows.Visibility.Collapsed; } })); break; diff --git a/demos/csharp/windows/ghostnet_wpf_example/MainRender.cs b/demos/csharp/windows/ghostnet_wpf_example/MainRender.cs index 016c86bb..98661f98 100644 --- a/demos/csharp/windows/ghostnet_wpf_example/MainRender.cs +++ b/demos/csharp/windows/ghostnet_wpf_example/MainRender.cs @@ -1,37 +1,42 @@ using System; using System.Windows.Media; -using System.Collections.Generic; using System.Windows.Media.Imaging; using System.Runtime.InteropServices; +using System.Windows.Controls; using GhostNET; namespace ghostnet_wpf_example { public partial class MainWindow { - bool m_busy_rendering; - int m_firstpage; - int m_lastpage; - - /* For PDF optimization */ + /* Filter so we get the first non-full res and the last + * full res */ private void PageRangeRender(int first_page, int last_page) { - bool render_pages = false; + if (m_viewer_state != ViewerState_t.DOC_OPEN) + return; + + int real_first_page = -1; + int real_last_page = -1; + for (int k = first_page; k <= last_page; k++) { - if (m_docPages[k].Content != Page_Content_t.FULL_RESOLUTION) + if (real_first_page == -1 && ((m_docPages[k].Content != Page_Content_t.FULL_RESOLUTION) || + (m_docPages[k].AA != m_aa))) { - render_pages = true; - break; + real_first_page = k; + } + if (m_docPages[k].Content != Page_Content_t.FULL_RESOLUTION || m_docPages[k].AA != m_aa) + { + real_last_page = k; } } - if (!render_pages) + + if (real_first_page == -1) return; - m_busy_rendering = true; - m_firstpage = first_page; - m_lastpage = last_page; - //m_ghostscript.gsDisplayDeviceRender(m_currfile, first_page + 1, last_page + 1, 1.0); + m_viewer_state = ViewerState_t.BUSY_RENDER; + m_ghostscript.gsDisplayDeviceRunFile(m_currfile, m_doczoom, m_aa, real_first_page + 1, real_last_page + 1); } /* Callback from ghostscript with the rendered image. */ @@ -51,15 +56,6 @@ namespace ghostnet_wpf_example image_data.zoom = zoom_in; m_images_rendered.Add(image_data); - /* Get the 1.0 page scalings */ - if (m_firstime) - { - pagesizes_t page_size = new pagesizes_t(); - page_size.size.X = width; - page_size.size.Y = height; - m_page_sizes.Add(page_size); - } - /* Dispatch progress bar update on UI thread */ System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, new Action(() => { @@ -71,65 +67,127 @@ namespace ghostnet_wpf_example /* Done rendering. Update the pages with the new raster information if needed */ private void RenderingDone() { - int page_index = m_firstpage - 1; - m_toppage_pos = new List(m_images_rendered.Count + 1); - int offset = 0; - for (int k = 0; k < m_images_rendered.Count; k++) { - DocPage doc_page = m_docPages[page_index + k]; + DocPage doc_page = m_docPages[m_images_rendered[k].page_num - 1]; if (doc_page.Content != Page_Content_t.FULL_RESOLUTION || - m_aa_change) + doc_page.AA != m_aa) { doc_page.Width = m_images_rendered[k].width; doc_page.Height = m_images_rendered[k].height; doc_page.Content = Page_Content_t.FULL_RESOLUTION; doc_page.Zoom = m_doczoom; + doc_page.AA = m_aa; doc_page.BitMap = BitmapSource.Create(doc_page.Width, doc_page.Height, 72, 72, PixelFormats.Bgr24, BitmapPalettes.Halftone256, m_images_rendered[k].bitmap, m_images_rendered[k].raster); } - m_toppage_pos.Add(offset + Constants.PAGE_VERT_MARGIN); - offset += doc_page.Height + Constants.PAGE_VERT_MARGIN; } xaml_ProgressGrid.Visibility = System.Windows.Visibility.Collapsed; xaml_RenderProgress.Value = 0; - m_aa_change = false; - m_firstime = false; - m_toppage_pos.Add(offset); - m_busy_rendering = false; m_images_rendered.Clear(); - m_file_open = true; - m_busy_render = false; - m_ghostscript.gsPageRenderedMain -= new ghostsharp.gsCallBackPageRenderedMain(gsPageRendered); + m_viewer_state = ViewerState_t.DOC_OPEN; } - /* Render all pages full resolution */ - private void RenderMainFirst() + private Tuple GetVisiblePages() + { + /* First child of list view */ + Decorator border = VisualTreeHelper.GetChild(xaml_PageList, 0) as Decorator; + + // Get scrollviewer + ScrollViewer scrollViewer = border.Child as ScrollViewer; + + double top_window = scrollViewer.VerticalOffset; + double bottom_window = top_window + scrollViewer.ViewportHeight; + int first_page = -1; + int last_page = -1; + + if (top_window > m_toppage_pos[m_numpages - 1]) + { + first_page = m_numpages - 1; + last_page = first_page; + } + else + { + for (int k = 0; k < (m_toppage_pos.Count - 1); k++) + { + if (top_window <= m_toppage_pos[k + 1] && bottom_window >= m_toppage_pos[k]) + { + if (first_page == -1) + { + first_page = k; + last_page = k; + } + else + { + last_page = k; + break; + } + } + else + { + if (first_page != -1) + { + last_page = first_page; + break; + } + } + } + } + + + return new Tuple(first_page, last_page); + } + + /* Render only visible pages. Used for single page formats as well + * as PDF (and ideally XPS) where the interpreter can interpret only + * specified pages */ + private void RenderMainRange() + { + if (m_viewer_state == ViewerState_t.OPENING) + { + m_doczoom = 1.0; + xaml_Zoomsize.Text = "100"; + m_ghostscript.gsPageRenderedMain += new ghostsharp.gsCallBackPageRenderedMain(gsPageRendered); + } + + m_viewer_state = ViewerState_t.BUSY_RENDER; + (int first_page, int last_page) = GetVisiblePages(); + m_ghostscript.gsDisplayDeviceRunFile(m_currfile, m_doczoom, m_aa, first_page + 1, last_page + 1); + } + + /* Render all pages full resolution. Used for single page files as + * well as documents like PostScript and PCL that are not page + * based indexed */ + private void RenderMainAll() { - m_firstpage = 1; - m_busy_render = true; xaml_RenderProgress.Value = 0; xaml_ProgressGrid.Visibility = System.Windows.Visibility.Visible; m_page_progress_count = 0; xaml_RenderProgressText.Text = "Rendering"; - if (m_firstime) + if (m_viewer_state == ViewerState_t.OPENING) { + m_doczoom = 1.0; xaml_Zoomsize.Text = "100"; + m_ghostscript.gsPageRenderedMain += new ghostsharp.gsCallBackPageRenderedMain(gsPageRendered); } - m_ghostscript.gsPageRenderedMain += new ghostsharp.gsCallBackPageRenderedMain(gsPageRendered); - m_ghostscript.gsDisplayDeviceRenderAll(m_currfile, m_doczoom, m_aa, GS_Task_t.DISPLAY_DEV_NON_PDF); + m_viewer_state = ViewerState_t.BUSY_RENDER; + m_ghostscript.gsDisplayDeviceRunFile(m_currfile, m_doczoom, m_aa, -1, -1); } - /* Render all, but only if not already busy, called via zoom or aa changes */ - private void RenderMainAll() + /* Called via zoom or aa changes */ + private void RenderMain() { - if (m_busy_render || !m_init_done) + if (m_viewer_state != ViewerState_t.DOC_OPEN) return; - RenderMainFirst(); + + if (m_doc_type_has_page_access) + RenderMainRange(); + else + RenderMainAll(); } } } diff --git a/demos/csharp/windows/ghostnet_wpf_example/MainThumbRendering.cs b/demos/csharp/windows/ghostnet_wpf_example/MainThumbRendering.cs index 5db50389..102bb764 100644 --- a/demos/csharp/windows/ghostnet_wpf_example/MainThumbRendering.cs +++ b/demos/csharp/windows/ghostnet_wpf_example/MainThumbRendering.cs @@ -18,13 +18,24 @@ namespace ghostnet_wpf_example DocPage doc_page = new DocPage(); doc_page.Content = Page_Content_t.THUMBNAIL; doc_page.Zoom = zoom_in; + doc_page.AA = m_aa; doc_page.BitMap = m_thumbnails[page_num - 1].BitMap; doc_page.Width = (int)(width / (Constants.SCALE_THUMB)); doc_page.Height = (int)(height / (Constants.SCALE_THUMB)); doc_page.PageNum = page_num; m_docPages.Add(doc_page); + + /* Set the page offsets. Used for determining which pages + * will be visible within viewport. */ m_toppage_pos.Add(offset + Constants.PAGE_VERT_MARGIN); - offset += doc_page.Height + Constants.PAGE_VERT_MARGIN; + offset += doc_page.Height + 2 * Constants.PAGE_VERT_MARGIN; + + /* Set page sizes for 1.0 scaling. This is used to quick + * rescale of pages prior to rendering at new zoom. */ + pagesizes_t page_size = new pagesizes_t(); + page_size.size.X = doc_page.Width; + page_size.size.Y = doc_page.Height; + m_page_sizes.Add(page_size); } /* Rendered all the thumbnail pages. Stick them in the appropriate lists */ @@ -58,7 +69,6 @@ namespace ghostnet_wpf_example m_ghostscript.gsPageRenderedMain -= new ghostsharp.gsCallBackPageRenderedMain(gsThumbRendered); - m_numpages = m_list_thumb.Count; if (m_numpages < 1) { @@ -67,13 +77,14 @@ namespace ghostnet_wpf_example } else { - m_init_done = true; xaml_TotalPages.Text = "/" + m_numpages; xaml_currPage.Text = m_currpage.ToString(); m_list_thumb.Clear(); - /* If non-pdf, kick off full page rendering */ - RenderMainFirst(); + if (m_doc_type_has_page_access) + RenderMainRange(); + else + RenderMainAll(); } } @@ -110,7 +121,7 @@ namespace ghostnet_wpf_example xaml_ProgressGrid.Visibility = System.Windows.Visibility.Visible; m_ghostscript.gsPageRenderedMain += new ghostsharp.gsCallBackPageRenderedMain(gsThumbRendered); - m_ghostscript.gsDisplayDeviceRenderAll(m_currfile, Constants.SCALE_THUMB, false, GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF); + m_ghostscript.gsDisplayDeviceRenderThumbs(m_currfile, Constants.SCALE_THUMB, false, GS_Task_t.DISPLAY_DEV_THUMBS); } } } diff --git a/demos/csharp/windows/ghostnet_wpf_example/MainWindow.xaml.cs b/demos/csharp/windows/ghostnet_wpf_example/MainWindow.xaml.cs index 7ac077c2..f4b103b8 100644 --- a/demos/csharp/windows/ghostnet_wpf_example/MainWindow.xaml.cs +++ b/demos/csharp/windows/ghostnet_wpf_example/MainWindow.xaml.cs @@ -9,6 +9,7 @@ using System.Diagnostics; using Microsoft.Win32; using GhostNET; using System.IO; +using System.Windows.Media; static class Constants { @@ -51,6 +52,7 @@ namespace ghostnet_wpf_example NOTSET, BLANK }; + public enum zoom_t { NO_ZOOM, @@ -64,9 +66,24 @@ namespace ghostnet_wpf_example PDF, PS, PCL, + PNG, + EPS, + JPG, + TIF, XPS } + public enum ViewerState_t + { + NO_FILE, + OPENING, + BUSY_RENDER, + DOC_OPEN, + DISTILLING, + PRINTING, + RESIZING + } + public struct idata_t { public int page_num; @@ -85,10 +102,9 @@ namespace ghostnet_wpf_example public partial class MainWindow : Window { - ghostsharp m_ghostscript; - bool m_file_open; doc_t m_document_type; + bool m_doc_type_has_page_access; String m_currfile; List m_tempfiles; String m_origfile; @@ -100,14 +116,11 @@ namespace ghostnet_wpf_example public List m_page_sizes; List m_list_thumb; List m_images_rendered; - bool m_init_done; - bool m_busy_render; - bool m_firstime; bool m_validZoom; bool m_aa; - bool m_aa_change; List m_toppage_pos; int m_page_progress_count; + ViewerState_t m_viewer_state; private static List m_pageType; @@ -132,6 +145,7 @@ namespace ghostnet_wpf_example m_ghostscript.gsUpdateMain += new ghostsharp.gsCallBackMain(gsProgress); m_ghostscript.gsIOUpdateMain += new ghostsharp.gsIOCallBackMain(gsIO); m_ghostscript.gsDLLProblemMain += new ghostsharp.gsDLLProblem(gsDLL); + m_ghostscript.DisplayDeviceOpen(); m_currpage = 0; m_gsoutput = new gsOutput(); @@ -141,30 +155,53 @@ namespace ghostnet_wpf_example m_docPages = new Pages(); m_pageType = new List(); m_page_sizes = new List(); - m_file_open = false; m_document_type = doc_t.UNKNOWN; m_doczoom = 1.0; - m_init_done = false; - m_busy_render = true; + m_viewer_state = ViewerState_t.NO_FILE; m_validZoom = true; - m_firstime = true; + m_doc_type_has_page_access = true; m_list_thumb = new List(); m_images_rendered = new List(); - m_busy_rendering = false; m_aa = true; - m_aa_change = false; xaml_PageList.AddHandler(Grid.DragOverEvent, new System.Windows.DragEventHandler(Grid_DragOver), true); xaml_PageList.AddHandler(Grid.DropEvent, new System.Windows.DragEventHandler(Grid_Drop), true); - /* For case of opening another file */ + + /* For case of opening another file, or launching a print process */ string[] arguments = Environment.GetCommandLineArgs(); - if (arguments.Length > 1) + if (arguments.Length == 3) { string filePath = arguments[1]; - ProcessFile(filePath); + string job = arguments[2]; + + if (String.Equals(job, "open")) + ProcessFile(filePath); + } + else if (arguments.Length == 5) + { + string filePath = arguments[1]; + string job = arguments[2]; + + try + { + m_currpage = Int32.Parse(arguments[3]); + m_numpages = Int32.Parse(arguments[4]); + } + catch (FormatException) + { + Console.WriteLine("Failure to parse print page info"); + Close(); + } + + /* Keep main window hidden if we are doing a print process */ + this.IsVisibleChanged += new System.Windows.DependencyPropertyChangedEventHandler(WindowVisible); + m_viewer_state = ViewerState_t.PRINTING; + Print(filePath); } + } + private void gsIO(String mess, int len) { m_gsoutput.Update(mess, len); @@ -198,8 +235,8 @@ namespace ghostnet_wpf_example { case GS_Task_t.CREATE_XPS: - xaml_DistillProgress.Value = 100; - xaml_DistillGrid.Visibility = System.Windows.Visibility.Collapsed; + m_printstatus.xaml_PrintProgress.Value = 100; + m_printstatus.xaml_PrintProgressGrid.Visibility = System.Windows.Visibility.Collapsed; break; case GS_Task_t.PS_DISTILL: @@ -210,11 +247,11 @@ namespace ghostnet_wpf_example case GS_Task_t.SAVE_RESULT: break; - case GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF: - case GS_Task_t.DISPLAY_DEV_THUMBS_PDF: + case GS_Task_t.DISPLAY_DEV_THUMBS: ThumbsDone(); break; + case GS_Task_t.DISPLAY_DEV_RUN_FILE: case GS_Task_t.DISPLAY_DEV_PDF: case GS_Task_t.DISPLAY_DEV_NON_PDF: RenderingDone(); @@ -251,7 +288,7 @@ namespace ghostnet_wpf_example switch (asyncInformation.Params.task) { case GS_Task_t.CREATE_XPS: - this.xaml_DistillProgress.Value = asyncInformation.Progress; + m_printstatus.xaml_PrintProgress.Value = asyncInformation.Progress; break; case GS_Task_t.PS_DISTILL: @@ -308,7 +345,6 @@ namespace ghostnet_wpf_example switch (gs_result.task) { case GS_Task_t.CREATE_XPS: - xaml_DistillGrid.Visibility = System.Windows.Visibility.Collapsed; /* Always do print all from xps conversion as it will do * the page range handling for us */ /* Add file to temp file list */ @@ -341,6 +377,7 @@ namespace ghostnet_wpf_example } tempfile.DeleteFile(); + m_viewer_state = ViewerState_t.NO_FILE; break; case GS_Task_t.SAVE_RESULT: @@ -357,8 +394,6 @@ namespace ghostnet_wpf_example private void CleanUp() { - m_init_done = false; - /* Collapse this stuff since it is going to be released */ xaml_ThumbGrid.Visibility = System.Windows.Visibility.Collapsed; @@ -381,23 +416,29 @@ namespace ghostnet_wpf_example m_currfile = null; m_origfile = null; m_numpages = -1; - m_file_open = false; - m_firstime = true; + m_doc_type_has_page_access = true; m_document_type = doc_t.UNKNOWN; m_origfile = null; CleanUpTempFiles(); - m_file_open = false; - m_busy_render = true; xaml_TotalPages.Text = "/ 0"; xaml_currPage.Text = "0"; CloseExtraWindows(false); + m_ghostscript.gsPageRenderedMain -= new ghostsharp.gsCallBackPageRenderedMain(gsPageRendered); + m_ghostscript.DisplayDeviceClose(); + m_ghostscript.DisplayDeviceOpen(); + m_viewer_state = ViewerState_t.NO_FILE; + + /* Set vertical scroll to top position */ + Decorator border = VisualTreeHelper.GetChild(xaml_PageList, 0) as Decorator; + ScrollViewer scrollViewer = border.Child as ScrollViewer; + scrollViewer.ScrollToVerticalOffset(0); return; } private void CloseCommand(object sender, ExecutedRoutedEventArgs e) { - if (m_init_done) + if (m_viewer_state == ViewerState_t.DOC_OPEN) CleanUp(); } @@ -420,7 +461,7 @@ namespace ghostnet_wpf_example return; OpenFileDialog dlg = new OpenFileDialog(); - dlg.Filter = "Document Files(*.ps;*.eps;*.pdf)|*.ps;*.eps;*.pdf;|All files (*.*)|*.*"; + dlg.Filter = "Document Files(*.ps;*.eps;*.pdf;*.bin;*.xps;*.oxps;*.jpg;*.png;*.tif|*.ps;*.eps;*.pdf;*.bin;*.xps;*.oxps;*.jpg;*.png;*.tif|All files (*.*)|*.*"; dlg.FilterIndex = 1; if (dlg.ShowDialog() == true) ProcessFile(dlg.FileName); @@ -435,7 +476,7 @@ namespace ghostnet_wpf_example ShowMessage(NotifyType_t.MESS_STATUS, "File not found!"); return; } - if (m_file_open) + if (m_viewer_state == ViewerState_t.DOC_OPEN) { /* In this case, we want to go ahead and launch a new process * handing it the filename */ @@ -443,7 +484,8 @@ namespace ghostnet_wpf_example string path = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; try { - Process.Start(path, FileName); + string Arguments = FileName + " open"; + Process.Start(path, Arguments); } catch (InvalidOperationException) { @@ -455,6 +497,10 @@ namespace ghostnet_wpf_example } return; } + else if (m_viewer_state != ViewerState_t.NO_FILE) + return; + + m_viewer_state = ViewerState_t.OPENING; /* If we have a ps or eps file then launch the distiller first * and then we will get a temp pdf file which we will open. This is done @@ -470,7 +516,7 @@ namespace ghostnet_wpf_example m_document_type = doc_t.PS; break; case ".EPS": - m_document_type = doc_t.PS; + m_document_type = doc_t.EPS; break; case ".PDF": m_document_type = doc_t.PDF; @@ -478,24 +524,40 @@ namespace ghostnet_wpf_example case ".XPS": m_document_type = doc_t.XPS; break; + case ".OXPS": + m_document_type = doc_t.XPS; + break; case ".BIN": m_document_type = doc_t.PCL; break; + case ".PNG": + m_document_type = doc_t.PNG; + break; + case ".JPG": + m_document_type = doc_t.JPG; + break; + case ".TIF": + m_document_type = doc_t.TIF; + break; default: { m_document_type = doc_t.UNKNOWN; ShowMessage(NotifyType_t.MESS_STATUS, "Unknown File Type"); + m_viewer_state = ViewerState_t.NO_FILE; return; } } - if (extension.ToUpper() != ".PDF") + if (m_document_type == doc_t.PCL || + m_document_type == doc_t.XPS || + m_document_type == doc_t.PS) { - MessageBoxResult result = MessageBox.Show("Would you like to Distill this file?", "ghostnet", MessageBoxButton.YesNoCancel); + MessageBoxResult result = MessageBox.Show("Would you like to distill this file?", "ghostnet", MessageBoxButton.YesNoCancel); switch (result) { case MessageBoxResult.Yes: xaml_DistillProgress.Value = 0; + m_viewer_state = ViewerState_t.DISTILLING; if (m_ghostscript.DistillPS(FileName, Constants.DEFAULT_GS_RES) == gsStatus.GS_BUSY) { ShowMessage(NotifyType_t.MESS_STATUS, "GS currently busy"); @@ -507,21 +569,23 @@ namespace ghostnet_wpf_example xaml_DistillGrid.Visibility = System.Windows.Visibility.Visible; return; case MessageBoxResult.No: + //m_doc_type_has_page_access = false; break; case MessageBoxResult.Cancel: + m_viewer_state = ViewerState_t.NO_FILE; return; } } m_currfile = FileName; - //m_numpages = m_ghostscript.GetPageCount(m_currfile); RenderThumbs(); return; - } + private void CancelDistillClick(object sender, RoutedEventArgs e) { } + private void DeleteTempFile(String file) { for (int k = 0; k < m_tempfiles.Count; k++) @@ -557,6 +621,7 @@ namespace ghostnet_wpf_example } m_tempfiles.Clear(); } + private void OnAboutClick(object sender, RoutedEventArgs e) { About about = new About(this); @@ -624,7 +689,7 @@ namespace ghostnet_wpf_example { e.Handled = true; - if (!m_init_done || m_busy_rendering || m_toppage_pos == null) + if (m_viewer_state != ViewerState_t.DOC_OPEN) return; /* Find the pages that are visible. */ @@ -640,7 +705,7 @@ namespace ghostnet_wpf_example } else { - for (int k = 0; k < (m_toppage_pos.Count() - 1); k++) + for (int k = 0; k < (m_toppage_pos.Count - 1); k++) { if (top_window <= m_toppage_pos[k + 1] && bottom_window >= m_toppage_pos[k]) { @@ -666,13 +731,9 @@ namespace ghostnet_wpf_example m_currpage = first_page; xaml_currPage.Text = (m_currpage + 1).ToString(); - /* Only PDF does this page sensitive approach */ - if (m_document_type != doc_t.PDF) - return; + if (m_doc_type_has_page_access) + PageRangeRender(first_page, last_page); - /* Disable for now. All do full doc rendering. NB implement - * for XPS and PDF which allow direct page access */ - //PageRangeRender(first_page, last_page); return; } private void Grid_DragOver(object sender, System.Windows.DragEventArgs e) @@ -687,6 +748,15 @@ namespace ghostnet_wpf_example } e.Handled = false; } + + /* Keep main window hidden if we are doing a print process */ + public void WindowVisible(object sender, DependencyPropertyChangedEventArgs e) + { + if (m_viewer_state == ViewerState_t.PRINTING) + { + this.Visibility = Visibility.Hidden; + } + } private void Grid_Drop(object sender, System.Windows.DragEventArgs e) { @@ -725,15 +795,13 @@ namespace ghostnet_wpf_example private void AA_uncheck(object sender, RoutedEventArgs e) { m_aa = false; - m_aa_change = true; - RenderMainAll(); + RenderMain(); } private void AA_check(object sender, RoutedEventArgs e) { m_aa = true; - m_aa_change = true; - RenderMainAll(); + RenderMain(); } } } diff --git a/demos/csharp/windows/ghostnet_wpf_example/MainZoom.cs b/demos/csharp/windows/ghostnet_wpf_example/MainZoom.cs index 0502e6c7..08e270e2 100644 --- a/demos/csharp/windows/ghostnet_wpf_example/MainZoom.cs +++ b/demos/csharp/windows/ghostnet_wpf_example/MainZoom.cs @@ -3,6 +3,7 @@ using System.Windows; using System.Windows.Controls; using System.Text.RegularExpressions; using System.Windows.Input; +using System.Windows.Media; namespace ghostnet_wpf_example { @@ -51,7 +52,7 @@ namespace ghostnet_wpf_example private bool ZoomDisabled() { - if (!m_init_done || m_busy_render) + if (m_viewer_state != ViewerState_t.DOC_OPEN) return true; else return false; @@ -61,26 +62,28 @@ namespace ghostnet_wpf_example { if (ZoomDisabled()) return; - if (!m_init_done || m_doczoom <= Constants.ZOOM_MIN) + + if (m_doczoom <= Constants.ZOOM_MIN) return; m_doczoom = GetNextZoom(m_doczoom, -1); xaml_Zoomsize.Text = Math.Round(m_doczoom * 100.0).ToString(); ResizePages(); - RenderMainAll(); + RenderMain(); } private void ZoomIn(object sender, RoutedEventArgs e) { if (ZoomDisabled()) return; - if (!m_init_done || m_doczoom >= Constants.ZOOM_MAX) + + if (m_doczoom >= Constants.ZOOM_MAX) return; m_doczoom = GetNextZoom(m_doczoom, 1); xaml_Zoomsize.Text = Math.Round(m_doczoom * 100.0).ToString(); ResizePages(); - RenderMainAll(); + RenderMain(); } private void ZoomTextChanged(object sender, TextChangedEventArgs e) @@ -114,6 +117,9 @@ namespace ghostnet_wpf_example if (e.Key == Key.Return) { + if (ZoomDisabled()) + return; + e.Handled = true; var desired_zoom = xaml_Zoomsize.Text; try @@ -126,7 +132,7 @@ namespace ghostnet_wpf_example m_doczoom = zoom; ResizePages(); - RenderMainAll(); + RenderMain(); xaml_Zoomsize.Text = Math.Round(zoom * 100.0).ToString(); } catch (FormatException) @@ -147,14 +153,22 @@ namespace ghostnet_wpf_example if (m_page_sizes.Count == 0) return; + int offset = 0; + + /* Get scroll relative location */ + Decorator border = VisualTreeHelper.GetChild(xaml_PageList, 0) as Decorator; + ScrollViewer scrollViewer = border.Child as ScrollViewer; + double top_window = scrollViewer.VerticalOffset; + double x_size = scrollViewer.ExtentHeight; + + m_viewer_state = ViewerState_t.RESIZING; for (int k = 0; k < m_numpages; k++) { var doc_page = m_docPages[k]; - if (doc_page.Zoom == m_doczoom && - doc_page.Width == (int)(m_doczoom * m_page_sizes[k].size.X) && - doc_page.Height == (int)(m_doczoom * m_page_sizes[k].size.Y)) - continue; - else + + if (doc_page.Zoom != m_doczoom || + doc_page.Width != (int)(m_doczoom * m_page_sizes[k].size.X) || + doc_page.Height != (int)(m_doczoom * m_page_sizes[k].size.Y)) { /* Resize it now */ doc_page.Width = (int)(m_doczoom * m_page_sizes[k].size.X); @@ -162,7 +176,18 @@ namespace ghostnet_wpf_example doc_page.Zoom = m_doczoom; doc_page.Content= Page_Content_t.OLD_RESOLUTION; } + + /* Adjust page top locations */ + m_toppage_pos[k] = offset + Constants.PAGE_VERT_MARGIN; + offset += doc_page.Height + 2 * Constants.PAGE_VERT_MARGIN; } + + m_toppage_pos[m_numpages] = offset; + m_viewer_state = ViewerState_t.DOC_OPEN; + + /* Reset scroll location */ + /* This could probably be improved a bit. We should also do horizontal position */ + scrollViewer.ScrollToVerticalOffset((top_window / x_size) * (double)offset); } } } \ No newline at end of file diff --git a/demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml b/demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml new file mode 100644 index 00000000..7a40d169 --- /dev/null +++ b/demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + Creating XPS + + diff --git a/demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml.cs b/demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml.cs new file mode 100644 index 00000000..41480471 --- /dev/null +++ b/demos/csharp/windows/ghostnet_wpf_example/PrintStatus.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace ghostnet_wpf_example +{ + /// + /// Interaction logic for PrintStatus.xaml + /// + public partial class PrintStatus : Window + { + public PrintStatus() + { + InitializeComponent(); + } + } +} diff --git a/demos/csharp/windows/ghostnet_wpf_example/ghostnet_simple_viewer.csproj b/demos/csharp/windows/ghostnet_wpf_example/ghostnet_simple_viewer.csproj index 895bff82..a7daf8f6 100644 --- a/demos/csharp/windows/ghostnet_wpf_example/ghostnet_simple_viewer.csproj +++ b/demos/csharp/windows/ghostnet_wpf_example/ghostnet_simple_viewer.csproj @@ -14,6 +14,21 @@ 4 true true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true AnyCPU @@ -37,7 +52,7 @@ true bin\x64\Debug\ - TRACE;DEBUG;WIN64;GHOSTPDL;WPF + TRACE;DEBUG;WIN64;GHOSTPDL full x64 7.3 @@ -57,7 +72,7 @@ true bin\x86\Debug\ - DEBUG;TRACE + TRACE;DEBUG;GHOSTPDL full x86 7.3 @@ -74,6 +89,9 @@ prompt MinimumRecommendedRules.ruleset + + Always + @@ -119,6 +137,9 @@ PrintControl.xaml + + PrintStatus.xaml + @@ -145,6 +166,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + @@ -172,6 +197,18 @@ + + + False + Microsoft .NET Framework 4.7.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + if $(ConfigurationName) == Debug ( diff --git a/demos/java/gsjava/.classpath b/demos/java/gsjava/.classpath new file mode 100644 index 00000000..0cbf9cda --- /dev/null +++ b/demos/java/gsjava/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/demos/java/gsjava/.project b/demos/java/gsjava/.project new file mode 100644 index 00000000..45e10ae9 --- /dev/null +++ b/demos/java/gsjava/.project @@ -0,0 +1,17 @@ + + + gsjava + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/demos/java/gsjava/README.txt b/demos/java/gsjava/README.txt new file mode 100644 index 00000000..07c55675 --- /dev/null +++ b/demos/java/gsjava/README.txt @@ -0,0 +1,149 @@ +Required libraries for this library: +gpdldll64.dll +gs_jni.dll + +Java Library: + +This library contains direct bindings to Ghostscript as +well as several utility methods to make using the +Ghostscript calls easier. + +The direct Ghostscript calls are found in +com.artifex.gsjava.GSAPI and are named in the same way +in which they are documented on https://www.ghostscript.com/doc/current/API.htm + +The com.artifex.gsjava.callbacks package contains +interfaces which store interfaces and abstract classes +used to implement Ghostscript callbacks in Java. These +can be passed to Ghostscript through the GSAPI class. + +The com.artifex.gsjava.util package contains several +classes to assist in passing parameters and handling +native values. The Reference and ByteArrayReference are +the only classes which need to be used, however the others +are avaliable if needed. The Reference class acts as +a pointer parameter in a C function. An example use of this +is in gsapi_new_instance which takes a Reference as +a parameter. Calling the method would place the new +Ghoscript instance in the Reference's value field. + +The com.artifex.gsjava.GSInstance is a +utility class. The GSInstance class stores an instance +of Ghostscript and a client handle. The methods in this +class are named the same in which they are documented without +the need to pass the "instance" parameter through. + +The com.artifex.gsjava.devices package contains several +classes representing Ghoscript devices. Using the classes +in this package is the greatest amount of separation from +using the raw Ghoscript calls and it requires no direct +calls through the GSAPI class. All device classes in this +package are extensions of Device which provides a way +of setting up a Ghoscript device and setting parameters. +Subclasses have utility methods to set individual parameters +through method calls instead of using a String and parameter +type to specify the parameter name and type, respectively. + +Example code segment to set up an instance of Ghoscript: + +import com.artifex.gsjava.*; +import com.artifex.gsjava.util.*; + +public static void main(String[] args) { + // Stores a reference to the Ghoscript instance + Reference instanceReference = new Reference<>(); + + // Creates a new Ghoscript instance with a NULL caller handle, + // placing the instance into instanceReference + int code = GSAPI.gsapi_new_instance(instanceReference, GSAPI.GS_NULL); + + if (code != GSAPI.GS_ERROR_OK) { + // An error has occured. + return; + } + + // Returns the value the instanceReference references. + // This value is equivalent to a void * and has the same + // size in bytes. + long instance = instanceReference.getValue(); + + // Deletes the Ghoscript instance + GSAPI.gsapi_delete_instance(instance); +} + +C++ Library: + +This library builds to gs_jni.dll and uses the +Java Native Interface (JNI) to bind the functions in +the GSAPI class to Ghoscript as well as handling callbacks, +exceptions, and references. + +The bindings in GSAPI are in the header com_artifex_gsjava_GSJAVA.h +and the implementations are in com_artifex_gsjava_GSJAVA.cpp. + +Utility methods for throwing exceptions, setting fields, calling +Java methods, and using the Reference class are declared +in jni_util.h. + +Example method explaining the implementation for +gsapi_run_string_begin: + + +/* JNIEnv *env - Provided the JNI. Allows interfacing into calling Java methods, + * setting Java fields, etc. Different threads have different JNIEnv objects. + * + * jclass - Provided by the JNI. It represents the class calling this method. + * + * jlong instance - Instance to be passed to gsapi_run_string_begin + * + * jint userErrors - User errors to be passed to gsapi_run_string_begin + * + * jobject pExitCode - A Reference object. This is always the case as the Java + * code will not allow anything else to be passed. The value which Ghostscript returns + * in the pExitCode parameter will be placed into here. + */ +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1begin + (JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode) +{ + // Declares the exitCode parameter which will be passed as a pointer + // to gsapi_run_string_begin + int exitCode; + + // Different threads have different JNIEnv objects, so each time a JNI method + // is called, this must be set so the Java callback methods can be called. + callbacks::setJNIEnv(env); + + // Calls the Ghoscript call gsapi_run_string_begin + int code = gsapi_run_string_begin((void *)instance, userErrors, &exitCode); + + // If the reference is not NULL, set the value of the reference to the exitCode returned + // from Ghoscript. It must be converted to the wrapper type java.lang.Integer as Java does not support + // primitive generic arguments (i.e. int, float, char, etc.) + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + + // Return the error code returned by Ghostscript + return code; +} + +Viewer: + +There is an eclipse project containing a viewer using the +Java Ghostscript bindings in gsjava. The eclipse project is +set up such that the gsjava eclipse project must be built +to a jar file and used in the gsviewer eclipse project. + +The viewer is designed to load PDF documents, but can also +load other files like PostScript files and distill them into +a PDF document to be opened. + +When the document is first loaded, every page is rendered at +a low resolution. These will be displayed as thumbnails on the +left side. All loadingg is done in the com.artifex.gsjava.Document +class. As the user changes the position of the viewport, the +viewer will dynamically load high resolution images based on +what page the user is viewing. This is done in the +com.artifex.gsviewer.ViewerController.SmartLoader class. This +also handles rendering zoomed images if necessary. Only pages +which need to be loaded at a high resolution are loaded, and +zoomed pages are unloaded when no longer necessary to save memory. \ No newline at end of file diff --git a/demos/java/gsjava/src/com/artifex/gsjava/GSAPI.java b/demos/java/gsjava/src/com/artifex/gsjava/GSAPI.java new file mode 100644 index 00000000..f275e417 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/GSAPI.java @@ -0,0 +1,284 @@ +package com.artifex.gsjava; + +import java.util.List; + +import com.artifex.gsjava.callbacks.DisplayCallback; +import com.artifex.gsjava.callbacks.ICalloutFunction; +import com.artifex.gsjava.callbacks.IPollFunction; +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; +import com.artifex.gsjava.util.Reference; +import com.artifex.gsjava.util.StringUtil; + +/** + * Class which contains native bindings to Ghostscript via the JNI. + * + * @author Ethan Vrhel + * + */ +public class GSAPI { + + static { + registerLibraries(); + } + + /** + * Registers the needed native libraries. + */ + private static void registerLibraries() { + System.loadLibrary("gs_jni"); + } + + /** + * NULL + */ + public static final long GS_NULL = 0L; + + /** + * Error codes + */ + public static final int GS_ERROR_OK = 0, + GS_ERROR_UNKNOWNERROR = -1, + GS_ERROR_DICTFULL = -2, + GS_ERROR_DICTSTACKOVERFLOW = -3, + GS_ERROR_DICTSTACKUNDERFLOW = -4, + GS_ERROR_EXECSTACKOVERFLOW = -5, + GS_ERROR_INTERRUPT = -6, + GS_ERROR_INVALIDACCESS = -7, + GS_ERROR_INVALIDEXIT = -8, + GS_ERROR_INVALIDFILEACCESS = -9, + GS_ERROR_INVALIDFONT = -10, + GS_ERROR_INVALIDRESTORE = -11, + GS_ERROR_IOERROR = -12, + GS_ERROR_LIMITCHECK = -13, + GS_ERROR_NOCURRENTPOINT = -14, + GS_ERROR_RANGECHECK = -15, + GS_ERROR_STACKOVERFLOW = -16, + GS_ERROR_STACKUNDERFLOW = -17, + GS_ERROR_SYNTAXERROR = -18, + GS_ERROR_TIMEOUT = -19, + GS_ERROR_TYPECHECK = -20, + GS_ERROR_UNDEFINED = -21, + GS_ERROR_UNDEFINEDFILENAME = -22, + GS_ERROR_UNDEFINEDRESULT = -23, + GS_ERROR_UNMATCHEDMARK = -24, + GS_ERROR_VMERROR = -25; + + /** + * Error codes + */ + public static final int GS_ERROR_CONFIGURATION_ERROR = -26, + GS_ERROR_UNDEFINEDRESOURCE = -27, + GS_ERROR_UNREGISTERED = -28, + GS_ERROR_INVALIDCONTEXT = -29, + GS_ERROR_INVALID = -30; + + public static final int GS_COLORS_NATIVE = (1 << 0), + GS_COLORS_GRAY = (1 << 1), + GS_COLORS_RGB = (1 << 2), + GS_COLORS_CMYK = (1 << 3), + GS_DISPLAY_COLORS_SEPARATION = (1 << 19); + + public static final long GS_DISPLAY_COLORS_MASK = 0x8000fL; + + public static final int GS_DISPLAY_ALPHA_NONE = (0 << 4), + GS_DISPLAY_ALPHA_FIRST = (1 << 4), + GS_DISPLAY_ALPHA_LAST = (1 << 5), + GS_DISPLAY_UNUSED_FIRST = (1 << 6), + GS_DISPLAY_UNUSED_LAST = (1 << 7); + + public static final long GS_DISPLAY_ALPHA_MASK = 0x00f0L; + + public static final int GS_DISPLAY_DEPTH_1 = (1 << 8), + GS_DISPLAY_DEPTH_2 = (1 << 9), + GS_DISPLAY_DEPTH_4 = (1 << 10), + GS_DISPLAY_DEPTH_8 = (1 << 11), + GS_DISPLAY_DEPTH_12 = (1 << 12), + GS_DISPLAY_DEPTH_16 = (1 << 3); + + public static final long GS_DISPLAY_DEPTH_MASK = 0xff00L; + + public static final int GS_DISPLAY_BIGENDIAN = (0 << 16), + GS_DISPLAY_LITTLEENDIAN = (1 << 16); + + public static final long GS_DISPLAY_ENDIAN_MASK = 0x00010000L; + + public static final int GS_DISPLAY_TOPFIRST = (0 << 17), + GS_DISPLAY_BOTTOMFIRST = (1 << 17); + + public static final long GS_DISPLAY_FIRSTROW_MASK = 0x00020000L; + + public static final int GS_SPT_INVALID = -1, + GS_SPT_NULL = 0, + GS_SPT_BOOL = 1, + GS_SPT_INT = 2, + GS_SPT_FLOAT = 3, + GS_SPT_NAME = 4, + GS_SPT_STRING = 5, + GS_SPT_LONG = 6, + GS_SPT_I64 = 7, + GS_SPT_SIZE_T = 8, + GS_SPT_PARSED = 9, + GS_SPT_MORE_TO_COME = 1 << 31; + + /** + * Class used to store version information about Ghostscript. + * + * @author Ethan Vrhel + * + */ + public static class Revision { + public volatile byte[] product; + public volatile byte[] copyright; + public volatile long revision; + public volatile long revisionDate; + + public Revision() { + this.product = null; + this.copyright = null; + this.revision = 0L; + this.revisionDate = 0L; + } + + /** + * Returns the product information as a String. + * + * @return The product information. + */ + public String getProduct() { + return new String(product); + } + + /** + * Returns the copyright information as a String. + * + * @return The copyright information. + */ + public String getCopyright() { + return new String(copyright); + } + } + + // Don't let this class be instantiated + private GSAPI() { } + + public static native int gsapi_revision(GSAPI.Revision revision, int len); + + public static native int gsapi_new_instance(Reference instance, long callerHandle); + + public static native void gsapi_delete_instance(long instance); + + public static native int gsapi_set_stdio_with_handle(long instance, IStdInFunction stdin, + IStdOutFunction stdout, IStdErrFunction stderr, long callerHandle); + + public static native int gsapi_set_stdio(long instance, IStdInFunction stdin, IStdOutFunction stdout, + IStdErrFunction stderr); + + public static native int gsapi_set_poll_with_handle(long instance, IPollFunction pollfun, long callerHandle); + + public static native int gsapi_set_poll(long instance, IPollFunction pollfun); + + public static native int gsapi_set_display_callback(long instance, DisplayCallback displayCallback); + + public static native int gsapi_register_callout(long instance, ICalloutFunction callout, long calloutHandle); + + public static native void gsapi_deregister_callout(long instance, ICalloutFunction callout, long calloutHandle); + + public static native int gsapi_set_arg_encoding(long instance, int encoding); + + public static native int gsapi_set_default_device_list(long instance, byte[] list, int listlen); + + public static native int gsapi_get_default_device_list(long instance, Reference list, Reference listlen); + + public static native int gsapi_init_with_args(long instance, int argc, byte[][] argv); + + public static native int gsapi_run_string_begin(long instance, int userErrors, Reference pExitCode); + + public static native int gsapi_run_string_continue(long instance, byte[] str, int length, int userErrors, + Reference pExitCode); + + public static native int gsapi_run_string_end(long instance, int userErrors, Reference pExitCode); + + public static native int gsapi_run_string_with_length(long instance, byte[] str, int length, int userErrors, + Reference pExitCode); + + public static native int gsapi_run_string(long instance, byte[] str, int userErrors, Reference pExitCode); + + public static native int gsapi_run_file(long instance, byte[] fileName, int userErrors, Reference pExitCode); + + public static native int gsapi_exit(long instance); + + public static native int gsapi_set_param(long instance, byte[] param, Object value, int paramType); + + public static native int gsapi_get_param(long instance, byte[] param, long value, int paramType); + + public static native int gsapi_get_param_once(long instance, byte[] param, Reference value, int paramType); + + public static native int gsapi_enumerate_params(long instance, Reference iter, Reference key, Reference paramType); + + public static native int gsapi_add_control_path(long instance, int type, byte[] path); + + public static native int gsapi_remove_control_path(long instance, int type, byte[] path); + + public static native void gsapi_purge_control_paths(long instance, int type); + + public static native void gsapi_activate_path_control(long instance, boolean enable); + + public static native boolean gsapi_is_path_control_active(long instance); + + // Utility methods to make calling some native methods easier + + public static int gsapi_init_with_args(long instance, String[] argv) { + return gsapi_init_with_args(instance, argv.length, StringUtil.to2DByteArray(argv)); + } + + public static int gsapi_init_with_args(long instance, List argv) { + return gsapi_init_with_args(instance, argv.toArray(new String[argv.size()])); + } + + public static int gsapi_run_string_continue(long instance, String str, int length, int userErrors, + Reference pExitCode) { + return gsapi_run_string_continue(instance, StringUtil.toNullTerminatedByteArray(str.substring(0, length)), + length, userErrors, pExitCode); + } + + public static int gsapi_run_string_with_length(long instance, String str, int length, int userErrors, + Reference pExitCode) { + return gsapi_run_string_with_length(instance, StringUtil.toNullTerminatedByteArray(str.substring(0, length)), + length, userErrors, pExitCode); + } + + public static int gsapi_run_string(long instance, String str, int userErrors, Reference pExitCode) { + return gsapi_run_string(instance, StringUtil.toNullTerminatedByteArray(str), userErrors, pExitCode); + } + + public static int gsapi_run_file(long instance, String fileName, int userErrors, Reference pExitCode) { + return gsapi_run_file(instance, StringUtil.toNullTerminatedByteArray(fileName), userErrors, pExitCode); + } + + public static int gsapi_set_param(long instnace, String param, String value, int paramType) { + return gsapi_set_param(instnace, StringUtil.toNullTerminatedByteArray(param), + StringUtil.toNullTerminatedByteArray(value), paramType); + } + + public static int gsapi_set_param(long instnace, String param, Object value, int paramType) { + return gsapi_set_param(instnace, StringUtil.toNullTerminatedByteArray(param), value, paramType); + } + + public static int gsapi_get_param(long instance, String param, long value, int paramType) { + return gsapi_get_param(instance, StringUtil.toNullTerminatedByteArray(param), value, paramType); + } + + public static int gsapi_get_param_once(long instance, String param, Reference value, int paramType) { + return gsapi_get_param_once(instance, StringUtil.toNullTerminatedByteArray(param), value, paramType); + } + + public static int gsapi_add_control_path(long instance, int type, String path) { + return gsapi_add_control_path(instance, type, StringUtil.toNullTerminatedByteArray(path)); + } + + public static int gsapi_remove_control_path(long instance, int type, String path) { + return gsapi_remove_control_path(instance, type, StringUtil.toNullTerminatedByteArray(path)); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/GSInstance.java b/demos/java/gsjava/src/com/artifex/gsjava/GSInstance.java new file mode 100644 index 00000000..e5e713c7 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/GSInstance.java @@ -0,0 +1,320 @@ +package com.artifex.gsjava; + +import static com.artifex.gsjava.GSAPI.*; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import com.artifex.gsjava.callbacks.DisplayCallback; +import com.artifex.gsjava.callbacks.ICalloutFunction; +import com.artifex.gsjava.callbacks.IPollFunction; +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; +import com.artifex.gsjava.util.ByteArrayReference; +import com.artifex.gsjava.util.Reference; + +/** + * Utility class to make Ghostscript calls easier by storing a + * Ghostscript instance and, optionally, a caller handle. + * + * @author Ethan Vrhel + * + */ +public class GSInstance implements Iterable> { + + public static class GSParam { + + public final String key; + public final V value; + + public GSParam(String key, V value) { + this.key = key; + this.value = value; + } + + public GSParam(V value) { + this(null, value); + } + + public boolean canConvertToString() { + return value instanceof String || value instanceof byte[]; + } + + public String stringValue() { + if (value instanceof String) + return (String)value; + else if (value instanceof byte[]) + return new String((byte[])value); + throw new IllegalStateException("Value cannot be converted to string"); + } + + @Override + public String toString() { + return key + " -> " + (canConvertToString() ? stringValue() : value); + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (o == this) + return true; + if (o instanceof GSParam) { + GSParam other = (GSParam)o; + return (key == null ? other.key == null : key.equals(other.key)) && + (value == null ? other.value == null : value.equals(other.value)); + } + return false; + } + + @Override + public int hashCode() { + return key.hashCode() + (value == null ? 0 : value.hashCode()); + } + } + + private static volatile boolean instanceExists = false; + + private long instance; + private long callerHandle; + + public GSInstance(long callerHandle) throws IllegalStateException { + if (instanceExists) + throw new IllegalStateException("An instance already exists"); + Reference ref = new Reference<>(); + int ret = gsapi_new_instance(ref, callerHandle); + if (ret != GS_ERROR_OK) + throw new IllegalStateException("Failed to create new instance: " + ret); + this.instance = ref.getValue(); + this.callerHandle = callerHandle; + instanceExists = true; + } + + public GSInstance() throws IllegalStateException { + this(GS_NULL); + } + + public void delete_instance() { + if (instance != GS_NULL) + gsapi_delete_instance(instance); + instance = GS_NULL; + instanceExists = false; + } + + public int set_stdio(IStdInFunction stdin, IStdOutFunction stdout, IStdErrFunction stderr) { + return gsapi_set_stdio_with_handle(instance, stdin, stdout, stderr, callerHandle); + } + + public int set_poll(IPollFunction pollfun) { + return gsapi_set_poll_with_handle(instance, pollfun, callerHandle); + } + + public int set_display_callback(DisplayCallback displaycallback) { + return gsapi_set_display_callback(instance, displaycallback); + } + + public int register_callout(ICalloutFunction callout) { + return gsapi_register_callout(instance, callout, callerHandle); + } + + public void deregister_callout(ICalloutFunction callout) { + gsapi_deregister_callout(instance, callout, callerHandle); + } + + public int set_arg_encoding(int encoding) { + return gsapi_set_arg_encoding(instance, encoding); + } + + public int set_default_device_list(byte[] list, int listlen) { + return gsapi_set_default_device_list(instance, list, listlen); + } + + public int get_default_device_list(Reference list, Reference listlen) { + return gsapi_get_default_device_list(instance, list, listlen); + } + + public int init_with_args(int argc, byte[][] argv) { + return gsapi_init_with_args(instance, argc, argv); + } + + public int init_with_args(String[] argv) { + return gsapi_init_with_args(instance, argv); + } + + public int init_with_args(List argv) { + return gsapi_init_with_args(instance, argv); + } + + public int run_string_begin(int userErrors, Reference pExitCode) { + return gsapi_run_string_begin(instance, userErrors, pExitCode); + } + + public int run_string_continue(byte[] str, int length, int userErrors, Reference pExitCode) { + return gsapi_run_string_continue(instance, str, length, userErrors, pExitCode); + } + + public int run_string_continue(String str, int length, int userErrors, Reference pExitCode) { + return gsapi_run_string_continue(instance, str, length, userErrors, pExitCode); + } + + public int run_string(byte[] str, int userErrors, Reference pExitCode) { + return gsapi_run_string(instance, str, userErrors, pExitCode); + } + + public int run_string(String str, int userErrors, Reference pExitCode) { + return gsapi_run_string(instance, str, userErrors, pExitCode); + } + + public int run_file(byte[] fileName, int userErrors, Reference pExitCode) { + return gsapi_run_file(instance, fileName, userErrors, pExitCode); + } + + public int run_file(String filename, int userErrors, Reference pExitCode) { + return gsapi_run_file(instance, filename, userErrors, pExitCode); + } + + public int exit() { + return gsapi_exit(instance); + } + + public int set_param(byte[] param, Object value, int paramType) { + return gsapi_set_param(instance, param, value, paramType); + } + + public int set_param(String param, String value, int paramType) { + return gsapi_set_param(instance, param, value, paramType); + } + + public int set_param(String param, Object value, int paramType) { + return gsapi_set_param(instance, param, value, paramType); + } + + public int get_param(byte[] param, long value, int paramType) { + return gsapi_get_param(instance, param, value, paramType); + } + + public int get_param(String param, long value, int paramType) { + return gsapi_get_param(instance, param, value, paramType); + } + + public int get_param_once(byte[] param, Reference value, int paramType) { + return gsapi_get_param_once(instance, param, value, paramType); + } + + public int get_param_once(String param, Reference value, int paramType) { + return gsapi_get_param_once(instance, param, value, paramType); + } + + public int enumerate_params(Reference iter, Reference key, Reference paramType) { + return gsapi_enumerate_params(instance, iter, key, paramType); + } + + public int add_control_path(int type, byte[] path) { + return gsapi_add_control_path(instance, type, path); + } + + public int add_control_path(int type, String path) { + return gsapi_add_control_path(instance, type, path); + } + + public int remove_control_path(int type, byte[] path) { + return gsapi_remove_control_path(instance, type, path); + } + + public int remove_control_path(int type, String path) { + return gsapi_remove_control_path(instance, type, path); + } + + public void purge_control_paths(int type) { + gsapi_purge_control_paths(instance, type); + } + + public void activate_path_control(boolean enable) { + gsapi_activate_path_control(instance, enable); + } + + public boolean is_path_control_active() { + return gsapi_is_path_control_active(instance); + } + + public GSParam[] getParamArray() { + List> params = new LinkedList<>(); + for (GSParam param : this) { + params.add(param); + } + return params.toArray(new GSParam[params.size()]); + } + + @Override + public void finalize() { + if (instance != GS_NULL) { + exit(); + delete_instance(); + } + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (o == this) + return true; + if (o instanceof GSInstance) { + GSInstance g = (GSInstance)o; + return g.instance == instance && g.callerHandle == callerHandle; + } + return false; + } + + @Override + public String toString() { + return "GSInstance[instance=0x" + Long.toHexString(instance) + "]"; + } + + @Override + public Iterator> iterator() { + return new ParamIterator(); + } + + private class ParamIterator implements Iterator> { + + private Reference iterator; + private ByteArrayReference key; + private Reference valueType; + private Reference value; + + private int returnCode; + + private ParamIterator() { + iterator = new Reference<>(0L); + key = new ByteArrayReference(); + valueType = new Reference<>(); + value = new Reference<>(); + } + + @Override + public boolean hasNext() { + long lastValue = iterator.getValue(); + returnCode = enumerate_params(iterator, null, null); + iterator.setValue(lastValue); + return returnCode != 1; + } + + @Override + public GSParam next() { + if (returnCode != 0) + throw new IllegalStateException("Reached end of iterator"); + returnCode = enumerate_params(iterator, key, valueType); + if (returnCode < 0) + throw new IllegalStateException("Failed to enumerate params"); + + int code = get_param_once(key.getValue(), value, valueType.getValue()); + if (code != 0) + throw new IllegalStateException("Failed to get param"); + return new GSParam<>(key.asString(), value.getValue()); + } + + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/DisplayCallback.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/DisplayCallback.java new file mode 100644 index 00000000..f2f7e712 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/DisplayCallback.java @@ -0,0 +1,75 @@ +package com.artifex.gsjava.callbacks; + +import com.artifex.gsjava.util.BytePointer; +import com.artifex.gsjava.util.Reference; + +/** + * Class wrapping a display_callback structure. + * + * @author Ethan Vrhel + * + */ +public abstract class DisplayCallback { + + public volatile int size; + public volatile int versionMajor; + public volatile int versionMinor; + + public int onDisplayOpen(long handle, long device) { + return 0; + } + + public int onDisplayPreclose(long handle, long device) { + return 0; + } + + public int onDisplayClose(long handle, long device) { + return 0; + } + + public int onDisplayPresize(long handle, long device, int width, + int height, int raster, int format) { + return 0; + } + + public int onDisplaySize(long handle, long device, int width, + int height,int raster, int format, BytePointer pimage) { + return 0; + } + + public int onDisplaySync(long handle, long device) { + return 0; + } + + public int onDisplayPage(long handle, long device, int copies, boolean flush) { + return 0; + } + + public int onDisplayUpdate(long handle, long device, int x, int y, int w, int h) { + return 0; + } + + /* + public long onDisplayMemalloc(long handle, long device, long size) { + return GS_NULL; + } + + public int onDisplayMemfree(long handle, long device, long mem) { + return 0; + }*/ + + public int onDisplaySeparation(long handle, long device, int component, byte[] componentName, + short c, short m, short y, short k) { + return 0; + } + + public int onDisplayAdjustBandHeight(long handle, long device, int bandHeight) { + return 0; + } + + public int onDisplayRectangleRequest(long handle, long device, Reference memory, Reference ox, + Reference oy, Reference raster, Reference planeRaster, Reference x, + Reference y, Reference w, Reference h) { + return 0; + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/ICalloutFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/ICalloutFunction.java new file mode 100644 index 00000000..9b163717 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/ICalloutFunction.java @@ -0,0 +1,7 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface ICalloutFunction { + + public int onCallout(long instance, long calloutHandle, byte[] deviceName, int id, int size, long data); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IPollFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IPollFunction.java new file mode 100644 index 00000000..ae0f3b50 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IPollFunction.java @@ -0,0 +1,7 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IPollFunction { + + public int onPoll(long callerHandle); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdErrFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdErrFunction.java new file mode 100644 index 00000000..5001b9c5 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdErrFunction.java @@ -0,0 +1,15 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IStdErrFunction { + + /** + * Called when something should be written to the standard error stream. + * + * @param callerHandle The caller handle. + * @param str The string to write. + * @param len The length of bytes to be written. + * @return The amount of bytes written, must be len. + */ + public int onStdErr(long callerHandle, byte[] str, int len); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdInFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdInFunction.java new file mode 100644 index 00000000..c6d97e94 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdInFunction.java @@ -0,0 +1,15 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IStdInFunction { + + /** + * + * + * @param callerHandle The caller handle. + * @param buf A string. + * @param len The number of bytes to read. + * @return The number of bytes read, must be len/ + */ + public int onStdIn(long callerHandle, byte[] buf, int len); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdOutFunction.java b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdOutFunction.java new file mode 100644 index 00000000..c3635f54 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/callbacks/IStdOutFunction.java @@ -0,0 +1,16 @@ +package com.artifex.gsjava.callbacks; + +@FunctionalInterface +public interface IStdOutFunction { + + /** + * Called when something should be written to the standard + * output stream. + * + * @param callerHandle The caller handle. + * @param str The string to write. + * @param len The number of bytes to write. + * @return The number of bytes written, must be len. + */ + public int onStdOut(long callerHandle, byte[] str, int len); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/BMPDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/BMPDevice.java new file mode 100644 index 00000000..2af8e7f1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/BMPDevice.java @@ -0,0 +1,18 @@ +package com.artifex.gsjava.devices; + +public class BMPDevice extends FileDevice { + + public static final String BMPMONO = "bmpmono"; + public static final String BMPGRAY = "bmpgray"; + public static final String BMPSEP1 = "bmpsep1"; + public static final String BMPSEP8 = "bmpsep8"; + public static final String BMP16 = "bmp16"; + public static final String BMP256 = "bmp256"; + public static final String BMP16M = "bmp16m"; + public static final String BMP32B = "bmp32b"; + + public BMPDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java new file mode 100644 index 00000000..74dc5332 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/Device.java @@ -0,0 +1,308 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +import java.awt.Dimension; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import com.artifex.gsjava.GSInstance; +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; +import com.artifex.gsjava.util.Reference; + +/** + *

The Device class allows easier rendering to a Ghostscript device. + * The class allows setting different device parameters, running a file, and some + * safety with regard to Ghostcript instances. There can only be one instance of a + * Device at a time.

+ * + *

Full documentation on each device can be found on the + * Details of Ghostscript Output Devices + * webpage.

+ * + * @author Ethan Vrhel + * + */ +public abstract class Device { + + private static Device activeDevice; // The active device, only one device may exist at a time + + private GSInstance instance; + private final String deviceName; + + /** + * Creates a new device with the given device name. When this constructor is called, + * an instance of Ghostscript cannot exist or an exception will be thrown. The check of + * whether an instance already exists does not include instances directly created + * through GSAPI.gsapi_new_instance. + * + * @param deviceName The name of the Ghostscript device. + * @throws DeviceNotSupportedException When deviceName is not a supported + * Ghostscript device. + * @throws DeviceInUseException When a Device object already exists. + * @throws IllegalStateException When an instance of Ghostscript created through GSInstance + * already exists. + */ + public Device(String deviceName) throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + if (activeDevice != null) + throw new DeviceInUseException(activeDevice); + GSInstance instance = new GSInstance(); + this.deviceName = Objects.requireNonNull(deviceName, "device name must be non-null"); + StdIO io = new StdIO(); + instance.set_stdio(io, io, io); + instance.init_with_args(new String[] { + "gs", + "-h", + }); + instance.exit(); + instance.delete_instance(); + if (!io.hasDevice) + throw new DeviceNotSupportedException(deviceName); + } + + /** + * Initializes the device on an instance with the given arguments. The + * given instance must not have had init_with_args called. + * + * @param instance The instance to initialize. + * @param more Arguments which should be passed to Ghostscript through + * gsapi_init_with_args. + */ + public void initWithInstance(GSInstance instance, String... more) { + if (this.instance != null) + throw new IllegalStateException("instance has already been initialized"); + this.instance = Objects.requireNonNull(instance, "Instance must be non-null"); + List args = new ArrayList<>(2 + more.length); + args.add("gs"); + args.add("-sDEVICE=" + deviceName); + for (String s : more) { + args.add(s); + } + instance.init_with_args(args); + } + + /** + * Runs a file. + * + * @param file The file to run. + * @param userErrors The user errors. + * @param pExitCode The exit code. + * @return The result of the run_file. + */ + public int runFile(File file, int userErrors, Reference pExitCode) { + return runFile(file.getAbsolutePath(), userErrors, pExitCode); + } + + /** + * Runs a file. + * + * @param file The file to run. + * @param userErrors The user errors. + * @param pExitCode The exit code. + * @return The result of the run_file. + */ + public int runFile(String filename, int userErrors, Reference pExitCode) { + return instance.run_file(filename, userErrors, pExitCode); + } + + /** + * Returns the internal device name. This name is the same as the one provided + * by the user in the Device constructor. + * + * @return The internal device name. + */ + public String getInternalName() { + return deviceName; + } + + /** + * Destroys this device. + * + * @throws IllegalStateException When the instance of Ghostscript fails to + * exit. + */ + public void destroyDevice() throws IllegalStateException { + int code = instance.exit(); + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to exit"); + instance.delete_instance(); + activeDevice = null; + } + + /** + * Sets a device parameter. + * + * @param param The name of the device parameter. + * @param value The value to set the device parameter to. + * @param paramType The type of the device parameter. + * @return The result of setting the parameter through + * gsapi_set_param. + */ + public int setParam(String param, Object value, int paramType) { + return instance.set_param(param, value, paramType); + } + + /** + * Sets a string device parameter. + * + * @param param The name of the device parameter. + * @param value The string value to set the device parameter to. + * @param paramType The type of the device parameter. + * @return The result of setting the parameter through + * gsapi_set_param. + */ + public int setParam(String param, String value, int paramType) { + return instance.set_param(param, value, paramType); + } + + public int setResolution(Dimension resolution) { + return setResolution("[" + resolution.width + " " + resolution.height + "]"); + } + + public int setResolution(int resolution) { + return setResolution("[" + resolution + " " + resolution + "]"); + } + + public int setResolution(String resolution) { + return setParam("HWResolution", resolution, GS_SPT_PARSED); + } + + public int setColorScreen(boolean state) { + return setParam("COLORSCREEN", state, GS_SPT_BOOL); + } + + public int setDitherPPI(int lpi) { + return setParam("DITHERPPI", lpi, GS_SPT_INT); + } + + public int setInterpolateControl(int controlValue) { + return setParam("InterpolateControl", controlValue, GS_SPT_INT); + } + + public int setTextAlphaBits(int value) { + return setParam("TextAlphaBits", value, GS_SPT_INT); + } + + public int setGraphicsAlphaBits(int value) { + return setParam("GraphicsAlphaBits", value, GS_SPT_INT); + } + + public int setAlignToPixels(int n) { + return setParam("AlignToPixels", n, GS_SPT_INT); + } + + public int setGridFitTT(int n) { + return setParam("GridFitTT", n, GS_SPT_INT); + } + + public int setFirstPage(int page) { + return setParam("FirstPage", page, GS_SPT_INT); + } + + public int setLastPage(int page) { + return setParam("LastPage", page, GS_SPT_INT); + } + + public int setPageList(String list) { + return setParam("PageList", list, GS_SPT_PARSED); + } + + public int setORIENT1(boolean state) { + return setParam("ORIENT1", state, GS_SPT_BOOL); + } + + public int setDeviceWidthPoints(int w) { + return setParam("DEVICEWIDTHPOINTS", w, GS_SPT_INT); + } + + public int setDeviceHeightPoints(int h) { + return setParam("DEVICEHEIGHTPOINTS", h, GS_SPT_INT); + } + + public int setDefaultPaperSize(String paperSize) { + return setParam("DEFAULTPAPERSIZE", paperSize, GS_SPT_STRING); + } + + public int setFontMap(String files) { + return setParam("FONTMAP", files, GS_SPT_PARSED); + } + + public int setFontPath(String paths) { + return setParam("FONTPATH", paths, GS_SPT_PARSED); + } + + public int setSubstFont(String fontname) { + return setParam("SUBSTFONT", fontname, GS_SPT_STRING); + } + + public int setGenericResourceDir(String path) { + return setParam("FontResourceDir", path, GS_SPT_STRING); + } + + public int setStdout(String filename) { + return setParam("stdout", filename, GS_SPT_STRING); + } + + /** + * Returns the stored Ghostscript instance. + * + * @return The instance. + */ + protected final GSInstance getInstance() { + return instance; + } + + protected final String toArrayParameter(String[] array) { + StringBuilder builder = new StringBuilder(); + if (array.length > 0) { + builder.append(array[0]); + for (int i = 1; i < array.length; i++) { + builder.append(','); + builder.append(array[i]); + } + } + return builder.toString(); + } + + protected final String toArrayParameter(List list) { + return toArrayParameter(list.toArray(new String[list.size()])); + } + + @Override + public String toString() { + return "Device[instance=" + instance + ",deviceName=" + deviceName + "]"; + } + + private class StdIO implements IStdInFunction, IStdOutFunction, IStdErrFunction { + + private boolean hasDevice; + + @Override + public int onStdIn(long callerHandle, byte[] buf, int len) { + return buf.length; + } + + @Override + public int onStdOut(long callerHandle, byte[] str, int len) { + if (!hasDevice) { + String outp = new String(str); + hasDevice = outp.contains(deviceName); + } + return str.length; + } + + @Override + public int onStdErr(long callerHandle, byte[] str, int len) { + if (!hasDevice) { + String outp = new String(str); + hasDevice = outp.contains(deviceName); + } + return str.length; + } + + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceInUseException.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceInUseException.java new file mode 100644 index 00000000..aa5621fc --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceInUseException.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +public class DeviceInUseException extends Exception { + + private static final long serialVersionUID = 1L; + + private Device device; + + public DeviceInUseException(Device device) { + super(device == null ? "null" : device.toString()); + this.device = device; + } + + public Device getDevice() { + return device; + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceNotSupportedException.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceNotSupportedException.java new file mode 100644 index 00000000..453fdead --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/DeviceNotSupportedException.java @@ -0,0 +1,28 @@ +package com.artifex.gsjava.devices; + +public class DeviceNotSupportedException extends Exception { + + private static final long serialVersionUID = 1L; + + public DeviceNotSupportedException() { + super(); + } + + public DeviceNotSupportedException(String message) { + super(message); + } + + public DeviceNotSupportedException(Throwable cause) { + super(cause); + } + + public DeviceNotSupportedException(String message, Throwable cause) { + super(message, cause); + } + + protected DeviceNotSupportedException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java new file mode 100644 index 00000000..959ed4d8 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/DisplayDevice.java @@ -0,0 +1,55 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +import java.util.List; + +public class DisplayDevice extends Device { + + public static final String X11 = "x11"; + public static final String X11ALPHA = "x11alpha"; + public static final String X11CMYK = "x11cmyk"; + public static final String X11MONO = "x11mono"; + public static final String X11GRAY2 = "x11gray2"; + public static final String X11GRAY4 = "x11gray4"; + + public DisplayDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("display"); + } + + public DisplayDevice(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setDisplayFormat(int format) { + setParam("DisplayFormat", format, GS_SPT_INT); + } + + public void setDisplayResolution(int dpi) { + setParam("DisplayResolution", dpi, GS_SPT_INT); + } + + public void setSeparationColorNames(String nameArray) { + setParam("SeparationColorNames", nameArray, GS_SPT_PARSED); + } + + public void setSeparationColorNames(String[] names) { + setSeparationColorNames(toArrayParameter(names)); + } + + public void setSeparationColorNames(List names) { + setSeparationColorNames(toArrayParameter(names)); + } + + public void setSeparationOrder(String orderArray) { + setParam("SeparationOrder", orderArray, GS_SPT_PARSED); + } + + public void setSeparationOrder(String[] order) { + setSeparationOrder(toArrayParameter(order)); + } + + public void setSeparationOrder(List order) { + setSeparationOrder(toArrayParameter(order)); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java new file mode 100644 index 00000000..efa999a1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/EPSDevice.java @@ -0,0 +1,9 @@ +package com.artifex.gsjava.devices; + +public class EPSDevice extends PostScriptDevice { + + public EPSDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("eps2write"); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/FAXDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/FAXDevice.java new file mode 100644 index 00000000..5770a8b4 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/FAXDevice.java @@ -0,0 +1,18 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class FAXDevice extends FileDevice { + + public static final String FAXG3 = "faxg3"; + public static final String FAXG32D = "faxg32d"; + public static final String FAXG4 = "faxg4"; + + public FAXDevice(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setMinFeatureSize(int value) { + setParam("MinFeatureSize", value, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/FileDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/FileDevice.java new file mode 100644 index 00000000..9f3d6ce3 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/FileDevice.java @@ -0,0 +1,36 @@ +package com.artifex.gsjava.devices; + +import java.io.File; + +import com.artifex.gsjava.GSAPI; +import com.artifex.gsjava.GSInstance; + +public abstract class FileDevice extends Device { + + public FileDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + public void initFileWithInstance(GSInstance instance, File file, String... more) { + initFileWithInstance(instance, file, more); + } + + public void setOutputFile(File file) { + setOutputFile(file.getAbsolutePath()); + } + + public void setOutputFile(String file) { + setParam("OutputFile", file, GSAPI.GS_SPT_STRING); + } + + public void initFileWithInstance(GSInstance instance, String file, String... more) { + String[] args = new String[2 + more.length]; + args[0] = "-o"; + args[1] = file; + for (int i = 0; i < more.length; i++) { + args[i + 2] = more[i]; + } + initWithInstance(instance, args); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/HighLevelDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/HighLevelDevice.java new file mode 100644 index 00000000..4a08d522 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/HighLevelDevice.java @@ -0,0 +1,13 @@ +package com.artifex.gsjava.devices; + +/** + * Interface indicating a device is a high-level device. + * See High Level Output Devices + * webpage for full documentation on each device. + * + * @author Ethan Vrhel + * + */ +public interface HighLevelDevice { + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/JPEGDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/JPEGDevice.java new file mode 100644 index 00000000..bf015349 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/JPEGDevice.java @@ -0,0 +1,19 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class JPEGDevice extends FileDevice { + + public JPEGDevice() + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super("jpeg"); + } + + public void setJPEGQuality(int quality) { + setParam("JPEGQ", quality, GSAPI.GS_SPT_INT); + } + + public void setQualityFactor(float scale) { + setParam("QFactor", scale, GSAPI.GS_SPT_FLOAT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/OCRDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/OCRDevice.java new file mode 100644 index 00000000..533714bf --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/OCRDevice.java @@ -0,0 +1,24 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class OCRDevice extends FileDevice { + + public static final int DEFAULT_ENGINE = 0; + public static final int LSTM_ENGINE = 1; + public static final int TESSERACT_ENGINE = 2; + public static final int LSTM_AND_TESSERACT_ENGINE = 3; + + public OCRDevice() + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super("ocr"); + } + + public void setOCRLanguage(String language) { + setParam("OCRLanguage", language, GSAPI.GS_SPT_PARSED); + } + + public void setOCREngine(int engine) { + setParam("OCREngine", engine, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PCXDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PCXDevice.java new file mode 100644 index 00000000..c0323e60 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PCXDevice.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +public class PCXDevice extends FileDevice { + + public static final String PCXMONO = "pcxmono"; + public static final String PCXGRAY = "pcxgray"; + public static final String PCX16 = "pcx16"; + public static final String PCX256 = "pcx256"; + public static final String PCX24B = "pcx24b"; + public static final String PCXCMYK = "pcxcmyk"; + + public PCXDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java new file mode 100644 index 00000000..2d084f71 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFDevice.java @@ -0,0 +1,90 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +public class PDFDevice extends PDFPostscriptDeviceFamily { + + public PDFDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("pdfwrite"); + } + + public void setMaxInlineImageSize(int value) { + setParam("MaxInlineImageSize", value, GS_SPT_INT); + } + + public void setDoNumCopies(boolean state) { + setParam("DoNumCopies", state, GS_SPT_BOOL); + } + + public void setDetectDuplicateImages(boolean state) { + setParam("DetectDuplicateImages", state, GS_SPT_BOOL); + } + + public void setFastWebView(boolean state) { + setParam("FastWebView", state, GS_SPT_BOOL); + } + + public void setPreserveAnnots(boolean state) { + setParam("PreserveAnnots", state, GS_SPT_BOOL); + } + + public void setPatternImagemask(boolean state) { + setParam("PatternImagemask", state, GS_SPT_BOOL); + } + + public void setMaxClipPathSize(int value) { + setParam("MaxClipPathSize", value, GS_SPT_INT); + } + + public void setMaxShadingBitmapSize(int value) { + setParam("MaxShadingBitmapSize", value, GS_SPT_INT); + } + + public void setHaveTrueTypes(boolean state) { + setParam("HaveTrueTypes", state, GS_SPT_BOOL); + } + + public void setHaveTransparency(boolean state) { + setParam("HaveTransparency", state, GS_SPT_BOOL); + } + + public void setPDFX(boolean state) { + setParam("PDFX", state, GS_SPT_BOOL); + } + + public void setOwnerPassword(String value) { + setParam("OwnerPassword", value, GS_SPT_STRING); + } + + public void setUserPassword(String value) { + setParam("UserPassword", value, GS_SPT_STRING); + } + + public void setPermissions(int value) { + setParam("Permissions", value, GS_SPT_INT); + } + + public void setEncryptionR(int num) { + setParam("EncryptionR", num, GS_SPT_INT); + } + + public void setKeyLength(int length) { + setParam("KeyLength", length, GS_SPT_INT); + } + + public void setDocumentUUID(String value) { + setParam("DocumentUUID", value, GS_SPT_STRING); + } + + public void setInstanceUUID(String value) { + setParam("InstanceUUID", value, GS_SPT_STRING); + } + + public void setDocumentTimeSeq(int value) { + setParam("DocumentTimeSeq", value, GS_SPT_INT); + } + + public void setDSCEncoding(String encoding) { + setParam("DSCEncoding", encoding, GS_SPT_STRING); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFImageDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFImageDevice.java new file mode 100644 index 00000000..8eedbab9 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFImageDevice.java @@ -0,0 +1,19 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class PDFImageDevice extends FileDevice { + + public static final String PDFIMAGE8 = "pdfimage8"; + public static final String PDFIMAGE24 = "pdfimage24"; + public static final String PDFIMAGE32 = "pdfimage32"; + + public PDFImageDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + public void setDownScaleFactor(int factor) { + setParam("DownScaleFactor", factor, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java new file mode 100644 index 00000000..6afc997c --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PDFPostscriptDeviceFamily.java @@ -0,0 +1,340 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +/** + * This class is the root device containing methods to set parameters defined + * in section 6.1 in the + * Vector Devices + * documentation. + * + * @author Ethan Vrhel + * + */ +public abstract class PDFPostscriptDeviceFamily extends FileDevice implements HighLevelDevice { + + public PDFPostscriptDeviceFamily(String device) + throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setCompressFonts(boolean state) { + setParam("CompressFonts", state, GS_SPT_BOOL); + } + + public void setCompressStreams(boolean state) { + setParam("CompressStreas", state, GS_SPT_BOOL); + } + + public void setAlwaysEmbed(String value) { + setParam("AlwaysEmbed", value, GS_SPT_PARSED); + } + + public void setAntiAliasColorImages(boolean state) { + setParam("AntiAliasColorImages", state, GS_SPT_BOOL); + } + + public void setAntiAliasGrayImages(boolean state) { + setParam("AntiAliasGrayImages", state, GS_SPT_BOOL); + } + + public void setAntiAliasMonoImages(boolean state) { + setParam("AntiAliasMonoImages", state, GS_SPT_BOOL); + } + + public void setASCII85EncodePages(boolean state) { + setParam("ASCII85EncodePages", state, GS_SPT_BOOL); + } + + public void setAutoFilterColorImages(boolean state) { + setParam("AutoFilterColorImages", state, GS_SPT_BOOL); + } + + public void setAutoFilterGrayImages(boolean state) { + setParam("AutoFilterGrayImages", state, GS_SPT_BOOL); + } + + public void setAutoPositionEPSFiles(boolean state) { + setParam("AutoPositionEPSFiles", state, GS_SPT_BOOL); + } + + public void setAutoRotatePages(String mode) { + setParam("AutoRotatePages", mode, GS_SPT_STRING); + } + + public void setBinding(String mode) { + setParam("Binding", mode, GS_SPT_STRING); + } + + public void setCalCMYKProfile(String profile) { + setParam("CalCMYKProfile", profile, GS_SPT_PARSED); + } + + public void setCalGrayProfile(String profile) { + setParam("CalGrayProfile", profile, GS_SPT_PARSED); + } + + public void setCalRGBProfile(String profile) { + setParam("CalRGBProfile", profile, GS_SPT_PARSED); + } + + public void setCannotEmbedFontPolicy(String mode) { + setParam("CannotEmbedFontPolicy", mode, GS_SPT_STRING); + } + + public void setColorACSImageDict(String dict) { + setParam("ColorACSImageDict", dict, GS_SPT_PARSED); + } + + public void setColorConversionStrategy(String strat) { + setParam("ColorConversionSrategy", strat, GS_SPT_STRING); + } + + public void setColorImageDepth(int value) { + setParam("ColorImageDepth", value, GS_SPT_INT); + } + + public void setColorImageDict(String dict) { + setParam("ColorImageDict", dict, GS_SPT_PARSED); + } + + public void setColorImageFilter(String filter) { + setParam("ColorImageFilter", filter, GS_SPT_STRING); + } + + public void setColorImageDownscaleThreshold(float value) { + setParam("ColorImageDownscaleThreshold", value, GS_SPT_FLOAT); + } + + public void setColorImageDownsampleType(String type) { + setParam("ColorImageDownsampleType", type, GS_SPT_STRING); + } + + public void setColorImageResolution(int value) { + setParam("ColorImageResolution", value, GS_SPT_INT); + } + + public void setCompatabilityLevel(String level) { + setParam("CompatabilityLevel", level, GS_SPT_PARSED); + } + + public void setCompressPages(boolean state) { + setParam("CompressPages", state, GS_SPT_BOOL); + } + + public void setConvertCMYKImagesToRGB(boolean state) { + setParam("ConvertCMYKImagesToRGB", state, GS_SPT_BOOL); + } + + public void setConvertColorImagesToIndexed(boolean state) { + setParam("ConvertColorImagesToIndexed", state, GS_SPT_BOOL); + } + + public void setCoreDictVersion(int version) { + setParam("CoreDictVersion", version, GS_SPT_INT); + } + + public void setCreateJobTicket(boolean state) { + setParam("CreateJobTicket", state, GS_SPT_BOOL); + } + + public void setDefaultRenderingIntent(String intent) { + setParam("DefaultRenderingIntent", intent, GS_SPT_STRING); + } + + public void setDetectBlends(boolean state) { + setParam("DetectBlends", state, GS_SPT_BOOL); + } + + public void setDoThumbnails(boolean state) { + setParam("DoThumbnails", state, GS_SPT_BOOL); + } + + public void setDownsampleColorImages(boolean state) { + setParam("DownsampleColorImages", state, GS_SPT_BOOL); + } + + public void setDownsampleGrayImages(boolean state) { + setParam("DownsampleGrayImages", state, GS_SPT_BOOL); + } + + public void setDownsampleMonoImages(boolean state) { + setParam("DownsampleMonoImages", state, GS_SPT_BOOL); + } + + public void setEmbedAllFonts(boolean state) { + setParam("EmbedAllFonts", state, GS_SPT_BOOL); + } + + public void setEmitDSCWarnings(boolean state) { + setParam("EmitDSCWarnings", state, GS_SPT_BOOL); + } + + public void setEncodeColorImages(boolean state) { + setParam("EncodeColorImages", state, GS_SPT_BOOL); + } + + public void setEncodeGrayImages(boolean state) { + setParam("EncodeGrayImages", state, GS_SPT_BOOL); + } + + public void setEncodeMonoImages(boolean state) { + setParam("EncodeMonoImages", state, GS_SPT_BOOL); + } + + public void setEndPage(int page) { + setParam("EndPage", page, GS_SPT_INT); + } + + public void setGrayACSImageDict(String dict) { + setParam("GrayACSImageDict", dict, GS_SPT_PARSED); + } + + public void setGrayImageDepth(int value) { + setParam("GrayImageDepth", value, GS_SPT_INT); + } + + public void setGrayImageDict(String dict) { + setParam("GrayImageDict", dict, GS_SPT_PARSED); + } + + public void setGrayImageDownsampleThreshold(float thresh) { + setParam("GrayImageDownsampleThreshold", thresh, GS_SPT_FLOAT); + } + + public void setGrayImageDownsampleType(String type) { + setParam("GrayImageDownsampleType", type, GS_SPT_STRING); + } + + public void setGrayImageFilter(String filter) { + setParam("GrayImageFilter", filter, GS_SPT_STRING); + } + + public void setGrayImageResolution(int resolution) { + setParam("GrayImageResolution", resolution, GS_SPT_INT); + } + + public void setImageMemory(long memory) { + setParam("ImageMemory", memory, GS_SPT_SIZE_T); + } + + public void setLockDistillerParams(boolean state) { + setParam("LockDistillerParams", state, GS_SPT_BOOL); + } + + public void setLZWEncodePages(boolean state) { + setParam("LZWEncodePages", state, GS_SPT_BOOL); + } + + public void setMaxSubsetPct(int value) { + setParam("MaxSubsetPct", value, GS_SPT_INT); + } + + public void setMonoImageDepth(int depth) { + setParam("MonoImageDepth", depth, GS_SPT_INT); + } + + public void setMonoImageDict(String dict) { + setParam("MonoImageDict", dict, GS_SPT_PARSED); + } + + public void setMonoImageDownsampleThreshold(float thresh) { + setParam("MonoImageDownsampleThreshold", thresh, GS_SPT_FLOAT); + } + + public void setMonoImageDownsampleType(String type) { + setParam("MonoImageDownsampleType", type, GS_SPT_STRING); + } + + public void setMonoImageFilter(String filter) { + setParam("MonoImageFilter", filter, GS_SPT_STRING); + } + + public void setMonoImageResolution(int resolution) { + setParam("MonoImageResolution", resolution, GS_SPT_INT); + } + + public void setNeverEmbed(String value) { + setParam("NeverEmbed", value, GS_SPT_PARSED); + } + + public void setOffOptimizations(int value) { + setParam("OffOptimizations", value, GS_SPT_INT); + } + + public void setOPM(int value) { + setParam("OPM", value, GS_SPT_INT); + } + + public void setOptimize(boolean state) { + setParam("Optimize", state, GS_SPT_BOOL); + } + + public void setParseDSCComments(boolean state) { + setParam("ParseDSCComments", state, GS_SPT_BOOL); + } + + public void setParseDSCCommentsForDocInfo(boolean state) { + setParam("ParseDSCCommentsForDocInfo", state, GS_SPT_BOOL); + } + + public void setPreserveCopyPage(boolean state) { + setParam("PreserveCopyPage", state, GS_SPT_BOOL); + } + + public void setPreserveEPSInfo(boolean state) { + setParam("PreserveEPSInfo", state, GS_SPT_BOOL); + } + + public void setPreserveHalftoneInfo(boolean state) { + setParam("PreserveHalftoneInfo", state, GS_SPT_BOOL); + } + + public void setPreserveOPIComments(boolean state) { + setParam("PreserveOPIComments", state, GS_SPT_BOOL); + } + + public void setPreserveOverprintSettings(boolean state) { + setParam("PreserveOverprintSettings", state, GS_SPT_BOOL); + } + + public void setsRGBProfile(String profile) { + setParam("sRGBProfile", profile, GS_SPT_PARSED); + } + + public void setStartPage(int page) { + setParam("StartPage", page, GS_SPT_INT); + } + + public void setSubsetFonts(boolean state) { + setParam("SubsetFonts", state, GS_SPT_BOOL); + } + + public void setTransferFunctionInfo(String info) { + setParam("TransferFunctionInfo", info, GS_SPT_STRING); + } + + public void setUCRandBGInfo(String info) { + setParam("UCRandBGInfo", info, GS_SPT_STRING); + } + + public void setUseFlateCompression(boolean state) { + setParam("UseFlateCompression", state, GS_SPT_BOOL); + } + + public void setUsePrologue(boolean state) { + setParam("UsePrologue", state, GS_SPT_BOOL); + } + + public void setPassThroughJPEGImages(boolean state) { + setParam("PassThroughJPEGImages", state, GS_SPT_BOOL); + } + + // Specific to PostScript and PDF input + + public void setPDFSETTINGS(String config) { + setParam("PDFSETTINGS", config, GS_SPT_STRING); + } + + // Specific to PCL and PXL input +} \ No newline at end of file diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PNGDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNGDevice.java new file mode 100644 index 00000000..8f291851 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNGDevice.java @@ -0,0 +1,36 @@ +package com.artifex.gsjava.devices; + +import java.awt.Color; + +import com.artifex.gsjava.GSAPI; + +public class PNGDevice extends FileDevice { + + public static final String PNG256 = "png256"; + public static final String PNG16 = "png16"; + public static final String PNGMONO = "pngmono"; + public static final String PNGMONOD = "pngmonod"; + public static final String PNG16M = "png16m"; + public static final String PNGGRAY = "pnggray"; + public static final String PNGALPHA = "pngalpha"; + + public PNGDevice(String format) throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(format); + } + + public void setDownScaleFactor(int value) { + setParam("DownScaleFactor", value, GSAPI.GS_SPT_INT); + } + + public void setMinFeatureSize(int state) { + setParam("MinFeatureSize", state, GSAPI.GS_SPT_INT); + } + + public void setBackgroundColor(Color color) { + setBackgroundColor(color.getRGB()); + } + + public void setBackgroundColor(int color) { + setParam("BackgroundColor", color, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PNMDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNMDevice.java new file mode 100644 index 00000000..14474906 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PNMDevice.java @@ -0,0 +1,25 @@ +package com.artifex.gsjava.devices; + +public class PNMDevice extends FileDevice { + + public static final String PBM = "pbm"; + public static final String PBMRAW = "pbmraw"; + public static final String PGM = "pbm"; + public static final String PGMRAW = "pgmraw"; + public static final String PGMN = "pgnm"; + public static final String PGMNRAW = "pgnmraw"; + public static final String PNM = "pnm"; + public static final String PNMRAW = "pnmraw"; + public static final String PPM = "ppm"; + public static final String PPMRAW = "ppmraw"; + public static final String PKM = "pkm"; + public static final String PKMRAW = "pkmraw"; + public static final String PKSM = "pksm"; + public static final String PKSMRAW = "pksmraw"; + + public PNMDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PSDDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PSDDevice.java new file mode 100644 index 00000000..312af85d --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PSDDevice.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +public class PSDDevice extends FileDevice { + + public static final String PSDCMYK = "psdcmyk"; + public static final String PSDRGB = "psdrgb"; + public static final String PSDCMYK16 = "psdcmyk16"; + public static final String PSDRGB16 = "psdrgb16"; + public static final String PSDCMYKOG = "psdcmykog"; + + public PSDDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + // Missing device parameters +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PXLDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PXLDevice.java new file mode 100644 index 00000000..9fb55fd2 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PXLDevice.java @@ -0,0 +1,17 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class PXLDevice extends FileDevice implements HighLevelDevice { + + public static final String PXLMONO = "pxlmono"; + public static final String PXLCOLOR = "pxlcolor"; + + public PXLDevice(String device) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(device); + } + + public void setCompressMode(int mode) { + setParam("CompressMode", mode, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java new file mode 100644 index 00000000..3926ebf9 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/PostScriptDevice.java @@ -0,0 +1,59 @@ +package com.artifex.gsjava.devices; + +import static com.artifex.gsjava.GSAPI.*; + +public class PostScriptDevice extends PDFPostscriptDeviceFamily { + + public PostScriptDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("ps2write"); + } + + /** + * Intended to be an internal way to override the normal + * ps2write device. + * + * @param override The device override name. + * @throws IllegalStateException {@link Device#Device(String)} + * @throws DeviceNotSupportedException {@link Device#Device(String)} + * @throws DeviceInUseException {@link Device#Device(String)} + */ + protected PostScriptDevice(String override) throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super(override); + } + +// public void setPSDocOptions(String options) { +// setParam("PSDocOptions", options, GS_SPT_STRING); +// } +// +// public void setPSPageOptions(String[] options) { +// +// } +// +// public void setPSPageOptions(List options) { +// setPSPageOptions(options.toArray(new String[options.size()])); +// } + + public void setProduceDSC(boolean state) { + setParam("ProduceDSC", state, GS_SPT_BOOL); + } + + public void setCompressEntireFile(boolean state) { + setParam("CompressEntireFile", state, GS_SPT_BOOL); + } + + public void setRotatePages(boolean state) { + setParam("RotatePages", state, GS_SPT_BOOL); + } + + public void setCenterPages(boolean state) { + setParam("CenterPages", state, GS_SPT_BOOL); + } + + public void setSetPageSize(boolean state) { + setParam("SetPageSize", state, GS_SPT_BOOL); + } + + public void setDoNumCopies(boolean state) { + setParam("DoNumCopies", state, GS_SPT_BOOL); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/TIFFDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/TIFFDevice.java new file mode 100644 index 00000000..25b9d335 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/TIFFDevice.java @@ -0,0 +1,80 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class TIFFDevice extends FileDevice { + + public static final String TIFFGRAY = "tiffgray"; + public static final String TIFF12NC = "tiff12nc"; + public static final String TIFF24NC = "tiff24nc"; + public static final String TIFF48NC = "tiff48nc"; + public static final String TIFF32NC = "tiff32nc"; + public static final String TIFF64NC = "tiff64nc"; + public static final String TIFFSEP = "tiffsep"; + + public static final String TIFFSEP1 = "tiffsep1"; + public static final String TIFFSCALED = "tiffscaled"; + public static final String TIFFSCALED4 = "tiffscaled4"; + public static final String TIFFSCALED8 = "tiffscaled8"; + public static final String TIFFSCALED24 = "tiffscaled24"; + public static final String TIFFSCALED32 = "tiffscaled32"; + + public static final String TIFFCRLE = "tiffcrle"; + public static final String TIFFG3 = "tiffg3"; + public static final String TIFFG32D = "tiffg32d"; + public static final String TIFFG4 = "tiffg4"; + public static final String TIFFLZW = "tifflzw"; + public static final String TIFFPACK = "tiffpack"; + + public static final String NONE = "none"; + public static final String CRLE = "crle"; + public static final String G3 = "g3"; + public static final String G4 = "g4"; + public static final String LZW = "lzw"; + public static final String PACK = "pack"; + + public TIFFDevice(String deviceName) + throws DeviceNotSupportedException, DeviceInUseException, IllegalStateException { + super(deviceName); + } + + public void setMaxStripSize(int size) { + setParam("MaxStripSize", size, GSAPI.GS_SPT_INT); + } + + public void setFillOrder(int order) { + setParam("FillOrder", order, GSAPI.GS_SPT_INT); + } + + public void setUseBigTIFF(boolean state) { + setParam("UseBigTIFF", state, GSAPI.GS_SPT_BOOL); + } + + public void setTIFFDateTime(boolean state) { + setParam("TIFFDateTime", state, GSAPI.GS_SPT_BOOL); + } + + public void setCompression(String compression) { + setParam("Compression", compression, GSAPI.GS_SPT_NAME); + } + + public void setAdjustWith(int state) { + setParam("AdjustWidth", state, GSAPI.GS_SPT_INT); + } + + public void setMinFeatureSize(int state) { + setParam("MinFeatureSize", state, GSAPI.GS_SPT_INT); + } + + public void setDownScaleFactor(int factor) { + setParam("DownScaleFactor", factor, GSAPI.GS_SPT_INT); + } + + public void setPostRenderProfile(String path) { + setParam("PostRenderProfile", path, GSAPI.GS_SPT_NAME); + } + + public void setPrintSpotCMYK(boolean state) { + setParam("PrintSpotCMYK", state, GSAPI.GS_SPT_BOOL); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/TextDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/TextDevice.java new file mode 100644 index 00000000..00f67f5a --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/TextDevice.java @@ -0,0 +1,14 @@ +package com.artifex.gsjava.devices; + +import com.artifex.gsjava.GSAPI; + +public class TextDevice extends FileDevice implements HighLevelDevice { + + public TextDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("txtwrite"); + } + + public void setTextFormat(int format) { + setParam("TextFormat", format, GSAPI.GS_SPT_INT); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/devices/XPSDevice.java b/demos/java/gsjava/src/com/artifex/gsjava/devices/XPSDevice.java new file mode 100644 index 00000000..258dc014 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/devices/XPSDevice.java @@ -0,0 +1,9 @@ +package com.artifex.gsjava.devices; + +public class XPSDevice extends FileDevice implements HighLevelDevice { + + public XPSDevice() throws IllegalStateException, DeviceNotSupportedException, DeviceInUseException { + super("xpswrite"); + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/AllocationError.java b/demos/java/gsjava/src/com/artifex/gsjava/util/AllocationError.java new file mode 100644 index 00000000..d2f6c99f --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/AllocationError.java @@ -0,0 +1,33 @@ +package com.artifex.gsjava.util; + +/** + * An error thrown when native memory allocation fails. + * + * @author Ethan Vrhel + * + */ +public class AllocationError extends Error { + + private static final long serialVersionUID = 1L; + + public AllocationError() { + super(); + } + + public AllocationError(String message) { + super(message); + } + + public AllocationError(String message, Throwable cause) { + super(message, cause); + } + + public AllocationError(Throwable cause) { + super(cause); + } + + protected AllocationError(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/ByteArrayReference.java b/demos/java/gsjava/src/com/artifex/gsjava/util/ByteArrayReference.java new file mode 100644 index 00000000..1638bb95 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/ByteArrayReference.java @@ -0,0 +1,23 @@ +package com.artifex.gsjava.util; + +/** + * Stores a reference to a byte array. + * + * @author Ethan Vrhel + * + */ +public class ByteArrayReference extends Reference { + + public ByteArrayReference() { + super(); + } + + public ByteArrayReference(final byte[] value) { + super(value); + } + + public String asString() { + byte[] val = getValue(); + return val == null ? "null" : new String(val); + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/BytePointer.java b/demos/java/gsjava/src/com/artifex/gsjava/util/BytePointer.java new file mode 100644 index 00000000..8b63254e --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/BytePointer.java @@ -0,0 +1,68 @@ +package com.artifex.gsjava.util; + +/** + * A byte pointer stores a pointer to a memory location containing + * bytes. + * + * @author Ethan Vrhel + * + */ +public class BytePointer extends NativePointer implements NativeArray { + + private long length; + + public BytePointer() { + super(); + this.length = 0; + } + + @Override + public void allocate(long length) throws IllegalStateException, AllocationError { + calloc(length, BYTE_SIZE); + this.length = length; + } + + @Override + public void set(long index, Byte value) throws IndexOutOfBoundsException, NullPointerException { + final long address = getAddress(); + if (address == NULL) + throw new NullPointerException("address is null"); + if (index < 0 || index >= length) + throw new IndexOutOfBoundsException(new StringBuilder().append("index: ").append(index).toString()); + setByteNative(address, index, value); + } + + @Override + public Byte at(long index) throws IndexOutOfBoundsException, NullPointerException { + final long address = getAddress(); + if (address == NULL) + throw new NullPointerException("address is null"); + if (index < 0 || index >= length) + throw new IndexOutOfBoundsException(new StringBuilder().append("index: ").append(index).toString()); + return byteAtNative(address, index); + } + + @Override + public Byte[] toArray() throws NullPointerException { + byte[] byteArray = (byte[])toArrayNoConvert(); + Byte[] bArray = new Byte[byteArray.length]; + int i = 0; + for (byte b : byteArray) + bArray[i++] = b; + return bArray; + } + + @Override + public Object toArrayNoConvert() throws NullPointerException { + final long address = getAddress(); + if (address == NULL) + throw new NullPointerException("address is null"); + return byteArrayNative(address, length); + } + + @Override + public long length() { + return length; + } + +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/NativeArray.java b/demos/java/gsjava/src/com/artifex/gsjava/util/NativeArray.java new file mode 100644 index 00000000..0ea059c1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/NativeArray.java @@ -0,0 +1,67 @@ +package com.artifex.gsjava.util; + +/** + * A NativeArray is an natively allocated array with a set length. + * + * @author Ethan Vrhel + * + * @param The type stored in the array. + */ +public interface NativeArray { + + /** + * Allocates the array of length length. + * + * @param length The length of the array. + * @throws IllegalStateException When the memory has already been allocated. + * @throws AllocationError When the allocation fails. + */ + public void allocate(long length) throws IllegalStateException, AllocationError; + + /** + * Sets the value of an element in the array. + * + * @param index The index to set. + * @param value The value to set to. + * @throws IndexOutOfBoundsException When index is less than 0 or + * greater or equal to the length. + * @throws NullPointerException When the array has not been allocated and is null. + */ + public void set(long index, T value) throws IndexOutOfBoundsException, NullPointerException; + + /** + * Returns the value at an index. + * + * @param index The index to get the value from. + * @return The respective value. + * @throws IndexOutOfBoundsException When index is less than 0 or + * greater or equal to the length. + * @throws NullPointerException When the array has not been allocated and is null. + */ + public T at(long index) throws IndexOutOfBoundsException, NullPointerException; + + /** + * Converts the native array to a Java array. + * + * @return A copy of the native array. + * @throws NullPointerException When the array has not been allocated and is null. + */ + public T[] toArray() throws NullPointerException; + + /** + * Converts the native array to a Java array without creating a new array ensuring + * that an array of T's are returned. This will generally be faster + * than calling toArray(). + * + * @return A copy of the native array. + * @throws NullPointerException + */ + public Object toArrayNoConvert() throws NullPointerException; + + /** + * Returns the length of the array. + * + * @return The length. + */ + public long length(); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/NativePointer.java b/demos/java/gsjava/src/com/artifex/gsjava/util/NativePointer.java new file mode 100644 index 00000000..222ade80 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/NativePointer.java @@ -0,0 +1,157 @@ +package com.artifex.gsjava.util; + +/** + *

The NativePointer class allows for direct non-managed memory + * allocations. The purpose of this class is to provide direct access + * to memory blocks.

+ * + *

An instance of the class is safe in the sense that + * no memory can be accessed that is filled with junk which has been + * freed, and a check is performed so that in the worst case scenario, + * only a Java exception will be thrown. However, an instance of the + * class can cause memory leaks if not used correctly as garbage collecting + * the object will not free the memory natively, so it will need to be + * maintained.

+ * + *

This class also contains several native methods which can be used + * for slightly faster native access to unmanaged memory. These methods + * are considered unsafe, and for read/write access to the memory, + * an implementation NativeArray should be used.. + * + * @author Ethan Vrhel + * + */ +public class NativePointer { + + static { + registerLibraries(); + } + + /** + * Registers the needed native libraries. + */ + private static void registerLibraries() { + System.loadLibrary("gs_jni"); + } + + public static final long NULL = 0x0L; + + public static final long BYTE_SIZE = 1L, + CHAR_SIZE = 2L, + SHORT_SIZE = 2L, + INT_SIZE = 4L, + LONG_SIZE = 8L; + + private long address; + + /** + * Constructs a null native pointer. + */ + public NativePointer() { + address = NULL; + } + + /** + * Allocates a memory block of size size. + * + * @param size The size of the block, in bytes. + * @throws IllegalStateException When this pointer already points to something. + * @throws AllocationError When the native allocation fails. + */ + public final void malloc(long size) throws IllegalStateException, AllocationError { + if (address != NULL) { + throw new IllegalStateException("Memory already allocated."); + } + this.address = mallocNative(size); + } + + /** + * Allocates an block of size count * size with each + * byte initialized to 0. + * + * @param count The number of elements to allocated. + * @param size The size of each element, in bytes. + * @throws IllegalStateException When this pointer already points to something. + * @throws AllocationError When the native allocation fails. + */ + public final void calloc(long count, long size) throws IllegalStateException, AllocationError { + if (address != NULL) { + throw new IllegalStateException("Memory already allocated."); + } + this.address = callocNative(count, size); + } + + /** + * Frees the allocated block, if any has been allocated. + */ + public final void free() { + freeNative(address); + address = NULL; + } + + /** + * Returns the native address of this pointer. + * + * @return The native address. + */ + public final long getAddress() { + return address; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof NativePointer) { + return address == ((NativePointer)o).address; + } + return false; + } + + @Override + public String toString() { + return new StringBuilder().append("0x").append(Long.toHexString(address)).toString(); + } + + @Override + public int hashCode() { + return (int)address; + } + + private static native long mallocNative(long size) throws AllocationError; + + private static native long callocNative(long count, long size) throws AllocationError; + + private static native void freeNative(long block); + + + public static native byte[] byteArrayNative(long address, long len); + + public static native byte byteAtNative(long address, long index); + + public static native void setByteNative(long address, long index, byte value); + + public static native char[] charArrayNative(long address, long len); + + public static native char charAtNative(long address, long index); + + public static native void setCharNative(long address, long index, char value); + + public static native short[] shortArrayNative(long address, long len); + + public static native short shortAtNative(long address, long index); + + public static native void setShortNative(long address, long index, short value); + + public static native int[] intArrayNative(long address, long len); + + public static native int intAtNative(long address, long index); + + public static native void setIntNative(long address, long index, int value); + + public static native long[] longArrayNative(long address, long len); + + public static native long longAtNative(long address, long index); + + public static native void setLongNative(long address, long index, long value); +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/Reference.java b/demos/java/gsjava/src/com/artifex/gsjava/util/Reference.java new file mode 100644 index 00000000..38a34ac1 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/Reference.java @@ -0,0 +1,45 @@ +package com.artifex.gsjava.util; + +public class Reference { + + private volatile T value; + + public Reference() { + this(null); + } + + public Reference(T value) { + this.value = value; + } + + public void setValue(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (o == this) + return true; + if (o instanceof Reference) { + Reference ref = (Reference)o; + return value == null ? ref.value == null : value.equals(ref.value); + } + return false; + } + + @Override + public int hashCode() { + return value == null ? 0 : value.hashCode(); + } + + @Override + public String toString() { + return "Reference<" + (value == null ? "?" : value.getClass().getName()) + "> -> " + value; + } +} diff --git a/demos/java/gsjava/src/com/artifex/gsjava/util/StringUtil.java b/demos/java/gsjava/src/com/artifex/gsjava/util/StringUtil.java new file mode 100644 index 00000000..0183ad81 --- /dev/null +++ b/demos/java/gsjava/src/com/artifex/gsjava/util/StringUtil.java @@ -0,0 +1,41 @@ +package com.artifex.gsjava.util; + +/** + * Contains utility methods to work with Strings. + * + * @author Ethan Vrhel + * + */ +public class StringUtil { + + /** + * Converts a Java String to a null-terminated byte array. + * + * @param str The string to convert. + * @return The result byte array. + */ + public static byte[] toNullTerminatedByteArray(final String str) { + final byte[] barray = str.getBytes(); + final byte[] result = new byte[barray.length + 1]; + System.arraycopy(barray, 0, result, 0, barray.length); + return result; + } + + /** + * Converts an array of Strings to a 2D byte array of null-terminated + * strings. + * + * @param strs The strings to convert. + * @return THe result 2D byte array. + */ + public static byte[][] to2DByteArray(final String[] strs){ + final byte[][] array = new byte[strs.length][]; + for (int i = 0; i < strs.length; i++) { + final String str = strs[i]; + array[i] = toNullTerminatedByteArray(str); + } + return array; + } + + private StringUtil() { } +} diff --git a/demos/java/gstest/.classpath b/demos/java/gstest/.classpath new file mode 100644 index 00000000..6d2a9e96 --- /dev/null +++ b/demos/java/gstest/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/demos/java/gstest/.project b/demos/java/gstest/.project new file mode 100644 index 00000000..b40f0f4f --- /dev/null +++ b/demos/java/gstest/.project @@ -0,0 +1,17 @@ + + + gstest + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/demos/java/gstest/src/gstest/Main.java b/demos/java/gstest/src/gstest/Main.java new file mode 100644 index 00000000..ad5b0fb1 --- /dev/null +++ b/demos/java/gstest/src/gstest/Main.java @@ -0,0 +1,41 @@ +package gstest; + +import static com.artifex.gsjava.GSAPI.*; + +import com.artifex.gsjava.GSInstance; +import com.artifex.gsjava.util.NativePointer; +import com.artifex.gsjava.util.Reference; + + +public class Main { + + public static void main(String[] args) throws Exception { + + GSInstance instance = new GSInstance(); + instance.set_arg_encoding(1); + + String[] gsargs = new String[] { + "gs", + "-sDEVICE=pngalpha", + "-r100" + }; + + instance.init_with_args(gsargs); + + Reference aaRef = new Reference<>(); + instance.get_param_once("TextAlphaBits", aaRef, GS_SPT_INT); + System.out.println("TextAlphaBits=" + aaRef.getValue()); + + instance.set_param("TextAlphaBits", 1, GS_SPT_INT); + + NativePointer value = new NativePointer(); + int bytes = instance.get_param("TextAlphaBits", NativePointer.NULL, GS_SPT_INT); + value.malloc(bytes); + instance.get_param("TextAlphaBits", value.getAddress(), GS_SPT_INT); + int val = NativePointer.intAtNative(value.getAddress(), 0); + System.out.println(val); + value.free(); + + instance.delete_instance(); + } +} diff --git a/demos/java/gsviewer/.classpath b/demos/java/gsviewer/.classpath new file mode 100644 index 00000000..3ad142b6 --- /dev/null +++ b/demos/java/gsviewer/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/demos/java/gsviewer/.project b/demos/java/gsviewer/.project new file mode 100644 index 00000000..5b8f7395 --- /dev/null +++ b/demos/java/gsviewer/.project @@ -0,0 +1,17 @@ + + + gsviewer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/demos/java/gsviewer/README.txt b/demos/java/gsviewer/README.txt new file mode 100644 index 00000000..885edf1f --- /dev/null +++ b/demos/java/gsviewer/README.txt @@ -0,0 +1,4 @@ +required libraries in this directory: +gpdldll64.dll +gs_jni.dll +gsjava.jar \ No newline at end of file diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/DefaultUnhandledExceptionHandler.java b/demos/java/gsviewer/src/com/artifex/gsviewer/DefaultUnhandledExceptionHandler.java new file mode 100644 index 00000000..2074b05b --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/DefaultUnhandledExceptionHandler.java @@ -0,0 +1,107 @@ +package com.artifex.gsviewer; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Enumeration; +import java.util.Properties; + +/** + * The default unhandled exception handler. This will handle exceptions which + * are not caught in a try/catch block and print an error message to + * System.err and a log file. + * + * @author Ethan Vrhel + * + */ +public class DefaultUnhandledExceptionHandler implements Thread.UncaughtExceptionHandler { + + /** + * An instance of the exception handler. + */ + public static final DefaultUnhandledExceptionHandler INSTANCE; + + static { + INSTANCE = new DefaultUnhandledExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(INSTANCE); + } + + private DefaultUnhandledExceptionHandler() { } + + @Override + public void uncaughtException(Thread t, Throwable e) { + StringBuilder builder = new StringBuilder(); + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); + builder.append("Unhandled exception!\n"); + + // Print the time of the error + builder.append("Time: " + dtf.format(LocalDateTime.now()) + "\n\n"); + + // Print all system properties + builder.append("PROPERTIES\n"); + Properties props = System.getProperties(); + for (Enumeration keys = props.keys(); keys.hasMoreElements();) { + String key = keys.nextElement().toString(); + String prop = props.getProperty(key); + String friendly = "\""; + for (int i = 0; i < prop.length(); i++) { + char c = prop.charAt(i); + switch (c) { + case '\n': + friendly += "\\n"; + break; + case '\r': + friendly += "\\r"; + break; + default: + friendly += c; + break; + } + } + friendly += "\""; + builder.append(key + " = " + friendly + "\n"); + } + builder.append('\n'); + + // Print the stack trace of the error + builder.append("EXCEPTION\n"); + builder.append("Exception: " + e.getClass().getName() + "\n"); + builder.append("Message: " + e.getMessage() + "\n"); + builder.append("Cause: " + (e.getCause() == null ? "[Unknown]" : + e.getCause().getClass().getName()) + "\n"); + builder.append("Thread: " + t.getName() + " (id=" + t.getId() + ")\n"); + builder.append("Stack trace:" + "\n"); + builder.append(stackTraceToString(e)); + + // Write to System.err and a log file + String fullMessage = builder.toString(); + System.err.println(fullMessage); + try { + PrintStream out = new PrintStream(new FileOutputStream("error.log")); + out.println(fullMessage); + out.close(); + } catch (FileNotFoundException e1) { + System.err.println("Failed to write to log file"); + } + + // Close the program + System.exit(1); + } + + /** + * Converts a stack trace to a string. + * + * @param e The Throwable whose stack trace should be converted. + * @return The stack trace as a string. + */ + private String stackTraceToString(Throwable e) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(os); + e.printStackTrace(out); + return new String(os.toByteArray()); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java new file mode 100644 index 00000000..6000d3e4 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Document.java @@ -0,0 +1,1075 @@ +package com.artifex.gsviewer; + +import static com.artifex.gsjava.GSAPI.*; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Objects; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import com.artifex.gsjava.GSInstance; +import com.artifex.gsjava.callbacks.DisplayCallback; +import com.artifex.gsjava.util.BytePointer; +import com.artifex.gsjava.util.Reference; +import com.artifex.gsviewer.ImageUtil.ImageParams; + +import sun.misc.Unsafe; + +/** + *

A Document stores an ordered list of Pages. This class implements + * java.util.List, so it inherits all of a list's capabilities, + * such as the ability to iterate over the document.

+ * + *

The Document class also handles loading of pages through Ghostcript + * and ensuring that two Ghostscript operations are not running at the + * same time.

+ * + * @author Ethan Vrhel + * + */ +public class Document implements List { + + private static final DocumentLoader documentLoader = new DocumentLoader(); // The document loader + private static final int format = GS_COLORS_RGB | GS_DISPLAY_DEPTH_8 | GS_DISPLAY_BIGENDIAN; // Format + + private static final ReentrantLock operationLock = new ReentrantLock(); // The operation lock + private static final Condition operationCv = operationLock.newCondition(); // The operation condition variable + private static volatile boolean operationInProgress = false; // Whether an operation is in progress + + private static GSInstance gsInstance = null; + + /** + * Asynchronous execution dispatch returns. + */ + public static final int ASYNC_DISPATCH_OK = 0, ASYNC_DISPATCH_OPERATION_IN_PROGRESS = 1; + + /** + * Operation mode indicating the method should wait until a running operation has finished. + */ + public static final int OPERATION_WAIT = 0; + + /** + * Operation mode indicating the method should immediately return if an operation is already + * running. + */ + public static final int OPERATION_RETURN = 1; + + /** + * Operation mode indicating the method should throw an OperationInProgressException + * if an operation is already running. + */ + public static final int OPERATION_THROW = 2; + + /** + * Loads a document on a separate thread. + * + * @param file The file to load. + * @param cb The callback when loading the document has finished. + * @param dlb The callback signifying when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return ASYNC_DISPATCH_OPERATION_IN_PROGRESS, or + * OPERATION_THROW meaning the loader should throw an + * OperationInProgressException. + * + * @return The state of the thread dispatching. This is either ASYNC_DISPATCH_OK + * or ASYNC_DISPATCH_OPERATION_IN_PROGRESS which is also dependent on + * operationMode. + * + * @throws NullPointerException When cb is null. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When operationMode is not + * OPERTAION_WAIT, OPERATION_RETURN, or OPERATION_THROW. + * @throws OperationInProgressException When an operation is in progress and + * operationMode is OPERATION_THROW. + */ + public static int loadDocumentAsync(final File file, final DocAsyncLoadCallback cb, + final DocLoadProgressCallback dlb, final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException, + OperationInProgressException { + if (!handleOperationMode(operationMode)) + return ASYNC_DISPATCH_OPERATION_IN_PROGRESS; + + Objects.requireNonNull(cb, "DocAsyncLoadCallback"); + final Thread t = new Thread(() -> { + Document doc = null; + Exception exception = null; + try { + doc = new Document(file, dlb, operationMode); + } catch (FileNotFoundException | IllegalStateException | NullPointerException e) { + exception = e; + } + cb.onDocumentLoad(doc, exception); + }); + t.setName("Document-Loader-Thread"); + t.setDaemon(true); + t.start(); + return ASYNC_DISPATCH_OK; + } + + /** + * Loads a document on a separate thread. + * + * @param file The file to load. + * @param cb The callback when loading the document has finished. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return ASYNC_DISPATCH_OPERATION_IN_PROGRESS, or + * OPERATION_THROW meaning the loader should throw an + * OperationInProgressException. + * + * @return The state of the thread dispatching. This is either ASYNC_DISPATCH_OK + * or ASYNC_DISPATCH_OPERATION_IN_PROGRESS which is also dependent on + * operationMode. + * + * @throws NullPointerException When cb is null. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When operationMode is not + * ASYNC_OPERTAION_WAIT or ASYNC_OPERATION_RETURN. + */ + public static int loadDocumentAsync(final File file, final DocAsyncLoadCallback cb, + final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException { + return loadDocumentAsync(file, cb, null, operationMode); + } + + /** + * Loads a document on a separate thread. + * + * @param filename The name of the file to load. + * @param cb The callback when loading the document has finished. + * @param dlb The callback signifying when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return ASYNC_DISPATCH_OPERATION_IN_PROGRESS, or + * OPERATION_THROW meaning the loader should throw an + * OperationInProgressException. + * + * @return The state of the thread dispatching. This is either ASYNC_DISPATCH_OK + * or ASYNC_DISPATCH_OPERATION_IN_PROGRESS which is also dependent on + * operationMode. + * + * @throws NullPointerException When cb is null. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When operationMode is not + * ASYNC_OPERTAION_WAIT or ASYNC_OPERATION_RETURN. + */ + public static int loadDocumentAsync(final String filename, final DocAsyncLoadCallback cb, + final DocLoadProgressCallback dlb, final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException { + return loadDocumentAsync(new File(filename), cb, dlb, operationMode); + } + + /** + * Loads a document on a separate thread. + * + * @param filename The name of the file to load. + * @param cb The callback when loading the document has finished. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return ASYNC_DISPATCH_OPERATION_IN_PROGRESS, or + * OPERATION_THROW meaning the loader should throw an + * OperationInProgressException. + * + * @return The state of the thread dispatching. This is either ASYNC_DISPATCH_OK + * or ASYNC_DISPATCH_OPERATION_IN_PROGRESS which is also dependent on + * operationMode. + * + * @throws NullPointerException When cb is null. + * @throws RuntimeException When the current thread fails to wait until a thread has finished + * completing an operation. + * @throws IllegalArgumentException When operationMode is not + * ASYNC_OPERTAION_WAIT or ASYNC_OPERATION_RETURN. + */ + public static int loadDocumentAsync(final String filename, final DocAsyncLoadCallback cb, + final int operationMode) + throws NullPointerException, RuntimeException, IllegalArgumentException { + return loadDocumentAsync(filename, cb, null, operationMode); + } + + /** + * Returns whether a file should being distilled to a PDF before loading. Also tests + * to make sure that the supplied file is a file type that can be loaded into the viewer. + * If the file cannot be loaded into the viewer, an IllegalArgumentException + * is thrown. + * + * @param file The file to test. + * @return true if the file should be distilled or false + * if it should not. + * @throws FileNotFoundException If file does not exist. + * @throws IllegalArgumentException If file is not a document which can + * be loaded into the viewer. + * @throws NullPointerException If file is null. + */ + public static boolean shouldDistill(File file) + throws FileNotFoundException, IllegalArgumentException, NullPointerException { + if (!Objects.requireNonNull(file, "file is null").exists()) + throw new FileNotFoundException("File does not exist."); + String path = file.getAbsolutePath(); + int extensionInd = path.lastIndexOf('.'); + if (extensionInd == -1 || !GSFileFilter.INSTANCE.accept(file)) + throw new IllegalArgumentException("Invalid file type"); + String extension = path.substring(extensionInd); + return !extension.equalsIgnoreCase(".pdf"); + } + + /** + * Distills a document into a PDF. + * + * @param input The input file to distill. + * @param out The output file to write to. If the file does not exist, it will be + * created. If this is null, a temporary file will be created. + * @return The file which was written to. + * @throws IOException When a file fails to be created. + * @throws FileNotFoundException When input does not exist. + * @throws IllegalStateException When the file fails to be distilled. + */ + public static File distillDocument(File input, File out) throws IOException, FileNotFoundException, IllegalStateException { + if (gsInstance != null) + throw new IllegalStateException("gsInstance is non-null"); + + if (!input.exists()) + throw new FileNotFoundException(input.getAbsolutePath()); + + out = out == null ? File.createTempFile(input.getName() + ".pdf", null) : out; + if (!out.exists()) + out.createNewFile(); + + try { + int code = initGSInstance( + "gs", + "-sDEVICE=pdfwrite", + "-dFirstPage=1", + "-dDisplayFormat=" + format, + "-o", out.getAbsolutePath(), + "-f", input.getAbsolutePath() + ); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to distill document (code = " + code + ")"); + } finally { + deleteGSInstance(); + } + return out; + } + + /** + * Call, internally, on the start of an operation. + */ + private static void startOperation() { + operationInProgress = true; + } + + /** + * Call, internally, on the start of an operation, before startOperation(). + * + * @param operationMode The operation mode. + * @return Whether the calling function should continue to its operation. + * @throws OperationInProgressException When an operation is in progress and operationMode + * is OPERATION_THROW. This should not be caught by the calling function, who should + * throw it instead. + * @throws IllegalArgumentException When operationMode is not a valid operation mode. + */ + private static boolean handleOperationMode(final int operationMode) + throws OperationInProgressException, IllegalArgumentException { + if (operationInProgress && operationMode == OPERATION_RETURN) + return false; + else if (operationInProgress && operationMode == OPERATION_THROW) { + StackTraceElement[] elems = new Exception().getStackTrace(); + throw new OperationInProgressException(elems[1].getClassName() + "." + elems[1].getMethodName()); + } else if (operationInProgress && operationMode == OPERATION_WAIT) + waitForOperation(); + else if (operationInProgress) + throw new IllegalArgumentException("Unknown operation mode: " + operationMode); + return true; + } + + /** + * Called internally by handleOperationMode(). Waits for an operation + * to finish. + */ + private static void waitForOperation() { + operationLock.lock(); + try { + operationCv.await(); + } catch (InterruptedException e) { + throw new RuntimeException("Thread interrupted", e); + } finally { + operationLock.unlock(); + } + } + + /** + * Call, internally, when an operation is done. + */ + private static void operationDone() { + operationLock.lock(); + operationInProgress = false; + try { + operationCv.signal(); + } finally { + operationLock.unlock(); + } + } + + @FunctionalInterface + public static interface DocAsyncLoadCallback { + + /** + * Called when a document has finished loading on a separate + * thread. + * + * @param doc The document which was loaded. null if the document + * failed to load. + * @param exception An exception that ocurred while loading, null + * if no exception was thrown. + */ + public void onDocumentLoad(Document doc, Exception exception); + } + + @FunctionalInterface + public static interface DocLoadProgressCallback { + + /** + * Called when the document has made progress while loading. + * + * @param progress The amount of progress (from 0 to 100). + */ + public void onDocumentProgress(int progress); + } + + /** + * Exception indicating an operation is already in progress. + * + * @author Ethan Vrhel + * + */ + public static final class OperationInProgressException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public OperationInProgressException(String message) { + super(message); + } + } + + /** + * Initializes a new instance of ghostscript. + * + * @param args The arguments for init_with_args. + * @return The return code of init_with_args. + * @throws IllegalStateException When any return code of a Ghostscript call is + * not GS_ERROR_OK. + */ + private static int initGSInstance(String... args) throws IllegalStateException { + deleteGSInstance(); + + GSInstance instance = new GSInstance(); + + int code; + code = instance.set_arg_encoding(1); + if (code != GS_ERROR_OK) { + instance.delete_instance(); + throw new IllegalStateException("Failed to set arg encoding (code = " + code + ")"); + } + + code = instance.set_display_callback(documentLoader.reset()); + if (code != GS_ERROR_OK) { + instance.delete_instance(); + throw new IllegalStateException("Failed to set display callback (code = " + code + ")"); + } + + code = instance.init_with_args(args); + if (code != GS_ERROR_OK) { + instance.delete_instance(); + throw new IllegalStateException("Failed to init with args (code = " + code + ")"); + } + + gsInstance = instance; + return code; + } + + /** + * Deletes the current instance of Ghostscript. + */ + private static void deleteGSInstance() { + if (gsInstance != null) { + gsInstance.exit(); + gsInstance.delete_instance(); + gsInstance = null; + } + } + + /** + * Sets Ghostscript parameters. + * + * @param dpi The dpi to set. + * @param startPage The start page to set. + * @param lastPage The last page to set. + * @throws NullPointerException When the Ghostscript instance is null. + * @throws IllegalStateException When any Ghostscript call does not return GS_ERROR_OK. + */ + private static void setParams(int dpi, int startPage, int lastPage) throws NullPointerException, IllegalStateException { + if (gsInstance == null) + throw new NullPointerException("gsInstance is null"); + + int code = gsInstance.set_param("HWResolution", Page.toDPIString(dpi), GS_SPT_PARSED); + if (code != GS_ERROR_OK) { + operationDone(); + throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")"); + } + + code = gsInstance.set_param("FirstPage", startPage, GS_SPT_INT); + if (code != GS_ERROR_OK) { + operationDone(); + throw new IllegalStateException("Failed to set dFirstPage (code = " + code + ")"); + } + + code = gsInstance.set_param("LastPage", lastPage, GS_SPT_INT); + if (code != GS_ERROR_OK) { + operationDone(); + throw new IllegalStateException("Failed to set dEndPage (code = " + code + ")"); + } + } + + /** + * Class which handles loading a Document. + * + * @author Ethan Vrhel + * + */ + private static class DocumentLoader extends DisplayCallback { + private int pageWidth, pageHeight, pageRaster; + private BytePointer pimage; + private List images; + private int progress; + private DocLoadProgressCallback callback; + + DocumentLoader() { + reset(); + } + + /** + * Resets the DcumentLoader to its default values. + * + * @return this. + */ + DocumentLoader reset() { + this.pageWidth = 0; + this.pageHeight = 0; + this.pageRaster = 0; + this.pimage = null; + this.images = new LinkedList<>(); + this.progress = 0; + this.callback = null; + return this; + } + + @Override + public int onDisplayPresize(long handle, long device, int width, int height, int raster, int format) { + return 0; + } + + @Override + public int onDisplaySize(long handle, long device, int width, int height, int raster, int format, + BytePointer pimage) { + this.pageWidth = width; + this.pageHeight = height; + this.pageRaster = raster; + this.pimage = pimage; + return 0; + } + + @Override + public int onDisplayPage(long handle, long device, int copies, boolean flush) { + byte[] data = (byte[]) pimage.toArrayNoConvert(); + images.add(ImageUtil.createImage(data, new ImageParams(pageWidth, pageHeight, pageRaster, BufferedImage.TYPE_3BYTE_BGR))); + + progress += (100 - progress) / 2; + if (callback != null) + callback.onDocumentProgress(progress); + + return 0; + } + + @Override + public void finalize() { + System.err.println("WARNING: The document loader has been freed by the Java VM"); + } + } + + private File file; + private List pages; + + /** + * Creates and loads a new document. + * + * @param file The file to load. + * @param loadCallback The callback to indicate when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return, or OPERATION_THROW meaning the loader + * should throw an OperationInProgressException. + * + * @throws FileNotFoundException When file does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When file is null. + * @throws OperationInProgressException When an operation is already in progress + * and operationMode is OPERATION_THROW. + * @throws IllegalArgumentException When operationMode is not + * OPERATION_WAIT, OPERATION_RETURN, or OPERATION_THROW. + */ + public Document(final File file, final DocLoadProgressCallback loadCallback, int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException, IllegalArgumentException { + this.file = Objects.requireNonNull(file, "file"); + if (!file.exists()) + throw new FileNotFoundException(file.getAbsolutePath()); + + if (!handleOperationMode(operationMode)) + return; + + try { + + startOperation(); + + int code = initGSInstance( + "gs", + "-sDEVICE=display", + "-dFirstPage=1", + "-dDisplayFormat=" + format + ); + + if (gsInstance == null) + throw new IllegalStateException("Failed to initialize Ghostscript"); + + documentLoader.callback = loadCallback; + + + code = gsInstance.set_param("HWResolution", Page.toDPIString(Page.PAGE_LOW_DPI), GS_SPT_PARSED); + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to set HWResolution (code = " + code + ")"); + + Reference exitCode = new Reference<>(); + code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + boolean aa = Settings.SETTINGS.getSetting("antialiasing"); + if (aa) { + gsInstance.set_param("TextAlphaBits", 4, GS_SPT_INT); + gsInstance.set_param("GraphicsAlphaBits", 4, GS_SPT_INT); + } else { + gsInstance.set_param("TextAlphaBits", 0, GS_SPT_INT); + gsInstance.set_param("GraphicsAlphaBits", 0, GS_SPT_INT); + } + + this.pages = new ArrayList<>(documentLoader.images.size()); + for (BufferedImage img : documentLoader.images) { + pages.add(new Page(img)); + } + + if (documentLoader.callback != null) + documentLoader.callback.onDocumentProgress(100); + } finally { + operationDone(); + } + } + + /** + * Creates and loads a document from a filename. + * + * @param file The file to load. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return, or OPERATION_THROW meaning the loader + * should throw an OperationInProgressException. + * + * @throws FileNotFoundException When file does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When file is null. + * @throws OperationInProgressException When an operation is already in progress + * and operationMode is OPERATION_THROW. + * @throws IllegalArgumentException When operationMode is not + * OPERATION_WAIT, OPERATION_RETURN, or OPERATION_THROW. + */ + public Document(final File file, final int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException { + this(file, null, operationMode); + } + + /** + * Creates and loads a document from a filename. + * + * @param filename The name of the file to load. + * @param loadCallback The callback to indicate when progress has occurred while loading. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return, or OPERATION_THROW meaning the loader + * should throw an OperationInProgressException. + * + * @throws FileNotFoundException When file does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When file is null. + * @throws OperationInProgressException When an operation is already in progress + * and operationMode is OPERATION_THROW. + * @throws IllegalArgumentException When operationMode is not + * OPERATION_WAIT, OPERATION_RETURN, or OPERATION_THROW. + */ + public Document(final String filename, final DocLoadProgressCallback loadCallback, + final int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException { + this(new File(Objects.requireNonNull(filename, "filename")), loadCallback, operationMode); + } + + /** + * Creates and loads a document from a filename. + * + * @param filename The name of the file to load. + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return, or OPERATION_THROW meaning the loader + * should throw an OperationInProgressException. + * + * @throws FileNotFoundException When filename does not exist. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws NullPointerException When filename is null. + * @throws OperationInProgressException When an operation is already in progress + * and operationMode is OPERATION_THROW. + * @throws IllegalArgumentException When operationMode is not + * OPERATION_WAIT, OPERATION_RETURN, or OPERATION_THROW. + */ + public Document(final String filename, final int operationMode) + throws FileNotFoundException, IllegalStateException, NullPointerException, + OperationInProgressException { + this(filename, null, operationMode); + } + + /** + * Loads the high resolution images in a range of images. + * + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return, or OPERATION_THROW meaning the loader + * should throw an OperationInProgressException. + * @param startPage The first page to load. + * @param endPage The end page to load. + * + * @throws IndexOutOfBoundsException When firstPage or endPage + * are not in the document or endPage is less than firstPage. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + */ + public void loadHighRes(int operationMode, int startPage, int endPage) + throws IndexOutOfBoundsException, IllegalStateException { + checkBounds(startPage, endPage); + + if (!handleOperationMode(operationMode)) + return; + + try { + startOperation(); + + documentLoader.images.clear(); + + setParams(Page.PAGE_HIGH_DPI, startPage, endPage); + + Reference exitCode = new Reference<>(); + int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + if (documentLoader.images.size() != endPage - startPage + 1) { + throw new IllegalStateException("Page range mismatch (expected " + + (endPage - startPage) + ", got " + documentLoader.images.size() + ")"); + } + + int ind = startPage - 1; + for (final BufferedImage img : documentLoader.images) { + this.pages.get(ind++).setHighRes(img); + } + } finally { + operationDone(); + } + } + + /** + * Loads the high resolution image of a singular page. + * + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return, or OPERATION_THROW meaning the loader + * should throw an OperationInProgressException. + * @param page The page to load. + * + * @throws IndexOutOfBoundsException When page is not in the document. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws OperationInProgressException When an operation is already in progress + * and operationMode is OPERATION_THROW. + * @throws IllegalArgumentException When operationMode is not + * OPERATION_WAIT, OPERATION_RETURN, or OPERATION_THROW. + */ + public void loadHighRes(int operationMode, int page) + throws IndexOutOfBoundsException, IllegalStateException, OperationInProgressException { + loadHighRes(operationMode, page, page); + } + + /** + * Unloads the high resolution images in a range of pages. + * + * @param startPage The start page to unload the high resolution image from. + * @param endPage The end page to unload the high resolution image from. + * + * @throws IndexOutOfBoundsException When startPage and endPage + * are outside document or endPage is less than startPage. + */ + public void unloadHighRes(int startPage, int endPage) throws IndexOutOfBoundsException { + checkBounds(startPage, endPage); + for (int i = startPage - 1; i < endPage; i++) { + pages.get(i).unloadHighRes(); + } + } + + /** + * Unloads a high resolution image at the given page. + * + * @param page The page to unload the high resolution image. + * + * @throws IndexOutOfBoundsException When page is not a page in the document. + */ + public void unloadHighRes(int page) throws IndexOutOfBoundsException { + unloadHighRes(page, page); + } + + /** + * Unloads the zoomed images for a range of pages. + * + * @param startPage The start page to unload. + * @param endPage The end page to unload. + * + * @throws IndexOutOfBoundsException When startPage and endPage + * are outside document or endPage is less than startPage. + */ + public void unloadZoomed(int startPage, int endPage) throws IndexOutOfBoundsException { + checkBounds(startPage, endPage); + for (int i = startPage; i < endPage; i++) { + pages.get(i).unloadZoomed(); + } + } + + /** + * Unloads a zoomed image for a page. + * + * @param page The page to unload. + * + * @throws IndexOutOfBoundsException When page is not in the document. + */ + public void unloadZoomed(int page) throws IndexOutOfBoundsException { + unloadZoomed(page, page); + } + + /** + * Unloads the document's resources. The document will be unusable after this + * call. + */ + public void unload() { + if (pages != null) + deleteGSInstance(); + + for (Page p : pages) { + p.unloadAll(); + } + pages.clear(); + pages = null; + } + + /** + * Returns the name of the document loaded. + * + * @return The name. + */ + public String getName() { + return file.getName(); + } + + /** + * Zooms the area around page page. The area around page + * is page - 1 to page + 1. The method will automatically + * handle if page - 1 or page + 1 are out of range. However, + * it does not handle if page is not in the document. + * + * @param operationMode How the loader should behave if an operation is already in + * progress. Can be OPERATION_WAIT, meaning the loader should + * wait until a running operation has finished, OPERATION_RETURN meaning + * the loader should immediately return, or OPERATION_THROW meaning the loader + * should throw an OperationInProgressException. + * @param page The page to load around. + * @param zoom The zoom of the pages. + * + * @throws IndexOutOfBoundsException When page is not in the document. + * @throws IllegalStateException When Ghostscript fails to initialize or load the document. + * @throws OperationInProgressException When an operation is already in progress + * and operationMode is OPERATION_THROW. + * @throws IllegalArgumentException When operationMode is not + * OPERATION_WAIT, OPERATION_RETURN, or OPERATION_THROW. + */ + public void zoomArea(final int operationMode, final int page, final double zoom) + throws IndexOutOfBoundsException { + checkBounds(page, page); + + if (!handleOperationMode(operationMode)) + return; + + try { + startOperation(); + + int start = page - 1; + start = start < 1 ? page : start; + int end = page + 1; + end = end > pages.size() ? page : end; + + documentLoader.images.clear(); + + setParams((int)(Page.PAGE_HIGH_DPI * zoom), start, end); + + Reference exitCode = new Reference<>(); + int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + int ind = start - 1; + for (final BufferedImage img : documentLoader.images) { + this.pages.get(ind++).setZoomed(img); + } + } finally { + operationDone(); + } + } + + public void zoomPage(final int operationMode, final int page, final double zoom) + throws IndexOutOfBoundsException { + checkBounds(page, page); + + if (!handleOperationMode(operationMode)) + return; + + try { + startOperation(); + + setParams((int)(Page.PAGE_HIGH_DPI * zoom), page, page); + + Reference exitCode = new Reference<>(); + int code = gsInstance.run_file(file.getAbsolutePath(), 0, exitCode); + + if (code != GS_ERROR_OK) + throw new IllegalStateException("Failed to run file (code = " + code + ")"); + + int ind = page - 1; + for (final BufferedImage img : documentLoader.images) { + this.pages.get(ind++).setZoomed(img); + } + + } finally { + operationDone(); + } + } + + /** + * Checks to make sure the pages start through + * end are in the document, and throws an + * IndexOutOfBoundsException if they are not. + * + * @param start The start page. + * @param end The end page. + * @throws IndexOutOfBoundsException When startPage and endPage + * are outside document or endPage is less than startPage. + */ + private void checkBounds(int start, int end) throws IndexOutOfBoundsException { + if (start < 1 || start > pages.size()) + throw new IndexOutOfBoundsException("start=" + start); + if (end < 1 || end > pages.size()) + throw new IndexOutOfBoundsException("end=" + end); + if (end < start) + throw new IndexOutOfBoundsException("end < start"); + } + + // Implementations of inherited methods from java.util.List. + + @Override + public int size() { + return pages.size(); + } + + @Override + public boolean isEmpty() { + return pages.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return pages.contains(o); + } + + @Override + public Iterator iterator() { + return pages.iterator(); + } + + @Override + public Object[] toArray() { + return pages.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return pages.toArray(a); + } + + @Override + public boolean add(Page e) { + return pages.add(e); + } + + @Override + public boolean remove(Object o) { + return pages.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return pages.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return pages.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + return pages.addAll(index, c); + } + + @Override + public boolean removeAll(Collection c) { + return pages.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return pages.retainAll(c); + } + + @Override + public void clear() { + pages.clear(); + } + + @Override + public Page get(int index) { + return pages.get(index); + } + + @Override + public Page set(int index, Page element) { + return pages.set(index, element); + } + + @Override + public void add(int index, Page element) { + pages.add(index, element); + } + + @Override + public Page remove(int index) { + return pages.remove(index); + } + + @Override + public int indexOf(Object o) { + return pages.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return pages.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return pages.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return pages.listIterator(index); + } + + @Override + public Document subList(int fromIndex, int toIndex) { + try { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe)unsafeField.get(null); + Document doc = (Document)unsafe.allocateInstance(Document.class); + doc.pages = pages.subList(fromIndex, toIndex); + doc.file = file; + return doc; + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException + | IllegalAccessException | InstantiationException e) { + throw new RuntimeException("Failed to create sublist: " + e); + } + } + + @Override + public String toString() { + return "Document[numPages=" + size() + "]"; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof Document) { + return pages.equals(((Document)o).pages); + } + return false; + } + + @Override + public int hashCode() { + return pages.hashCode(); + } + + @Override + protected void finalize() { + unload(); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/GSFileFilter.java b/demos/java/gsviewer/src/com/artifex/gsviewer/GSFileFilter.java new file mode 100644 index 00000000..85033c5a --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/GSFileFilter.java @@ -0,0 +1,50 @@ +package com.artifex.gsviewer; + +import java.io.File; + +import javax.swing.filechooser.FileFilter; + +/** + *

A file filter used for the file choose to only accept certain + * file extensions.

+ * + *

This file filter only accepts files of type ".pdf", ".eps", ".ps", + * ".xps", ".oxps", and ".bin"

+ * + * @author Ethan Vrhel + * + */ +public class GSFileFilter extends FileFilter { + + /** + * An instance of the file filter. + */ + public static final GSFileFilter INSTANCE = new GSFileFilter(); + + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + final String name = f.getName(); + final int ind = name.lastIndexOf('.'); + if (ind < 0) + return false; + final String ext = name.substring(ind); + return + equals(ext, ".pdf") || + equals(ext, ".eps") || + equals(ext, ".ps") || + equals(ext, ".xps") || + equals(ext, ".oxps") || + equals(ext, ".bin"); + } + + @Override + public String getDescription() { + return "Ghostscript Files"; + } + + private boolean equals(String extension, String compare) { + return extension.equalsIgnoreCase(compare); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/ImageUtil.java b/demos/java/gsviewer/src/com/artifex/gsviewer/ImageUtil.java new file mode 100644 index 00000000..3754d6f7 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/ImageUtil.java @@ -0,0 +1,45 @@ +package com.artifex.gsviewer; + +import java.awt.Point; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; + +public class ImageUtil { + + public static BufferedImage createImage(final byte[] data, final ImageParams params) { + final DataBuffer dataBuffer = new DataBufferByte(data, data.length); + final WritableRaster wraster = Raster.createInterleavedRaster(dataBuffer, params.width, + params.height, params.raster, 3, new int[] { 0, 1, 2 }, new Point()); + final ColorModel model = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), + new int[] { 8, 8, 8 }, false, false, ColorModel.OPAQUE, DataBuffer.TYPE_BYTE); + + return new BufferedImage(model, wraster, false, null); + } + + public static class ImageParams { + public int width; + public int height; + public int raster; + public int format; + + public ImageParams() { + this(0, 0, 0, 0); + } + + public ImageParams(final int width, final int height, final int raster, final int format) { + this.width = width; + this.height = height; + this.raster = raster; + this.format = format; + } + } + + private ImageUtil() { } + +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java new file mode 100644 index 00000000..beecdd3b --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Main.java @@ -0,0 +1,42 @@ +package com.artifex.gsviewer; + +import java.io.IOException; + +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import com.artifex.gsviewer.gui.ViewerWindow; + +public class Main { + + public static void main(String[] args) { + Runtime.getRuntime().addShutdownHook(new Thread(new Shutdown())); + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException + | UnsupportedLookAndFeelException e) { + System.err.println("Failed to set Look and Feel: " + e); + } + + ViewerWindow win = new ViewerWindow(new ViewerController()); + SwingUtilities.invokeLater(() -> { + win.setVisible(true); + }); + } + + private static class Shutdown implements Runnable { + + @Override + public void run() { + try { + Settings.SETTINGS.save(); + } catch (IOException e) { + System.err.println("Failed to write settings file"); + e.printStackTrace(); + } + } + + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java b/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java new file mode 100644 index 00000000..e7bd7046 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/PDFFileFilter.java @@ -0,0 +1,28 @@ +package com.artifex.gsviewer; + +import java.io.File; + +import javax.swing.filechooser.FileFilter; + +public class PDFFileFilter extends FileFilter { + + public static final PDFFileFilter INSTANCE = new PDFFileFilter(); + + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + String filename = f.getName(); + int ind = filename.lastIndexOf('.'); + if (ind == -1) + return false; + String ext = filename.substring(ind); + return ext.equalsIgnoreCase(".pdf"); + } + + @Override + public String getDescription() { + return "PDF Files"; + } + +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java new file mode 100644 index 00000000..a3435f56 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Page.java @@ -0,0 +1,359 @@ +package com.artifex.gsviewer; + +import java.awt.Dimension; +import java.awt.image.BufferedImage; +import java.util.Collection; +import java.util.HashSet; + +import com.artifex.gsviewer.ImageUtil.ImageParams; + +/** + * A Page represents an individual page within a Document. It stores a high resolution image, + * a low resolution preview image, and a zoomed image if the viewer is zoomed. + * + * @author Ethan Vrhel + * + */ +public class Page { + + /** + * The high-resolution DPI to use. + */ + public static final int PAGE_HIGH_DPI = 72; + + /** + * The low-resolution DPI to use. + */ + public static final int PAGE_LOW_DPI = 10; + + /** + * Converts a dpi value to a Ghostscript-friendly string. + * + * @param dpi The dpi to convert. + * @return The respective string. + */ + public static String toDPIString(int dpi) { + return "[" + dpi + " " + dpi + "]"; + } + + private volatile BufferedImage lowRes; // The low resolution image + private volatile BufferedImage highRes; // The high resolution image + private volatile BufferedImage zoomed; // The zoomed image based on the zoom of the viewer + + private Collection callbacks; // The page callbacks + + /** + * Creates a new page with now low-resolution or high-resolution image. + */ + public Page() { + this(null, null); + } + + /** + * Creates a new page with a low-resolution image. + * + * @param lowRes The low-resolution image. + */ + public Page(final BufferedImage lowRes) { + this(lowRes, null); + } + + /** + * Creates a new page with a low-resolution image and a high-resolution image. + * + * @param lowRes The low-resolution image. + * @param highRes The high-resolution image. + */ + public Page(final BufferedImage lowRes, final BufferedImage highRes) { + this.lowRes = lowRes; + this.highRes = highRes; + this.callbacks = new HashSet<>(); + } + + /** + * Loads a high resolution image from data. + * + * @param data The raw image data. + * @param width The width of the image. + * @param height The height of the image. + * @param raster The length of one line of the image in bytes. + * @param format The image format. + */ + public void loadHighRes(final byte[] data, final int width, final int height, final int raster, final int format) { + setHighRes(ImageUtil.createImage(data, new ImageParams(width, height, raster, format))); + } + + /** + * Sets the high resolution image + * + * @param highRes An image. + */ + public void setHighRes(final BufferedImage highRes) { + unloadHighRes(); + this.highRes = highRes; + for (PageUpdateCallback cb : callbacks) { + cb.onLoadHighRes(); + cb.onPageUpdate(); + } + } + + /** + * Unloads the high-resolution image. If none is loaded, this method + * does nothing. + */ + public void unloadHighRes() { + if (highRes != null) { + highRes.flush(); + highRes = null; + for (PageUpdateCallback cb : callbacks) { + cb.onUnloadHighRes(); + cb.onPageUpdate(); + } + } + } + + /** + * Loads a low resolution image from data. + * + * @param data The raw image data. + * @param width The width of the image. + * @param height The height of the image. + * @param raster The length of one line of the image in bytes. + * @param format The image format. + */ + public void loadLowRes(final byte[] data, final int width, final int height, final int raster, final int format) { + setLowRes(ImageUtil.createImage(data, new ImageParams(width, height, raster, format))); + } + + /** + * Sets the low resolution image + * + * @param lowRes An image. + */ + public void setLowRes(final BufferedImage lowRes) { + unloadLowRes(); + this.lowRes = lowRes; + for (PageUpdateCallback cb : callbacks) { + cb.onLoadLowRes(); + cb.onPageUpdate(); + } + } + + /** + * Unloads the low-resolution image. If none is loaded, this method + * does nothing. + */ + public void unloadLowRes() { + if (lowRes != null) { + lowRes.flush(); + lowRes = null; + for (PageUpdateCallback cb : callbacks) { + cb.onUnloadLowRes(); + cb.onPageUpdate(); + } + } + } + + /** + * Loads a zoomed image from data. + * + * @param data The raw image data. + * @param width The width of the image. + * @param height The height of the image. + * @param raster The length of one line of the image in bytes. + * @param format The image format. + */ + public void loadZoomed(final byte[] data, final int width, final int height, + final int raster, final int format) { + setZoomed(ImageUtil.createImage(data, new ImageParams(width, height, raster, format))); + } + + /** + * Sets the zoomed image + * + * @param zoomed An image. + */ + public void setZoomed(final BufferedImage zoomed) { + unloadZoomed(); + this.zoomed = zoomed; + for (PageUpdateCallback cb : callbacks) { + cb.onLoadZoomed(); + cb.onPageUpdate(); + } + } + + /** + * Unloads the zoomed image. If none is loaded, this method + * does nothing. + */ + public void unloadZoomed() { + if (zoomed != null) { + zoomed.flush(); + zoomed = null; + for (PageUpdateCallback cb : callbacks) { + cb.onUnloadZoomed(); + cb.onPageUpdate(); + } + } + } + + /** + * Unloads all images. If no images are loaded, this method + * does nothing. + */ + public void unloadAll() { + unloadLowRes(); + unloadHighRes(); + unloadZoomed(); + } + + /** + * Returns the current low-resolution image. + * + * @return The current low-resolution image, or null + * if none is loaded. + */ + public BufferedImage getLowResImage() { + return lowRes; + } + + /** + * Returns the current high-resolution image. + * + * @return The current high-resolution image, or null + * if none is loaded. + */ + public BufferedImage getHighResImage() { + return highRes; + } + + /** + * Returns the current zoomed image. + * + * @return The current zoomed image, or null + * if none is loaded. + */ + public BufferedImage getZoomedImage() { + return zoomed; + } + + /** + * Returns the non-zoomed highest resolution image which can be + * displayed. + * + * @return The highest resolution, non-zoomed image which can be + * displayed. If no non-zoomed images are loaded, null + * is returned. + */ + public BufferedImage getDisplayableImage() { + return highRes == null ? lowRes : highRes; + } + + /** + * Returns the size of the low-resolution image. + * + * @return The size of the low-resolution image, or null + * if it is not loaded. + */ + public Dimension getLowResSize() { + return lowRes == null ? null : new Dimension(lowRes.getWidth(), lowRes.getHeight()); + } + + /** + * Returns the size of the high-resolution image. + * + * @return The size of the high-resolution image, or null + * if it is not loaded. + */ + public Dimension getHighResSize() { + return highRes == null ? null : new Dimension(highRes.getWidth(), highRes.getHeight()); + } + + /** + * Returns the size of the zoomed image. + * + * @return The size of the zoomed image, or null + * if it is not loaded. + */ + public Dimension getZoomedSize() { + return zoomed == null ? null : new Dimension(zoomed.getWidth(), zoomed.getHeight()); + } + + /** + * Returns the size of the non-zoomed highest resolution image which + * can be displayed. + * + * @return The size of the highest resolution, non-zoomed image which + * can be displayed. If no non-zoomed images are loaded, null + * is returned. + */ + public Dimension getDisplayableSize() { + return highRes == null ? getLowResSize() : getHighResSize(); + } + + /** + * Returns the actual size of the image. + * + * @return The size of the page, or null if no images are + * loaded. + */ + public Dimension getSize() { + Dimension size = getHighResSize(); + if (size != null) + return size; + size = getLowResSize(); + if (size == null) + return new Dimension(0, 0); + return new Dimension(size.width * PAGE_HIGH_DPI / PAGE_LOW_DPI, + size.height * PAGE_HIGH_DPI / PAGE_LOW_DPI); + } + + /** + * Adds a PageUpdateCallback to receive callbacks regarding + * page change events. + * + * @param cb The callback to add. + */ + public void addCallback(PageUpdateCallback cb) { + callbacks.add(cb); + cb.onPageUpdate(); + } + + /** + * Removes a callback added through addCallback. If the supplied + * callback was not added, this method does nothing. + * + * @param cb The callback to remove. + */ + public void removeCallback(PageUpdateCallback cb) { + callbacks.remove(cb); + } + + @Override + public String toString() { + return "Page[lowResLoaded=" + (lowRes != null) + ",highResLoaded=" + (highRes != null) + "]"; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof Page) { + Page p = (Page)o; + boolean first = lowRes == null ? p.lowRes == null : lowRes.equals(p.lowRes); + boolean second = highRes == null ? p.highRes == null : highRes.equals(p.highRes); + return first && second; + } + return false; + } + + @Override + public int hashCode() { + return (lowRes == null ? 0 : lowRes.hashCode()) + (highRes == null ? 0 : highRes.hashCode()); + } + + @Override + public void finalize() { + unloadAll(); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/PageUpdateCallback.java b/demos/java/gsviewer/src/com/artifex/gsviewer/PageUpdateCallback.java new file mode 100644 index 00000000..6efaf69e --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/PageUpdateCallback.java @@ -0,0 +1,15 @@ +package com.artifex.gsviewer; + +public interface PageUpdateCallback { + + public void onPageUpdate(); + + public void onLoadLowRes(); + public void onUnloadLowRes(); + + public void onLoadHighRes(); + public void onUnloadHighRes(); + + public void onLoadZoomed(); + public void onUnloadZoomed(); +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/Settings.java b/demos/java/gsviewer/src/com/artifex/gsviewer/Settings.java new file mode 100644 index 00000000..13f6d6b7 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/Settings.java @@ -0,0 +1,142 @@ +package com.artifex.gsviewer; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +public class Settings { + + public static final String SETTINGS_FILE = "gsviewer.cfg"; + + public static final Settings SETTINGS; + + static { + SETTINGS = new Settings(SETTINGS_FILE); + } + + private Map settingsMap; + private String filename; + + private Settings(String filename) { + this.filename = filename; + this.settingsMap = new HashMap<>(); + loadDefaultSettings(); + + File f = new File(filename); + if (!f.exists()) + return; + + try { + InputStream in = new FileInputStream(filename); + int b; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + while ((b = in.read()) != -1) { + bout.write(b); + } + + in.close(); + bout.close(); + + byte[] array = bout.toByteArray(); + loadFromString(new String(array)); + } catch (IOException e) { + throw new IllegalStateException("Failed to load settings file: " + SETTINGS_FILE, e); + } + } + + private void loadDefaultSettings() { + putSetting("scrollSens", 50); + putSetting("preloadRange", 2); + putSetting("antialiasing", true); + } + + private void loadFromString(String data) { + String[] lines = data.split("\n"); + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + String[] tokens = line.split(" "); + if (tokens.length != 3) + throw new IllegalStateException("Malformed settings file (line " + (i + 1) + ")"); + try { + switch (tokens[0]) { + case "int": + putSetting(tokens[1], Integer.parseInt(tokens[2])); + break; + case "double": + putSetting(tokens[1], Double.parseDouble(tokens[2])); + break; + case "bool": + putSetting(tokens[1], Boolean.parseBoolean(tokens[2])); + break; + default: + throw new IllegalStateException("Invalid type specifier \"" + tokens[0] + "\" (line " + (i + 1) + ")"); + } + } catch (NumberFormatException e) { + throw new IllegalStateException("Invalid value \"" + tokens[2] + "\" for type " + + tokens[0] + " (line " + (i + 1) + ")", e); + } + } + } + + /** + * Returns the value of a setting of type name key. + * + * @param The type of setting stored. + * @param key The name of the setting. + * @return The respective setting, casted to T. + */ + @SuppressWarnings("unchecked") + public T getSetting(String key) { + return (T)settingsMap.get(key); + } + + public void putSetting(String key, Object value) { + settingsMap.put(key, value); + } + + public void setSetting(String key, Object value) throws IllegalArgumentException { + if (settingsMap.get(key) == null) { + putSetting(key, value); + } else if (settingsMap.get(key).getClass() == value.getClass()) { + putSetting(key, value); + } else { + throw new IllegalArgumentException("value is not type " + + settingsMap.get(key).getClass().getName() + " (got " + (value == null ? "null" : value.getClass().getName()) + ")"); + } + } + + public void save() throws IOException { + StringBuilder data = new StringBuilder(); + + for (String setting : settingsMap.keySet()) { + Object value = settingsMap.get(setting); + if (value.getClass() == Integer.class) { + data.append("int "); + } else if (value.getClass() == Double.class) { + data.append("double "); + } else if (value.getClass() == Boolean.class) { + data.append("bool "); + } + data.append(setting); + data.append(' '); + data.append(value); + data.append('\n'); + } + + OutputStream out = new FileOutputStream(filename); + out.write(data.toString().getBytes()); + out.close(); + } + + @Override + public String toString() { + return settingsMap.toString() + " at " + filename; + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/StdIO.java b/demos/java/gsviewer/src/com/artifex/gsviewer/StdIO.java new file mode 100644 index 00000000..4ea1b205 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/StdIO.java @@ -0,0 +1,38 @@ +package com.artifex.gsviewer; + +import com.artifex.gsjava.callbacks.IStdErrFunction; +import com.artifex.gsjava.callbacks.IStdInFunction; +import com.artifex.gsjava.callbacks.IStdOutFunction; + +/** + * Implementation of IStdOutFunction, IStdErrFunction, and + * IStdInFunction to get IO data from Ghostscript. + * + * @author Ethan Vrhel + * + */ +public class StdIO implements IStdOutFunction, IStdErrFunction, IStdInFunction { + + public static final boolean ENABLE_STD_OUT_IO = false; + public static final boolean ENABLE_STD_ERR_IO = true; + + @Override + public int onStdIn(long callerHandle, byte[] buf, int len) { + return len; + } + + @Override + public int onStdErr(long callerHandle, byte[] str, int len) { + if (ENABLE_STD_ERR_IO) + System.err.println(new String(str)); + return len; + } + + @Override + public int onStdOut(long callerHandle, byte[] str, int len) { + if (ENABLE_STD_OUT_IO) + System.out.println(new String(str)); + return len; + } + +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java new file mode 100644 index 00000000..f2801426 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/ViewerController.java @@ -0,0 +1,372 @@ +package com.artifex.gsviewer; + +import java.awt.HeadlessException; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.swing.JFileChooser; +import com.artifex.gsviewer.gui.SettingsDialog; +import com.artifex.gsviewer.gui.ViewerGUIListener; +import com.artifex.gsviewer.gui.ViewerWindow; + +/** + * The ViewerController is an implementation of a ViewerGUIListener + * used to control the main logic of the viewer such as determining what pages + * should be loaded. + * + * @author Ethan Vrhel + * + */ +public class ViewerController implements ViewerGUIListener { + + /** + * The lock for the SmartLoader. + */ + private static final Lock lock = new ReentrantLock(); + + /** + * The condition variable for the SmartLoader to signal when an operation + * needs to happen. + */ + private static final Condition cv = lock.newCondition(); + + /** + * The flag for the smart loader to read after completing an operation. If + * this flag is true, the SmartLoader will skip waiting for + * cv to be signaled and will immediately continue to the next + * operation. + */ + private static volatile boolean outOfDate = true; + + private ViewerWindow source; // The viewer window where documents will be displayed + private Document currentDocument; // The current document loaded in the viewer + private SmartLoader smartLoader; // The SmartLoader used to load pages based on scroll and zoom + private boolean loadingDocument; + + /** + *

Opens a document from a files asynchronously.

+ * + *

This method handles distilling files if they should be distilled and the user + * chooses to distill them.

+ * + * @param file The file to load. + * @throws NullPointerException When file is null. + * @throws IllegalArgumentException If file is not a file type which can be loaded + * into the viewer, if distilling occurs and fails. + * @throws FileNotFoundException When file does not exist. + * @throws IOException If distilling occurs and a temporary files to be created. + * @throws HeadlessException If distilling occurs and GraphicsEnvironment.isHeadless() returns + * true. + * @throws RuntimeException When an error occurs while launching the loader thread. + */ + public void open(File file) + throws NullPointerException, IllegalArgumentException, FileNotFoundException, IOException, + HeadlessException, RuntimeException { + if (loadingDocument) { + source.showWarningDialog("Error", "A document is already loading"); + return; + } + if (Document.shouldDistill(file)) { + int ret = source.showConfirmDialog("Distill", "Would you like to distill this document before opening?"); + if (ret == ViewerWindow.CANCEL) + return; + else if (ret == ViewerWindow.YES) { + try { + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new File(".")); + chooser.setFileFilter(PDFFileFilter.INSTANCE); + ret = chooser.showSaveDialog(source); + if (ret != JFileChooser.APPROVE_OPTION) + return; + File out = chooser.getSelectedFile(); + String filepath = out.getAbsolutePath(); + if (filepath.lastIndexOf('.') == -1) + out = new File(filepath + ".pdf"); + if (out.exists()) { + ret = source.showConfirmDialog("Overwrite?", out.getName() + " already exists. Overwrite?"); + if (ret != ViewerWindow.YES) + return; + } + if (currentDocument != null) + close(); + file = Document.distillDocument(file, out); + } catch (IllegalStateException | IOException e) { + System.err.println("Failed to distill: " + e); + } + } + } + + if (currentDocument != null) + close(); + loadingDocument = true; + Document.loadDocumentAsync(file, (final Document doc, final Exception exception) -> { + try { + source.loadDocumentToViewer(doc); + source.setLoadProgress(0); + if (exception != null) { + throw new RuntimeException("Failed to load", exception); + //source.showErrorDialog("Failed to load", exception.toString()); + } else { + this.currentDocument = doc; + dispatchSmartLoader(); + } + source.revalidate(); + } finally { + loadingDocument = false; + } + }, (int progress) -> { + source.setLoadProgress(progress); + }, Document.OPERATION_RETURN); + } + + /** + * Closes the currently loaded document, if one is loaded. If no document + * is loaded, this method does nothing. + */ + public void close() { + if (loadingDocument) { + source.showWarningDialog("Error", "A document is already loading"); + return; + } + + if (smartLoader != null) { + smartLoader.stop(); + smartLoader = null; + } + + if (currentDocument != null) { + source.loadDocumentToViewer(null); + currentDocument.unload(); + currentDocument = null; + } + } + + /** + * Returns the current document being viewed. + * + * @return The current document being viewed or null if + * no document is being viewed. + */ + public Document getCurrentDocument() { + return currentDocument; + } + + @Override + public void onViewerAdd(ViewerWindow source) { + this.source = source; + Thread.setDefaultUncaughtExceptionHandler(new UnhandledExceptionHandler()); + } + + @Override + public void onPageChange(int oldPage, int newPage) { + smartLoader.signalOutOfDate(); + } + + @Override + public void onZoomChange(double oldZoom, double newZoom) { + if (newZoom > 1.0) { + smartLoader.resetZoom(); + smartLoader.signalOutOfDate(); + } + } + + @Override + public void onScrollChange(int newScroll) { + if (smartLoader != null) + smartLoader.signalOutOfDate(); + } + + @Override + public void onOpenFile() { + JFileChooser chooser = new JFileChooser(); + chooser.setFileFilter(GSFileFilter.INSTANCE); + chooser.setCurrentDirectory(new File("").getAbsoluteFile()); + int status = chooser.showOpenDialog(source); + if (status == JFileChooser.APPROVE_OPTION) { + try { + open(chooser.getSelectedFile()); + } catch (IOException | RuntimeException e) { + source.showErrorDialog("Failed to Open", "Failed to open file (" + e + ")"); + } + } + } + + @Override + public void onCloseFile() { + close(); + } + + @Override + public void onClosing() { + source.dispose(); + System.exit(0); + } + + @Override + public void onSettingsOpen() { + SettingsDialog dialog = new SettingsDialog(source, true); + dialog.setVisible(true); + } + + /** + * Starts the SmartLoader on the currently loaded document. If a + * SmartLoader already exists, it will be stopped. + */ + private void dispatchSmartLoader() { + if (smartLoader != null) + smartLoader.stop(); + smartLoader = new SmartLoader(currentDocument); + smartLoader.start(); + } + + /** + * Implementation of Thread.UncaughtExceptionHandler to handle unhandled + * exceptions. This is used to show an error dialog to the user describing the error + * and then routes the error to the instance of the DefaultUnhandledExceptionHandler. + * + * @author Ethan Vrhel + * + */ + private class UnhandledExceptionHandler implements Thread.UncaughtExceptionHandler { + + @Override + public void uncaughtException(Thread t, Throwable e) { + e.printStackTrace(System.err); + if (source != null) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(os); + e.printStackTrace(out); + String errorMessage = new String(os.toByteArray()); + source.showErrorDialog("Unhandled Exception", errorMessage); + } + DefaultUnhandledExceptionHandler.INSTANCE.uncaughtException(t, e); + } + + } + + private class SmartLoader implements Runnable { + + private volatile boolean[] loaded; + private volatile boolean[] zoomLoaded; + private volatile boolean shouldRun; + private Thread thread; + + SmartLoader(Document doc) { + loaded = new boolean[doc.size()]; + zoomLoaded = new boolean[doc.size()]; + shouldRun = true; + } + + void start() { + if (thread != null) + stop(); + shouldRun = true; + thread = new Thread(this); + thread.setDaemon(true); + thread.setName("Document-Smart-Loader-Thread"); + thread.start(); + } + + void stop() { + lock.lock(); + cv.signalAll(); + lock.unlock(); + outOfDate = false; + shouldRun = false; + try { + thread.join(); + } catch (InterruptedException e) { + throw new RuntimeException("Thread join interrupted", e); + } + thread = null; + } + + void resetZoom() { + for (int i = 0; i < zoomLoaded.length; i++) { + zoomLoaded[i] = false; + } + } + + void signalOutOfDate() { + outOfDate = true; + lock.lock(); + try { + cv.signalAll(); + } catch (IllegalMonitorStateException e) { + System.err.println("Exception on signaling: " + e); + } finally { + lock.unlock(); + } + } + + @Override + public void run() { + System.out.println("Smart loader dispatched."); + while (shouldRun) { + int currentPage = source.getCurrentPage(); + int[] toLoad = genToLoad(currentPage); + + if (loaded.length != currentDocument.size()) + throw new IllegalStateException("Array is size " + loaded.length + " while doc size is " + currentDocument.size()); + + int ind = 0; + for (int page : toLoad) { + if (page >= 1 && page <= currentDocument.size()) { + if (source.getZoom() > 1.0) { + + // Load the zoomed page view only if it has not already been loaded. + if (!zoomLoaded[page - 1]) { + currentDocument.zoomArea(Document.OPERATION_WAIT, page, source.getZoom()); + zoomLoaded[page - 1] = true; + } + } else { + + // Unload any zoomed image to save memory consumption + currentDocument.unloadZoomed(page); + + // Load the high-resolution page view only if it has not already been loaded + if (!loaded[page - 1]) { + currentDocument.loadHighRes(Document.OPERATION_WAIT, page); + loaded[page - 1] = true; + } + } + } + ind++; + source.setLoadProgress((int)(((double)ind / toLoad.length) * 100)); + } + source.setLoadProgress(0); + + // First check if the current view is out of date and if so, just immediately continue + // so the thread does not get stuck in the lock until another event has occurred. + if (!outOfDate) { + outOfDate = false; + lock.lock(); + try { + cv.await(); + } catch (InterruptedException e) { + System.err.println("Interrupted in smart loader: " + e); + } finally { + lock.unlock(); + } + } else { + outOfDate = false; + } + } + } + + int[] genToLoad(int page) { + int range = Settings.SETTINGS.getSetting("preloadRange"); + int[] arr = new int[range * 2 + 1]; + for (int i = -range; i <= range; i++) { + arr[i + range] = page + i; + } + return arr; + } + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ScrollMap.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ScrollMap.java new file mode 100644 index 00000000..4e0dd5d4 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ScrollMap.java @@ -0,0 +1,142 @@ +package com.artifex.gsviewer.gui; + +import java.awt.Dimension; +import java.util.Arrays; +import java.util.Objects; + +import javax.swing.JComponent; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; + +import com.artifex.gsviewer.Document; + +/** + * A ScrollMap stores information on how far down a scroll bar + * a certain page is in a viewer. + * + * @author Ethan Vrhel + * + */ +public class ScrollMap { + + private final Document document; // The document which is being viewed + private final ViewerWindow window; // The window containing the scroll pane + private final int gap; // The gap in between each page + private int[] scrollMap; // A map mapping page indices to scroll values + + /** + * Creates and generates a new ScrollMap at zoom 1.0. + * + * @param document The document to generate the map from. + * @param window The viewer window to receive scroll panes from. + * @param gap The gap in between pages. + */ + public ScrollMap(final Document document, final ViewerWindow window, final int gap) { + this.document = Objects.requireNonNull(document, "document"); + this.scrollMap = null; + this.window = Objects.requireNonNull(window, "window"); + this.gap = gap; + genMap(1.0); + } + + /** + * Generates a map at a given zoom amount. + * + * @param zoom The amount that the document is zoomed in. + * @throws IllegalArgumentException If zoom is less than + * 0 or greater than 2. + */ + public synchronized void genMap(final double zoom) throws IllegalArgumentException { + if (zoom < 0.0 || zoom > 2.0) + throw new IllegalArgumentException("0.0 < zoom < 2.0"); + scrollMap = new int[document.size()]; + int currentScroll = 0; + for (int pageNum = 0; pageNum < document.size(); pageNum++) { + final JComponent component = window.getPageComponent(pageNum + 1); + if (component == null) + throw new NullPointerException("component is null!"); + final Dimension cSize = component.getSize(); + + scrollMap[pageNum] = currentScroll; + currentScroll += cSize.height * zoom; + currentScroll += gap; + } + } + + /** + * Returns the amount of scroll on the scroll pane at which page + * page is visible. + * + * @param page The page to get the scroll value for. + * @return The respective value. + * @throws IndexOutOfBoundsException If page is not a page + * in the document. + */ + public synchronized int getScroll(int page) throws IndexOutOfBoundsException { + if (page < 1 || page > scrollMap.length) + throw new IndexOutOfBoundsException("page = " + page); + return scrollMap[page - 1]; + } + + /** + * Returns the current page scrolled to in the scroll pane. + * + * @return The current page scrolled to. + */ + public synchronized int getCurrentPage() { + final JScrollPane scrollPane = window.getViewerScrollPane(); + final JScrollBar vScrollBar = scrollPane.getVerticalScrollBar(); + final int scrollValue = vScrollBar.getValue(); + return getPageFor(scrollValue); + } + + /** + * Returns the page for a given scroll value. + * + * @param scroll The scroll value to get the page for. + * @return The respective page. + */ + public synchronized int getPageFor(int scroll) { + for (int i = 0; i < scrollMap.length; i++) { + if (scroll < scrollMap[i]) + return i; /* Not i + 1! */ + } + return scrollMap.length; + } + + /** + * Automatically scrolls the scroll pane inside the viewer to the + * given page. + * + * @param page The page to srcoll to. + * @throws IndexOutOfBoundsException When page is not in + * the document. + */ + public synchronized void scrollTo(int page) throws IndexOutOfBoundsException { + if (page < 1 || page > scrollMap.length) + throw new IndexOutOfBoundsException("page = " + page); + final int scroll = scrollMap[page - 1]; + final JScrollPane scrollPane = window.getViewerScrollPane(); + final JScrollBar vScrollBar = scrollPane.getVerticalScrollBar(); + vScrollBar.setValue(scroll); + } + + /** + * Returns a copy of the array backing the scroll map, or + * null if none has been generated. + * + * @return A copy of the scroll map's backing array. + */ + public synchronized int[] getMap() { + if (scrollMap == null) + return null; + final int[] copy = new int[this.scrollMap.length]; + System.arraycopy(scrollMap, 0, copy, 0, scrollMap.length); + return copy; + } + + @Override + public String toString() { + return "ScrollMap[map=" + Arrays.toString(scrollMap) + "]"; + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/SettingsDialog.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/SettingsDialog.java new file mode 100644 index 00000000..a4ee5d82 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/SettingsDialog.java @@ -0,0 +1,241 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.artifex.gsviewer.gui; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import com.artifex.gsviewer.Settings; + +/** + * The settings dialog + * + * @author Ethan Vrhel + */ +public class SettingsDialog extends javax.swing.JDialog { + + private static final long serialVersionUID = 1L; + + /** + * Creates new form SettingsDialog + */ + public SettingsDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + setLocationRelativeTo(parent); + + scrollSensitivitySlider.addMouseListener(new MouseAdapter() { + + @Override + public void mouseReleased(MouseEvent e) { + scrollSensitvityField + .setText(new StringBuilder().append(scrollSensitivitySlider.getValue()).toString()); + } + }); + + init(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + + // + private void initComponents() { + + scrollSensitivityLabel = new javax.swing.JLabel(); + antialiasingCheckbox = new javax.swing.JCheckBox(); + cancelButton = new javax.swing.JButton(); + applyButton = new javax.swing.JButton(); + okButton = new javax.swing.JButton(); + preloadRangeLabel = new javax.swing.JLabel(); + scrollSensitivitySlider = new javax.swing.JSlider(); + scrollSensitvityField = new javax.swing.JTextField(); + preloadRangeSpinner = new javax.swing.JSpinner(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Settings"); + setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL); + setResizable(false); + + scrollSensitivityLabel.setText("Scroll Sensitivity"); + + antialiasingCheckbox.setText("Antialiasing"); + antialiasingCheckbox.setHideActionText(true); + antialiasingCheckbox.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + antialiasingCheckbox.setMargin(new java.awt.Insets(0, 0, 0, 0)); + + cancelButton.setText("Cancel"); + cancelButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + + applyButton.setText("Apply"); + applyButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + applyButtonActionPerformed(evt); + } + }); + + okButton.setText("OK"); + okButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + preloadRangeLabel.setText("Preload Range"); + + scrollSensitivitySlider.setMaximum(200); + scrollSensitivitySlider.setMinimum(1); + scrollSensitivitySlider.setToolTipText("The number of pixels to scroll"); + + scrollSensitvityField.addKeyListener(new java.awt.event.KeyAdapter() { + @Override + public void keyPressed(java.awt.event.KeyEvent evt) { + scrollSensitvityFieldKeyPressed(evt); + } + }); + + preloadRangeSpinner.setToolTipText("The range for loading out of view pages"); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout + .createSequentialGroup().addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout + .createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scrollSensitivityLabel).addComponent(preloadRangeLabel) + .addComponent(antialiasingCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 79, + javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(43, 43, 43) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(scrollSensitivitySlider, javax.swing.GroupLayout.PREFERRED_SIZE, + 126, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(scrollSensitvityField, javax.swing.GroupLayout.DEFAULT_SIZE, 69, + Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(preloadRangeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 40, + javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup( + layout.createSequentialGroup().addComponent(cancelButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, + javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(applyButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 51, + javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(3, 3, 3))) + .addContainerGap())); + layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout + .createSequentialGroup().addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup().addComponent(scrollSensitivityLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(preloadRangeLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(antialiasingCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cancelButton).addComponent(applyButton).addComponent(okButton))) + .addGroup(layout.createSequentialGroup().addGroup(layout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scrollSensitivitySlider, javax.swing.GroupLayout.PREFERRED_SIZE, + javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(scrollSensitvityField, javax.swing.GroupLayout.Alignment.TRAILING, + javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, + javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(preloadRangeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, + javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); + + pack(); + }// + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { + apply(); + dispose(); + } + + private void applyButtonActionPerformed(java.awt.event.ActionEvent evt) { + apply(); + } + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) { + dispose(); + } + + private void scrollSensitvityFieldKeyPressed(java.awt.event.KeyEvent evt) { + try { + int val = Integer.parseInt(scrollSensitvityField.getText()); + val = Math.max(Math.min(val, 200), 1); + scrollSensitivitySlider.setValue(val); + } catch (NumberFormatException e) { + } + } + + // Variables declaration - do not modify + private javax.swing.JCheckBox antialiasingCheckbox; + private javax.swing.JButton applyButton; + private javax.swing.JButton cancelButton; + private javax.swing.JButton okButton; + private javax.swing.JLabel preloadRangeLabel; + private javax.swing.JSpinner preloadRangeSpinner; + private javax.swing.JLabel scrollSensitivityLabel; + private javax.swing.JSlider scrollSensitivitySlider; + private javax.swing.JTextField scrollSensitvityField; + // End of variables declaration + + private void init() { + Settings settings = Settings.SETTINGS; + int scrollSens = settings.getSetting("scrollSens"); + int preloadRange = settings.getSetting("preloadRange"); + boolean antialiasing = settings.getSetting("antialiasing"); + + scrollSensitvityField.setText(new StringBuilder().append(scrollSens).toString()); + scrollSensitivitySlider.setValue(scrollSens); + + preloadRangeSpinner.setValue(preloadRange); + + antialiasingCheckbox.setSelected(antialiasing); + } + + private void apply() { + Settings settings = Settings.SETTINGS; + Integer scrollSens = settings.getSetting("scrollSens"); + Integer preloadRange = settings.getSetting("preloadRange"); + Boolean antialiasing = settings.getSetting("antialiasing"); + + try { + scrollSens = Integer.parseInt(scrollSensitvityField.getText()); + } catch (NumberFormatException e) { + } + + try { + int set = (Integer) preloadRangeSpinner.getValue(); + preloadRange = set >= 0 ? set : 0; + } catch (ClassCastException e) { + } + + antialiasing = antialiasingCheckbox.isSelected(); + + settings.setSetting("scrollSens", scrollSens); + settings.setSetting("preloadRange", preloadRange); + settings.setSetting("antialiasing", antialiasing); + } +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerGUIListener.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerGUIListener.java new file mode 100644 index 00000000..5a169731 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerGUIListener.java @@ -0,0 +1,61 @@ +package com.artifex.gsviewer.gui; + +/** + * This interface provides several methods which are used to listen + * for events on a ViewerWindow. + * + * @author Ethan Vrhel + * + */ +public interface ViewerGUIListener { + + /** + * Called when this listener is added to a ViewerWindow. + * + * @param source The window added to. + */ + public void onViewerAdd(ViewerWindow source); + + /** + * Called when the user scrolls to a new page. + * + * @param oldPage The old page. + * @param newPage The new page. + */ + public void onPageChange(int oldPage, int newPage); + + /** + * Called when the zoom value changes. + * + * @param oldZoom The old zoom value. + * @param newZoom The new zoom value. + */ + public void onZoomChange(double oldZoom, double newZoom); + + /** + * Called when the user scrolls. + * + * @param newScroll The scroll value which the user scrolls to. + */ + public void onScrollChange(int newScroll); + + /** + * Called when a file is opened. + */ + public void onOpenFile(); + + /** + * Called when a file is closed. + */ + public void onCloseFile(); + + /** + * Called when the window is closing. + */ + public void onClosing(); + + /** + * Called when the settings window opens. + */ + public void onSettingsOpen(); +} diff --git a/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java new file mode 100644 index 00000000..48b39953 --- /dev/null +++ b/demos/java/gsviewer/src/com/artifex/gsviewer/gui/ViewerWindow.java @@ -0,0 +1,1020 @@ +package com.artifex.gsviewer.gui; + +import java.awt.Adjustable; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.HeadlessException; +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +import com.artifex.gsviewer.Document; +import com.artifex.gsviewer.Page; +import com.artifex.gsviewer.PageUpdateCallback; +import com.artifex.gsviewer.Settings; + +/** + *

Used to display documents into a window.

+ * + *

Partially a auto-generated form using NetBeans.

+ */ +public class ViewerWindow extends javax.swing.JFrame { + + private static final long serialVersionUID = 1L; + + /** + * The gap between each page in the main viewer, in pixels. + */ + public static final int VIEWER_PAGE_GAP = 10; + + /** + * The gap between each page in the mini viewer, in pixels. + */ + public static final int MINI_VIEWER_PAGE_GAP = 10; + + /** + * Constant indicating the "Yes" option was clicked in a dialog. + */ + public static final int YES = JOptionPane.YES_OPTION; + + /** + * Constant indicating the "No" option was clicked in a dialog. + */ + public static final int NO = JOptionPane.NO_OPTION; + + /** + * Constant indicating the "Cancel" option was clicked in a ddialog. + */ + public static final int CANCEL = JOptionPane.CANCEL_OPTION; + + private ViewerGUIListener guiListener; // The ViewerGUIListener to receive callbacks + private int currentPage, maxPage; // Current page displayed and the length of the document + private double currentZoom; // The amount the viewer is zoomed + + private Document loadedDocument; // The currently loaded document + private ScrollMap scrollMap; // The ScrollMap mapping scroll values to page numbers + private List viewerPagePanels; // A list of the page panels in the viewer + private List miniViewerPagePanels; // A list of the page panels in the mini viewer + + private Dimension min; // The minimum window size + private Dimension max; // The maximum window size + + private boolean gotoPage; // Whether the viewer should jump to currentPage + + private boolean isLoading; + + /** + * Creates new ViewerWindow. + */ + public ViewerWindow() { + this(null); + } + + /** + * Creates a new ViewerWindow with a GUIListener. + * + * @param listener A ViewerGUIListener which will receive callbacks regarding + * different events. + */ + public ViewerWindow(final ViewerGUIListener listener) { + initComponents(); + this.currentPage = 0; + this.maxPage = 0; + this.currentZoom = 1.0; + this.viewerPagePanels = new ArrayList<>(); + this.miniViewerPagePanels = new ArrayList<>(); + + // Adjustment listener looks for any change in the scroll value of the scrollbar + this.viewerScrollPane.getVerticalScrollBar().addAdjustmentListener((AdjustmentEvent evt) -> { + this.viewerScrollPane.getVerticalScrollBar().setUnitIncrement(Settings.SETTINGS.getSetting("scrollSens")); + if (scrollMap != null) { + Adjustable adjustable = evt.getAdjustable(); + int currentPage = scrollMap.getPageFor(adjustable.getValue()); + if (ViewerWindow.this.currentPage != currentPage) { + if (guiListener != null) + guiListener.onPageChange(ViewerWindow.this.currentPage, currentPage); + } + if (guiListener != null) + guiListener.onScrollChange(adjustable.getValue()); + ViewerWindow.this.currentPage = currentPage; + assumePage(currentPage); + } + refreshButtons(); + }); + + setGUIListener(listener); + + zoomSlider.setEnabled(false); + increaseZoomButton.setEnabled(false); + decreaseZoomButton.setEnabled(false); + zoomSlider.setValue(50); + + nextPageButton.setEnabled(false); + lastPageButton.setEnabled(false); + pageNumberField.setEditable(false); + + setLocationRelativeTo(null); + + min = getMinimumSize(); + max = getMaximumSize(); + + gotoPage = false; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + + // + private void initComponents() { + + viewerScrollPane = new javax.swing.JScrollPane(); + viewerContentPane = new javax.swing.JPanel(); + miniViewerScrollPane = new javax.swing.JScrollPane(); + miniViewerContentPane = new javax.swing.JPanel(); + toolbarPanel = new javax.swing.JPanel(); + decreaseZoomButton = new javax.swing.JButton(); + zoomSlider = new javax.swing.JSlider(); + increaseZoomButton = new javax.swing.JButton(); + progressBar = new javax.swing.JProgressBar(); + lastPageButton = new javax.swing.JButton(); + pageNumberField = new javax.swing.JTextField(); + pageSlashLabel = new javax.swing.JLabel(); + maxPagesLabel = new javax.swing.JTextField(); + nextPageButton = new javax.swing.JButton(); + menuBar = new javax.swing.JMenuBar(); + fileMenu = new javax.swing.JMenu(); + openMenu = new javax.swing.JMenuItem(); + closeMenuItem = new javax.swing.JMenuItem(); + fileMenuSeparator = new javax.swing.JPopupMenu.Separator(); + exitMenuItem = new javax.swing.JMenuItem(); + editMenu = new javax.swing.JMenu(); + settingsMenuItem = new javax.swing.JMenuItem(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + setTitle("Viewer"); + setMinimumSize(new java.awt.Dimension(640, 650)); + addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + + viewerScrollPane.setMinimumSize(new java.awt.Dimension(85, 110)); + + javax.swing.GroupLayout viewerContentPaneLayout = new javax.swing.GroupLayout(viewerContentPane); + viewerContentPane.setLayout(viewerContentPaneLayout); + viewerContentPaneLayout.setHorizontalGroup( + viewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 623, Short.MAX_VALUE) + ); + viewerContentPaneLayout.setVerticalGroup( + viewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 639, Short.MAX_VALUE) + ); + + viewerScrollPane.setViewportView(viewerContentPane); + + miniViewerScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + javax.swing.GroupLayout miniViewerContentPaneLayout = new javax.swing.GroupLayout(miniViewerContentPane); + miniViewerContentPane.setLayout(miniViewerContentPaneLayout); + miniViewerContentPaneLayout.setHorizontalGroup( + miniViewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 118, Short.MAX_VALUE) + ); + miniViewerContentPaneLayout.setVerticalGroup( + miniViewerContentPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 639, Short.MAX_VALUE) + ); + + miniViewerScrollPane.setViewportView(miniViewerContentPane); + + decreaseZoomButton.setText("-"); + decreaseZoomButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + decreaseZoomButtonActionPerformed(evt); + } + }); + + zoomSlider.setMajorTickSpacing(25); + zoomSlider.setMinorTickSpacing(5); + zoomSlider.setPaintTicks(true); + zoomSlider.setSnapToTicks(true); + zoomSlider.addMouseListener(new java.awt.event.MouseAdapter() { + @Override + public void mouseReleased(java.awt.event.MouseEvent evt) { + zoomSliderMouseReleased(evt); + } + }); + + increaseZoomButton.setText("+"); + increaseZoomButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + increaseZoomButtonActionPerformed(evt); + } + }); + + lastPageButton.setText("<"); + lastPageButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + lastPageButtonActionPerformed(evt); + } + }); + + pageNumberField.setText("0"); + pageNumberField.addKeyListener(new java.awt.event.KeyAdapter() { + @Override + public void keyPressed(java.awt.event.KeyEvent evt) { + pageNumberFieldKeyPressed(evt); + } + }); + + pageSlashLabel.setText("/"); + + maxPagesLabel.setEditable(false); + maxPagesLabel.setText("0"); + + nextPageButton.setText(">"); + nextPageButton.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + nextPageButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout toolbarPanelLayout = new javax.swing.GroupLayout(toolbarPanel); + toolbarPanel.setLayout(toolbarPanelLayout); + toolbarPanelLayout.setHorizontalGroup( + toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolbarPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolbarPanelLayout.createSequentialGroup() + .addComponent(decreaseZoomButton, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(increaseZoomButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lastPageButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pageSlashLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(nextPageButton)) + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + toolbarPanelLayout.setVerticalGroup( + toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolbarPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(toolbarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(increaseZoomButton) + .addComponent(lastPageButton) + .addComponent(pageNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(pageSlashLabel) + .addComponent(maxPagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(nextPageButton)) + .addComponent(zoomSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(decreaseZoomButton)) + .addGap(17, 17, 17) + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + fileMenu.setText("File"); + + openMenu.setText("Open"); + openMenu.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + openMenuActionPerformed(evt); + } + }); + fileMenu.add(openMenu); + + closeMenuItem.setText("Close"); + closeMenuItem.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeMenuItemActionPerformed(evt); + } + }); + fileMenu.add(closeMenuItem); + fileMenu.add(fileMenuSeparator); + + exitMenuItem.setText("Exit"); + exitMenuItem.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + exitMenuItemActionPerformed(evt); + } + }); + fileMenu.add(exitMenuItem); + + menuBar.add(fileMenu); + + editMenu.setText("Edit"); + + settingsMenuItem.setText("Settings"); + settingsMenuItem.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + settingsMenuItemActionPerformed(evt); + } + }); + editMenu.add(settingsMenuItem); + + menuBar.add(editMenu); + + setJMenuBar(menuBar); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(miniViewerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(toolbarPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 642, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(miniViewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 592, Short.MAX_VALUE) + .addComponent(viewerScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 592, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(toolbarPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + pack(); + }// + + private void lastPageButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_lastPageButtonActionPerformed + if (maxPage > 0) { + tryChangePage(currentPage - 1); + } else { + pageNumberField.setText(new StringBuilder().append(0).toString()); + } + }// GEN-LAST:event_lastPageButtonActionPerformed + + private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_nextPageButtonActionPerformed + if (maxPage > 0) { + tryChangePage(currentPage + 1); + } else { + pageNumberField.setText(new StringBuilder().append(0).toString()); + } + }// GEN-LAST:event_nextPageButtonActionPerformed + + private void formWindowClosing(java.awt.event.WindowEvent evt) {// GEN-FIRST:event_formWindowClosing + if (guiListener != null) + guiListener.onClosing(); + }// GEN-LAST:event_formWindowClosing + + private void pageNumberFieldKeyPressed(java.awt.event.KeyEvent evt) {// GEN-FIRST:event_pageNumberFieldKeyPressed + if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER) { + try { + final String text = pageNumberField.getText(); + tryChangePage(Integer.parseInt(text)); + } catch (NumberFormatException e) { + System.err.println("Invalid page numer."); + } + } + }// GEN-LAST:event_pageNumberFieldKeyPressed + + private void zoomSliderMouseReleased(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_zoomSliderMouseReleased + tryChangeZoom(zoomSlider.getValue() / 50.0); + }// GEN-LAST:event_zoomSliderMouseReleased + + private void increaseZoomButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_increaseZoomButtonActionPerformed + if (tryChangeZoom(Math.min(Math.ceil((currentZoom * 10) + 1) / 10, 2.0))) + zoomSlider.setValue((int)(currentZoom * 50)); + }// GEN-LAST:event_increaseZoomButtonActionPerformed + + private void decreaseZoomButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_decreaseZoomButtonActionPerformed + if (tryChangeZoom(Math.max(Math.floor((currentZoom * 10) - 1) / 10, 0.0))) + zoomSlider.setValue((int)(currentZoom * 50)); + }// GEN-LAST:event_decreaseZoomButtonActionPerformed + + private void openMenuActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_openMenuActionPerformed + if (guiListener != null) + guiListener.onOpenFile(); + }// GEN-LAST:event_openMenuActionPerformed + + private void closeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_closeMenuItemActionPerformed + if (guiListener != null) + guiListener.onCloseFile(); + }// GEN-LAST:event_closeMenuItemActionPerformed + + private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_exitMenuItemActionPerformed + if (guiListener != null) + guiListener.onClosing(); + }// GEN-LAST:event_exitMenuItemActionPerformed + + private void settingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_settingsMenuItemActionPerformed + if (guiListener != null) + guiListener.onSettingsOpen(); + tryChangeZoom(0.1); + }// GEN-LAST:event_settingsMenuItemActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenuItem closeMenuItem; + private javax.swing.JButton decreaseZoomButton; + private javax.swing.JMenu editMenu; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenu; + private javax.swing.JPopupMenu.Separator fileMenuSeparator; + private javax.swing.JButton increaseZoomButton; + private javax.swing.JButton lastPageButton; + private javax.swing.JTextField maxPagesLabel; + private javax.swing.JMenuBar menuBar; + private javax.swing.JPanel miniViewerContentPane; + private javax.swing.JScrollPane miniViewerScrollPane; + private javax.swing.JButton nextPageButton; + private javax.swing.JMenuItem openMenu; + private javax.swing.JTextField pageNumberField; + private javax.swing.JLabel pageSlashLabel; + private javax.swing.JProgressBar progressBar; + private javax.swing.JMenuItem settingsMenuItem; + private javax.swing.JPanel toolbarPanel; + private javax.swing.JPanel viewerContentPane; + private javax.swing.JScrollPane viewerScrollPane; + private javax.swing.JSlider zoomSlider; + // End of variables declaration//GEN-END:variables + + private class PagePanel extends JPanel implements PageUpdateCallback { + + static final long serialVersionUID = 1L; + + Object lock; // A lock to ensure multiple draw calls don't happen + Page page; // The page to display + double size; // The size of the page + + Image toDraw; // The image which should be drawn by the panel + + /** + * Creates a new page panel to display a page of a document. + * + * @param page The page to display. + * @param size The size of the page. + */ + PagePanel(final Page page, double size) { + this.lock = new Object(); + this.page = page; + this.size = size == 0.0 ? 0.01 : size; + + Dimension pageSize = page.getSize(); + + Dimension actualSize = new Dimension((int)(pageSize.width * size), + (int)(pageSize.height * size)); + + toDraw = getImage(); + + setPreferredSize(actualSize); + setMaximumSize(actualSize); + + setBackground(Color.WHITE); + + setDoubleBuffered(false); + //pack(); + + page.addCallback(this); + } + + /** + * Returns the image which should be displayed in the viewer. This will + * change depending on the availability of high resolution images and zoom + * values. + * + * @return The image which should be displayed in the viewer. + */ + Image getImage() { + if (page != null && page.getLowResImage() != null) { + Dimension pageSize = page.getSize(); + Dimension actualSize = new Dimension((int)(pageSize.width * size), + (int)(pageSize.height * size)); + BufferedImage img = page.getDisplayableImage(); + if (page.getZoomedImage() != null && size > 1.0) + img = page.getZoomedImage(); + + Image result = img; + if (img == page.getLowResImage() || currentZoom < 1.0 || + (img == page.getHighResImage() && currentZoom > 1.0 && page.getZoomedImage() == null)) { + result = img.getScaledInstance(actualSize.width, actualSize.height, Image.SCALE_SMOOTH); + } + return result; + } else { + return null; + } + } + + /** + * Cleans up this page panel. + */ + void cleanup() { + if (page != null) { + page.removeCallback(this); + page = null; + } + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + synchronized (lock) { + if (toDraw != null) { + g.drawImage(toDraw, 0, 0, this); + } + } + } + + @Override + public void onPageUpdate() { + toDraw = getImage(); + SwingUtilities.invokeLater(() -> { + repaint(); + }); + } + + @Override + public void onLoadLowRes() { } + + @Override + public void onUnloadLowRes() { } + + @Override + public void onLoadHighRes() { } + + @Override + public void onUnloadHighRes() { } + + @Override + public void onLoadZoomed() { } + + @Override + public void onUnloadZoomed() { } + } + + /** + * The action listener to listen for button clicks in the + * mini viewer. Clicking on a button in the mini viewer will jump + * the user's view to the respective page. + * + * @author evrhe + * + */ + private class MiniViewerActionListener implements ActionListener { + + final int pageNum; // The assigned page number for this listener + + /** + * Creates a new listener with a tied page. + * + * @param pageNum The page number tied to this listener. + */ + MiniViewerActionListener(int pageNum) { + this.pageNum = pageNum; + } + + @Override + public void actionPerformed(ActionEvent e) { + tryChangePage(pageNum); + } + + } + + @Override + public void validate() { + super.validate(); + if (this.scrollMap != null) { + assumePage(this.currentPage = this.scrollMap.getCurrentPage()); + if (gotoPage) + scrollMap.scrollTo(currentPage); + } + unlockSize(); + gotoPage = false; + } + + /** + * Sets the ViewerGUIListener the window should use. + * + * @param listener A listener. + */ + public void setGUIListener(final ViewerGUIListener listener) { + this.guiListener = listener; + listener.onViewerAdd(this); + } + + /** + * Sets the progress of the progress bar in the window. + * + * @param progress The amount of progress (0-100). + */ + public void setLoadProgress(final int progress) { + progressBar.setValue(progress); + } + + /** + * Loads a document into the viewer and unloads the currently loaded document + * if one is loaded. + * + * @param document The document to load into the viewer. + */ + public void loadDocumentToViewer(final Document document) { + isLoading = true; + try { + unloadViewerDocument(); + if (document == null) + return; + lockSize(); + + this.loadedDocument = document; + viewerContentPane.setLayout(new BoxLayout(viewerContentPane, BoxLayout.Y_AXIS)); + + // Generate the viewer page components + /*for (final Page page : document) { + final PagePanel panel = new PagePanel(page, 1.0); + viewerContentPane.add(panel); + viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP)); + + viewerPagePanels.add(panel); + }*/ + + miniViewerContentPane.setLayout(new BoxLayout(miniViewerContentPane, BoxLayout.Y_AXIS)); + + int height = 0; + // Generate the mini viewer icons + int pageNum = 1; + for (final Page page : document) { + + final PagePanel panel = new PagePanel(page, 1.0); + viewerContentPane.add(panel); + viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP)); + + viewerPagePanels.add(panel); + height += page.getSize().height; + height += VIEWER_PAGE_GAP; + + ImageIcon icon = new ImageIcon(page.getLowResImage()); + JButton button = new JButton(icon); + button.setPreferredSize(page.getLowResSize()); + button.addActionListener(new MiniViewerActionListener(pageNum++)); + button.setFocusable(false); + + miniViewerContentPane.add(button); + miniViewerContentPane.add(Box.createVerticalStrut(MINI_VIEWER_PAGE_GAP)); + } + System.out.println(height); + + // Generate the scroll map + invokeAndWait(() -> { + revalidate(); + this.scrollMap = new ScrollMap(document, this, VIEWER_PAGE_GAP); + }); + assumePage(this.currentPage = 1); + assumeMaxPages(this.maxPage = document.size()); + + setTitle("Viewer - " + document.getName()); + + // Enable all widgets + zoomSlider.setEnabled(true); + increaseZoomButton.setEnabled(true); + decreaseZoomButton.setEnabled(true); + zoomSlider.setValue(50); + zoomSlider.setFocusable(true); + + nextPageButton.setEnabled(true); + lastPageButton.setEnabled(true); + pageNumberField.setEditable(true); + + refreshButtons(); + } finally { + isLoading = false; + } + } + + /** + * Unloads the currently loaded document from the viewer. If no document + * is loaded, this method does nothing. + */ + public void unloadViewerDocument() { + if (this.loadedDocument == null) + return; + + lockSize(); + + this.loadedDocument = null; + this.scrollMap = null; + + // Disable all widgets + this.assumePage(0); + this.assumeMaxPages(0); + this.zoomSlider.setValue(50); + this.zoomSlider.setEnabled(false); + this.zoomSlider.setFocusable(false); + this.pageNumberField.setEditable(false); + + setTitle("Viewer"); + + // Remove all pages + for (final PagePanel panel : viewerPagePanels) { + synchronized (panel.lock) { + panel.cleanup(); + } + } + viewerContentPane.removeAll(); + viewerPagePanels.clear(); + + miniViewerContentPane.removeAll(); + miniViewerPagePanels.clear(); + + System.gc(); + + invokeAndWait(() -> { + viewerContentPane.revalidate(); + viewerContentPane.repaint(); + + miniViewerContentPane.revalidate(); + miniViewerContentPane.repaint(); + }); + + } + + /** + * Returns the document currently loaded in the viewer. + * + * @return The currently loaded document, or null if none + * is loaded. + */ + public Document getLoadedDocument() { + return loadedDocument; + } + + /** + * Returns the respective component inside of the viewer for a page. + * + * @param pageNum The page to get the component for. + * @return The respective component. + * @throws IndexOutOfBoundsException If pageNum is not a page in the document. + */ + public JComponent getPageComponent(final int pageNum) throws IndexOutOfBoundsException { + return viewerPagePanels.get(pageNum - 1); + } + + /** + * Returns the scroll pane used by the viewer. + * + * @return The scroll pane. + */ + public JScrollPane getViewerScrollPane() { + return viewerScrollPane; + } + + /** + * Tries to change the page to another page. + * + * @param newPage The page to change to. + * @return true if the page is a valid page and false + * otherwise. + */ + public boolean tryChangePage(final int newPage) { + if (newPage < 1 || newPage > maxPage) + return false; + if (newPage != currentPage) { + final int oldPage = currentPage; + this.currentPage = newPage; + if (guiListener != null) + guiListener.onPageChange(oldPage, currentPage); + if (this.scrollMap != null) { + scrollMap.scrollTo(newPage); + assumePage(newPage); + } + + refreshButtons(); + + pageNumberField.setText(new StringBuilder().append(currentPage).toString()); + } + return true; + } + + /** + * Tries to change the zoom to another zoom value. + * + * @param newZoom The zoom to change to. + * @return true if the zoom is a valid zoom value and + * false otherwise. + */ + public boolean tryChangeZoom(final double newZoom) { + if (newZoom < 0 || newZoom > 2) + return false; + if (newZoom != currentZoom) { + gotoPage = true; + final double oldZoom = currentZoom; + this.currentZoom = newZoom; + if (guiListener != null) + guiListener.onZoomChange(oldZoom, currentZoom); + if (this.scrollMap != null) { + redisplayDocument(); + } + + refreshButtons(); + } + return true; + } + + /** + * Returns the current page the user is scrolled to. + * + * @return The current page. + */ + public int getCurrentPage() { + if (this.scrollMap != null) + return scrollMap.getCurrentPage(); + return 0; + } + + /** + * Shows an error dialog with a title and message. + * + * @param title The title of the dialog. + * @param message The message of the dialog. + * @throws HeadlessException If GraphicsEnvironment.isHeadless returns true. + */ + public void showErrorDialog(String title, String message) throws HeadlessException { + JOptionPane.showMessageDialog(this, message, title, JOptionPane.ERROR_MESSAGE); + } + + /** + * Shows a warning dialog with a title and message. + * + * @param title The title of the dialog. + * @param message The message of the dialog. + * @throws HeadlessException If GraphicsEnvironment.isHeadless returns true. + */ + public void showWarningDialog(String title, String message) throws HeadlessException { + JOptionPane.showMessageDialog(this, message, title, JOptionPane.WARNING_MESSAGE); + } + + /** + * Shows a confirmation dialog with a title and message. + * + * @param title The title of the dialog. + * @param message The message of the dialog. + * @return The button the user clicked (ViewerWindow.YES, ViewerWindow.NO, + * or ViewerWindow.CANCEL). + * @throws HeadlessException If GraphicsEnvironment.isHeadless returns true. + */ + public int showConfirmDialog(String title, String message) throws HeadlessException { + return JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_NO_CANCEL_OPTION); + } + + /** + * Returns how much the viewer is zoomed in. + * + * @return The current zoom. + */ + public double getZoom() { + return currentZoom; + } + + /** + * Returns whether the window is loading a document. + * + * @return true if the window is loading a document + * and false otherwise. + */ + public boolean isLoading() { + return isLoading; + } + + public void apply(Settings settings) { + int sens = settings.getSetting("scrollSens"); + this.viewerScrollPane.getVerticalScrollBar().setUnitIncrement(sens); + this.miniViewerScrollPane.getVerticalScrollBar().setUnitIncrement(sens); + } + + /** + * Refresh each button's state. + */ + private void refreshButtons() { + this.lastPageButton.setEnabled(currentPage != 1 && loadedDocument != null); + this.nextPageButton.setEnabled(currentPage != maxPage && loadedDocument != null); + + this.increaseZoomButton.setEnabled(currentZoom != 2.0 && loadedDocument != null); + this.decreaseZoomButton.setEnabled(currentZoom != 0.0 && loadedDocument != null); + } + + /** + * Redisplays the currently loaded document. This will remove all loaded page panels + * and recreate them. + */ + private void redisplayDocument() { + lockSize(); + + for (final PagePanel panel : viewerPagePanels) { + synchronized (panel.lock) { + panel.cleanup(); + } + } + viewerContentPane.removeAll(); + viewerPagePanels.clear(); + + System.gc(); + + for (final Page page : loadedDocument) { + final PagePanel panel = new PagePanel(page, currentZoom); + viewerContentPane.add(panel); + viewerContentPane.add(Box.createVerticalStrut(VIEWER_PAGE_GAP)); + + viewerPagePanels.add(panel); + } + + invokeAndWait(() -> { + gotoPage = true; + revalidate(); + scrollMap.genMap(1.0); + }); + } + + /** + * Prevents the window from being resized. + */ + private void lockSize() { + Dimension size = getSize(); + setMinimumSize(size); + setMaximumSize(size); + //setResizable(false); + } + + /** + * Allows the window to be resized. + */ + private void unlockSize() { + setMinimumSize(min); + setMaximumSize(max); + //setResizable(true); + } + + /** + * Assume that we are on a certain page by setting the page number field. + * + * @param pageNum A page number. + */ + private void assumePage(int pageNum) { + this.pageNumberField.setText(new StringBuilder().append(pageNum).toString()); + } + + /** + * Assume that we have a certain max page count by setting the max pages field. + * + * @param pageCount A page count. + */ + private void assumeMaxPages(int pageCount) { + this.maxPagesLabel.setText(new StringBuilder().append(pageCount).toString()); + } + + private void invokeAndWait(Runnable r) { + if (!SwingUtilities.isEventDispatchThread()) { + try { + SwingUtilities.invokeAndWait(r); + } catch (InvocationTargetException | InterruptedException e) { + r.run(); + } + } else { + r.run(); + } + } +} diff --git a/demos/java/jni/gs_jni/callbacks.cpp b/demos/java/jni/gs_jni/callbacks.cpp new file mode 100644 index 00000000..a8ad2196 --- /dev/null +++ b/demos/java/jni/gs_jni/callbacks.cpp @@ -0,0 +1,368 @@ +#include "callbacks.h" + +#include "jni_util.h" + +#include + +#define STDIN_SIG "(J[BI)I" +#define STDOUT_SIG "(J[BI)I" +#define STDERR_SIG "(J[BI)I" + +#define POLL_SIG "(J)I" + +#define DISPLAY_OPEN_SIG "(JJ)I" +#define DISPLAY_PRECLOSE_SIG "(JJ)I" +#define DISPLAY_CLOSE_SIG "(JJ)I" +#define DISPLAY_PRESIZE_SIG "(JJIIII)I" +#define DISPLAY_SIZE_SIG "(JJIIIILcom/artifex/gsjava/util/BytePointer;)I" +#define DISPLAY_SYNC_SIG "(JJ)I" +#define DISPLAY_PAGE_SIG "(JJIZ)I" +#define DISPLAY_UPDATE_SIG "(JJIIII)I" +// display memalloc +// display memfree +#define DISPLAY_SEPARATION_SIG "(JJI[BSSSS)I" +#define DISPLAY_ADJUST_BAND_HEIGHT_SIG "(JJI)I" +#define DISPLAY_RECTANGLE_REQUEST "(JJLcom/artifex/gsjava/LongReference;Lcom/artifex/gsjava/IntReference;\ +Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;\ +Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;Lcom/artifex/gsjava/IntReference;\ +Lcom/artifex/gsjava/IntReference;)I" + +#define CHECK_AND_RETURN(E) if (E->ExceptionCheck()) { return -21; } + +using namespace util; + +static JNIEnv *g_env = NULL; + +static jobject g_stdIn = NULL; +static jobject g_stdOut = NULL; +static jobject g_stdErr = NULL; + +static jobject g_poll = NULL; + +static jobject g_displayCallback = NULL; + +static jobject g_callout = NULL; + +void callbacks::setJNIEnv(JNIEnv *env) +{ + g_env = env; +} + +void callbacks::setIOCallbacks(jobject stdIn, jobject stdOut, jobject stdErr) +{ + if (g_env) + { + if (g_stdIn) + g_env->DeleteGlobalRef(g_stdIn); + + if (g_stdOut) + g_env->DeleteGlobalRef(g_stdOut); + + if (g_stdErr) + g_env->DeleteGlobalRef(g_stdErr); + + g_stdIn = g_env->NewGlobalRef(stdIn); + g_stdOut = g_env->NewGlobalRef(stdOut); + g_stdErr = g_env->NewGlobalRef(stdErr); + } +} + +int callbacks::stdInFunction(void *callerHandle, char *buf, int len) +{ + int code = 0; + if (g_env && g_stdIn) + { + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (jbyte *)buf); + code = callIntMethod(g_env, g_stdIn, "onStdIn", STDIN_SIG, (jlong)callerHandle, byteArray, (jint)len); + } + return code; +} + +int callbacks::stdOutFunction(void *callerHandle, const char *str, int len) +{ + int code = 0; + if (g_env && g_stdOut) + { + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)str); + code = callIntMethod(g_env, g_stdOut, "onStdOut", STDOUT_SIG, (jlong)callerHandle, byteArray, (jint)len); + } + return code; +} + +int callbacks::stdErrFunction(void *callerHandle, const char *str, int len) +{ + int code = 0; + if (g_env && g_stdErr) + { + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)str); + code = callIntMethod(g_env, g_stdErr, "onStdErr", STDERR_SIG, (jlong)callerHandle, byteArray, (jint)len); + } + return code; +} + +void callbacks::setPollCallback(jobject poll) +{ + if (g_env) + { + if (g_poll) + g_env->DeleteGlobalRef(g_poll); + + g_poll = g_env->NewGlobalRef(poll); + } +} + +int callbacks::pollFunction(void *callerHandle) +{ + int code = 0; + if (g_env && g_poll) + { + code = callIntMethod(g_env, g_poll, "onPoll", POLL_SIG, (jlong)callerHandle); + } + return code; +} + +void callbacks::setDisplayCallback(jobject displayCallback) +{ + if (g_env) + { + if (g_displayCallback) + { + g_env->DeleteGlobalRef(g_displayCallback); + g_displayCallback = NULL; + } + + g_displayCallback = g_env->NewGlobalRef(displayCallback); + //g_displayCallback = displayCallback; + } +} + +void callbacks::setCalloutCallback(jobject callout) +{ + if (g_env) + { + if (g_callout) + g_env->DeleteGlobalRef(g_callout); + + g_callout = g_env->NewGlobalRef(callout); + } +} + +int callbacks::calloutFunction(void *instance, void *handle, const char *deviceName, int id, int size, void *data) +{ + int code = 0; + if (g_env && g_callout) + { + jsize len = strlen(deviceName); + jbyteArray array = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(array, 0, len, (const jbyte *)deviceName); + code = callIntMethod(g_env, g_callout, "onCallout", "(JJ[BIIJ)I", (jlong)instance, (jlong)handle, array, id, size, (jlong)data); + } + return code; +} + +int callbacks::display::displayOpenFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + jclass clazz = g_env->GetObjectClass(g_displayCallback); + const char *name = getClassName(g_env, clazz); + freeClassName(name); + code = callIntMethod(g_env, g_displayCallback, "onDisplayOpen", DISPLAY_OPEN_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return 0; +} + +int callbacks::display::displayPrecloseFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayPreclose", DISPLAY_PRECLOSE_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayCloseFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayClose", DISPLAY_CLOSE_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayPresizeFunction(void *handle, void *device, int width, int height, int raster, unsigned int format) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayPresize", DISPLAY_PRESIZE_SIG, (jlong)handle, + (jlong)device, width, height, raster, (jint)format); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displaySizeFunction(void *handle, void *device, int width, int height, int raster, + unsigned int format, unsigned char *pimage) +{ + int code = 0; + if (g_env && g_displayCallback) + { + jsize len = height * raster; + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (signed char *)pimage); + + static const char *const bytePointerClassName = "com/artifex/gsjava/util/BytePointer"; + static const char *const nativePointerClassName = "com/artifex/gsjava/util/NativePointer"; + + jclass bytePointerClass = g_env->FindClass(bytePointerClassName); + if (bytePointerClass == NULL) + { + throwNoClassDefError(g_env, bytePointerClassName); + return -21; + } + + jclass nativePointerClass = g_env->FindClass(nativePointerClassName); + if (nativePointerClass == NULL) + { + throwNoClassDefError(g_env, nativePointerClassName); + return -21; + } + + jmethodID constructor = g_env->GetMethodID(bytePointerClass, "", "()V"); + if (constructor == NULL) + { + throwNoSuchMethodError(g_env, "com.artifex.gsjava.util.BytePointer.()V"); + return -21; + } + jobject bytePointer = g_env->NewObject(bytePointerClass, constructor); + + jfieldID dataPtrID = g_env->GetFieldID(nativePointerClass, "address", "J"); + if (dataPtrID == NULL) + { + throwNoSuchFieldError(g_env, "address"); + return -21; + } + + jfieldID lengthID = g_env->GetFieldID(bytePointerClass, "length", "J"); + if (lengthID == NULL) + { + throwNoSuchFieldError(g_env, "length"); + return -21; + } + + g_env->SetLongField(bytePointer, dataPtrID, (jlong)pimage); + g_env->SetLongField(bytePointer, lengthID, len); + + code = callIntMethod(g_env, g_displayCallback, "onDisplaySize", DISPLAY_SIZE_SIG, (jlong)handle, + (jlong)device, width, height, raster, (jint)format, bytePointer); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displaySyncFunction(void *handle, void *device) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplaySync", DISPLAY_SYNC_SIG, (jlong)handle, (jlong)device); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayPageFunction(void *handle, void *device, int copies, int flush) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayPage", DISPLAY_PAGE_SIG, (jlong)handle, + (jlong)device, copies, flush); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayUpdateFunction(void *handle, void *device, int x, int y, int w, int h) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayUpdate", DISPLAY_UPDATE_SIG, (jlong)handle, + (jlong)device, x, y, w, h); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displaySeparationFunction(void *handle, void *device, int component, const char *componentName, + unsigned short c, unsigned short m, unsigned short y, unsigned short k) +{ + int code = 0; + if (g_env && g_displayCallback) + { + jsize len = strlen(componentName); + jbyteArray byteArray = g_env->NewByteArray(len); + g_env->SetByteArrayRegion(byteArray, 0, len, (const jbyte *)componentName); + code = callIntMethod(g_env, g_displayCallback, "onDisplaySeparation", DISPLAY_SEPARATION_SIG, (jlong)handle, + (jlong)device, component, byteArray, c, m, y, k); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayAdjustBandHeightFunction(void *handle, void *device, int bandHeight) +{ + int code = 0; + if (g_env && g_displayCallback) + { + code = callIntMethod(g_env, g_displayCallback, "onDisplayAdjustBandHeght", DISPLAY_ADJUST_BAND_HEIGHT_SIG, + (jlong)handle, (jlong)device, bandHeight); + CHECK_AND_RETURN(g_env); + } + return code; +} + +int callbacks::display::displayRectangleRequestFunction(void *handle, void *device, void **memory, int *ox, int *oy, + int *raster, int *plane_raster, int *x, int *y, int *w, int *h) +{ + int code = 0; + if (g_env && g_displayCallback) + { + Reference memoryRef = Reference(g_env, toWrapperType(g_env, (jlong)*memory)); + Reference oxRef = Reference(g_env, toWrapperType(g_env, (jint)*ox)); + Reference oyRef = Reference(g_env, toWrapperType(g_env, (jint)*oy)); + Reference rasterRef = Reference(g_env, toWrapperType(g_env, (jint)*raster)); + Reference planeRasterRef = Reference(g_env, toWrapperType(g_env, (jint)*plane_raster)); + Reference xRef = Reference(g_env, toWrapperType(g_env, (jint)*x)); + Reference yRef = Reference(g_env, toWrapperType(g_env, (jint)*y)); + Reference wRef = Reference(g_env, toWrapperType(g_env, (jint)*w)); + Reference hRef = Reference(g_env, toWrapperType(g_env, (jint)*h)); + + code = callIntMethod(g_env, g_displayCallback, "onDisplayRectangleRequest", DISPLAY_RECTANGLE_REQUEST, + (jlong)handle, (jlong)device, memoryRef, oxRef, oyRef, rasterRef, planeRasterRef, xRef, yRef, wRef, hRef); + + *memory = (void *)memoryRef.longValue(); + *ox = oxRef.intValue(); + *oy = oyRef.intValue(); + *raster = rasterRef.intValue(); + *plane_raster = planeRasterRef.intValue(); + *x = xRef.intValue(); + *y = yRef.intValue(); + *w = wRef.intValue(); + *h = hRef.intValue(); + + CHECK_AND_RETURN(g_env); + } + return code; +} diff --git a/demos/java/jni/gs_jni/callbacks.h b/demos/java/jni/gs_jni/callbacks.h new file mode 100644 index 00000000..55508f2b --- /dev/null +++ b/demos/java/jni/gs_jni/callbacks.h @@ -0,0 +1,54 @@ +#pragma once + +#include + +namespace callbacks +{ + /*! + Sets the JNIEnv which the callbacks should use. Must be set for any Java + callbacks to be called. + + @param env A JNIEnv. + */ + void setJNIEnv(JNIEnv *env); + + void setIOCallbacks(jobject stdIn, jobject stdOut, jobject stdErr); + int stdInFunction(void *callerHandle, char *buf, int len); + int stdOutFunction(void *callerHandle, const char *str, int len); + int stdErrFunction(void *callerHandle, const char *str, int len); + + void setPollCallback(jobject poll); + int pollFunction(void *callerHandle); + + void setDisplayCallback(jobject displayCallback); + + namespace display + { + int displayOpenFunction(void *handle, void *device); + int displayPrecloseFunction(void *handle, void *device); + int displayCloseFunction(void *handle, void *device); + int displayPresizeFunction(void *handle, void *device, int width, + int height, int raster, unsigned int format); + int displaySizeFunction(void *handle, void *device, int width, + int height, int raster, unsigned int format, + unsigned char *pimage); + int displaySyncFunction(void *handle, void *device); + int displayPageFunction(void *handle, void *device, int copies, + int flush); + int displayUpdateFunction(void *handle, void *device, int x, + int y, int w, int h); + // display_memalloc omitted + // display_memfree omitted + int displaySeparationFunction(void *handle, void *device, + int component, const char *componentName, unsigned short c, + unsigned short m, unsigned short y, unsigned short k); + int displayAdjustBandHeightFunction(void *handle, void *device, + int bandHeight); + int displayRectangleRequestFunction(void *handle, void *device, + void **memory, int *ox, int *oy, int *raster, int *plane_raster, + int *x, int *y, int *w, int *h); + } + + void setCalloutCallback(jobject calout); + int calloutFunction(void *instance, void *handle, const char *deviceName, int id, int size, void *data); +} \ No newline at end of file diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp new file mode 100644 index 00000000..7858112e --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.cpp @@ -0,0 +1,555 @@ +#include "com_artifex_gsjava_GSAPI.h" + +#include +#include +#include +#include + +#include "jni_util.h" +#include "callbacks.h" + +using namespace util; + +static void *getAsPointer(JNIEnv *env, jobject object, gs_set_param_type type, bool *success); + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1revision + (JNIEnv *env, jclass, jobject revision, jint len) +{ + if (revision == NULL) + return throwNullPointerException(env, "Revision object is NULL"); + gsapi_revision_t gsrevision; + jint code = gsapi_revision(&gsrevision, sizeof(gsapi_revision_t)); + if (code == 0) + { + setByteArrayField(env, revision, "product", gsrevision.product); + setByteArrayField(env, revision, "copyright", gsrevision.copyright); + setLongField(env, revision, "revision", gsrevision.revision); + setLongField(env, revision, "revisionDate", gsrevision.revisiondate); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1new_1instance + (JNIEnv *env, jclass, jobject instance, jlong callerHandle) +{ + if (instance == NULL) + return throwNullPointerException(env, "LongReference object is NULL"); + + void *gsInstance; + int code = gsapi_new_instance(&gsInstance, (void *)callerHandle); + if (code == 0) + Reference::setValueField(env, instance, toWrapperType(env, (jlong)gsInstance)); + return code; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1delete_1instance + (JNIEnv *env, jclass, jlong instance) +{ + callbacks::setJNIEnv(env); + gsapi_delete_instance((void *)instance); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1handle + (JNIEnv *env, jclass, jlong instance, jobject stdIn, jobject stdOut, jobject stdErr, jlong callerHandle) +{ + int code = gsapi_set_stdio_with_handle((void *)instance, callbacks::stdInFunction, + callbacks::stdOutFunction, callbacks::stdErrFunction, (void *)callerHandle); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setIOCallbacks(stdIn, stdOut, stdErr); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio + (JNIEnv *env, jclass, jlong instance, jobject stdIn, jobject stdOut, jobject stdErr) +{ + int code = gsapi_set_stdio((void *)instance, callbacks::stdInFunction, + callbacks::stdOutFunction, callbacks::stdErrFunction); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setIOCallbacks(stdIn, stdOut, stdErr); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll_1with_1handle + (JNIEnv *env, jclass, jlong instance, jobject poll, jlong callerHandle) +{ + int code = gsapi_set_poll_with_handle((void *)instance, callbacks::pollFunction, (void *)callerHandle); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setPollCallback(poll); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll + (JNIEnv *env, jclass, jlong instance, jobject poll) +{ + int code = gsapi_set_poll((void *)instance, callbacks::pollFunction); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setPollCallback(poll); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1display_1callback + (JNIEnv *env, jclass, jlong instance, jobject displayCallback) +{ + display_callback *cb = new display_callback; + cb->size = sizeof(display_callback); + cb->version_major = DISPLAY_VERSION_MAJOR; + cb->version_minor = DISPLAY_VERSION_MINOR; + + cb->display_open = callbacks::display::displayOpenFunction; + cb->display_preclose = callbacks::display::displayPrecloseFunction; + cb->display_close = callbacks::display::displayCloseFunction; + cb->display_presize = callbacks::display::displayPresizeFunction; + cb->display_size = callbacks::display::displaySizeFunction; + cb->display_sync = callbacks::display::displaySyncFunction; + cb->display_page = callbacks::display::displayPageFunction; + cb->display_update = callbacks::display::displayUpdateFunction; + cb->display_memalloc = NULL; + cb->display_memfree = NULL; + cb->display_separation = callbacks::display::displaySeparationFunction; + cb->display_adjust_band_height = callbacks::display::displayAdjustBandHeightFunction; + cb->display_rectangle_request = callbacks::display::displayRectangleRequestFunction; + + int code = gsapi_set_display_callback((void *)instance, cb); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setDisplayCallback(displayCallback); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1register_1callout + (JNIEnv *env, jclass, jlong instance, jobject callout, jlong calloutHandle) +{ + int code = gsapi_register_callout((void *)instance, callbacks::calloutFunction, (void *)calloutHandle); + if (code == 0) + { + callbacks::setJNIEnv(env); + callbacks::setCalloutCallback(callout); + } + return code; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1deregister_1callout + (JNIEnv *env, jclass, jlong instance, jobject callout, jlong calloutHandle) +{ + gsapi_deregister_callout((void *)instance, callbacks::calloutFunction, (void *)calloutHandle); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1arg_1encoding + (JNIEnv *env, jclass, jlong instance, jint encoding) +{ + return gsapi_set_arg_encoding((void *)instance, encoding); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1default_1device_1list + (JNIEnv *env, jclass, jlong instance, jbyteArray list, jint listlen) +{ + if (list == NULL) + return throwNullPointerException(env, "list"); + jboolean isCopy = false; + callbacks::setJNIEnv(env); + int code = gsapi_set_default_device_list((void *)instance, + (const char *)env->GetByteArrayElements(list, &isCopy), listlen); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1default_1device_1list + (JNIEnv *env, jclass, jlong instance, jobject list, jobject listlen) +{ + char *clist = NULL; + int clistlen = 0; + int code = gsapi_get_default_device_list((void *)instance, &clist, &clistlen); + if (code == 0) + { + if (list) + { + jbyteArray arr = env->NewByteArray(clistlen); + env->SetByteArrayRegion(arr, 0, clistlen, (jbyte *)clist); + Reference::setValueField(env, list, arr); + env->DeleteLocalRef(arr); + } + if (listlen) + Reference::setValueField(env, listlen, toWrapperType(env, (jint)clistlen)); + } + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1init_1with_1args + (JNIEnv *env, jclass, jlong instance, jint argc, jobjectArray argv) +{ + if (argv == NULL) + return throwNullPointerException(env, "argv"); + char **cargv = jbyteArray2DToCharArray(env, argv); + callbacks::setJNIEnv(env); + int code = gsapi_init_with_args((void *)instance, argc, cargv); + delete2DByteArray(argc, cargv); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1begin + (JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode) +{ + int exitCode; + callbacks::setJNIEnv(env); + int code = gsapi_run_string_begin((void *)instance, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1continue + (JNIEnv *env, jclass, jlong instance, jbyteArray str, jint length, jint userErrors, jobject pExitCode) +{ + if (str == NULL) + return throwNullPointerException(env, "str"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(str, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_string_continue((void *)instance, cstring, length, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1end + (JNIEnv *env, jclass, jlong instance, jint userErrors, jobject pExitCode) +{ + int exitCode; + callbacks::setJNIEnv(env); + int code = gsapi_run_string_end((void *)instance, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1with_1length + (JNIEnv *env, jclass, jlong instance, jbyteArray str, jint length, jint userErrors, jobject pExitCode) +{ + if (str == NULL) + return throwNullPointerException(env, "str"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(str, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_string_with_length((void *)instance, cstring, length, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string + (JNIEnv *env, jclass, jlong instance, jbyteArray str, jint userErrors, jobject pExitCode) +{ + if (str == NULL) + return throwNullPointerException(env, "str"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(str, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_string((void *)instance, cstring, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1file + (JNIEnv *env, jclass, jlong instance, jbyteArray fileName, jint userErrors, jobject pExitCode) +{ + if (fileName == NULL) + return throwNullPointerException(env, "fileName"); + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(fileName, ©); + callbacks::setJNIEnv(env); + int code = gsapi_run_file((void *)instance, cstring, userErrors, &exitCode); + if (pExitCode) + Reference::setValueField(env, pExitCode, toWrapperType(env, (jint)exitCode)); + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1exit + (JNIEnv *env, jclass, jlong instance) +{ + return gsapi_exit((void *)instance); +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1param + (JNIEnv *env, jclass, jlong instance, jbyteArray param, jobject value, jint paramType) +{ + if (!param) + { + throwNullPointerException(env, "param"); + return -1; + } + + gs_set_param_type type = (gs_set_param_type)paramType; + bool paramSuccess; + void *data = getAsPointer(env, value, type, ¶mSuccess); + if (!paramSuccess) + { + throwIllegalArgumentException(env, "paramType"); + return -1; + } + + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(param, ©); + + callbacks::setJNIEnv(env); + int code = gsapi_set_param((void *)instance, cstring, data, type); + free(data); + + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param + (JNIEnv *env, jclass, jlong instance, jbyteArray param, jlong value, jint paramType) +{ + if (!param) + { + throwNullPointerException(env, "paramType"); + return -1; + } + + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(param, ©); + + int ret = gsapi_get_param((void *)instance, cstring, (void *)value, (gs_set_param_type)paramType); + + return ret; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param_1once + (JNIEnv *env, jclass, jlong instance, jbyteArray param, jobject value, jint paramType) +{ + jboolean copy = false; + int exitCode; + const char *cstring = (const char *)env->GetByteArrayElements(param, ©); + + int bytes = gsapi_get_param((void *)instance, cstring, NULL, (gs_set_param_type)paramType); + if (bytes < 0) + return bytes; + + void *data = new char[bytes]; + int code = gsapi_get_param((void *)instance, cstring, data, (gs_set_param_type)paramType); + if (code < 0) + { + delete[] data; + return code; + } + + int stripped = paramType & ~(gs_spt_more_to_come); + Reference ref = Reference(env, value); + + jbyteArray arr = NULL; + const char *str = NULL; + int len = 0; + switch (stripped) + { + case gs_spt_null: + break; + case gs_spt_bool: + ref.set((jboolean)*((int *)data)); + break; + case gs_spt_int: + ref.set(*((jint *)data)); + break; + case gs_spt_float: + ref.set(*((jfloat *)data)); + break; + case gs_spt_long: + ref.set(*((jlong *)data)); + break; + case gs_spt_i64: + ref.set((jlong)*((long long *)data)); + break; + case gs_spt_size_t: + ref.set((jlong)*((size_t *)data)); + break; + case gs_spt_name: + case gs_spt_string: + case gs_spt_parsed: + str = (const char *)data; + len = strlen(str) + 1; + arr = env->NewByteArray(len); + env->SetByteArrayRegion(arr, 0, len, (const jbyte *)str); + ref.set(arr); + break; + case gs_spt_invalid: + default: + throwIllegalArgumentException(env, "paramType"); + delete[] data; + return -1; + break; + } + delete[] data; + return 0; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1enumerate_1params + (JNIEnv *env, jclass, jlong instance, jobject iter, jobject key, jobject paramType) +{ + if (!iter) + { + throwNullPointerException(env, "iterator is NULL"); + return -1; + } + + Reference iterRef = Reference(env, iter); + + Reference keyRef = Reference(env, key); + Reference typeRef = Reference(env, paramType); + + void *citer = (void *)iterRef.longValue(); + + if (env->ExceptionCheck()) + return -1; + + const char *ckey; + gs_set_param_type type; + + int code = gsapi_enumerate_params((void *)instance, &citer, &ckey, &type); + + if (code == 0) + { + iterRef.set((jlong)citer); + + jsize len = strlen(ckey) + 1; + jbyteArray arr = env->NewByteArray(len); + env->SetByteArrayRegion(arr, 0, len, (const jbyte *)ckey); + keyRef.set(arr); + env->DeleteLocalRef(arr); + + typeRef.set((jint)type); + } + + return code; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1add_1control_1path + (JNIEnv *env, jclass, jlong instance, jint type, jbyteArray path) +{ + if (!path) + { + throwNullPointerException(env, "path is NULL"); + return -1; + } + + jboolean copy = false; + const char *cstring = (const char *)env->GetByteArrayElements(path, ©); + + int exitCode = gsapi_add_control_path((void *)instance, type, cstring); + + return exitCode; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1remove_1control_1path +(JNIEnv *env, jclass, jlong instance, jint type, jbyteArray path) +{ + if (!path) + { + throwNullPointerException(env, "path is NULL"); + return -1; + } + + jboolean copy = false; + const char *cstring = (const char *)env->GetByteArrayElements(path, ©); + + int exitCode = gsapi_remove_control_path((void *)instance, type, cstring); + + return exitCode; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1purge_1control_1paths + (JNIEnv *, jclass, jlong instance, jint type) +{ + gsapi_purge_control_paths((void *)instance, type); +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1activate_1path_1control + (JNIEnv *, jclass, jlong instance, jboolean enable) +{ + gsapi_activate_path_control((void *)instance, enable); +} + +JNIEXPORT jboolean JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1is_1path_1control_1active + (JNIEnv *env, jclass, jlong instance) +{ + return gsapi_is_path_control_active((void *)instance); +} + +void *getAsPointer(JNIEnv *env, jobject object, gs_set_param_type type, bool *success) +{ + *success = true; + void *result = NULL; + int stripped = type & ~gs_spt_more_to_come; + + jbyteArray arr = NULL; + jboolean copy = false; + const char *cstring = NULL; + jsize len = 0; + switch (stripped) + { + case gs_spt_null: + return result; + break; + case gs_spt_bool: + result = malloc(sizeof(int)); + *((int *)result) = (bool)toBoolean(env, object); + break; + case gs_spt_int: + result = malloc(sizeof(int)); + *((int *)result) = (int)toInt(env, object); + break; + case gs_spt_float: + result = malloc(sizeof(float)); + *((float *)result) = (float)toFloat(env, object); + break; + case gs_spt_long: + case gs_spt_i64: + result = malloc(sizeof(long long)); + *((long long *)result) = (long long)toLong(env, object); + break; + case gs_spt_size_t: + result = malloc(sizeof(size_t)); + *((size_t *)result) = (size_t)toLong(env, object); + break; + case gs_spt_name: + case gs_spt_string: + case gs_spt_parsed: + arr = (jbyteArray)object; + cstring = (const char *)env->GetByteArrayElements(arr, ©); + len = env->GetArrayLength(arr); + result = malloc(sizeof(char) * len); + //((char *)result)[len - 1] = 0; + memcpy(result, cstring, len); + break; + case gs_spt_invalid: + default: + *success = false; + break; + } + if (env->ExceptionCheck()) + { + if (result) + free(result); + result = NULL; + *success = false; + } + return result; +} diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h new file mode 100644 index 00000000..68c61e58 --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_GSAPI.h @@ -0,0 +1,386 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_artifex_gsjava_GSAPI */ + +#ifndef _Included_com_artifex_gsjava_GSAPI +#define _Included_com_artifex_gsjava_GSAPI +#ifdef __cplusplus +extern "C" { +#endif +#undef com_artifex_gsjava_GSAPI_GS_NULL +#define com_artifex_gsjava_GSAPI_GS_NULL 0i64 +#undef com_artifex_gsjava_GSAPI_GS_ERROR_OK +#define com_artifex_gsjava_GSAPI_GS_ERROR_OK 0L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNKNOWNERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNKNOWNERROR -1L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_DICTFULL +#define com_artifex_gsjava_GSAPI_GS_ERROR_DICTFULL -2L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKOVERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKOVERFLOW -3L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKUNDERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_DICTSTACKUNDERFLOW -4L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_EXECSTACKOVERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_EXECSTACKOVERFLOW -5L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INTERRUPT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INTERRUPT -6L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDACCESS +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDACCESS -7L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDEXIT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDEXIT -8L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFILEACCESS +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFILEACCESS -9L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFONT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDFONT -10L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDRESTORE +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDRESTORE -11L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_IOERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_IOERROR -12L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_LIMITCHECK +#define com_artifex_gsjava_GSAPI_GS_ERROR_LIMITCHECK -13L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_NOCURRENTPOINT +#define com_artifex_gsjava_GSAPI_GS_ERROR_NOCURRENTPOINT -14L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_RANGECHECK +#define com_artifex_gsjava_GSAPI_GS_ERROR_RANGECHECK -15L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_STACKOVERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_STACKOVERFLOW -16L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_STACKUNDERFLOW +#define com_artifex_gsjava_GSAPI_GS_ERROR_STACKUNDERFLOW -17L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_SYNTAXERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_SYNTAXERROR -18L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_TIMEOUT +#define com_artifex_gsjava_GSAPI_GS_ERROR_TIMEOUT -19L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_TYPECHECK +#define com_artifex_gsjava_GSAPI_GS_ERROR_TYPECHECK -20L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINED +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINED -21L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDFILENAME +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDFILENAME -22L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESULT +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESULT -23L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNMATCHEDMARK +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNMATCHEDMARK -24L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_VMERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_VMERROR -25L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_CONFIGURATION_ERROR +#define com_artifex_gsjava_GSAPI_GS_ERROR_CONFIGURATION_ERROR -26L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESOURCE +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNDEFINEDRESOURCE -27L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_UNREGISTERED +#define com_artifex_gsjava_GSAPI_GS_ERROR_UNREGISTERED -28L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDCONTEXT +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALIDCONTEXT -29L +#undef com_artifex_gsjava_GSAPI_GS_ERROR_INVALID +#define com_artifex_gsjava_GSAPI_GS_ERROR_INVALID -30L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_NATIVE +#define com_artifex_gsjava_GSAPI_GS_COLORS_NATIVE 1L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_GRAY +#define com_artifex_gsjava_GSAPI_GS_COLORS_GRAY 2L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_RGB +#define com_artifex_gsjava_GSAPI_GS_COLORS_RGB 4L +#undef com_artifex_gsjava_GSAPI_GS_COLORS_CMYK +#define com_artifex_gsjava_GSAPI_GS_COLORS_CMYK 8L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_SEPARATION +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_SEPARATION 524288L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_COLORS_MASK 524303i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_NONE +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_NONE 0L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_FIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_FIRST 16L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_LAST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_LAST 32L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_FIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_FIRST 64L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_LAST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_UNUSED_LAST 128L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ALPHA_MASK 240i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_1 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_1 256L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_2 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_2 512L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_4 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_4 1024L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_8 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_8 2048L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_12 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_12 4096L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_16 +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_16 8L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_DEPTH_MASK 65280i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_BIGENDIAN +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_BIGENDIAN 0L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_LITTLEENDIAN +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_LITTLEENDIAN 65536L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_ENDIAN_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_ENDIAN_MASK 65536i64 +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_TOPFIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_TOPFIRST 0L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_BOTTOMFIRST +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_BOTTOMFIRST 131072L +#undef com_artifex_gsjava_GSAPI_GS_DISPLAY_FIRSTROW_MASK +#define com_artifex_gsjava_GSAPI_GS_DISPLAY_FIRSTROW_MASK 131072i64 +#undef com_artifex_gsjava_GSAPI_GS_SPT_INVALID +#define com_artifex_gsjava_GSAPI_GS_SPT_INVALID -1L +#undef com_artifex_gsjava_GSAPI_GS_SPT_NULL +#define com_artifex_gsjava_GSAPI_GS_SPT_NULL 0L +#undef com_artifex_gsjava_GSAPI_GS_SPT_BOOL +#define com_artifex_gsjava_GSAPI_GS_SPT_BOOL 1L +#undef com_artifex_gsjava_GSAPI_GS_SPT_INT +#define com_artifex_gsjava_GSAPI_GS_SPT_INT 2L +#undef com_artifex_gsjava_GSAPI_GS_SPT_FLOAT +#define com_artifex_gsjava_GSAPI_GS_SPT_FLOAT 3L +#undef com_artifex_gsjava_GSAPI_GS_SPT_NAME +#define com_artifex_gsjava_GSAPI_GS_SPT_NAME 4L +#undef com_artifex_gsjava_GSAPI_GS_SPT_STRING +#define com_artifex_gsjava_GSAPI_GS_SPT_STRING 5L +#undef com_artifex_gsjava_GSAPI_GS_SPT_LONG +#define com_artifex_gsjava_GSAPI_GS_SPT_LONG 6L +#undef com_artifex_gsjava_GSAPI_GS_SPT_I64 +#define com_artifex_gsjava_GSAPI_GS_SPT_I64 7L +#undef com_artifex_gsjava_GSAPI_GS_SPT_SIZE_T +#define com_artifex_gsjava_GSAPI_GS_SPT_SIZE_T 8L +#undef com_artifex_gsjava_GSAPI_GS_SPT_PARSED +#define com_artifex_gsjava_GSAPI_GS_SPT_PARSED 9L +#undef com_artifex_gsjava_GSAPI_GS_SPT_MORE_TO_COME +#define com_artifex_gsjava_GSAPI_GS_SPT_MORE_TO_COME -2147483648L + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_revision + * Signature: (Lcom/artifex/gsjava/GSAPI/Revision;I)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1revision + (JNIEnv *, jclass, jobject, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_new_instance + * Signature: (Lcom/artifex/gsjava/util/Reference;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1new_1instance + (JNIEnv *, jclass, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_delete_instance + * Signature: (J)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1delete_1instance + (JNIEnv *, jclass, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_stdio_with_handle + * Signature: (JLcom/artifex/gsjava/callbacks/IStdInFunction;Lcom/artifex/gsjava/callbacks/IStdOutFunction;Lcom/artifex/gsjava/callbacks/IStdErrFunction;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio_1with_1handle + (JNIEnv *, jclass, jlong, jobject, jobject, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_stdio + * Signature: (JLcom/artifex/gsjava/callbacks/IStdInFunction;Lcom/artifex/gsjava/callbacks/IStdOutFunction;Lcom/artifex/gsjava/callbacks/IStdErrFunction;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1stdio + (JNIEnv *, jclass, jlong, jobject, jobject, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_poll_with_handle + * Signature: (JLcom/artifex/gsjava/callbacks/IPollFunction;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll_1with_1handle + (JNIEnv *, jclass, jlong, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_poll + * Signature: (JLcom/artifex/gsjava/callbacks/IPollFunction;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1poll + (JNIEnv *, jclass, jlong, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_display_callback + * Signature: (JLcom/artifex/gsjava/callbacks/DisplayCallback;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1display_1callback + (JNIEnv *, jclass, jlong, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_register_callout + * Signature: (JLcom/artifex/gsjava/callbacks/ICalloutFunction;J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1register_1callout + (JNIEnv *, jclass, jlong, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_deregister_callout + * Signature: (JLcom/artifex/gsjava/callbacks/ICalloutFunction;J)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1deregister_1callout + (JNIEnv *, jclass, jlong, jobject, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_arg_encoding + * Signature: (JI)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1arg_1encoding + (JNIEnv *, jclass, jlong, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_default_device_list + * Signature: (J[BI)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1default_1device_1list + (JNIEnv *, jclass, jlong, jbyteArray, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_get_default_device_list + * Signature: (JLcom/artifex/gsjava/util/Reference;Lcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1default_1device_1list + (JNIEnv *, jclass, jlong, jobject, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_init_with_args + * Signature: (JI[[B)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1init_1with_1args + (JNIEnv *, jclass, jlong, jint, jobjectArray); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_begin + * Signature: (JILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1begin + (JNIEnv *, jclass, jlong, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_continue + * Signature: (J[BIILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1continue + (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_end + * Signature: (JILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1end + (JNIEnv *, jclass, jlong, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string_with_length + * Signature: (J[BIILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string_1with_1length + (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_string + * Signature: (J[BILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1string + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_run_file + * Signature: (J[BILcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1run_1file + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_exit + * Signature: (J)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1exit + (JNIEnv *, jclass, jlong); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_set_param + * Signature: (J[BLjava/lang/Object;I)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1set_1param + (JNIEnv *, jclass, jlong, jbyteArray, jobject, jint); + + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param + (JNIEnv *, jclass, jlong, jbyteArray, jlong, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_get_param_once + * Signature: (J[BLcom/artifex/gsjava/util/Reference;I)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1get_1param_1once + (JNIEnv *, jclass, jlong, jbyteArray, jobject, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_enumerate_params + * Signature: (JLcom/artifex/gsjava/util/Reference;Lcom/artifex/gsjava/util/ByteArrayReference;Lcom/artifex/gsjava/util/Reference;)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1enumerate_1params + (JNIEnv *, jclass, jlong, jobject, jobject, jobject); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_add_control_path + * Signature: (JI[B)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1add_1control_1path + (JNIEnv *, jclass, jlong, jint, jbyteArray); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_remove_control_path + * Signature: (JI[B)I + */ + JNIEXPORT jint JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1remove_1control_1path + (JNIEnv *, jclass, jlong, jint, jbyteArray); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_purge_control_paths + * Signature: (JI)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1purge_1control_1paths + (JNIEnv *, jclass, jlong, jint); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_activate_path_control + * Signature: (JZ)V + */ + JNIEXPORT void JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1activate_1path_1control + (JNIEnv *, jclass, jlong, jboolean); + + /* + * Class: com_artifex_gsjava_GSAPI + * Method: gsapi_is_path_control_active + * Signature: (J)Z + */ + JNIEXPORT jboolean JNICALL Java_com_artifex_gsjava_GSAPI_gsapi_1is_1path_1control_1active + (JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.cpp b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.cpp new file mode 100644 index 00000000..b58c070c --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.cpp @@ -0,0 +1,131 @@ +#include "com_artifex_gsjava_util_NativePointer.h" + +#include + +#include "jni_util.h" + +using namespace util; + +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_mallocNative +(JNIEnv *env, jclass, jlong size) +{ + void *ptr = malloc((size_t)size); + if (ptr == NULL) + return throwAllocationError(env, "malloc"); + return (jlong)ptr; +} + +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_callocNative +(JNIEnv *env, jclass, jlong count, jlong size) +{ + void *ptr = calloc(count, (size_t)size); + if (ptr == NULL) + return throwAllocationError(env, "calloc"); + return (jlong)ptr; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_freeNative +(JNIEnv *, jclass, jlong block) +{ + free((void *)block); +} + +JNIEXPORT jbyteArray JNICALL Java_com_artifex_gsjava_util_NativePointer_byteArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jbyteArray array = env->NewByteArray(len); + env->SetByteArrayRegion(array, 0, len, (const jbyte *)address); + return array; +} + +JNIEXPORT jbyte JNICALL Java_com_artifex_gsjava_util_NativePointer_byteAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jbyte *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setByteNative +(JNIEnv *, jclass, jlong address, jlong index, jbyte value) +{ + ((jbyte *)address)[index]; +} + +JNIEXPORT jcharArray JNICALL Java_com_artifex_gsjava_util_NativePointer_charArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jcharArray array = env->NewCharArray(len); + env->SetCharArrayRegion(array, 0, len, (const jchar *)address); + return array; +} + +JNIEXPORT jchar JNICALL Java_com_artifex_gsjava_util_NativePointer_charAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jchar *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setCharNative +(JNIEnv *, jclass, jlong address, jlong index, jchar value) +{ + ((jchar *)address)[index] = value; +} + +JNIEXPORT jshortArray JNICALL Java_com_artifex_gsjava_util_NativePointer_shortArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jshortArray array = env->NewShortArray(len); + env->SetShortArrayRegion(array, 0, len, (const jshort *)address); + return array; +} + +JNIEXPORT jshort JNICALL Java_com_artifex_gsjava_util_NativePointer_shortAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jshort *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setShortNative +(JNIEnv *, jclass, jlong address, jlong index, jshort value) +{ + ((jshort *)address)[index] = value; +} + +JNIEXPORT jintArray JNICALL Java_com_artifex_gsjava_util_NativePointer_intArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jintArray array = env->NewIntArray(len); + env->SetIntArrayRegion(array, 0, len, (const jint *)address); + return array; +} + +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_util_NativePointer_intAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jint *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setIntNative +(JNIEnv *, jclass, jlong address, jlong index, jint value) +{ + ((jint *)address)[index] = value; +} + +JNIEXPORT jlongArray JNICALL Java_com_artifex_gsjava_util_NativePointer_longArrayNative +(JNIEnv *env, jclass, jlong address, jlong len) +{ + jlongArray array = env->NewLongArray(len); + env->SetLongArrayRegion(array, 0, len, (const jlong *)address); + return array; +} + +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_longAtNative +(JNIEnv *, jclass, jlong address, jlong index) +{ + return ((jlong *)address)[index]; +} + +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setLongNative +(JNIEnv *, jclass, jlong address, jlong index, jlong value) +{ + ((jlong *)address)[index] = value; +} \ No newline at end of file diff --git a/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.h b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.h new file mode 100644 index 00000000..8dd6a30b --- /dev/null +++ b/demos/java/jni/gs_jni/com_artifex_gsjava_util_NativePointer.h @@ -0,0 +1,169 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_artifex_gsjava_util_NativePointer */ + +#ifndef _Included_com_artifex_gsjava_util_NativePointer +#define _Included_com_artifex_gsjava_util_NativePointer +#ifdef __cplusplus +extern "C" { +#endif +#undef com_artifex_gsjava_util_NativePointer_NULL +#define com_artifex_gsjava_util_NativePointer_NULL 0i64 +#undef com_artifex_gsjava_util_NativePointer_BYTE_SIZE +#define com_artifex_gsjava_util_NativePointer_BYTE_SIZE 1i64 +#undef com_artifex_gsjava_util_NativePointer_CHAR_SIZE +#define com_artifex_gsjava_util_NativePointer_CHAR_SIZE 2i64 +#undef com_artifex_gsjava_util_NativePointer_SHORT_SIZE +#define com_artifex_gsjava_util_NativePointer_SHORT_SIZE 2i64 +#undef com_artifex_gsjava_util_NativePointer_INT_SIZE +#define com_artifex_gsjava_util_NativePointer_INT_SIZE 4i64 +#undef com_artifex_gsjava_util_NativePointer_LONG_SIZE +#define com_artifex_gsjava_util_NativePointer_LONG_SIZE 8i64 +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: mallocNative + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_mallocNative + (JNIEnv *, jclass, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: callocNative + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_callocNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: freeNative + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_freeNative + (JNIEnv *, jclass, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: byteArrayNative + * Signature: (JJ)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_artifex_gsjava_util_NativePointer_byteArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: byteAtNative + * Signature: (JJ)B + */ +JNIEXPORT jbyte JNICALL Java_com_artifex_gsjava_util_NativePointer_byteAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setByteNative + * Signature: (JJB)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setByteNative + (JNIEnv *, jclass, jlong, jlong, jbyte); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: charArrayNative + * Signature: (JJ)[C + */ +JNIEXPORT jcharArray JNICALL Java_com_artifex_gsjava_util_NativePointer_charArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: charAtNative + * Signature: (JJ)C + */ +JNIEXPORT jchar JNICALL Java_com_artifex_gsjava_util_NativePointer_charAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setCharNative + * Signature: (JJC)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setCharNative + (JNIEnv *, jclass, jlong, jlong, jchar); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: shortArrayNative + * Signature: (JJ)[S + */ +JNIEXPORT jshortArray JNICALL Java_com_artifex_gsjava_util_NativePointer_shortArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: shortAtNative + * Signature: (JJ)S + */ +JNIEXPORT jshort JNICALL Java_com_artifex_gsjava_util_NativePointer_shortAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setShortNative + * Signature: (JJS)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setShortNative + (JNIEnv *, jclass, jlong, jlong, jshort); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: intArrayNative + * Signature: (JJ)[I + */ +JNIEXPORT jintArray JNICALL Java_com_artifex_gsjava_util_NativePointer_intArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: intAtNative + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_artifex_gsjava_util_NativePointer_intAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setIntNative + * Signature: (JJI)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setIntNative + (JNIEnv *, jclass, jlong, jlong, jint); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: longArrayNative + * Signature: (JJ)[J + */ +JNIEXPORT jlongArray JNICALL Java_com_artifex_gsjava_util_NativePointer_longArrayNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: longAtNative + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_com_artifex_gsjava_util_NativePointer_longAtNative + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_artifex_gsjava_util_NativePointer + * Method: setLongNative + * Signature: (JJJ)V + */ +JNIEXPORT void JNICALL Java_com_artifex_gsjava_util_NativePointer_setLongNative + (JNIEnv *, jclass, jlong, jlong, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/demos/java/jni/gs_jni/dllmain.cpp b/demos/java/jni/gs_jni/dllmain.cpp new file mode 100644 index 00000000..f6091f3f --- /dev/null +++ b/demos/java/jni/gs_jni/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : Defines the entry point for the DLL application. + +#include + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} \ No newline at end of file diff --git a/demos/java/jni/gs_jni/framework.h b/demos/java/jni/gs_jni/framework.h new file mode 100644 index 00000000..54b83e94 --- /dev/null +++ b/demos/java/jni/gs_jni/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include diff --git a/demos/java/jni/gs_jni/gs_jni.sln b/demos/java/jni/gs_jni/gs_jni.sln new file mode 100644 index 00000000..965b2df5 --- /dev/null +++ b/demos/java/jni/gs_jni/gs_jni.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30225.117 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gs_jni", "gs_jni.vcxproj", "{72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x64.ActiveCfg = Debug|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x64.Build.0 = Debug|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x86.ActiveCfg = Debug|Win32 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Debug|x86.Build.0 = Debug|Win32 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x64.ActiveCfg = Release|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x64.Build.0 = Release|x64 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x86.ActiveCfg = Release|Win32 + {72CAF1B0-7CA6-4044-8705-E0FB2DFF01DD}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {70A01221-9F8F-496E-A834-AA2EB06F515A} + EndGlobalSection +EndGlobal diff --git a/demos/java/jni/gs_jni/gs_jni.vcxproj b/demos/java/jni/gs_jni/gs_jni.vcxproj new file mode 100644 index 00000000..eae045e8 --- /dev/null +++ b/demos/java/jni/gs_jni/gs_jni.vcxproj @@ -0,0 +1,184 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {72caf1b0-7ca6-4044-8705-e0fb2dff01dd} + gsjni + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + + + $(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories) + + + Windows + true + false + %(AdditionalDependencies) + $(SolutionDir)..\..\..\..\debugbin;%(AdditionalLibraryDirectories) + + + + + Level3 + true + true + true + WIN32;NDEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + + + $(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + + + $(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories) + + + Windows + true + false + gpdldll64.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\..\..\debugbin;%(AdditionalLibraryDirectories) + + + + + Level3 + true + true + true + NDEBUG;GSJNI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + + + $(SolutionDir)..\..\..\..\psi;$(SolutionDir)include;$(SolutionDir)..\..\..\..\..\ghostpdl\devices;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + false + $(SolutionDir)..\..\..\..\bin;%(AdditionalLibraryDirectories) + gpdldll64.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/java/jni/gs_jni/gs_jni.vcxproj.filters b/demos/java/jni/gs_jni/gs_jni.vcxproj.filters new file mode 100644 index 00000000..14063f1b --- /dev/null +++ b/demos/java/jni/gs_jni/gs_jni.vcxproj.filters @@ -0,0 +1,51 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/demos/java/jni/gs_jni/include/classfile_constants.h b/demos/java/jni/gs_jni/include/classfile_constants.h new file mode 100644 index 00000000..e5c20cd9 --- /dev/null +++ b/demos/java/jni/gs_jni/include/classfile_constants.h @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef CLASSFILE_CONSTANTS_H +#define CLASSFILE_CONSTANTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Classfile version number for this information */ +#define JVM_CLASSFILE_MAJOR_VERSION 52 +#define JVM_CLASSFILE_MINOR_VERSION 0 + +/* Flags */ + +enum { + JVM_ACC_PUBLIC = 0x0001, + JVM_ACC_PRIVATE = 0x0002, + JVM_ACC_PROTECTED = 0x0004, + JVM_ACC_STATIC = 0x0008, + JVM_ACC_FINAL = 0x0010, + JVM_ACC_SYNCHRONIZED = 0x0020, + JVM_ACC_SUPER = 0x0020, + JVM_ACC_VOLATILE = 0x0040, + JVM_ACC_BRIDGE = 0x0040, + JVM_ACC_TRANSIENT = 0x0080, + JVM_ACC_VARARGS = 0x0080, + JVM_ACC_NATIVE = 0x0100, + JVM_ACC_INTERFACE = 0x0200, + JVM_ACC_ABSTRACT = 0x0400, + JVM_ACC_STRICT = 0x0800, + JVM_ACC_SYNTHETIC = 0x1000, + JVM_ACC_ANNOTATION = 0x2000, + JVM_ACC_ENUM = 0x4000 +}; + +/* Used in newarray instruction. */ + +enum { + JVM_T_BOOLEAN = 4, + JVM_T_CHAR = 5, + JVM_T_FLOAT = 6, + JVM_T_DOUBLE = 7, + JVM_T_BYTE = 8, + JVM_T_SHORT = 9, + JVM_T_INT = 10, + JVM_T_LONG = 11 +}; + +/* Constant Pool Entries */ + +enum { + JVM_CONSTANT_Utf8 = 1, + JVM_CONSTANT_Unicode = 2, /* unused */ + JVM_CONSTANT_Integer = 3, + JVM_CONSTANT_Float = 4, + JVM_CONSTANT_Long = 5, + JVM_CONSTANT_Double = 6, + JVM_CONSTANT_Class = 7, + JVM_CONSTANT_String = 8, + JVM_CONSTANT_Fieldref = 9, + JVM_CONSTANT_Methodref = 10, + JVM_CONSTANT_InterfaceMethodref = 11, + JVM_CONSTANT_NameAndType = 12, + JVM_CONSTANT_MethodHandle = 15, // JSR 292 + JVM_CONSTANT_MethodType = 16, // JSR 292 + JVM_CONSTANT_InvokeDynamic = 18 +}; + +/* JVM_CONSTANT_MethodHandle subtypes */ +enum { + JVM_REF_getField = 1, + JVM_REF_getStatic = 2, + JVM_REF_putField = 3, + JVM_REF_putStatic = 4, + JVM_REF_invokeVirtual = 5, + JVM_REF_invokeStatic = 6, + JVM_REF_invokeSpecial = 7, + JVM_REF_newInvokeSpecial = 8, + JVM_REF_invokeInterface = 9 +}; + +/* StackMapTable type item numbers */ + +enum { + JVM_ITEM_Top = 0, + JVM_ITEM_Integer = 1, + JVM_ITEM_Float = 2, + JVM_ITEM_Double = 3, + JVM_ITEM_Long = 4, + JVM_ITEM_Null = 5, + JVM_ITEM_UninitializedThis = 6, + JVM_ITEM_Object = 7, + JVM_ITEM_Uninitialized = 8 +}; + +/* Type signatures */ + +enum { + JVM_SIGNATURE_ARRAY = '[', + JVM_SIGNATURE_BYTE = 'B', + JVM_SIGNATURE_CHAR = 'C', + JVM_SIGNATURE_CLASS = 'L', + JVM_SIGNATURE_ENDCLASS = ';', + JVM_SIGNATURE_ENUM = 'E', + JVM_SIGNATURE_FLOAT = 'F', + JVM_SIGNATURE_DOUBLE = 'D', + JVM_SIGNATURE_FUNC = '(', + JVM_SIGNATURE_ENDFUNC = ')', + JVM_SIGNATURE_INT = 'I', + JVM_SIGNATURE_LONG = 'J', + JVM_SIGNATURE_SHORT = 'S', + JVM_SIGNATURE_VOID = 'V', + JVM_SIGNATURE_BOOLEAN = 'Z' +}; + +/* Opcodes */ + +enum { + JVM_OPC_nop = 0, + JVM_OPC_aconst_null = 1, + JVM_OPC_iconst_m1 = 2, + JVM_OPC_iconst_0 = 3, + JVM_OPC_iconst_1 = 4, + JVM_OPC_iconst_2 = 5, + JVM_OPC_iconst_3 = 6, + JVM_OPC_iconst_4 = 7, + JVM_OPC_iconst_5 = 8, + JVM_OPC_lconst_0 = 9, + JVM_OPC_lconst_1 = 10, + JVM_OPC_fconst_0 = 11, + JVM_OPC_fconst_1 = 12, + JVM_OPC_fconst_2 = 13, + JVM_OPC_dconst_0 = 14, + JVM_OPC_dconst_1 = 15, + JVM_OPC_bipush = 16, + JVM_OPC_sipush = 17, + JVM_OPC_ldc = 18, + JVM_OPC_ldc_w = 19, + JVM_OPC_ldc2_w = 20, + JVM_OPC_iload = 21, + JVM_OPC_lload = 22, + JVM_OPC_fload = 23, + JVM_OPC_dload = 24, + JVM_OPC_aload = 25, + JVM_OPC_iload_0 = 26, + JVM_OPC_iload_1 = 27, + JVM_OPC_iload_2 = 28, + JVM_OPC_iload_3 = 29, + JVM_OPC_lload_0 = 30, + JVM_OPC_lload_1 = 31, + JVM_OPC_lload_2 = 32, + JVM_OPC_lload_3 = 33, + JVM_OPC_fload_0 = 34, + JVM_OPC_fload_1 = 35, + JVM_OPC_fload_2 = 36, + JVM_OPC_fload_3 = 37, + JVM_OPC_dload_0 = 38, + JVM_OPC_dload_1 = 39, + JVM_OPC_dload_2 = 40, + JVM_OPC_dload_3 = 41, + JVM_OPC_aload_0 = 42, + JVM_OPC_aload_1 = 43, + JVM_OPC_aload_2 = 44, + JVM_OPC_aload_3 = 45, + JVM_OPC_iaload = 46, + JVM_OPC_laload = 47, + JVM_OPC_faload = 48, + JVM_OPC_daload = 49, + JVM_OPC_aaload = 50, + JVM_OPC_baload = 51, + JVM_OPC_caload = 52, + JVM_OPC_saload = 53, + JVM_OPC_istore = 54, + JVM_OPC_lstore = 55, + JVM_OPC_fstore = 56, + JVM_OPC_dstore = 57, + JVM_OPC_astore = 58, + JVM_OPC_istore_0 = 59, + JVM_OPC_istore_1 = 60, + JVM_OPC_istore_2 = 61, + JVM_OPC_istore_3 = 62, + JVM_OPC_lstore_0 = 63, + JVM_OPC_lstore_1 = 64, + JVM_OPC_lstore_2 = 65, + JVM_OPC_lstore_3 = 66, + JVM_OPC_fstore_0 = 67, + JVM_OPC_fstore_1 = 68, + JVM_OPC_fstore_2 = 69, + JVM_OPC_fstore_3 = 70, + JVM_OPC_dstore_0 = 71, + JVM_OPC_dstore_1 = 72, + JVM_OPC_dstore_2 = 73, + JVM_OPC_dstore_3 = 74, + JVM_OPC_astore_0 = 75, + JVM_OPC_astore_1 = 76, + JVM_OPC_astore_2 = 77, + JVM_OPC_astore_3 = 78, + JVM_OPC_iastore = 79, + JVM_OPC_lastore = 80, + JVM_OPC_fastore = 81, + JVM_OPC_dastore = 82, + JVM_OPC_aastore = 83, + JVM_OPC_bastore = 84, + JVM_OPC_castore = 85, + JVM_OPC_sastore = 86, + JVM_OPC_pop = 87, + JVM_OPC_pop2 = 88, + JVM_OPC_dup = 89, + JVM_OPC_dup_x1 = 90, + JVM_OPC_dup_x2 = 91, + JVM_OPC_dup2 = 92, + JVM_OPC_dup2_x1 = 93, + JVM_OPC_dup2_x2 = 94, + JVM_OPC_swap = 95, + JVM_OPC_iadd = 96, + JVM_OPC_ladd = 97, + JVM_OPC_fadd = 98, + JVM_OPC_dadd = 99, + JVM_OPC_isub = 100, + JVM_OPC_lsub = 101, + JVM_OPC_fsub = 102, + JVM_OPC_dsub = 103, + JVM_OPC_imul = 104, + JVM_OPC_lmul = 105, + JVM_OPC_fmul = 106, + JVM_OPC_dmul = 107, + JVM_OPC_idiv = 108, + JVM_OPC_ldiv = 109, + JVM_OPC_fdiv = 110, + JVM_OPC_ddiv = 111, + JVM_OPC_irem = 112, + JVM_OPC_lrem = 113, + JVM_OPC_frem = 114, + JVM_OPC_drem = 115, + JVM_OPC_ineg = 116, + JVM_OPC_lneg = 117, + JVM_OPC_fneg = 118, + JVM_OPC_dneg = 119, + JVM_OPC_ishl = 120, + JVM_OPC_lshl = 121, + JVM_OPC_ishr = 122, + JVM_OPC_lshr = 123, + JVM_OPC_iushr = 124, + JVM_OPC_lushr = 125, + JVM_OPC_iand = 126, + JVM_OPC_land = 127, + JVM_OPC_ior = 128, + JVM_OPC_lor = 129, + JVM_OPC_ixor = 130, + JVM_OPC_lxor = 131, + JVM_OPC_iinc = 132, + JVM_OPC_i2l = 133, + JVM_OPC_i2f = 134, + JVM_OPC_i2d = 135, + JVM_OPC_l2i = 136, + JVM_OPC_l2f = 137, + JVM_OPC_l2d = 138, + JVM_OPC_f2i = 139, + JVM_OPC_f2l = 140, + JVM_OPC_f2d = 141, + JVM_OPC_d2i = 142, + JVM_OPC_d2l = 143, + JVM_OPC_d2f = 144, + JVM_OPC_i2b = 145, + JVM_OPC_i2c = 146, + JVM_OPC_i2s = 147, + JVM_OPC_lcmp = 148, + JVM_OPC_fcmpl = 149, + JVM_OPC_fcmpg = 150, + JVM_OPC_dcmpl = 151, + JVM_OPC_dcmpg = 152, + JVM_OPC_ifeq = 153, + JVM_OPC_ifne = 154, + JVM_OPC_iflt = 155, + JVM_OPC_ifge = 156, + JVM_OPC_ifgt = 157, + JVM_OPC_ifle = 158, + JVM_OPC_if_icmpeq = 159, + JVM_OPC_if_icmpne = 160, + JVM_OPC_if_icmplt = 161, + JVM_OPC_if_icmpge = 162, + JVM_OPC_if_icmpgt = 163, + JVM_OPC_if_icmple = 164, + JVM_OPC_if_acmpeq = 165, + JVM_OPC_if_acmpne = 166, + JVM_OPC_goto = 167, + JVM_OPC_jsr = 168, + JVM_OPC_ret = 169, + JVM_OPC_tableswitch = 170, + JVM_OPC_lookupswitch = 171, + JVM_OPC_ireturn = 172, + JVM_OPC_lreturn = 173, + JVM_OPC_freturn = 174, + JVM_OPC_dreturn = 175, + JVM_OPC_areturn = 176, + JVM_OPC_return = 177, + JVM_OPC_getstatic = 178, + JVM_OPC_putstatic = 179, + JVM_OPC_getfield = 180, + JVM_OPC_putfield = 181, + JVM_OPC_invokevirtual = 182, + JVM_OPC_invokespecial = 183, + JVM_OPC_invokestatic = 184, + JVM_OPC_invokeinterface = 185, + JVM_OPC_invokedynamic = 186, + JVM_OPC_new = 187, + JVM_OPC_newarray = 188, + JVM_OPC_anewarray = 189, + JVM_OPC_arraylength = 190, + JVM_OPC_athrow = 191, + JVM_OPC_checkcast = 192, + JVM_OPC_instanceof = 193, + JVM_OPC_monitorenter = 194, + JVM_OPC_monitorexit = 195, + JVM_OPC_wide = 196, + JVM_OPC_multianewarray = 197, + JVM_OPC_ifnull = 198, + JVM_OPC_ifnonnull = 199, + JVM_OPC_goto_w = 200, + JVM_OPC_jsr_w = 201, + JVM_OPC_MAX = 201 +}; + +/* Opcode length initializer, use with something like: + * unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER; + */ +#define JVM_OPCODE_LENGTH_INITIALIZER { \ + 1, /* nop */ \ + 1, /* aconst_null */ \ + 1, /* iconst_m1 */ \ + 1, /* iconst_0 */ \ + 1, /* iconst_1 */ \ + 1, /* iconst_2 */ \ + 1, /* iconst_3 */ \ + 1, /* iconst_4 */ \ + 1, /* iconst_5 */ \ + 1, /* lconst_0 */ \ + 1, /* lconst_1 */ \ + 1, /* fconst_0 */ \ + 1, /* fconst_1 */ \ + 1, /* fconst_2 */ \ + 1, /* dconst_0 */ \ + 1, /* dconst_1 */ \ + 2, /* bipush */ \ + 3, /* sipush */ \ + 2, /* ldc */ \ + 3, /* ldc_w */ \ + 3, /* ldc2_w */ \ + 2, /* iload */ \ + 2, /* lload */ \ + 2, /* fload */ \ + 2, /* dload */ \ + 2, /* aload */ \ + 1, /* iload_0 */ \ + 1, /* iload_1 */ \ + 1, /* iload_2 */ \ + 1, /* iload_3 */ \ + 1, /* lload_0 */ \ + 1, /* lload_1 */ \ + 1, /* lload_2 */ \ + 1, /* lload_3 */ \ + 1, /* fload_0 */ \ + 1, /* fload_1 */ \ + 1, /* fload_2 */ \ + 1, /* fload_3 */ \ + 1, /* dload_0 */ \ + 1, /* dload_1 */ \ + 1, /* dload_2 */ \ + 1, /* dload_3 */ \ + 1, /* aload_0 */ \ + 1, /* aload_1 */ \ + 1, /* aload_2 */ \ + 1, /* aload_3 */ \ + 1, /* iaload */ \ + 1, /* laload */ \ + 1, /* faload */ \ + 1, /* daload */ \ + 1, /* aaload */ \ + 1, /* baload */ \ + 1, /* caload */ \ + 1, /* saload */ \ + 2, /* istore */ \ + 2, /* lstore */ \ + 2, /* fstore */ \ + 2, /* dstore */ \ + 2, /* astore */ \ + 1, /* istore_0 */ \ + 1, /* istore_1 */ \ + 1, /* istore_2 */ \ + 1, /* istore_3 */ \ + 1, /* lstore_0 */ \ + 1, /* lstore_1 */ \ + 1, /* lstore_2 */ \ + 1, /* lstore_3 */ \ + 1, /* fstore_0 */ \ + 1, /* fstore_1 */ \ + 1, /* fstore_2 */ \ + 1, /* fstore_3 */ \ + 1, /* dstore_0 */ \ + 1, /* dstore_1 */ \ + 1, /* dstore_2 */ \ + 1, /* dstore_3 */ \ + 1, /* astore_0 */ \ + 1, /* astore_1 */ \ + 1, /* astore_2 */ \ + 1, /* astore_3 */ \ + 1, /* iastore */ \ + 1, /* lastore */ \ + 1, /* fastore */ \ + 1, /* dastore */ \ + 1, /* aastore */ \ + 1, /* bastore */ \ + 1, /* castore */ \ + 1, /* sastore */ \ + 1, /* pop */ \ + 1, /* pop2 */ \ + 1, /* dup */ \ + 1, /* dup_x1 */ \ + 1, /* dup_x2 */ \ + 1, /* dup2 */ \ + 1, /* dup2_x1 */ \ + 1, /* dup2_x2 */ \ + 1, /* swap */ \ + 1, /* iadd */ \ + 1, /* ladd */ \ + 1, /* fadd */ \ + 1, /* dadd */ \ + 1, /* isub */ \ + 1, /* lsub */ \ + 1, /* fsub */ \ + 1, /* dsub */ \ + 1, /* imul */ \ + 1, /* lmul */ \ + 1, /* fmul */ \ + 1, /* dmul */ \ + 1, /* idiv */ \ + 1, /* ldiv */ \ + 1, /* fdiv */ \ + 1, /* ddiv */ \ + 1, /* irem */ \ + 1, /* lrem */ \ + 1, /* frem */ \ + 1, /* drem */ \ + 1, /* ineg */ \ + 1, /* lneg */ \ + 1, /* fneg */ \ + 1, /* dneg */ \ + 1, /* ishl */ \ + 1, /* lshl */ \ + 1, /* ishr */ \ + 1, /* lshr */ \ + 1, /* iushr */ \ + 1, /* lushr */ \ + 1, /* iand */ \ + 1, /* land */ \ + 1, /* ior */ \ + 1, /* lor */ \ + 1, /* ixor */ \ + 1, /* lxor */ \ + 3, /* iinc */ \ + 1, /* i2l */ \ + 1, /* i2f */ \ + 1, /* i2d */ \ + 1, /* l2i */ \ + 1, /* l2f */ \ + 1, /* l2d */ \ + 1, /* f2i */ \ + 1, /* f2l */ \ + 1, /* f2d */ \ + 1, /* d2i */ \ + 1, /* d2l */ \ + 1, /* d2f */ \ + 1, /* i2b */ \ + 1, /* i2c */ \ + 1, /* i2s */ \ + 1, /* lcmp */ \ + 1, /* fcmpl */ \ + 1, /* fcmpg */ \ + 1, /* dcmpl */ \ + 1, /* dcmpg */ \ + 3, /* ifeq */ \ + 3, /* ifne */ \ + 3, /* iflt */ \ + 3, /* ifge */ \ + 3, /* ifgt */ \ + 3, /* ifle */ \ + 3, /* if_icmpeq */ \ + 3, /* if_icmpne */ \ + 3, /* if_icmplt */ \ + 3, /* if_icmpge */ \ + 3, /* if_icmpgt */ \ + 3, /* if_icmple */ \ + 3, /* if_acmpeq */ \ + 3, /* if_acmpne */ \ + 3, /* goto */ \ + 3, /* jsr */ \ + 2, /* ret */ \ + 99, /* tableswitch */ \ + 99, /* lookupswitch */ \ + 1, /* ireturn */ \ + 1, /* lreturn */ \ + 1, /* freturn */ \ + 1, /* dreturn */ \ + 1, /* areturn */ \ + 1, /* return */ \ + 3, /* getstatic */ \ + 3, /* putstatic */ \ + 3, /* getfield */ \ + 3, /* putfield */ \ + 3, /* invokevirtual */ \ + 3, /* invokespecial */ \ + 3, /* invokestatic */ \ + 5, /* invokeinterface */ \ + 5, /* invokedynamic */ \ + 3, /* new */ \ + 2, /* newarray */ \ + 3, /* anewarray */ \ + 1, /* arraylength */ \ + 1, /* athrow */ \ + 3, /* checkcast */ \ + 3, /* instanceof */ \ + 1, /* monitorenter */ \ + 1, /* monitorexit */ \ + 0, /* wide */ \ + 4, /* multianewarray */ \ + 3, /* ifnull */ \ + 3, /* ifnonnull */ \ + 5, /* goto_w */ \ + 5 /* jsr_w */ \ +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* CLASSFILE_CONSTANTS */ diff --git a/demos/java/jni/gs_jni/include/jawt.h b/demos/java/jni/gs_jni/include/jawt.h new file mode 100644 index 00000000..f06e8071 --- /dev/null +++ b/demos/java/jni/gs_jni/include/jawt.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JAVASOFT_JAWT_H_ +#define _JAVASOFT_JAWT_H_ + +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * AWT native interface (new in JDK 1.3) + * + * The AWT native interface allows a native C or C++ application a means + * by which to access native structures in AWT. This is to facilitate moving + * legacy C and C++ applications to Java and to target the needs of the + * community who, at present, wish to do their own native rendering to canvases + * for performance reasons. Standard extensions such as Java3D also require a + * means to access the underlying native data structures of AWT. + * + * There may be future extensions to this API depending on demand. + * + * A VM does not have to implement this API in order to pass the JCK. + * It is recommended, however, that this API is implemented on VMs that support + * standard extensions, such as Java3D. + * + * Since this is a native API, any program which uses it cannot be considered + * 100% pure java. + */ + +/* + * AWT Native Drawing Surface (JAWT_DrawingSurface). + * + * For each platform, there is a native drawing surface structure. This + * platform-specific structure can be found in jawt_md.h. It is recommended + * that additional platforms follow the same model. It is also recommended + * that VMs on Win32 and Solaris support the existing structures in jawt_md.h. + * + ******************* + * EXAMPLE OF USAGE: + ******************* + * + * In Win32, a programmer wishes to access the HWND of a canvas to perform + * native rendering into it. The programmer has declared the paint() method + * for their canvas subclass to be native: + * + * + * MyCanvas.java: + * + * import java.awt.*; + * + * public class MyCanvas extends Canvas { + * + * static { + * System.loadLibrary("mylib"); + * } + * + * public native void paint(Graphics g); + * } + * + * + * myfile.c: + * + * #include "jawt_md.h" + * #include + * + * JNIEXPORT void JNICALL + * Java_MyCanvas_paint(JNIEnv* env, jobject canvas, jobject graphics) + * { + * JAWT awt; + * JAWT_DrawingSurface* ds; + * JAWT_DrawingSurfaceInfo* dsi; + * JAWT_Win32DrawingSurfaceInfo* dsi_win; + * jboolean result; + * jint lock; + * + * // Get the AWT + * awt.version = JAWT_VERSION_1_3; + * result = JAWT_GetAWT(env, &awt); + * assert(result != JNI_FALSE); + * + * // Get the drawing surface + * ds = awt.GetDrawingSurface(env, canvas); + * assert(ds != NULL); + * + * // Lock the drawing surface + * lock = ds->Lock(ds); + * assert((lock & JAWT_LOCK_ERROR) == 0); + * + * // Get the drawing surface info + * dsi = ds->GetDrawingSurfaceInfo(ds); + * + * // Get the platform-specific drawing info + * dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo; + * + * ////////////////////////////// + * // !!! DO PAINTING HERE !!! // + * ////////////////////////////// + * + * // Free the drawing surface info + * ds->FreeDrawingSurfaceInfo(dsi); + * + * // Unlock the drawing surface + * ds->Unlock(ds); + * + * // Free the drawing surface + * awt.FreeDrawingSurface(ds); + * } + * + */ + +/* + * JAWT_Rectangle + * Structure for a native rectangle. + */ +typedef struct jawt_Rectangle { + jint x; + jint y; + jint width; + jint height; +} JAWT_Rectangle; + +struct jawt_DrawingSurface; + +/* + * JAWT_DrawingSurfaceInfo + * Structure for containing the underlying drawing information of a component. + */ +typedef struct jawt_DrawingSurfaceInfo { + /* + * Pointer to the platform-specific information. This can be safely + * cast to a JAWT_Win32DrawingSurfaceInfo on Windows or a + * JAWT_X11DrawingSurfaceInfo on Solaris. On Mac OS X this is a + * pointer to a NSObject that conforms to the JAWT_SurfaceLayers + * protocol. See jawt_md.h for details. + */ + void* platformInfo; + /* Cached pointer to the underlying drawing surface */ + struct jawt_DrawingSurface* ds; + /* Bounding rectangle of the drawing surface */ + JAWT_Rectangle bounds; + /* Number of rectangles in the clip */ + jint clipSize; + /* Clip rectangle array */ + JAWT_Rectangle* clip; +} JAWT_DrawingSurfaceInfo; + +#define JAWT_LOCK_ERROR 0x00000001 +#define JAWT_LOCK_CLIP_CHANGED 0x00000002 +#define JAWT_LOCK_BOUNDS_CHANGED 0x00000004 +#define JAWT_LOCK_SURFACE_CHANGED 0x00000008 + +/* + * JAWT_DrawingSurface + * Structure for containing the underlying drawing information of a component. + * All operations on a JAWT_DrawingSurface MUST be performed from the same + * thread as the call to GetDrawingSurface. + */ +typedef struct jawt_DrawingSurface { + /* + * Cached reference to the Java environment of the calling thread. + * If Lock(), Unlock(), GetDrawingSurfaceInfo() or + * FreeDrawingSurfaceInfo() are called from a different thread, + * this data member should be set before calling those functions. + */ + JNIEnv* env; + /* Cached reference to the target object */ + jobject target; + /* + * Lock the surface of the target component for native rendering. + * When finished drawing, the surface must be unlocked with + * Unlock(). This function returns a bitmask with one or more of the + * following values: + * + * JAWT_LOCK_ERROR - When an error has occurred and the surface could not + * be locked. + * + * JAWT_LOCK_CLIP_CHANGED - When the clip region has changed. + * + * JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed. + * + * JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed + */ + jint (JNICALL *Lock) + (struct jawt_DrawingSurface* ds); + /* + * Get the drawing surface info. + * The value returned may be cached, but the values may change if + * additional calls to Lock() or Unlock() are made. + * Lock() must be called before this can return a valid value. + * Returns NULL if an error has occurred. + * When finished with the returned value, FreeDrawingSurfaceInfo must be + * called. + */ + JAWT_DrawingSurfaceInfo* (JNICALL *GetDrawingSurfaceInfo) + (struct jawt_DrawingSurface* ds); + /* + * Free the drawing surface info. + */ + void (JNICALL *FreeDrawingSurfaceInfo) + (JAWT_DrawingSurfaceInfo* dsi); + /* + * Unlock the drawing surface of the target component for native rendering. + */ + void (JNICALL *Unlock) + (struct jawt_DrawingSurface* ds); +} JAWT_DrawingSurface; + +/* + * JAWT + * Structure for containing native AWT functions. + */ +typedef struct jawt { + /* + * Version of this structure. This must always be set before + * calling JAWT_GetAWT() + */ + jint version; + /* + * Return a drawing surface from a target jobject. This value + * may be cached. + * Returns NULL if an error has occurred. + * Target must be a java.awt.Component (should be a Canvas + * or Window for native rendering). + * FreeDrawingSurface() must be called when finished with the + * returned JAWT_DrawingSurface. + */ + JAWT_DrawingSurface* (JNICALL *GetDrawingSurface) + (JNIEnv* env, jobject target); + /* + * Free the drawing surface allocated in GetDrawingSurface. + */ + void (JNICALL *FreeDrawingSurface) + (JAWT_DrawingSurface* ds); + /* + * Since 1.4 + * Locks the entire AWT for synchronization purposes + */ + void (JNICALL *Lock)(JNIEnv* env); + /* + * Since 1.4 + * Unlocks the entire AWT for synchronization purposes + */ + void (JNICALL *Unlock)(JNIEnv* env); + /* + * Since 1.4 + * Returns a reference to a java.awt.Component from a native + * platform handle. On Windows, this corresponds to an HWND; + * on Solaris and Linux, this is a Drawable. For other platforms, + * see the appropriate machine-dependent header file for a description. + * The reference returned by this function is a local + * reference that is only valid in this environment. + * This function returns a NULL reference if no component could be + * found with matching platform information. + */ + jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo); + +} JAWT; + +/* + * Get the AWT native structure. This function returns JNI_FALSE if + * an error occurs. + */ +_JNI_IMPORT_OR_EXPORT_ +jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt); + +#define JAWT_VERSION_1_3 0x00010003 +#define JAWT_VERSION_1_4 0x00010004 +#define JAWT_VERSION_1_7 0x00010007 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* !_JAVASOFT_JAWT_H_ */ diff --git a/demos/java/jni/gs_jni/include/jdwpTransport.h b/demos/java/jni/gs_jni/include/jdwpTransport.h new file mode 100644 index 00000000..4f4b92ed --- /dev/null +++ b/demos/java/jni/gs_jni/include/jdwpTransport.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Java Debug Wire Protocol Transport Service Provider Interface. + */ + +#ifndef JDWPTRANSPORT_H +#define JDWPTRANSPORT_H + +#include "jni.h" + +enum { + JDWPTRANSPORT_VERSION_1_0 = 0x00010000 +}; + +#ifdef __cplusplus +extern "C" { +#endif + +struct jdwpTransportNativeInterface_; + +struct _jdwpTransportEnv; + +#ifdef __cplusplus +typedef _jdwpTransportEnv jdwpTransportEnv; +#else +typedef const struct jdwpTransportNativeInterface_ *jdwpTransportEnv; +#endif /* __cplusplus */ + +/* + * Errors. Universal errors with JVMTI/JVMDI equivalents keep the + * values the same. + */ +typedef enum { + JDWPTRANSPORT_ERROR_NONE = 0, + JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT = 103, + JDWPTRANSPORT_ERROR_OUT_OF_MEMORY = 110, + JDWPTRANSPORT_ERROR_INTERNAL = 113, + JDWPTRANSPORT_ERROR_ILLEGAL_STATE = 201, + JDWPTRANSPORT_ERROR_IO_ERROR = 202, + JDWPTRANSPORT_ERROR_TIMEOUT = 203, + JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE = 204 +} jdwpTransportError; + + +/* + * Structure to define capabilities + */ +typedef struct { + unsigned int can_timeout_attach :1; + unsigned int can_timeout_accept :1; + unsigned int can_timeout_handshake :1; + unsigned int reserved3 :1; + unsigned int reserved4 :1; + unsigned int reserved5 :1; + unsigned int reserved6 :1; + unsigned int reserved7 :1; + unsigned int reserved8 :1; + unsigned int reserved9 :1; + unsigned int reserved10 :1; + unsigned int reserved11 :1; + unsigned int reserved12 :1; + unsigned int reserved13 :1; + unsigned int reserved14 :1; + unsigned int reserved15 :1; +} JDWPTransportCapabilities; + + +/* + * Structures to define packet layout. + * + * See: http://java.sun.com/j2se/1.5/docs/guide/jpda/jdwp-spec.html + */ + +enum { + /* + * If additional flags are added that apply to jdwpCmdPacket, + * then debugLoop.c: reader() will need to be updated to + * accept more than JDWPTRANSPORT_FLAGS_NONE. + */ + JDWPTRANSPORT_FLAGS_NONE = 0x0, + JDWPTRANSPORT_FLAGS_REPLY = 0x80 +}; + +typedef struct { + jint len; + jint id; + jbyte flags; + jbyte cmdSet; + jbyte cmd; + jbyte *data; +} jdwpCmdPacket; + +typedef struct { + jint len; + jint id; + jbyte flags; + jshort errorCode; + jbyte *data; +} jdwpReplyPacket; + +typedef struct { + union { + jdwpCmdPacket cmd; + jdwpReplyPacket reply; + } type; +} jdwpPacket; + +/* + * JDWP functions called by the transport. + */ +typedef struct jdwpTransportCallback { + void *(*alloc)(jint numBytes); /* Call this for all allocations */ + void (*free)(void *buffer); /* Call this for all deallocations */ +} jdwpTransportCallback; + +typedef jint (JNICALL *jdwpTransport_OnLoad_t)(JavaVM *jvm, + jdwpTransportCallback *callback, + jint version, + jdwpTransportEnv** env); + + + +/* Function Interface */ + +struct jdwpTransportNativeInterface_ { + /* 1 : RESERVED */ + void *reserved1; + + /* 2 : Get Capabilities */ + jdwpTransportError (JNICALL *GetCapabilities)(jdwpTransportEnv* env, + JDWPTransportCapabilities *capabilities_ptr); + + /* 3 : Attach */ + jdwpTransportError (JNICALL *Attach)(jdwpTransportEnv* env, + const char* address, + jlong attach_timeout, + jlong handshake_timeout); + + /* 4: StartListening */ + jdwpTransportError (JNICALL *StartListening)(jdwpTransportEnv* env, + const char* address, + char** actual_address); + + /* 5: StopListening */ + jdwpTransportError (JNICALL *StopListening)(jdwpTransportEnv* env); + + /* 6: Accept */ + jdwpTransportError (JNICALL *Accept)(jdwpTransportEnv* env, + jlong accept_timeout, + jlong handshake_timeout); + + /* 7: IsOpen */ + jboolean (JNICALL *IsOpen)(jdwpTransportEnv* env); + + /* 8: Close */ + jdwpTransportError (JNICALL *Close)(jdwpTransportEnv* env); + + /* 9: ReadPacket */ + jdwpTransportError (JNICALL *ReadPacket)(jdwpTransportEnv* env, + jdwpPacket *pkt); + + /* 10: Write Packet */ + jdwpTransportError (JNICALL *WritePacket)(jdwpTransportEnv* env, + const jdwpPacket* pkt); + + /* 11: GetLastError */ + jdwpTransportError (JNICALL *GetLastError)(jdwpTransportEnv* env, + char** error); + +}; + + +/* + * Use inlined functions so that C++ code can use syntax such as + * env->Attach("mymachine:5000", 10*1000, 0); + * + * rather than using C's :- + * + * (*env)->Attach(env, "mymachine:5000", 10*1000, 0); + */ +struct _jdwpTransportEnv { + const struct jdwpTransportNativeInterface_ *functions; +#ifdef __cplusplus + + jdwpTransportError GetCapabilities(JDWPTransportCapabilities *capabilities_ptr) { + return functions->GetCapabilities(this, capabilities_ptr); + } + + jdwpTransportError Attach(const char* address, jlong attach_timeout, + jlong handshake_timeout) { + return functions->Attach(this, address, attach_timeout, handshake_timeout); + } + + jdwpTransportError StartListening(const char* address, + char** actual_address) { + return functions->StartListening(this, address, actual_address); + } + + jdwpTransportError StopListening(void) { + return functions->StopListening(this); + } + + jdwpTransportError Accept(jlong accept_timeout, jlong handshake_timeout) { + return functions->Accept(this, accept_timeout, handshake_timeout); + } + + jboolean IsOpen(void) { + return functions->IsOpen(this); + } + + jdwpTransportError Close(void) { + return functions->Close(this); + } + + jdwpTransportError ReadPacket(jdwpPacket *pkt) { + return functions->ReadPacket(this, pkt); + } + + jdwpTransportError WritePacket(const jdwpPacket* pkt) { + return functions->WritePacket(this, pkt); + } + + jdwpTransportError GetLastError(char** error) { + return functions->GetLastError(this, error); + } + + +#endif /* __cplusplus */ +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* JDWPTRANSPORT_H */ diff --git a/demos/java/jni/gs_jni/include/jni.h b/demos/java/jni/gs_jni/include/jni.h new file mode 100644 index 00000000..97b14d8a --- /dev/null +++ b/demos/java/jni/gs_jni/include/jni.h @@ -0,0 +1,1964 @@ +/* + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef _JAVASOFT_JNI_H_ +#define _JAVASOFT_JNI_H_ + +#include +#include + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#ifdef _WIN32 +#include "win32/jni_md.h" +#else +#include "jni_md.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* Return values from jobjectRefType */ +typedef enum _jobjectType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + + +#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); + + /* New JNI 1.6 Features */ + + jobjectRefType (JNICALL *GetObjectRefType) + (JNIEnv* env, jobject obj); +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + const jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + jobjectRefType GetObjectRefType(jobject obj) { + return functions->GetObjectRefType(this, obj); + } + +#endif /* __cplusplus */ +}; + +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +/* These will be VM-specific. */ + +#define JDK1_2 +#define JDK1_4 + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +/* Defined by native libraries. */ +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 +#define JNI_VERSION_1_8 0x00010008 + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JNI_H_ */ diff --git a/demos/java/jni/gs_jni/include/jvmti.h b/demos/java/jni/gs_jni/include/jvmti.h new file mode 100644 index 00000000..e8de8585 --- /dev/null +++ b/demos/java/jni/gs_jni/include/jvmti.h @@ -0,0 +1,2533 @@ +/* + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + + /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ + + + /* Include file for the Java(tm) Virtual Machine Tool Interface */ + +#ifndef _JAVA_JVMTI_H_ +#define _JAVA_JVMTI_H_ + +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + JVMTI_VERSION_1 = 0x30010000, + JVMTI_VERSION_1_0 = 0x30010000, + JVMTI_VERSION_1_1 = 0x30010100, + JVMTI_VERSION_1_2 = 0x30010200, + + JVMTI_VERSION = 0x30000000 + (1 * 0x10000) + (2 * 0x100) + 1 /* version: 1.2.1 */ +}; + +JNIEXPORT jint JNICALL +Agent_OnLoad(JavaVM *vm, char *options, void *reserved); + +JNIEXPORT jint JNICALL +Agent_OnAttach(JavaVM* vm, char* options, void* reserved); + +JNIEXPORT void JNICALL +Agent_OnUnload(JavaVM *vm); + + /* Forward declaration of the environment */ + +struct _jvmtiEnv; + +struct jvmtiInterface_1_; + +#ifdef __cplusplus +typedef _jvmtiEnv jvmtiEnv; +#else +typedef const struct jvmtiInterface_1_ *jvmtiEnv; +#endif /* __cplusplus */ + +/* Derived Base Types */ + +typedef jobject jthread; +typedef jobject jthreadGroup; +typedef jlong jlocation; +struct _jrawMonitorID; +typedef struct _jrawMonitorID *jrawMonitorID; +typedef struct JNINativeInterface_ jniNativeInterface; + + /* Constants */ + + + /* Thread State Flags */ + +enum { + JVMTI_THREAD_STATE_ALIVE = 0x0001, + JVMTI_THREAD_STATE_TERMINATED = 0x0002, + JVMTI_THREAD_STATE_RUNNABLE = 0x0004, + JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400, + JVMTI_THREAD_STATE_WAITING = 0x0080, + JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010, + JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020, + JVMTI_THREAD_STATE_SLEEPING = 0x0040, + JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100, + JVMTI_THREAD_STATE_PARKED = 0x0200, + JVMTI_THREAD_STATE_SUSPENDED = 0x100000, + JVMTI_THREAD_STATE_INTERRUPTED = 0x200000, + JVMTI_THREAD_STATE_IN_NATIVE = 0x400000, + JVMTI_THREAD_STATE_VENDOR_1 = 0x10000000, + JVMTI_THREAD_STATE_VENDOR_2 = 0x20000000, + JVMTI_THREAD_STATE_VENDOR_3 = 0x40000000 +}; + + /* java.lang.Thread.State Conversion Masks */ + +enum { + JVMTI_JAVA_LANG_THREAD_STATE_MASK = JVMTI_THREAD_STATE_TERMINATED | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT, + JVMTI_JAVA_LANG_THREAD_STATE_NEW = 0, + JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED = JVMTI_THREAD_STATE_TERMINATED, + JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE, + JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER, + JVMTI_JAVA_LANG_THREAD_STATE_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY, + JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +}; + + /* Thread Priority Constants */ + +enum { + JVMTI_THREAD_MIN_PRIORITY = 1, + JVMTI_THREAD_NORM_PRIORITY = 5, + JVMTI_THREAD_MAX_PRIORITY = 10 +}; + + /* Heap Filter Flags */ + +enum { + JVMTI_HEAP_FILTER_TAGGED = 0x4, + JVMTI_HEAP_FILTER_UNTAGGED = 0x8, + JVMTI_HEAP_FILTER_CLASS_TAGGED = 0x10, + JVMTI_HEAP_FILTER_CLASS_UNTAGGED = 0x20 +}; + + /* Heap Visit Control Flags */ + +enum { + JVMTI_VISIT_OBJECTS = 0x100, + JVMTI_VISIT_ABORT = 0x8000 +}; + + /* Heap Reference Enumeration */ + +typedef enum { + JVMTI_HEAP_REFERENCE_CLASS = 1, + JVMTI_HEAP_REFERENCE_FIELD = 2, + JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT = 3, + JVMTI_HEAP_REFERENCE_CLASS_LOADER = 4, + JVMTI_HEAP_REFERENCE_SIGNERS = 5, + JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN = 6, + JVMTI_HEAP_REFERENCE_INTERFACE = 7, + JVMTI_HEAP_REFERENCE_STATIC_FIELD = 8, + JVMTI_HEAP_REFERENCE_CONSTANT_POOL = 9, + JVMTI_HEAP_REFERENCE_SUPERCLASS = 10, + JVMTI_HEAP_REFERENCE_JNI_GLOBAL = 21, + JVMTI_HEAP_REFERENCE_SYSTEM_CLASS = 22, + JVMTI_HEAP_REFERENCE_MONITOR = 23, + JVMTI_HEAP_REFERENCE_STACK_LOCAL = 24, + JVMTI_HEAP_REFERENCE_JNI_LOCAL = 25, + JVMTI_HEAP_REFERENCE_THREAD = 26, + JVMTI_HEAP_REFERENCE_OTHER = 27 +} jvmtiHeapReferenceKind; + + /* Primitive Type Enumeration */ + +typedef enum { + JVMTI_PRIMITIVE_TYPE_BOOLEAN = 90, + JVMTI_PRIMITIVE_TYPE_BYTE = 66, + JVMTI_PRIMITIVE_TYPE_CHAR = 67, + JVMTI_PRIMITIVE_TYPE_SHORT = 83, + JVMTI_PRIMITIVE_TYPE_INT = 73, + JVMTI_PRIMITIVE_TYPE_LONG = 74, + JVMTI_PRIMITIVE_TYPE_FLOAT = 70, + JVMTI_PRIMITIVE_TYPE_DOUBLE = 68 +} jvmtiPrimitiveType; + + /* Heap Object Filter Enumeration */ + +typedef enum { + JVMTI_HEAP_OBJECT_TAGGED = 1, + JVMTI_HEAP_OBJECT_UNTAGGED = 2, + JVMTI_HEAP_OBJECT_EITHER = 3 +} jvmtiHeapObjectFilter; + + /* Heap Root Kind Enumeration */ + +typedef enum { + JVMTI_HEAP_ROOT_JNI_GLOBAL = 1, + JVMTI_HEAP_ROOT_SYSTEM_CLASS = 2, + JVMTI_HEAP_ROOT_MONITOR = 3, + JVMTI_HEAP_ROOT_STACK_LOCAL = 4, + JVMTI_HEAP_ROOT_JNI_LOCAL = 5, + JVMTI_HEAP_ROOT_THREAD = 6, + JVMTI_HEAP_ROOT_OTHER = 7 +} jvmtiHeapRootKind; + + /* Object Reference Enumeration */ + +typedef enum { + JVMTI_REFERENCE_CLASS = 1, + JVMTI_REFERENCE_FIELD = 2, + JVMTI_REFERENCE_ARRAY_ELEMENT = 3, + JVMTI_REFERENCE_CLASS_LOADER = 4, + JVMTI_REFERENCE_SIGNERS = 5, + JVMTI_REFERENCE_PROTECTION_DOMAIN = 6, + JVMTI_REFERENCE_INTERFACE = 7, + JVMTI_REFERENCE_STATIC_FIELD = 8, + JVMTI_REFERENCE_CONSTANT_POOL = 9 +} jvmtiObjectReferenceKind; + + /* Iteration Control Enumeration */ + +typedef enum { + JVMTI_ITERATION_CONTINUE = 1, + JVMTI_ITERATION_IGNORE = 2, + JVMTI_ITERATION_ABORT = 0 +} jvmtiIterationControl; + + /* Class Status Flags */ + +enum { + JVMTI_CLASS_STATUS_VERIFIED = 1, + JVMTI_CLASS_STATUS_PREPARED = 2, + JVMTI_CLASS_STATUS_INITIALIZED = 4, + JVMTI_CLASS_STATUS_ERROR = 8, + JVMTI_CLASS_STATUS_ARRAY = 16, + JVMTI_CLASS_STATUS_PRIMITIVE = 32 +}; + + /* Event Enable/Disable */ + +typedef enum { + JVMTI_ENABLE = 1, + JVMTI_DISABLE = 0 +} jvmtiEventMode; + + /* Extension Function/Event Parameter Types */ + +typedef enum { + JVMTI_TYPE_JBYTE = 101, + JVMTI_TYPE_JCHAR = 102, + JVMTI_TYPE_JSHORT = 103, + JVMTI_TYPE_JINT = 104, + JVMTI_TYPE_JLONG = 105, + JVMTI_TYPE_JFLOAT = 106, + JVMTI_TYPE_JDOUBLE = 107, + JVMTI_TYPE_JBOOLEAN = 108, + JVMTI_TYPE_JOBJECT = 109, + JVMTI_TYPE_JTHREAD = 110, + JVMTI_TYPE_JCLASS = 111, + JVMTI_TYPE_JVALUE = 112, + JVMTI_TYPE_JFIELDID = 113, + JVMTI_TYPE_JMETHODID = 114, + JVMTI_TYPE_CCHAR = 115, + JVMTI_TYPE_CVOID = 116, + JVMTI_TYPE_JNIENV = 117 +} jvmtiParamTypes; + + /* Extension Function/Event Parameter Kinds */ + +typedef enum { + JVMTI_KIND_IN = 91, + JVMTI_KIND_IN_PTR = 92, + JVMTI_KIND_IN_BUF = 93, + JVMTI_KIND_ALLOC_BUF = 94, + JVMTI_KIND_ALLOC_ALLOC_BUF = 95, + JVMTI_KIND_OUT = 96, + JVMTI_KIND_OUT_BUF = 97 +} jvmtiParamKind; + + /* Timer Kinds */ + +typedef enum { + JVMTI_TIMER_USER_CPU = 30, + JVMTI_TIMER_TOTAL_CPU = 31, + JVMTI_TIMER_ELAPSED = 32 +} jvmtiTimerKind; + + /* Phases of execution */ + +typedef enum { + JVMTI_PHASE_ONLOAD = 1, + JVMTI_PHASE_PRIMORDIAL = 2, + JVMTI_PHASE_START = 6, + JVMTI_PHASE_LIVE = 4, + JVMTI_PHASE_DEAD = 8 +} jvmtiPhase; + + /* Version Interface Types */ + +enum { + JVMTI_VERSION_INTERFACE_JNI = 0x00000000, + JVMTI_VERSION_INTERFACE_JVMTI = 0x30000000 +}; + + /* Version Masks */ + +enum { + JVMTI_VERSION_MASK_INTERFACE_TYPE = 0x70000000, + JVMTI_VERSION_MASK_MAJOR = 0x0FFF0000, + JVMTI_VERSION_MASK_MINOR = 0x0000FF00, + JVMTI_VERSION_MASK_MICRO = 0x000000FF +}; + + /* Version Shifts */ + +enum { + JVMTI_VERSION_SHIFT_MAJOR = 16, + JVMTI_VERSION_SHIFT_MINOR = 8, + JVMTI_VERSION_SHIFT_MICRO = 0 +}; + + /* Verbose Flag Enumeration */ + +typedef enum { + JVMTI_VERBOSE_OTHER = 0, + JVMTI_VERBOSE_GC = 1, + JVMTI_VERBOSE_CLASS = 2, + JVMTI_VERBOSE_JNI = 4 +} jvmtiVerboseFlag; + + /* JLocation Format Enumeration */ + +typedef enum { + JVMTI_JLOCATION_JVMBCI = 1, + JVMTI_JLOCATION_MACHINEPC = 2, + JVMTI_JLOCATION_OTHER = 0 +} jvmtiJlocationFormat; + + /* Resource Exhaustion Flags */ + +enum { + JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR = 0x0001, + JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP = 0x0002, + JVMTI_RESOURCE_EXHAUSTED_THREADS = 0x0004 +}; + + /* Errors */ + +typedef enum { + JVMTI_ERROR_NONE = 0, + JVMTI_ERROR_INVALID_THREAD = 10, + JVMTI_ERROR_INVALID_THREAD_GROUP = 11, + JVMTI_ERROR_INVALID_PRIORITY = 12, + JVMTI_ERROR_THREAD_NOT_SUSPENDED = 13, + JVMTI_ERROR_THREAD_SUSPENDED = 14, + JVMTI_ERROR_THREAD_NOT_ALIVE = 15, + JVMTI_ERROR_INVALID_OBJECT = 20, + JVMTI_ERROR_INVALID_CLASS = 21, + JVMTI_ERROR_CLASS_NOT_PREPARED = 22, + JVMTI_ERROR_INVALID_METHODID = 23, + JVMTI_ERROR_INVALID_LOCATION = 24, + JVMTI_ERROR_INVALID_FIELDID = 25, + JVMTI_ERROR_NO_MORE_FRAMES = 31, + JVMTI_ERROR_OPAQUE_FRAME = 32, + JVMTI_ERROR_TYPE_MISMATCH = 34, + JVMTI_ERROR_INVALID_SLOT = 35, + JVMTI_ERROR_DUPLICATE = 40, + JVMTI_ERROR_NOT_FOUND = 41, + JVMTI_ERROR_INVALID_MONITOR = 50, + JVMTI_ERROR_NOT_MONITOR_OWNER = 51, + JVMTI_ERROR_INTERRUPT = 52, + JVMTI_ERROR_INVALID_CLASS_FORMAT = 60, + JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION = 61, + JVMTI_ERROR_FAILS_VERIFICATION = 62, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED = 63, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED = 64, + JVMTI_ERROR_INVALID_TYPESTATE = 65, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED = 66, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED = 67, + JVMTI_ERROR_UNSUPPORTED_VERSION = 68, + JVMTI_ERROR_NAMES_DONT_MATCH = 69, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED = 70, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED = 71, + JVMTI_ERROR_UNMODIFIABLE_CLASS = 79, + JVMTI_ERROR_NOT_AVAILABLE = 98, + JVMTI_ERROR_MUST_POSSESS_CAPABILITY = 99, + JVMTI_ERROR_NULL_POINTER = 100, + JVMTI_ERROR_ABSENT_INFORMATION = 101, + JVMTI_ERROR_INVALID_EVENT_TYPE = 102, + JVMTI_ERROR_ILLEGAL_ARGUMENT = 103, + JVMTI_ERROR_NATIVE_METHOD = 104, + JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED = 106, + JVMTI_ERROR_OUT_OF_MEMORY = 110, + JVMTI_ERROR_ACCESS_DENIED = 111, + JVMTI_ERROR_WRONG_PHASE = 112, + JVMTI_ERROR_INTERNAL = 113, + JVMTI_ERROR_UNATTACHED_THREAD = 115, + JVMTI_ERROR_INVALID_ENVIRONMENT = 116, + JVMTI_ERROR_MAX = 116 +} jvmtiError; + + /* Event IDs */ + +typedef enum { + JVMTI_MIN_EVENT_TYPE_VAL = 50, + JVMTI_EVENT_VM_INIT = 50, + JVMTI_EVENT_VM_DEATH = 51, + JVMTI_EVENT_THREAD_START = 52, + JVMTI_EVENT_THREAD_END = 53, + JVMTI_EVENT_CLASS_FILE_LOAD_HOOK = 54, + JVMTI_EVENT_CLASS_LOAD = 55, + JVMTI_EVENT_CLASS_PREPARE = 56, + JVMTI_EVENT_VM_START = 57, + JVMTI_EVENT_EXCEPTION = 58, + JVMTI_EVENT_EXCEPTION_CATCH = 59, + JVMTI_EVENT_SINGLE_STEP = 60, + JVMTI_EVENT_FRAME_POP = 61, + JVMTI_EVENT_BREAKPOINT = 62, + JVMTI_EVENT_FIELD_ACCESS = 63, + JVMTI_EVENT_FIELD_MODIFICATION = 64, + JVMTI_EVENT_METHOD_ENTRY = 65, + JVMTI_EVENT_METHOD_EXIT = 66, + JVMTI_EVENT_NATIVE_METHOD_BIND = 67, + JVMTI_EVENT_COMPILED_METHOD_LOAD = 68, + JVMTI_EVENT_COMPILED_METHOD_UNLOAD = 69, + JVMTI_EVENT_DYNAMIC_CODE_GENERATED = 70, + JVMTI_EVENT_DATA_DUMP_REQUEST = 71, + JVMTI_EVENT_MONITOR_WAIT = 73, + JVMTI_EVENT_MONITOR_WAITED = 74, + JVMTI_EVENT_MONITOR_CONTENDED_ENTER = 75, + JVMTI_EVENT_MONITOR_CONTENDED_ENTERED = 76, + JVMTI_EVENT_RESOURCE_EXHAUSTED = 80, + JVMTI_EVENT_GARBAGE_COLLECTION_START = 81, + JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82, + JVMTI_EVENT_OBJECT_FREE = 83, + JVMTI_EVENT_VM_OBJECT_ALLOC = 84, + JVMTI_MAX_EVENT_TYPE_VAL = 84 +} jvmtiEvent; + + + /* Pre-Declarations */ +struct _jvmtiThreadInfo; +typedef struct _jvmtiThreadInfo jvmtiThreadInfo; +struct _jvmtiMonitorStackDepthInfo; +typedef struct _jvmtiMonitorStackDepthInfo jvmtiMonitorStackDepthInfo; +struct _jvmtiThreadGroupInfo; +typedef struct _jvmtiThreadGroupInfo jvmtiThreadGroupInfo; +struct _jvmtiFrameInfo; +typedef struct _jvmtiFrameInfo jvmtiFrameInfo; +struct _jvmtiStackInfo; +typedef struct _jvmtiStackInfo jvmtiStackInfo; +struct _jvmtiHeapReferenceInfoField; +typedef struct _jvmtiHeapReferenceInfoField jvmtiHeapReferenceInfoField; +struct _jvmtiHeapReferenceInfoArray; +typedef struct _jvmtiHeapReferenceInfoArray jvmtiHeapReferenceInfoArray; +struct _jvmtiHeapReferenceInfoConstantPool; +typedef struct _jvmtiHeapReferenceInfoConstantPool jvmtiHeapReferenceInfoConstantPool; +struct _jvmtiHeapReferenceInfoStackLocal; +typedef struct _jvmtiHeapReferenceInfoStackLocal jvmtiHeapReferenceInfoStackLocal; +struct _jvmtiHeapReferenceInfoJniLocal; +typedef struct _jvmtiHeapReferenceInfoJniLocal jvmtiHeapReferenceInfoJniLocal; +struct _jvmtiHeapReferenceInfoReserved; +typedef struct _jvmtiHeapReferenceInfoReserved jvmtiHeapReferenceInfoReserved; +union _jvmtiHeapReferenceInfo; +typedef union _jvmtiHeapReferenceInfo jvmtiHeapReferenceInfo; +struct _jvmtiHeapCallbacks; +typedef struct _jvmtiHeapCallbacks jvmtiHeapCallbacks; +struct _jvmtiClassDefinition; +typedef struct _jvmtiClassDefinition jvmtiClassDefinition; +struct _jvmtiMonitorUsage; +typedef struct _jvmtiMonitorUsage jvmtiMonitorUsage; +struct _jvmtiLineNumberEntry; +typedef struct _jvmtiLineNumberEntry jvmtiLineNumberEntry; +struct _jvmtiLocalVariableEntry; +typedef struct _jvmtiLocalVariableEntry jvmtiLocalVariableEntry; +struct _jvmtiParamInfo; +typedef struct _jvmtiParamInfo jvmtiParamInfo; +struct _jvmtiExtensionFunctionInfo; +typedef struct _jvmtiExtensionFunctionInfo jvmtiExtensionFunctionInfo; +struct _jvmtiExtensionEventInfo; +typedef struct _jvmtiExtensionEventInfo jvmtiExtensionEventInfo; +struct _jvmtiTimerInfo; +typedef struct _jvmtiTimerInfo jvmtiTimerInfo; +struct _jvmtiAddrLocationMap; +typedef struct _jvmtiAddrLocationMap jvmtiAddrLocationMap; + + /* Function Types */ + +typedef void (JNICALL *jvmtiStartFunction) + (jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg); + +typedef jint (JNICALL *jvmtiHeapIterationCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, jint length, void* user_data); + +typedef jint (JNICALL *jvmtiHeapReferenceCallback) + (jvmtiHeapReferenceKind reference_kind, const jvmtiHeapReferenceInfo* reference_info, jlong class_tag, jlong referrer_class_tag, jlong size, jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data); + +typedef jint (JNICALL *jvmtiPrimitiveFieldCallback) + (jvmtiHeapReferenceKind kind, const jvmtiHeapReferenceInfo* info, jlong object_class_tag, jlong* object_tag_ptr, jvalue value, jvmtiPrimitiveType value_type, void* user_data); + +typedef jint (JNICALL *jvmtiArrayPrimitiveValueCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, jint element_count, jvmtiPrimitiveType element_type, const void* elements, void* user_data); + +typedef jint (JNICALL *jvmtiStringPrimitiveValueCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, const jchar* value, jint value_length, void* user_data); + +typedef jint (JNICALL *jvmtiReservedCallback) + (); + +typedef jvmtiIterationControl (JNICALL *jvmtiHeapObjectCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiHeapRootCallback) + (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiStackReferenceCallback) + (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong thread_tag, jint depth, jmethodID method, jint slot, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiObjectReferenceCallback) + (jvmtiObjectReferenceKind reference_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong referrer_tag, jint referrer_index, void* user_data); + +typedef jvmtiError (JNICALL *jvmtiExtensionFunction) + (jvmtiEnv* jvmti_env, ...); + +typedef void (JNICALL *jvmtiExtensionEvent) + (jvmtiEnv* jvmti_env, ...); + + + /* Structure Types */ +struct _jvmtiThreadInfo { + char* name; + jint priority; + jboolean is_daemon; + jthreadGroup thread_group; + jobject context_class_loader; +}; +struct _jvmtiMonitorStackDepthInfo { + jobject monitor; + jint stack_depth; +}; +struct _jvmtiThreadGroupInfo { + jthreadGroup parent; + char* name; + jint max_priority; + jboolean is_daemon; +}; +struct _jvmtiFrameInfo { + jmethodID method; + jlocation location; +}; +struct _jvmtiStackInfo { + jthread thread; + jint state; + jvmtiFrameInfo* frame_buffer; + jint frame_count; +}; +struct _jvmtiHeapReferenceInfoField { + jint index; +}; +struct _jvmtiHeapReferenceInfoArray { + jint index; +}; +struct _jvmtiHeapReferenceInfoConstantPool { + jint index; +}; +struct _jvmtiHeapReferenceInfoStackLocal { + jlong thread_tag; + jlong thread_id; + jint depth; + jmethodID method; + jlocation location; + jint slot; +}; +struct _jvmtiHeapReferenceInfoJniLocal { + jlong thread_tag; + jlong thread_id; + jint depth; + jmethodID method; +}; +struct _jvmtiHeapReferenceInfoReserved { + jlong reserved1; + jlong reserved2; + jlong reserved3; + jlong reserved4; + jlong reserved5; + jlong reserved6; + jlong reserved7; + jlong reserved8; +}; +union _jvmtiHeapReferenceInfo { + jvmtiHeapReferenceInfoField field; + jvmtiHeapReferenceInfoArray array; + jvmtiHeapReferenceInfoConstantPool constant_pool; + jvmtiHeapReferenceInfoStackLocal stack_local; + jvmtiHeapReferenceInfoJniLocal jni_local; + jvmtiHeapReferenceInfoReserved other; +}; +struct _jvmtiHeapCallbacks { + jvmtiHeapIterationCallback heap_iteration_callback; + jvmtiHeapReferenceCallback heap_reference_callback; + jvmtiPrimitiveFieldCallback primitive_field_callback; + jvmtiArrayPrimitiveValueCallback array_primitive_value_callback; + jvmtiStringPrimitiveValueCallback string_primitive_value_callback; + jvmtiReservedCallback reserved5; + jvmtiReservedCallback reserved6; + jvmtiReservedCallback reserved7; + jvmtiReservedCallback reserved8; + jvmtiReservedCallback reserved9; + jvmtiReservedCallback reserved10; + jvmtiReservedCallback reserved11; + jvmtiReservedCallback reserved12; + jvmtiReservedCallback reserved13; + jvmtiReservedCallback reserved14; + jvmtiReservedCallback reserved15; +}; +struct _jvmtiClassDefinition { + jclass klass; + jint class_byte_count; + const unsigned char* class_bytes; +}; +struct _jvmtiMonitorUsage { + jthread owner; + jint entry_count; + jint waiter_count; + jthread* waiters; + jint notify_waiter_count; + jthread* notify_waiters; +}; +struct _jvmtiLineNumberEntry { + jlocation start_location; + jint line_number; +}; +struct _jvmtiLocalVariableEntry { + jlocation start_location; + jint length; + char* name; + char* signature; + char* generic_signature; + jint slot; +}; +struct _jvmtiParamInfo { + char* name; + jvmtiParamKind kind; + jvmtiParamTypes base_type; + jboolean null_ok; +}; +struct _jvmtiExtensionFunctionInfo { + jvmtiExtensionFunction func; + char* id; + char* short_description; + jint param_count; + jvmtiParamInfo* params; + jint error_count; + jvmtiError* errors; +}; +struct _jvmtiExtensionEventInfo { + jint extension_event_index; + char* id; + char* short_description; + jint param_count; + jvmtiParamInfo* params; +}; +struct _jvmtiTimerInfo { + jlong max_value; + jboolean may_skip_forward; + jboolean may_skip_backward; + jvmtiTimerKind kind; + jlong reserved1; + jlong reserved2; +}; +struct _jvmtiAddrLocationMap { + const void* start_address; + jlocation location; +}; + +typedef struct { + unsigned int can_tag_objects : 1; + unsigned int can_generate_field_modification_events : 1; + unsigned int can_generate_field_access_events : 1; + unsigned int can_get_bytecodes : 1; + unsigned int can_get_synthetic_attribute : 1; + unsigned int can_get_owned_monitor_info : 1; + unsigned int can_get_current_contended_monitor : 1; + unsigned int can_get_monitor_info : 1; + unsigned int can_pop_frame : 1; + unsigned int can_redefine_classes : 1; + unsigned int can_signal_thread : 1; + unsigned int can_get_source_file_name : 1; + unsigned int can_get_line_numbers : 1; + unsigned int can_get_source_debug_extension : 1; + unsigned int can_access_local_variables : 1; + unsigned int can_maintain_original_method_order : 1; + unsigned int can_generate_single_step_events : 1; + unsigned int can_generate_exception_events : 1; + unsigned int can_generate_frame_pop_events : 1; + unsigned int can_generate_breakpoint_events : 1; + unsigned int can_suspend : 1; + unsigned int can_redefine_any_class : 1; + unsigned int can_get_current_thread_cpu_time : 1; + unsigned int can_get_thread_cpu_time : 1; + unsigned int can_generate_method_entry_events : 1; + unsigned int can_generate_method_exit_events : 1; + unsigned int can_generate_all_class_hook_events : 1; + unsigned int can_generate_compiled_method_load_events : 1; + unsigned int can_generate_monitor_events : 1; + unsigned int can_generate_vm_object_alloc_events : 1; + unsigned int can_generate_native_method_bind_events : 1; + unsigned int can_generate_garbage_collection_events : 1; + unsigned int can_generate_object_free_events : 1; + unsigned int can_force_early_return : 1; + unsigned int can_get_owned_monitor_stack_depth_info : 1; + unsigned int can_get_constant_pool : 1; + unsigned int can_set_native_method_prefix : 1; + unsigned int can_retransform_classes : 1; + unsigned int can_retransform_any_class : 1; + unsigned int can_generate_resource_exhaustion_heap_events : 1; + unsigned int can_generate_resource_exhaustion_threads_events : 1; + unsigned int : 7; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; +} jvmtiCapabilities; + + + /* Event Definitions */ + +typedef void (JNICALL *jvmtiEventReserved)(void); + + +typedef void (JNICALL *jvmtiEventBreakpoint) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location); + +typedef void (JNICALL *jvmtiEventClassFileLoadHook) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jclass class_being_redefined, + jobject loader, + const char* name, + jobject protection_domain, + jint class_data_len, + const unsigned char* class_data, + jint* new_class_data_len, + unsigned char** new_class_data); + +typedef void (JNICALL *jvmtiEventClassLoad) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jclass klass); + +typedef void (JNICALL *jvmtiEventClassPrepare) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jclass klass); + +typedef void (JNICALL *jvmtiEventCompiledMethodLoad) + (jvmtiEnv *jvmti_env, + jmethodID method, + jint code_size, + const void* code_addr, + jint map_length, + const jvmtiAddrLocationMap* map, + const void* compile_info); + +typedef void (JNICALL *jvmtiEventCompiledMethodUnload) + (jvmtiEnv *jvmti_env, + jmethodID method, + const void* code_addr); + +typedef void (JNICALL *jvmtiEventDataDumpRequest) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventDynamicCodeGenerated) + (jvmtiEnv *jvmti_env, + const char* name, + const void* address, + jint length); + +typedef void (JNICALL *jvmtiEventException) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jobject exception, + jmethodID catch_method, + jlocation catch_location); + +typedef void (JNICALL *jvmtiEventExceptionCatch) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jobject exception); + +typedef void (JNICALL *jvmtiEventFieldAccess) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jclass field_klass, + jobject object, + jfieldID field); + +typedef void (JNICALL *jvmtiEventFieldModification) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jclass field_klass, + jobject object, + jfieldID field, + char signature_type, + jvalue new_value); + +typedef void (JNICALL *jvmtiEventFramePop) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jboolean was_popped_by_exception); + +typedef void (JNICALL *jvmtiEventGarbageCollectionFinish) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventGarbageCollectionStart) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventMethodEntry) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method); + +typedef void (JNICALL *jvmtiEventMethodExit) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jboolean was_popped_by_exception, + jvalue return_value); + +typedef void (JNICALL *jvmtiEventMonitorContendedEnter) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object); + +typedef void (JNICALL *jvmtiEventMonitorContendedEntered) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object); + +typedef void (JNICALL *jvmtiEventMonitorWait) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jlong timeout); + +typedef void (JNICALL *jvmtiEventMonitorWaited) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jboolean timed_out); + +typedef void (JNICALL *jvmtiEventNativeMethodBind) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + void* address, + void** new_address_ptr); + +typedef void (JNICALL *jvmtiEventObjectFree) + (jvmtiEnv *jvmti_env, + jlong tag); + +typedef void (JNICALL *jvmtiEventResourceExhausted) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jint flags, + const void* reserved, + const char* description); + +typedef void (JNICALL *jvmtiEventSingleStep) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location); + +typedef void (JNICALL *jvmtiEventThreadEnd) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventThreadStart) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventVMDeath) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env); + +typedef void (JNICALL *jvmtiEventVMInit) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventVMObjectAlloc) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jclass object_klass, + jlong size); + +typedef void (JNICALL *jvmtiEventVMStart) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env); + + /* Event Callback Structure */ + +typedef struct { + /* 50 : VM Initialization Event */ + jvmtiEventVMInit VMInit; + /* 51 : VM Death Event */ + jvmtiEventVMDeath VMDeath; + /* 52 : Thread Start */ + jvmtiEventThreadStart ThreadStart; + /* 53 : Thread End */ + jvmtiEventThreadEnd ThreadEnd; + /* 54 : Class File Load Hook */ + jvmtiEventClassFileLoadHook ClassFileLoadHook; + /* 55 : Class Load */ + jvmtiEventClassLoad ClassLoad; + /* 56 : Class Prepare */ + jvmtiEventClassPrepare ClassPrepare; + /* 57 : VM Start Event */ + jvmtiEventVMStart VMStart; + /* 58 : Exception */ + jvmtiEventException Exception; + /* 59 : Exception Catch */ + jvmtiEventExceptionCatch ExceptionCatch; + /* 60 : Single Step */ + jvmtiEventSingleStep SingleStep; + /* 61 : Frame Pop */ + jvmtiEventFramePop FramePop; + /* 62 : Breakpoint */ + jvmtiEventBreakpoint Breakpoint; + /* 63 : Field Access */ + jvmtiEventFieldAccess FieldAccess; + /* 64 : Field Modification */ + jvmtiEventFieldModification FieldModification; + /* 65 : Method Entry */ + jvmtiEventMethodEntry MethodEntry; + /* 66 : Method Exit */ + jvmtiEventMethodExit MethodExit; + /* 67 : Native Method Bind */ + jvmtiEventNativeMethodBind NativeMethodBind; + /* 68 : Compiled Method Load */ + jvmtiEventCompiledMethodLoad CompiledMethodLoad; + /* 69 : Compiled Method Unload */ + jvmtiEventCompiledMethodUnload CompiledMethodUnload; + /* 70 : Dynamic Code Generated */ + jvmtiEventDynamicCodeGenerated DynamicCodeGenerated; + /* 71 : Data Dump Request */ + jvmtiEventDataDumpRequest DataDumpRequest; + /* 72 */ + jvmtiEventReserved reserved72; + /* 73 : Monitor Wait */ + jvmtiEventMonitorWait MonitorWait; + /* 74 : Monitor Waited */ + jvmtiEventMonitorWaited MonitorWaited; + /* 75 : Monitor Contended Enter */ + jvmtiEventMonitorContendedEnter MonitorContendedEnter; + /* 76 : Monitor Contended Entered */ + jvmtiEventMonitorContendedEntered MonitorContendedEntered; + /* 77 */ + jvmtiEventReserved reserved77; + /* 78 */ + jvmtiEventReserved reserved78; + /* 79 */ + jvmtiEventReserved reserved79; + /* 80 : Resource Exhausted */ + jvmtiEventResourceExhausted ResourceExhausted; + /* 81 : Garbage Collection Start */ + jvmtiEventGarbageCollectionStart GarbageCollectionStart; + /* 82 : Garbage Collection Finish */ + jvmtiEventGarbageCollectionFinish GarbageCollectionFinish; + /* 83 : Object Free */ + jvmtiEventObjectFree ObjectFree; + /* 84 : VM Object Allocation */ + jvmtiEventVMObjectAlloc VMObjectAlloc; +} jvmtiEventCallbacks; + + + /* Function Interface */ + +typedef struct jvmtiInterface_1_ { + + /* 1 : RESERVED */ + void *reserved1; + + /* 2 : Set Event Notification Mode */ + jvmtiError (JNICALL *SetEventNotificationMode) (jvmtiEnv* env, + jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread, + ...); + + /* 3 : RESERVED */ + void *reserved3; + + /* 4 : Get All Threads */ + jvmtiError (JNICALL *GetAllThreads) (jvmtiEnv* env, + jint* threads_count_ptr, + jthread** threads_ptr); + + /* 5 : Suspend Thread */ + jvmtiError (JNICALL *SuspendThread) (jvmtiEnv* env, + jthread thread); + + /* 6 : Resume Thread */ + jvmtiError (JNICALL *ResumeThread) (jvmtiEnv* env, + jthread thread); + + /* 7 : Stop Thread */ + jvmtiError (JNICALL *StopThread) (jvmtiEnv* env, + jthread thread, + jobject exception); + + /* 8 : Interrupt Thread */ + jvmtiError (JNICALL *InterruptThread) (jvmtiEnv* env, + jthread thread); + + /* 9 : Get Thread Info */ + jvmtiError (JNICALL *GetThreadInfo) (jvmtiEnv* env, + jthread thread, + jvmtiThreadInfo* info_ptr); + + /* 10 : Get Owned Monitor Info */ + jvmtiError (JNICALL *GetOwnedMonitorInfo) (jvmtiEnv* env, + jthread thread, + jint* owned_monitor_count_ptr, + jobject** owned_monitors_ptr); + + /* 11 : Get Current Contended Monitor */ + jvmtiError (JNICALL *GetCurrentContendedMonitor) (jvmtiEnv* env, + jthread thread, + jobject* monitor_ptr); + + /* 12 : Run Agent Thread */ + jvmtiError (JNICALL *RunAgentThread) (jvmtiEnv* env, + jthread thread, + jvmtiStartFunction proc, + const void* arg, + jint priority); + + /* 13 : Get Top Thread Groups */ + jvmtiError (JNICALL *GetTopThreadGroups) (jvmtiEnv* env, + jint* group_count_ptr, + jthreadGroup** groups_ptr); + + /* 14 : Get Thread Group Info */ + jvmtiError (JNICALL *GetThreadGroupInfo) (jvmtiEnv* env, + jthreadGroup group, + jvmtiThreadGroupInfo* info_ptr); + + /* 15 : Get Thread Group Children */ + jvmtiError (JNICALL *GetThreadGroupChildren) (jvmtiEnv* env, + jthreadGroup group, + jint* thread_count_ptr, + jthread** threads_ptr, + jint* group_count_ptr, + jthreadGroup** groups_ptr); + + /* 16 : Get Frame Count */ + jvmtiError (JNICALL *GetFrameCount) (jvmtiEnv* env, + jthread thread, + jint* count_ptr); + + /* 17 : Get Thread State */ + jvmtiError (JNICALL *GetThreadState) (jvmtiEnv* env, + jthread thread, + jint* thread_state_ptr); + + /* 18 : Get Current Thread */ + jvmtiError (JNICALL *GetCurrentThread) (jvmtiEnv* env, + jthread* thread_ptr); + + /* 19 : Get Frame Location */ + jvmtiError (JNICALL *GetFrameLocation) (jvmtiEnv* env, + jthread thread, + jint depth, + jmethodID* method_ptr, + jlocation* location_ptr); + + /* 20 : Notify Frame Pop */ + jvmtiError (JNICALL *NotifyFramePop) (jvmtiEnv* env, + jthread thread, + jint depth); + + /* 21 : Get Local Variable - Object */ + jvmtiError (JNICALL *GetLocalObject) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject* value_ptr); + + /* 22 : Get Local Variable - Int */ + jvmtiError (JNICALL *GetLocalInt) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint* value_ptr); + + /* 23 : Get Local Variable - Long */ + jvmtiError (JNICALL *GetLocalLong) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong* value_ptr); + + /* 24 : Get Local Variable - Float */ + jvmtiError (JNICALL *GetLocalFloat) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat* value_ptr); + + /* 25 : Get Local Variable - Double */ + jvmtiError (JNICALL *GetLocalDouble) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble* value_ptr); + + /* 26 : Set Local Variable - Object */ + jvmtiError (JNICALL *SetLocalObject) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject value); + + /* 27 : Set Local Variable - Int */ + jvmtiError (JNICALL *SetLocalInt) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint value); + + /* 28 : Set Local Variable - Long */ + jvmtiError (JNICALL *SetLocalLong) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong value); + + /* 29 : Set Local Variable - Float */ + jvmtiError (JNICALL *SetLocalFloat) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat value); + + /* 30 : Set Local Variable - Double */ + jvmtiError (JNICALL *SetLocalDouble) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble value); + + /* 31 : Create Raw Monitor */ + jvmtiError (JNICALL *CreateRawMonitor) (jvmtiEnv* env, + const char* name, + jrawMonitorID* monitor_ptr); + + /* 32 : Destroy Raw Monitor */ + jvmtiError (JNICALL *DestroyRawMonitor) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 33 : Raw Monitor Enter */ + jvmtiError (JNICALL *RawMonitorEnter) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 34 : Raw Monitor Exit */ + jvmtiError (JNICALL *RawMonitorExit) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 35 : Raw Monitor Wait */ + jvmtiError (JNICALL *RawMonitorWait) (jvmtiEnv* env, + jrawMonitorID monitor, + jlong millis); + + /* 36 : Raw Monitor Notify */ + jvmtiError (JNICALL *RawMonitorNotify) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 37 : Raw Monitor Notify All */ + jvmtiError (JNICALL *RawMonitorNotifyAll) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 38 : Set Breakpoint */ + jvmtiError (JNICALL *SetBreakpoint) (jvmtiEnv* env, + jmethodID method, + jlocation location); + + /* 39 : Clear Breakpoint */ + jvmtiError (JNICALL *ClearBreakpoint) (jvmtiEnv* env, + jmethodID method, + jlocation location); + + /* 40 : RESERVED */ + void *reserved40; + + /* 41 : Set Field Access Watch */ + jvmtiError (JNICALL *SetFieldAccessWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 42 : Clear Field Access Watch */ + jvmtiError (JNICALL *ClearFieldAccessWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 43 : Set Field Modification Watch */ + jvmtiError (JNICALL *SetFieldModificationWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 44 : Clear Field Modification Watch */ + jvmtiError (JNICALL *ClearFieldModificationWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 45 : Is Modifiable Class */ + jvmtiError (JNICALL *IsModifiableClass) (jvmtiEnv* env, + jclass klass, + jboolean* is_modifiable_class_ptr); + + /* 46 : Allocate */ + jvmtiError (JNICALL *Allocate) (jvmtiEnv* env, + jlong size, + unsigned char** mem_ptr); + + /* 47 : Deallocate */ + jvmtiError (JNICALL *Deallocate) (jvmtiEnv* env, + unsigned char* mem); + + /* 48 : Get Class Signature */ + jvmtiError (JNICALL *GetClassSignature) (jvmtiEnv* env, + jclass klass, + char** signature_ptr, + char** generic_ptr); + + /* 49 : Get Class Status */ + jvmtiError (JNICALL *GetClassStatus) (jvmtiEnv* env, + jclass klass, + jint* status_ptr); + + /* 50 : Get Source File Name */ + jvmtiError (JNICALL *GetSourceFileName) (jvmtiEnv* env, + jclass klass, + char** source_name_ptr); + + /* 51 : Get Class Modifiers */ + jvmtiError (JNICALL *GetClassModifiers) (jvmtiEnv* env, + jclass klass, + jint* modifiers_ptr); + + /* 52 : Get Class Methods */ + jvmtiError (JNICALL *GetClassMethods) (jvmtiEnv* env, + jclass klass, + jint* method_count_ptr, + jmethodID** methods_ptr); + + /* 53 : Get Class Fields */ + jvmtiError (JNICALL *GetClassFields) (jvmtiEnv* env, + jclass klass, + jint* field_count_ptr, + jfieldID** fields_ptr); + + /* 54 : Get Implemented Interfaces */ + jvmtiError (JNICALL *GetImplementedInterfaces) (jvmtiEnv* env, + jclass klass, + jint* interface_count_ptr, + jclass** interfaces_ptr); + + /* 55 : Is Interface */ + jvmtiError (JNICALL *IsInterface) (jvmtiEnv* env, + jclass klass, + jboolean* is_interface_ptr); + + /* 56 : Is Array Class */ + jvmtiError (JNICALL *IsArrayClass) (jvmtiEnv* env, + jclass klass, + jboolean* is_array_class_ptr); + + /* 57 : Get Class Loader */ + jvmtiError (JNICALL *GetClassLoader) (jvmtiEnv* env, + jclass klass, + jobject* classloader_ptr); + + /* 58 : Get Object Hash Code */ + jvmtiError (JNICALL *GetObjectHashCode) (jvmtiEnv* env, + jobject object, + jint* hash_code_ptr); + + /* 59 : Get Object Monitor Usage */ + jvmtiError (JNICALL *GetObjectMonitorUsage) (jvmtiEnv* env, + jobject object, + jvmtiMonitorUsage* info_ptr); + + /* 60 : Get Field Name (and Signature) */ + jvmtiError (JNICALL *GetFieldName) (jvmtiEnv* env, + jclass klass, + jfieldID field, + char** name_ptr, + char** signature_ptr, + char** generic_ptr); + + /* 61 : Get Field Declaring Class */ + jvmtiError (JNICALL *GetFieldDeclaringClass) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jclass* declaring_class_ptr); + + /* 62 : Get Field Modifiers */ + jvmtiError (JNICALL *GetFieldModifiers) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jint* modifiers_ptr); + + /* 63 : Is Field Synthetic */ + jvmtiError (JNICALL *IsFieldSynthetic) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jboolean* is_synthetic_ptr); + + /* 64 : Get Method Name (and Signature) */ + jvmtiError (JNICALL *GetMethodName) (jvmtiEnv* env, + jmethodID method, + char** name_ptr, + char** signature_ptr, + char** generic_ptr); + + /* 65 : Get Method Declaring Class */ + jvmtiError (JNICALL *GetMethodDeclaringClass) (jvmtiEnv* env, + jmethodID method, + jclass* declaring_class_ptr); + + /* 66 : Get Method Modifiers */ + jvmtiError (JNICALL *GetMethodModifiers) (jvmtiEnv* env, + jmethodID method, + jint* modifiers_ptr); + + /* 67 : RESERVED */ + void *reserved67; + + /* 68 : Get Max Locals */ + jvmtiError (JNICALL *GetMaxLocals) (jvmtiEnv* env, + jmethodID method, + jint* max_ptr); + + /* 69 : Get Arguments Size */ + jvmtiError (JNICALL *GetArgumentsSize) (jvmtiEnv* env, + jmethodID method, + jint* size_ptr); + + /* 70 : Get Line Number Table */ + jvmtiError (JNICALL *GetLineNumberTable) (jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr); + + /* 71 : Get Method Location */ + jvmtiError (JNICALL *GetMethodLocation) (jvmtiEnv* env, + jmethodID method, + jlocation* start_location_ptr, + jlocation* end_location_ptr); + + /* 72 : Get Local Variable Table */ + jvmtiError (JNICALL *GetLocalVariableTable) (jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLocalVariableEntry** table_ptr); + + /* 73 : Set Native Method Prefix */ + jvmtiError (JNICALL *SetNativeMethodPrefix) (jvmtiEnv* env, + const char* prefix); + + /* 74 : Set Native Method Prefixes */ + jvmtiError (JNICALL *SetNativeMethodPrefixes) (jvmtiEnv* env, + jint prefix_count, + char** prefixes); + + /* 75 : Get Bytecodes */ + jvmtiError (JNICALL *GetBytecodes) (jvmtiEnv* env, + jmethodID method, + jint* bytecode_count_ptr, + unsigned char** bytecodes_ptr); + + /* 76 : Is Method Native */ + jvmtiError (JNICALL *IsMethodNative) (jvmtiEnv* env, + jmethodID method, + jboolean* is_native_ptr); + + /* 77 : Is Method Synthetic */ + jvmtiError (JNICALL *IsMethodSynthetic) (jvmtiEnv* env, + jmethodID method, + jboolean* is_synthetic_ptr); + + /* 78 : Get Loaded Classes */ + jvmtiError (JNICALL *GetLoadedClasses) (jvmtiEnv* env, + jint* class_count_ptr, + jclass** classes_ptr); + + /* 79 : Get Classloader Classes */ + jvmtiError (JNICALL *GetClassLoaderClasses) (jvmtiEnv* env, + jobject initiating_loader, + jint* class_count_ptr, + jclass** classes_ptr); + + /* 80 : Pop Frame */ + jvmtiError (JNICALL *PopFrame) (jvmtiEnv* env, + jthread thread); + + /* 81 : Force Early Return - Object */ + jvmtiError (JNICALL *ForceEarlyReturnObject) (jvmtiEnv* env, + jthread thread, + jobject value); + + /* 82 : Force Early Return - Int */ + jvmtiError (JNICALL *ForceEarlyReturnInt) (jvmtiEnv* env, + jthread thread, + jint value); + + /* 83 : Force Early Return - Long */ + jvmtiError (JNICALL *ForceEarlyReturnLong) (jvmtiEnv* env, + jthread thread, + jlong value); + + /* 84 : Force Early Return - Float */ + jvmtiError (JNICALL *ForceEarlyReturnFloat) (jvmtiEnv* env, + jthread thread, + jfloat value); + + /* 85 : Force Early Return - Double */ + jvmtiError (JNICALL *ForceEarlyReturnDouble) (jvmtiEnv* env, + jthread thread, + jdouble value); + + /* 86 : Force Early Return - Void */ + jvmtiError (JNICALL *ForceEarlyReturnVoid) (jvmtiEnv* env, + jthread thread); + + /* 87 : Redefine Classes */ + jvmtiError (JNICALL *RedefineClasses) (jvmtiEnv* env, + jint class_count, + const jvmtiClassDefinition* class_definitions); + + /* 88 : Get Version Number */ + jvmtiError (JNICALL *GetVersionNumber) (jvmtiEnv* env, + jint* version_ptr); + + /* 89 : Get Capabilities */ + jvmtiError (JNICALL *GetCapabilities) (jvmtiEnv* env, + jvmtiCapabilities* capabilities_ptr); + + /* 90 : Get Source Debug Extension */ + jvmtiError (JNICALL *GetSourceDebugExtension) (jvmtiEnv* env, + jclass klass, + char** source_debug_extension_ptr); + + /* 91 : Is Method Obsolete */ + jvmtiError (JNICALL *IsMethodObsolete) (jvmtiEnv* env, + jmethodID method, + jboolean* is_obsolete_ptr); + + /* 92 : Suspend Thread List */ + jvmtiError (JNICALL *SuspendThreadList) (jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results); + + /* 93 : Resume Thread List */ + jvmtiError (JNICALL *ResumeThreadList) (jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results); + + /* 94 : RESERVED */ + void *reserved94; + + /* 95 : RESERVED */ + void *reserved95; + + /* 96 : RESERVED */ + void *reserved96; + + /* 97 : RESERVED */ + void *reserved97; + + /* 98 : RESERVED */ + void *reserved98; + + /* 99 : RESERVED */ + void *reserved99; + + /* 100 : Get All Stack Traces */ + jvmtiError (JNICALL *GetAllStackTraces) (jvmtiEnv* env, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr, + jint* thread_count_ptr); + + /* 101 : Get Thread List Stack Traces */ + jvmtiError (JNICALL *GetThreadListStackTraces) (jvmtiEnv* env, + jint thread_count, + const jthread* thread_list, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr); + + /* 102 : Get Thread Local Storage */ + jvmtiError (JNICALL *GetThreadLocalStorage) (jvmtiEnv* env, + jthread thread, + void** data_ptr); + + /* 103 : Set Thread Local Storage */ + jvmtiError (JNICALL *SetThreadLocalStorage) (jvmtiEnv* env, + jthread thread, + const void* data); + + /* 104 : Get Stack Trace */ + jvmtiError (JNICALL *GetStackTrace) (jvmtiEnv* env, + jthread thread, + jint start_depth, + jint max_frame_count, + jvmtiFrameInfo* frame_buffer, + jint* count_ptr); + + /* 105 : RESERVED */ + void *reserved105; + + /* 106 : Get Tag */ + jvmtiError (JNICALL *GetTag) (jvmtiEnv* env, + jobject object, + jlong* tag_ptr); + + /* 107 : Set Tag */ + jvmtiError (JNICALL *SetTag) (jvmtiEnv* env, + jobject object, + jlong tag); + + /* 108 : Force Garbage Collection */ + jvmtiError (JNICALL *ForceGarbageCollection) (jvmtiEnv* env); + + /* 109 : Iterate Over Objects Reachable From Object */ + jvmtiError (JNICALL *IterateOverObjectsReachableFromObject) (jvmtiEnv* env, + jobject object, + jvmtiObjectReferenceCallback object_reference_callback, + const void* user_data); + + /* 110 : Iterate Over Reachable Objects */ + jvmtiError (JNICALL *IterateOverReachableObjects) (jvmtiEnv* env, + jvmtiHeapRootCallback heap_root_callback, + jvmtiStackReferenceCallback stack_ref_callback, + jvmtiObjectReferenceCallback object_ref_callback, + const void* user_data); + + /* 111 : Iterate Over Heap */ + jvmtiError (JNICALL *IterateOverHeap) (jvmtiEnv* env, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data); + + /* 112 : Iterate Over Instances Of Class */ + jvmtiError (JNICALL *IterateOverInstancesOfClass) (jvmtiEnv* env, + jclass klass, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data); + + /* 113 : RESERVED */ + void *reserved113; + + /* 114 : Get Objects With Tags */ + jvmtiError (JNICALL *GetObjectsWithTags) (jvmtiEnv* env, + jint tag_count, + const jlong* tags, + jint* count_ptr, + jobject** object_result_ptr, + jlong** tag_result_ptr); + + /* 115 : Follow References */ + jvmtiError (JNICALL *FollowReferences) (jvmtiEnv* env, + jint heap_filter, + jclass klass, + jobject initial_object, + const jvmtiHeapCallbacks* callbacks, + const void* user_data); + + /* 116 : Iterate Through Heap */ + jvmtiError (JNICALL *IterateThroughHeap) (jvmtiEnv* env, + jint heap_filter, + jclass klass, + const jvmtiHeapCallbacks* callbacks, + const void* user_data); + + /* 117 : RESERVED */ + void *reserved117; + + /* 118 : RESERVED */ + void *reserved118; + + /* 119 : RESERVED */ + void *reserved119; + + /* 120 : Set JNI Function Table */ + jvmtiError (JNICALL *SetJNIFunctionTable) (jvmtiEnv* env, + const jniNativeInterface* function_table); + + /* 121 : Get JNI Function Table */ + jvmtiError (JNICALL *GetJNIFunctionTable) (jvmtiEnv* env, + jniNativeInterface** function_table); + + /* 122 : Set Event Callbacks */ + jvmtiError (JNICALL *SetEventCallbacks) (jvmtiEnv* env, + const jvmtiEventCallbacks* callbacks, + jint size_of_callbacks); + + /* 123 : Generate Events */ + jvmtiError (JNICALL *GenerateEvents) (jvmtiEnv* env, + jvmtiEvent event_type); + + /* 124 : Get Extension Functions */ + jvmtiError (JNICALL *GetExtensionFunctions) (jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionFunctionInfo** extensions); + + /* 125 : Get Extension Events */ + jvmtiError (JNICALL *GetExtensionEvents) (jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionEventInfo** extensions); + + /* 126 : Set Extension Event Callback */ + jvmtiError (JNICALL *SetExtensionEventCallback) (jvmtiEnv* env, + jint extension_event_index, + jvmtiExtensionEvent callback); + + /* 127 : Dispose Environment */ + jvmtiError (JNICALL *DisposeEnvironment) (jvmtiEnv* env); + + /* 128 : Get Error Name */ + jvmtiError (JNICALL *GetErrorName) (jvmtiEnv* env, + jvmtiError error, + char** name_ptr); + + /* 129 : Get JLocation Format */ + jvmtiError (JNICALL *GetJLocationFormat) (jvmtiEnv* env, + jvmtiJlocationFormat* format_ptr); + + /* 130 : Get System Properties */ + jvmtiError (JNICALL *GetSystemProperties) (jvmtiEnv* env, + jint* count_ptr, + char*** property_ptr); + + /* 131 : Get System Property */ + jvmtiError (JNICALL *GetSystemProperty) (jvmtiEnv* env, + const char* property, + char** value_ptr); + + /* 132 : Set System Property */ + jvmtiError (JNICALL *SetSystemProperty) (jvmtiEnv* env, + const char* property, + const char* value); + + /* 133 : Get Phase */ + jvmtiError (JNICALL *GetPhase) (jvmtiEnv* env, + jvmtiPhase* phase_ptr); + + /* 134 : Get Current Thread CPU Timer Information */ + jvmtiError (JNICALL *GetCurrentThreadCpuTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 135 : Get Current Thread CPU Time */ + jvmtiError (JNICALL *GetCurrentThreadCpuTime) (jvmtiEnv* env, + jlong* nanos_ptr); + + /* 136 : Get Thread CPU Timer Information */ + jvmtiError (JNICALL *GetThreadCpuTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 137 : Get Thread CPU Time */ + jvmtiError (JNICALL *GetThreadCpuTime) (jvmtiEnv* env, + jthread thread, + jlong* nanos_ptr); + + /* 138 : Get Timer Information */ + jvmtiError (JNICALL *GetTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 139 : Get Time */ + jvmtiError (JNICALL *GetTime) (jvmtiEnv* env, + jlong* nanos_ptr); + + /* 140 : Get Potential Capabilities */ + jvmtiError (JNICALL *GetPotentialCapabilities) (jvmtiEnv* env, + jvmtiCapabilities* capabilities_ptr); + + /* 141 : RESERVED */ + void *reserved141; + + /* 142 : Add Capabilities */ + jvmtiError (JNICALL *AddCapabilities) (jvmtiEnv* env, + const jvmtiCapabilities* capabilities_ptr); + + /* 143 : Relinquish Capabilities */ + jvmtiError (JNICALL *RelinquishCapabilities) (jvmtiEnv* env, + const jvmtiCapabilities* capabilities_ptr); + + /* 144 : Get Available Processors */ + jvmtiError (JNICALL *GetAvailableProcessors) (jvmtiEnv* env, + jint* processor_count_ptr); + + /* 145 : Get Class Version Numbers */ + jvmtiError (JNICALL *GetClassVersionNumbers) (jvmtiEnv* env, + jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr); + + /* 146 : Get Constant Pool */ + jvmtiError (JNICALL *GetConstantPool) (jvmtiEnv* env, + jclass klass, + jint* constant_pool_count_ptr, + jint* constant_pool_byte_count_ptr, + unsigned char** constant_pool_bytes_ptr); + + /* 147 : Get Environment Local Storage */ + jvmtiError (JNICALL *GetEnvironmentLocalStorage) (jvmtiEnv* env, + void** data_ptr); + + /* 148 : Set Environment Local Storage */ + jvmtiError (JNICALL *SetEnvironmentLocalStorage) (jvmtiEnv* env, + const void* data); + + /* 149 : Add To Bootstrap Class Loader Search */ + jvmtiError (JNICALL *AddToBootstrapClassLoaderSearch) (jvmtiEnv* env, + const char* segment); + + /* 150 : Set Verbose Flag */ + jvmtiError (JNICALL *SetVerboseFlag) (jvmtiEnv* env, + jvmtiVerboseFlag flag, + jboolean value); + + /* 151 : Add To System Class Loader Search */ + jvmtiError (JNICALL *AddToSystemClassLoaderSearch) (jvmtiEnv* env, + const char* segment); + + /* 152 : Retransform Classes */ + jvmtiError (JNICALL *RetransformClasses) (jvmtiEnv* env, + jint class_count, + const jclass* classes); + + /* 153 : Get Owned Monitor Stack Depth Info */ + jvmtiError (JNICALL *GetOwnedMonitorStackDepthInfo) (jvmtiEnv* env, + jthread thread, + jint* monitor_info_count_ptr, + jvmtiMonitorStackDepthInfo** monitor_info_ptr); + + /* 154 : Get Object Size */ + jvmtiError (JNICALL *GetObjectSize) (jvmtiEnv* env, + jobject object, + jlong* size_ptr); + + /* 155 : Get Local Instance */ + jvmtiError (JNICALL *GetLocalInstance) (jvmtiEnv* env, + jthread thread, + jint depth, + jobject* value_ptr); + +} jvmtiInterface_1; + +struct _jvmtiEnv { + const struct jvmtiInterface_1_ *functions; +#ifdef __cplusplus + + + jvmtiError Allocate(jlong size, + unsigned char** mem_ptr) { + return functions->Allocate(this, size, mem_ptr); + } + + jvmtiError Deallocate(unsigned char* mem) { + return functions->Deallocate(this, mem); + } + + jvmtiError GetThreadState(jthread thread, + jint* thread_state_ptr) { + return functions->GetThreadState(this, thread, thread_state_ptr); + } + + jvmtiError GetCurrentThread(jthread* thread_ptr) { + return functions->GetCurrentThread(this, thread_ptr); + } + + jvmtiError GetAllThreads(jint* threads_count_ptr, + jthread** threads_ptr) { + return functions->GetAllThreads(this, threads_count_ptr, threads_ptr); + } + + jvmtiError SuspendThread(jthread thread) { + return functions->SuspendThread(this, thread); + } + + jvmtiError SuspendThreadList(jint request_count, + const jthread* request_list, + jvmtiError* results) { + return functions->SuspendThreadList(this, request_count, request_list, results); + } + + jvmtiError ResumeThread(jthread thread) { + return functions->ResumeThread(this, thread); + } + + jvmtiError ResumeThreadList(jint request_count, + const jthread* request_list, + jvmtiError* results) { + return functions->ResumeThreadList(this, request_count, request_list, results); + } + + jvmtiError StopThread(jthread thread, + jobject exception) { + return functions->StopThread(this, thread, exception); + } + + jvmtiError InterruptThread(jthread thread) { + return functions->InterruptThread(this, thread); + } + + jvmtiError GetThreadInfo(jthread thread, + jvmtiThreadInfo* info_ptr) { + return functions->GetThreadInfo(this, thread, info_ptr); + } + + jvmtiError GetOwnedMonitorInfo(jthread thread, + jint* owned_monitor_count_ptr, + jobject** owned_monitors_ptr) { + return functions->GetOwnedMonitorInfo(this, thread, owned_monitor_count_ptr, owned_monitors_ptr); + } + + jvmtiError GetOwnedMonitorStackDepthInfo(jthread thread, + jint* monitor_info_count_ptr, + jvmtiMonitorStackDepthInfo** monitor_info_ptr) { + return functions->GetOwnedMonitorStackDepthInfo(this, thread, monitor_info_count_ptr, monitor_info_ptr); + } + + jvmtiError GetCurrentContendedMonitor(jthread thread, + jobject* monitor_ptr) { + return functions->GetCurrentContendedMonitor(this, thread, monitor_ptr); + } + + jvmtiError RunAgentThread(jthread thread, + jvmtiStartFunction proc, + const void* arg, + jint priority) { + return functions->RunAgentThread(this, thread, proc, arg, priority); + } + + jvmtiError SetThreadLocalStorage(jthread thread, + const void* data) { + return functions->SetThreadLocalStorage(this, thread, data); + } + + jvmtiError GetThreadLocalStorage(jthread thread, + void** data_ptr) { + return functions->GetThreadLocalStorage(this, thread, data_ptr); + } + + jvmtiError GetTopThreadGroups(jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return functions->GetTopThreadGroups(this, group_count_ptr, groups_ptr); + } + + jvmtiError GetThreadGroupInfo(jthreadGroup group, + jvmtiThreadGroupInfo* info_ptr) { + return functions->GetThreadGroupInfo(this, group, info_ptr); + } + + jvmtiError GetThreadGroupChildren(jthreadGroup group, + jint* thread_count_ptr, + jthread** threads_ptr, + jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return functions->GetThreadGroupChildren(this, group, thread_count_ptr, threads_ptr, group_count_ptr, groups_ptr); + } + + jvmtiError GetStackTrace(jthread thread, + jint start_depth, + jint max_frame_count, + jvmtiFrameInfo* frame_buffer, + jint* count_ptr) { + return functions->GetStackTrace(this, thread, start_depth, max_frame_count, frame_buffer, count_ptr); + } + + jvmtiError GetAllStackTraces(jint max_frame_count, + jvmtiStackInfo** stack_info_ptr, + jint* thread_count_ptr) { + return functions->GetAllStackTraces(this, max_frame_count, stack_info_ptr, thread_count_ptr); + } + + jvmtiError GetThreadListStackTraces(jint thread_count, + const jthread* thread_list, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr) { + return functions->GetThreadListStackTraces(this, thread_count, thread_list, max_frame_count, stack_info_ptr); + } + + jvmtiError GetFrameCount(jthread thread, + jint* count_ptr) { + return functions->GetFrameCount(this, thread, count_ptr); + } + + jvmtiError PopFrame(jthread thread) { + return functions->PopFrame(this, thread); + } + + jvmtiError GetFrameLocation(jthread thread, + jint depth, + jmethodID* method_ptr, + jlocation* location_ptr) { + return functions->GetFrameLocation(this, thread, depth, method_ptr, location_ptr); + } + + jvmtiError NotifyFramePop(jthread thread, + jint depth) { + return functions->NotifyFramePop(this, thread, depth); + } + + jvmtiError ForceEarlyReturnObject(jthread thread, + jobject value) { + return functions->ForceEarlyReturnObject(this, thread, value); + } + + jvmtiError ForceEarlyReturnInt(jthread thread, + jint value) { + return functions->ForceEarlyReturnInt(this, thread, value); + } + + jvmtiError ForceEarlyReturnLong(jthread thread, + jlong value) { + return functions->ForceEarlyReturnLong(this, thread, value); + } + + jvmtiError ForceEarlyReturnFloat(jthread thread, + jfloat value) { + return functions->ForceEarlyReturnFloat(this, thread, value); + } + + jvmtiError ForceEarlyReturnDouble(jthread thread, + jdouble value) { + return functions->ForceEarlyReturnDouble(this, thread, value); + } + + jvmtiError ForceEarlyReturnVoid(jthread thread) { + return functions->ForceEarlyReturnVoid(this, thread); + } + + jvmtiError FollowReferences(jint heap_filter, + jclass klass, + jobject initial_object, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return functions->FollowReferences(this, heap_filter, klass, initial_object, callbacks, user_data); + } + + jvmtiError IterateThroughHeap(jint heap_filter, + jclass klass, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return functions->IterateThroughHeap(this, heap_filter, klass, callbacks, user_data); + } + + jvmtiError GetTag(jobject object, + jlong* tag_ptr) { + return functions->GetTag(this, object, tag_ptr); + } + + jvmtiError SetTag(jobject object, + jlong tag) { + return functions->SetTag(this, object, tag); + } + + jvmtiError GetObjectsWithTags(jint tag_count, + const jlong* tags, + jint* count_ptr, + jobject** object_result_ptr, + jlong** tag_result_ptr) { + return functions->GetObjectsWithTags(this, tag_count, tags, count_ptr, object_result_ptr, tag_result_ptr); + } + + jvmtiError ForceGarbageCollection() { + return functions->ForceGarbageCollection(this); + } + + jvmtiError IterateOverObjectsReachableFromObject(jobject object, + jvmtiObjectReferenceCallback object_reference_callback, + const void* user_data) { + return functions->IterateOverObjectsReachableFromObject(this, object, object_reference_callback, user_data); + } + + jvmtiError IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, + jvmtiStackReferenceCallback stack_ref_callback, + jvmtiObjectReferenceCallback object_ref_callback, + const void* user_data) { + return functions->IterateOverReachableObjects(this, heap_root_callback, stack_ref_callback, object_ref_callback, user_data); + } + + jvmtiError IterateOverHeap(jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return functions->IterateOverHeap(this, object_filter, heap_object_callback, user_data); + } + + jvmtiError IterateOverInstancesOfClass(jclass klass, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return functions->IterateOverInstancesOfClass(this, klass, object_filter, heap_object_callback, user_data); + } + + jvmtiError GetLocalObject(jthread thread, + jint depth, + jint slot, + jobject* value_ptr) { + return functions->GetLocalObject(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalInstance(jthread thread, + jint depth, + jobject* value_ptr) { + return functions->GetLocalInstance(this, thread, depth, value_ptr); + } + + jvmtiError GetLocalInt(jthread thread, + jint depth, + jint slot, + jint* value_ptr) { + return functions->GetLocalInt(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalLong(jthread thread, + jint depth, + jint slot, + jlong* value_ptr) { + return functions->GetLocalLong(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalFloat(jthread thread, + jint depth, + jint slot, + jfloat* value_ptr) { + return functions->GetLocalFloat(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalDouble(jthread thread, + jint depth, + jint slot, + jdouble* value_ptr) { + return functions->GetLocalDouble(this, thread, depth, slot, value_ptr); + } + + jvmtiError SetLocalObject(jthread thread, + jint depth, + jint slot, + jobject value) { + return functions->SetLocalObject(this, thread, depth, slot, value); + } + + jvmtiError SetLocalInt(jthread thread, + jint depth, + jint slot, + jint value) { + return functions->SetLocalInt(this, thread, depth, slot, value); + } + + jvmtiError SetLocalLong(jthread thread, + jint depth, + jint slot, + jlong value) { + return functions->SetLocalLong(this, thread, depth, slot, value); + } + + jvmtiError SetLocalFloat(jthread thread, + jint depth, + jint slot, + jfloat value) { + return functions->SetLocalFloat(this, thread, depth, slot, value); + } + + jvmtiError SetLocalDouble(jthread thread, + jint depth, + jint slot, + jdouble value) { + return functions->SetLocalDouble(this, thread, depth, slot, value); + } + + jvmtiError SetBreakpoint(jmethodID method, + jlocation location) { + return functions->SetBreakpoint(this, method, location); + } + + jvmtiError ClearBreakpoint(jmethodID method, + jlocation location) { + return functions->ClearBreakpoint(this, method, location); + } + + jvmtiError SetFieldAccessWatch(jclass klass, + jfieldID field) { + return functions->SetFieldAccessWatch(this, klass, field); + } + + jvmtiError ClearFieldAccessWatch(jclass klass, + jfieldID field) { + return functions->ClearFieldAccessWatch(this, klass, field); + } + + jvmtiError SetFieldModificationWatch(jclass klass, + jfieldID field) { + return functions->SetFieldModificationWatch(this, klass, field); + } + + jvmtiError ClearFieldModificationWatch(jclass klass, + jfieldID field) { + return functions->ClearFieldModificationWatch(this, klass, field); + } + + jvmtiError GetLoadedClasses(jint* class_count_ptr, + jclass** classes_ptr) { + return functions->GetLoadedClasses(this, class_count_ptr, classes_ptr); + } + + jvmtiError GetClassLoaderClasses(jobject initiating_loader, + jint* class_count_ptr, + jclass** classes_ptr) { + return functions->GetClassLoaderClasses(this, initiating_loader, class_count_ptr, classes_ptr); + } + + jvmtiError GetClassSignature(jclass klass, + char** signature_ptr, + char** generic_ptr) { + return functions->GetClassSignature(this, klass, signature_ptr, generic_ptr); + } + + jvmtiError GetClassStatus(jclass klass, + jint* status_ptr) { + return functions->GetClassStatus(this, klass, status_ptr); + } + + jvmtiError GetSourceFileName(jclass klass, + char** source_name_ptr) { + return functions->GetSourceFileName(this, klass, source_name_ptr); + } + + jvmtiError GetClassModifiers(jclass klass, + jint* modifiers_ptr) { + return functions->GetClassModifiers(this, klass, modifiers_ptr); + } + + jvmtiError GetClassMethods(jclass klass, + jint* method_count_ptr, + jmethodID** methods_ptr) { + return functions->GetClassMethods(this, klass, method_count_ptr, methods_ptr); + } + + jvmtiError GetClassFields(jclass klass, + jint* field_count_ptr, + jfieldID** fields_ptr) { + return functions->GetClassFields(this, klass, field_count_ptr, fields_ptr); + } + + jvmtiError GetImplementedInterfaces(jclass klass, + jint* interface_count_ptr, + jclass** interfaces_ptr) { + return functions->GetImplementedInterfaces(this, klass, interface_count_ptr, interfaces_ptr); + } + + jvmtiError GetClassVersionNumbers(jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr) { + return functions->GetClassVersionNumbers(this, klass, minor_version_ptr, major_version_ptr); + } + + jvmtiError GetConstantPool(jclass klass, + jint* constant_pool_count_ptr, + jint* constant_pool_byte_count_ptr, + unsigned char** constant_pool_bytes_ptr) { + return functions->GetConstantPool(this, klass, constant_pool_count_ptr, constant_pool_byte_count_ptr, constant_pool_bytes_ptr); + } + + jvmtiError IsInterface(jclass klass, + jboolean* is_interface_ptr) { + return functions->IsInterface(this, klass, is_interface_ptr); + } + + jvmtiError IsArrayClass(jclass klass, + jboolean* is_array_class_ptr) { + return functions->IsArrayClass(this, klass, is_array_class_ptr); + } + + jvmtiError IsModifiableClass(jclass klass, + jboolean* is_modifiable_class_ptr) { + return functions->IsModifiableClass(this, klass, is_modifiable_class_ptr); + } + + jvmtiError GetClassLoader(jclass klass, + jobject* classloader_ptr) { + return functions->GetClassLoader(this, klass, classloader_ptr); + } + + jvmtiError GetSourceDebugExtension(jclass klass, + char** source_debug_extension_ptr) { + return functions->GetSourceDebugExtension(this, klass, source_debug_extension_ptr); + } + + jvmtiError RetransformClasses(jint class_count, + const jclass* classes) { + return functions->RetransformClasses(this, class_count, classes); + } + + jvmtiError RedefineClasses(jint class_count, + const jvmtiClassDefinition* class_definitions) { + return functions->RedefineClasses(this, class_count, class_definitions); + } + + jvmtiError GetObjectSize(jobject object, + jlong* size_ptr) { + return functions->GetObjectSize(this, object, size_ptr); + } + + jvmtiError GetObjectHashCode(jobject object, + jint* hash_code_ptr) { + return functions->GetObjectHashCode(this, object, hash_code_ptr); + } + + jvmtiError GetObjectMonitorUsage(jobject object, + jvmtiMonitorUsage* info_ptr) { + return functions->GetObjectMonitorUsage(this, object, info_ptr); + } + + jvmtiError GetFieldName(jclass klass, + jfieldID field, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return functions->GetFieldName(this, klass, field, name_ptr, signature_ptr, generic_ptr); + } + + jvmtiError GetFieldDeclaringClass(jclass klass, + jfieldID field, + jclass* declaring_class_ptr) { + return functions->GetFieldDeclaringClass(this, klass, field, declaring_class_ptr); + } + + jvmtiError GetFieldModifiers(jclass klass, + jfieldID field, + jint* modifiers_ptr) { + return functions->GetFieldModifiers(this, klass, field, modifiers_ptr); + } + + jvmtiError IsFieldSynthetic(jclass klass, + jfieldID field, + jboolean* is_synthetic_ptr) { + return functions->IsFieldSynthetic(this, klass, field, is_synthetic_ptr); + } + + jvmtiError GetMethodName(jmethodID method, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return functions->GetMethodName(this, method, name_ptr, signature_ptr, generic_ptr); + } + + jvmtiError GetMethodDeclaringClass(jmethodID method, + jclass* declaring_class_ptr) { + return functions->GetMethodDeclaringClass(this, method, declaring_class_ptr); + } + + jvmtiError GetMethodModifiers(jmethodID method, + jint* modifiers_ptr) { + return functions->GetMethodModifiers(this, method, modifiers_ptr); + } + + jvmtiError GetMaxLocals(jmethodID method, + jint* max_ptr) { + return functions->GetMaxLocals(this, method, max_ptr); + } + + jvmtiError GetArgumentsSize(jmethodID method, + jint* size_ptr) { + return functions->GetArgumentsSize(this, method, size_ptr); + } + + jvmtiError GetLineNumberTable(jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr) { + return functions->GetLineNumberTable(this, method, entry_count_ptr, table_ptr); + } + + jvmtiError GetMethodLocation(jmethodID method, + jlocation* start_location_ptr, + jlocation* end_location_ptr) { + return functions->GetMethodLocation(this, method, start_location_ptr, end_location_ptr); + } + + jvmtiError GetLocalVariableTable(jmethodID method, + jint* entry_count_ptr, + jvmtiLocalVariableEntry** table_ptr) { + return functions->GetLocalVariableTable(this, method, entry_count_ptr, table_ptr); + } + + jvmtiError GetBytecodes(jmethodID method, + jint* bytecode_count_ptr, + unsigned char** bytecodes_ptr) { + return functions->GetBytecodes(this, method, bytecode_count_ptr, bytecodes_ptr); + } + + jvmtiError IsMethodNative(jmethodID method, + jboolean* is_native_ptr) { + return functions->IsMethodNative(this, method, is_native_ptr); + } + + jvmtiError IsMethodSynthetic(jmethodID method, + jboolean* is_synthetic_ptr) { + return functions->IsMethodSynthetic(this, method, is_synthetic_ptr); + } + + jvmtiError IsMethodObsolete(jmethodID method, + jboolean* is_obsolete_ptr) { + return functions->IsMethodObsolete(this, method, is_obsolete_ptr); + } + + jvmtiError SetNativeMethodPrefix(const char* prefix) { + return functions->SetNativeMethodPrefix(this, prefix); + } + + jvmtiError SetNativeMethodPrefixes(jint prefix_count, + char** prefixes) { + return functions->SetNativeMethodPrefixes(this, prefix_count, prefixes); + } + + jvmtiError CreateRawMonitor(const char* name, + jrawMonitorID* monitor_ptr) { + return functions->CreateRawMonitor(this, name, monitor_ptr); + } + + jvmtiError DestroyRawMonitor(jrawMonitorID monitor) { + return functions->DestroyRawMonitor(this, monitor); + } + + jvmtiError RawMonitorEnter(jrawMonitorID monitor) { + return functions->RawMonitorEnter(this, monitor); + } + + jvmtiError RawMonitorExit(jrawMonitorID monitor) { + return functions->RawMonitorExit(this, monitor); + } + + jvmtiError RawMonitorWait(jrawMonitorID monitor, + jlong millis) { + return functions->RawMonitorWait(this, monitor, millis); + } + + jvmtiError RawMonitorNotify(jrawMonitorID monitor) { + return functions->RawMonitorNotify(this, monitor); + } + + jvmtiError RawMonitorNotifyAll(jrawMonitorID monitor) { + return functions->RawMonitorNotifyAll(this, monitor); + } + + jvmtiError SetJNIFunctionTable(const jniNativeInterface* function_table) { + return functions->SetJNIFunctionTable(this, function_table); + } + + jvmtiError GetJNIFunctionTable(jniNativeInterface** function_table) { + return functions->GetJNIFunctionTable(this, function_table); + } + + jvmtiError SetEventCallbacks(const jvmtiEventCallbacks* callbacks, + jint size_of_callbacks) { + return functions->SetEventCallbacks(this, callbacks, size_of_callbacks); + } + + jvmtiError SetEventNotificationMode(jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread, + ...) { + return functions->SetEventNotificationMode(this, mode, event_type, event_thread); + } + + jvmtiError GenerateEvents(jvmtiEvent event_type) { + return functions->GenerateEvents(this, event_type); + } + + jvmtiError GetExtensionFunctions(jint* extension_count_ptr, + jvmtiExtensionFunctionInfo** extensions) { + return functions->GetExtensionFunctions(this, extension_count_ptr, extensions); + } + + jvmtiError GetExtensionEvents(jint* extension_count_ptr, + jvmtiExtensionEventInfo** extensions) { + return functions->GetExtensionEvents(this, extension_count_ptr, extensions); + } + + jvmtiError SetExtensionEventCallback(jint extension_event_index, + jvmtiExtensionEvent callback) { + return functions->SetExtensionEventCallback(this, extension_event_index, callback); + } + + jvmtiError GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) { + return functions->GetPotentialCapabilities(this, capabilities_ptr); + } + + jvmtiError AddCapabilities(const jvmtiCapabilities* capabilities_ptr) { + return functions->AddCapabilities(this, capabilities_ptr); + } + + jvmtiError RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) { + return functions->RelinquishCapabilities(this, capabilities_ptr); + } + + jvmtiError GetCapabilities(jvmtiCapabilities* capabilities_ptr) { + return functions->GetCapabilities(this, capabilities_ptr); + } + + jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetCurrentThreadCpuTimerInfo(this, info_ptr); + } + + jvmtiError GetCurrentThreadCpuTime(jlong* nanos_ptr) { + return functions->GetCurrentThreadCpuTime(this, nanos_ptr); + } + + jvmtiError GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetThreadCpuTimerInfo(this, info_ptr); + } + + jvmtiError GetThreadCpuTime(jthread thread, + jlong* nanos_ptr) { + return functions->GetThreadCpuTime(this, thread, nanos_ptr); + } + + jvmtiError GetTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetTimerInfo(this, info_ptr); + } + + jvmtiError GetTime(jlong* nanos_ptr) { + return functions->GetTime(this, nanos_ptr); + } + + jvmtiError GetAvailableProcessors(jint* processor_count_ptr) { + return functions->GetAvailableProcessors(this, processor_count_ptr); + } + + jvmtiError AddToBootstrapClassLoaderSearch(const char* segment) { + return functions->AddToBootstrapClassLoaderSearch(this, segment); + } + + jvmtiError AddToSystemClassLoaderSearch(const char* segment) { + return functions->AddToSystemClassLoaderSearch(this, segment); + } + + jvmtiError GetSystemProperties(jint* count_ptr, + char*** property_ptr) { + return functions->GetSystemProperties(this, count_ptr, property_ptr); + } + + jvmtiError GetSystemProperty(const char* property, + char** value_ptr) { + return functions->GetSystemProperty(this, property, value_ptr); + } + + jvmtiError SetSystemProperty(const char* property, + const char* value) { + return functions->SetSystemProperty(this, property, value); + } + + jvmtiError GetPhase(jvmtiPhase* phase_ptr) { + return functions->GetPhase(this, phase_ptr); + } + + jvmtiError DisposeEnvironment() { + return functions->DisposeEnvironment(this); + } + + jvmtiError SetEnvironmentLocalStorage(const void* data) { + return functions->SetEnvironmentLocalStorage(this, data); + } + + jvmtiError GetEnvironmentLocalStorage(void** data_ptr) { + return functions->GetEnvironmentLocalStorage(this, data_ptr); + } + + jvmtiError GetVersionNumber(jint* version_ptr) { + return functions->GetVersionNumber(this, version_ptr); + } + + jvmtiError GetErrorName(jvmtiError error, + char** name_ptr) { + return functions->GetErrorName(this, error, name_ptr); + } + + jvmtiError SetVerboseFlag(jvmtiVerboseFlag flag, + jboolean value) { + return functions->SetVerboseFlag(this, flag, value); + } + + jvmtiError GetJLocationFormat(jvmtiJlocationFormat* format_ptr) { + return functions->GetJLocationFormat(this, format_ptr); + } + +#endif /* __cplusplus */ +}; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVA_JVMTI_H_ */ \ No newline at end of file diff --git a/demos/java/jni/gs_jni/include/jvmticmlr.h b/demos/java/jni/gs_jni/include/jvmticmlr.h new file mode 100644 index 00000000..a9c88f36 --- /dev/null +++ b/demos/java/jni/gs_jni/include/jvmticmlr.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * This header file defines the data structures sent by the VM + * through the JVMTI CompiledMethodLoad callback function via the + * "void * compile_info" parameter. The memory pointed to by the + * compile_info parameter may not be referenced after returning from + * the CompiledMethodLoad callback. These are VM implementation + * specific data structures that may evolve in future releases. A + * JVMTI agent should interpret a non-NULL compile_info as a pointer + * to a region of memory containing a list of records. In a typical + * usage scenario, a JVMTI agent would cast each record to a + * jvmtiCompiledMethodLoadRecordHeader, a struct that represents + * arbitrary information. This struct contains a kind field to indicate + * the kind of information being passed, and a pointer to the next + * record. If the kind field indicates inlining information, then the + * agent would cast the record to a jvmtiCompiledMethodLoadInlineRecord. + * This record contains an array of PCStackInfo structs, which indicate + * for every pc address what are the methods on the invocation stack. + * The "methods" and "bcis" fields in each PCStackInfo struct specify a + * 1-1 mapping between these inlined methods and their bytecode indices. + * This can be used to derive the proper source lines of the inlined + * methods. + */ + +#ifndef _JVMTI_CMLR_H_ +#define _JVMTI_CMLR_H_ + +enum { + JVMTI_CMLR_MAJOR_VERSION_1 = 0x00000001, + JVMTI_CMLR_MINOR_VERSION_0 = 0x00000000, + + JVMTI_CMLR_MAJOR_VERSION = 0x00000001, + JVMTI_CMLR_MINOR_VERSION = 0x00000000 + + /* + * This comment is for the "JDK import from HotSpot" sanity check: + * version: 1.0.0 + */ +}; + +typedef enum { + JVMTI_CMLR_DUMMY = 1, + JVMTI_CMLR_INLINE_INFO = 2 +} jvmtiCMLRKind; + +/* + * Record that represents arbitrary information passed through JVMTI + * CompiledMethodLoadEvent void pointer. + */ +typedef struct _jvmtiCompiledMethodLoadRecordHeader { + jvmtiCMLRKind kind; /* id for the kind of info passed in the record */ + jint majorinfoversion; /* major and minor info version values. Init'ed */ + jint minorinfoversion; /* to current version value in jvmtiExport.cpp. */ + + struct _jvmtiCompiledMethodLoadRecordHeader* next; +} jvmtiCompiledMethodLoadRecordHeader; + +/* + * Record that gives information about the methods on the compile-time + * stack at a specific pc address of a compiled method. Each element in + * the methods array maps to same element in the bcis array. + */ +typedef struct _PCStackInfo { + void* pc; /* the pc address for this compiled method */ + jint numstackframes; /* number of methods on the stack */ + jmethodID* methods; /* array of numstackframes method ids */ + jint* bcis; /* array of numstackframes bytecode indices */ +} PCStackInfo; + +/* + * Record that contains inlining information for each pc address of + * an nmethod. + */ +typedef struct _jvmtiCompiledMethodLoadInlineRecord { + jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */ + jint numpcs; /* number of pc descriptors in this nmethod */ + PCStackInfo* pcinfo; /* array of numpcs pc descriptors */ +} jvmtiCompiledMethodLoadInlineRecord; + +/* + * Dummy record used to test that we can pass records with different + * information through the void pointer provided that they can be cast + * to a jvmtiCompiledMethodLoadRecordHeader. + */ + +typedef struct _jvmtiCompiledMethodLoadDummyRecord { + jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */ + char message[50]; +} jvmtiCompiledMethodLoadDummyRecord; + +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCallbacks.h b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCallbacks.h new file mode 100644 index 00000000..df5035b8 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCallbacks.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * AccessBridgeCallbacks.h 1.17 05/03/21 + */ + +/* + * Header file defining callback typedefs for Windows routines + * which are called from Java (responding to events, etc.). + */ + +#ifndef __AccessBridgeCallbacks_H__ +#define __AccessBridgeCallbacks_H__ + +#include +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*AccessBridge_PropertyChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldValue, wchar_t *newValue); + +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); + +typedef void (*AccessBridge_FocusGainedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_FocusLostFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_CaretUpdateFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MouseClickedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseEnteredFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseExitedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MousePressedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseReleasedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuDeselectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuSelectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeInvisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeVisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_PropertyNameChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldName, wchar_t *newName); +typedef void (*AccessBridge_PropertyDescriptionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldDescription, wchar_t *newDescription); +typedef void (*AccessBridge_PropertyStateChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldState, wchar_t *newState); +typedef void (*AccessBridge_PropertyValueChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); +typedef void (*AccessBridge_PropertySelectionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyTextChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyCaretChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + int oldPosition, int newPosition); +typedef void (*AccessBridge_PropertyVisibleDataChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyChildChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldChild, JOBJECT64 newChild); +typedef void (*AccessBridge_PropertyActiveDescendentChangeFP) (long vmID, JOBJECT64 event, + JOBJECT64 source, + JOBJECT64 oldActiveDescendent, + JOBJECT64 newActiveDescendent); + +typedef void (*AccessBridge_PropertyTableModelChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 src, + wchar_t *oldValue, wchar_t *newValue); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.c b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.c new file mode 100644 index 00000000..36866481 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.c @@ -0,0 +1,1131 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * @(#)AccessBridgeCalls.c 1.25 05/08/22 + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + + +#include +#include + + +//#define ACCESSBRIDGE_32 +//#define ACCESSBRIDGE_64 + +#include "AccessBridgeCalls.h" +#include "AccessBridgeDebug.h" + +#ifdef __cplusplus +extern "C" { +#endif + + HINSTANCE theAccessBridgeInstance; + AccessBridgeFPs theAccessBridge; + + BOOL theAccessBridgeInitializedFlag = FALSE; + +#define LOAD_FP(result, type, name) \ + PrintDebugString("LOAD_FP loading: %s ...", name); \ + if ((theAccessBridge.result = \ + (type) GetProcAddress(theAccessBridgeInstance, name)) == (type) 0) { \ + PrintDebugString("LOAD_FP failed: %s", name); \ + return FALSE; \ + } + + BOOL initializeAccessBridge() { + +#ifdef ACCESSBRIDGE_ARCH_32 // For 32bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-32"); +#else +#ifdef ACCESSBRIDGE_ARCH_64 // For 64bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-64"); +#else // legacy + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE"); +#endif +#endif + if (theAccessBridgeInstance != 0) { + LOAD_FP(Windows_run, Windows_runFP, "Windows_run"); + + LOAD_FP(SetJavaShutdown, SetJavaShutdownFP, "setJavaShutdownFP"); + LOAD_FP(SetFocusGained, SetFocusGainedFP, "setFocusGainedFP"); + LOAD_FP(SetFocusLost, SetFocusLostFP, "setFocusLostFP"); + + LOAD_FP(SetCaretUpdate, SetCaretUpdateFP, "setCaretUpdateFP"); + + LOAD_FP(SetMouseClicked, SetMouseClickedFP, "setMouseClickedFP"); + LOAD_FP(SetMouseEntered, SetMouseEnteredFP, "setMouseEnteredFP"); + LOAD_FP(SetMouseExited, SetMouseExitedFP, "setMouseExitedFP"); + LOAD_FP(SetMousePressed, SetMousePressedFP, "setMousePressedFP"); + LOAD_FP(SetMouseReleased, SetMouseReleasedFP, "setMouseReleasedFP"); + + LOAD_FP(SetMenuCanceled, SetMenuCanceledFP, "setMenuCanceledFP"); + LOAD_FP(SetMenuDeselected, SetMenuDeselectedFP, "setMenuDeselectedFP"); + LOAD_FP(SetMenuSelected, SetMenuSelectedFP, "setMenuSelectedFP"); + LOAD_FP(SetPopupMenuCanceled, SetPopupMenuCanceledFP, "setPopupMenuCanceledFP"); + LOAD_FP(SetPopupMenuWillBecomeInvisible, SetPopupMenuWillBecomeInvisibleFP, "setPopupMenuWillBecomeInvisibleFP"); + LOAD_FP(SetPopupMenuWillBecomeVisible, SetPopupMenuWillBecomeVisibleFP, "setPopupMenuWillBecomeVisibleFP"); + + LOAD_FP(SetPropertyNameChange, SetPropertyNameChangeFP, "setPropertyNameChangeFP"); + LOAD_FP(SetPropertyDescriptionChange, SetPropertyDescriptionChangeFP, "setPropertyDescriptionChangeFP"); + LOAD_FP(SetPropertyStateChange, SetPropertyStateChangeFP, "setPropertyStateChangeFP"); + LOAD_FP(SetPropertyValueChange, SetPropertyValueChangeFP, "setPropertyValueChangeFP"); + LOAD_FP(SetPropertySelectionChange, SetPropertySelectionChangeFP, "setPropertySelectionChangeFP"); + LOAD_FP(SetPropertyTextChange, SetPropertyTextChangeFP, "setPropertyTextChangeFP"); + LOAD_FP(SetPropertyCaretChange, SetPropertyCaretChangeFP, "setPropertyCaretChangeFP"); + LOAD_FP(SetPropertyVisibleDataChange, SetPropertyVisibleDataChangeFP, "setPropertyVisibleDataChangeFP"); + LOAD_FP(SetPropertyChildChange, SetPropertyChildChangeFP, "setPropertyChildChangeFP"); + LOAD_FP(SetPropertyActiveDescendentChange, SetPropertyActiveDescendentChangeFP, "setPropertyActiveDescendentChangeFP"); + + LOAD_FP(SetPropertyTableModelChange, SetPropertyTableModelChangeFP, "setPropertyTableModelChangeFP"); + + LOAD_FP(ReleaseJavaObject, ReleaseJavaObjectFP, "releaseJavaObject"); + LOAD_FP(GetVersionInfo, GetVersionInfoFP, "getVersionInfo"); + + LOAD_FP(IsJavaWindow, IsJavaWindowFP, "isJavaWindow"); + LOAD_FP(IsSameObject, IsSameObjectFP, "isSameObject"); + LOAD_FP(GetAccessibleContextFromHWND, GetAccessibleContextFromHWNDFP, "getAccessibleContextFromHWND"); + LOAD_FP(getHWNDFromAccessibleContext, getHWNDFromAccessibleContextFP, "getHWNDFromAccessibleContext"); + + LOAD_FP(GetAccessibleContextAt, GetAccessibleContextAtFP, "getAccessibleContextAt"); + LOAD_FP(GetAccessibleContextWithFocus, GetAccessibleContextWithFocusFP, "getAccessibleContextWithFocus"); + LOAD_FP(GetAccessibleContextInfo, GetAccessibleContextInfoFP, "getAccessibleContextInfo"); + LOAD_FP(GetAccessibleChildFromContext, GetAccessibleChildFromContextFP, "getAccessibleChildFromContext"); + LOAD_FP(GetAccessibleParentFromContext, GetAccessibleParentFromContextFP, "getAccessibleParentFromContext"); + + /* begin AccessibleTable */ + LOAD_FP(getAccessibleTableInfo, getAccessibleTableInfoFP, "getAccessibleTableInfo"); + LOAD_FP(getAccessibleTableCellInfo, getAccessibleTableCellInfoFP, "getAccessibleTableCellInfo"); + + LOAD_FP(getAccessibleTableRowHeader, getAccessibleTableRowHeaderFP, "getAccessibleTableRowHeader"); + LOAD_FP(getAccessibleTableColumnHeader, getAccessibleTableColumnHeaderFP, "getAccessibleTableColumnHeader"); + + LOAD_FP(getAccessibleTableRowDescription, getAccessibleTableRowDescriptionFP, "getAccessibleTableRowDescription"); + LOAD_FP(getAccessibleTableColumnDescription, getAccessibleTableColumnDescriptionFP, "getAccessibleTableColumnDescription"); + + LOAD_FP(getAccessibleTableRowSelectionCount, getAccessibleTableRowSelectionCountFP, + "getAccessibleTableRowSelectionCount"); + LOAD_FP(isAccessibleTableRowSelected, isAccessibleTableRowSelectedFP, + "isAccessibleTableRowSelected"); + LOAD_FP(getAccessibleTableRowSelections, getAccessibleTableRowSelectionsFP, + "getAccessibleTableRowSelections"); + + LOAD_FP(getAccessibleTableColumnSelectionCount, getAccessibleTableColumnSelectionCountFP, + "getAccessibleTableColumnSelectionCount"); + LOAD_FP(isAccessibleTableColumnSelected, isAccessibleTableColumnSelectedFP, + "isAccessibleTableColumnSelected"); + LOAD_FP(getAccessibleTableColumnSelections, getAccessibleTableColumnSelectionsFP, + "getAccessibleTableColumnSelections"); + + LOAD_FP(getAccessibleTableRow, getAccessibleTableRowFP, + "getAccessibleTableRow"); + LOAD_FP(getAccessibleTableColumn, getAccessibleTableColumnFP, + "getAccessibleTableColumn"); + LOAD_FP(getAccessibleTableIndex, getAccessibleTableIndexFP, + "getAccessibleTableIndex"); + + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + LOAD_FP(getAccessibleRelationSet, getAccessibleRelationSetFP, "getAccessibleRelationSet"); + + /* AccessibleHypertext */ + LOAD_FP(getAccessibleHypertext, getAccessibleHypertextFP, "getAccessibleHypertext"); + LOAD_FP(activateAccessibleHyperlink, activateAccessibleHyperlinkFP, "activateAccessibleHyperlink"); + LOAD_FP(getAccessibleHyperlinkCount, getAccessibleHyperlinkCountFP, "getAccessibleHyperlinkCount"); + LOAD_FP(getAccessibleHypertextExt, getAccessibleHypertextExtFP, "getAccessibleHypertextExt"); + LOAD_FP(getAccessibleHypertextLinkIndex, getAccessibleHypertextLinkIndexFP, "getAccessibleHypertextLinkIndex"); + LOAD_FP(getAccessibleHyperlink, getAccessibleHyperlinkFP, "getAccessibleHyperlink"); + + /* Accessible KeyBinding, Icon and Action */ + LOAD_FP(getAccessibleKeyBindings, getAccessibleKeyBindingsFP, "getAccessibleKeyBindings"); + LOAD_FP(getAccessibleIcons, getAccessibleIconsFP, "getAccessibleIcons"); + LOAD_FP(getAccessibleActions, getAccessibleActionsFP, "getAccessibleActions"); + LOAD_FP(doAccessibleActions, doAccessibleActionsFP, "doAccessibleActions"); + + /* AccessibleText */ + LOAD_FP(GetAccessibleTextInfo, GetAccessibleTextInfoFP, "getAccessibleTextInfo"); + LOAD_FP(GetAccessibleTextItems, GetAccessibleTextItemsFP, "getAccessibleTextItems"); + LOAD_FP(GetAccessibleTextSelectionInfo, GetAccessibleTextSelectionInfoFP, "getAccessibleTextSelectionInfo"); + LOAD_FP(GetAccessibleTextAttributes, GetAccessibleTextAttributesFP, "getAccessibleTextAttributes"); + LOAD_FP(GetAccessibleTextRect, GetAccessibleTextRectFP, "getAccessibleTextRect"); + LOAD_FP(GetAccessibleTextLineBounds, GetAccessibleTextLineBoundsFP, "getAccessibleTextLineBounds"); + LOAD_FP(GetAccessibleTextRange, GetAccessibleTextRangeFP, "getAccessibleTextRange"); + + LOAD_FP(GetCurrentAccessibleValueFromContext, GetCurrentAccessibleValueFromContextFP, "getCurrentAccessibleValueFromContext"); + LOAD_FP(GetMaximumAccessibleValueFromContext, GetMaximumAccessibleValueFromContextFP, "getMaximumAccessibleValueFromContext"); + LOAD_FP(GetMinimumAccessibleValueFromContext, GetMinimumAccessibleValueFromContextFP, "getMinimumAccessibleValueFromContext"); + + LOAD_FP(AddAccessibleSelectionFromContext, AddAccessibleSelectionFromContextFP, "addAccessibleSelectionFromContext"); + LOAD_FP(ClearAccessibleSelectionFromContext, ClearAccessibleSelectionFromContextFP, "clearAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionFromContext, GetAccessibleSelectionFromContextFP, "getAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionCountFromContext, GetAccessibleSelectionCountFromContextFP, "getAccessibleSelectionCountFromContext"); + LOAD_FP(IsAccessibleChildSelectedFromContext, IsAccessibleChildSelectedFromContextFP, "isAccessibleChildSelectedFromContext"); + LOAD_FP(RemoveAccessibleSelectionFromContext, RemoveAccessibleSelectionFromContextFP, "removeAccessibleSelectionFromContext"); + LOAD_FP(SelectAllAccessibleSelectionFromContext, SelectAllAccessibleSelectionFromContextFP, "selectAllAccessibleSelectionFromContext"); + + LOAD_FP(setTextContents, setTextContentsFP, "setTextContents"); + LOAD_FP(getParentWithRole, getParentWithRoleFP, "getParentWithRole"); + LOAD_FP(getTopLevelObject, getTopLevelObjectFP, "getTopLevelObject"); + LOAD_FP(getParentWithRoleElseRoot, getParentWithRoleElseRootFP, "getParentWithRoleElseRoot"); + LOAD_FP(getObjectDepth, getObjectDepthFP, "getObjectDepth"); + LOAD_FP(getActiveDescendent, getActiveDescendentFP, "getActiveDescendent"); + + // additional methods for Teton + LOAD_FP(getVirtualAccessibleName, getVirtualAccessibleNameFP, "getVirtualAccessibleName"); + LOAD_FP(requestFocus, requestFocusFP, "requestFocus"); + LOAD_FP(selectTextRange, selectTextRangeFP, "selectTextRange"); + LOAD_FP(getTextAttributesInRange, getTextAttributesInRangeFP, "getTextAttributesInRange"); + LOAD_FP(getVisibleChildrenCount, getVisibleChildrenCountFP, "getVisibleChildrenCount"); + LOAD_FP(getVisibleChildren, getVisibleChildrenFP, "getVisibleChildren"); + LOAD_FP(setCaretPosition, setCaretPositionFP, "setCaretPosition"); + LOAD_FP(getCaretLocation, getCaretLocationFP, "getCaretLocation"); + + LOAD_FP(getEventsWaiting, getEventsWaitingFP, "getEventsWaiting"); + + theAccessBridge.Windows_run(); + + theAccessBridgeInitializedFlag = TRUE; + PrintDebugString("theAccessBridgeInitializedFlag = TRUE"); + return TRUE; + } else { + return FALSE; + } + } + + + BOOL shutdownAccessBridge() { + BOOL result; + DWORD error; + theAccessBridgeInitializedFlag = FALSE; + if (theAccessBridgeInstance != (HANDLE) 0) { + result = FreeLibrary(theAccessBridgeInstance); + if (result != TRUE) { + error = GetLastError(); + } + return TRUE; + } + return FALSE; + } + + + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetJavaShutdown(fp); + } + } + + void SetFocusGained(AccessBridge_FocusGainedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusGained(fp); + } + } + + void SetFocusLost(AccessBridge_FocusLostFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusLost(fp); + } + } + + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetCaretUpdate(fp); + } + } + + + void SetMouseClicked(AccessBridge_MouseClickedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseClicked(fp); + } + } + + void SetMouseEntered(AccessBridge_MouseEnteredFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseEntered(fp); + } + } + + void SetMouseExited(AccessBridge_MouseExitedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseExited(fp); + } + } + + void SetMousePressed(AccessBridge_MousePressedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMousePressed(fp); + } + } + + void SetMouseReleased(AccessBridge_MouseReleasedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseReleased(fp); + } + } + + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuCanceled(fp); + } + } + + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuDeselected(fp); + } + } + + void SetMenuSelected(AccessBridge_MenuSelectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuSelected(fp); + } + } + + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuCanceled(fp); + } + } + + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeInvisible(fp); + } + } + + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeVisible(fp); + } + } + + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyNameChange(fp); + } + } + + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyDescriptionChange(fp); + } + } + + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyStateChange(fp); + } + } + + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyValueChange(fp); + } + } + + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertySelectionChange(fp); + } + } + + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTextChange(fp); + } + } + + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyCaretChange(fp); + } + } + + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyVisibleDataChange(fp); + } + } + + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyChildChange(fp); + } + } + + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyActiveDescendentChange(fp); + } + } + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTableModelChange(fp); + } + } + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ReleaseJavaObject(vmID, object); + } + } + + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetVersionInfo(vmID, info); + } + return FALSE; + } + + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window) { + if (theAccessBridgeInitializedFlag == TRUE) { + BOOL ret ; + ret = theAccessBridge.IsJavaWindow(window); + return ret ; + + } + return FALSE; + } + + + /** + * Returns the virtual machine ID and AccessibleContext for a top-level window + */ + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextFromHWND(target, vmID, ac); + } + return FALSE; + } + + /** + * Returns the HWND from the AccessibleContext of a top-level window. Returns 0 + * on error or if the AccessibleContext does not refer to a top-level window. + */ + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getHWNDFromAccessibleContext(vmID, accesibleContext); + } + return (HWND)0; + } + + /** + * returns whether two objects are the same + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsSameObject(vmID, obj1, obj2); + } + return FALSE; + } + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setTextContents(vmID, accessibleContext, text); + } + return FALSE; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRole(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRoleElseRoot(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTopLevelObject(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getObjectDepth(vmID, accessibleContext); + } + return -1; + } + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getActiveDescendent(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextAt(vmID, acParent, x, y, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextWithFocus(window, vmID, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextInfo(vmID, ac, info); + } + return FALSE; + } + + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleChildFromContext(vmID, ac, index); + } + return (AccessibleContext) 0; + } + + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleParentFromContext(vmID, ac); + } + return (AccessibleContext) 0; + } + + /* begin AccessibleTable routines */ + + /* + * get information about an AccessibleTable + */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableInfo(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable cell + */ + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableCellInfo(vmID, accessibleTable, row, column, tableCellInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable row header + */ + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable column header + */ + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * return a description of an AccessibleTable row header + */ + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowDescription(vmID, acParent, row); + } + return (AccessibleContext)0; + } + + /* + * return a description of an AccessibleTable column header + */ + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnDescription(vmID, acParent, column); + } + return (AccessibleContext)0; + } + + /* + * return the number of rows selected in an AccessibleTable + */ + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a row is selected in an AccessibleTable + */ + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableRowSelected(vmID, table, row); + } + return FALSE; + } + + /* + * get an array of selected rows in an AccessibleTable + */ + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the number of columns selected in an AccessibleTable + */ + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a column is selected in an AccessibleTable + */ + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableColumnSelected(vmID, table, column); + } + return FALSE; + } + + /* + * get an array of columns selected in an AccessibleTable + */ + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the row number for a cell at a given index + */ + jint + getAccessibleTableRow(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRow(vmID, table, index); + } + return -1; + } + + /* + * return the column number for a cell at a given index + */ + jint + getAccessibleTableColumn(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumn(vmID, table, index); + } + return -1; + } + + /* + * return the index of a cell at a given row and column + */ + jint + getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableIndex(vmID, table, row, column); + } + return -1; + } + + /* end AccessibleTable routines */ + + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextInfo(vmID, at, textInfo, x, y); + } + return FALSE; + } + + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextItems(vmID, at, textItems, index); + } + return FALSE; + } + + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextSelectionInfo(vmID, at, textSelection); + } + return FALSE; + } + + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextAttributes(vmID, at, index, attributes); + } + return FALSE; + } + + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRect(vmID, at, rectInfo, index); + } + return FALSE; + } + + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextLineBounds(vmID, at, index, startIndex, endIndex); + } + return FALSE; + } + + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRange(vmID, at, start, end, text, len); + } + return FALSE; + } + + /** + * AccessibleRelationSet routines + */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleRelationSet(vmID, accessibleContext, relationSetInfo); + } + return FALSE; + } + + /** + * AccessibleHypertext routines + */ + + // Gets AccessibleHypertext for an AccessibleContext + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertext(vmID, accessibleContext, hypertextInfo); + } + return FALSE; + } + + // Activates an AccessibleHyperlink for an AccessibleContext + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.activateAccessibleHyperlink(vmID, accessibleContext, accessibleHyperlink); + } + return FALSE; + } + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlinkCount(vmID, accessibleContext); + } + return -1; + } + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextExt(vmID, + accessibleContext, + nStartIndex, + hypertextInfo); + } + return FALSE; + } + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; + * Maps to AccessibleHypertext.getLinkIndex. + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextLinkIndex(vmID, + hypertext, + nIndex); + } + return -1; + } + + /* + * Returns the nth hyperlink in a document. + * Maps to AccessibleHypertext.getLink. + * Returns -1 on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlink(vmID, + hypertext, + nIndex, + hyperlinkInfo); + } + return FALSE; + } + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleKeyBindings(vmID, accessibleContext, keyBindings); + } + return FALSE; + } + + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleIcons(vmID, accessibleContext, icons); + } + return FALSE; + } + + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleActions(vmID, accessibleContext, actions); + } + return FALSE; + } + + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.doAccessibleActions(vmID, accessibleContext, actionsToDo, failure); + } + return FALSE; + } + + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetCurrentAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMaximumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMinimumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + + /** + * Accessible Selection routines + */ + void addAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.AddAccessibleSelectionFromContext(vmID, as, i); + } + } + + void clearAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ClearAccessibleSelectionFromContext(vmID, as); + } + } + + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionFromContext(vmID, as, i); + } + return (JOBJECT64) 0; + } + + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionCountFromContext(vmID, as); + } + return -1; + } + + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsAccessibleChildSelectedFromContext(vmID, as, i); + } + return FALSE; + } + + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.RemoveAccessibleSelectionFromContext(vmID, as, i); + } + } + + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SelectAllAccessibleSelectionFromContext(vmID, as); + } + } + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVirtualAccessibleName(vmID, accessibleContext, name, len); + } + return FALSE; + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.requestFocus(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.selectTextRange(vmID, accessibleContext, startIndex, endIndex); + } + return FALSE; + } + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTextAttributesInRange(vmID, accessibleContext, startIndex, + endIndex, attributes, len); + } + return FALSE; + } + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildrenCount(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *visibleChildrenInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildren(vmID, accessibleContext, startIndex, + visibleChildrenInfo); + } + return FALSE; + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setCaretPosition(vmID, accessibleContext, position); + } + return FALSE; + } + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getCaretLocation(vmID, ac, rectInfo, index); + } + return FALSE; + } + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting() { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getEventsWaiting(); + } + return FALSE; + } + +#ifdef __cplusplus +} +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.h b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.h new file mode 100644 index 00000000..ad007400 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgeCalls.h @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + +#include +#include +#include "AccessBridgeCallbacks.h" +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define null NULL + + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + + typedef void (*Windows_runFP) (); + + typedef void (*SetPropertyChangeFP) (AccessBridge_PropertyChangeFP fp); + + typedef void (*SetJavaShutdownFP) (AccessBridge_JavaShutdownFP fp); + typedef void (*SetFocusGainedFP) (AccessBridge_FocusGainedFP fp); + typedef void (*SetFocusLostFP) (AccessBridge_FocusLostFP fp); + + typedef void (*SetCaretUpdateFP) (AccessBridge_CaretUpdateFP fp); + + typedef void (*SetMouseClickedFP) (AccessBridge_MouseClickedFP fp); + typedef void (*SetMouseEnteredFP) (AccessBridge_MouseEnteredFP fp); + typedef void (*SetMouseExitedFP) (AccessBridge_MouseExitedFP fp); + typedef void (*SetMousePressedFP) (AccessBridge_MousePressedFP fp); + typedef void (*SetMouseReleasedFP) (AccessBridge_MouseReleasedFP fp); + + typedef void (*SetMenuCanceledFP) (AccessBridge_MenuCanceledFP fp); + typedef void (*SetMenuDeselectedFP) (AccessBridge_MenuDeselectedFP fp); + typedef void (*SetMenuSelectedFP) (AccessBridge_MenuSelectedFP fp); + typedef void (*SetPopupMenuCanceledFP) (AccessBridge_PopupMenuCanceledFP fp); + typedef void (*SetPopupMenuWillBecomeInvisibleFP) (AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + typedef void (*SetPopupMenuWillBecomeVisibleFP) (AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + typedef void (*SetPropertyNameChangeFP) (AccessBridge_PropertyNameChangeFP fp); + typedef void (*SetPropertyDescriptionChangeFP) (AccessBridge_PropertyDescriptionChangeFP fp); + typedef void (*SetPropertyStateChangeFP) (AccessBridge_PropertyStateChangeFP fp); + typedef void (*SetPropertyValueChangeFP) (AccessBridge_PropertyValueChangeFP fp); + typedef void (*SetPropertySelectionChangeFP) (AccessBridge_PropertySelectionChangeFP fp); + typedef void (*SetPropertyTextChangeFP) (AccessBridge_PropertyTextChangeFP fp); + typedef void (*SetPropertyCaretChangeFP) (AccessBridge_PropertyCaretChangeFP fp); + typedef void (*SetPropertyVisibleDataChangeFP) (AccessBridge_PropertyVisibleDataChangeFP fp); + typedef void (*SetPropertyChildChangeFP) (AccessBridge_PropertyChildChangeFP fp); + typedef void (*SetPropertyActiveDescendentChangeFP) (AccessBridge_PropertyActiveDescendentChangeFP fp); + + typedef void (*SetPropertyTableModelChangeFP) (AccessBridge_PropertyTableModelChangeFP fp); + + typedef void (*ReleaseJavaObjectFP) (long vmID, Java_Object object); + + typedef BOOL (*GetVersionInfoFP) (long vmID, AccessBridgeVersionInfo *info); + + typedef BOOL (*IsJavaWindowFP) (HWND window); + typedef BOOL (*IsSameObjectFP) (long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + typedef BOOL (*GetAccessibleContextFromHWNDFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef HWND (*getHWNDFromAccessibleContextFP) (long vmID, AccessibleContext ac); + + typedef BOOL (*GetAccessibleContextAtFP) (long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextWithFocusFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextInfoFP) (long vmID, AccessibleContext ac, AccessibleContextInfo *info); + typedef AccessibleContext (*GetAccessibleChildFromContextFP) (long vmID, AccessibleContext ac, jint i); + typedef AccessibleContext (*GetAccessibleParentFromContextFP) (long vmID, AccessibleContext ac); + + /* begin AccessibleTable */ + typedef BOOL (*getAccessibleTableInfoFP) (long vmID, AccessibleContext ac, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableCellInfoFP) (long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo); + + typedef BOOL (*getAccessibleTableRowHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableColumnHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + typedef AccessibleContext (*getAccessibleTableRowDescriptionFP) (long vmID, AccessibleContext acParent, jint row); + typedef AccessibleContext (*getAccessibleTableColumnDescriptionFP) (long vmID, AccessibleContext acParent, jint column); + + typedef jint (*getAccessibleTableRowSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableRowSelectedFP) (long vmID, AccessibleTable table, jint row); + typedef BOOL (*getAccessibleTableRowSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableColumnSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableColumnSelectedFP) (long vmID, AccessibleTable table, jint column); + typedef BOOL (*getAccessibleTableColumnSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableRowFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableColumnFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableIndexFP) (long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + typedef BOOL (*getAccessibleRelationSetFP) (long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* AccessibleHypertext */ + typedef BOOL (*getAccessibleHypertextFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + typedef BOOL (*activateAccessibleHyperlinkFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + typedef jint (*getAccessibleHyperlinkCountFP)(const long vmID, + const AccessibleContext accessibleContext); + + typedef BOOL (*getAccessibleHypertextExtFP) (const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + AccessibleHypertextInfo *hypertextInfo); + + typedef jint (*getAccessibleHypertextLinkIndexFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + typedef BOOL (*getAccessibleHyperlinkFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + typedef BOOL (*getAccessibleKeyBindingsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + typedef BOOL (*getAccessibleIconsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + typedef BOOL (*getAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + typedef BOOL (*doAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + /* AccessibleText */ + + typedef BOOL (*GetAccessibleTextInfoFP) (long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + typedef BOOL (*GetAccessibleTextItemsFP) (long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + typedef BOOL (*GetAccessibleTextSelectionInfoFP) (long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + typedef BOOL (*GetAccessibleTextAttributesFP) (long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + typedef BOOL (*GetAccessibleTextRectFP) (long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + typedef BOOL (*GetAccessibleTextLineBoundsFP) (long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + typedef BOOL (*GetAccessibleTextRangeFP) (long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + typedef BOOL (*GetCurrentAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMaximumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMinimumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + + typedef void (*AddAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*ClearAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + typedef JOBJECT64 (*GetAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef int (*GetAccessibleSelectionCountFromContextFP) (long vmID, AccessibleSelection as); + typedef BOOL (*IsAccessibleChildSelectedFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*RemoveAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*SelectAllAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + + /* Utility methods */ + + typedef BOOL (*setTextContentsFP) (const long vmID, const AccessibleContext ac, const wchar_t *text); + typedef AccessibleContext (*getParentWithRoleFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getParentWithRoleElseRootFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getTopLevelObjectFP) (const long vmID, const AccessibleContext ac); + typedef int (*getObjectDepthFP) (const long vmID, const AccessibleContext ac); + typedef AccessibleContext (*getActiveDescendentFP) (const long vmID, const AccessibleContext ac); + + + typedef BOOL (*getVirtualAccessibleNameFP) (const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + typedef BOOL (*requestFocusFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*selectTextRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex); + + typedef BOOL (*getTextAttributesInRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + typedef int (*getVisibleChildrenCountFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*getVisibleChildrenFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *children); + + typedef BOOL (*setCaretPositionFP) (const long vmID, const AccessibleContext accessibleContext, const int position); + + typedef BOOL (*getCaretLocationFP) (long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index); + + typedef int (*getEventsWaitingFP) (); + + typedef struct AccessBridgeFPsTag { + Windows_runFP Windows_run; + + SetPropertyChangeFP SetPropertyChange; + + SetJavaShutdownFP SetJavaShutdown; + SetFocusGainedFP SetFocusGained; + SetFocusLostFP SetFocusLost; + + SetCaretUpdateFP SetCaretUpdate; + + SetMouseClickedFP SetMouseClicked; + SetMouseEnteredFP SetMouseEntered; + SetMouseExitedFP SetMouseExited; + SetMousePressedFP SetMousePressed; + SetMouseReleasedFP SetMouseReleased; + + SetMenuCanceledFP SetMenuCanceled; + SetMenuDeselectedFP SetMenuDeselected; + SetMenuSelectedFP SetMenuSelected; + SetPopupMenuCanceledFP SetPopupMenuCanceled; + SetPopupMenuWillBecomeInvisibleFP SetPopupMenuWillBecomeInvisible; + SetPopupMenuWillBecomeVisibleFP SetPopupMenuWillBecomeVisible; + + SetPropertyNameChangeFP SetPropertyNameChange; + SetPropertyDescriptionChangeFP SetPropertyDescriptionChange; + SetPropertyStateChangeFP SetPropertyStateChange; + SetPropertyValueChangeFP SetPropertyValueChange; + SetPropertySelectionChangeFP SetPropertySelectionChange; + SetPropertyTextChangeFP SetPropertyTextChange; + SetPropertyCaretChangeFP SetPropertyCaretChange; + SetPropertyVisibleDataChangeFP SetPropertyVisibleDataChange; + SetPropertyChildChangeFP SetPropertyChildChange; + SetPropertyActiveDescendentChangeFP SetPropertyActiveDescendentChange; + + SetPropertyTableModelChangeFP SetPropertyTableModelChange; + + ReleaseJavaObjectFP ReleaseJavaObject; + GetVersionInfoFP GetVersionInfo; + + IsJavaWindowFP IsJavaWindow; + IsSameObjectFP IsSameObject; + GetAccessibleContextFromHWNDFP GetAccessibleContextFromHWND; + getHWNDFromAccessibleContextFP getHWNDFromAccessibleContext; + + GetAccessibleContextAtFP GetAccessibleContextAt; + GetAccessibleContextWithFocusFP GetAccessibleContextWithFocus; + GetAccessibleContextInfoFP GetAccessibleContextInfo; + GetAccessibleChildFromContextFP GetAccessibleChildFromContext; + GetAccessibleParentFromContextFP GetAccessibleParentFromContext; + + getAccessibleTableInfoFP getAccessibleTableInfo; + getAccessibleTableCellInfoFP getAccessibleTableCellInfo; + + getAccessibleTableRowHeaderFP getAccessibleTableRowHeader; + getAccessibleTableColumnHeaderFP getAccessibleTableColumnHeader; + + getAccessibleTableRowDescriptionFP getAccessibleTableRowDescription; + getAccessibleTableColumnDescriptionFP getAccessibleTableColumnDescription; + + getAccessibleTableRowSelectionCountFP getAccessibleTableRowSelectionCount; + isAccessibleTableRowSelectedFP isAccessibleTableRowSelected; + getAccessibleTableRowSelectionsFP getAccessibleTableRowSelections; + + getAccessibleTableColumnSelectionCountFP getAccessibleTableColumnSelectionCount; + isAccessibleTableColumnSelectedFP isAccessibleTableColumnSelected; + getAccessibleTableColumnSelectionsFP getAccessibleTableColumnSelections; + + getAccessibleTableRowFP getAccessibleTableRow; + getAccessibleTableColumnFP getAccessibleTableColumn; + getAccessibleTableIndexFP getAccessibleTableIndex; + + getAccessibleRelationSetFP getAccessibleRelationSet; + + getAccessibleHypertextFP getAccessibleHypertext; + activateAccessibleHyperlinkFP activateAccessibleHyperlink; + getAccessibleHyperlinkCountFP getAccessibleHyperlinkCount; + getAccessibleHypertextExtFP getAccessibleHypertextExt; + getAccessibleHypertextLinkIndexFP getAccessibleHypertextLinkIndex; + getAccessibleHyperlinkFP getAccessibleHyperlink; + + getAccessibleKeyBindingsFP getAccessibleKeyBindings; + getAccessibleIconsFP getAccessibleIcons; + getAccessibleActionsFP getAccessibleActions; + doAccessibleActionsFP doAccessibleActions; + + GetAccessibleTextInfoFP GetAccessibleTextInfo; + GetAccessibleTextItemsFP GetAccessibleTextItems; + GetAccessibleTextSelectionInfoFP GetAccessibleTextSelectionInfo; + GetAccessibleTextAttributesFP GetAccessibleTextAttributes; + GetAccessibleTextRectFP GetAccessibleTextRect; + GetAccessibleTextLineBoundsFP GetAccessibleTextLineBounds; + GetAccessibleTextRangeFP GetAccessibleTextRange; + + GetCurrentAccessibleValueFromContextFP GetCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextFP GetMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextFP GetMinimumAccessibleValueFromContext; + + AddAccessibleSelectionFromContextFP AddAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextFP ClearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextFP GetAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextFP GetAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextFP IsAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextFP RemoveAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextFP SelectAllAccessibleSelectionFromContext; + + setTextContentsFP setTextContents; + getParentWithRoleFP getParentWithRole; + getTopLevelObjectFP getTopLevelObject; + getParentWithRoleElseRootFP getParentWithRoleElseRoot; + getObjectDepthFP getObjectDepth; + getActiveDescendentFP getActiveDescendent; + + getVirtualAccessibleNameFP getVirtualAccessibleName; + requestFocusFP requestFocus; + selectTextRangeFP selectTextRange; + getTextAttributesInRangeFP getTextAttributesInRange; + getVisibleChildrenCountFP getVisibleChildrenCount; + getVisibleChildrenFP getVisibleChildren; + setCaretPositionFP setCaretPosition; + getCaretLocationFP getCaretLocation; + + getEventsWaitingFP getEventsWaiting; + + } AccessBridgeFPs; + + + /** + * Initialize the world + */ + BOOL initializeAccessBridge(); + BOOL shutdownAccessBridge(); + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window); + + // Returns the virtual machine ID and AccessibleContext for a top-level window + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac); + + // Returns the HWND from the AccessibleContext of a top-level window + HWND getHWNDFromAccessibleContext(long vmID, AccessibleContext ac); + + + /** + * Event handling routines + */ + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp); + void SetFocusGained(AccessBridge_FocusGainedFP fp); + void SetFocusLost(AccessBridge_FocusLostFP fp); + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp); + + void SetMouseClicked(AccessBridge_MouseClickedFP fp); + void SetMouseEntered(AccessBridge_MouseEnteredFP fp); + void SetMouseExited(AccessBridge_MouseExitedFP fp); + void SetMousePressed(AccessBridge_MousePressedFP fp); + void SetMouseReleased(AccessBridge_MouseReleasedFP fp); + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp); + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp); + void SetMenuSelected(AccessBridge_MenuSelectedFP fp); + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp); + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp); + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp); + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp); + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp); + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp); + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp); + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp); + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp); + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp); + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp); + + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object); + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info); + HWND GetHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext); + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac); + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info); + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index); + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac); + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + /* begin AccessibleTable routines */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row); + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row); + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableRow(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableColumn(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* ----- AccessibleRelationSet routines */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* ----- AccessibleHypertext routines */ + + /* + * Returns hypertext information associated with a component. + */ + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + /* + * Requests that a hyperlink be activated. + */ + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleHypertext hypertext); + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * Returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; maps to AccessibleHypertext.getLinkIndex + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + /* + * Returns the nth hyperlink in a document + * Maps to AccessibleHypertext.getLink. + * Returns FALSE on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + /* Accessible KeyBindings, Icons and Actions */ + + /* + * Returns a list of key bindings associated with a component. + */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + /* + * Returns a list of icons associate with a component. + */ + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + /* + * Returns a list of actions that a component can perform. + */ + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + /* + * Request that a list of AccessibleActions be performed by a component. + * Returns TRUE if all actions are performed. Returns FALSE + * when the first requested action fails in which case "failure" + * contains the index of the action that failed. + */ + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + + /* Additional utility methods */ + + /* + * Returns whether two object references refer to the same object. + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length that can be set is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + /** + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + + /** + * Accessible Selection routines + */ + void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as); + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i); + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful. + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful. + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, const int startIndex, + const int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful. + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position); + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, + AccessibleTextRectInfo *rectInfo, jint index); + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting(); + +#ifdef __cplusplus +} +#endif diff --git a/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgePackages.h b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgePackages.h new file mode 100644 index 00000000..478f7c63 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/bridge/AccessBridgePackages.h @@ -0,0 +1,2215 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Header file for packages of paramaters passed between Java Accessibility + * and native Assistive Technologies + */ + +#ifndef __AccessBridgePackages_H__ +#define __AccessBridgePackages_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ACCESSBRIDGE_ARCH_LEGACY +typedef jobject JOBJECT64; +typedef HWND ABHWND64; +#define ABHandleToLong +#define ABLongToHandle +#else +typedef jlong JOBJECT64; +typedef long ABHWND64; +#define ABHandleToLong HandleToLong +#define ABLongToHandle LongToHandle +#endif + +#define MAX_BUFFER_SIZE 10240 +#define MAX_STRING_SIZE 1024 +#define SHORT_STRING_SIZE 256 + + // object types + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + /** + ****************************************************** + * Java event types + ****************************************************** + */ + +#define cPropertyChangeEvent (jlong) 1 // 1 +#define cFocusGainedEvent (jlong) 2 // 2 +#define cFocusLostEvent (jlong) 4 // 4 +#define cCaretUpdateEvent (jlong) 8 // 8 +#define cMouseClickedEvent (jlong) 16 // 10 +#define cMouseEnteredEvent (jlong) 32 // 20 +#define cMouseExitedEvent (jlong) 64 // 40 +#define cMousePressedEvent (jlong) 128 // 80 +#define cMouseReleasedEvent (jlong) 256 // 100 +#define cMenuCanceledEvent (jlong) 512 // 200 +#define cMenuDeselectedEvent (jlong) 1024 // 400 +#define cMenuSelectedEvent (jlong) 2048 // 800 +#define cPopupMenuCanceledEvent (jlong) 4096 // 1000 +#define cPopupMenuWillBecomeInvisibleEvent (jlong) 8192 // 2000 +#define cPopupMenuWillBecomeVisibleEvent (jlong) 16384 // 4000 +#define cJavaShutdownEvent (jlong) 32768 // 8000 + + /** + ****************************************************** + * Accessible Roles + * Defines all AccessibleRoles in Local.US + ****************************************************** + */ + + /** + * Object is used to alert the user about something. + */ +#define ACCESSIBLE_ALERT L"alert" + + /** + * The header for a column of data. + */ +#define ACCESSIBLE_COLUMN_HEADER L"column header" + + /** + * Object that can be drawn into and is used to trap + * events. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_CANVAS L"canvas" + + /** + * A list of choices the user can select from. Also optionally + * allows the user to enter a choice of their own. + */ +#define ACCESSIBLE_COMBO_BOX L"combo box" + + /** + * An iconified internal frame in a DESKTOP_PANE. + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_ICON L"desktop icon" + + /** + * A frame-like object that is clipped by a desktop pane. The + * desktop pane, internal frame, and desktop icon objects are + * often used to create multiple document interfaces within an + * application. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_FRAME + */ +#define ACCESSIBLE_INTERNAL_FRAME L"internal frame" + + /** + * A pane that supports internal frames and + * iconified versions of those internal frames. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_PANE L"desktop pane" + + /** + * A specialized pane whose primary use is inside a DIALOG + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_OPTION_PANE L"option pane" + + /** + * A top level window with no title or border. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_WINDOW L"window" + + /** + * A top level window with a title bar, border, menu bar, etc. It is + * often used as the primary window for an application. + * see ACCESSIBLE_DIALOG + * see ACCESSIBLE_CANVAS + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_FRAME L"frame" + + /** + * A top level window with title bar and a border. A dialog is similar + * to a frame, but it has fewer properties and is often used as a + * secondary window for an application. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_DIALOG L"dialog" + + /** + * A specialized dialog that lets the user choose a color. + */ +#define ACCESSIBLE_COLOR_CHOOSER L"color chooser" + + + /** + * A pane that allows the user to navigate through + * and select the contents of a directory. May be used + * by a file chooser. + * see ACCESSIBLE_FILE_CHOOSER + */ +#define ACCESSIBLE_DIRECTORY_PANE L"directory pane" + + /** + * A specialized dialog that displays the files in the directory + * and lets the user select a file, browse a different directory, + * or specify a filename. May use the directory pane to show the + * contents of a directory. + * see ACCESSIBLE_DIRECTORY_PANE + */ +#define ACCESSIBLE_FILE_CHOOSER L"file chooser" + + /** + * An object that fills up space in a user interface. It is often + * used in interfaces to tweak the spacing between components, + * but serves no other purpose. + */ +#define ACCESSIBLE_FILLER L"filler" + + /** + * A hypertext anchor + */ +#define ACCESSIBLE_HYPERLINK L"hyperlink" + + /** + * A small fixed size picture, typically used to decorate components. + */ +#define ACCESSIBLE_ICON L"icon" + + /** + * An object used to present an icon or short string in an interface. + */ +#define ACCESSIBLE_LABEL L"label" + + /** + * A specialized pane that has a glass pane and a layered pane as its + * children. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_ROOT_PANE L"root pane" + + /** + * A pane that is guaranteed to be painted on top + * of all panes beneath it. + * see ACCESSIBLE_ROOT_PANE + * see ACCESSIBLE_CANVAS + */ +#define ACCESSIBLE_GLASS_PANE L"glass pane" + + /** + * A specialized pane that allows its children to be drawn in layers, + * providing a form of stacking order. This is usually the pane that + * holds the menu bar as well as the pane that contains most of the + * visual components in a window. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_ROOT_PANE + */ +#define ACCESSIBLE_LAYERED_PANE L"layered pane" + + /** + * An object that presents a list of objects to the user and allows the + * user to select one or more of them. A list is usually contained + * within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST_ITEM + */ +#define ACCESSIBLE_LIST L"list" + + /** + * An object that presents an element in a list. A list is usually + * contained within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST + */ +#define ACCESSIBLE_LIST_ITEM L"list item" + + /** + * An object usually drawn at the top of the primary dialog box of + * an application that contains a list of menus the user can choose + * from. For example, a menu bar might contain menus for "File," + * "Edit," and "Help." + * see ACCESSIBLE_MENU + * see ACCESSIBLE_POPUP_MENU + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_MENU_BAR L"menu bar" + + /** + * A temporary window that is usually used to offer the user a + * list of choices, and then hides when the user selects one of + * those choices. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_POPUP_MENU L"popup menu" + + /** + * An object usually found inside a menu bar that contains a list + * of actions the user can choose from. A menu can have any object + * as its children, but most often they are menu items, other menus, + * or rudimentary objects such as radio buttons, check boxes, or + * separators. For example, an application may have an "Edit" menu + * that contains menu items for "Cut" and "Paste." + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_MENU_ITEM + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_RADIO_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU L"menu" + + /** + * An object usually contained in a menu that presents an action + * the user can choose. For example, the "Cut" menu item in an + * "Edit" menu would be an action the user can select to cut the + * selected area of text in a document. + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU_ITEM L"menu item" + + /** + * An object usually contained in a menu to provide a visual + * and logical separation of the contents in a menu. For example, + * the "File" menu of an application might contain menu items for + * "Open," "Close," and "Exit," and will place a separator between + * "Close" and "Exit" menu items. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_SEPARATOR L"separator" + + /** + * An object that presents a series of panels (or page tabs), one at a + * time, through some mechanism provided by the object. The most common + * mechanism is a list of tabs at the top of the panel. The children of + * a page tab list are all page tabs. + * see ACCESSIBLE_PAGE_TAB + */ +#define ACCESSIBLE_PAGE_TAB_LIST L"page tab list" + + /** + * An object that is a child of a page tab list. Its sole child is + * the panel that is to be presented to the user when the user + * selects the page tab from the list of tabs in the page tab list. + * see ACCESSIBLE_PAGE_TAB_LIST + */ +#define ACCESSIBLE_PAGE_TAB L"page tab" + + /** + * A generic container that is often used to group objects. + */ +#define ACCESSIBLE_PANEL L"panel" + + /** + * An object used to indicate how much of a task has been completed. + */ +#define ACCESSIBLE_PROGRESS_BAR L"progress bar" + + /** + * A text object used for passwords, or other places where the + * text contents is not shown visibly to the user + */ +#define ACCESSIBLE_PASSWORD_TEXT L"password text" + + /** + * An object the user can manipulate to tell the application to do + * something. + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_PUSH_BUTTON L"push button" + + /** + * A specialized push button that can be checked or unchecked, but + * does not provide a separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_TOGGLE_BUTTON L"toggle button" + + /** + * A choice that can be checked or unchecked and provides a + * separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_CHECK_BOX L"check box" + + /** + * A specialized check box that will cause other radio buttons in the + * same group to become unchecked when this one is checked. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_CHECK_BOX + */ +#define ACCESSIBLE_RADIO_BUTTON L"radio button" + + /** + * The header for a row of data. + */ +#define ACCESSIBLE_ROW_HEADER L"row header" + + /** + * An object that allows a user to incrementally view a large amount + * of information. Its children can include scroll bars and a viewport. + * see ACCESSIBLE_SCROLL_BAR + * see ACCESSIBLE_VIEWPORT + */ +#define ACCESSIBLE_SCROLL_PANE L"scroll pane" + + /** + * An object usually used to allow a user to incrementally view a + * large amount of data. Usually used only by a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_SCROLL_BAR L"scroll bar" + + /** + * An object usually used in a scroll pane. It represents the portion + * of the entire data that the user can see. As the user manipulates + * the scroll bars, the contents of the viewport can change. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_VIEWPORT L"viewport" + + /** + * An object that allows the user to select from a bounded range. For + * example, a slider might be used to select a number between 0 and 100. + */ +#define ACCESSIBLE_SLIDER L"slider" + + /** + * A specialized panel that presents two other panels at the same time. + * Between the two panels is a divider the user can manipulate to make + * one panel larger and the other panel smaller. + */ +#define ACCESSIBLE_SPLIT_PANE L"split pane" + + /** + * An object used to present information in terms of rows and columns. + * An example might include a spreadsheet application. + */ +#define ACCESSIBLE_TABLE L"table" + + /** + * An object that presents text to the user. The text is usually + * editable by the user as opposed to a label. + * see ACCESSIBLE_LABEL + */ +#define ACCESSIBLE_TEXT L"text" + + /** + * An object used to present hierarchical information to the user. + * The individual nodes in the tree can be collapsed and expanded + * to provide selective disclosure of the tree's contents. + */ +#define ACCESSIBLE_TREE L"tree" + + /** + * A bar or palette usually composed of push buttons or toggle buttons. + * It is often used to provide the most frequently used functions for an + * application. + */ +#define ACCESSIBLE_TOOL_BAR L"tool bar" + + /** + * An object that provides information about another object. The + * accessibleDescription property of the tool tip is often displayed + * to the user in a small L"help bubble" when the user causes the + * mouse to hover over the object associated with the tool tip. + */ +#define ACCESSIBLE_TOOL_TIP L"tool tip" + + /** + * An AWT component, but nothing else is known about it. + * see ACCESSIBLE_SWING_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_AWT_COMPONENT L"awt component" + + /** + * A Swing component, but nothing else is known about it. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_SWING_COMPONENT L"swing component" + + /** + * The object contains some Accessible information, but its role is + * not known. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_SWING_COMPONENT + */ +#define ACCESSIBLE_UNKNOWN L"unknown" + + /** + * A STATUS_BAR is an simple component that can contain + * multiple labels of status information to the user. + */ +#define ACCESSIBLE_STATUS_BAR L"status bar" + + /** + * A DATE_EDITOR is a component that allows users to edit + * java.util.Date and java.util.Time objects + */ +#define ACCESSIBLE_DATE_EDITOR L"date editor" + + /** + * A SPIN_BOX is a simple spinner component and its main use + * is for simple numbers. + */ +#define ACCESSIBLE_SPIN_BOX L"spin box" + + /** + * A FONT_CHOOSER is a component that lets the user pick various + * attributes for fonts. + */ +#define ACCESSIBLE_FONT_CHOOSER L"font chooser" + + /** + * A GROUP_BOX is a simple container that contains a border + * around it and contains components inside it. + */ +#define ACCESSIBLE_GROUP_BOX L"group box" + + /** + * A text header + */ +#define ACCESSIBLE_HEADER L"header" + + /** + * A text footer + */ +#define ACCESSIBLE_FOOTER L"footer" + + /** + * A text paragraph + */ +#define ACCESSIBLE_PARAGRAPH L"paragraph" + + /** + * A ruler is an object used to measure distance + */ +#define ACCESSIBLE_RULER L"ruler" + + /** + * A role indicating the object acts as a formula for + * calculating a value. An example is a formula in + * a spreadsheet cell. + */ +#define ACCESSIBLE_EDITBAR L"editbar" + + /** + * A role indicating the object monitors the progress + * of some operation. + */ +#define PROGRESS_MONITOR L"progress monitor" + + + /** + ****************************************************** + * Accessibility event types + ****************************************************** + */ + +#define cPropertyNameChangeEvent (jlong) 1 // 1 +#define cPropertyDescriptionChangeEvent (jlong) 2 // 2 +#define cPropertyStateChangeEvent (jlong) 4 // 4 +#define cPropertyValueChangeEvent (jlong) 8 // 8 +#define cPropertySelectionChangeEvent (jlong) 16 // 10 +#define cPropertyTextChangeEvent (jlong) 32 // 20 +#define cPropertyCaretChangeEvent (jlong) 64 // 40 +#define cPropertyVisibleDataChangeEvent (jlong) 128 // 80 +#define cPropertyChildChangeEvent (jlong) 256 // 100 +#define cPropertyActiveDescendentChangeEvent (jlong) 512 // 200 +#define cPropertyTableModelChangeEvent (jlong) 1024 // 400 + + /** + ****************************************************** + * optional AccessibleContext interfaces + * + * This version of the bridge reuses the accessibleValue + * field in the AccessibleContextInfo struct to represent + * additional optional interfaces that are supported by + * the Java AccessibleContext. This is backwardly compatable + * because the old accessibleValue was set to the BOOL + * value TRUE (i.e., 1) if the AccessibleValue interface is + * supported. + ****************************************************** + */ + +#define cAccessibleValueInterface (jlong) 1 // 1 << 1 (TRUE) +#define cAccessibleActionInterface (jlong) 2 // 1 << 2 +#define cAccessibleComponentInterface (jlong) 4 // 1 << 3 +#define cAccessibleSelectionInterface (jlong) 8 // 1 << 4 +#define cAccessibleTableInterface (jlong) 16 // 1 << 5 +#define cAccessibleTextInterface (jlong) 32 // 1 << 6 +#define cAccessibleHypertextInterface (jlong) 64 // 1 << 7 + + + /** + ****************************************************** + * Accessibility information bundles + ****************************************************** + */ + + typedef struct AccessBridgeVersionInfoTag { + wchar_t VMversion[SHORT_STRING_SIZE]; // output of "java -version" + wchar_t bridgeJavaClassVersion[SHORT_STRING_SIZE]; // version of the AccessBridge.class + wchar_t bridgeJavaDLLVersion[SHORT_STRING_SIZE]; // version of JavaAccessBridge.dll + wchar_t bridgeWinDLLVersion[SHORT_STRING_SIZE]; // version of WindowsAccessBridge.dll + } AccessBridgeVersionInfo; + + + typedef struct AccessibleContextInfoTag { + wchar_t name[MAX_STRING_SIZE]; // the AccessibleName of the object + wchar_t description[MAX_STRING_SIZE]; // the AccessibleDescription of the object + + wchar_t role[SHORT_STRING_SIZE]; // localized AccesibleRole string + wchar_t role_en_US[SHORT_STRING_SIZE]; // AccesibleRole string in the en_US locale + wchar_t states[SHORT_STRING_SIZE]; // localized AccesibleStateSet string (comma separated) + wchar_t states_en_US[SHORT_STRING_SIZE]; // AccesibleStateSet string in the en_US locale (comma separated) + + jint indexInParent; // index of object in parent + jint childrenCount; // # of children, if any + + jint x; // screen coords in pixels + jint y; // " + jint width; // pixel width of object + jint height; // pixel height of object + + BOOL accessibleComponent; // flags for various additional + BOOL accessibleAction; // Java Accessibility interfaces + BOOL accessibleSelection; // FALSE if this object doesn't + BOOL accessibleText; // implement the additional interface + // in question + + // BOOL accessibleValue; // old BOOL indicating whether AccessibleValue is supported + BOOL accessibleInterfaces; // new bitfield containing additional interface flags + + } AccessibleContextInfo; + + + + // AccessibleText packages + typedef struct AccessibleTextInfoTag { + jint charCount; // # of characters in this text object + jint caretIndex; // index of caret + jint indexAtPoint; // index at the passsed in point + } AccessibleTextInfo; + + typedef struct AccessibleTextItemsInfoTag { + wchar_t letter; + wchar_t word[SHORT_STRING_SIZE]; + wchar_t sentence[MAX_STRING_SIZE]; + } AccessibleTextItemsInfo; + + typedef struct AccessibleTextSelectionInfoTag { + jint selectionStartIndex; + jint selectionEndIndex; + wchar_t selectedText[MAX_STRING_SIZE]; + } AccessibleTextSelectionInfo; + + typedef struct AccessibleTextRectInfoTag { + jint x; // bounding rect of char at index + jint y; // " + jint width; // " + jint height; // " + } AccessibleTextRectInfo; + + // standard attributes for text; note: tabstops are not supported + typedef struct AccessibleTextAttributesInfoTag { + BOOL bold; + BOOL italic; + BOOL underline; + BOOL strikethrough; + BOOL superscript; + BOOL subscript; + + wchar_t backgroundColor[SHORT_STRING_SIZE]; + wchar_t foregroundColor[SHORT_STRING_SIZE]; + wchar_t fontFamily[SHORT_STRING_SIZE]; + jint fontSize; + + jint alignment; + jint bidiLevel; + + jfloat firstLineIndent; + jfloat leftIndent; + jfloat rightIndent; + jfloat lineSpacing; + jfloat spaceAbove; + jfloat spaceBelow; + + wchar_t fullAttributesString[MAX_STRING_SIZE]; + } AccessibleTextAttributesInfo; + + /** + ****************************************************** + * IPC management typedefs + ****************************************************** + */ + +#define cMemoryMappedNameSize 255 + + /** + * sent by the WindowsDLL -> the memory-mapped file is setup + * + */ + typedef struct MemoryMappedFileCreatedPackageTag { +// HWND bridgeWindow; // redundant, but easier to get to here... + ABHWND64 bridgeWindow; // redundant, but easier to get to here... + char filename[cMemoryMappedNameSize]; + } MemoryMappedFileCreatedPackage; + + + + + /** + * sent when a new JavaVM attaches to the Bridge + * + */ + typedef struct JavaVMCreatedPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMCreatedPackage; + + /** + * sent when a JavaVM detatches from the Bridge + * + */ + typedef struct JavaVMDestroyedPackageTag { + ABHWND64 bridgeWindow; + } JavaVMDestroyedPackage; + + /** + * sent when a new AT attaches to the Bridge + * + */ + typedef struct WindowsATCreatedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATCreatedPackage; + + /** + * sent when an AT detatches from the Bridge + * + */ + typedef struct WindowsATDestroyedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATDestroyedPackage; + + + /** + * sent by JVM Bridges in response to a WindowsATCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct JavaVMPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMPresentNotificationPackage; + + /** + * sent by AT Bridges in response to a JavaVMCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct WindowsATPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + } WindowsATPresentNotificationPackage; + + + /** + ****************************************************** + * Core packages + ****************************************************** + */ + + typedef struct ReleaseJavaObjectPackageTag { + long vmID; + JOBJECT64 object; + } ReleaseJavaObjectPackage; + + typedef struct GetAccessBridgeVersionPackageTag { + long vmID; // can't get VM info w/out a VM! + AccessBridgeVersionInfo rVersionInfo; + } GetAccessBridgeVersionPackage; + + typedef struct IsSameObjectPackageTag { + long vmID; + JOBJECT64 obj1; + JOBJECT64 obj2; + jboolean rResult; + } IsSameObjectPackage; + + /** + ****************************************************** + * Windows packages + ****************************************************** + */ + + typedef struct IsJavaWindowPackageTag { + jint window; + jboolean rResult; + } IsJavaWindowPackage; + + typedef struct GetAccessibleContextFromHWNDPackageTag { + jint window; + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextFromHWNDPackage; + + typedef struct GetHWNDFromAccessibleContextPackageTag { + JOBJECT64 accessibleContext; + ABHWND64 rHWND; + } GetHWNDFromAccessibleContextPackage; + + /** +****************************************************** +* AccessibleContext packages +****************************************************** +*/ + + typedef struct GetAccessibleContextAtPackageTag { + jint x; + jint y; + long vmID; + JOBJECT64 AccessibleContext; // look within this AC + JOBJECT64 rAccessibleContext; + } GetAccessibleContextAtPackage; + + typedef struct GetAccessibleContextWithFocusPackageTag { + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextWithFocusPackage; + + typedef struct GetAccessibleContextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleContextInfo rAccessibleContextInfo; + } GetAccessibleContextInfoPackage; + + typedef struct GetAccessibleChildFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint childIndex; + JOBJECT64 rAccessibleContext; + } GetAccessibleChildFromContextPackage; + + typedef struct GetAccessibleParentFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + JOBJECT64 rAccessibleContext; + } GetAccessibleParentFromContextPackage; + + /** +****************************************************** +* AccessibleTable packages +****************************************************** +*/ + +#define MAX_TABLE_SELECTIONS 64 + + // table information + typedef struct AccessibleTableInfoTag { + JOBJECT64 caption; // AccesibleContext + JOBJECT64 summary; // AccessibleContext + jint rowCount; + jint columnCount; + JOBJECT64 accessibleContext; + JOBJECT64 accessibleTable; + } AccessibleTableInfo; + + typedef struct GetAccessibleTableInfoPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableInfoPackage; + + // table cell information + typedef struct AccessibleTableCellInfoTag { + JOBJECT64 accessibleContext; + jint index; + jint row; + jint column; + jint rowExtent; + jint columnExtent; + jboolean isSelected; + } AccessibleTableCellInfo; + + typedef struct GetAccessibleTableCellInfoPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + AccessibleTableCellInfo rTableCellInfo; + } GetAccessibleTableCellInfoPackage; + + typedef struct GetAccessibleTableRowHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableRowHeaderPackage; + + typedef struct GetAccessibleTableColumnHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableColumnHeaderPackage; + + typedef struct GetAccessibleTableRowDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint row; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableRowDescriptionPackage; + + typedef struct GetAccessibleTableColumnDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint column; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableColumnDescriptionPackage; + + typedef struct GetAccessibleTableRowSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableRowSelectionCountPackage; + + typedef struct IsAccessibleTableRowSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jboolean rResult; + } IsAccessibleTableRowSelectedPackage; + + typedef struct GetAccessibleTableRowSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableRowSelectionsPackage; + + typedef struct GetAccessibleTableColumnSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableColumnSelectionCountPackage; + + typedef struct IsAccessibleTableColumnSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint column; + jboolean rResult; + } IsAccessibleTableColumnSelectedPackage; + + typedef struct GetAccessibleTableColumnSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableColumnSelectionsPackage; + + + typedef struct GetAccessibleTableRowPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rRow; + } GetAccessibleTableRowPackage; + + typedef struct GetAccessibleTableColumnPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rColumn; + } GetAccessibleTableColumnPackage; + + typedef struct GetAccessibleTableIndexPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + jint rIndex; + } GetAccessibleTableIndexPackage; + + + /** + ****************************************************** + * AccessibleRelationSet packages + ****************************************************** + */ + +#define MAX_RELATION_TARGETS 25 +#define MAX_RELATIONS 5 + + typedef struct AccessibleRelationInfoTag { + wchar_t key[SHORT_STRING_SIZE]; + jint targetCount; + JOBJECT64 targets[MAX_RELATION_TARGETS]; // AccessibleContexts + } AccessibleRelationInfo; + + typedef struct AccessibleRelationSetInfoTag { + jint relationCount; + AccessibleRelationInfo relations[MAX_RELATIONS]; + } AccessibleRelationSetInfo; + + typedef struct GetAccessibleRelationSetPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleRelationSetInfo rAccessibleRelationSetInfo; + } GetAccessibleRelationSetPackage; + + /** + ****************************************************** + * AccessibleHypertext packagess + ****************************************************** + */ + +#define MAX_HYPERLINKS 64 // maximum number of hyperlinks returned + + // hyperlink information + typedef struct AccessibleHyperlinkInfoTag { + wchar_t text[SHORT_STRING_SIZE]; // the hyperlink text + jint startIndex; //index in the hypertext document where the link begins + jint endIndex; //index in the hypertext document where the link ends + JOBJECT64 accessibleHyperlink; // AccessibleHyperlink object + } AccessibleHyperlinkInfo; + + // hypertext information + typedef struct AccessibleHypertextInfoTag { + jint linkCount; // number of hyperlinks + AccessibleHyperlinkInfo links[MAX_HYPERLINKS]; // the hyperlinks + JOBJECT64 accessibleHypertext; // AccessibleHypertext object + } AccessibleHypertextInfo; + + // struct for sending a message to get the hypertext for an AccessibleContext + typedef struct GetAccessibleHypertextPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + } GetAccessibleHypertextPackage; + + // struct for sending an message to activate a hyperlink + typedef struct ActivateAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing the link + JOBJECT64 accessibleHyperlink; // the link to activate + BOOL rResult; // hyperlink activation return value + } ActivateAccessibleHyperlinkPackage; + + // struct for sending a message to get the number of hyperlinks in a component + typedef struct GetAccessibleHyperlinkCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing AccessibleHypertext + jint rLinkCount; // link count return value + } GetAccessibleHyperlinkCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetAccessibleHypertextExtPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + jint startIndex; // start index in document + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + BOOL rSuccess; // whether call succeeded + } GetAccessibleHypertextExtPackage; + + // struct for sending a message to get the nth hyperlink in a document; + // maps to AccessibleHypertext.getLink + typedef struct GetAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint linkIndex; // hyperlink index + AccessibleHyperlinkInfo rAccessibleHyperlinkInfo; // returned hyperlink + } GetAccessibleHyperlinkPackage; + + // struct for sending a message to get the index into an array + // of hyperlinks that is associated with a character index in a + // document; maps to AccessibleHypertext.getLinkIndex + typedef struct GetAccessibleHypertextLinkIndexPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint charIndex; // character index in document + jint rLinkIndex; // returned hyperlink index + } GetAccessibleHypertextLinkIndexPackage; + + /** + ****************************************************** + * Accessible Key Bindings packages + ****************************************************** + */ + +#define MAX_KEY_BINDINGS 10 + + // keyboard character modifiers +#define ACCESSIBLE_SHIFT_KEYSTROKE 1 +#define ACCESSIBLE_CONTROL_KEYSTROKE 2 +#define ACCESSIBLE_META_KEYSTROKE 4 +#define ACCESSIBLE_ALT_KEYSTROKE 8 +#define ACCESSIBLE_ALT_GRAPH_KEYSTROKE 16 +#define ACCESSIBLE_BUTTON1_KEYSTROKE 32 +#define ACCESSIBLE_BUTTON2_KEYSTROKE 64 +#define ACCESSIBLE_BUTTON3_KEYSTROKE 128 +#define ACCESSIBLE_FKEY_KEYSTROKE 256 // F key pressed, character contains 1-24 +#define ACCESSIBLE_CONTROLCODE_KEYSTROKE 512 // Control code key pressed, character contains control code. + +// The supported control code keys are: +#define ACCESSIBLE_VK_BACK_SPACE 8 +#define ACCESSIBLE_VK_DELETE 127 +#define ACCESSIBLE_VK_DOWN 40 +#define ACCESSIBLE_VK_END 35 +#define ACCESSIBLE_VK_HOME 36 +#define ACCESSIBLE_VK_INSERT 155 +#define ACCESSIBLE_VK_KP_DOWN 225 +#define ACCESSIBLE_VK_KP_LEFT 226 +#define ACCESSIBLE_VK_KP_RIGHT 227 +#define ACCESSIBLE_VK_KP_UP 224 +#define ACCESSIBLE_VK_LEFT 37 +#define ACCESSIBLE_VK_PAGE_DOWN 34 +#define ACCESSIBLE_VK_PAGE_UP 33 +#define ACCESSIBLE_VK_RIGHT 39 +#define ACCESSIBLE_VK_UP 38 + + // a key binding associates with a component + typedef struct AccessibleKeyBindingInfoTag { + jchar character; // the key character + jint modifiers; // the key modifiers + } AccessibleKeyBindingInfo; + + // all of the key bindings associated with a component + typedef struct AccessibleKeyBindingsTag { + int keyBindingsCount; // number of key bindings + AccessibleKeyBindingInfo keyBindingInfo[MAX_KEY_BINDINGS]; + } AccessibleKeyBindings; + + // struct to get the key bindings associated with a component + typedef struct GetAccessibleKeyBindingsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleKeyBindings rAccessibleKeyBindings; // the key bindings + } GetAccessibleKeyBindingsPackage; + + /** +****************************************************** +* AccessibleIcon packages +****************************************************** +*/ +#define MAX_ICON_INFO 8 + + // an icon assocated with a component + typedef struct AccessibleIconInfoTag { + wchar_t description[SHORT_STRING_SIZE]; // icon description + jint height; // icon height + jint width; // icon width + } AccessibleIconInfo; + + // all of the icons associated with a component + typedef struct AccessibleIconsTag { + jint iconsCount; // number of icons + AccessibleIconInfo iconInfo[MAX_ICON_INFO]; // the icons + } AccessibleIcons; + + // struct to get the icons associated with a component + typedef struct GetAccessibleIconsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleIcons rAccessibleIcons; // the icons + } GetAccessibleIconsPackage; + + + /** +****************************************************** +* AccessibleAction packages +****************************************************** +*/ +#define MAX_ACTION_INFO 256 +#define MAX_ACTIONS_TO_DO 32 + + // an action assocated with a component + typedef struct AccessibleActionInfoTag { + wchar_t name[SHORT_STRING_SIZE]; // action name + } AccessibleActionInfo; + + // all of the actions associated with a component + typedef struct AccessibleActionsTag { + jint actionsCount; // number of actions + AccessibleActionInfo actionInfo[MAX_ACTION_INFO]; // the action information + } AccessibleActions; + + // struct for requesting the actions associated with a component + typedef struct GetAccessibleActionsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the component + AccessibleActions rAccessibleActions; // the actions + } GetAccessibleActionsPackage; + + // list of AccessibleActions to do + typedef struct AccessibleActionsToDoTag { + jint actionsCount; // number of actions to do + AccessibleActionInfo actions[MAX_ACTIONS_TO_DO];// the accessible actions to do + } AccessibleActionsToDo; + + // struct for sending an message to do one or more actions + typedef struct DoAccessibleActionsPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // component to do the action + AccessibleActionsToDo actionsToDo; // the accessible actions to do + BOOL rResult; // action return value + jint failure; // index of action that failed if rResult is FALSE + } DoAccessibleActionsPackage; + + /** +****************************************************** +* AccessibleText packages +****************************************************** +*/ + + typedef struct GetAccessibleTextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint x; + jint y; + AccessibleTextInfo rTextInfo; + } GetAccessibleTextInfoPackage; + + typedef struct GetAccessibleTextItemsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextItemsInfo rTextItemsInfo; + } GetAccessibleTextItemsPackage; + + typedef struct GetAccessibleTextSelectionInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleTextSelectionInfo rTextSelectionItemsInfo; + } GetAccessibleTextSelectionInfoPackage; + + typedef struct GetAccessibleTextAttributeInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextAttributesInfo rAttributeInfo; + } GetAccessibleTextAttributeInfoPackage; + + typedef struct GetAccessibleTextRectInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetAccessibleTextRectInfoPackage; + + typedef struct GetCaretLocationPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetCaretLocationPackage; + + typedef struct GetAccessibleTextLineBoundsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jint rLineStart; + jint rLineEnd; + } GetAccessibleTextLineBoundsPackage; + + typedef struct GetAccessibleTextRangePackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint start; + jint end; + wchar_t rText[MAX_BUFFER_SIZE]; + } GetAccessibleTextRangePackage; + + /** +****************************************************** +* +* Utility method packages +****************************************************** +*/ + + typedef struct SetTextContentsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the text field + wchar_t text[MAX_STRING_SIZE]; // the text + BOOL rResult; + } SetTextContentsPackage; + + typedef struct GetParentWithRolePackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRolePackage; + + typedef struct GetTopLevelObjectPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetTopLevelObjectPackage; + + typedef struct GetParentWithRoleElseRootPackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRoleElseRootPackage; + + typedef struct GetObjectDepthPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint rResult; + } GetObjectDepthPackage; + + typedef struct GetActiveDescendentPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetActiveDescendentPackage; + + /** +****************************************************** +* AccessibleValue packages +****************************************************** +*/ + + typedef struct GetCurrentAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetCurrentAccessibleValueFromContextPackage; + + typedef struct GetMaximumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMaximumAccessibleValueFromContextPackage; + + typedef struct GetMinimumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMinimumAccessibleValueFromContextPackage; + + + /** +****************************************************** +* AccessibleSelection packages +****************************************************** +*/ + + typedef struct AddAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } AddAccessibleSelectionFromContextPackage; + + typedef struct ClearAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } ClearAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + JOBJECT64 rAccessibleContext; + } GetAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionCountFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint rCount; + } GetAccessibleSelectionCountFromContextPackage; + + typedef struct IsAccessibleChildSelectedFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jboolean rResult; + } IsAccessibleChildSelectedFromContextPackage; + + typedef struct RemoveAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } RemoveAccessibleSelectionFromContextPackage; + + typedef struct SelectAllAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } SelectAllAccessibleSelectionFromContextPackage; + + + /** +****************************************************** +* Java Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddJavaEventNotificationPackage; + + typedef struct RemoveJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveJavaEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddAccessibilityEventNotificationPackage; + + typedef struct RemoveAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveAccessibilityEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Property Change Event packages +****************************************************** +*/ + + typedef struct PropertyCaretChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + jint oldPosition; + jint newPosition; + } PropertyCaretChangePackage; + + typedef struct PropertyDescriptionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldDescription[SHORT_STRING_SIZE]; + wchar_t newDescription[SHORT_STRING_SIZE]; + } PropertyDescriptionChangePackage; + + typedef struct PropertyNameChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldName[SHORT_STRING_SIZE]; + wchar_t newName[SHORT_STRING_SIZE]; + } PropertyNameChangePackage; + + typedef struct PropertySelectionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertySelectionChangePackage; + + typedef struct PropertyStateChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldState[SHORT_STRING_SIZE]; + wchar_t newState[SHORT_STRING_SIZE]; + } PropertyStateChangePackage; + + typedef struct PropertyTextChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyTextChangePackage; + + typedef struct PropertyValueChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyValueChangePackage; + + typedef struct PropertyVisibleDataChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyVisibleDataChangePackage; + + typedef struct PropertyChildChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldChildAccessibleContext; + JOBJECT64 newChildAccessibleContext; + } PropertyChildChangePackage; + + typedef struct PropertyActiveDescendentChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldActiveDescendentAccessibleContext; + JOBJECT64 newActiveDescendentAccessibleContext; + } PropertyActiveDescendentChangePackage; + + + // String format for newValue is: + // "type" one of "INSERT", "UPDATE" or "DELETE" + // "firstRow" + // "lastRow" + // "firstColumn" + // "lastColumn" + // + // oldValue is currently unused + // + typedef struct PropertyTableModelChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyTableModelChangePackage; + + + /** +****************************************************** +* Property Change Event packages +****************************************************** +*/ + + /* + typedef struct PropertyChangePackageTag { + long vmID; + jobject Event; + jobject AccessibleContextSource; + char propertyName[SHORT_STRING_SIZE]; + char oldValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getOldValue().toString() + char newValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getNewValue().toString() + } PropertyChangePackage; + */ + + /* + * Java shutdown event package + */ + typedef struct JavaShutdownPackageTag { + long vmID; + } JavaShutdownPackage; + + + /** +****************************************************** +* Focus Event packages +****************************************************** +*/ + + typedef struct FocusGainedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusGainedPackage; + + typedef struct FocusLostPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusLostPackage; + + + /** +****************************************************** +* Caret Event packages +****************************************************** +*/ + + typedef struct CaretUpdatePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } CaretUpdatePackage; + + + /** +****************************************************** +* Mouse Event packages +****************************************************** +*/ + + typedef struct MouseClickedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseClickedPackage; + + typedef struct MouseEnteredPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseEnteredPackage; + + typedef struct MouseExitedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseExitedPackage; + + typedef struct MousePressedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MousePressedPackage; + + typedef struct MouseReleasedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseReleasedPackage; + + + /** +****************************************************** +* Menu/PopupMenu Event packages +****************************************************** +*/ + + typedef struct MenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuCanceledPackage; + + typedef struct MenuDeselectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuDeselectedPackage; + + typedef struct MenuSelectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuSelectedPackage; + + + typedef struct PopupMenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuCanceledPackage; + + typedef struct PopupMenuWillBecomeInvisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeInvisiblePackage; + + typedef struct PopupMenuWillBecomeVisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeVisiblePackage; + + /** +****************************************************** +* Additional methods for Teton +****************************************************** +*/ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + typedef struct GetVirtualAccessibleNamePackageTag { + long vmID; + AccessibleContext accessibleContext; + wchar_t rName[MAX_STRING_SIZE]; + int len; + } GetVirtualAccessibleNamePackage; + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + typedef struct RequestFocusPackageTag { + long vmID; + AccessibleContext accessibleContext; + } RequestFocusPackage; + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + typedef struct SelectTextRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; + jint endIndex; + } SelectTextRangePackage; + + /** + * Gets the number of contiguous characters with the same attributes. + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + typedef struct GetTextAttributesInRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; // start index (inclusive) + jint endIndex; // end index (inclusive) + AccessibleTextAttributesInfo attributes; // character attributes to match + short rLength; // number of contiguous characters with matching attributes + } GetTextAttributesInRangePackage; + +#define MAX_VISIBLE_CHILDREN 256 + + // visible children information + typedef struct VisibleChildenInfoTag { + int returnedChildrenCount; // number of children returned + AccessibleContext children[MAX_VISIBLE_CHILDREN]; // the visible children + } VisibleChildrenInfo; + + // struct for sending a message to get the number of visible children + typedef struct GetVisibleChildrenCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint rChildrenCount; // visible children count return value + } GetVisibleChildrenCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetVisibleChildrenPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint startIndex; // start index for retrieving children + VisibleChildrenInfo rVisibleChildrenInfo; // returned info + BOOL rSuccess; // whether call succeeded + } GetVisibleChildrenPackage; + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + typedef struct SetCaretPositionPackageTag { + long vmID; + AccessibleContext accessibleContext; + jint position; + } SetCaretPositionPackage; + + + /** + ****************************************************** + * Wrapping up all of the packages + ****************************************************** + */ + + /** + * What is the type of this package + */ + typedef enum PackageType { + + cMemoryMappedFileCreatedPackage = 0x11000, + + // many of these will go away... + cJavaVMCreatedPackage = 0x10000, + cJavaVMDestroyedPackage, + cWindowsATCreatedPackage, + cWindowsATDestroyedPackage, + cJavaVMPresentNotificationPackage, + cWindowsATPresentNotificationPackage, + + cReleaseJavaObjectPackage = 1, + cGetAccessBridgeVersionPackage = 2, + + cGetAccessibleContextFromHWNDPackage = 0x10, + cIsJavaWindowPackage, + cGetHWNDFromAccessibleContextPackage, + + cGetAccessibleContextAtPackage = 0x100, + cGetAccessibleContextWithFocusPackage, + cGetAccessibleContextInfoPackage, + cGetAccessibleChildFromContextPackage, + cGetAccessibleParentFromContextPackage, + cIsSameObjectPackage, + + cGetAccessibleTextInfoPackage = 0x200, + cGetAccessibleTextItemsPackage, + cGetAccessibleTextSelectionInfoPackage, + cGetAccessibleTextAttributeInfoPackage, + cGetAccessibleTextRectInfoPackage, + cGetAccessibleTextLineBoundsPackage, + cGetAccessibleTextRangePackage, + + cGetCurrentAccessibleValueFromContextPackage = 0x300, + cGetMaximumAccessibleValueFromContextPackage, + cGetMinimumAccessibleValueFromContextPackage, + + cAddAccessibleSelectionFromContextPackage = 0x400, + cClearAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionCountFromContextPackage, + cIsAccessibleChildSelectedFromContextPackage, + cRemoveAccessibleSelectionFromContextPackage, + cSelectAllAccessibleSelectionFromContextPackage, + + cAddJavaEventNotificationPackage = 0x900, + cRemoveJavaEventNotificationPackage, + cAddAccessibilityEventNotificationPackage, + cRemoveAccessibilityEventNotificationPackage, + + cPropertyChangePackage = 0x1000, + + cJavaShutdownPackage = 0x1010, + cFocusGainedPackage, + cFocusLostPackage, + + cCaretUpdatePackage = 0x1020, + + cMouseClickedPackage = 0x1030, + cMouseEnteredPackage, + cMouseExitedPackage, + cMousePressedPackage, + cMouseReleasedPackage, + + cMenuCanceledPackage = 0x1040, + cMenuDeselectedPackage, + cMenuSelectedPackage, + cPopupMenuCanceledPackage, + cPopupMenuWillBecomeInvisiblePackage, + cPopupMenuWillBecomeVisiblePackage, + + cPropertyCaretChangePackage = 0x1100, + cPropertyDescriptionChangePackage, + cPropertyNameChangePackage, + cPropertySelectionChangePackage, + cPropertyStateChangePackage, + cPropertyTextChangePackage, + cPropertyValueChangePackage, + cPropertyVisibleDataChangePackage, + cPropertyChildChangePackage, + cPropertyActiveDescendentChangePackage, + + + // AccessibleTable + cGetAccessibleTableInfoPackage = 0x1200, + cGetAccessibleTableCellInfoPackage, + + cGetAccessibleTableRowHeaderPackage, + cGetAccessibleTableColumnHeaderPackage, + + cGetAccessibleTableRowDescriptionPackage, + cGetAccessibleTableColumnDescriptionPackage, + + cGetAccessibleTableRowSelectionCountPackage, + cIsAccessibleTableRowSelectedPackage, + cGetAccessibleTableRowSelectionsPackage, + + cGetAccessibleTableColumnSelectionCountPackage, + cIsAccessibleTableColumnSelectedPackage, + cGetAccessibleTableColumnSelectionsPackage, + + cGetAccessibleTableRowPackage, + cGetAccessibleTableColumnPackage, + cGetAccessibleTableIndexPackage, + + cPropertyTableModelChangePackage, + + + // AccessibleRelationSet + cGetAccessibleRelationSetPackage = 0x1300, + + // AccessibleHypertext + cGetAccessibleHypertextPackage = 0x1400, + cActivateAccessibleHyperlinkPackage, + cGetAccessibleHyperlinkCountPackage, + cGetAccessibleHypertextExtPackage, + cGetAccessibleHypertextLinkIndexPackage, + cGetAccessibleHyperlinkPackage, + + // Accessible KeyBinding, Icon and Action + cGetAccessibleKeyBindingsPackage = 0x1500, + cGetAccessibleIconsPackage, + cGetAccessibleActionsPackage, + cDoAccessibleActionsPackage, + + // Utility methods + cSetTextContentsPackage = 0x1600, + cGetParentWithRolePackage, + cGetTopLevelObjectPackage, + cGetParentWithRoleElseRootPackage, + cGetObjectDepthPackage, + cGetActiveDescendentPackage, + + // Additional methods for Teton + cGetVirtualAccessibleNamePackage = 0x1700, + cRequestFocusPackage, + cSelectTextRangePackage, + cGetTextAttributesInRangePackage, + cGetSameTextAttributesInRangePackage, + cGetVisibleChildrenCountPackage, + cGetVisibleChildrenPackage, + cSetCaretPositionPackage, + cGetCaretLocationPackage + + + } PackageType; + + + /** + * Union of all package contents + */ + typedef union AllPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // Event contents packages + // PropertyChangePackage propertyChange; + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage getAccessibleRelationSet; + + // AccessibleHypertext + GetAccessibleHypertextPackage _getAccessibleHypertext; + ActivateAccessibleHyperlinkPackage _activateAccessibleHyperlink; + GetAccessibleHyperlinkCountPackage _getAccessibleHyperlinkCount; + GetAccessibleHypertextExtPackage _getAccessibleHypertextExt; + GetAccessibleHypertextLinkIndexPackage _getAccessibleHypertextLinkIndex; + GetAccessibleHyperlinkPackage _getAccessibleHyperlink; + + // Accessible KeyBinding, Icon and Action + GetAccessibleKeyBindingsPackage getAccessibleKeyBindings; + GetAccessibleIconsPackage getAccessibleIcons; + GetAccessibleActionsPackage getAccessibleActions; + DoAccessibleActionsPackage doAccessibleActions; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + } AllPackages; + + + /** + * Union of all Java-initiated package contents + */ + typedef union JavaInitiatedPackagesTag { + + // Initial Rendezvous packages + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + + // Event contents packages + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + } JavaInitiatedPackages; + + + /** + * Union of all Windows-initiated package contents + */ + typedef union WindowsInitiatedPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // AccessibleTable + GetAccessibleTableInfoPackage _getAccessibleTableInfo; + GetAccessibleTableCellInfoPackage _getAccessibleTableCellInfo; + + GetAccessibleTableRowHeaderPackage _getAccessibleTableRowHeader; + GetAccessibleTableColumnHeaderPackage _getAccessibleTableColumnHeader; + + GetAccessibleTableRowDescriptionPackage _getAccessibleTableRowDescription; + GetAccessibleTableColumnDescriptionPackage _getAccessibleTableColumnDescription; + + GetAccessibleTableRowSelectionCountPackage _getAccessibleTableRowSelectionCount; + IsAccessibleTableRowSelectedPackage _isAccessibleTableRowSelected; + GetAccessibleTableRowSelectionsPackage _getAccessibleTableRowSelections; + + GetAccessibleTableColumnSelectionCountPackage _getAccessibleTableColumnSelectionCount; + IsAccessibleTableColumnSelectedPackage _isAccessibleTableColumnSelected; + GetAccessibleTableColumnSelectionsPackage _getAccessibleTableColumnSelections; + + GetAccessibleTableRowPackage _getAccessibleTableRow; + GetAccessibleTableColumnPackage _getAccessibleTableColumn; + GetAccessibleTableIndexPackage _getAccessibleTableIndex; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage _getAccessibleRelationSet; + + // Accessible KeyBindings, Icons and Actions + GetAccessibleKeyBindingsPackage _getAccessibleKeyBindings; + GetAccessibleIconsPackage _getAccessibleIcons; + GetAccessibleActionsPackage _getAccessibleActions; + DoAccessibleActionsPackage _doAccessibleActions; + + + IsSameObjectPackage _isSameObject; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + + } WindowsInitiatedPackages; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/demos/java/jni/gs_jni/include/win32/jawt_md.h b/demos/java/jni/gs_jni/include/win32/jawt_md.h new file mode 100644 index 00000000..66e7256a --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/jawt_md.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JAVASOFT_JAWT_MD_H_ +#define _JAVASOFT_JAWT_MD_H_ + +#include +#include "jawt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Win32-specific declarations for AWT native interface. + * See notes in jawt.h for an example of use. + */ +typedef struct jawt_Win32DrawingSurfaceInfo { + /* Native window, DDB, or DIB handle */ + union { + HWND hwnd; + HBITMAP hbitmap; + void* pbits; + }; + /* + * This HDC should always be used instead of the HDC returned from + * BeginPaint() or any calls to GetDC(). + */ + HDC hdc; + HPALETTE hpalette; +} JAWT_Win32DrawingSurfaceInfo; + +#ifdef __cplusplus +} +#endif + +#endif /* !_JAVASOFT_JAWT_MD_H_ */ diff --git a/demos/java/jni/gs_jni/include/win32/jni_md.h b/demos/java/jni/gs_jni/include/win32/jni_md.h new file mode 100644 index 00000000..38080013 --- /dev/null +++ b/demos/java/jni/gs_jni/include/win32/jni_md.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#define JNIEXPORT __declspec(dllexport) +#define JNIIMPORT __declspec(dllimport) +#define JNICALL __stdcall + +typedef long jint; +typedef __int64 jlong; +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/demos/java/jni/gs_jni/jni_util.cpp b/demos/java/jni/gs_jni/jni_util.cpp new file mode 100644 index 00000000..0a99f8bc --- /dev/null +++ b/demos/java/jni/gs_jni/jni_util.cpp @@ -0,0 +1,593 @@ +#include "jni_util.h" + +#include +#include +#include +#include + +using namespace util; + +jfieldID util::getFieldID(JNIEnv *env, jobject object, const char *field, const char *sig) +{ + if (env == NULL || object == NULL || field == NULL || sig == NULL) + return NULL; + + jclass clazz = env->GetObjectClass(object); + jfieldID fieldID = env->GetFieldID(clazz, field, sig); + if (fieldID == NULL) + { + const char *className = getClassName(env, clazz); + + const std::string full = std::string(className) + "." + field; + throwNoSuchFieldError(env, full.c_str()); + + freeClassName(className); + + return NULL; + } + + return fieldID; +} + +jmethodID util::getMethodID(JNIEnv *env, jobject object, const char *method, const char *sig) +{ + if (env == NULL || object == NULL || method == NULL || sig == NULL) + return NULL; + + jclass clazz = env->GetObjectClass(object); + + jmethodID methodID = env->GetMethodID(clazz, method, sig); + if (methodID == NULL) + { + const char *className = getClassName(env, clazz); + + const std::string full = std::string(className) + "." + method + sig; + throwNoSuchMethodError(env, full.c_str()); + + freeClassName(className); + + env->DeleteLocalRef(clazz); + return NULL; + } + + env->DeleteLocalRef(clazz); + return methodID; +} + + +void util::setByteArrayField(JNIEnv *env, jobject object, const char *field, jbyteArray value) +{ + jfieldID fieldID = getFieldID(env, object, field, "[B"); + if (fieldID == NULL) + return; + + env->SetObjectField(object, fieldID, value); +} + +void util::setByteArrayField(JNIEnv *env, jobject object, const char *field, const char *string) +{ + jsize len = (jsize)strlen(string); + jbyteArray byteArray = env->NewByteArray(len); + env->SetByteArrayRegion(byteArray, 0, len, (const signed char *)string); + setByteArrayField(env, object, field, byteArray); +} + +jbyteArray util::getByteArrayField(JNIEnv *env, jobject object, const char *field) +{ + jfieldID fieldID = getFieldID(env, object, field, "[B"); + if (fieldID == NULL) + return NULL; + + return (jbyteArray)env->GetObjectField(object, fieldID); +} + +char **util::jbyteArray2DToCharArray(JNIEnv *env, jobjectArray array) +{ + jboolean copy = false; + jsize len = env->GetArrayLength(array); + char **result = new char*[len]; + for (jsize i = 0; i < len; i++) + { + jbyteArray byteArrayObject = (jbyteArray)env->GetObjectArrayElement(array, i); + char *elem = (char *)env->GetByteArrayElements(byteArrayObject, ©); + jsize slen = strlen(elem); + char *nstring = new char[slen + 1LL]; + nstring[slen] = 0; + memcpy(nstring, elem, slen); + result[i] = nstring; + } + return result; +} + +void util::delete2DByteArray(int count, char **array) +{ + for (int i = 0; i < count; i++) + { + delete[] array[i]; + array[i] = NULL; + } + delete[] array; +} + +void util::setLongField(JNIEnv *env, jobject object, const char *field, jlong value) +{ + jfieldID fieldID = getFieldID(env, object, field, "J"); + if (fieldID == NULL) + return; + + env->SetLongField(object, fieldID, value); +} + +jlong util::getLongField(JNIEnv *env, jobject object, const char *field) +{ + jfieldID fieldID = getFieldID(env, object, field, "J"); + if (fieldID == NULL) + return 0LL; + + return env->GetLongField(object, fieldID); +} + +void util::setIntField(JNIEnv *env, jobject object, const char *field, jint value) +{ + jfieldID fieldID = getFieldID(env, object, field, "I"); + if (fieldID == NULL) + return; + + env->SetIntField(object, fieldID, value); +} + +jint util::getIntField(JNIEnv *env, jobject object, const char *field) +{ + jfieldID fieldID = getFieldID(env, object, field, "I"); + if (fieldID == NULL) + return 0; + + return env->GetIntField(object, fieldID); +} + +int util::callIntMethod(JNIEnv *env, jobject object, const char *method, const char *sig, ...) +{ + jmethodID methodID = getMethodID(env, object, method, sig); + if (methodID == NULL) + return 0; + + va_list args; + int result; + va_start(args, sig); + result = env->CallIntMethodV(object, methodID, args); + va_end(args); + + return result; +} + +void util::setObjectField(JNIEnv *env, jobject object, const char *field, jobject value) +{ + jfieldID fieldID = getFieldID(env, object, field, "Ljava/lang/Object;"); + if (fieldID == NULL) + return; + + env->SetObjectField(object, fieldID, value); +} + +jobject util::getObjectField(JNIEnv *env, jobject object, const char *field) +{ + + jfieldID fieldID = getFieldID(env, object, field, "Ljava/lang/Object;"); + if (fieldID == NULL) + return 0; + + return env->GetObjectField(object, fieldID); +} + +jobject util::toWrapperType(JNIEnv *env, jboolean value) +{ + jclass clazz; + static const char *const className = "java/lang/Boolean"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(Z)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jbyte value) +{ + jclass clazz; + static const char *const className = "java/lang/Byte"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(Z)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jchar value) +{ + jclass clazz; + static const char *const className = "java/lang/Character"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(C)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jshort value) +{ + jclass clazz; + static const char *const className = "java/lang/Short"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(S)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jint value) +{ + jclass clazz; + static const char *const className = "java/lang/Integer"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(I)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jlong value) +{ + jclass clazz; + static const char *const className = "java/lang/Long"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(J)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jfloat value) +{ + jclass clazz; + static const char *const className = "java/lang/Float"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(F)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jobject util::toWrapperType(JNIEnv *env, jdouble value) +{ + jclass clazz; + static const char *const className = "java/lang/Double"; + clazz = env->FindClass(className); + if (!clazz) + { + throwNoClassDefError(env, className); + return NULL; + } + jmethodID methodID = env->GetMethodID(clazz, "", "(D)V"); + jobject result = env->NewObject(clazz, methodID, value); + return result; +} + +jboolean util::toBoolean(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jboolean on NULL jobject"); + return JNI_FALSE; + } + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "Z"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetBooleanField(wrapped, fieldID); +} + +jbyte util::toByte(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jbyte on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "B"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetByteField(wrapped, fieldID); +} + +jchar util::toChar(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jchar on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "C"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetCharField(wrapped, fieldID); +} + +jshort util::toShort(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jshort on NULL jobject"); + return 0; + } + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "S"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetShortField(wrapped, fieldID); +} + +jint util::toInt(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jint on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "I"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetIntField(wrapped, fieldID); +} + +jlong util::toLong(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jlong on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "J"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetLongField(wrapped, fieldID); +} + +jfloat util::toFloat(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jfloat on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "F"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetFloatField(wrapped, fieldID); +} + +jdouble util::toDouble(JNIEnv *env, jobject wrapped) +{ + if (!wrapped) + { + throwNullPointerException(env, "attempting to get wrapped jdouble on NULL jobject"); + return 0; + } + + jclass clazz = env->GetObjectClass(wrapped); + jfieldID fieldID = env->GetFieldID(clazz, "value", "D"); + if (fieldID == NULL) + { + throwNoSuchFieldError(env, "value"); + return 0; + } + return env->GetDoubleField(wrapped, fieldID); +} + +jint util::throwNoClassDefError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NoClassDefFoundError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + throw std::exception("Failed to find java.lang.NoClassDefFoundError"); + + return env->ThrowNew(exClass, message); +} + +jint util::throwNullPointerException(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NullPointerException"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwNoSuchMethodError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NoSuchMethodError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwNoSuchFieldError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/NoSuchFieldError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwAllocationError(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "com/artifex/gsjava/util/AllocationError"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +jint util::throwIllegalArgumentException(JNIEnv *env, const char *message) +{ + if (env == NULL) + return -1; + + jclass exClass; + static const char *const className = "java/lang/IllegalArgumentException"; + + exClass = env->FindClass(className); + if (exClass == NULL) + return throwNoClassDefError(env, className); + + return env->ThrowNew(exClass, message); +} + +const char *util::getClassName(JNIEnv *env, jclass clazz) +{ + jclass clsClazz = env->GetObjectClass(clazz); + + jmethodID methodId = env->GetMethodID(clsClazz, "getName", "()Ljava/lang/String;"); + jstring className = (jstring)env->CallObjectMethod(clazz, methodId); + const char *chars = env->GetStringUTFChars(className, NULL); + jsize len = env->GetStringLength(className); + char *cstr = new char[len + 1LL]; + if (cstr == NULL) + { + env->ReleaseStringUTFChars(className, chars); + env->DeleteLocalRef(className); + return NULL; + } + cstr[len] = 0; + memcpy(cstr, chars, len); + env->ReleaseStringUTFChars(className, chars); + env->DeleteLocalRef(className); + return cstr; +} + +void util::freeClassName(const char *className) +{ + delete[] className; +} + +util::Reference::Reference(JNIEnv *env) : Reference(m_env, NULL) +{ +} + +util::Reference::Reference(JNIEnv *env, jobject object) : m_env(env), m_object(NULL) +{ + if (!object) + { + static const char *const CLASS_NAME = "com/artifex/gsjava/util/Reference"; + jclass refClass = env->FindClass(CLASS_NAME); + if (refClass == NULL) + { + throwNoClassDefError(env, CLASS_NAME); + return; + } + jmethodID constructor = env->GetMethodID(refClass, "", "()V"); + if (constructor == NULL) + { + throwNoSuchMethodError(env, "com/artifex/gsjava/util/Reference.()V"); + return; + } + object = m_env->NewObject(refClass, constructor); + if (object == NULL) + return; + } + m_object = m_env->NewGlobalRef(object); +} + +util::Reference::~Reference() +{ + if (m_object) + m_env->DeleteGlobalRef(m_object); +} diff --git a/demos/java/jni/gs_jni/jni_util.h b/demos/java/jni/gs_jni/jni_util.h new file mode 100644 index 00000000..6439712e --- /dev/null +++ b/demos/java/jni/gs_jni/jni_util.h @@ -0,0 +1,377 @@ +#pragma once + +#include + +#define REFERENCE_VALUE_FILED_NAME "value" + +namespace util +{ + + typedef class Reference Reference; + typedef class LongReference LongReference; + typedef class IntReference IntReference; + typedef class ByteArrayReference ByteArrayReference; + + /*! + Returns the field ID of a field inside an object, checking if it exists and ensuring + all arguments are non-null. If the field is not found, the Java exception NoSuchFieldError + will be thrown and NULL will be returned. + + @param env A JNIEnv. + @param object The object to find the field in. + @param field The name of the field. + @param sig The field's signature. + + @return The field ID, or NULL if the field is not found, or any argument is NULL. + */ + jfieldID getFieldID(JNIEnv *env, jobject object, const char *field, const char *sig); + + /*! + Returns the method ID of a method inside an object, checking if it exists and ensuring + all arguments are non-null. If the method is not found, the Java exception NoSuchMethodError + will be thrown and NULL will be returned. + + @param env A JNIEnv. + @param object The object to find the method in. + @param method The name of the method. + @param sig The method's signature. + + @return The method ID, or NULL if the method is not found, or any argument is NULL. + */ + jmethodID getMethodID(JNIEnv *env, jobject object, const char *method, const char *sig); + + /*! + Sets a byte array field of an object. + + @param env A JNIEnv. + @param object The object containing a byte array field. + @param field The name of the field to set. + @param value The value to set the field to. + */ + void setByteArrayField(JNIEnv *env, jobject object, const char *field, jbyteArray value); + + /*! + Sets a byte array field of an object. + + @param env A JNIEnv. + @param object The object containing a byte array field. + @param field The name of the field to set. + @param string The value to set the field to. + */ + void setByteArrayField(JNIEnv *env, jobject object, const char *field, const char *string); + + /*! + Returns the value of a byte array field in an object. + + @param env A JNIEnv. + @param object The object to get the byte array field from. + @param field The name of the field. + + @return The value of the field. + */ + jbyteArray getByteArrayField(JNIEnv *env, jobject object, const char *field); + + /*! + Converts a 2D Java byte array to a 2D C++ char array. The returned + value should be used in delete2DByteArray() when finished. + + @param env A JNIEnv. + @param array The array to convert. + + @return The 2D C++ char array. + */ + char **jbyteArray2DToCharArray(JNIEnv *env, jobjectArray array); + + /*! + Deletes a 2D C++ char array allocated from jbyteArray2DToCharArray(). + + @param count The size of the array. + @param array The array to delete. + */ + void delete2DByteArray(int count, char **array); + + /*! + Sets a long field of an object. + + @param env A JNIEnv. + @param object The object containing a long field. + @param field The name of the field to set. + @param value The value to set the field to. + */ + void setLongField(JNIEnv *env, jobject object, const char *field, jlong value); + + /*! + Returns the value of a long field in an object. + + @param env A JNIEnv. + @param object The object to get the long field from. + @param field The name of the long field. + + @return The value of the long field. + */ + jlong getLongField(JNIEnv *env, jobject object, const char *field); + + /*! + Sets a int field of an object. + + @param env A JNIEnv. + @param object The object containing a int field. + @param field The name of the field to set. + @param value The value to set the field to. + */ + void setIntField(JNIEnv *env, jobject object, const char *field, jint value); + + /*! + Returns the value of a int field in an object. + + @param env A JNIEnv. + @param object The object to get the int field from. + @param field The name of the int field. + + @return The value of the int field. + */ + jint getIntField(JNIEnv *env, jobject object, const char *field); + + /*! + Calls a Java method returning an int. + + @param env A JNIEnv. + @param object The object containing the int method. + @param name The name of the method. + @param sig The method's signature. + @param ... The varargs representing the object's arguments in their respective order. + */ + int callIntMethod(JNIEnv *env, jobject object, const char *name, const char *sig, ...); + + void setObjectField(JNIEnv *env, jobject object, const char *field, jobject value); + + jobject getObjectField(JNIEnv *env, jobject object, const char *field); + + jobject toWrapperType(JNIEnv *env, jboolean value); + jobject toWrapperType(JNIEnv *env, jbyte value); + jobject toWrapperType(JNIEnv *env, jchar value); + jobject toWrapperType(JNIEnv *env, jshort value); + jobject toWrapperType(JNIEnv *env, jint value); + jobject toWrapperType(JNIEnv *env, jlong value); + jobject toWrapperType(JNIEnv *env, jfloat value); + jobject toWrapperType(JNIEnv *env, jdouble value); + + jboolean toBoolean(JNIEnv *env, jobject wrapped); + jbyte toByte(JNIEnv *env, jobject wrapped); + jchar toChar(JNIEnv *env, jobject wrapped); + jshort toShort(JNIEnv *env, jobject wrapped); + jint toInt(JNIEnv *env, jobject wrapped); + jlong toLong(JNIEnv *env, jobject wrapped); + jfloat toFloat(JNIEnv *env, jobject wrapped); + jdouble toDouble(JNIEnv *env, jobject wrapped); + + /*! + Throws the Java exception java.lang.NoClassDefFoundError with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the error. + + @return The result of throwing the error. + */ + jint throwNoClassDefError(JNIEnv *env, const char *message); + + /*! + Throws the Java exception java.lang.NullPointerException with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwNullPointerException(JNIEnv *env, const char *message); + + /*! + Throws the Java exception java.lang.NoSuchMethodError with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwNoSuchMethodError(JNIEnv *env, const char *message); + + /*! + Throws the Java exception java.lang.NoSuchFieldError with a message. The function + calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwNoSuchFieldError(JNIEnv *env, const char *message); + + /*! + Throws the Java exception com.artifex.gsjava.util.AllocationError with a message. + The function calling this function should immediately return after calling this function. + + @param env A JNIEnv. + @param message The message of the exception. + + @return The result of throwing the exception. + */ + jint throwAllocationError(JNIEnv *env, const char *message); + + jint throwIllegalArgumentException(JNIEnv *env, const char *message); + + /*! + Returns the name of a jclass. The name is dynamically allocated and after usage, + freeClassName() should be called. + + @param env A JNIEnv. + @param clazz A jclass. + + @return The name of the class, or NULL if env or clazz are NULL. + */ + const char *getClassName(JNIEnv *env, jclass clazz); + + /*! + Frees a class name generated from getClassName(). + + @param className The className generated from getClassName(). + */ + void freeClassName(const char *className); + + class Reference + { + public: + + static inline void setValueField(JNIEnv *env, jobject object, jobject value) + { + setObjectField(env, object, "value", value); + } + + static inline jobject getValueField(JNIEnv *env, jobject object) + { + return getObjectField(env, object, "value"); + } + + private: + JNIEnv *m_env; + jobject m_object; + public: + /*! + Creates a new reference. + + @param env A JNIEnv. + */ + Reference(JNIEnv *env); + + /*! + Creates a new reference. + + @param env A JNIEnv. + @param object A com.artifex.gsjava.util.Reference or NULL if one + should be created. + */ + Reference(JNIEnv *env, jobject object); + ~Reference(); + + inline jobject object() + { + return m_object; + } + + inline jobject value() + { + return getValueField(m_env, m_object); + } + + inline jboolean booleanValue() + { + jobject val = value(); + return val ? toBoolean(m_env, val) : JNI_FALSE; + } + + inline jbyte byteValue() + { + jobject val = value(); + return val ? toByte(m_env, val) : 0; + } + + inline jchar charValue() + { + jobject val = value(); + return val ? toChar(m_env, val) : 0; + } + + inline jshort shortValue() + { + jobject val = value(); + return val ? toShort(m_env, val) : 0; + } + + inline jint intValue() + { + jobject val = value(); + return val ? toInt(m_env, val) : 0; + } + + inline jlong longValue() + { + jobject val = value(); + return val ? toLong(m_env, val) : 0LL; + } + + inline jfloat floatValue() + { + jobject val = value(); + return val ? toFloat(m_env, val) : 0.0f; + } + + inline jdouble doubleValue() + { + jobject val = value(); + return val ? toDouble(m_env, val) : 0.0; + } + + inline void set(jobject value) + { + setValueField(m_env, m_object, value); + } + + inline void set(jboolean value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jbyte value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jshort value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jint value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jlong value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jfloat value) + { + set(toWrapperType(m_env, value)); + } + + inline void set(jdouble value) + { + set(toWrapperType(m_env, value)); + } + }; + +} diff --git a/demos/python/gsapiwrap.py b/demos/python/gsapiwrap.py deleted file mode 100755 index 0ef0bb08..00000000 --- a/demos/python/gsapiwrap.py +++ /dev/null @@ -1,699 +0,0 @@ -#! /usr/bin/env python3 - -''' -Use Swig to build wrappers for gsapi. - -Example usage: - - Note that we use mupdf's scripts/jlib.py, and assume that there is a mupdf - checkout in the parent directory of the ghostpdl checkout - see 'import - jlib' below. - - ./toolbin/gsapiwrap.py --python -l -0 -1 -t - Build python wrapper for gsapi and run simple test. - - ./toolbin/gsapiwrap.py --csharp -l -0 -1 -t - Build C# wrapper for gsapi and run simple test. - -Args: - - -c: - Clean language-specific out-dir. - - -l: - Build libgs.so (by running make). - - -0: - Run swig to generate language-specific files. - - -1: - Generate language wrappers by compiling/linking the files generated by - -0. - - --csharp: - Generate C# wrappers (requires Mono on Linux). Should usually be first - param. - - --python - Generate Python wrappers. Should usually be first param. - - --swig - Set location of swig binary. - - -t - Run simple test of language wrappers generated by -1. - -Status: - As of 2020-05-22: - Some python wrappers seem to work ok. - - C# wrappers are not implemented for gsapi_set_poll() and - gsapi_set_stdio(). -''' - -import os -import re -import sys -import textwrap - -import jlib - - -def devpython_info(): - ''' - Use python3-config to find libpython.so and python-dev include path etc. - ''' - python_configdir = jlib.system( 'python3-config --configdir', out='return') - libpython_so = os.path.join( - python_configdir.strip(), - f'libpython{sys.version_info[0]}.{sys.version_info[1]}.so', - ) - assert os.path.isfile( libpython_so), f'cannot find libpython_so={libpython_so}' - - python_includes = jlib.system( 'python3-config --includes', out='return') - python_includes = python_includes.strip() - return python_includes, libpython_so - -def swig_version( swig='swig'): - t = jlib.system( f'{swig} -version', out='return') - m = re.search( 'SWIG Version ([0-9]+)[.]([0-9]+)[.]([0-9]+)', t) - assert m - swig_major = int( m.group(1)) - return swig_major - - -dir_ghostpdl = os.path.abspath( f'{__file__}/../../') + '/' - - -def out_dir( language): - if language == 'python': - return 'gsapiwrap/python/' - if language == 'csharp': - return 'gsapiwrap/csharp/' - assert 0 - -def out_so( language): - ''' - Returns name of .so that implements language-specific wrapper. I think - these names have to match what the language runtime requires. - - For python, Swig generates a module foo.py which does 'import _foo'. - - Similarly C# assumes a file called 'libfoo.so'. - ''' - if language == 'python': - return f'{out_dir(language)}_gsapi.so' - if language == 'csharp': - return f'{out_dir(language)}libgsapi.so' - assert 0 - -def lib_gs_info(): - return f'{dir_ghostpdl}sodebugbin/libgs.so', 'make sodebug' - return f'{dir_ghostpdl}sobin/libgs.so', 'make so' - -def lib_gs(): - ''' - Returns name of the gs shared-library. - ''' - return lib_gs_info()[0] - - -def swig_i( swig, language): - ''' - Returns text for a swig .i file for psi/iapi.h. - ''' - swig_major = swig_version( swig) - - - # We need to redeclare or wrap some functions, e.g. to add OUTPUT - # annotations. We use #define, %ignore and #undef to hide the original - # declarations in the .h file. - # - fns_redeclare = ( - 'gsapi_run_file', - 'gsapi_run_string', - 'gsapi_run_string_begin', - 'gsapi_run_string_continue', - 'gsapi_run_string_end', - 'gsapi_run_string_with_length', - 'gsapi_set_poll', - 'gsapi_set_poll_with_handle', - 'gsapi_set_stdio', - 'gsapi_set_stdio_with_handle', - 'gsapi_new_instance', - ) - - - swig_i_text = textwrap.dedent(f''' - %module(directors="1") gsapi - - %include cpointer.i - %pointer_functions(int, pint); - - // This seems to be necessary to make csharp handle OUTPUT args. - // - %include typemaps.i - - // For gsapi_init_with_args(). - %include argcargv.i - - %include cstring.i - - // Include type information in python doc strings. If we have - // swig-4, we can propogate comments from the C api instead, which - // is preferred. - // - {'%feature("autodoc", "3");' if swig_major < 4 else ''} - - %{{ - #include "psi/iapi.h" - //#include "base/gserrors.h" - - // Define wrapper functions that present a modified API that - // swig can cope with. - // - - // Swig cannot handle void** out-param. - // - static void* new_instance( void* caller_handle, int* out) - {{ - void* ret = NULL; - *out = gsapi_new_instance( &ret, caller_handle); - printf( "gsapi_new_instance() returned *out=%i ret=%p\\n", *out, ret); - fflush( stdout); - return ret; - }} - - // Swig cannot handle (const char* str, int strlen) args. - // - static int run_string_continue(void *instance, const char *str, int user_errors, int *pexit_code) {{ - - return gsapi_run_string_continue( instance, str, strlen(str), user_errors, pexit_code); - }} - %}} - - // Strip gsapi_ prefix from all generated names. - // - %rename("%(strip:[gsapi_])s") ""; - - // Tell Swig about gsapi_get_default_device_list()'s out-params, so - // it adds them to the returned object. - // - // I think the '(void) *$1' will ensure that swig code doesn't - // attempt to free() the returned string. - // - {'%cstring_output_allocate_size(char **list, int *listlen, (void) *$1);' if language == 'python' else ''} - - // Tell swig about the (argc,argv) args in gsapi_init_with_args(). - // - %apply (int ARGC, char **ARGV) {{ (int argc, char **argv) }} - - // Support for wrapping various functions that take function - // pointer args. For each, we define a wrapper function that, - // instead of having function pointer args, takes a class with - // virtual methods. This allows swig to wrap things - python/c# etc - // can create a derived class that implements these virtual methods - // in the python/c# world. - // - - // Wrap gsapi_set_stdio_with_handle(). - // - %feature("director") set_stdio_class; - - %inline {{ - struct set_stdio_class {{ - - virtual int stdin_fn( char* buf, int len) = 0; - virtual int stdout_fn( const char* buf, int len) = 0; - virtual int stderr_fn( const char* buf, int len) = 0; - - static int stdin_fn_wrap( void *caller_handle, char *buf, int len) {{ - return ((set_stdio_class*) caller_handle)->stdin_fn(buf, len); - }} - static int stdout_fn_wrap( void *caller_handle, const char *buf, int len) {{ - return ((set_stdio_class*) caller_handle)->stdout_fn(buf, len); - }} - static int stderr_fn_wrap( void *caller_handle, const char *buf, int len) {{ - return ((set_stdio_class*) caller_handle)->stderr_fn(buf, len); - }} - - virtual ~set_stdio_class() {{}} - }}; - - int set_stdio_with_class( void *instance, set_stdio_class* class_) {{ - return gsapi_set_stdio_with_handle( - instance, - set_stdio_class::stdin_fn_wrap, - set_stdio_class::stdout_fn_wrap, - set_stdio_class::stderr_fn_wrap, - (void*) class_ - ); - }} - - - }} - - // Wrap gsapi_set_poll(). - // - %feature("director") set_poll_class; - - %inline {{ - struct set_poll_class {{ - virtual int poll_fn() = 0; - - static int poll_fn_wrap( void* caller_handle) {{ - return ((set_poll_class*) caller_handle)->poll_fn(); - }} - - virtual ~set_poll_class() {{}} - }}; - - int set_poll_with_class( void* instance, set_poll_class* class_) {{ - return gsapi_set_poll_with_handle( - instance, - set_poll_class::poll_fn_wrap, - (void*) class_ - ); - }} - - }} - - // For functions that we re-declare (typically to specify OUTPUT on - // one or more args), use a macro to rename the declaration in the - // header file and tell swig to ignore these renamed declarations. - // - ''') - - for fn in fns_redeclare: - swig_i_text += f'#define {fn} {fn}0\n' - - for fn in fns_redeclare: - swig_i_text += f'%ignore {fn}0;\n' - - swig_i_text += textwrap.dedent(f''' - #include "psi/iapi.h" - //#include "base/gserrors.h" - ''') - - for fn in fns_redeclare: - swig_i_text += f'#undef {fn}\n' - - - swig_i_text += textwrap.dedent(f''' - // Tell swig about our wrappers and altered declarations. - // - - // Use swig's OUTPUT annotation for out-parameters. - // - int gsapi_run_file(void *instance, const char *file_name, int user_errors, int *OUTPUT); - int gsapi_run_string_begin(void *instance, int user_errors, int *OUTPUT); - int gsapi_run_string_end(void *instance, int user_errors, int *OUTPUT); - //int gsapi_run_string_with_length(void *instance, const char *str, unsigned int length, int user_errors, int *OUTPUT); - int gsapi_run_string(void *instance, const char *str, int user_errors, int *OUTPUT); - - // Declare functions defined above that we want swig to wrap. These - // don't have the gsapi_ prefix, so that they can internally call - // the wrapped gsapi_*() function. [We've told swig to strip the - // gsapi_ prefix on generated functions anyway, so this doesn't - // afffect the generated names.] - // - static int run_string_continue(void *instance, const char *str, int user_errors, int *OUTPUT); - static void* new_instance(void* caller_handle, int* OUTPUT); - ''') - - if language == 'python': - swig_i_text += textwrap.dedent(f''' - - // Define python code that is needed to handle functions with - // function-pointer args. - // - %pythoncode %{{ - - set_stdio_g = None - def set_stdio( instance, stdin, stdout, stderr): - class derived( set_stdio_class): - def stdin_fn( self): - return stdin() - def stdout_fn( self, text, len): - return stdout( text, len) - def stderr_fn( self, text, len): - return stderr( text) - - global set_stdio_g - set_stdio_g = derived() - return set_stdio_with_class( instance, set_stdio_g) - - set_poll_g = None - def set_poll( instance, fn): - class derived( set_poll_class): - def poll_fn( self): - return fn() - global set_poll_g - set_poll_g = derived() - return set_poll_with_class( instance, set_poll_g) - %}} - ''') - - return swig_i_text - - - -def run_swig( swig, language): - ''' - Runs swig using a generated .i file. - - The .i file modifies the gsapi API in places to allow specification of - out-parameters that swig understands - e.g. void** OUTPUT doesn't work. - ''' - os.makedirs( out_dir(language), exist_ok=True) - swig_major = swig_version( swig) - - swig_i_text = swig_i( swig, language) - swig_i_filename = f'{out_dir(language)}iapi.i' - jlib.update_file( swig_i_text, swig_i_filename) - - out_cpp = f'{out_dir(language)}gsapi.cpp' - - if language == 'python': - out_lang = f'{out_dir(language)}gsapi.py' - elif language == 'csharp': - out_lang = f'{out_dir(language)}gsapi.cs' - else: - assert 0 - - out_files = (out_cpp, out_lang) - - doxygen_arg = '' - if swig_major >= 4 and language == 'python': - doxygen_arg = '-doxygen' - - extra = '' - if language == 'csharp': - # Tell swig to put all generated csharp code into a single file. - extra = f'-outfile gsapi.cs' - - command = (textwrap.dedent(f''' - {swig} - -Wall - -c++ - -{language} - {doxygen_arg} - -module gsapi - -outdir {out_dir(language)} - -o {out_cpp} - {extra} - -includeall - -I{dir_ghostpdl} - -ignoremissing - {swig_i_filename} - ''').strip().replace( '\n', ' \\\n') - ) - - jlib.build( - (swig_i_filename,), - out_files, - command, - prefix=' ', - ) - - -def main( argv): - - swig = 'swig' - language = 'python' - - args = jlib.Args( sys.argv[1:]) - while 1: - try: - arg = args.next() - except StopIteration: - break - - if 0: - pass - - elif arg == '-c': - jlib.system( f'rm {out_dir(language)}* || true', verbose=1, prefix=' ') - - elif arg == '-l': - command = lib_gs_info()[1] - jlib.system( command, verbose=1, prefix=' ') - - elif arg == '-0': - run_swig( swig, language) - - elif arg == '-1': - - libs = [lib_gs()] - includes = [dir_ghostpdl] - file_cpp = f'{out_dir(language)}gsapi.cpp' - - if language == 'python': - python_includes, libpython_so = devpython_info() - libs.append( libpython_so) - includes.append( python_includes) - - includes_text = '' - for i in includes: - includes_text += f' -I{i}' - command = textwrap.dedent(f''' - g++ - -g - -Wall -W - -o {out_so(language)} - -fPIC - -shared - {includes_text} - {jlib.link_l_flags(libs)} - {file_cpp} - ''').strip().replace( '\n', ' \\\n') - jlib.build( - (file_cpp, lib_gs(), 'psi/iapi.h'), - (out_so(language),), - command, - prefix=' ', - ) - - elif arg == '--csharp': - language = 'csharp' - - elif arg == '--python': - language = 'python' - - elif arg == '--swig': - swig = args.next() - - elif arg == '-t': - - if language == 'python': - text = textwrap.dedent(''' - #!/usr/bin/env python3 - - import os - import sys - - import gsapi - - gsapi.gs_error_Quit = -101 - - def main(): - minst, code = gsapi.new_instance(None) - print( f'minst={minst} code={code}') - - if 1: - def stdin_local(len): - # Not sure whether this is right. - return sys.stdin.read(len) - def stdout_local(text, l): - sys.stdout.write(text[:l]) - return l - def stderr_local(text, l): - sys.stderr.write(text[:l]) - return l - gsapi.set_stdio( minst, None, stdout_local, stderr_local); - - if 1: - def poll_fn(): - return 0 - gsapi.set_poll(minst, poll_fn) - if 1: - s = 'display x11alpha x11 bbox' - gsapi.set_default_device_list( minst, s, len(s)) - - e, text = gsapi.get_default_device_list( minst) - print( f'gsapi.get_default_device_list() returned e={e} text={text!r}') - - out = 'out.pdf' - if os.path.exists( out): - os.remove( out) - assert not os.path.exists( out) - - gsargv = [''] - gsargv += f'-dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile={out} contrib/pcl3/ps/levels-test.ps'.split() - print( f'gsargv={gsargv}') - code = gsapi.set_arg_encoding(minst, gsapi.GS_ARG_ENCODING_UTF8) - if code == 0: - code = gsapi.init_with_args(minst, gsargv) - - code, exit_code = gsapi.run_string_begin( minst, 0) - print( f'gsapi.run_string_begin() returned code={code} exit_code={exit_code}') - assert code == 0 - assert exit_code == 0 - - gsapi.run_string - - code1 = gsapi.exit(minst) - if (code == 0 or code == gsapi.gs_error_Quit): - code = code1 - gsapi.delete_instance(minst) - assert os.path.isfile( out) - if code == 0 or code == gsapi.gs_error_Quit: - return 0 - return 1 - - if __name__ == '__main__': - code = main() - assert code == 0 - sys.exit( code) - ''') - text = text[1:] # skip leading \n. - test_py = f'{out_dir(language)}test.py' - jlib.update_file( text, test_py) - os.chmod( test_py, 0o744) - - jlib.system( - f'LD_LIBRARY_PATH={os.path.abspath( f"{lib_gs()}/..")}' - f' PYTHONPATH={out_dir(language)}' - f' {test_py}' - , - verbose = 1, - prefix=' ', - ) - - elif language == 'csharp': - # See: https://github.com/swig/swig/blob/master/Lib/csharp/typemaps.i - # - text = textwrap.dedent(''' - using System; - public class runme { - static void Main() { - int code; - SWIGTYPE_p_void instance; - Console.WriteLine("hello world"); - instance = gsapi.new_instance(null, out code); - Console.WriteLine("code is: " + code); - gsapi.add_control_path(instance, 0, "hello"); - } - } - ''') - test_cs = f'{out_dir(language)}test.cs' - jlib.update_file( text, test_cs) - files_in = f'{out_dir(language)}gsapi.cs', test_cs - file_out = f'{out_dir(language)}test.exe' - command = f'mono-csc -debug+ -out:{file_out} {" ".join(files_in)}' - jlib.build( files_in, (file_out,), command, prefix=' ') - - ld_library_path = f'{dir_ghostpdl}sobin' - jlib.system( f'LD_LIBRARY_PATH={ld_library_path} {file_out}', verbose=jlib.log, prefix=' ') - - elif arg == '--tt': - # small swig test case. - os.makedirs( 'swig-tt', exist_ok=True) - i = textwrap.dedent(f''' - %include cpointer.i - %include cstring.i - %feature("autodoc", "3"); - %cstring_output_allocate_size(char **list, int *listlen, (void) *$1); - %inline {{ - static inline int gsapi_get_default_device_list(void *instance, char **list, int *listlen) - {{ - *list = (char*) "hello world"; - *listlen = 6; - return 0; - }} - }} - ''') - jlib.update_file(i, 'swig-tt/tt.i') - jlib.system('swig -c++ -python -module tt -outdir swig-tt -o swig-tt/tt.cpp swig-tt/tt.i', verbose=1) - p = textwrap.dedent(f''' - #!/usr/bin/env python3 - import tt - print( tt.gsapi_get_default_device_list(None)) - ''')[1:] - jlib.update_file( p, 'swig-tt/test.py') - python_includes, python_so = devpython_info() - includes = f'-I {python_includes}' - link_flags = jlib.link_l_flags( [python_so]) - jlib.system( f'g++ -shared -fPIC {includes} {link_flags} -o swig-tt/_tt.so swig-tt/tt.cpp', verbose=1) - jlib.system( f'cd swig-tt; python3 test.py', verbose=1) - - elif arg == '-T': - # Very simple test that we can create c# wrapper for trivial code. - os.makedirs( 'swig-cs-test', exist_ok=True) - example_cpp = textwrap.dedent(''' - #include - double My_variable = 3.0; - - int fact(int n) { - if (n <= 1) return 1; - else return n*fact(n-1); - } - - int my_mod(int x, int y) { - return (x%y); - } - - char *get_time() - { - time_t ltime; - time(<ime); - return ctime(<ime); - } - ''') - jlib.update_file( example_cpp, 'swig-cs-test/example.cpp') - - example_i = textwrap.dedent(''' - %module example - %{ - /* Put header files here or function declarations like below */ - extern double My_variable; - extern int fact(int n); - extern int my_mod(int x, int y); - extern char *get_time(); - %} - - extern double My_variable; - extern int fact(int n); - extern int my_mod(int x, int y); - extern char *get_time(); - ''') - jlib.update_file( example_i, 'swig-cs-test/example.i') - - runme_cs = textwrap.dedent(''' - using System; - public class runme { - static void Main() { - Console.WriteLine(example.My_variable); - Console.WriteLine(example.fact(5)); - Console.WriteLine(example.get_time()); - } - } - ''') - jlib.update_file( runme_cs, 'swig-cs-test/runme.cs') - jlib.system( 'g++ -g -fPIC -shared -o swig-cs-test/libfoo.so swig-cs-test/example.cpp', verbose=1) - jlib.system( 'swig -c++ -csharp -module example -outdir swig-cs-test -o swig-cs-test/example_wrap.cpp -outfile example.cs swig-cs-test/example.i', verbose=1) - jlib.system( 'g++ -g -fPIC -shared -L swig-cs-test -l foo swig-cs-test/example_wrap.cpp -o swig-cs-test/libexample.so', verbose=1) - jlib.system( 'cd swig-cs-test; mono-csc -out:runme.exe example.cs runme.cs', verbose=1) - jlib.system( 'cd swig-cs-test; LD_LIBRARY_PATH=`pwd` ./runme.exe', verbose=1) - jlib.system( 'ls -l swig-cs-test', verbose=1) - - - else: - raise Exception( f'unrecognised arg: {arg}') - -if __name__ == '__main__': - try: - main( sys.argv) - except Exception as e: - jlib.exception_info( out=sys.stdout) - sys.exit(1) diff --git a/demos/python/jlib.py b/demos/python/jlib.py deleted file mode 100644 index 20506c38..00000000 --- a/demos/python/jlib.py +++ /dev/null @@ -1,1355 +0,0 @@ -from __future__ import print_function - -import codecs -import inspect -import io -import os -import shutil -import subprocess -import sys -import time -import traceback -import threading - - -def place( frame_record): - ''' - Useful debugging function - returns representation of source position of - caller. - ''' - filename = frame_record.filename - line = frame_record.lineno - function = frame_record.function - ret = os.path.split( filename)[1] + ':' + str( line) + ':' + function + ':' - if 0: - tid = str(threading.currentThread()) - ret = '[' + tid + '] ' + ret - return ret - - -def expand_nv( text, caller): - ''' - Returns with special handling of {} items. - - text: - String containing {} items. - caller: - If an int, the number of frames to step up when looking for file:line - information or evaluating expressions. - - Otherwise should be a frame record as returned by inspect.stack()[]. - - is evaluated in 's context using eval(), and expanded - to or =. - - If ends with '=', this character is removed and we prefix the - result with =. - - E.g.: - x = 45 - y = 'hello' - expand_nv( 'foo {x} {y=}') - returns: - foo 45 y=hello - - can also use ':' and '!' to control formatting, like - str.format(). - ''' - if isinstance( caller, int): - frame_record = inspect.stack()[ caller] - else: - frame_record = caller - frame = frame_record.frame - try: - def get_items(): - ''' - Yields (pre, item), where is contents of next {...} or None, - and
 is preceding text.
-            '''
-            pos = 0
-            pre = ''
-            while 1:
-                if pos == len( text):
-                    yield pre, None
-                    break
-                rest = text[ pos:]
-                if rest.startswith( '{{') or rest.startswith( '}}'):
-                    pre += rest[0]
-                    pos += 2
-                elif text[ pos] == '{':
-                    close = text.find( '}', pos)
-                    if close < 0:
-                        raise Exception( 'After "{" at offset %s, cannot find closing "}". text is: %r' % (
-                                pos, text))
-                    yield pre, text[ pos+1 : close]
-                    pre = ''
-                    pos = close + 1
-                else:
-                    pre += text[ pos]
-                    pos += 1
-
-        ret = ''
-        for pre, item in get_items():
-            ret += pre
-            nv = False
-            if item:
-                if item.endswith( '='):
-                    nv = True
-                    item = item[:-1]
-                expression, tail = split_first_of( item, '!:')
-                try:
-                    value = eval( expression, frame.f_globals, frame.f_locals)
-                    value_text = ('{0%s}' % tail).format( value)
-                except Exception as e:
-                    value_text = '{??Failed to evaluate %r in context %s:%s because: %s??}' % (
-                            expression,
-                            frame_record.filename,
-                            frame_record.lineno,
-                            e,
-                            )
-                if nv:
-                    ret += '%s=' % expression
-                ret += value_text
-
-        return ret
-
-    finally:
-        del frame
-
-
-class LogPrefixTime:
-    def __init__( self, date=False, time_=True, elapsed=False):
-        self.date = date
-        self.time = time_
-        self.elapsed = elapsed
-        self.t0 = time.time()
-    def __call__( self):
-        ret = ''
-        if self.date:
-            ret += time.strftime( ' %F')
-        if self.time:
-            ret += time.strftime( ' %T')
-        if self.elapsed:
-            ret += ' (+%s)' % time_duration( time.time() - self.t0, s_format='%.1f')
-        if ret:
-            ret = ret.strip() + ': '
-        return ret
-
-class LogPrefixFileLine:
-    def __call__( self, caller):
-        if isinstance( caller, int):
-            caller = inspect.stack()[ caller]
-        return place( caller) + ' '
-
-class LogPrefixScopes:
-    '''
-    Internal use only.
-    '''
-    def __init__( self):
-        self.items = []
-    def __call__( self):
-        ret = ''
-        for item in self.items:
-            if callable( item):
-                item = item()
-            ret += item
-        return ret
-
-
-class LogPrefixScope:
-    '''
-    Can be used to insert scoped prefix to log output.
-    '''
-    def __init__( self, prefix):
-        g_log_prefixe_scopes.items.append( prefix)
-    def __enter__( self):
-        pass
-    def __exit__( self, exc_type, exc_value, traceback):
-        global g_log_prefix
-        g_log_prefixe_scopes.items.pop()
-
-
-g_log_delta = 0
-
-class LogDeltaScope:
-    '''
-    Can be used to temporarily change verbose level of logging.
-
-    E.g to temporarily increase logging:
-
-        with jlib.LogDeltaScope(-1):
-            ...
-    '''
-    def __init__( self, delta):
-        self.delta = delta
-        global g_log_delta
-        g_log_delta += self.delta
-    def __enter__( self):
-        pass
-    def __exit__( self, exc_type, exc_value, traceback):
-        global g_log_delta
-        g_log_delta -= self.delta
-
-# Special item that can be inserted into  to enable
-# temporary addition of text into log prefixes.
-#
-g_log_prefixe_scopes = LogPrefixScopes()
-
-# List of items that form prefix for all output from log().
-#
-g_log_prefixes = []
-
-
-def log_text( text=None, caller=1, nv=True):
-    '''
-    Returns log text, prepending all lines with text from g_log_prefixes.
-
-    text:
-        The text to output. Each line is prepended with prefix text.
-    caller:
-        If an int, the number of frames to step up when looking for file:line
-        information or evaluating expressions.
-
-        Otherwise should be a frame record as returned by inspect.stack()[].
-    nv:
-        If true, we expand {...} in  using expand_nv().
-    '''
-    if isinstance( caller, int):
-        caller += 1
-    prefix = ''
-    for p in g_log_prefixes:
-        if callable( p):
-            if isinstance( p, LogPrefixFileLine):
-                p = p(caller)
-            else:
-                p = p()
-        prefix += p
-
-    if text is None:
-        return prefix
-
-    if nv:
-        text = expand_nv( text, caller)
-
-    if text.endswith( '\n'):
-        text = text[:-1]
-    lines = text.split( '\n')
-
-    text = ''
-    for line in lines:
-        text += prefix + line + '\n'
-    return text
-
-
-
-s_log_levels_cache = dict()
-s_log_levels_items = []
-
-def log_levels_find( caller):
-    if not s_log_levels_items:
-        return 0
-
-    tb = traceback.extract_stack( None, 1+caller)
-    if len(tb) == 0:
-        return 0
-    filename, line, function, text = tb[0]
-
-    key = function, filename, line,
-    delta = s_log_levels_cache.get( key)
-
-    if delta is None:
-        # Calculate and populate cache.
-        delta = 0
-        for item_function, item_filename, item_delta in s_log_levels_items:
-            if item_function and not function.startswith( item_function):
-                continue
-            if item_filename and not filename.startswith( item_filename):
-                continue
-            delta = item_delta
-            break
-
-        s_log_levels_cache[ key] = delta
-
-    return delta
-
-
-def log_levels_add( delta, filename_prefix, function_prefix):
-    '''
-    log() calls from locations with filenames starting with 
-    and/or function names starting with  will have 
-    added to their level.
-
-    Use -ve delta to increase verbosity from particular filename or function
-    prefixes.
-    '''
-    log( 'adding level: {filename_prefix=!r} {function_prefix=!r}')
-
-    # Sort in reverse order so that long functions and filename specs come
-    # first.
-    #
-    s_log_levels_items.append( (function_prefix, filename_prefix, delta))
-    s_log_levels_items.sort( reverse=True)
-
-
-def log( text, level=0, caller=1, nv=True, out=None):
-    '''
-    Writes log text, with special handling of {} items in 
-    similar to python3's f-strings.
-
-    text:
-        The text to output.
-    caller:
-        How many frames to step up to get caller's context when evaluating
-        file:line information and/or expressions. Or frame record as returned
-        by inspect.stack()[].
-    nv:
-        If true, we expand {...} in  using expand_nv().
-    out:
-        Where to send output. If None we use sys.stdout.
-
-     is evaluated in our caller's context ( stack frames up)
-    using eval(), and expanded to  or =.
-
-    If  ends with '=', this character is removed and we prefix the
-    result with =.
-
-    E.g.:
-        x = 45
-        y = 'hello'
-        expand_nv( 'foo {x} {y=}')
-    returns:
-        foo 45 y=hello
-
-     can also use ':' and '!' to control formatting, like
-    str.format().
-    '''
-    if out is None:
-        out = sys.stdout
-    level += g_log_delta
-    if isinstance( caller, int):
-        caller += 1
-    level += log_levels_find( caller)
-    if level <= 0:
-        text = log_text( text, caller, nv=nv)
-        out.write( text)
-        out.flush()
-
-
-def log0( text, caller=1, nv=True, out=None):
-    '''
-    Most verbose log. Same as log().
-    '''
-    log( text, level=0, caller=caller+1, nv=nv, out=out)
-
-def log1( text, caller=1, nv=True, out=None):
-    log( text, level=1, caller=caller+1, nv=nv, out=out)
-
-def log2( text, caller=1, nv=True, out=None):
-    log( text, level=2, caller=caller+1, nv=nv, out=out)
-
-def log3( text, caller=1, nv=True, out=None):
-    log( text, level=3, caller=caller+1, nv=nv, out=out)
-
-def log4( text, caller=1, nv=True, out=None):
-    log( text, level=4, caller=caller+1, nv=nv, out=out)
-
-def log5( text, caller=1, nv=True, out=None):
-    '''
-    Least verbose log.
-    '''
-    log( text, level=5, caller=caller+1, nv=nv, out=out)
-
-def logx( text, caller=1, nv=True, out=None):
-    '''
-    Does nothing, useful when commenting out a log().
-    '''
-    pass
-
-
-def log_levels_add_env( name='JLIB_log_levels'):
-    '''
-    Added log levels encoded in an environmental variable.
-    '''
-    t = os.environ.get( name)
-    if t:
-        for ffll in t.split( ','):
-            ffl, delta = ffll.split( '=', 1)
-            delta = int( delta)
-            ffl = ffl.split( ':')
-            if 0:
-                pass
-            elif len( ffl) == 1:
-                filename = ffl
-                function = None
-            elif len( ffl) == 2:
-                filename, function = ffl
-            else:
-                assert 0
-            log_levels_add( delta, filename, function)
-
-
-def strpbrk( text, substrings):
-    '''
-    Finds first occurrence of any item in  in .
-
-    Returns (pos, substring) or (len(text), None) if not found.
-    '''
-    ret_pos = len( text)
-    ret_substring = None
-    for substring in substrings:
-        pos = text.find( substring)
-        if pos >= 0 and pos < ret_pos:
-            ret_pos = pos
-            ret_substring = substring
-    return ret_pos, ret_substring
-
-
-def split_first_of( text, substrings):
-    '''
-    Returns (pre, post), where 
 doesn't contain any item in 
-    and  is empty or starts with an item in .
-    '''
-    pos, _ = strpbrk( text, substrings)
-    return text[ :pos], text[ pos:]
-
-
-
-log_levels_add_env()
-
-
-def force_line_buffering():
-    '''
-    Ensure sys.stdout and sys.stderr are line-buffered. E.g. makes things work
-    better if output is piped to a file via 'tee'.
-
-    Returns original out,err streams.
-    '''
-    stdout0 = sys.stdout
-    stderr0 = sys.stderr
-    sys.stdout = os.fdopen( os.dup( sys.stdout.fileno()), 'w', 1)
-    sys.stderr = os.fdopen( os.dup( sys.stderr.fileno()), 'w', 1)
-    return stdout0, stderr0
-
-
-def exception_info( exception=None, limit=None, out=None, prefix='', oneline=False):
-    '''
-    General replacement for traceback.* functions that print/return information
-    about exceptions. This function provides a simple way of getting the
-    functionality provided by these traceback functions:
-
-        traceback.format_exc()
-        traceback.format_exception()
-        traceback.print_exc()
-        traceback.print_exception()
-
-    Returns:
-        A string containing description of specified exception and backtrace.
-
-    Inclusion of outer frames:
-        We improve upon traceback.* in that we also include stack frames above
-        the point at which an exception was caught - frames from the top-level
-         or thread creation fn to the try..catch block, which makes
-        backtraces much more useful.
-
-        Google 'sys.exc_info backtrace incomplete' for more details.
-
-        We deliberately leave a slightly curious pair of items in the backtrace
-        - the point in the try: block that ended up raising an exception, and
-        the point in the associated except: block from which we were called.
-
-        For clarity, we insert an empty frame in-between these two items, so
-        that one can easily distinguish the two parts of the backtrace.
-
-        So the backtrace looks like this:
-
-            root (e.g.  or /usr/lib/python2.7/threading.py:778:__bootstrap():
-            ...
-            file:line in the except: block where the exception was caught.
-            ::(): marker
-            file:line in the try: block.
-            ...
-            file:line where the exception was raised.
-
-        The items after the ::(): marker are the usual items that traceback.*
-        shows for an exception.
-
-    Also the backtraces that are generated are more concise than those provided
-    by traceback.* - just one line per frame instead of two - and filenames are
-    output relative to the current directory if applicatble. And one can easily
-    prefix all lines with a specified string, e.g. to indent the text.
-
-    Returns a string containing backtrace and exception information, and sends
-    returned string to  if specified.
-
-    exception:
-        None, or a (type, value, traceback) tuple, e.g. from sys.exc_info(). If
-        None, we call sys.exc_info() and use its return value.
-    limit:
-        None or maximum number of stackframes to output.
-    out:
-        None or callable taking single  parameter or object with a
-        'write' member that takes a single  parameter.
-    prefix:
-        Used to prefix all lines of text.
-    '''
-    if exception is None:
-        exception = sys.exc_info()
-    etype, value, tb = exception
-
-    if sys.version_info[0] == 2:
-        out2 = io.BytesIO()
-    else:
-        out2 = io.StringIO()
-    try:
-
-        frames = []
-
-        # Get frames above point at which exception was caught - frames
-        # starting at top-level  or thread creation fn, and ending
-        # at the point in the catch: block from which we were called.
-        #
-        # These frames are not included explicitly in sys.exc_info()[2] and are
-        # also omitted by traceback.* functions, which makes for incomplete
-        # backtraces that miss much useful information.
-        #
-        for f in reversed(inspect.getouterframes(tb.tb_frame)):
-            ff = f[1], f[2], f[3], f[4][0].strip()
-            frames.append(ff)
-
-        if 1:
-            # It's useful to see boundary between upper and lower frames.
-            frames.append( None)
-
-        # Append frames from point in the try: block that caused the exception
-        # to be raised, to the point at which the exception was thrown.
-        #
-        # [One can get similar information using traceback.extract_tb(tb):
-        #   for f in traceback.extract_tb(tb):
-        #       frames.append(f)
-        # ]
-        for f in inspect.getinnerframes(tb):
-            ff = f[1], f[2], f[3], f[4][0].strip()
-            frames.append(ff)
-
-        cwd = os.getcwd() + os.sep
-        if oneline:
-            if etype and value:
-                # The 'exception_text' variable below will usually be assigned
-                # something like ': ', unless
-                # there was no explanatory text provided (e.g. "raise Exception()").
-                # In this case, str(value) will evaluate to ''.
-                exception_text = traceback.format_exception_only(etype, value)[0].strip()
-                filename, line, fnname, text = frames[-1]
-                if filename.startswith(cwd):
-                    filename = filename[len(cwd):]
-                if not str(value):
-                    # The exception doesn't have any useful explanatory text
-                    # (for example, maybe it was raised by an expression like
-                    # "assert " without a subsequent comma).  In
-                    # the absence of anything more helpful, print the code that
-                    # raised the exception.
-                    exception_text += ' (%s)' % text
-                line = '%s%s at %s:%s:%s()' % (prefix, exception_text, filename, line, fnname)
-                out2.write(line)
-        else:
-            out2.write( '%sBacktrace:\n' % prefix)
-            for frame in frames:
-                if frame is None:
-                    out2.write( '%s    ^except raise:\n' % prefix)
-                    continue
-                filename, line, fnname, text = frame
-                if filename.startswith( cwd):
-                    filename = filename[ len(cwd):]
-                if filename.startswith( './'):
-                    filename = filename[ 2:]
-                out2.write( '%s    %s:%s:%s(): %s\n' % (
-                        prefix, filename, line, fnname, text))
-
-            if etype and value:
-                out2.write( '%sException:\n' % prefix)
-                lines = traceback.format_exception_only( etype, value)
-                for line in lines:
-                    out2.write( '%s    %s' % ( prefix, line))
-
-        text = out2.getvalue()
-
-        # Write text to  if specified.
-        out = getattr( out, 'write', out)
-        if callable( out):
-            out( text)
-        return text
-
-    finally:
-        # clear things to avoid cycles.
-        exception = None
-        etype = None
-        value = None
-        tb = None
-        frames = None
-
-
-def number_sep( s):
-    '''
-    Simple number formatter, adds commas in-between thousands.  can
-    be a number or a string. Returns a string.
-    '''
-    if not isinstance( s, str):
-        s = str( s)
-    c = s.find( '.')
-    if c==-1:   c = len(s)
-    end = s.find('e')
-    if end == -1:   end = s.find('E')
-    if end == -1:   end = len(s)
-    ret = ''
-    for i in range( end):
-        ret += s[i]
-        if ic and i interval or override:
-        debug_periodic_t0[0] = t
-        debug(text)
-
-
-def time_duration( seconds, verbose=False, s_format='%i'):
-    '''
-    Returns string expressing an interval.
-
-    seconds:
-        The duration in seconds
-    verbose:
-        If true, return like '4 days 1 hour 2 mins 23 secs', otherwise as
-        '4d3h2m23s'.
-    s_format:
-        If specified, use as printf-style format string for seconds.
-    '''
-    x = abs(seconds)
-    ret = ''
-    i = 0
-    for div, text in [
-            ( 60, 'sec'),
-            ( 60, 'min'),
-            ( 24, 'hour'),
-            ( None, 'day'),
-            ]:
-        force = ( x == 0 and i == 0)
-        if div:
-            remainder = x % div
-            x = int( x/div)
-        else:
-            remainder = x
-        if not verbose:
-            text = text[0]
-        if remainder or force:
-            if verbose and remainder > 1:
-                # plural.
-                text += 's'
-            if verbose:
-                text = ' %s ' % text
-            if i == 0:
-                remainder = s_format % remainder
-            ret = '%s%s%s' % ( remainder, text, ret)
-        i += 1
-    ret = ret.strip()
-    if ret == '':
-        ret = '0s'
-    if seconds < 0:
-        ret = '-%s' % ret
-    return ret
-
-assert time_duration( 303333) == '3d12h15m33s'
-assert time_duration( 303333.33, s_format='%.1f') == '3d12h15m33.3s'
-assert time_duration( 303333, verbose=True) == '3 days 12 hours 15 mins 33 secs'
-assert time_duration( 303333.33, verbose=True, s_format='%.1f') == '3 days 12 hours 15 mins 33.3 secs'
-
-assert time_duration( 0) == '0s'
-assert time_duration( 0, verbose=True) == '0 sec'
-
-
-def date_time( t=None):
-    if t is None:
-        t = time.time()
-    return time.strftime( "%F-%T", time.gmtime( t))
-
-def stream_prefix_time( stream):
-    '''
-    Returns StreamPrefix that prefixes lines with time and elapsed time.
-    '''
-    t_start = time.time()
-    def prefix_time():
-        return '%s (+%s): ' % (
-                time.strftime( '%T'),
-                time_duration( time.time() - t_start, s_format='0.1f'),
-                )
-    return StreamPrefix( stream, prefix_time)
-
-def stdout_prefix_time():
-    '''
-    Changes sys.stdout to prefix time and elapsed time; returns original
-    sys.stdout.
-    '''
-    ret = sys.stdout
-    sys.stdout = stream_prefix_time( sys.stdout)
-    return ret
-
-
-def make_stream( out):
-    '''
-    If  already has a .write() member, returns .
-
-    Otherwise a stream-like object with a .write() method that writes to .
-
-    out:
-        Where output is sent.
-        If None, output is lost.
-        Otherwise if an integer, we do: os.write( out, text)
-        Otherwise if callable, we do: out( text)
-        Otherwise we assume  is python stream or similar already.
-    '''
-    if getattr( out, 'write', None):
-        return out
-    class Ret:
-        def flush():
-            pass
-    ret = Ret()
-    if out is None:
-        ret.write = lambda text: None
-    elif isinstance( out, int):
-        ret.write = lambda text: os.write( out, text)
-    elif callable( out):
-        ret.write = out
-    else:
-        ret.write = lambda text: out.write( text)
-    return ret
-
-
-def system_raw(
-        command,
-        out=None,
-        shell=True,
-        encoding='latin_1',
-        errors='strict',
-        buffer_len=-1,
-        ):
-    '''
-    Runs command, writing output to  which can be an int fd, a python
-    stream or a Stream object.
-
-    Args:
-        command:
-            The command to run.
-        out:
-            Where output is sent.
-            If None, output is lost.
-            If -1, output is sent to stdout and stderr.
-            Otherwise if an integer, we do: os.write( out, text)
-            Otherwise if callable, we do: out( text)
-            Otherwise we assume  is python stream or similar, and do: out.write(text)
-        shell:
-            Whether to run command inside a shell (see subprocess.Popen).
-        encoding:
-            Sepecify the encoding used to translate the command's output
-            to characters.
-
-            Note that if  is None and we are being run by python3,
-             will be passed bytes, not a string.
-
-            Note that latin_1 will never raise a UnicodeDecodeError.
-        errors:
-            How to handle encoding errors; see docs for codecs module for
-            details.
-        buffer_len:
-            The number of bytes we attempt to read at a time. If -1 we read
-            output one line at a time.
-
-    Returns:
-        subprocess's , i.e. -N means killed by signal N, otherwise
-        the exit value (e.g. 12 if command terminated with exit(12)).
-    '''
-    if out == -1:
-        stdin = 0
-        stdout = 1
-        stderr = 2
-    else:
-        stdin = None
-        stdout = subprocess.PIPE
-        stderr = subprocess.STDOUT
-    child = subprocess.Popen(
-            command,
-            shell=shell,
-            stdin=stdin,
-            stdout=stdout,
-            stderr=stderr,
-            close_fds=True,
-            #encoding=encoding - only python-3.6+.
-            )
-
-    child_out = child.stdout
-    if encoding:
-        child_out = codecs.getreader( encoding)( child_out, errors)
-
-    out = make_stream( out)
-
-    if stdout == subprocess.PIPE:
-        if buffer_len == -1:
-            for line in child_out:
-                out.write( line)
-        else:
-            while 1:
-                text = child_out.read( buffer_len)
-                if not text:
-                    break
-                out.write( text)
-    #decode( lambda : os.read( child_out.fileno(), 100), outfn, encoding)
-
-    return child.wait()
-
-if __name__ == '__main__':
-
-    if os.getenv( 'jtest_py_system_raw_test') == '1':
-        out = io.StringIO()
-        system_raw(
-                'jtest_py_system_raw_test=2 python jlib.py',
-                sys.stdout,
-                encoding='utf-8',
-                #'latin_1',
-                errors='replace',
-                )
-        print( repr( out.getvalue()))
-
-    elif os.getenv( 'jtest_py_system_raw_test') == '2':
-        for i in range(256):
-            sys.stdout.write( chr(i))
-
-
-def system(
-        command,
-        verbose=None,
-        raise_errors=True,
-        out=None,
-        prefix=None,
-        rusage=False,
-        shell=True,
-        encoding=None,
-        errors='replace',
-        buffer_len=-1,
-        ):
-    '''
-    Runs a command like os.system() or subprocess.*, but with more flexibility.
-
-    We give control over where the command's output is sent, whether to return
-    the output and/or exit code, and whether to raise an exception if the
-    command fails.
-
-    We also support the use of /usr/bin/time to gather rusage information.
-
-        command:
-            The command to run.
-        verbose:
-            If true, we output information about the command that we run, and
-            its result.
-
-            If callable or something with a .write() method, information is
-            sent to  itself. Otherwise it is sent to  (without
-            applying ).
-        raise_errors:
-            If true, we raise an exception if the command fails, otherwise we
-            return the failing error code or zero.
-        out:
-            Python stream, fd, callable or Stream instance to which output is
-            sent.
-
-            If  is 'return', we buffer the output and return (e,
-            ). Note that if raise_errors is true, we only return if 
-            is zero.
-
-            If -1, output is sent to stdout and stderr.
-        prefix:
-            If not None, should be prefix string or callable used to prefix
-            all output. [This is for convenience to avoid the need to do
-            out=StreamPrefix(...).]
-        rusage:
-            If true, we run via /usr/bin/time and return rusage string
-            containing information on execution.  and
-            out='return' are ignored.
-        shell:
-            Passed to underlying subprocess.Popen() call.
-        encoding:
-            Sepecify the encoding used to translate the command's output
-            to characters. Defaults to utf-8.
-        errors:
-            How to handle encoding errors; see docs for codecs module
-            for details. Defaults to 'replace' so we never raise a
-            UnicodeDecodeError.
-        buffer_len:
-            The number of bytes we attempt to read at a time. If -1 we read
-            output one line at a time.
-
-    Returns:
-        If  is true, we return the rusage text.
-
-        Else if raise_errors is true:
-            If the command failed, we raise an exception.
-            Else if  is 'return' we return the text output from the command.
-            Else we return None
-
-        Else if  is 'return', we return (e, text) where  is the
-        command's exit code and  is the output from the command.
-
-        Else we return , the command's exit code.
-    '''
-    if encoding is None:
-        if sys.version_info[0] == 2:
-            # python-2 doesn't seem to implement 'replace' properly.
-            encoding = None
-            errors = None
-        else:
-            encoding = 'utf-8'
-            errors = 'replace'
-
-    out_original = out
-    if out is None:
-        out = sys.stdout
-    elif out == 'return':
-        # Store the output ourselves so we can return it.
-        out = io.StringIO()
-    else:
-        out = make_stream( out)
-
-    if verbose:
-        if getattr( verbose, 'write', None):
-            pass
-        elif callable( verbose):
-            verbose = make_stream( verbose)
-        else:
-            verbose = out
-
-    if prefix:
-        out = StreamPrefix( out, prefix)
-
-    if verbose:
-        verbose.write( 'running: %s\n' % command)
-
-    if rusage:
-        command2 = ''
-        command2 += '/usr/bin/time -o ubt-out -f "D=%D E=%D F=%F I=%I K=%K M=%M O=%O P=%P R=%r S=%S U=%U W=%W X=%X Z=%Z c=%c e=%e k=%k p=%p r=%r s=%s t=%t w=%w x=%x C=%C"'
-        command2 += ' '
-        command2 += command
-        system_raw( command2, out, shell, encoding, errors, buffer_len=buffer_len)
-        with open('ubt-out') as f:
-            rusage_text = f.read()
-        #print 'have read rusage output: %r' % rusage_text
-        if rusage_text.startswith( 'Command '):
-            # Annoyingly, /usr/bin/time appears to write 'Command
-            # exited with ...' or 'Command terminated by ...' to the
-            # output file before the rusage info if command doesn't
-            # exit 0.
-            nl = rusage_text.find('\n')
-            rusage_text = rusage_text[ nl+1:]
-        return rusage_text
-    else:
-        e = system_raw( command, out, shell, encoding, errors, buffer_len=buffer_len)
-
-        if verbose:
-            verbose.write( '[returned e=%s]\n' % e)
-
-        if raise_errors:
-            if e:
-                raise Exception( 'command failed: %s' % command)
-            if out_original == 'return':
-                return out.getvalue()
-            return
-
-        if out_original == 'return':
-            return e, out.getvalue()
-        return e
-
-def get_gitfiles( directory, submodules=False):
-    '''
-    Returns list of all files known to git in ;  must be
-    somewhere within a git checkout.
-
-    Returned names are all relative to .
-
-    If .git directory, we also create /jtest-git-files. Otherwise we
-    assume a this file already exists.
-    '''
-    if os.path.isdir( '%s/.git' % directory):
-        command = 'cd ' + directory + ' && git ls-files'
-        if submodules:
-            command += ' --recurse-submodules'
-        command += ' > jtest-git-files'
-        system( command, verbose=sys.stdout)
-
-    with open( '%s/jtest-git-files' % directory, 'r') as f:
-        text = f.read()
-    ret = text.split( '\n')
-    return ret
-
-def get_git_id_raw( directory):
-    if not os.path.isdir( '%s/.git' % directory):
-        return
-    text = system(
-            f'cd {directory} && (PAGER= git show --pretty=oneline|head -n 1 && git diff)',
-            out='return',
-            )
-    return text
-
-def get_git_id( directory, allow_none=False):
-    '''
-    Returns text where first line is ' ' and remaining
-    lines contain output from 'git diff' in .
-
-    directory:
-        Root of git checkout.
-    allow_none:
-        If true, we return None if  is not a git checkout and
-        jtest-git-id file does not exist.
-    '''
-    filename = f'{directory}/jtest-git-id'
-    text = get_git_id_raw( directory)
-    if text:
-        with open( filename, 'w') as f:
-            f.write( text)
-    elif os.path.isfile( filename):
-        with open( filename) as f:
-            text = f.read()
-    else:
-        if not allow_none:
-            raise Exception( f'Not in git checkout, and no file {filename}.')
-        text = None
-    return text
-
-class Args:
-    '''
-    Iterates over argv items. Does getopt-style splitting of args starting with
-    single '-' character.
-    '''
-    def __init__( self, argv):
-        self.argv = argv
-        self.pos = 0
-        self.pos_sub = None
-    def next( self):
-        while 1:
-            if self.pos >= len(self.argv):
-                raise StopIteration()
-            arg = self.argv[self.pos]
-            if (not self.pos_sub
-                    and arg.startswith('-')
-                    and not arg.startswith('--')
-                    ):
-                # Start splitting current arg.
-                self.pos_sub = 1
-            if self.pos_sub and self.pos_sub >= len(arg):
-                # End of '-' sub-arg.
-                self.pos += 1
-                self.pos_sub = None
-                continue
-            if self.pos_sub:
-                # Return '-' sub-arg.
-                ret = arg[self.pos_sub]
-                self.pos_sub += 1
-                return f'-{ret}'
-            # Return normal arg.
-            self.pos += 1
-            return arg
-
-def update_file( text, filename):
-    '''
-    Writes  to . Does nothing if contents of  are
-    already .
-    '''
-    try:
-        with open( filename) as f:
-            text0 = f.read()
-    except OSError:
-        text0 = None
-    if text == text0:
-        log( 'Unchanged: ' + filename)
-    else:
-        log( 'Updating:  ' + filename)
-        # Write to temp file and rename, to ensure we are atomic.
-        filename_temp = f'{filename}-jlib-temp'
-        with open( filename_temp, 'w') as f:
-            f.write( text)
-        os.rename( filename_temp, filename)
-
-
-def mtime( filename, default=0):
-    '''
-    Returns mtime of file, or  if error - e.g. doesn't exist.
-    '''
-    try:
-        return os.path.getmtime( filename)
-    except OSError:
-        return default
-
-def get_filenames( paths):
-    '''
-    Yields each file in , walking any directories.
-    '''
-    if isinstance( paths, str):
-        paths = (paths,)
-    for name in paths:
-        if os.path.isdir( name):
-            for dirpath, dirnames, filenames in os.walk( name):
-                for filename in filenames:
-                    path = os.path.join( dirpath, filename)
-                    yield path
-        else:
-            yield name
-
-def remove( path):
-    '''
-    Removes file or directory, without raising exception if it doesn't exist.
-
-    We assert-fail if the path still exists when we return, in case of
-    permission problems etc.
-    '''
-    try:
-        os.remove( path)
-    except Exception:
-        pass
-    shutil.rmtree( path, ignore_errors=1)
-    assert not os.path.exists( path)
-
-
-# Things for figuring out whether files need updating, using mtimes.
-#
-def newest( names):
-    '''
-    Returns mtime of newest file in . Returns 0 if no file exists.
-    '''
-    assert isinstance( names, (list, tuple))
-    assert names
-    ret_t = 0
-    ret_name = None
-    for filename in get_filenames( names):
-        t = mtime( filename)
-        if t > ret_t:
-            ret_t = t
-            ret_name = filename
-    return ret_t, ret_name
-
-def oldest( names):
-    '''
-    Returns mtime of oldest file in  or 0 if no file exists.
-    '''
-    assert isinstance( names, (list, tuple))
-    assert names
-    ret_t = None
-    ret_name = None
-    for filename in get_filenames( names):
-        t = mtime( filename)
-        if ret_t is None or t < ret_t:
-            ret_t = t
-            ret_name = filename
-    if ret_t is None:
-        ret_t = 0
-    return ret_t, ret_name
-
-def update_needed( infiles, outfiles):
-    '''
-    If any file in  is newer than any file in , returns
-    string description. Otherwise returns None.
-    '''
-    in_tmax, in_tmax_name = newest( infiles)
-    out_tmin, out_tmin_name = oldest( outfiles)
-    if in_tmax > out_tmin:
-        text = f'{in_tmax_name} is newer than {out_tmin_name}'
-        return text
-
-def build(
-        infiles,
-        outfiles,
-        command,
-        force_rebuild=False,
-        out=None,
-        all_reasons=False,
-        verbose=True,
-        prefix=None,
-        ):
-    '''
-    Ensures that  are up to date using enhanced makefile-like
-    determinism of dependencies.
-
-    Rebuilds  by running  if we determine that any of them
-    are out of date.
-
-    infiles:
-        Names of files that are read by . Can be a single filename. If
-        an item is a directory, we expand to all filenames in the directory's
-        tree.
-    outfiles:
-        Names of files that are written by . Can also be a single
-        filename.
-    command:
-        Command to run.
-    force_rebuild:
-        If true, we always re-run the command.
-    out:
-        A callable, passed to jlib.system(). If None, we use jlib.log() with
-        our caller's stack record.
-    all_reasons:
-        If true we check all ways for a build being needed, even if we already
-        know a build is needed; this only affects the diagnostic that we
-        output.
-    verbose:
-        Passed to jlib.system().
-    prefix:
-        Passed to jlib.system().
-
-    We compare mtimes of  and , and we also detect changes
-    to the command itself.
-
-    If any of infiles are newer than any of outfiles, or  is
-    different to contents of commandfile '.cmd, then truncates
-    commandfile and runs . If  succeeds we writes 
-    to commandfile.
-    '''
-    if isinstance( infiles, str):
-        infiles = (infiles,)
-    if isinstance( outfiles, str):
-        infiles = (outfiles,)
-
-    if not out:
-        out_frame_record = inspect.stack()[1]
-        out = lambda text: log( text, nv=0, caller=out_frame_record)
-
-    command_filename = f'{outfiles[0]}.cmd'
-
-    reasons = []
-
-    if not reasons or all_reasons:
-        if force_rebuild:
-            reasons.append( 'force_rebuild was specified')
-
-    if not reasons or all_reasons:
-        try:
-            with open( command_filename) as f:
-                command0 = f.read()
-        except Exception:
-            command0 = None
-        if command != command0:
-            if command0:
-                reasons.append( 'command has changed')
-            else:
-                reasons.append( 'no previous command')
-
-    if not reasons or all_reasons:
-        reason = update_needed( infiles, outfiles)
-        if reason:
-            reasons.append( reason)
-
-    if not reasons:
-        out( 'Already up to date: ' + ' '.join(outfiles))
-        return
-
-    if out:
-        out( 'Rebuilding because %s: %s' % (
-                ', and '.join( reasons),
-                ' '.join(outfiles),
-                ))
-
-    # Empty . For each unique item we
-    use -L with parent directory, and -l with embedded name (without leading
-    'lib' or trailing '.co').
-    '''
-    dirs = set()
-    names = []
-    if isinstance( sos, str):
-        sos = (sos,)
-    for so in sos:
-        dir_ = os.path.dirname( so)
-        name = os.path.basename( so)
-        assert name.startswith( 'lib')
-        assert name.endswith ( '.so')
-        name = name[3:-3]
-        dirs.add( dir_)
-        names.append( name)
-    ret = ''
-    # Important to use sorted() here, otherwise ordering from set() is
-    # arbitrary causing occasional spurious rebuilds by jlib.build().
-    for dir_ in sorted(dirs):
-        ret += f' -L {dir_}'
-    for name in names:
-        ret += f' -l {name}'
-    return ret
diff --git a/devices/dcontrib.mak b/devices/dcontrib.mak
index 975c68bd..423d3ba2 100644
--- a/devices/dcontrib.mak
+++ b/devices/dcontrib.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2020 Artifex Software, Inc.
+# Copyright (C) 2001-2021 Artifex Software, Inc.
 # All Rights Reserved.
 #
 # This software is provided AS-IS with no warranty, either express or
diff --git a/devices/devs.mak b/devices/devs.mak
index 5526a907..dced3bf4 100644
--- a/devices/devs.mak
+++ b/devices/devs.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2020 Artifex Software, Inc.
+# Copyright (C) 2001-2021 Artifex Software, Inc.
 # All Rights Reserved.
 #
 # This software is provided AS-IS with no warranty, either express or
@@ -24,7 +24,7 @@ DEVVECSRC=$(DEVVEC)$(D)
 DEVI_=$(DEVGENDIR) $(II)$(GLSRCDIR) $(II)$(GLGENDIR) $(II)$(DEVSRCDIR)
 DEVF_=
 
-DEVCCFLAGS=$(I_)$(DEVI_)$(_I) $(I_)$(DEVVEC)$(_I) $(DEVF_)
+DEVCCFLAGS=$(I_)$(DEVI_)$(_I) $(I_)$(DEVVEC)$(_I) $(D_)OCR_VERSION=$(OCR_VERSION)$(_D) $(DEVF_)
 DEVCC=$(CC_) $(DEVCCFLAGS)
 XPSDEVCC=$(CC_) $(XPSPRINTCFLAGS) $(DEVCCFLAGS)
 
@@ -117,6 +117,7 @@ DEVGEN=$(DEVGENDIR)$(D)
 # High-level file formats:
 #	pdfwrite	PDF output (like Adobe Acrobat Distiller)
 #	txtwrite	ASCII or Unicode text output
+#	docxwrite	Docx output
 #	pxlmono 	Black-and-white PCL XL
 #	pxlcolor	Color PCL XL
 # Other raster file formats and devices:
@@ -633,14 +634,14 @@ $(DEVOBJ)gdevpsdi.$(OBJ) : $(DEVVECSRC)gdevpsdi.c $(GXERR)\
  $(scfx_h) $(slzwx_h) $(spngpx_h)\
  $(strimpl_h) $(szlibx_h) $(sisparam_h)\
  $(gdevpsdf_h) $(gdevpsds_h) $(gxdevmem_h) $(gxcspace_h) $(gxparamx_h)\
- $(sjbig2_luratech_h) $(sjpx_luratech_h) $(gsicc_manage_h) $(DEVS_MAK) $(MAKEDIRS)
+ $(gsicc_manage_h) $(DEVS_MAK) $(MAKEDIRS)
 	$(GDEVLWFJB2JPXCC) $(DEVO_)gdevpsdi.$(OBJ) $(C_) $(DEVVECSRC)gdevpsdi.c
 
 $(DEVOBJ)gdevpsdp.$(OBJ) : $(DEVVECSRC)gdevpsdp.c $(GDEVH)\
  $(string__h) $(jpeglib__h)\
  $(scfx_h) $(sdct_h) $(slzwx_h) $(srlx_h) $(strimpl_h) $(szlibx_h)\
  $(gsparamx_h) $(gsutil_h) $(gdevpsdf_h)\
- $(sjbig2_luratech_h) $(sjpx_luratech_h) $(DEVS_MAK) $(MAKEDIRS)
+ $(DEVS_MAK) $(MAKEDIRS)
 	$(GDEVLWFJB2JPXCC) $(DEVO_)gdevpsdp.$(OBJ) $(C_) $(DEVVECSRC)gdevpsdp.c
 
 $(DEVOBJ)gdevpsds.$(OBJ) : $(DEVVECSRC)gdevpsds.c $(GX) $(memory__h)\
@@ -659,7 +660,7 @@ $(DEVOBJ)gdevpsdu.$(OBJ) : $(DEVVECSRC)gdevpsdu.c $(GXERR)\
 
 gdevagl_h=$(DEVVECSRC)gdevagl.h
 
-txtwrite_=$(DEVOBJ)gdevtxtw.$(OBJ) $(DEVOBJ)gdevagl.$(OBJ)
+txtwrite_=$(DEVOBJ)gdevtxtw.$(OBJ) $(DEVOBJ)gdevagl.$(OBJ) $(DEVOBJ)doc_common.$(OBJ)
 
 $(DD)txtwrite.dev : $(ECHOGS_XE) $(txtwrite_) $(GDEV)\
  $(gdevagl_h) $(DEVS_MAK) $(MAKEDIRS)
@@ -668,7 +669,7 @@ $(DD)txtwrite.dev : $(ECHOGS_XE) $(txtwrite_) $(GDEV)\
 $(DEVOBJ)gdevtxtw.$(OBJ) : $(DEVVECSRC)gdevtxtw.c $(GDEV) $(gdevkrnlsclass_h) \
   $(memory__h) $(string__h) $(gp_h) $(gsparam_h) $(gsutil_h) \
   $(gsdevice_h) $(gxfont_h) $(gxfont0_h) $(gstext_h) $(gxfcid_h)\
-  $(gxgstate_h) $(gxpath_h) $(gdevagl_h) $(DEVS_MAK) $(MAKEDIRS)
+  $(gxgstate_h) $(gxpath_h) $(gdevagl_h) $(DEVS_MAK) $(MAKEDIRS) $(DEVVECSRC)doc_common.h
 	$(DEVCC) $(DEVO_)gdevtxtw.$(OBJ) $(C_) $(DEVVECSRC)gdevtxtw.c
 
 $(DEVOBJ)gdevagl.$(OBJ) : $(DEVVECSRC)gdevagl.c $(GDEV)\
@@ -676,6 +677,32 @@ $(DEVOBJ)gdevagl.$(OBJ) : $(DEVVECSRC)gdevagl.c $(GDEV)\
 	$(DEVCC) $(DEVO_)gdevagl.$(OBJ) $(C_) $(DEVVECSRC)gdevagl.c
 
 
+# Docx writer
+
+gdevagl_h=$(DEVVECSRC)gdevagl.h
+
+docxwrite_=$(DEVOBJ)gdevdocxw.$(OBJ) $(DEVOBJ)gdevagl.$(OBJ) $(DEVOBJ)doc_common.$(OBJ)
+
+$(DD)docxwrite.dev : $(ECHOGS_XE) $(docxwrite_) $(GDEV)\
+ $(gdevagl_h) $(DEVS_MAK) $(MAKEDIRS) $(EXTRACT_OBJS)
+	$(SETDEV2) $(DD)docxwrite $(docxwrite_) $(EXTRACT_OBJS)
+
+$(DEVOBJ)gdevdocxw.$(OBJ) : $(DEVVECSRC)gdevdocxw.c $(GDEV) $(gdevkrnlsclass_h) \
+  $(memory__h) $(string__h) $(gp_h) $(gsparam_h) $(gsutil_h) \
+  $(gsdevice_h) $(gxfont_h) $(gxfont0_h) $(gstext_h) $(gxfcid_h)\
+  $(gxgstate_h) $(gxpath_h) $(gdevagl_h) $(DEVS_MAK) $(MAKEDIRS) \
+  $(DEVVECSRC)doc_common.h
+	$(DEVCC) $(DEVO_)gdevdocxw.$(OBJ) $(C_) $(DEVVECSRC)gdevdocxw.c
+
+# Shared code used by txtwrite and docxwrite.
+
+$(DEVOBJ)doc_common.$(OBJ) : $(DEVVECSRC)doc_common.c $(GDEV) $(gdevkrnlsclass_h) \
+  $(memory__h) $(string__h) $(gp_h) $(gsparam_h) $(gsutil_h) \
+  $(gsdevice_h) $(gxfont_h) $(gxfont0_h) $(gstext_h) $(gxfcid_h)\
+  $(gxgstate_h) $(gxpath_h) $(gdevagl_h) $(DEVS_MAK) $(MAKEDIRS) $(DEVVECSRC)doc_common.h
+	$(DEVCC) $(DEVO_)doc_common.$(OBJ) $(C_) $(DEVVECSRC)doc_common.c
+
+
 ################ BEGIN PDF WRITER ################
 
 # We reserve slots here for gdevpdfa...z, just in case we need them.
@@ -847,7 +874,7 @@ $(DEVOBJ)gdevpdfu.$(OBJ) : $(DEVVECSRC)gdevpdfu.c $(GXERR)\
  $(gsdsrc_h) $(gsfunc_h) $(gsfunc3_h)\
  $(sa85x_h) $(scfx_h) $(sdct_h) $(slzwx_h) $(spngpx_h)\
  $(srlx_h) $(sarc4_h) $(smd5_h) $(sstring_h) $(strimpl_h) $(szlibx_h)\
- $(strmio_h) $(sjbig2_luratech_h) $(sjpx_luratech_h)\
+ $(strmio_h) \
  $(opdfread_h) $(gdevagl_h) $(gs_mro_e_h) $(gs_mgl_e_h) \
  $(DEVS_MAK) $(MAKEDIRS)
 	$(GDEVLWFJB2JPXCC) $(DEVO_)gdevpdfu.$(OBJ) $(C_) $(DEVVECSRC)gdevpdfu.c
@@ -1248,38 +1275,6 @@ $(DEVOBJ)gdevperm.$(OBJ) : $(DEVSRC)gdevperm.c $(PDEVH) $(math__h)\
  $(gdevdcrd_h) $(gscrd_h) $(gscrdp_h) $(gsparam_h) $(gxlum_h) $(DEVS_MAK) $(MAKEDIRS)
 	$(DEVCC) $(DEVO_)gdevperm.$(OBJ) $(C_) $(DEVSRC)gdevperm.c
 
-### ------------------------ JBIG2 testing device ---------------------- ###
-
-gdevjbig2_=$(DEVOBJ)gdevjbig2.$(OBJ)
-
-$(DD)gdevjbig2.dev : $(gdevjbig2_) $(GLD)page.dev $(GDEV) \
- $(DEVS_MAK) $(MAKEDIRS)
-	$(SETPDEV2) $(DD)gdevjbig2 $(gdevjbig2_)
-
-$(DEVOBJ)gdevjbig2.$(OBJ) : $(DEVSRC)gdevjbig2.c $(PDEVH)\
- $(stream_h) $(strimpl_h) $(sjbig2_luratech_h) $(DEVS_MAK) $(MAKEDIRS)
-	$(GDEVLDFJB2CC) $(DEVO_)gdevjbig2.$(OBJ) $(C_) $(DEVSRC)gdevjbig2.c
-
-### ------------------------ JPX testing device ----------------------
-###
-
-gdevjpx_=$(DEVOBJ)gdevjpx.$(OBJ)
-
-$(DD)jpxrgb.dev : $(gdevjpx_) $(GLD)page.dev $(GDEV) \
- $(DEVS_MAK) $(MAKEDIRS)
-	$(SETPDEV2) $(DD)jpxrgb $(gdevjpx_)
-
-$(DD)jpxgray.dev : $(gdevjpx_) $(GLD)page.dev $(GDEV) \
- $(DEVS_MAK) $(MAKEDIRS)
-	$(SETPDEV2) $(DD)jpxgray $(gdevjpx_)
-
-$(DD)jpxcmyk.dev : $(gdevjpx_) $(GLD)page.dev $(GDEV) \
- $(DEVS_MAK) $(MAKEDIRS)
-	$(SETPDEV2) $(DD)jpxcmyk $(gdevjpx_)
-
-$(DEVOBJ)gdevjpx.$(OBJ) : $(DEVSRC)gdevjpx.c $(PDEVH)\
- $(stream_h) $(strimpl_h) $(sjpx_luratech_h) $(DEVS_MAK) $(MAKEDIRS)
-	$(GDEVLWFJPXCC) $(DEVO_)gdevjpx.$(OBJ) $(C_) $(DEVSRC)gdevjpx.c
 
 ### ------------------------- JPEG file format ------------------------- ###
 
@@ -1709,7 +1704,7 @@ $(DEVOBJ)gdevtsep_1.$(OBJ) : $(DEVSRC)gdevtsep.c $(PDEVH) $(stdint__h)\
 
 $(DEVOBJ)gdevtsep.$(OBJ) : $(DEVOBJ)gdevtsep_$(WITH_CAL).$(OBJ)
 	$(CP_) $(DEVOBJ)gdevtsep_$(WITH_CAL).$(OBJ) $(DEVOBJ)gdevtsep.$(OBJ)
-			 
+
 
 # TIFF Scaled (downscaled gray -> mono), configurable compression
 
diff --git a/devices/extract.mak b/devices/extract.mak
new file mode 100644
index 00000000..5e186e08
--- /dev/null
+++ b/devices/extract.mak
@@ -0,0 +1,48 @@
+extract_cc = $(CC) $(CCFLAGS) $(I_)$(EXTRACT_DIR)/include$(_I) $(I_)$(ZSRCDIR)$(_I) $(O_)
+extract_out_prefix = $(GLOBJDIR)$(D)extract_
+
+$(extract_out_prefix)alloc.$(OBJ):          $(EXTRACT_DIR)/src/alloc.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/alloc.c
+
+$(extract_out_prefix)astring.$(OBJ):        $(EXTRACT_DIR)/src/astring.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/astring.c
+
+$(extract_out_prefix)buffer.$(OBJ):         $(EXTRACT_DIR)/src/buffer.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/buffer.c
+
+$(extract_out_prefix)docx.$(OBJ):           $(EXTRACT_DIR)/src/docx.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/docx.c
+
+$(extract_out_prefix)docx_template.$(OBJ):  $(EXTRACT_DIR)/src/docx_template.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/docx_template.c
+
+$(extract_out_prefix)extract.$(OBJ):        $(EXTRACT_DIR)/src/extract.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/extract.c
+
+$(extract_out_prefix)join.$(OBJ):           $(EXTRACT_DIR)/src/join.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/join.c
+
+$(extract_out_prefix)mem.$(OBJ):            $(EXTRACT_DIR)/src/mem.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/mem.c
+
+$(extract_out_prefix)outf.$(OBJ):           $(EXTRACT_DIR)/src/outf.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/outf.c
+
+$(extract_out_prefix)xml.$(OBJ):            $(EXTRACT_DIR)/src/xml.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/xml.c
+
+$(extract_out_prefix)zip.$(OBJ):            $(EXTRACT_DIR)/src/zip.c
+	$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/zip.c
+
+EXTRACT_OBJS = \
+	$(extract_out_prefix)alloc.$(OBJ) \
+	$(extract_out_prefix)astring.$(OBJ) \
+	$(extract_out_prefix)buffer.$(OBJ) \
+	$(extract_out_prefix)docx.$(OBJ) \
+	$(extract_out_prefix)docx_template.$(OBJ) \
+	$(extract_out_prefix)extract.$(OBJ) \
+	$(extract_out_prefix)join.$(OBJ) \
+	$(extract_out_prefix)mem.$(OBJ) \
+	$(extract_out_prefix)outf.$(OBJ) \
+	$(extract_out_prefix)xml.$(OBJ) \
+	$(extract_out_prefix)zip.$(OBJ) \
diff --git a/devices/gdev3852.c b/devices/gdev3852.c
index 32649bd1..1b3377b2 100644
--- a/devices/gdev3852.c
+++ b/devices/gdev3852.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdev4081.c b/devices/gdev4081.c
index 6a715b8b..70bfbb51 100644
--- a/devices/gdev4081.c
+++ b/devices/gdev4081.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdev8510.c b/devices/gdev8510.c
index ad5c6978..af9fcf8f 100644
--- a/devices/gdev8510.c
+++ b/devices/gdev8510.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdev8bcm.c b/devices/gdev8bcm.c
index 0adb7963..a76541be 100644
--- a/devices/gdev8bcm.c
+++ b/devices/gdev8bcm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdev8bcm.h b/devices/gdev8bcm.h
index 4b30675a..6b12a24d 100644
--- a/devices/gdev8bcm.h
+++ b/devices/gdev8bcm.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevatx.c b/devices/gdevatx.c
index aaf22a5e..1836edf6 100644
--- a/devices/gdevatx.c
+++ b/devices/gdevatx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevbit.c b/devices/gdevbit.c
index 86786fb9..600bfdd2 100644
--- a/devices/gdevbit.c
+++ b/devices/gdevbit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -319,6 +319,8 @@ const gx_device_bit gs_bitrgbtags_device =
         0,  /*DisablePageHandler*/
         0,  /*ObjectFilter*/
         0,  /*ObjectHandlerPushed*/
+        0,  /*NupControl*/
+        0,  /*NupHandlerPushed*/
         0,  /*PageCount*/
         0,  /*ShowPageCount*/
         1,  /*NumCopies*/
@@ -332,6 +334,7 @@ const gx_device_bit gs_bitrgbtags_device =
         {false}, /*sgr*/
         0, /*MaxPatternBitmap*/
         0, /*page_uses_transparency*/
+        0, /*page_uses_overprint*/
         {
           MAX_BITMAP, BUFFER_SPACE,
           { BAND_PARAMS_INITIAL_VALUES },
@@ -365,7 +368,7 @@ const gx_device_bit gs_bitrgbtags_device =
         false, /* file_is_new */
         NULL,  /* file */
         false, /* bg_print_requested */
-        {0},   /* bg_print */
+        0,     /* bg_print *  */
         0,     /* num_render_threads_requested */
         NULL,  /* saved_pages_list */
         {0}    /* save_procs_while_delaying_erasepage */
diff --git a/devices/gdevbj10.c b/devices/gdevbj10.c
index cbb9c469..9468552a 100644
--- a/devices/gdevbj10.c
+++ b/devices/gdevbj10.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevbjc.h b/devices/gdevbjc.h
index 9d58211e..120f528f 100644
--- a/devices/gdevbjc.h
+++ b/devices/gdevbjc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevbjcl.c b/devices/gdevbjcl.c
index 4692266b..75377d74 100644
--- a/devices/gdevbjcl.c
+++ b/devices/gdevbjcl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevbjcl.h b/devices/gdevbjcl.h
index a3bc9987..e249d790 100644
--- a/devices/gdevbjcl.h
+++ b/devices/gdevbjcl.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevbmp.c b/devices/gdevbmp.c
index 14033dca..52a13374 100644
--- a/devices/gdevbmp.c
+++ b/devices/gdevbmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevbmp.h b/devices/gdevbmp.h
index aec8f12c..4d58fc36 100644
--- a/devices/gdevbmp.h
+++ b/devices/gdevbmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevbmpc.c b/devices/gdevbmpc.c
index 81b2abd6..efc2333b 100644
--- a/devices/gdevbmpc.c
+++ b/devices/gdevbmpc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevccr.c b/devices/gdevccr.c
index 5c9b7098..451cb82c 100644
--- a/devices/gdevccr.c
+++ b/devices/gdevccr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevcdj.c b/devices/gdevcdj.c
index ce74cc29..49b30df6 100644
--- a/devices/gdevcdj.c
+++ b/devices/gdevcdj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevcfax.c b/devices/gdevcfax.c
index a6d0db44..cd3dc15c 100644
--- a/devices/gdevcfax.c
+++ b/devices/gdevcfax.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevchameleon.c b/devices/gdevchameleon.c
index 74421244..20abe218 100644
--- a/devices/gdevchameleon.c
+++ b/devices/gdevchameleon.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevcif.c b/devices/gdevcif.c
index d2e09b79..66a44013 100644
--- a/devices/gdevcif.c
+++ b/devices/gdevcif.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevclj.c b/devices/gdevclj.c
index 4c5ffb7b..5edac41e 100644
--- a/devices/gdevclj.c
+++ b/devices/gdevclj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevcljc.c b/devices/gdevcljc.c
index 15405cbd..bf8a4b82 100644
--- a/devices/gdevcljc.c
+++ b/devices/gdevcljc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevcmykog.c b/devices/gdevcmykog.c
index 4330258e..dcd1a4a4 100644
--- a/devices/gdevcmykog.c
+++ b/devices/gdevcmykog.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -171,9 +171,9 @@ cmykog_open(gx_device * pdev)
   dev->icc_struct->supports_devn = true;
 
   /* This device is a DeviceN color based device but unlike psdcmyk and
-     tiffsep it can't change its color characteristics.  It remains as 
-     a 6 color cmykog device.  Postsript files can change the maxseparations 
-     (example Bug 696600 29-07E.PS)  The gdevdevn code will, if it 
+     tiffsep it can't change its color characteristics.  It remains as
+     a 6 color cmykog device.  Postsript files can change the maxseparations
+     (example Bug 696600 29-07E.PS)  The gdevdevn code will, if it
      detects a change occured, close the device and reopen (see
      devn_printer_put_params) possibly resetting the color info.  tiffsep
      and psdcmyk, when reopened, will  reset their color characteristics based upon
diff --git a/devices/gdevcslw.c b/devices/gdevcslw.c
index 4ded7ccd..8744f668 100644
--- a/devices/gdevcslw.c
+++ b/devices/gdevcslw.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdfax.c b/devices/gdevdfax.c
index 3d2a579f..d113fd07 100644
--- a/devices/gdevdfax.c
+++ b/devices/gdevdfax.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdjet.c b/devices/gdevdjet.c
index ea81dead..402e8aaa 100644
--- a/devices/gdevdjet.c
+++ b/devices/gdevdjet.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdjtc.c b/devices/gdevdjtc.c
index a0ffe625..34bb030d 100644
--- a/devices/gdevdjtc.c
+++ b/devices/gdevdjtc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdljm.c b/devices/gdevdljm.c
index fa859164..321160a0 100644
--- a/devices/gdevdljm.c
+++ b/devices/gdevdljm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdljm.h b/devices/gdevdljm.h
index 679bd561..18335805 100644
--- a/devices/gdevdljm.h
+++ b/devices/gdevdljm.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdm24.c b/devices/gdevdm24.c
index 42706eee..08cad67f 100644
--- a/devices/gdevdm24.c
+++ b/devices/gdevdm24.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdsp.c b/devices/gdevdsp.c
index 0a66a027..10cfd85e 100644
--- a/devices/gdevdsp.c
+++ b/devices/gdevdsp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -1430,9 +1430,6 @@ static int display_check_structure(gx_device_display *ddev)
     }
     else if (ddev->callback->size == sizeof(struct display_callback_v2_s)) {
         /* V2 structure with added display_separation callback */
-        if (ddev->callback->size != sizeof(display_callback))
-            return_error(gs_error_rangecheck);
-
         if (ddev->callback->version_major != DISPLAY_VERSION_MAJOR_V2)
             return_error(gs_error_rangecheck);
 
@@ -1649,7 +1646,7 @@ display_size_buf_device(gx_device_buf_space_t *space, gx_device *target,
                         int height, bool for_band)
 {
     gx_device_display *ddev = (gx_device_display *)target;
-    gx_device_memory mdev;
+    gx_device_memory mdev = { 0 };
     int code;
     int planar = ddev->nFormat & (DISPLAY_PLANAR | DISPLAY_PLANAR_INTERLEAVED);
     int interleaved = (ddev->nFormat & DISPLAY_PLANAR_INTERLEAVED);
@@ -1680,75 +1677,6 @@ static gx_device_buf_procs_t display_buf_procs = {
     gx_default_destroy_buf_device
 };
 
-static int		/* returns 0 ok, else -ve error cde */
-setup_as_clist(gx_device_display *ddev, gs_memory_t *buffer_memory)
-{
-    gdev_space_params space_params = ddev->space_params;
-    gx_device *target = (gx_device *)ddev;
-    uint space;
-    int code;
-    gx_device_clist *const pclist_dev = (gx_device_clist *)ddev;
-    gx_device_clist_common * const pcldev = &pclist_dev->common;
-    byte *base;
-    bool save_is_open = ddev->is_open;	/* Save around temporary failure in open_c loop */
-
-    while (target->parent != NULL) {
-        target = target->parent;
-        gx_update_from_subclass(target);
-    }
-
-    /* Try to allocate based simply on param-requested buffer size */
-    for ( space = space_params.BufferSpace; ; ) {
-        base = gs_alloc_bytes(buffer_memory, space,
-                              "cmd list buffer");
-        if (base != NULL)
-            break;
-        if ((space >>= 1) < MIN_BUFFER_SPACE)
-            break;
-    }
-    if (base == NULL)
-        return_error(gs_error_VMerror);
-
-    /* Try opening the command list, to see if we allocated */
-    /* enough buffer space. */
-open_c:
-    ddev->buf = base;
-    ddev->buffer_space = space;
-    pclist_dev->common.orig_spec_op = ddev->orig_procs.dev_spec_op;
-    clist_init_io_procs(pclist_dev, ddev->BLS_force_memory);
-    clist_init_params(pclist_dev, base, space, target,
-                      display_buf_procs,
-                      space_params.band,
-                      false, /* do_not_open_or_close_bandfiles */
-                      (ddev->bandlist_memory == NULL ?
-                       ddev->memory->non_gc_memory:
-                       ddev->bandlist_memory),
-                      ddev->clist_disable_mask,
-                      ddev->page_uses_transparency);
-    code = (*gs_clist_device_procs.open_device)( (gx_device *)pcldev );
-    if (code < 0) {
-        /* If there wasn't enough room, and we haven't */
-        /* already shrunk the buffer, try enlarging it. */
-        if (code == gs_error_rangecheck &&
-            space >= space_params.BufferSpace) {
-            space += space / 8;
-            gs_free_object(buffer_memory, base,
-                           "cmd list buf(retry open)");
-            base = gs_alloc_bytes(buffer_memory, space,
-                                  "cmd list buf(retry open)");
-            ddev->buf = base;
-            if (base != NULL) {
-                ddev->is_open = save_is_open;	/* allow for success when we loop */
-                goto open_c;
-            }
-        }
-        /* Failure. */
-        gs_free_object(buffer_memory, base, "cmd list buf");
-        ddev->buffer_space = 0;
-    }
-    return code;
-}
-
 /* Allocate the backing bitmap. */
 static int
 display_alloc_bitmap(gx_device_display * ddev, gx_device * param_dev)
@@ -1814,7 +1742,14 @@ display_alloc_bitmap(gx_device_display * ddev, gx_device * param_dev)
             return_error(gs_error_VMerror);
         }
         /* Let's set up as a clist. */
-        ccode = setup_as_clist(ddev, ddev->memory->non_gc_memory);
+        ccode = clist_mutate_to_clist((gx_device_clist_mutatable *)ddev,
+                                      ddev->memory->non_gc_memory,
+                                      NULL,
+                                      &ddev->space_params,
+                                      0,
+                                      &display_buf_procs,
+                                      ddev->orig_procs.dev_spec_op,
+                                      MIN_BUFFER_SPACE);
         if (ccode >= 0)
             ddev->procs = gs_clist_device_procs;
     } else {
@@ -2285,7 +2220,7 @@ display_set_color_format(gx_device_display *ddev, int nFormat)
             if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) {
                 ddev->devn_params.bitspercomponent = bpc;
                 if (ddev->icc_struct == NULL) {
-                    ddev->icc_struct = gsicc_new_device_profile_array(ddev->memory);
+                    ddev->icc_struct = gsicc_new_device_profile_array((gx_device *)ddev);
                     if (ddev->icc_struct == NULL)
                         return_error(gs_error_VMerror);
                 }
diff --git a/devices/gdevdsp.h b/devices/gdevdsp.h
index a062374b..37a839f2 100644
--- a/devices/gdevdsp.h
+++ b/devices/gdevdsp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevdsp2.h b/devices/gdevdsp2.h
index 3a098873..a592a9ce 100644
--- a/devices/gdevdsp2.h
+++ b/devices/gdevdsp2.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevepsc.c b/devices/gdevepsc.c
index 830d7668..5818eac8 100644
--- a/devices/gdevepsc.c
+++ b/devices/gdevepsc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -182,7 +182,7 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
     char start_graphics;
     int first_pass;
     int last_pass;
-    int dots_per_space; 
+    int dots_per_space;
     int bytes_per_space;
     int skip = 0, lnum = 0, code = 0, pass;
 
@@ -201,7 +201,7 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
     if (x_dpi > max_dpi) {
         return_error(gs_error_rangecheck);
     }
-    
+
     start_graphics = (char)
         ((y_24pin ? graphics_modes_24 : graphics_modes_9)[x_dpi / 60]);
     first_pass = (start_graphics & DD ? 1 : 0);
diff --git a/devices/gdevepsn.c b/devices/gdevepsn.c
index 7b77b998..bea4b2c0 100644
--- a/devices/gdevepsn.c
+++ b/devices/gdevepsn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -171,7 +171,7 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
         int tab_min_pixels = x_dpi * MIN_TAB_10THS / 10;
         int skip = 0, lnum = 0, pass, ypass;
         int code = 0;
-        
+
         char start_graphics;
         int first_pass;
         int last_pass;
@@ -195,12 +195,12 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
             /* This avoids divide by zero later on, bug 701843. */
             return_error(gs_error_rangecheck);
         }
-        
+
         buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf1)");
         buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf2)");
         in = buf1;
         out = buf2;
-        
+
 
         /* Check allocations */
         if ( buf1 == 0 || buf2 == 0 ) {
diff --git a/devices/gdevescp.c b/devices/gdevescp.c
index 14e420b5..f111785a 100644
--- a/devices/gdevescp.c
+++ b/devices/gdevescp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevfax.c b/devices/gdevfax.c
index 27b3c888..f85d8392 100644
--- a/devices/gdevfax.c
+++ b/devices/gdevfax.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -69,7 +69,7 @@ gdev_fax_get_params(gx_device * dev, gs_param_list * plist)
         ecode = code;
      if ((code = param_write_bool(plist, "BlackIs1", &fdev->BlackIs1)) < 0)
         ecode = code;
- 
+
     return ecode;
 }
 int
diff --git a/devices/gdevfax.h b/devices/gdevfax.h
index b0419d31..73a668e6 100644
--- a/devices/gdevfax.h
+++ b/devices/gdevfax.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevfpng.c b/devices/gdevfpng.c
index 74cfac70..324cbd28 100644
--- a/devices/gdevfpng.c
+++ b/devices/gdevfpng.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevhl7x.c b/devices/gdevhl7x.c
index 66d1db29..c2f1eaa1 100644
--- a/devices/gdevhl7x.c
+++ b/devices/gdevhl7x.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevicov.c b/devices/gdevicov.c
index 355be240..91e98d6e 100644
--- a/devices/gdevicov.c
+++ b/devices/gdevicov.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -77,7 +77,7 @@ cov_write_page(gx_device_printer *pdev, gp_file *file)
             k = (double)k_pix / total_pix;
 	    }
 
-        
+
         if (IS_LIBCTX_STDOUT(pdev->memory, gp_get_file(file))) {
             outprintf(pdev->memory, "%8.5f %8.5f %8.5f %8.5f CMYK %s\n",
                 c, m, y, k, code ? "ERROR" : "OK");
@@ -122,13 +122,13 @@ static int cov_write_page_ink(gx_device_printer *pdev, gp_file *file)
         end = row + raster;
 
         for (; row < end; row += 4) {
-          
+
 			dc_pix += row[0];
 
             dm_pix += row[1];
 
 			dy_pix += row[2];
-            
+
 			dk_pix += row[3];
 
 			++total_pix;
diff --git a/devices/gdevijs.c b/devices/gdevijs.c
index 42e1e916..884ea54a 100644
--- a/devices/gdevijs.c
+++ b/devices/gdevijs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevimgn.c b/devices/gdevimgn.c
index c6e291a4..1abde294 100644
--- a/devices/gdevimgn.c
+++ b/devices/gdevimgn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevjbig2.c b/devices/gdevjbig2.c
deleted file mode 100644
index d6b4ef96..00000000
--- a/devices/gdevjbig2.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
-   All Rights Reserved.
-
-   This software is provided AS-IS with no warranty, either express or
-   implied.
-
-   This software is distributed under license and may not be copied,
-   modified or distributed except as expressly authorized under the terms
-   of the license contained in the file LICENSE in this distribution.
-
-   Refer to licensing information at http://www.artifex.com or contact
-   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
-   CA 94945, U.S.A., +1(415)492-9861, for further information.
-*/
-
-
-/* $Id: gdevjbig2.c 6300 2005-12-28 19:56:24Z giles $ */
-/* JBIG2 encode filter test device */
-
-#include "gdevprn.h"
-#include "stream.h"
-#include "strimpl.h"
-#include "sjbig2_luratech.h"
-
-/* Structure for the JBIG2-writing device. */
-typedef struct gx_device_jbig2_s {
-    gx_device_common;
-    gx_prn_device_common;
-} gx_device_jbig2;
-
-/* ------ The device descriptors ------ */
-
-/* Default X and Y resolution. */
-#ifndef X_DPI
-#  define X_DPI 72
-#endif
-#ifndef Y_DPI
-#  define Y_DPI 72
-#endif
-
-static dev_proc_print_page(jbig2_print_page);
-
-/* Monochrome only */
-
-const gx_device_printer gs_gdevjbig2_device =
-prn_device(prn_bg_procs, "jbig2",	/* The print_page proc is compatible with allowing bg printing */
-        DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
-        X_DPI, Y_DPI,	/* resolution */
-        0, 0, 0, 0,	/* margins */
-        1, jbig2_print_page);
-
-/* Send the page to the file. */
-static int
-jbig2_print_page(gx_device_printer * pdev, gp_file * prn_stream)
-{
-    gx_device_jbig2 *jdev = (gx_device_jbig2 *) pdev;
-    gs_memory_t *mem = jdev->memory;
-    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
-    byte *in = gs_alloc_bytes(mem, line_size, "jbig2_print_page(in)");
-    byte *fbuf = 0;
-    uint fbuf_size;
-    byte *jbuf = 0;
-    uint jbuf_size;
-    int lnum;
-    int code = 0;
-    stream_jbig2encode_state state;
-    stream fstrm, cstrm;
-
-    if (in == 0) {
-        code = gs_note_error(gs_error_VMerror);
-        goto fail;
-    }
-    /* Create the jbig2encode state. */
-    s_init_state((stream_state *)&state, &s_jbig2encode_template, 0);
-    if (state.templat->set_defaults)
-        (*state.templat->set_defaults) ((stream_state *) & state);
-    state.width = jdev->width;
-    state.height = jdev->height;
-    /* Set up the streams. */
-    fbuf_size = max(512 /* arbitrary */ , state.templat->min_out_size);
-    jbuf_size = state.templat->min_in_size;
-    if ((fbuf = gs_alloc_bytes(mem, fbuf_size, "jbig2_print_page(fbuf)")) == 0 ||
-        (jbuf = gs_alloc_bytes(mem, jbuf_size, "jbig2_print_page(jbuf)")) == 0
-        ) {
-        code = gs_note_error(gs_error_VMerror);
-        goto done;
-    }
-    s_init(&fstrm, mem);
-    swrite_file(&fstrm, prn_stream, fbuf, fbuf_size);
-    s_init(&cstrm, mem);
-    s_std_init(&cstrm, jbuf, jbuf_size, &s_filter_write_procs,
-               s_mode_write);
-    cstrm.state = (stream_state *) & state;
-    cstrm.procs.process = state.templat->process;
-    cstrm.strm = &fstrm;
-    if (state.templat->init)
-        (*state.templat->init) (cstrm.state);
-
-    state.jb2_encode = true;
-
-    /* Copy the data to the output. */
-    for (lnum = 0; lnum < jdev->height; ++lnum) {
-        byte *data;
-        uint ignore_used;
-        int i;
-
-        if (cstrm.end_status) {
-            code = gs_note_error(gs_error_ioerror);
-            goto done;
-        }
-        code = gdev_prn_get_bits(pdev, lnum, in, &data);
-        if (code < 0)
-            goto done;
-        sputs(&cstrm, data, state.stride, &ignore_used);
-    }
-
-    /* Wrap up. */
-    sclose(&cstrm);
-    sflush(&fstrm);
-  done:
-    gs_free_object(mem, jbuf, "jbig2_print_page(jbuf)");
-    gs_free_object(mem, fbuf, "jbig2_print_page(fbuf)");
-    gs_free_object(mem, in, "jbig2_print_page(in)");
-    return code;
-  fail:
-    gs_free_object(mem, in, "jbig2_print_page(in)");
-    return code;
-}
diff --git a/devices/gdevjpeg.c b/devices/gdevjpeg.c
index 7162acdb..eee3abd0 100644
--- a/devices/gdevjpeg.c
+++ b/devices/gdevjpeg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevjpx.c b/devices/gdevjpx.c
deleted file mode 100644
index b3c3690b..00000000
--- a/devices/gdevjpx.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
-   All Rights Reserved.
-
-   This software is provided AS-IS with no warranty, either express or
-   implied.
-
-   This software is distributed under license and may not be copied,
-   modified or distributed except as expressly authorized under the terms
-   of the license contained in the file LICENSE in this distribution.
-
-   Refer to licensing information at http://www.artifex.com or contact
-   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
-   CA 94945, U.S.A., +1(415)492-9861, for further information.
-*/
-
-
-/* $Id: gdevjpx.c 6300 2005-12-28 19:56:24Z giles $ */
-/* JPX encode filter test device */
-
-#include "gdevprn.h"
-#include "stream.h"
-#include "strimpl.h"
-#include "sjpx_luratech.h"
-
-/* Structure for the JPX-writing device. */
-typedef struct gx_device_jpx_s {
-    gx_device_common;
-    gx_prn_device_common;
-} gx_device_jpx;
-
-/* The device descriptor */
-static dev_proc_print_page(jpx_print_page);
-
-/* ------ The device descriptors ------ */
-
-/* Default X and Y resolution. */
-#ifndef X_DPI
-#  define X_DPI 72
-#endif
-#ifndef Y_DPI
-#  define Y_DPI 72
-#endif
-
-static dev_proc_print_page(jpx_print_page);
-
-/* 24 bit RGB default */
-/* Since the print_page doesn't alter the device, this device can print in the background */
-static const gx_device_procs jpxrgb_procs =
-prn_color_procs(gdev_prn_open, gdev_prn_bg_output_page, gdev_prn_close,
-                       gx_default_rgb_map_rgb_color,
-                       gx_default_rgb_map_color_rgb);
-const gx_device_printer gs_jpxrgb_device = {
-    prn_device_std_body(gx_device_jpx, jpxrgb_procs, "jpx",
-        DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
-        X_DPI, Y_DPI,	/* resolution */
-        0, 0, 0, 0,	/* margins */
-        24,		/* bits per pixel */
-        jpx_print_page)
-};
-
-/* 8 bit Grayscale */
-/* Since the print_page doesn't alter the device, this device can print in the background */
-static const gx_device_procs jpxgray_procs =
-prn_color_procs(gdev_prn_open, gdev_prn_bg_output_page, gdev_prn_close,
-                       gx_default_gray_map_rgb_color,
-                       gx_default_gray_map_color_rgb);
-const gx_device_printer gs_jpxgray_device = {
-    prn_device_body(gx_device_jpx, jpxgray_procs, "jpxgray",
-        DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
-        X_DPI, Y_DPI,	/* resolution */
-        0, 0, 0, 0,	/* margins */
-        1, 8, 255, 0, 256, 0, /* components, depth and min/max values */
-        jpx_print_page)
-};
-
-/* 32 bit CMKY */
-static dev_proc_map_color_rgb(jpx_cmyk_map_color_rgb);
-static dev_proc_map_cmyk_color(jpx_cmyk_map_cmyk_color);
-static const gx_device_procs jpxcmyk_procs =
-{       gdev_prn_open,
-        gx_default_get_initial_matrix,
-/* Since the print_page doesn't alter the device, this device can print in the background */
-        NULL,   /* sync_output */
-        gdev_prn_bg_output_page,
-        gdev_prn_close,
-        NULL,
-        jpx_cmyk_map_color_rgb,
-        NULL,   /* fill_rectangle */
-        NULL,   /* tile_rectangle */
-        NULL,   /* copy_mono */
-        NULL,   /* copy_color */
-        NULL,   /* draw_line */
-        NULL,   /* get_bits */
-        gdev_prn_get_params,
-        gdev_prn_put_params,
-        jpx_cmyk_map_cmyk_color,
-        NULL,   /* get_xfont_procs */
-        NULL,   /* get_xfont_device */
-        NULL,   /* map_rgb_alpha_color */
-        gx_page_device_get_page_device  /* get_page_device */
-};
-const gx_device_printer gs_jpxcmyk_device = {
-    prn_device_std_body(gx_device_jpx, jpxcmyk_procs, "jpxcmyk",
-        DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
-        X_DPI, Y_DPI,	/* resolution */
-        0, 0, 0, 0,	/* margins */
-        32,		/* bits per pixel */
-        jpx_print_page)
-};
-
-/* private color conversion routines;
-   we don't seem to have defaults for cmyk. */
-static int
-jpx_cmyk_map_color_rgb(gx_device * dev, gx_color_index color,
-                        gx_color_value prgb[3])
-{
-    int not_k = color & 0xff,
-        r = not_k - ~(color >> 24),
-        g = not_k - ~((color >> 16) & 0xff),
-        b = not_k - ~((color >> 8) & 0xff);
-
-    prgb[0] = (r < 0 ? 0 : gx_color_value_from_byte(r));
-    prgb[1] = (g < 0 ? 0 : gx_color_value_from_byte(g));
-    prgb[2] = (b < 0 ? 0 : gx_color_value_from_byte(b));
-    return 0;
-}
-
-static gx_color_index
-jpx_cmyk_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
-{
-    gx_color_index color = ~(
-        gx_color_value_to_byte(cv[3]) +
-        ((uint)gx_color_value_to_byte(cv[2]) << 8) +
-        ((uint)gx_color_value_to_byte(cv[1]) << 16) +
-        ((uint)gx_color_value_to_byte(cv[0]) << 24));
-
-    return (color == gx_no_color_index ? color ^ 1 : color);
-}
-
-/* Send the page to the file. */
-static int
-jpx_print_page(gx_device_printer * pdev, gp_file * prn_stream)
-{
-    gx_device_jpx *jdev = (gx_device_jpx *) pdev;
-    gs_memory_t *mem = jdev->memory;
-    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
-    byte *in = gs_alloc_bytes(mem, line_size, "jpx_print_page(in)");
-    byte *fbuf = 0;
-    uint fbuf_size;
-    byte *jbuf = 0;
-    uint jbuf_size;
-    int lnum;
-    int code = 0;
-    stream_jpxe_state state;
-    stream fstrm, cstrm;
-
-    if (in == 0) {
-        code = gs_note_error(gs_error_VMerror);
-        goto fail;
-    }
-    /* Create the jpx encoder state. */
-    s_init_state((stream_state *)&state, &s_jpxe_template, 0);
-    if (state.templat->set_defaults)
-        (*state.templat->set_defaults) ((stream_state *) & state);
-    state.width = jdev->width;
-    state.height = jdev->height;
-    switch (jdev->color_info.depth) {
-        case 32: state.colorspace = gs_jpx_cs_cmyk; break;
-        case 24: state.colorspace = gs_jpx_cs_rgb; break;
-        case  8: state.colorspace = gs_jpx_cs_gray; break;
-        default:
-            state.colorspace = gs_jpx_cs_gray; /* safest option */
-            dmlprintf1(mem, "unexpected color_info depth %d\n",
-                                        jdev->color_info.depth);
-    }
-    state.bpc = 8; /* currently only 8 bits per component is supported */
-
-    /* ask for lossless encoding */
-    /* state.lossless = 1; */
-    /* or, set the quality level different from the default */
-    /* state.quality = 35; */
-
-    /* Set up the streams. */
-    fbuf_size = max(512 /* arbitrary */ , state.templat->min_out_size);
-    jbuf_size = state.templat->min_in_size;
-    if ((fbuf = gs_alloc_bytes(mem, fbuf_size, "jpx_print_page(fbuf)")) == 0 ||
-        (jbuf = gs_alloc_bytes(mem, jbuf_size, "jpx_print_page(jbuf)")) == 0
-        ) {
-        code = gs_note_error(gs_error_VMerror);
-        goto done;
-    }
-    s_init(&fstrm, mem);
-    swrite_file(&fstrm, prn_stream, fbuf, fbuf_size);
-    s_init(&cstrm, mem);
-    s_std_init(&cstrm, jbuf, jbuf_size, &s_filter_write_procs,
-               s_mode_write);
-    cstrm.state = (stream_state *) & state;
-    cstrm.procs.process = state.templat->process;
-    cstrm.strm = &fstrm;
-    if (state.templat->init)
-        (*state.templat->init) (cstrm.state);
-
-    /* Copy the data to the output. */
-    for (lnum = 0; lnum < jdev->height; ++lnum) {
-        byte *data;
-        uint ignore_used;
-
-        if (cstrm.end_status) {
-            code = gs_note_error(gs_error_ioerror);
-            goto done;
-        }
-        code = gdev_prn_get_bits(pdev, lnum, in, &data);
-        if (code < 0)
-            goto done;
-        sputs(&cstrm, data, state.stride, &ignore_used);
-    }
-
-    /* Wrap up. */
-    sclose(&cstrm);
-    sflush(&fstrm);
-  done:
-    gs_free_object(mem, jbuf, "jpx_print_page(jbuf)");
-    gs_free_object(mem, fbuf, "jpx_print_page(fbuf)");
-    gs_free_object(mem, in, "jpx_print_page(in)");
-    return code;
-  fail:
-    gs_free_object(mem, in, "jpx_print_page(in)");
-    return code;
-}
diff --git a/devices/gdevl31s.c b/devices/gdevl31s.c
index a3225ea9..9a32d434 100644
--- a/devices/gdevl31s.c
+++ b/devices/gdevl31s.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevlbp8.c b/devices/gdevlbp8.c
index ca96b69c..a53b2461 100644
--- a/devices/gdevlbp8.c
+++ b/devices/gdevlbp8.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevlj56.c b/devices/gdevlj56.c
index a3314e03..ed022c0c 100644
--- a/devices/gdevlj56.c
+++ b/devices/gdevlj56.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevlp8k.c b/devices/gdevlp8k.c
index 60d3c6e3..8083db8a 100644
--- a/devices/gdevlp8k.c
+++ b/devices/gdevlp8k.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevlxm.c b/devices/gdevlxm.c
index 6e557ede..4f9bfca1 100644
--- a/devices/gdevlxm.c
+++ b/devices/gdevlxm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -298,7 +298,7 @@ lxm5700m_print_page(gx_device_printer *pdev, gp_file *prn_stream)
                     sxMask = 0x80>>(sx%8);
 
                     /* loop through all the swipeHeight bits of this column.
-                    
+
                     Note that  looks like it can get out of range, so we
                     check for this here. This fixes bug 701842.
 
diff --git a/devices/gdevmeds.c b/devices/gdevmeds.c
index 9435fed3..08ca0aa4 100644
--- a/devices/gdevmeds.c
+++ b/devices/gdevmeds.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevmeds.h b/devices/gdevmeds.h
index 2c247299..85344222 100644
--- a/devices/gdevmeds.h
+++ b/devices/gdevmeds.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevmgr.c b/devices/gdevmgr.c
index d0b81b11..a2d9b4d1 100644
--- a/devices/gdevmgr.c
+++ b/devices/gdevmgr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevmgr.h b/devices/gdevmgr.h
index 483237ec..dbea5895 100644
--- a/devices/gdevmgr.h
+++ b/devices/gdevmgr.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevmiff.c b/devices/gdevmiff.c
index c1d56496..7919f7a5 100644
--- a/devices/gdevmiff.c
+++ b/devices/gdevmiff.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevn533.c b/devices/gdevn533.c
index c697d441..aa4ebef3 100644
--- a/devices/gdevn533.c
+++ b/devices/gdevn533.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevo182.c b/devices/gdevo182.c
index ec26205c..ce57db05 100644
--- a/devices/gdevo182.c
+++ b/devices/gdevo182.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevocr.c b/devices/gdevocr.c
index ddfaa809..cd1efeb1 100644
--- a/devices/gdevocr.c
+++ b/devices/gdevocr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -34,7 +34,8 @@ static dev_proc_print_page(ocr_print_page);
 static dev_proc_print_page(hocr_print_page);
 static dev_proc_get_params(ocr_get_params);
 static dev_proc_put_params(ocr_put_params);
-static dev_proc_open_device(hocr_open);
+static dev_proc_open_device(ocr_open);
+static dev_proc_close_device(ocr_close);
 static dev_proc_close_device(hocr_close);
 
 typedef struct gx_device_ocr_s gx_device_ocr;
@@ -43,13 +44,15 @@ struct gx_device_ocr_s {
     gx_prn_device_common;
     gx_downscaler_params downscale;
     char language[1024];
+    int engine;
     int page_count;
+    void *api;
 };
 
 /* 8-bit gray bitmap -> UTF8 OCRd text */
 
 static const gx_device_procs ocr_procs =
-prn_color_params_procs(gdev_prn_open, gdev_prn_bg_output_page, gdev_prn_close,
+prn_color_params_procs(ocr_open, gdev_prn_bg_output_page, ocr_close,
                        gx_default_gray_map_rgb_color,
                        gx_default_gray_map_color_rgb,
                        ocr_get_params, ocr_put_params);
@@ -66,7 +69,7 @@ const gx_device_ocr gs_ocr_device =
 /* 8-bit gray bitmap -> HTML OCRd text */
 
 static const gx_device_procs hocr_procs =
-prn_color_params_procs(hocr_open, gdev_prn_bg_output_page, hocr_close,
+prn_color_params_procs(ocr_open, gdev_prn_bg_output_page, hocr_close,
                        gx_default_gray_map_rgb_color,
                        gx_default_gray_map_color_rgb,
                        ocr_get_params, ocr_put_params);
@@ -86,15 +89,32 @@ const gx_device_ocr gs_hocr_device =
 #define HOCR_TRAILER " \n\n"
 
 static int
-hocr_open(gx_device *pdev)
+ocr_open(gx_device *pdev)
 {
     gx_device_ocr *dev = (gx_device_ocr *)pdev;
+    int code;
 
     dev->page_count = 0;
 
+    code = ocr_init_api(dev->memory->non_gc_memory,
+                        dev->language, dev->engine, &dev->api);
+    if (code < 0)
+        return code;
+
     return gdev_prn_open(pdev);
 }
 
+static int
+ocr_close(gx_device *pdev)
+{
+    gx_device_ocr *dev = (gx_device_ocr *)pdev;
+    gx_device_printer * const ppdev = (gx_device_printer *)pdev;
+
+    ocr_fin_api(dev->memory->non_gc_memory, dev->api);
+
+    return gdev_prn_close(pdev);
+}
+
 static int
 hocr_close(gx_device *pdev)
 {
@@ -105,7 +125,7 @@ hocr_close(gx_device *pdev)
        gp_fwrite(HOCR_TRAILER, 1, sizeof(HOCR_TRAILER)-1, dev->file);
     }
 
-    return gdev_prn_close(pdev);
+    return ocr_close(pdev);
 }
 
 static int
@@ -127,6 +147,9 @@ ocr_get_params(gx_device * dev, gs_param_list * plist)
     if ((code = param_write_string(plist, "OCRLanguage", &langstr)) < 0)
         ecode = code;
 
+    if ((code = param_write_int(plist, "OCREngine", &pdev->engine)) < 0)
+        ecode = code;
+
     if ((code = gx_downscaler_write_params(plist, &pdev->downscale,
                                            GX_DOWNSCALER_PARAMS_MFS)) < 0)
         ecode = code;
@@ -146,6 +169,7 @@ ocr_put_params(gx_device *dev, gs_param_list *plist)
     gs_param_string langstr;
     const char *param_name;
     size_t len;
+    int engine;
 
     switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
         case 0:
@@ -162,6 +186,17 @@ ocr_put_params(gx_device *dev, gs_param_list *plist)
             param_signal_error(plist, param_name, ecode);
     }
 
+    switch (code = param_read_int(plist, (param_name = "OCREngine"), &engine)) {
+        case 0:
+            pdev->engine = engine;
+            break;
+        case 1:
+            break;
+        default:
+            ecode = code;
+            param_signal_error(plist, param_name, ecode);
+    }
+
     code = gx_downscaler_read_params(plist, &pdev->downscale,
                                      GX_DOWNSCALER_PARAMS_MFS);
     if (code < 0)
@@ -219,20 +254,20 @@ do_ocr_print_page(gx_device_ocr * pdev, gp_file * file, int hocr)
         goto done;
 
     if (hocr)
-        code = ocr_image_to_hocr(pdev->memory,
+        code = ocr_image_to_hocr(pdev->api,
                                  width, height,
                                  8, raster,
                                  (int)pdev->HWResolution[0],
                                  (int)pdev->HWResolution[1],
                                  data, 0, pdev->page_count,
-                                 "eng", &out);
+                                 &out);
     else
-        code = ocr_image_to_utf8(pdev->memory,
+        code = ocr_image_to_utf8(pdev->api,
                                  width, height,
                                  8, raster,
                                  (int)pdev->HWResolution[0],
                                  (int)pdev->HWResolution[1],
-                                 data, 0, "eng", &out);
+                                 data, 0, &out);
     if (code < 0)
         goto done;
     if (out)
@@ -241,7 +276,8 @@ do_ocr_print_page(gx_device_ocr * pdev, gp_file * file, int hocr)
             gp_fwrite(HOCR_HEADER, 1, sizeof(HOCR_HEADER)-1, file);
         }
         gp_fwrite(out, 1, strlen(out), file);
-        gs_free_object(pdev->memory, out, "ocr_image_to_utf8");
+        gs_free_object(pdev->memory->non_gc_memory,
+                       out, "ocr_image_to_utf8");
     }
 
   done:
diff --git a/devices/gdevokii.c b/devices/gdevokii.c
index 62fe616c..f9eaf6a8 100644
--- a/devices/gdevokii.c
+++ b/devices/gdevokii.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpbm.c b/devices/gdevpbm.c
index fd9b2619..9bba6889 100644
--- a/devices/gdevpbm.c
+++ b/devices/gdevpbm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpcl.c b/devices/gdevpcl.c
index be196663..ce1e6f93 100644
--- a/devices/gdevpcl.c
+++ b/devices/gdevpcl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpcl.h b/devices/gdevpcl.h
index 3d167ae4..3b98fff1 100644
--- a/devices/gdevpcl.h
+++ b/devices/gdevpcl.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpcx.c b/devices/gdevpcx.c
index 137955cb..1515d411 100644
--- a/devices/gdevpcx.c
+++ b/devices/gdevpcx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpdfimg.c b/devices/gdevpdfimg.c
index 313d714f..7d04755b 100644
--- a/devices/gdevpdfimg.c
+++ b/devices/gdevpdfimg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -32,11 +32,13 @@
 
 #include "gdevpdfimg.h"
 
-#define	    COMPRESSION_NONE	1	/* dump mode */
-#define	    COMPRESSION_LZW		2       /* Lempel-Ziv  & Welch */
-#define	    COMPRESSION_FLATE	3
-#define	    COMPRESSION_JPEG	4
-#define	    COMPRESSION_RLE		5
+enum {
+    COMPRESSION_NONE	= 1,	/* dump mode */
+    COMPRESSION_LZW	= 2,    /* Lempel-Ziv & Welch */
+    COMPRESSION_FLATE	= 3,
+    COMPRESSION_JPEG	= 4,
+    COMPRESSION_RLE	= 5
+};
 
 static struct compression_string {
     unsigned char id;
@@ -256,6 +258,7 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
 
         stream_puts(pdf_dev->strm, "%PDF-1.3\n");
         stream_puts(pdf_dev->strm, "%\307\354\217\242\n");
+        pdfimage_write_args_comment(pdf_dev,pdf_dev->strm);
 
         if (pdf_dev->ocr.file_init) {
             code = pdf_dev->ocr.file_init(pdf_dev);
@@ -270,7 +273,6 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
             }
         }
 
-        pdfimage_write_args_comment(pdf_dev, pdf_dev->strm);
         pdf_dev->Pages = page;
     } else {
         pdfimage_page *current = pdf_dev->Pages;
@@ -278,7 +280,7 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
             current = current->next;
         current->next = page;
     }
-    page->ImageObjectNumber = (pdf_dev->NumPages * 4) + 3 + pdf_dev->ocr.file_objects;
+    page->ImageObjectNumber = (pdf_dev->NumPages * 4) + PDFIMG_STATIC_OBJS + pdf_dev->ocr.file_objects;
     page->LengthObjectNumber = page->ImageObjectNumber + 1;
     page->PageStreamObjectNumber = page->LengthObjectNumber + 1;
     page->PageDictObjectNumber = page->PageStreamObjectNumber + 1;
@@ -596,7 +598,7 @@ pdf_image_downscale_and_print_page(gx_device_printer *dev,
     stream_puts(pdf_dev->strm, Buffer);
     pprintd1(pdf_dev->strm, "/Resources <<\n/XObject <<\n/Im1 %d 0 R\n>>\n", page->ImageObjectNumber);
     if (pdf_dev->ocr.file_init)
-        stream_puts(pdf_dev->strm, "/Font <<\n/Ft0 3 0 R\n>>\n");
+        pprintd1(pdf_dev->strm, "/Font <<\n/Ft0 %d 0 R\n>>\n", PDFIMG_STATIC_OBJS);
     stream_puts(pdf_dev->strm, ">>\n>>\nendobj\n");
 
     gx_downscaler_fin(&ds);
@@ -622,12 +624,10 @@ static void write_fileID(stream *s, const byte *str, int size)
         stream_cursor_write w;
         int status;
 
-        r.ptr = str - 1;
-        r.limit = r.ptr + size;
-        w.limit = buf + sizeof(buf) - 1;
+        stream_cursor_read_init(&r, str, size);
+
         do {
-            /* One picky compiler complains if we initialize to buf - 1. */
-            w.ptr = buf;  w.ptr--;
+            stream_cursor_write_init(&w, buf, sizeof(buf));
             status = (*templat->process) (st, &r, &w, true);
             stream_write(s, buf, (uint) (w.ptr + 1 - buf));
         }
@@ -722,7 +722,7 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm)
         pdf_store_default_Producer(Producer);
 
         pdf_dev->RootOffset = stell(pdf_dev->strm);
-        stream_puts(pdf_dev->strm, "1 0 obj\n<<\n/Pages 2 0 R\n/Type /Catalog\n>>\nendobj\n");
+        stream_puts(pdf_dev->strm, "1 0 obj\n<<\n/Pages 2 0 R\n/Type /Catalog\n/Info 3 0 R\n>>\nendobj\n");
 
         pdf_dev->PagesOffset = stell(pdf_dev->strm);
         pprintd1(pdf_dev->strm, "2 0 obj\n<<\n/Count %d\n", pdf_dev->NumPages);
@@ -755,13 +755,21 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm)
             tms.tm_hour, tms.tm_min, tms.tm_sec,
             timesign, timeoffset / 60, timeoffset % 60);
 
+        pdf_dev->InfoOffset = stell(pdf_dev->strm);
+        stream_puts(pdf_dev->strm, "3 0 obj\n<<\n/Producer");
+        stream_puts(pdf_dev->strm, Producer);
+        stream_puts(pdf_dev->strm, "\n/CreationDate");
+        stream_puts(pdf_dev->strm, CreationDate);
+        stream_puts(pdf_dev->strm, "\n>>\nendobj\n");
+
         pdf_dev->xrefOffset = stell(pdf_dev->strm);
         if (PCLm)
             pprintd1(pdf_dev->strm, "xref\n0 %d\n0000000000 65536 f \n", pdf_dev->NextObject);
         else
-            pprintd1(pdf_dev->strm, "xref\n0 %d\n0000000000 65536 f \n", (pdf_dev->NumPages * 4) + 3 + pdf_dev->ocr.file_objects);
+            pprintd1(pdf_dev->strm, "xref\n0 %d\n0000000000 65536 f \n", (pdf_dev->NumPages * 4) + PDFIMG_STATIC_OBJS + pdf_dev->ocr.file_objects);
         write_xref_entry(pdf_dev->strm, pdf_dev->RootOffset);
         write_xref_entry(pdf_dev->strm, pdf_dev->PagesOffset);
+        write_xref_entry(pdf_dev->strm, pdf_dev->InfoOffset);
         if (pdf_dev->ocr.file_objects) {
             int i;
 
@@ -779,7 +787,7 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm)
                 write_xref_entry(pdf_dev->strm, page->PageDictOffset);
                 page = page->next;
             }
-            pprintd1(pdf_dev->strm, "trailer\n<<\n/Size %d\n/Root 1 0 R\n/ID [", (pdf_dev->NumPages * 4) + 3 + pdf_dev->ocr.file_objects);
+            pprintd1(pdf_dev->strm, "trailer\n<<\n/Size %d\n/Root 1 0 R\n/ID [", (pdf_dev->NumPages * 4) + PDFIMG_STATIC_OBJS + pdf_dev->ocr.file_objects);
             pdf_compute_fileID(pdf_dev, fileID, CreationDate, Title, Producer);
             write_fileID(pdf_dev->strm, (const byte *)&fileID, 16);
             write_fileID(pdf_dev->strm, (const byte *)&fileID, 16);
diff --git a/devices/gdevpdfimg.h b/devices/gdevpdfimg.h
index baf8175e..322c1622 100644
--- a/devices/gdevpdfimg.h
+++ b/devices/gdevpdfimg.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -19,6 +19,13 @@
 #include "gdevprn.h"
 #include "gxdownscale.h"
 
+/* This is the number of always defined objects; object 0 the head
+ * of the free list, Object 1 the Root dictionary, Object 2
+ * the Pages dictionary and object 3 the Info dictionary
+ */
+#define PDFIMG_STATIC_OBJS 4
+#define OCR_MAX_FILE_OBJECTS 8
+
 typedef struct pdfimage_page_s {
     int ImageObjectNumber;
     gs_offset_t ImageOffset;
@@ -39,8 +46,6 @@ typedef struct PCLm_temp_file_s {
     byte *strm_buf;
 } PCLm_temp_file_t;
 
-#define OCR_MAX_FILE_OBJECTS 8
-
 typedef struct gx_device_pdf_image_s {
     gx_device_common;
     gx_prn_device_common;
@@ -55,6 +60,7 @@ typedef struct gx_device_pdf_image_s {
     int NumPages;
     gs_offset_t RootOffset;
     gs_offset_t PagesOffset;
+    gs_offset_t InfoOffset;
     gs_offset_t xrefOffset;
     pdfimage_page *Pages;
     PCLm_temp_file_t xref_stream;
@@ -64,6 +70,7 @@ typedef struct gx_device_pdf_image_s {
     /* OCR data */
     struct {
         char language[1024];
+        int engine;
         void *state;
 
         /* Number of "file level" objects - i.e. the number of objects
diff --git a/devices/gdevpdfocr.c b/devices/gdevpdfocr.c
index 95d358b1..afc73ff2 100644
--- a/devices/gdevpdfocr.c
+++ b/devices/gdevpdfocr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -31,24 +31,7 @@
 #include "sjpeg.h"
 
 #include "gdevpdfimg.h"
-
-#define	    COMPRESSION_NONE	1	/* dump mode */
-#define	    COMPRESSION_LZW		2       /* Lempel-Ziv  & Welch */
-#define	    COMPRESSION_FLATE	3
-#define	    COMPRESSION_JPEG	4
-#define	    COMPRESSION_RLE		5
-
-static struct compression_string {
-    unsigned char id;
-    const char *str;
-} compression_strings [] = {
-    { COMPRESSION_NONE, "None" },
-    { COMPRESSION_LZW, "LZW" },     /* Not supported in PCLm */
-    { COMPRESSION_FLATE, "Flate" },
-    { COMPRESSION_JPEG, "JPEG" },
-    { COMPRESSION_RLE, "RLE" },
-    { 0, NULL }
-};
+#include "tessocr.h"
 
 int pdf_ocr_open(gx_device *pdev);
 int pdf_ocr_close(gx_device *pdev);
@@ -63,6 +46,7 @@ pdfocr_put_some_params(gx_device * dev, gs_param_list * plist)
     gs_param_string langstr;
     const char *param_name;
     size_t len;
+    int engine;
 
     switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
         case 0:
@@ -79,6 +63,17 @@ pdfocr_put_some_params(gx_device * dev, gs_param_list * plist)
             param_signal_error(plist, param_name, ecode);
     }
 
+    switch (code = param_read_int(plist, (param_name = "OCREngine"), &engine)) {
+        case 0:
+            pdf_dev->ocr.engine = engine;
+            break;
+        case 1:
+            break;
+        default:
+            ecode = code;
+            param_signal_error(plist, param_name, ecode);
+    }
+
     return code;
 }
 
@@ -120,6 +115,9 @@ pdfocr_get_some_params(gx_device * dev, gs_param_list * plist)
     if ((code = param_write_string(plist, "OCRLanguage", &langstr)) < 0)
         ecode = code;
 
+    if ((code = param_write_int(plist, "OCREngine", &pdf_dev->ocr.engine)) < 0)
+        ecode = code;
+
     return ecode;
 }
 
@@ -228,21 +226,27 @@ const gx_device_pdf_image gs_pdfocr32_device = {
     0    /* JPEGQ */
 };
 
+/* These strings have object numbers built into them which are only
+ * correct for a specific value of PDFIMG_STATIC_OBJS (currently 4)
+ * If we add more static objects (eg Metadata) then we need to update
+ * the values in the strings below.
+ */
+
 /* Funky font */
 static const char funky_font[] =
-"3 0 obj\n<>\nendobj\n";
 
 static const char funky_font2[] =
-"4 0 obj\n<>"
-"/FontDescriptor 7 0 R/Subtype /CIDFontType2/Type/Font"
+"/FontDescriptor 8 0 R/Subtype /CIDFontType2/Type/Font"
 "/DW 500>>\nendobj\n";
 
 static const char funky_font3[] =
-"5 0 obj\n<>stream\n";
 
 static const char funky_font3a[] = {
@@ -279,7 +283,7 @@ static const char funky_font3b[] =
 "endstream\nendobj\n";
 
 static const char funky_font4[] =
-"6 0 obj\n<>\nstream\n"
+"7 0 obj\n<>\nstream\n"
 "/CIDInit /ProcSet findresource begin\n"
 "12 dict begin\n"
 "begincmap\n"
@@ -305,13 +309,13 @@ static const char funky_font4[] =
 "endobj\n";
 
 static const char funky_font5[] =
-"7 0 obj\n"
+"8 0 obj\n"
 "<>\nendobj\n";
 
 static const char funky_font6[] =
-"8 0 obj\n<>\nstream\n";
+"9 0 obj\n<>\nstream\n";
 
 static const char funky_font6a[] =
 {
@@ -416,7 +420,7 @@ ocr_file_init(gx_device_pdf_image *dev)
     stream_write(dev->strm, funky_font6a, sizeof(funky_font6a));
     stream_write(dev->strm, funky_font6b, sizeof(funky_font6b)-1);
 
-    return ocr_init_api(dev->memory, language, &dev->ocr.state);
+    return ocr_init_api(dev->memory->non_gc_memory, language, dev->ocr.engine, &dev->ocr.state);
 }
 
 static void
diff --git a/devices/gdevpe.c b/devices/gdevpe.c
index d2590b92..b4d462f3 100644
--- a/devices/gdevpe.c
+++ b/devices/gdevpe.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevperm.c b/devices/gdevperm.c
index e03c8cae..80afdf48 100644
--- a/devices/gdevperm.c
+++ b/devices/gdevperm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevphex.c b/devices/gdevphex.c
index 3eccb787..7afc6ba3 100644
--- a/devices/gdevphex.c
+++ b/devices/gdevphex.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpjet.c b/devices/gdevpjet.c
index bd428295..8df438f5 100644
--- a/devices/gdevpjet.c
+++ b/devices/gdevpjet.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevplan.c b/devices/gdevplan.c
index 7e5e5f0a..bf9a81e5 100644
--- a/devices/gdevplan.c
+++ b/devices/gdevplan.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevplib.c b/devices/gdevplib.c
index 026b4f8f..f1bf6598 100644
--- a/devices/gdevplib.c
+++ b/devices/gdevplib.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevplib.h b/devices/gdevplib.h
index e4c87345..b724eb42 100644
--- a/devices/gdevplib.h
+++ b/devices/gdevplib.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpm.h b/devices/gdevpm.h
index d79b0f37..af7fec19 100644
--- a/devices/gdevpm.h
+++ b/devices/gdevpm.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpng.c b/devices/gdevpng.c
index a564e6c3..4833efb1 100644
--- a/devices/gdevpng.c
+++ b/devices/gdevpng.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpsd.c b/devices/gdevpsd.c
index 27a6f262..03495ae0 100644
--- a/devices/gdevpsd.c
+++ b/devices/gdevpsd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -752,56 +752,12 @@ psd_get_params_cmyk(gx_device * pdev, gs_param_list * plist)
     return psd_get_params_generic(pdev, plist, 1);
 }
 
-
-
-/* Compare a C string and a gs_param_string. */
-static bool
-param_string_eq(const gs_param_string *pcs, const char *str)
-{
-    return (strlen(str) == pcs->size &&
-            !strncmp(str, (const char *)pcs->data, pcs->size));
-}
-
-static int
-psd_set_color_model(psd_device *xdev, psd_color_model color_model)
-{
-    xdev->color_model = color_model;
-    if (color_model == psd_DEVICE_GRAY) {
-        xdev->devn_params.std_colorant_names = DeviceGrayComponents;
-        xdev->devn_params.num_std_colorant_names = 1;
-        xdev->color_info.cm_name = "DeviceGray";
-        xdev->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE;
-    } else if (color_model == psd_DEVICE_RGB) {
-        xdev->devn_params.std_colorant_names = DeviceRGBComponents;
-        xdev->devn_params.num_std_colorant_names = 3;
-        xdev->color_info.cm_name = "DeviceRGB";
-        xdev->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE;
-    } else if (color_model == psd_DEVICE_CMYK) {
-        xdev->devn_params.std_colorant_names = DeviceCMYKComponents;
-        xdev->devn_params.num_std_colorant_names = 4;
-        xdev->color_info.cm_name = "DeviceCMYK";
-        xdev->color_info.polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
-    } else if (color_model == psd_DEVICE_N) {
-        xdev->devn_params.std_colorant_names = DeviceCMYKComponents;
-        xdev->devn_params.num_std_colorant_names = 4;
-        xdev->color_info.cm_name = "DeviceN";
-        xdev->color_info.polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
-    } else {
-        return -1;
-    }
-
-    return 0;
-}
-
 /* Set parameters.  We allow setting the number of bits per component. */
 static int
 psd_put_params_generic(gx_device * pdev, gs_param_list * plist, int cmyk)
 {
     psd_device * const pdevn = (psd_device *) pdev;
     int code = 0;
-    gs_param_string pcm;
-    psd_color_model color_model = pdevn->color_model;
-    gx_device_color_info save_info = pdevn->color_info;
 
     code = gx_downscaler_read_params(plist, &pdevn->downscale,
                                      cmyk ? GX_DOWNSCALER_PARAMS_TRAP : 0);
@@ -835,37 +791,10 @@ psd_put_params_generic(gx_device * pdev, gs_param_list * plist, int cmyk)
             break;
     }
 
-    if (code >= 0)
-        code = param_read_name(plist, "ProcessColorModel", &pcm);
-
-    /* Bug 696318.  Don't allow process color model change for RGB device */
-    if (code == 0 && color_model != psd_DEVICE_RGB) {
-        if (param_string_eq (&pcm, "DeviceGray"))
-            color_model = psd_DEVICE_GRAY;
-        else if (param_string_eq (&pcm, "DeviceRGB"))
-            color_model = psd_DEVICE_RGB;
-        else if (param_string_eq (&pcm, "DeviceCMYK"))
-            color_model = psd_DEVICE_CMYK;
-        else if (param_string_eq (&pcm, "DeviceN"))
-            color_model = psd_DEVICE_N;
-        else {
-            param_signal_error(plist, "ProcessColorModel",
-                               code = gs_error_rangecheck);
-        }
-    }
-
-    if (code >= 0)
-        code = psd_set_color_model(pdevn, color_model);
-
     /* handle the standard DeviceN related parameters */
-    if (code == 0)
+    if (code >= 0)
         code = gx_devn_prn_put_params(pdev, plist);
 
-    if (code < 0) {
-        pdev->color_info = save_info;
-        return code;
-    }
-
     return code;
 }
 
diff --git a/devices/gdevpsd.h b/devices/gdevpsd.h
index 98d2e9ae..a10e4ec7 100644
--- a/devices/gdevpsd.h
+++ b/devices/gdevpsd.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpsim.c b/devices/gdevpsim.c
index 4e4080fe..1640da74 100644
--- a/devices/gdevpsim.c
+++ b/devices/gdevpsim.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevpxut.c b/devices/gdevpxut.c
index 08d7741a..c09692b1 100644
--- a/devices/gdevpxut.c
+++ b/devices/gdevpxut.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -45,7 +45,7 @@ px_write_file_header(stream *s, const gx_device *dev, bool staple)
     static const char *const resolution_2400 = "2400";
     static const char *const file_header =
         "\n@PJL ENTER LANGUAGE = PCLXL\n\
-) HP-PCL XL;1;1;Comment Copyright Artifex Sofware, Inc. 2005\000\n";
+) HP-PCL XL;1;1;Comment Copyright Artifex Sofware, Inc. 2005-2021\000\n";
     static const byte stream_header[] = {
         DA(pxaUnitsPerMeasure),
         DUB(0), DA(pxaMeasure),
diff --git a/devices/gdevpxut.h b/devices/gdevpxut.h
index 28f55847..1db5d332 100644
--- a/devices/gdevpxut.h
+++ b/devices/gdevpxut.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevrinkj.c b/devices/gdevrinkj.c
index d10a7a1b..a49ee1c0 100644
--- a/devices/gdevrinkj.c
+++ b/devices/gdevrinkj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevsj48.c b/devices/gdevsj48.c
index 8b1304b9..9a004446 100644
--- a/devices/gdevsj48.c
+++ b/devices/gdevsj48.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevsnfb.c b/devices/gdevsnfb.c
index 76d5cf47..6ffc7ba4 100644
--- a/devices/gdevsnfb.c
+++ b/devices/gdevsnfb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevsppr.c b/devices/gdevsppr.c
index 8257aa39..29d34dd9 100644
--- a/devices/gdevsppr.c
+++ b/devices/gdevsppr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevstc.c b/devices/gdevstc.c
index 22314777..5d8bf425 100644
--- a/devices/gdevstc.c
+++ b/devices/gdevstc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevstc.h b/devices/gdevstc.h
index 7db27e9a..1b9910d0 100644
--- a/devices/gdevstc.h
+++ b/devices/gdevstc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevstc1.c b/devices/gdevstc1.c
index dd10268c..cabaac5a 100644
--- a/devices/gdevstc1.c
+++ b/devices/gdevstc1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevstc2.c b/devices/gdevstc2.c
index 90dca523..e8150565 100644
--- a/devices/gdevstc2.c
+++ b/devices/gdevstc2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevstc3.c b/devices/gdevstc3.c
index 56fea31d..a4ed4f10 100644
--- a/devices/gdevstc3.c
+++ b/devices/gdevstc3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevstc4.c b/devices/gdevstc4.c
index 1c7c4589..b747b9e3 100644
--- a/devices/gdevstc4.c
+++ b/devices/gdevstc4.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtfax.c b/devices/gdevtfax.c
index b8aa7e74..d7abc954 100644
--- a/devices/gdevtfax.c
+++ b/devices/gdevtfax.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtfax.h b/devices/gdevtfax.h
index deaa6516..60fd90f8 100644
--- a/devices/gdevtfax.h
+++ b/devices/gdevtfax.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtfnx.c b/devices/gdevtfnx.c
index b3fea72e..e7c7f0fe 100644
--- a/devices/gdevtfnx.c
+++ b/devices/gdevtfnx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtifs.c b/devices/gdevtifs.c
index 4ecafa8b..d72549f5 100644
--- a/devices/gdevtifs.c
+++ b/devices/gdevtifs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtifs.h b/devices/gdevtifs.h
index adc9f4ae..bbd01bb6 100644
--- a/devices/gdevtifs.h
+++ b/devices/gdevtifs.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtknk.c b/devices/gdevtknk.c
index 741b5925..7ea92326 100644
--- a/devices/gdevtknk.c
+++ b/devices/gdevtknk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtrac.c b/devices/gdevtrac.c
index 77b7dc93..7fff3862 100644
--- a/devices/gdevtrac.c
+++ b/devices/gdevtrac.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
index 3dde3523..1a52aede 100644
--- a/devices/gdevtsep.c
+++ b/devices/gdevtsep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -2240,7 +2240,13 @@ tiffsep_print_page(gx_device_printer * pdev, gp_file * file)
         for (sep_num = 0; sep_num < num_spot; sep_num++) {
             copy_separation_name(tfdev, name,
                 gp_file_name_sizeof - base_filename_length - SUFFIX_SIZE, sep_num, 0);
-            dmlprintf1(pdev->memory, "%%%%SeparationName: %s\n", name);
+            dmlprintf1(pdev->memory, "%%%%SeparationName: %s", name);
+            dmlprintf4(pdev->memory, " CMYK = [ %d %d %d %d ]\n",
+                tfdev->equiv_cmyk_colors.color[sep_num].c,
+                tfdev->equiv_cmyk_colors.color[sep_num].m,
+                tfdev->equiv_cmyk_colors.color[sep_num].y,
+                tfdev->equiv_cmyk_colors.color[sep_num].k
+            );
         }
     }
 
diff --git a/devices/gdevupd.c b/devices/gdevupd.c
index 702548d8..badc8041 100644
--- a/devices/gdevupd.c
+++ b/devices/gdevupd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevwpr2.c b/devices/gdevwpr2.c
index 3a4b97b6..c91e82a1 100644
--- a/devices/gdevwpr2.c
+++ b/devices/gdevwpr2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -704,7 +704,7 @@ win_pr2_set_bpp(gx_device * dev, int depth)
             if (wdev->icc_struct) {
                 rc_decrement(wdev->icc_struct, "win_pr2_set_bpp");
             }
-            wdev->icc_struct = gsicc_new_device_profile_array(wdev->memory);
+            wdev->icc_struct = gsicc_new_device_profile_array((gx_device *)wdev);
 
             if (wdev->icc_struct) {
                 code = gsicc_set_device_profile(dev, dev->memory,
@@ -729,7 +729,7 @@ win_pr2_set_bpp(gx_device * dev, int depth)
             if (wdev->icc_struct) {
                 rc_decrement(wdev->icc_struct, "win_pr2_set_bpp");
             }
-            wdev->icc_struct = gsicc_new_device_profile_array(wdev->memory);
+            wdev->icc_struct = gsicc_new_device_profile_array((gx_device *)wdev);
 
             if (wdev->icc_struct) {
                 code = gsicc_set_device_profile(dev, dev->memory,
@@ -754,7 +754,7 @@ win_pr2_set_bpp(gx_device * dev, int depth)
             if (wdev->icc_struct) {
                 rc_decrement(wdev->icc_struct, "win_pr2_set_bpp");
             }
-            wdev->icc_struct = gsicc_new_device_profile_array(wdev->memory);
+            wdev->icc_struct = gsicc_new_device_profile_array((gx_device *)wdev);
 
             if (wdev->icc_struct) {
                 code = gsicc_set_device_profile(dev, dev->memory,
@@ -776,7 +776,7 @@ win_pr2_set_bpp(gx_device * dev, int depth)
             if (wdev->icc_struct) {
                 rc_decrement(wdev->icc_struct, "win_pr2_set_bpp");
             }
-            wdev->icc_struct = gsicc_new_device_profile_array(wdev->memory);
+            wdev->icc_struct = gsicc_new_device_profile_array((gx_device *)wdev);
 
             if (wdev->icc_struct) {
                 code = gsicc_set_device_profile(dev, dev->memory,
diff --git a/devices/gdevx.c b/devices/gdevx.c
index cfde7543..438af172 100644
--- a/devices/gdevx.c
+++ b/devices/gdevx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -36,8 +36,6 @@
 /****** THIS IS USELESS.  XGetImage DOES NOT GENERATE EXPOSURE EVENTS. ******/
 #define GET_IMAGE_EXPOSURES 0
 
-/* GC descriptors */
-private_st_device_X();
 
 /* Forward references */
 static int x_copy_image(gx_device_X * xdev, const byte * base, int sourcex,
@@ -240,6 +238,23 @@ const gx_device_X this_device = { \
     } \
 };
 
+static void
+x_finalize(const gs_memory_t *cmem, void *vpdev)
+{
+    /* Do an actual close of the window. */
+    gx_device_X *xdev = (gx_device_X *)vpdev;
+
+    if (xdev->dpy) {
+        XCloseDisplay(xdev->dpy);
+        xdev->dpy = NULL;
+    }
+    gx_device_finalize(cmem, vpdev);
+}
+
+gs_public_st_suffix_add1_final(st_device_X, gx_device_X,
+    "gx_device_X", device_x_enum_ptrs, device_x_reloc_ptrs,
+    x_finalize, st_device_bbox, buffer);
+
 x_device(gs_x11_device,
          std_device_color_stype_body(gx_device_X, 0, "x11", &st_device_X,
                                      FAKE_RES * DEFAULT_WIDTH_10THS / 10,
diff --git a/devices/gdevx.h b/devices/gdevx.h
index 4becd639..b35d4d85 100644
--- a/devices/gdevx.h
+++ b/devices/gdevx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -199,10 +199,6 @@ typedef struct gx_device_X_s {
              xdev->text.origin.y, xdev->text.items, xdev->text.item_count)
 
 } gx_device_X;
-#define private_st_device_X()	/* in gdevx.c */\
-  gs_public_st_suffix_add1_final(st_device_X, gx_device_X,\
-    "gx_device_X", device_x_enum_ptrs, device_x_reloc_ptrs,\
-    gx_device_finalize, st_device_bbox, buffer)
 
 /* Send an event to the Ghostview process */
 void gdev_x_send_event(gx_device_X *xdev, Atom msg);
diff --git a/devices/gdevxalt.c b/devices/gdevxalt.c
index 4d8cc339..0290c8c6 100644
--- a/devices/gdevxalt.c
+++ b/devices/gdevxalt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevxcf.c b/devices/gdevxcf.c
index c4c44bf6..18ff322e 100644
--- a/devices/gdevxcf.c
+++ b/devices/gdevxcf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -1241,7 +1241,7 @@ xcf_icc_to_tile(gx_device_printer *pdev, xcf_write_ctx *xc, byte **tile_data, co
                    understand what is going on in the loop
                    with the 255^row[row_idx++] operation */
 
-            gscms_transform_color((gx_device*) pdev, link, 
+            gscms_transform_color((gx_device*) pdev, link,
                                   (void *) (&(row[row_idx])),
                                    &(base_ptr[base_idx]), 1);
 
diff --git a/devices/gdevxcmp.c b/devices/gdevxcmp.c
index 9f7e0401..c43426d7 100644
--- a/devices/gdevxcmp.c
+++ b/devices/gdevxcmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevxcmp.h b/devices/gdevxcmp.h
index 9d6fca73..8fa1d8e7 100644
--- a/devices/gdevxcmp.h
+++ b/devices/gdevxcmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gdevxini.c b/devices/gdevxini.c
index ca8ca2f9..82032cd6 100644
--- a/devices/gdevxini.c
+++ b/devices/gdevxini.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -107,14 +107,16 @@ gdev_x_open(gx_device_X * xdev)
     }
 # endif
 #endif
+
     if (!(xdev->dpy = XOpenDisplay((char *)NULL))) {
         char *dispname = getenv("DISPLAY");
 
         emprintf1(xdev->memory,
-                  "Cannot open X display `%s'.\n",
-                 (dispname == NULL ? "(null)" : dispname));
+            "Cannot open X display `%s'.\n",
+            (dispname == NULL ? "(null)" : dispname));
         return_error(gs_error_ioerror);
     }
+
     xdev->dest = 0;
     if ((window_id = getenv("GHOSTVIEW"))) {
         if (!(xdev->ghostview = sscanf(window_id, "%ld %ld",
@@ -892,7 +894,7 @@ gdev_x_put_params(gx_device * dev, gs_param_list * plist)
                                   dev->width, dev->height, dev->dname);
             return_error(gs_error_rangecheck);
         }
-        
+
         /* points */
         dev->MediaSize[0] = (float)dev->width / xdev->x_pixels_per_inch * 72;
         dev->MediaSize[1] = (float)dev->height / xdev->y_pixels_per_inch * 72;
@@ -927,7 +929,7 @@ gdev_x_put_params(gx_device * dev, gs_param_list * plist)
     }
     xdev->MaxTempPixmap = values.MaxTempPixmap;
     xdev->MaxTempImage = values.MaxTempImage;
-    
+
     if (clear_window || xdev->space_params.MaxBitmap != orig_MaxBitmap) {
         if (xdev->is_open)
             gdev_x_clear_window(xdev);
@@ -949,16 +951,28 @@ gdev_x_close(gx_device_X *xdev)
         xdev->vinfo = NULL;
     }
     gdev_x_free_colors(xdev);
-    if (xdev->cmap != DefaultColormapOfScreen(xdev->scr))
+    if (xdev->dpy && xdev->cmap != DefaultColormapOfScreen(xdev->scr)) {
         XFreeColormap(xdev->dpy, xdev->cmap);
-    if (xdev->gc)
+        xdev->cmap = DefaultColormapOfScreen(xdev->scr);
+    }
+    if (xdev->dpy && xdev->gc) {
         XFreeGC(xdev->dpy, xdev->gc);
+        xdev->gc = NULL;
+    }
+    if (xdev->dpy && xdev->bpixmap != (Pixmap)0) {
+        XFreePixmap(xdev->dpy, xdev->bpixmap);
+        xdev->bpixmap = (Pixmap)0;
+        xdev->dest = (Pixmap)0;
+    }
+
+    /* Closure of device will not close the window
+       finalize will do that. */
+    xdev->pwin = xdev->win;
 
-    XCloseDisplay(xdev->dpy);
     /* MaxBitmap == 0 ensures x_set_buffer() configures as non-buffering */
     xdev->space_params.MaxBitmap = 0;
     x_set_buffer(xdev);
     xdev->space_params.MaxBitmap = MaxBitmap;
 
     return 0;
-}
+}
\ No newline at end of file
diff --git a/devices/gdevxres.c b/devices/gdevxres.c
index 748d3c58..acdef22a 100644
--- a/devices/gdevxres.c
+++ b/devices/gdevxres.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/gxfcopy.c b/devices/gxfcopy.c
index c6d90c9a..4f2ca6fd 100644
--- a/devices/gxfcopy.c
+++ b/devices/gxfcopy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -389,24 +389,34 @@ copy_subrs(gs_font_type1 *pfont, bool global, gs_subr_info_t *psi,
  * pointer to the slot where it would be added, which will have gdata.data
  * == 0, and return gs_error_undefined; if the glyph is defined, store the
  * pointer and return 0.
+ *
+ * NOTE:
+ * The interim variable (idx) is used here as a workaround for what appears
+ * to be a compiler optimiser bug in VS2019 - using "glyph - GS_MIN_CID_GLYPH"
+ * directly to index into the cfdata->glyphs array results in a pointer value
+ * in *pslot which is complete nonsense. Using the variable to store the
+ * calculated value results in working code.
  */
 static int
 copied_glyph_slot(gs_copied_font_data_t *cfdata, gs_glyph glyph,
                   gs_copied_glyph_t **pslot)
 {
     uint gsize = cfdata->glyphs_size;
+    unsigned int idx;
 
     *pslot = 0;
     if (glyph >= GS_MIN_GLYPH_INDEX) {
         /* CIDFontType 2 uses glyph indices for slots.  */
-        if (glyph - GS_MIN_GLYPH_INDEX >= gsize)
+        idx = (unsigned int)(glyph - GS_MIN_GLYPH_INDEX);
+        if (idx >= gsize)
             return_error(gs_error_rangecheck);
-        *pslot = &cfdata->glyphs[glyph - GS_MIN_GLYPH_INDEX];
+        *pslot = &cfdata->glyphs[idx];
     } else if (glyph >= GS_MIN_CID_GLYPH) {
         /* CIDFontType 0 uses CIDS for slots.  */
-        if (glyph - GS_MIN_CID_GLYPH >= gsize)
+        idx = (unsigned int)(glyph - GS_MIN_CID_GLYPH);
+        if (idx >= gsize)
             return_error(gs_error_rangecheck);
-        *pslot = &cfdata->glyphs[glyph - GS_MIN_CID_GLYPH];
+        *pslot = &cfdata->glyphs[idx];
     } else if (cfdata->names == 0)
         return_error(gs_error_rangecheck);
     else {
@@ -515,16 +525,22 @@ copy_glyph_data(gs_font *font, gs_glyph glyph, gs_font *copied, int options,
             code = gs_note_error(gs_error_undefined);
         else {
             uint str_size = prefix_bytes + size;
-            byte *str = gs_alloc_string(copied->memory, str_size,
-                                        "copy_glyph_data(data)");
-
-            if (str == 0)
-                code = gs_note_error(gs_error_VMerror);
-            else {
-                if (prefix_bytes)
-                    memcpy(str, prefix, prefix_bytes);
-                memcpy(str + prefix_bytes, pgdata->bits.data, size);
-                pcg->gdata.data = str;
+
+            code = 0;
+            if (str_size > 0) {
+                byte *str = gs_alloc_string(copied->memory, str_size,
+                                            "copy_glyph_data(data)");
+
+                if (str == 0)
+                    code = gs_note_error(gs_error_VMerror);
+                else {
+                    if (prefix_bytes)
+                        memcpy(str, prefix, prefix_bytes);
+                    memcpy(str + prefix_bytes, pgdata->bits.data, size);
+                    pcg->gdata.data = str;
+                }
+            }
+            if (code >= 0) {
                 pcg->gdata.size = str_size;
                 pcg->used = HAS_DATA;
                 pcg->order_index = -1;
@@ -577,11 +593,14 @@ copy_glyph_name(gs_font *font, gs_glyph glyph, gs_font *copied,
 
         if (extra_name == 0)
             return_error(gs_error_VMerror);
+        memset(extra_name, 0x00, sizeof(gs_copied_glyph_extra_name_t));
         extra_name->next = cfdata->extra_names;
         extra_name->gid = pcg - cfdata->glyphs;
         cfdata->extra_names = extra_name;
         pcgn = &extra_name->name;
     }
+    if (pcgn->str.size != 0 && !gs_is_c_glyph_name(pcgn->str.data, pcgn->str.size))
+        gs_free_string(copied->memory, (byte *)pcgn->str.data, pcgn->str.size, "Free copied glyph name");
     pcgn->glyph = glyph;
     pcgn->str = str;
     return 0;
@@ -968,7 +987,7 @@ copied_type1_seac_data(gs_font_type1 * pfont, int ccode,
     code = gs_c_glyph_name(glyph, gstr);
     if (code < 0)
         return code;
-    code = pfont->dir->global_glyph_code(pfont->memory, gstr, &glyph1);
+    code = pfont->dir->global_glyph_code((gs_font *)pfont, gstr, &glyph1);
     if (code < 0)
         return code;
     if (pglyph)
@@ -1850,7 +1869,6 @@ copy_font_cid2(gs_font *font, gs_font *copied)
                             copied2->memory, return_error(gs_error_VMerror), "copy_font_cid2");
         subst->data[0] = subst->data[1] = 0;
         copied2->subst_CID_on_WMode = subst;
-        rc_increment(subst);
     }
 
     return 0;
@@ -1865,12 +1883,13 @@ static int expand_CIDMap(gs_font_cid2 *copied2, uint CIDCount)
         return 0;
     CIDMap = (ushort *)
         gs_alloc_byte_array(copied2->memory, CIDCount, sizeof(ushort),
-                            "copy_font_cid2(CIDMap");
+                            "expand_CIDMap(new CIDMap)");
     if (CIDMap == 0)
         return_error(gs_error_VMerror);
     memcpy(CIDMap, cfdata->CIDMap, copied2->cidata.common.CIDCount * sizeof(*CIDMap));
     memset(CIDMap + copied2->cidata.common.CIDCount, 0xFF,
             (CIDCount - copied2->cidata.common.CIDCount) * sizeof(*CIDMap));
+    gs_free_object(copied2->memory, cfdata->CIDMap, "expand_CIDMap(old CIDMap)");
     cfdata->CIDMap = CIDMap;
     copied2->cidata.common.CIDCount = CIDCount;
     return 0;
@@ -2194,9 +2213,13 @@ gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_f
     if (code < 0)
         goto fail;
 
-    *pfont_new = copied;
     if (cfdata->notdef != GS_NO_GLYPH)
         code = gs_copy_glyph(font, cfdata->notdef, copied);
+    if (code < 0)
+        gs_free_copied_font(copied);
+    else
+        *pfont_new = copied;
+
     return code;
 
  fail:
@@ -2251,6 +2274,7 @@ int gs_free_copied_font(gs_font *font)
     gs_memory_t *mem = font->memory;
     int i, code;
     gs_copied_glyph_t *pcg = 0;
+    gs_copied_glyph_name_t *pcgn = 0;
 
     /* For CID fonts, we must also free the descendants, which we copied
      * at the time we copied the actual CIDFont itself
@@ -2267,13 +2291,39 @@ int gs_free_copied_font(gs_font *font)
         copied0->cidata.FDArray = 0;
     }
 
+    if (font->FontType == ft_CID_TrueType) {
+        gs_font_cid2 *copied2 = (gs_font_cid2 *)font;
+
+        if (copied2->subst_CID_on_WMode)
+            rc_decrement(copied2->subst_CID_on_WMode, "gs_free_copied_font(subst_CID_on_WMode");
+    }
+
     if (cfdata) {
         /* free copied glyph data */
         for (i=0;i < cfdata->glyphs_size;i++) {
             pcg = &cfdata->glyphs[i];
-            if(pcg->gdata.size) {
+            if(pcg->gdata.data != NULL) {
                 gs_free_string(font->memory, (byte *)pcg->gdata.data, pcg->gdata.size, "Free copied glyph");
             }
+            if (cfdata->names) {
+                pcgn = &cfdata->names[i];
+                if (pcgn->str.data != NULL) {
+                    if (!gs_is_c_glyph_name(pcgn->str.data, pcgn->str.size))
+                        gs_free_string(font->memory, (byte *)pcgn->str.data, pcgn->str.size, "Free copied glyph name");
+                }
+            }
+        }
+        if (cfdata->extra_names) {
+            gs_copied_glyph_extra_name_t *extra_name = cfdata->extra_names, *next;
+
+            while (extra_name != NULL) {
+                next = extra_name->next;
+                if (!gs_is_c_glyph_name(extra_name->name.str.data, extra_name->name.str.size))
+                    gs_free_string(font->memory, (byte *)extra_name->name.str.data, extra_name->name.str.size, "Free extra name string");
+                gs_free_object(font->memory, extra_name, "free copied font(extra_names)");
+                extra_name = next;
+            }
+            cfdata->extra_names = NULL;
         }
 
         uncopy_string(mem, &cfdata->info.FullName,
@@ -2284,8 +2334,18 @@ int gs_free_copied_font(gs_font *font)
                       "gs_free_copied_font(Notice)");
         uncopy_string(mem, &cfdata->info.Copyright,
                       "gs_free_copied_font(Copyright)");
+        if (cfdata->subrs.data != NULL)
+            gs_free_object(mem, cfdata->subrs.data, "gs_free_copied_font(subrs.data)");
+        if (cfdata->subrs.starts != NULL)
+            gs_free_object(mem, cfdata->subrs.starts, "gs_free_copied_font(subrs.dtarts)");
+        if (cfdata->global_subrs.data !=  NULL)
+            gs_free_object(mem, cfdata->global_subrs.data, "gs_free_copied_font(gsubrs.data)");
+        if (cfdata->global_subrs.starts !=  NULL)
+            gs_free_object(mem, cfdata->global_subrs.starts, "gs_free_copied_font(gsubrs.starts)");
         if (cfdata->Encoding)
             gs_free_object(mem, cfdata->Encoding, "gs_free_copied_font(Encoding)");
+        if (cfdata->CIDMap)
+            gs_free_object(mem, cfdata->CIDMap, "gs_free_copied_font(CIDMap)");
         gs_free_object(mem, cfdata->glyphs, "gs_free_copied_font(glyphs)");
         gs_free_object(mem, cfdata->names, "gs_free_copied_font(names)");
         gs_free_object(mem, cfdata->data, "gs_free_copied_font(data)");
diff --git a/devices/gxfcopy.h b/devices/gxfcopy.h
index 8a6efbaa..8c6909ed 100644
--- a/devices/gxfcopy.h
+++ b/devices/gxfcopy.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/minftrsz.c b/devices/minftrsz.c
index a8c5d202..5b9aadf2 100644
--- a/devices/minftrsz.c
+++ b/devices/minftrsz.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/minftrsz.h b/devices/minftrsz.h
index d520a62a..5552a9c6 100644
--- a/devices/minftrsz.h
+++ b/devices/minftrsz.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/evenbetter-rll.c b/devices/rinkj/evenbetter-rll.c
index 5928704a..ac03960f 100644
--- a/devices/rinkj/evenbetter-rll.c
+++ b/devices/rinkj/evenbetter-rll.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/evenbetter-rll.h b/devices/rinkj/evenbetter-rll.h
index 3e1d7fa6..1cb1f687 100644
--- a/devices/rinkj/evenbetter-rll.h
+++ b/devices/rinkj/evenbetter-rll.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-byte-stream.c b/devices/rinkj/rinkj-byte-stream.c
index 9f84ce96..c6e551ff 100644
--- a/devices/rinkj/rinkj-byte-stream.c
+++ b/devices/rinkj/rinkj-byte-stream.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-byte-stream.h b/devices/rinkj/rinkj-byte-stream.h
index b2741088..0f68bd0f 100644
--- a/devices/rinkj/rinkj-byte-stream.h
+++ b/devices/rinkj/rinkj-byte-stream.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-config.c b/devices/rinkj/rinkj-config.c
index 4b084458..7e6119fc 100644
--- a/devices/rinkj/rinkj-config.c
+++ b/devices/rinkj/rinkj-config.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-config.h b/devices/rinkj/rinkj-config.h
index 716caa75..2f999575 100644
--- a/devices/rinkj/rinkj-config.h
+++ b/devices/rinkj/rinkj-config.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-device.c b/devices/rinkj/rinkj-device.c
index 43ba6f80..11d076e0 100644
--- a/devices/rinkj/rinkj-device.c
+++ b/devices/rinkj/rinkj-device.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-device.h b/devices/rinkj/rinkj-device.h
index c936711f..8b173c3e 100644
--- a/devices/rinkj/rinkj-device.h
+++ b/devices/rinkj/rinkj-device.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-dither.c b/devices/rinkj/rinkj-dither.c
index f5a12844..fdf8a3b0 100644
--- a/devices/rinkj/rinkj-dither.c
+++ b/devices/rinkj/rinkj-dither.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-dither.h b/devices/rinkj/rinkj-dither.h
index 815368c8..1572ec43 100644
--- a/devices/rinkj/rinkj-dither.h
+++ b/devices/rinkj/rinkj-dither.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-epson870.c b/devices/rinkj/rinkj-epson870.c
index 59d55f57..83bcf12c 100644
--- a/devices/rinkj/rinkj-epson870.c
+++ b/devices/rinkj/rinkj-epson870.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-epson870.h b/devices/rinkj/rinkj-epson870.h
index 08f135f9..308c75c7 100644
--- a/devices/rinkj/rinkj-epson870.h
+++ b/devices/rinkj/rinkj-epson870.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-screen-eb.c b/devices/rinkj/rinkj-screen-eb.c
index e6a9f779..6724b5e2 100644
--- a/devices/rinkj/rinkj-screen-eb.c
+++ b/devices/rinkj/rinkj-screen-eb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/rinkj/rinkj-screen-eb.h b/devices/rinkj/rinkj-screen-eb.h
index 8b61fe35..6a978fd6 100644
--- a/devices/rinkj/rinkj-screen-eb.h
+++ b/devices/rinkj/rinkj-screen-eb.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/doc_common.c b/devices/vector/doc_common.c
new file mode 100644
index 00000000..50123f8f
--- /dev/null
+++ b/devices/vector/doc_common.c
@@ -0,0 +1,532 @@
+#include "doc_common.h"
+
+#include "gxfont.h"
+#include "gserrors.h"
+#include "gxfcid.h"
+#include "gdevagl.h"
+#include "gxdevcli.h"
+#include "gxgstate.h"
+
+#include 
+
+
+extern single_glyph_list_t SingleGlyphList[];
+extern double_glyph_list_t DoubleGlyphList[];
+extern treble_glyph_list_t TrebleGlyphList[];
+extern quad_glyph_list_t QuadGlyphList[];
+
+
+static int
+font_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
+{
+    int code;
+
+    switch (font->FontType) {
+    case ft_composite:                /* subfonts have their own FontMatrix */
+    case ft_TrueType:
+    case ft_CID_TrueType:
+        /* The TrueType FontMatrix is 1 unit per em, which is what we want. */
+        gs_make_identity(pmat);
+        return 0;
+    case ft_encrypted:
+    case ft_encrypted2:
+    case ft_CID_encrypted:
+    case ft_user_defined:
+    case ft_PCL_user_defined:
+    case ft_GL2_stick_user_defined:
+    case ft_GL2_531:
+        /*
+         * Type 1 fonts are supposed to use a standard FontMatrix of
+         * [0.001 0 0 0.001 0 0], with a 1000-unit cell.  However,
+         * Windows NT 4.0 creates Type 1 fonts, apparently derived from
+         * TrueType fonts, that use a 2048-unit cell and corresponding
+         * FontMatrix.  Also, some PS programs perform font scaling by
+         * replacing FontMatrix like this :
+         *
+         *   /f12 /Times-Roman findfont
+         *   copyfont          % (remove FID)
+         *   dup /FontMatrix [0.012 0 0 0.012 0 0] put
+         *   definefont
+         *   /f12 1 selectfont
+         *
+         * Such fonts are their own "base font", but the orig_matrix
+         * must still be set to 0.001, not 0.012 .
+         *
+         * The old code used a heuristic to detect and correct for this here.
+         * Unfortunately it doesn't work properly when it meets a font
+         * with FontMatrix like this :
+         *
+         *   /FontMatrix [1 2288 div 0 0 1 2288 div 0 0 ] def
+         *
+         * (the bug 686970). Also comparefiles\455690.pdf appears to
+         * have similar problem. Therefore we added a support to lib/gs_fonts.ps,
+         * src/zbfont.c, src/gsfont.c that provides an acces to the original
+         * font via a special key OrigFont added to the font dictionary while definefont.
+         * Now we work through this access with PS interpreter,
+         * but keep the old heuristic for other clients.
+         */
+        {
+            const gs_font *base_font = font;
+
+            while (base_font->base != base_font)
+                base_font = base_font->base;
+            if (font->FontType == ft_user_defined ||
+                font->FontType == ft_PCL_user_defined ||
+                font->FontType == ft_GL2_stick_user_defined ||
+                font->FontType == ft_GL2_531)
+                *pmat = base_font->FontMatrix;
+            else if (base_font->orig_FontMatrix.xx != 0 || base_font->orig_FontMatrix.xy != 0 ||
+                base_font->orig_FontMatrix.yx != 0 || base_font->orig_FontMatrix.yy != 0)
+                *pmat = base_font->orig_FontMatrix;
+            else {
+                /*  Must not happen with PS interpreter.
+                    Provide a hewuristic for other clients.
+                */
+                if (base_font->FontMatrix.xx == 1.0/2048 &&
+                    base_font->FontMatrix.xy == 0 &&
+                    base_font->FontMatrix.yx == 0 &&
+                    any_abs(base_font->FontMatrix.yy) == 1.0/2048
+                    )
+                    *pmat = base_font->FontMatrix;
+                else
+                    gs_make_scaling(0.001, 0.001, pmat);
+            }
+        }
+        if (font->FontType == ft_CID_encrypted && cid != -1) {
+            int fidx;
+
+            if (cid < GS_MIN_CID_GLYPH)
+                cid = GS_MIN_CID_GLYPH;
+            code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
+                                cid, NULL, &fidx);
+            if (code < 0) {
+                code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
+                                (gs_glyph)GS_MIN_CID_GLYPH, NULL, &fidx);
+            }
+            if (code >= 0) {
+                gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
+                                pmat, pmat);
+            }
+        }
+        return 0;
+    default:
+        return_error(gs_error_rangecheck);
+    }
+}
+
+/*
+ * Special version of font_orig_matrix(), that considers FDArray font's FontMatrix too.
+ * Called only by txt_glyph_width().
+ * 'cid' is only consulted if 'font' is a CIDFontType 0 CID font.
+ */
+static int
+glyph_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
+{
+    int code = font_orig_matrix(font, cid, pmat);
+    if (code >= 0) {
+        if (font->FontType == ft_CID_encrypted) {
+            int fidx;
+
+            if (cid < GS_MIN_CID_GLYPH)
+                cid = GS_MIN_CID_GLYPH;
+            code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
+                                cid, NULL, &fidx);
+            if (code < 0) {
+                code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
+                                (gs_glyph)GS_MIN_CID_GLYPH, NULL, &fidx);
+            }
+            if (code >= 0) {
+                gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
+                                pmat, pmat);
+            }
+        }
+    }
+    return code;
+}
+
+float txt_calculate_text_size(gs_gstate *pgs, gs_font *ofont,
+                              const gs_matrix *pfmat, gs_matrix *smat, gs_matrix *tmat,
+                              gs_font *font, gx_device *pdev)
+{
+    gs_matrix orig_matrix;
+    double
+        sx = pdev->HWResolution[0] / 72.0,
+        sy = pdev->HWResolution[1] / 72.0;
+    float size;
+
+    /* Get the original matrix of the base font. */
+
+    font_orig_matrix(ofont, -1, &orig_matrix);
+    /* Compute the scaling matrix and combined matrix. */
+
+    if (gs_matrix_invert(&orig_matrix, smat) < 0) {
+        gs_make_identity(smat);
+        return 1; /* Arbitrary */
+    }
+    gs_matrix_multiply(smat, pfmat, smat);
+    *tmat = ctm_only(pgs);
+    tmat->tx = tmat->ty = 0;
+    gs_matrix_multiply(smat, tmat, tmat);
+
+    /* Try to find a reasonable size value. */
+
+    size = hypot(tmat->yx, tmat->yy) / sy;
+    if (size < 0.01)
+        size = hypot(tmat->xx, tmat->xy) / sx;
+    if (size < 0.01)
+        size = 1;
+
+    return(size);
+}
+
+static int
+store_glyph_width(txt_glyph_width_t *pwidth, int wmode, const gs_matrix *scale,
+                  const gs_glyph_info_t *pinfo)
+{
+    double w, v;
+
+    gs_distance_transform(pinfo->width[wmode].x, pinfo->width[wmode].y, scale, &pwidth->xy);
+    if (wmode)
+        w = pwidth->xy.y, v = pwidth->xy.x;
+    else
+        w = pwidth->xy.x, v = pwidth->xy.y;
+    if (v != 0)
+        return 1;
+    pwidth->w = w;
+    gs_distance_transform(pinfo->v.x, pinfo->v.y, scale, &pwidth->v);
+    return 0;
+}
+
+static int
+get_missing_width(gs_font *font, int wmode, const gs_matrix *scale_c,
+                    txt_glyph_widths_t *pwidths)
+{
+    gs_font_info_t finfo;
+    int code;
+
+    code = font->procs.font_info((gs_font *)font, NULL,
+                                  FONT_INFO_MISSING_WIDTH, &finfo);
+    if (code < 0)
+        return code;
+    if (!(finfo.members & FONT_INFO_MISSING_WIDTH))
+        return_error(gs_error_undefined);
+
+    if (wmode) {
+        gs_distance_transform(0.0, -finfo.MissingWidth, scale_c, &pwidths->real_width.xy);
+        pwidths->Width.xy.x = 0;
+        pwidths->Width.xy.y = pwidths->real_width.xy.y;
+        pwidths->Width.w = pwidths->real_width.w =
+                pwidths->Width.xy.y;
+        pwidths->Width.v.x = - pwidths->Width.xy.y / 2;
+        pwidths->Width.v.y = - pwidths->Width.xy.y;
+    } else {
+        gs_distance_transform(finfo.MissingWidth, 0.0, scale_c, &pwidths->real_width.xy);
+        pwidths->Width.xy.x = pwidths->real_width.xy.x;
+        pwidths->Width.xy.y = 0;
+        pwidths->Width.w = pwidths->real_width.w =
+                pwidths->Width.xy.x;
+        pwidths->Width.v.x = pwidths->Width.v.y = 0;
+    }
+    /*
+     * Don't mark the width as known, just in case this is an
+     * incrementally defined font.
+     */
+    return 1;
+}
+
+/*
+ * Get the widths (unmodified from the copied font,
+ * and possibly modified from the original font) of a given glyph.
+ * Return 1 if the width was defaulted to MissingWidth.
+ * Return TEXT_PROCESS_CDEVPROC if a CDevProc callout is needed.
+ * cdevproc_result != NULL if we restart after a CDevProc callout.
+ */
+int
+txt_glyph_widths(gs_font *font, int wmode, gs_glyph glyph,
+                 gs_font *orig_font, txt_glyph_widths_t *pwidths,
+                 const double cdevproc_result[10])
+{
+    gs_font *ofont = orig_font;
+    gs_glyph_info_t info;
+    gs_matrix scale_c, scale_o;
+    int code, rcode = 0;
+    gs_point v;
+    int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType
+                || orig_font->FontType == ft_CID_encrypted
+                ? GLYPH_INFO_CDEVPROC : 0); /* fixme : allow more font types. */
+
+    if (ofont->FontType == ft_composite)
+        return_error(gs_error_unregistered); /* Must not happen. */
+    code = glyph_orig_matrix((const gs_font *)font, glyph, &scale_c);
+    if (code < 0)
+        return code;
+    code = glyph_orig_matrix(ofont, glyph, &scale_o);
+    if (code < 0)
+        return code;
+    gs_matrix_scale(&scale_c, 1000.0, 1000.0, &scale_c);
+    gs_matrix_scale(&scale_o, 1000.0, 1000.0, &scale_o);
+    pwidths->Width.v.x = pwidths->Width.v.y = pwidths->Width.xy.x = pwidths->Width.xy.y = 0;
+    pwidths->real_width.v.x = pwidths->real_width.v.y = pwidths->real_width.xy.x = pwidths->real_width.xy.y = 0;
+    pwidths->Width.w = pwidths->real_width.w = 0.0;
+    pwidths->replaced_v = false;
+    if (glyph == GS_NO_GLYPH)
+        return get_missing_width(font, wmode, &scale_c, pwidths);
+    code = font->procs.glyph_info((gs_font *)font, glyph, NULL,
+                                    GLYPH_INFO_WIDTH0 |
+                                    (GLYPH_INFO_WIDTH0 << wmode) |
+                                    GLYPH_INFO_OUTLINE_WIDTHS |
+                                    (GLYPH_INFO_VVECTOR0 << wmode),
+                                    &info);
+    /* For CID fonts the PDF spec requires the x-component of v-vector
+       to be equal to half glyph width, and AR5 takes it from W, DW.
+       So make a compatibe data here.
+     */
+    if (font->FontType != ft_PCL_user_defined && font->FontType != ft_GL2_stick_user_defined &&
+        font->FontType != ft_GL2_531
+        && (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))) {
+        code = get_missing_width(font, wmode, &scale_c, pwidths);
+        if (code < 0)
+            return code;
+        else
+            v.y = pwidths->Width.v.y;
+        if (wmode && (ofont->FontType == ft_CID_encrypted ||
+            ofont->FontType == ft_CID_TrueType)) {
+            txt_glyph_widths_t widths1;
+
+            if (get_missing_width(font, 0, &scale_c, &widths1) < 0)
+                v.x = 0;
+            else
+                v.x = widths1.Width.w / 2;
+        } else
+            v.x = pwidths->Width.v.x;
+    } else if (code < 0)
+        return code;
+    else {
+        code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
+        if (code < 0)
+            return code;
+        rcode |= code;
+        if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode))
+            gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
+        else
+            v.x = v.y = 0;
+        if (wmode && (ofont->FontType == ft_CID_encrypted ||
+            ofont->FontType == ft_CID_TrueType)) {
+            if (info.members & (GLYPH_INFO_WIDTH0 << wmode)) {
+                gs_point xy;
+
+                gs_distance_transform(info.width[0].x, info.width[0].y, &scale_c, &xy);
+                v.x = xy.x / 2;
+            } else {
+                txt_glyph_widths_t widths1;
+
+                if (get_missing_width(font, 0, &scale_c, &widths1) < 0)
+                    v.x = 0;
+                else
+                    v.x = widths1.Width.w / 2;
+            }
+        }
+    }
+    pwidths->Width.v = v;
+    /* Skip only if not paralel to the axis. */
+    if (code > 0 && ofont->FontType != ft_CID_encrypted &&
+            ofont->FontType != ft_CID_TrueType)
+        pwidths->Width.xy.x = pwidths->Width.xy.y = pwidths->Width.w = 0;
+    if (cdevproc_result == NULL) {
+        info.members = 0;
+        code = ofont->procs.glyph_info(ofont, glyph, NULL,
+                                            (GLYPH_INFO_WIDTH0 << wmode) |
+                                            (GLYPH_INFO_VVECTOR0 << wmode) |
+                                            allow_cdevproc_callout,
+                                            &info);
+        /* fixme : Move this call before cfont->procs.glyph_info. */
+        if (info.members & GLYPH_INFO_CDEVPROC) {
+            if (allow_cdevproc_callout)
+                return TEXT_PROCESS_CDEVPROC;
+        else
+            return_error(gs_error_rangecheck);
+        }
+    } else {
+        info.width[0].x = cdevproc_result[0];
+        info.width[0].y = cdevproc_result[1];
+        info.width[1].x = cdevproc_result[6];
+        info.width[1].y = cdevproc_result[7];
+        info.v.x = (wmode ? cdevproc_result[8] : 0);
+        info.v.y = (wmode ? cdevproc_result[9] : 0);
+        info.members = (GLYPH_INFO_WIDTH0 << wmode) |
+                       (wmode ? GLYPH_INFO_VVECTOR1 : 0);
+        code = 0;
+    }
+    if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))
+        pwidths->real_width = pwidths->Width;
+    else if (code < 0)
+        return code;
+    else {
+        if ((info.members & (GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1)) != 0)
+            pwidths->replaced_v = true;
+        else
+            info.v.x = info.v.y = 0;
+        code = store_glyph_width(&pwidths->real_width, wmode, &scale_o, &info);
+        if (code < 0)
+            return code;
+        rcode |= code;
+        gs_distance_transform(info.v.x, info.v.y, &scale_o, &pwidths->real_width.v);
+    }
+    return rcode;
+}
+
+void
+txt_char_widths_to_uts(gs_font *font /* may be NULL for non-Type3 */,
+                       txt_glyph_widths_t *pwidths)
+{
+    if (font && (font->FontType == ft_user_defined ||
+        font->FontType == ft_PCL_user_defined ||
+        font->FontType == ft_GL2_stick_user_defined ||
+        font->FontType == ft_GL2_531)) {
+        gs_matrix *pmat = &font->orig_FontMatrix;
+
+        pwidths->Width.xy.x *= pmat->xx; /* formula simplified based on wy in glyph space == 0 */
+        pwidths->Width.xy.y  = 0.0; /* WMode == 0 for PDF Type 3 fonts */
+        gs_distance_transform(pwidths->real_width.xy.x, pwidths->real_width.xy.y, pmat, &pwidths->real_width.xy);
+    } else {
+        /*
+         * For other font types:
+         * - PDF design->text space is a simple scaling by 0.001.
+         * - The Width.xy.x/y that should be zeroed-out per 5.3.3 "Text Space Details" is already 0.
+         */
+        pwidths->Width.xy.x /= 1000.0;
+        pwidths->Width.xy.y /= 1000.0;
+        pwidths->real_width.xy.x /= 1000.0;
+        pwidths->real_width.xy.y /= 1000.0;
+    }
+}
+
+
+int txt_get_unicode(gx_device *dev, gs_font *font, gs_glyph glyph, gs_char ch, unsigned short *Buffer)
+{
+    int code;
+    gs_const_string gnstr;
+    unsigned short fallback = ch;
+    ushort *unicode = NULL;
+    int length;
+
+    length = font->procs.decode_glyph((gs_font *)font, glyph, ch, NULL, 0);
+    if (length == 0) {
+        if (glyph != GS_NO_GLYPH) {
+            code = font->procs.glyph_name(font, glyph, &gnstr);
+            if (code >= 0 && gnstr.size == 7) {
+                if (!memcmp(gnstr.data, "uni", 3)) {
+                    static const char *hexdigits = "0123456789ABCDEF";
+                    char *d0 = strchr(hexdigits, gnstr.data[3]);
+                    char *d1 = strchr(hexdigits, gnstr.data[4]);
+                    char *d2 = strchr(hexdigits, gnstr.data[5]);
+                    char *d3 = strchr(hexdigits, gnstr.data[6]);
+
+                    if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
+                        *Buffer++ = ((d0 - hexdigits) << 12) + ((d1 - hexdigits) << 8) + ((d2 - hexdigits) << 4) + (d3 - hexdigits);
+                        return 1;
+                    }
+                }
+            }
+            if (length == 0) {
+                single_glyph_list_t *sentry = SingleGlyphList;
+                double_glyph_list_t *dentry = DoubleGlyphList;
+                treble_glyph_list_t *tentry = TrebleGlyphList;
+                quad_glyph_list_t *qentry = QuadGlyphList;
+
+                /* Search glyph to single Unicode value table */
+                while (sentry->Glyph != 0) {
+                    if (sentry->Glyph[0] < gnstr.data[0]) {
+                        sentry++;
+                        continue;
+                    }
+                    if (sentry->Glyph[0] > gnstr.data[0]){
+                        break;
+                    }
+                    if (strlen(sentry->Glyph) == gnstr.size) {
+                        if(memcmp(gnstr.data, sentry->Glyph, gnstr.size) == 0) {
+                            *Buffer = sentry->Unicode;
+                            return 1;
+                        }
+                    }
+                    sentry++;
+                }
+
+                /* Search glyph to double Unicode value table */
+                while (dentry->Glyph != 0) {
+                    if (dentry->Glyph[0] < gnstr.data[0]) {
+                        dentry++;
+                        continue;
+                    }
+                    if (dentry->Glyph[0] > gnstr.data[0]){
+                        break;
+                    }
+                    if (strlen(dentry->Glyph) == gnstr.size) {
+                        if(memcmp(gnstr.data, dentry->Glyph, gnstr.size) == 0) {
+                            memcpy(Buffer, dentry->Unicode, 2);
+                            return 2;
+                        }
+                    }
+                    dentry++;
+                }
+
+                /* Search glyph to triple Unicode value table */
+                while (tentry->Glyph != 0) {
+                    if (tentry->Glyph[0] < gnstr.data[0]) {
+                        tentry++;
+                        continue;
+                    }
+                    if (tentry->Glyph[0] > gnstr.data[0]){
+                        break;
+                    }
+                    if (strlen(tentry->Glyph) == gnstr.size) {
+                        if(memcmp(gnstr.data, tentry->Glyph, gnstr.size) == 0) {
+                            memcpy(Buffer, tentry->Unicode, 3);
+                            return 3;
+                        }
+                    }
+                    tentry++;
+                }
+
+                /* Search glyph to quadruple Unicode value table */
+                while (qentry->Glyph != 0) {
+                    if (qentry->Glyph[0] < gnstr.data[0]) {
+                        qentry++;
+                        continue;
+                    }
+                    if (qentry->Glyph[0] > gnstr.data[0]){
+                        break;
+                    }
+                    if (strlen(qentry->Glyph) == gnstr.size) {
+                        if(memcmp(gnstr.data, qentry->Glyph, gnstr.size) == 0) {
+                            memcpy(Buffer, qentry->Unicode, 4);
+                            return 4;
+                        }
+                    }
+                    qentry++;
+                }
+            }
+        }
+        *Buffer = fallback;
+        return 1;
+    } else {
+        char *b, *u;
+        int l = length - 1;
+
+        unicode = (ushort *)gs_alloc_bytes(dev->memory, length, "temporary Unicode array");
+        length = font->procs.decode_glyph((gs_font *)font, glyph, ch, unicode, length);
+#if ARCH_IS_BIG_ENDIAN
+        memcpy(Buffer, unicode, length);
+#else
+        b = (char *)Buffer;
+        u = (char *)unicode;
+
+        for (l=0;lmemory, unicode, "free temporary unicode buffer");
+        return length / sizeof(short);
+    }
+}
diff --git a/devices/vector/doc_common.h b/devices/vector/doc_common.h
new file mode 100644
index 00000000..24369054
--- /dev/null
+++ b/devices/vector/doc_common.h
@@ -0,0 +1,58 @@
+#ifndef gdevtxtw_INCLUDED
+#define gdevtxtw_INCLUDED
+
+#include "gsccode.h"
+#include "gsccode.h"
+#include "gsdevice.h"
+#include "gsfont.h"
+#include "gsgstate.h"
+#include "gsmatrix.h"
+#include "gstypes.h"
+
+/*
+ * Some structures and functions that are used by gdevdocxw.c and gdevtxtw.c.
+ */
+
+/*
+ * Define the structure used to return glyph width information.  Note that
+ * there are two different sets of width information: real-number (x,y)
+ * values, which give the true advance width, and an integer value, which
+ * gives an X advance width for WMode = 0 or a Y advance width for WMode = 1.
+ * The return value from txt_glyph_width() indicates which of these is/are
+ * valid.
+ */
+typedef struct txt_glyph_width_s {
+    double w;
+    gs_point xy;
+    gs_point v;				/* glyph origin shift */
+} txt_glyph_width_t;
+
+typedef struct txt_glyph_widths_s {
+    txt_glyph_width_t Width;		/* unmodified, for Widths */
+    txt_glyph_width_t real_width;	/* possibly modified, for rendering */
+    bool replaced_v;
+} txt_glyph_widths_t;
+
+int
+txt_glyph_widths(gs_font *font, int wmode, gs_glyph glyph,
+                 gs_font *orig_font, txt_glyph_widths_t *pwidths,
+                 const double cdevproc_result[10]);
+
+/* Try to convert glyph names/character codes to Unicode. We first try to see
+ * if we have any Unicode information either from a ToUnicode CMap or GlyphNames2Unicode
+ * table. If that fails we look at the glyph name to see if it starts 'uni'
+ * in which case we assume the remainder of the name is the Unicode value. If
+ * its not a glyph of that form then we search a bunch of tables whcih map standard
+ * glyph names to Unicode code points. If that fails we finally just return the character code.
+ */
+int txt_get_unicode(gx_device *dev, gs_font *font, gs_glyph glyph, gs_char ch, unsigned short *Buffer);
+
+void
+txt_char_widths_to_uts(gs_font *font /* may be NULL for non-Type3 */,
+                       txt_glyph_widths_t *pwidths);
+
+float txt_calculate_text_size(gs_gstate *pgs, gs_font *ofont,
+                              const gs_matrix *pfmat, gs_matrix *smat, gs_matrix *tmat,
+                              gs_font *font, gx_device *pdev);
+
+#endif
diff --git a/devices/vector/gdevagl.c b/devices/vector/gdevagl.c
index a551bb38..05b971a1 100644
--- a/devices/vector/gdevagl.c
+++ b/devices/vector/gdevagl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevagl.h b/devices/vector/gdevagl.h
index 066eae76..e05b53be 100644
--- a/devices/vector/gdevagl.h
+++ b/devices/vector/gdevagl.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevdocxw.c b/devices/vector/gdevdocxw.c
new file mode 100644
index 00000000..c9be4757
--- /dev/null
+++ b/devices/vector/gdevdocxw.c
@@ -0,0 +1,1376 @@
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
+   All Rights Reserved.
+
+   This software is provided AS-IS with no warranty, either express or
+   implied.
+
+   This software is distributed under license and may not be copied,
+   modified or distributed except as expressly authorized under the terms
+   of the license contained in the file LICENSE in this distribution.
+
+   Refer to licensing information at http://www.artifex.com or contact
+   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
+   CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* Device for creating docx files. */
+
+#include "memory_.h"
+#include "string_.h"
+#include "gp.h"			/* for gp_file_name_sizeof */
+#include "gx.h"
+#include "gserrors.h"
+#include "gsparam.h"
+#include "gsutil.h"
+#include "gxdevice.h"
+#include "gsdevice.h"		/* requires gsmatrix.h */
+#include "gxfont.h"
+#include "gxfont0.h"
+#include "gstext.h"
+#include "gxfcid.h"
+#include "gxgstate.h"
+#include "gxpath.h"
+#include "gdevagl.h"
+#include "gxdevsop.h"
+#include "gzpath.h"
+#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and obejct filter */
+#include "gxchar.h"
+
+#include "doc_common.h"
+
+#include "../../extract/include/extract.h"
+
+#include 
+
+#define outf(format, ...)
+#define outfx(format, ...)
+
+#ifdef __unix__
+#if 0
+
+/* Enable logging using outf() macro/function. */
+#include 
+
+static void (outf)(const char* file, int line, const char* function, const char* format, ...)
+{
+    static char buffer[2048];
+    size_t prefix;
+    va_list va;
+    snprintf(buffer, sizeof(buffer), "%s:%i:%s(): ", file, line, function);
+    prefix = strlen(buffer);
+    va_start(va, format);
+    vsnprintf(buffer + prefix, sizeof(buffer) - 1 - prefix, format, va);
+    va_end(va);
+    size_t l = strlen(buffer);
+    buffer[l] = '\n';
+    buffer[l+1] = 0;
+    write(2, buffer, l+1);
+}
+
+#undef outf
+#define outf(format, ...)  outf(__FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
+
+#endif
+#endif
+
+
+
+extern single_glyph_list_t SingleGlyphList[];
+extern double_glyph_list_t DoubleGlyphList[];
+extern treble_glyph_list_t TrebleGlyphList[];
+extern quad_glyph_list_t QuadGlyphList[];
+
+/* Structure to record the Unicode characters, the total width of the text
+ * recorded, and various useful attributes such as the font, size, colour
+ * rendering mode, writing mode etc. These are stored as a series of x-ordered
+ * entries in a list, using the starting x co-ordinate.
+ */
+typedef struct docx_list_entry_t {
+    struct text_list_entry_s *previous;
+    struct text_list_entry_s *next;
+    gs_matrix matrix;		/* Tm et al */
+    char *FontName;
+    int wmode;			/* WMode of font */
+    double size;
+} docx_list_entry_t;
+
+/* The custom sub-classed device structure */
+typedef struct {
+    gx_device_common;
+    char fname[gp_file_name_sizeof];	/* OutputFile */
+    gp_file *file;
+    int TextFormat;
+    extract_alloc_t *alloc;
+    extract_t *extract;
+    int file_per_page;
+    float x;    /* Used to maintain x pos as we iterate through a span. */
+} gx_device_docxwrite_t;
+
+
+/* Device procedures */
+static dev_proc_open_device(docxwrite_open_device);
+static dev_proc_close_device(docxwrite_close_device);
+static dev_proc_output_page(docxwrite_output_page);
+static dev_proc_fill_rectangle(docxwrite_fill_rectangle);
+static dev_proc_get_params(docxwrite_get_params);
+static dev_proc_put_params(docxwrite_put_params);
+static dev_proc_fill_path(docxwrite_fill_path);
+static dev_proc_stroke_path(docxwrite_stroke_path);
+static dev_proc_text_begin(docxwrite_text_begin);
+static dev_proc_strip_copy_rop(docxwrite_strip_copy_rop);
+static dev_proc_dev_spec_op(docxwrite_dev_spec_op);
+
+
+/* The device prototype */
+#define X_DPI 72
+#define Y_DPI 72
+
+/* Define the text enumerator. */
+typedef struct {
+    gs_text_enum_common;
+    gs_text_enum_t *pte_fallback;
+    double d1_width;
+    bool d1_width_set;
+    bool charproc_accum;
+    bool cdevproc_callout;
+    double cdevproc_result[10];
+    docx_list_entry_t *text_state;
+} docxw_text_enum_t;
+#define private_st_textw_text_enum()\
+  extern_st(st_gs_text_enum);\
+  gs_private_st_suffix_add0(st_textw_text_enum, docxw_text_enum_t,\
+    "docxw_text_enum_t", textw_text_enum_enum_ptrs, textw_text_enum_reloc_ptrs,\
+    st_gs_text_enum)
+
+private_st_textw_text_enum();
+
+const gx_device_docxwrite_t gs_docxwrite_device =
+{
+    /* Define the device as 8-bit gray scale to avoid computing halftones. */
+    std_device_dci_body(gx_device_docxwrite_t, 0, "docxwrite",
+                        DEFAULT_WIDTH_10THS * X_DPI / 10,
+                        DEFAULT_HEIGHT_10THS * Y_DPI / 10,
+                        X_DPI, Y_DPI,
+                        1, 8, 255, 0, 256, 1),
+    {docxwrite_open_device,
+     NULL, /*gx_upright_get_initial_matrix,*/
+     NULL, /*gx_default_sync_output,*/
+     docxwrite_output_page,
+     docxwrite_close_device,
+     NULL, /*gx_default_gray_map_rgb_color,*/
+     NULL, /*gx_default_gray_map_color_rgb,*/
+     docxwrite_fill_rectangle,               /* Can't be NULL and there is no gx_default_fill_rectangle! */
+     NULL, /*gx_default_tile_rectangle,*/
+     NULL, /*gx_default_copy_mono,*/
+     NULL, /*gx_default_copy_color,*/
+     NULL, /*gx_default_draw_line,*/
+     NULL, /*gx_default_get_bits,*/
+     docxwrite_get_params,
+     docxwrite_put_params,
+     NULL, /*gx_default_map_cmyk_color,*/
+     NULL, /*gx_default_get_xfont_procs,*/
+     NULL, /*gx_default_get_xfont_device,*/
+     NULL, /*gx_default_map_rgb_alpha_color,*/
+     gx_page_device_get_page_device, /*gx_page_device_get_page_device,*/
+     NULL,			/* get_alpha_bits */
+     NULL, /*gx_default_copy_alpha,*/
+     NULL,			/* get_band */
+     NULL,			/* copy_rop */
+     docxwrite_fill_path,
+     docxwrite_stroke_path,
+     NULL, /*gx_default_fill_mask,*/
+     NULL, /*gx_default_fill_trapezoid,*/
+     NULL, /*gx_default_fill_parallelogram,*/
+     NULL, /*gx_default_fill_triangle,*/
+     NULL, /*gx_default_draw_thin_line,*/
+     NULL,                      /* begin image */
+     NULL,			/* image_data */
+     NULL,			/* end_image */
+     NULL, /*gx_default_strip_tile_rectangle,*/
+     docxwrite_strip_copy_rop,
+     NULL,			/* get_clipping_box */
+     NULL, /* docxwrite_begin_typed_image */
+     NULL,			/* get_bits_rectangle */
+     NULL, /*gx_default_map_color_rgb_alpha,*/
+     gx_null_create_compositor,
+     NULL,			/* get_hardware_params */
+     docxwrite_text_begin,
+     NULL,			/* finish_copydevice */
+     NULL,			/* begin_transparency_group */
+     NULL,			/* end_transparency_group */
+     NULL,			/* begin_transparency_mask */
+     NULL,			/* end_transparency_mask */
+     NULL,			/* discard_transparency_layer */
+     NULL,			/* get_color_mapping_procs */
+     NULL,			/* get_color_comp_index */
+     NULL,			/* encode_color */
+     NULL,			/* decode_color */
+     NULL,                      /* pattern manager */
+     NULL,                      /* fill_rectangle_hl_color */
+     NULL,                      /* include_color_space */
+     NULL,                      /* fill_linear_color_scanline */
+     NULL,                      /* fill_linear_color_trapezoid */
+     NULL,                      /* fill_linear_color_triangle */
+     NULL,                      /* update_spot_equivalent_colors */
+     NULL,                      /* ret_devn_params */
+     NULL,                      /* fillpage */
+     NULL,                      /* push_transparency_state */
+     NULL,                      /* pop_transparency_state */
+     NULL,                      /* put_image */
+     docxwrite_dev_spec_op,      /* dev_spec_op */
+     NULL,                      /* copy_planes */
+     NULL,                      /* get_profile */
+     NULL,                      /* set_graphics_type_tag */
+     NULL,                      /* strip_copy_rop2 */
+     NULL                       /* strip_tile_rect_devn */
+    },
+    { 0 },			/* Page Data */
+    0,				/* Output FILE * */
+    0,				/* TextFormat */
+    NULL,           /* alloc */
+    NULL,			/* extract */
+    0,              /* file_per_page */
+    0.0             /* x */
+};
+
+
+static const gs_param_item_t docx_param_items[] = {
+#define pi(key, type, memb) { key, type, offset_of(gx_device_docxwrite_t, memb) }
+    pi("TextFormat", gs_param_type_int, TextFormat),
+#undef pi
+    gs_param_item_end
+};
+
+/* ---------------- Open/close/page ---------------- */
+
+
+static void *s_extract_realloc_fn(void *state, void *ptr, size_t newsize)
+{
+    /* We have to go to some effort to behave like realloc() when we only have
+    make gs_malloc() and gs_free() available. We store each allocated block's
+    allocation size in the preceding size_t. */
+    gs_memory_t *mem = state;
+    size_t *oldbase = (ptr) ? (size_t*) ptr - 1 : NULL;
+    size_t oldsize = (oldbase) ? *oldbase : 0;
+    size_t *newbase = NULL;
+    if (newsize) {
+        /* malloc() or realloc() - allocate new buffer.  */
+        newbase = gs_malloc(mem, sizeof(size_t) + newsize /*nelts*/, 1 /*esize*/, "extract");
+        if (newbase) {
+            *newbase = newsize;
+            if (oldbase) {
+                /* Realloc, so copy across. */
+                size_t minsize = (newsize < oldsize) ? newsize : oldsize;
+                memcpy(newbase+1, oldbase+1, minsize);
+            }
+        }
+    }
+    if (oldbase && (!newsize || newbase)) {
+        /* free() or successful realloc() - free the old buffer. */
+        gs_free(mem, oldbase, sizeof(size_t) + oldsize /*nelts*/, 1 /*esize*/, "extract");
+    }
+    return (newbase) ? newbase + 1 : NULL;
+}
+
+static int s_errno_to_gs(void)
+{
+    if (errno == EPERM) return gs_error_invalidaccess;
+    if (errno == ENOENT) return gs_error_invalidfileaccess;
+    if (errno == ESRCH) {}
+    if (errno == EINTR) {}
+    if (errno == EIO) return gs_error_ioerror;
+    if (errno == ENXIO) {}
+
+    return gs_error_unknownerror;
+}
+
+static int
+docxwrite_open_device(gx_device * dev)
+{
+    gx_device_docxwrite_t * tdev = (gx_device_docxwrite_t *) dev;
+    const char* fmt = NULL;
+    gs_parsed_file_name_t parsed;
+    int code = 0;
+
+    gx_device_fill_in_procs(dev);
+    if (tdev->fname[0] == 0)
+        return_error(gs_error_undefinedfilename);
+
+    tdev->file = NULL;
+    dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
+    set_linear_color_bits_mask_shift(dev);
+    dev->interpolate_control = 0;
+
+    tdev->alloc = NULL;
+    tdev->extract = NULL;
+
+    code = gx_parse_output_file_name(&parsed, &fmt, tdev->fname, strlen(tdev->fname), tdev->memory);
+    if (code < 0) goto end;
+    tdev->file_per_page = (fmt) ? 1 : 0;
+
+    if (extract_alloc_create(s_extract_realloc_fn, tdev->memory, &tdev->alloc)) {
+        code = s_errno_to_gs();
+        goto end;
+    }
+    extract_alloc_exp_min(tdev->alloc, 64);
+
+    if (extract_begin(tdev->alloc, &tdev->extract)) {
+        code = s_errno_to_gs();
+        goto end;
+    }
+    if (extract_page_begin(tdev->extract)) {
+        code = s_errno_to_gs();
+        goto end;
+    }
+    code = install_internal_subclass_devices((gx_device **)&dev, NULL);
+
+    end:
+
+    if (code < 0) {
+        extract_alloc_destroy(&tdev->alloc);
+        extract_end(&tdev->extract);
+    }
+    return code;
+}
+
+/* For use with an extract_buffer_t - writes directly to tdev->file. */
+static int docxwrite_extract_buffer_write(void* handle, const void* source, size_t numbytes, size_t* o_actual)
+{
+    int n;
+    gx_device_docxwrite_t *tdev = handle;
+    n = gp_fwrite(source, 1 /*size*/, numbytes /*count*/, tdev->file);
+    if (n < 0) return s_errno_to_gs();
+    *o_actual = n;
+    return 0;
+}
+
+/* Finishes processing for page.
+
+If  is true, we write to file; e.g. set if we are writing a file
+per page, or if we are being called from docxwrite_close_device(). */
+static int
+s_end_page(gx_device_docxwrite_t *tdev, int write_file)
+{
+    int code = 0;
+    extract_buffer_t *buffer = NULL;
+
+    if (!tdev->extract) {
+        /* Nothing to do. */
+        return 0;
+    }
+    if (extract_page_end(tdev->extract)) {
+        code = s_errno_to_gs();
+        goto end;
+    }
+    if (extract_process(tdev->extract, 0 /*spacing*/, 1 /*rotation*/, 1 /*images*/)) {
+        code = s_errno_to_gs();
+        goto end;
+    }
+    if (write_file) {
+        code = gx_device_open_output_file((gx_device*) tdev, tdev->fname, true, false, &tdev->file);
+        if (code) goto end;
+        /* extract_write() can only write to an extract_buffer_t, so we create one that
+        writes to tdev->file. */
+        if (extract_buffer_open(
+                tdev->alloc,
+                tdev,
+                NULL /*fn_read*/,
+                docxwrite_extract_buffer_write,
+                NULL /*cache*/,
+                NULL /*fn_close*/,
+                &buffer
+                )) {
+            code = s_errno_to_gs();
+            goto end;
+        }
+        if (extract_write(tdev->extract, buffer)) {
+            code = s_errno_to_gs();
+            goto end;
+        }
+    }
+
+    end:
+    extract_buffer_close(&buffer);
+    if (tdev->file) {
+        gx_device_close_output_file((gx_device*) tdev, tdev->fname, tdev->file);
+        tdev->file = NULL;
+    }
+    return code;
+}
+
+static int
+docxwrite_close_device(gx_device * dev)
+{
+    int code = 0;
+    gx_device_docxwrite_t *const tdev = (gx_device_docxwrite_t *) dev;
+    if (!tdev->file_per_page)
+    {
+        s_end_page(tdev, true /*write_file*/);
+    }
+    extract_end(&tdev->extract);
+    extract_alloc_destroy(&tdev->alloc);
+    return code;
+}
+
+static int
+docxwrite_output_page(gx_device * dev, int num_copies, int flush)
+{
+    int code;
+    gx_device_docxwrite_t *tdev = (gx_device_docxwrite_t *) dev;
+
+    s_end_page(tdev, tdev->file_per_page /*write_file*/);
+
+    if (tdev->file_per_page) {
+        /* Create a new extract_t for the next page. */
+        extract_end(&tdev->extract);
+        if (extract_begin(tdev->alloc, &tdev->extract)) {
+            code = s_errno_to_gs();
+            goto end;
+        }
+    }
+    if (extract_page_begin(tdev->extract)) {
+        code = s_errno_to_gs();
+        goto end;
+    }
+
+    code =  gx_default_output_page(dev, num_copies, flush);
+    if (code < 0)
+        goto end;
+
+    end:
+    return code;
+}
+
+/* ---------------- Low-level drawing ---------------- */
+
+static int
+docxwrite_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
+                    gx_color_index color)
+{
+    return 0;
+}
+
+/*static int
+docxwrite_copy_alpha(gx_device * dev, const byte * data, int data_x,
+                int raster, gx_bitmap_id id, int x, int y, int w, int h,
+                gx_color_index color, int depth)
+{
+    return 0;
+}
+
+static int
+docxwrite_copy_mono(gx_device * dev, const byte * data, int dx, int raster,
+               gx_bitmap_id id, int x, int y, int w, int h,
+               gx_color_index zero, gx_color_index one)
+{
+    return 0;
+}
+static int
+docxwrite_copy_color(gx_device * dev, const byte * data,
+                int data_x, int raster, gx_bitmap_id id,
+                int x, int y, int width, int height)
+{
+    return 0;
+}
+
+static int
+docxwrite_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
+   int x, int y, int w, int h, gx_color_index color0, gx_color_index color1,
+                          int px, int py)
+{
+    return 0;
+}
+
+static int
+docxwrite_strip_copy_rop(gx_device * dev,
+                    const byte * sdata, int sourcex, uint sraster,
+                    gx_bitmap_id id,
+                    const gx_color_index * scolors,
+                    const gx_strip_bitmap * textures,
+                    const gx_color_index * tcolors,
+                    int x, int y, int w, int h,
+                    int phase_x, int phase_y, gs_logical_operation_t lop)
+{
+    return 0;
+}*/
+
+/* ---------------- Parameters ---------------- */
+
+static int docxwrite_get_param(gx_device *dev, char *Param, void *list)
+{
+    gx_device_docxwrite_t *const tdev = (gx_device_docxwrite_t *) dev;
+    gs_param_list * plist = (gs_param_list *)list;
+    bool bool_T = true;
+
+    if (strcmp(Param, "OutputFile") == 0) {
+        gs_param_string ofns;
+
+        ofns.data = (const byte *)tdev->fname,
+        ofns.size = strlen(tdev->fname),
+        ofns.persistent = false;
+        return param_write_string(plist, "OutputFile", &ofns);
+    }
+    if (strcmp(Param, "WantsToUnicode") == 0) {
+        return param_write_bool(plist, "WantsToUnicode", &bool_T);
+    }
+    if (strcmp(Param, "PreserveTrMode") == 0) {
+        return param_write_bool(plist, "PreserveTrMode", &bool_T);
+    }
+    if (strcmp(Param, "HighLevelDevice") == 0) {
+        return param_write_bool(plist, "HighLevelDevice", &bool_T);
+    }
+    return_error(gs_error_undefined);
+}
+
+static int
+docxwrite_get_params(gx_device * dev, gs_param_list * plist)
+{
+    int code;
+    bool bool_T = true;
+    gs_param_string ofns;
+    gx_device_docxwrite_t *const tdev = (gx_device_docxwrite_t *) dev;
+
+    code = gx_default_get_params(dev, plist);
+    if (code < 0)
+        return code;
+
+    ofns.data = (const byte *)tdev->fname,
+    ofns.size = strlen(tdev->fname),
+    ofns.persistent = false;
+    code = param_write_string(plist, "OutputFile", &ofns);
+    if (code < 0)
+        return code;
+
+    code = param_write_bool(plist, "WantsToUnicode", &bool_T);
+    if (code < 0)
+        return code;
+
+    code = param_write_bool(plist, "PreserveTrMode", &bool_T);
+    if (code < 0)
+        return code;
+
+    code = param_write_bool(plist, "HighLevelDevice", &bool_T);
+    if (code < 0)
+        return code;
+
+   code = gs_param_write_items(plist, tdev, NULL, docx_param_items);
+   return code;
+}
+
+/* We implement put_params to ensure that we keep the important */
+/* device parameters up to date, and to prevent an /undefined error */
+static int
+docxwrite_put_params(gx_device * dev, gs_param_list * plist)
+{
+    gx_device_docxwrite_t *tdev = (gx_device_docxwrite_t *) dev;
+    int ecode = 0;
+    int code, old_TextFormat = tdev->TextFormat;
+    const char *param_name;
+    gs_param_string ofs;
+    bool dummy, open = dev->is_open;
+
+    switch (code = param_read_string(plist, (param_name = "OutputFile"), &ofs)) {
+        case 0:
+            if (dev->LockSafetyParams &&
+                    bytes_compare(ofs.data, ofs.size,
+                        (const byte *)tdev->fname, strlen(tdev->fname))) {
+                ecode = gs_note_error(gs_error_invalidaccess);
+                goto ofe;
+            }
+            if (ofs.size >= gp_file_name_sizeof)
+                ecode = gs_error_limitcheck;
+            else
+                break;
+            goto ofe;
+        default:
+            ecode = code;
+          ofe:param_signal_error(plist, param_name, ecode);
+        /* fall through */
+        case 1:
+            ofs.data = 0;
+            break;
+    }
+
+    if (ecode < 0)
+        return ecode;
+
+    code = param_read_int(plist, "TextFormat", &tdev->TextFormat);
+    if (code < 0)
+        return code;
+
+    code = param_read_bool(plist, "WantsToUnicode", &dummy);
+    if (code < 0)
+        return code;
+
+    code = param_read_bool(plist, "HighLevelDevice", &dummy);
+    if (code < 0)
+        return code;
+
+    code = param_read_bool(plist, "PreserveTrMode", &dummy);
+    if (code < 0)
+        return code;
+
+    if (ofs.data != 0) {	/* Close the file if it's open. */
+        if (0 && tdev->file != 0) {
+            gp_fclose(tdev->file);
+            tdev->file = 0;
+            outf("have closed tdef->file. tdev=%p", tdev);
+        }
+        memcpy(tdev->fname, ofs.data, ofs.size);
+        tdev->fname[ofs.size] = 0;
+    }
+
+    /* If we change media size then gs_default_put_params will close
+     * the device if it is open. We don't want it to do that, so set
+     * the device's 'is_open' flag to false, and reset it after we've
+     * processed the params.
+     */
+    if (old_TextFormat == tdev->TextFormat && open)
+        dev->is_open = false;
+
+    code = gx_default_put_params(dev, plist);
+    if (code < 0)
+        return code;
+
+    dev->is_open = open;
+
+    dev->interpolate_control = 0;
+
+    return 0;
+}
+
+/* ---------------- Polygon drawing ---------------- */
+
+/*static int
+docxwrite_fill_trapezoid(gx_device * dev,
+                    const gs_fixed_edge * left, const gs_fixed_edge * right,
+                    fixed ybot, fixed ytop, bool swap_axes,
+                    const gx_device_color * pdevc, gs_logical_operation_t lop)
+{
+    return 0;
+}
+
+static int
+docxwrite_fill_parallelogram(gx_device * dev,
+                        fixed px, fixed py, fixed ax, fixed ay,
+                        fixed bx, fixed by, const gx_device_color * pdevc,
+                        gs_logical_operation_t lop)
+{
+    return 0;
+}
+
+static int
+docxwrite_fill_triangle(gx_device * dev,
+                   fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by,
+                   const gx_device_color * pdevc, gs_logical_operation_t lop)
+{
+    return 0;
+}
+
+static int
+docxwrite_draw_thin_line(gx_device * dev,
+                    fixed fx0, fixed fy0, fixed fx1, fixed fy1,
+                    const gx_device_color * pdevc, gs_logical_operation_t lop,
+                    fixed adjustx, fixed adjusty)
+{
+    return 0;
+}*/
+
+/* ---------------- High-level drawing ---------------- */
+
+static int
+docxwrite_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
+               const gx_fill_params * params, const gx_device_color * pdevc,
+               const gx_clip_path * pcpath)
+{
+        return 0;
+}
+
+static int
+docxwrite_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
+                 const gx_stroke_params * params,
+                 const gx_drawing_color * pdevc, const gx_clip_path * pcpath)
+{
+    return 0;
+}
+
+
+/*
+ * Compute the cached values in the text processing state from the text
+ * parameters, current_font, and pgs->ctm.  Return either an error code (<
+ * 0) or a mask of operation attributes that the caller must emulate.
+ * Currently the only such attributes are TEXT_ADD_TO_ALL_WIDTHS and
+ * TEXT_ADD_TO_SPACE_WIDTH.  Note that this procedure fills in all the
+ * values in ppts->values, not just the ones that need to be set now.
+ */
+static int
+transform_delta_inverse(const gs_point *pdelta, const gs_matrix *pmat,
+                        gs_point *ppt)
+{
+    int code = gs_distance_transform_inverse(pdelta->x, pdelta->y, pmat, ppt);
+    gs_point delta;
+
+    if (code < 0)
+        return code;
+    if (ppt->y == 0)
+        return 0;
+    /* Check for numerical fuzz. */
+    code = gs_distance_transform(ppt->x, 0.0, pmat, &delta);
+    if (code < 0)
+        return 0;                /* punt */
+    if (fabs(delta.x - pdelta->x) < 0.01 && fabs(delta.y - pdelta->y) < 0.01) {
+        /* Close enough to y == 0: device space error < 0.01 pixel. */
+        ppt->y = 0;
+    }
+    return 0;
+}
+
+static int
+docx_update_text_state(docx_list_entry_t *ppts,
+                      const docxw_text_enum_t *penum,
+                      gs_font *ofont, const gs_matrix *pfmat)
+{
+    gx_device *const pdev = penum->dev;
+    gs_font *font = penum->current_font;
+    gs_fixed_point cpt;
+    gs_matrix smat, tmat;
+    float size;
+    int mask = 0;
+    int code = gx_path_current_point(penum->path, &cpt);
+
+    if (code < 0)
+        return code;
+
+    size = txt_calculate_text_size(penum->pgs, ofont, pfmat, &smat, &tmat, penum->current_font, pdev);
+    /* Check for spacing parameters we can handle, and transform them. */
+
+    if (penum->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
+        if (penum->current_font->WMode == 0) {
+            gs_point pt;
+
+            code = transform_delta_inverse(&penum->text.delta_all, &smat, &pt);
+            if (code < 0 || pt.y != 0)
+                mask |= TEXT_ADD_TO_ALL_WIDTHS;
+        }
+        else
+            mask |= TEXT_ADD_TO_ALL_WIDTHS;
+    }
+
+    if (penum->text.operation & TEXT_ADD_TO_SPACE_WIDTH) {
+        gs_point pt;
+
+        code = transform_delta_inverse(&penum->text.delta_space, &smat, &pt);
+        if (code < 0 || pt.y != 0 || penum->text.space.s_char != 32)
+            mask |= TEXT_ADD_TO_SPACE_WIDTH;
+    }
+    /* Store the updated values. */
+
+    tmat.xx /= size;
+    tmat.xy /= size;
+    tmat.yx /= size;
+    tmat.yy /= size;
+    tmat.tx += fixed2float(cpt.x);
+    tmat.ty += fixed2float(cpt.y);
+
+    ppts->size = size;
+    ppts->matrix = tmat;
+    ppts->FontName = (char *)gs_malloc(pdev->memory->stable_memory, 1,
+        font->font_name.size + 1, "txtwrite alloc font name");
+    if (!ppts->FontName)
+        return gs_note_error(gs_error_VMerror);
+    memcpy(ppts->FontName, font->font_name.chars, font->font_name.size + 1);
+
+    if (font->PaintType == 2 && penum->pgs->text_rendering_mode == 0)
+    {
+        gs_gstate *pgs = penum->pgs;
+        gs_font *font = penum->current_font;
+        double scaled_width = font->StrokeWidth != 0 ? font->StrokeWidth : 0.001;
+        double saved_width = pgs->line_params.half_width;
+        /*
+         * See stream_to_text in gdevpdfu.c re the computation of
+         * the scaling value.
+         */
+        double scale = 72.0 / pdev->HWResolution[1];
+
+        if (font->FontMatrix.yy != 0)
+            scaled_width *= fabs(font->orig_FontMatrix.yy) * size * tmat.yy * scale;
+        else
+            scaled_width *= fabs(font->orig_FontMatrix.xy) * size * tmat.xy * scale;
+
+        pgs->line_params.half_width = scaled_width / 2;
+        if (code < 0)
+            return code;
+
+        pgs->line_params.half_width = saved_width;
+    }
+    return (code < 0 ? code : mask);
+}
+
+/* Simple routine to update the current point by the accumulated width of the
+ * text.
+ */
+static int
+docx_shift_text_currentpoint(docxw_text_enum_t *penum, gs_point *wpt)
+{
+    return gs_moveto_aux(penum->pgs, gx_current_path(penum->pgs),
+                              fixed2float(penum->origin.x) + wpt->x,
+                              fixed2float(penum->origin.y) + wpt->y);
+}
+
+static int font_final(gx_device_docxwrite_t *tdev, docxw_text_enum_t *penum)
+{
+    gs_text_enum_t* pte = (void*) penum;
+    gs_font_base *font_base = (gs_font_base *)pte->current_font;
+    int code;
+
+    penum->d1_width = 0;
+    penum->d1_width_set = false;
+    if (font_base->FontBBox.p.x != font_base->FontBBox.q.x ||
+        font_base->FontBBox.p.y != font_base->FontBBox.q.y) {
+        gs_point p0, p1, p2, p3;
+        gs_matrix m;
+
+        m = ctm_only(pte->pgs);
+        m.tx = m.ty = fixed2float(0);
+        gs_matrix_multiply(&font_base->FontMatrix, &m, &m);
+        gs_point_transform(font_base->FontBBox.p.x, font_base->FontBBox.p.y, &m, &p0);
+        gs_point_transform(font_base->FontBBox.p.x, font_base->FontBBox.q.y, &m, &p1);
+        gs_point_transform(font_base->FontBBox.q.x, font_base->FontBBox.p.y, &m, &p2);
+        gs_point_transform(font_base->FontBBox.q.x, font_base->FontBBox.q.y, &m, &p3);
+    }
+    code = docx_shift_text_currentpoint(penum, &penum->returned.total_width);
+    return code;
+}
+
+
+/* Routines to enumerate each glyph/character code in turn and sent to
+ * extract_add_char().
+ */
+
+static int
+docxwrite_process_cmap_text(gx_device_docxwrite_t *tdev, gs_text_enum_t *pte)
+{
+    docxw_text_enum_t *const penum = (docxw_text_enum_t *)pte;
+    unsigned int rcode = 0;
+    gs_text_enum_t scan = *(gs_text_enum_t *)pte;
+    int i;
+
+    /* Composite font using a CMap */
+
+    for (i=0; ; ++i) {
+        const char* prevFontName;
+
+        gs_glyph glyph;
+        int font_code, code;
+        gs_font *subfont;
+        gs_char chr;
+        txt_glyph_widths_t widths;
+        gs_matrix m3;
+        gs_point wanted;	/* user space */
+        gs_point dpt = {0,0};
+
+        font_code = scan.orig_font->procs.next_char_glyph
+                (&scan, &chr, &glyph);
+
+        subfont = scan.fstack.items[scan.fstack.depth].font;
+
+        if (font_code == 2) {
+            /* end of string */
+            return 0;
+        }
+        if (font_code != 0 && font_code != 1) {
+            /* error */
+            return font_code;
+        }
+
+        if (font_code == 1) {
+            /* font change */
+            if (i) abort();
+        }
+
+        code = txt_glyph_widths(subfont, scan.orig_font->WMode, glyph, (gs_font *)subfont, &widths,
+                penum->cdevproc_callout ? penum->cdevproc_result : NULL);
+        if (code == TEXT_PROCESS_CDEVPROC) {
+            penum->cdevproc_callout = true;
+            pte->returned.current_glyph = glyph;
+            scan.returned.current_glyph = glyph;
+            pte->current_font = subfont;
+            scan.current_font = subfont;
+            rcode = TEXT_PROCESS_CDEVPROC;
+            break;
+        }
+        else {
+            penum->cdevproc_callout = false;
+            pte->index = scan.index;
+        }
+        code = gs_matrix_multiply(&subfont->FontMatrix, &pte->orig_font->FontMatrix, &m3);
+        if (code < 0) {
+            outf("returning code=%i", code);
+            return code;
+        }
+        prevFontName = penum->text_state->FontName;
+        code = docx_update_text_state(penum->text_state, (docxw_text_enum_t *)pte, subfont, &m3);
+        if (code < 0) {
+            outf("returning code=%i", code);
+            return code;
+        }
+        if (!prevFontName && penum->text_state->FontName) {
+
+            tdev->x = fixed2float(penum->origin.x) - penum->text_state->matrix.tx;
+
+            if (extract_span_begin(
+                    tdev->extract,
+                    penum->text_state->FontName,
+                    0 /*font_bold*/,
+                    0 /*font_italic*/,
+                    penum->text_state->wmode,
+                    penum->text_state->matrix.xx,
+                    penum->text_state->matrix.xy,
+                    penum->text_state->matrix.yx,
+                    penum->text_state->matrix.yy,
+                    penum->text_state->matrix.tx,
+                    penum->text_state->matrix.ty,
+                    penum->text_state->size,
+                    0.0f,
+                    0.0f,
+                    penum->text_state->size,
+                    0.0f,
+                    0.0f
+                    )) {
+                return s_errno_to_gs();
+            }
+        }
+        txt_char_widths_to_uts(pte->orig_font, &widths); /* convert design->text space */
+        gs_distance_transform(widths.real_width.xy.x * penum->text_state->size,
+                  widths.real_width.xy.y * penum->text_state->size,
+                  &penum->text_state->matrix, &wanted);
+        pte->returned.total_width.x += wanted.x;
+        pte->returned.total_width.y += wanted.y;
+
+        {
+            unsigned short buffer[4];
+            float glyph_width = widths.real_width.xy.x * penum->text_state->size;
+
+            if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
+                gs_point tpt;
+
+                gs_distance_transform(pte->text.delta_all.x, pte->text.delta_all.y,
+                          &ctm_only(pte->pgs), &tpt);
+                dpt.x += tpt.x;
+                dpt.y += tpt.y;
+            }
+            if (pte->text.operation & TEXT_ADD_TO_SPACE_WIDTH && chr == pte->text.space.s_char) {
+                gs_point tpt;
+
+                gs_distance_transform(pte->text.delta_space.x, pte->text.delta_space.y,
+                          &ctm_only(pte->pgs), &tpt);
+                dpt.x += tpt.x;
+                dpt.y += tpt.y;
+            }
+            pte->returned.total_width.x += dpt.x;
+            pte->returned.total_width.y += dpt.y;
+
+            glyph_width += dpt.x;
+
+            /* We can get up to 4 Unicode points per glyph, and a glyph can be
+             * be represented by as little as one byte. So we make a very large
+             * temporary buffer to hold the Unicode string as we assemble it. When
+             * we copy it to the text fragment we will allocate only as many bytes
+             * as are required to hold the actual nukmber of Unicode values we
+             * decoded, and this temporary buffer will be discarded.
+             */
+
+            txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, chr, &buffer[0]);
+
+            if (extract_add_char(
+                    tdev->extract,
+                    tdev->x,
+                    fixed2float(penum->origin.y) - penum->text_state->matrix.ty,
+                    buffer[0] /*ucs*/,
+                    glyph_width / penum->text_state->size /*adv*/,
+                    0 /*autosplit*/
+                    )) {
+                return s_errno_to_gs();
+            }
+        }
+
+        tdev->x += widths.real_width.xy.x * penum->text_state->size;
+
+        if (rcode || pte->index >= pte->text.size)
+            break;
+    }
+    if (!rcode) rcode = font_final(tdev, penum);
+    return rcode;
+}
+
+static int
+docxwrite_process_plain_text(gx_device_docxwrite_t *tdev, gs_text_enum_t *pte)
+{
+    /* one byte regular font */
+    docxw_text_enum_t *const penum = (docxw_text_enum_t *)pte;
+    gs_font *font = pte->orig_font;
+    const gs_glyph *gdata = NULL;
+    gs_glyph glyph;
+    gs_char ch = 0;
+    int i, code;
+    uint operation = pte->text.operation;
+    txt_glyph_widths_t widths;
+    gs_point wanted;	/* user space */
+
+    for (i=pte->index;itext.size;i++) {
+        const char* prevFontName;
+        float span_delta_x;
+        float glyph_width;
+        unsigned short chr2[4];
+
+        gs_point dpt = {0,0};
+        if (operation & (TEXT_FROM_STRING | TEXT_FROM_BYTES)) {
+            ch = pte->text.data.bytes[pte->index];
+        } else if (operation & (TEXT_FROM_CHARS | TEXT_FROM_SINGLE_CHAR)) {
+            ch = pte->text.data.chars[pte->index];
+        } else if (operation & (TEXT_FROM_GLYPHS | TEXT_FROM_SINGLE_GLYPH)) {
+            if (operation & TEXT_FROM_GLYPHS) {
+                gdata = pte->text.data.glyphs + (pte->index++ * sizeof (gs_glyph));
+            } else {
+                gdata = &pte->text.data.d_glyph;
+            }
+        }
+        glyph = (gdata == NULL ? pte->orig_font->procs.encode_char(pte->orig_font, ch, GLYPH_SPACE_NAME)
+                           : *gdata);
+
+        code = txt_glyph_widths(font, font->WMode, glyph, (gs_font *)font, &widths, NULL);
+        if (code < 0) {
+            if (penum->d1_width_set) {
+                widths.Width.w = widths.Width.xy.x = widths.real_width.w = widths.real_width.xy.x = penum->d1_width;
+                penum->d1_width = 0;
+                penum->d1_width_set = 0;
+            }
+            else
+                return code;
+        }
+
+        prevFontName = penum->text_state->FontName;
+        penum->cdevproc_callout = false;
+        code = docx_update_text_state(penum->text_state, (docxw_text_enum_t *)pte, pte->orig_font, &font->FontMatrix);
+        if (code < 0)
+            return code;
+
+        if (!prevFontName && penum->text_state->FontName) {
+
+            tdev->x = fixed2float(penum->origin.x) - penum->text_state->matrix.tx;
+
+            if (extract_span_begin(
+                    tdev->extract,
+                    penum->text_state->FontName,
+                    0 /*font_bold*/,
+                    0 /*font_italic*/,
+                    penum->text_state->wmode,
+                    penum->text_state->matrix.xx,
+                    penum->text_state->matrix.xy,
+                    penum->text_state->matrix.yx,
+                    penum->text_state->matrix.yy,
+                    penum->text_state->matrix.tx,
+                    penum->text_state->matrix.ty,
+                    penum->text_state->size,
+                    0.0f,
+                    0.0f,
+                    penum->text_state->size,
+                    0.0f,
+                    0.0f
+                    )) {
+                return s_errno_to_gs();
+            }
+        }
+        txt_char_widths_to_uts(pte->orig_font, &widths); /* convert design->text space */
+        gs_distance_transform(widths.real_width.xy.x * penum->text_state->size,
+                          widths.real_width.xy.y * penum->text_state->size,
+                          &penum->text_state->matrix, &wanted);
+        pte->returned.total_width.x += wanted.x;
+        pte->returned.total_width.y += wanted.y;
+        span_delta_x = widths.real_width.xy.x * penum->text_state->size;
+        glyph_width = widths.real_width.xy.x * penum->text_state->size;
+
+        if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
+            gs_point tpt;
+
+            gs_distance_transform(pte->text.delta_all.x, pte->text.delta_all.y,
+                              &ctm_only(pte->pgs), &tpt);
+            dpt.x += tpt.x;
+            dpt.y += tpt.y;
+        }
+        if (pte->text.operation & TEXT_ADD_TO_SPACE_WIDTH && ch == pte->text.space.s_char) {
+            gs_point tpt;
+
+            gs_distance_transform(pte->text.delta_space.x, pte->text.delta_space.y,
+                              &ctm_only(pte->pgs), &tpt);
+            dpt.x += tpt.x;
+            dpt.y += tpt.y;
+        }
+        pte->returned.total_width.x += dpt.x;
+        pte->returned.total_width.y += dpt.y;
+
+        span_delta_x += dpt.x;
+
+        code = txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, ch, &chr2[0]);
+        /* If a single text code returned multiple Unicode values, then we need to set the
+         * 'extra' code points' widths to 0.
+         */
+
+        if (extract_add_char(
+                tdev->extract,
+                tdev->x,
+                fixed2float(penum->origin.y) - penum->text_state->matrix.ty,
+                chr2[0] /*ucs*/,
+                glyph_width / penum->text_state->size /*adv*/,
+                0 /*autosplit*/
+                )) {
+            return s_errno_to_gs();
+        }
+        tdev->x += span_delta_x;
+        pte->index++;
+    }
+    code = 0;
+    if (!code) code = font_final(tdev, penum);
+
+    return code;
+}
+
+/* This routine selects whether the text needs to be handled as regular glyphs
+ * and character codes, or as CIDs, depending on the font type. This is required
+ * because there are ways that regular text can be handled that aren't possible
+ * with CIDFonts.
+ */
+static int
+textw_text_process(gs_text_enum_t *pte)
+{
+    docxw_text_enum_t *const penum = (docxw_text_enum_t *)pte;
+    gx_device_docxwrite_t *const tdev = (gx_device_docxwrite_t *) pte->dev;
+    gs_font *font = pte->orig_font;
+    int code = 0;
+    gs_text_enum_t *pte_fallback;
+
+    if (pte->text.size == 0)
+        return 0;
+
+    pte_fallback = penum->pte_fallback;
+    if (pte_fallback) {
+        code = gx_default_text_restore_state(pte_fallback);
+        if (code < 0)
+            return code;
+        gs_text_release(NULL, pte_fallback, "docxwrite_text_process");
+    }
+    pte_fallback = penum->pte_fallback = NULL;
+
+    {
+        switch (font->FontType) {
+        case ft_CID_encrypted:
+        case ft_CID_TrueType:
+        case ft_composite:
+            code = docxwrite_process_cmap_text(tdev, pte);
+            break;
+        case ft_encrypted:
+        case ft_encrypted2:
+        case ft_TrueType:
+        case ft_user_defined:
+        case ft_PCL_user_defined:
+        case ft_GL2_stick_user_defined:
+        case ft_GL2_531:
+            code = docxwrite_process_plain_text(tdev, pte);
+            break;
+        default:
+            return_error(gs_error_rangecheck);
+            break;
+        }
+        if (code != 0) {
+            if (code == gs_error_unregistered) /* Debug purpose only. */
+                return code;
+            if (code == gs_error_VMerror)
+                return code;
+            if (code == gs_error_invalidfont) /* Bug 688370. */
+                return code;
+            /* Fall back to the default implementation. */
+            code = gx_default_text_begin(pte->dev, pte->pgs, &pte->text, pte->current_font,
+                                 pte->path, pte->pdcolor, pte->pcpath, pte->memory, &pte_fallback);
+            if (code < 0)
+                return code;
+            penum->pte_fallback = pte_fallback;
+            gs_text_enum_copy_dynamic(pte_fallback, pte, false);
+
+            code = gs_text_process(pte_fallback);
+            if (code != 0) {
+                penum->returned.current_char = pte_fallback->returned.current_char;
+                penum->returned.current_glyph = pte_fallback->returned.current_glyph;
+                return code;
+            }
+            gs_text_release(NULL, pte_fallback, "docxwrite_text_process");
+            penum->pte_fallback = 0;
+        }
+    }
+    return code;
+}
+
+/* Begin processing text. */
+
+/* Define the auxiliary procedures for text processing. */
+static int
+textw_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
+{
+    return gs_text_resync(pte, pfrom);
+}
+static bool
+textw_text_is_width_only(const gs_text_enum_t *pte)
+{
+    return false;
+}
+static int
+textw_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth)
+{
+    return gs_text_current_width(pte, pwidth);
+}
+static int
+textw_text_set_cache(gs_text_enum_t *pte, const double *pw,
+                   gs_text_cache_control_t control)
+{
+    docxw_text_enum_t *const penum = (docxw_text_enum_t *)pte;
+
+    switch (control) {
+        case TEXT_SET_CHAR_WIDTH:
+        case TEXT_SET_CACHE_DEVICE:
+            if (penum->pte_fallback != NULL) {
+                penum->d1_width = *pw;
+                penum->d1_width_set = true;
+                return 0;
+            }
+            return gs_text_set_cache(pte, pw, control);
+        case TEXT_SET_CACHE_DEVICE2:
+            if (penum->cdevproc_callout) {
+                memcpy(penum->cdevproc_result, pw, sizeof(penum->cdevproc_result));
+                return 0;
+            }
+            return gs_text_set_cache(pte, pw, control);
+        default:
+            return_error(gs_error_rangecheck);
+    }
+    return 0;
+}
+
+static int
+textw_text_retry(gs_text_enum_t *pte)
+{
+    return gs_text_retry(pte);
+}
+static void
+textw_text_release(gs_text_enum_t *pte, client_name_t cname)
+{
+    docxw_text_enum_t *const penum = (docxw_text_enum_t *)pte;
+    gx_device_docxwrite_t *const tdev = (gx_device_docxwrite_t *) pte->dev;
+
+    /* If this is copied away when we complete the text enumeration succesfully, then
+     * we set the pointer to NULL, if we get here with it non-NULL , then there was
+     * an error.
+     */
+    if (penum->text_state)
+        gs_free(tdev->memory, penum->text_state, 1, sizeof(penum->text_state), "txtwrite free text state");
+
+    gs_text_release(NULL, pte, cname);
+}
+
+/* This is the list of methods for the text enumerator */
+static const gs_text_enum_procs_t textw_text_procs = {
+    textw_text_resync, textw_text_process,
+    textw_text_is_width_only, textw_text_current_width,
+    textw_text_set_cache, textw_text_retry,
+    textw_text_release
+};
+
+/* This device method gets called by the interpreter to deal with text. It
+ * must create a text enumerator, which contains the methods for dealing with
+ * the text itself. The interpreter will use the enumerator methods to deal with
+ * the text, it won't refer to the device methods again for this text.
+ */
+static int
+docxwrite_text_begin(gx_device * dev, gs_gstate * pgs,
+                const gs_text_params_t * text, gs_font * font,
+                gx_path * path, const gx_device_color * pdcolor,
+                const gx_clip_path * pcpath,
+                gs_memory_t * mem, gs_text_enum_t ** ppenum)
+{
+    gx_device_docxwrite_t *const tdev = (gx_device_docxwrite_t *) dev;
+    docxw_text_enum_t *penum;
+    int code;
+
+    /* If this is a stringwidth, we must let the default graphics library code handle it
+     * in case there is no current point (this can happen if this is the first operation
+     * we get, the current font is a CIDFont, and its descendant is a substitute type 1
+     * font). If there is no current point we throw an error in text_process and that
+     * messes up all the font handling. The test below is copied from pdfwrite
+     * (gdev_pdf_text_begin) and seems to do the job.
+     */
+    if ((!(text->operation & TEXT_DO_DRAW) && pgs->text_rendering_mode != 3)
+                    || path == 0 || !path_position_valid(path))
+            return gx_default_text_begin(dev, pgs, text, font, path, pdcolor,
+                                         pcpath, mem, ppenum);
+    /* Allocate and initialize one of our text enumerators. */
+    rc_alloc_struct_1(penum, docxw_text_enum_t, &st_textw_text_enum, mem,
+                      return_error(gs_error_VMerror), "gdev_textw_text_begin");
+    penum->rc.free = rc_free_text_enum;
+    penum->charproc_accum = false;
+    penum->cdevproc_callout = false;
+    penum->returned.total_width.x = penum->returned.total_width.y = 0;
+    penum->pte_fallback = NULL;
+    penum->d1_width = 0;
+    penum->d1_width_set = false;
+    /* The enumerator's text_release method frees this memory */
+    penum->text_state = (docx_list_entry_t *)gs_malloc(tdev->memory->stable_memory, 1,
+            sizeof(docx_list_entry_t), "txtwrite alloc text state");
+    if (!penum->text_state)
+        return gs_note_error(gs_error_VMerror);
+    memset(penum->text_state, 0x00, sizeof(docx_list_entry_t));
+
+    code = gs_text_enum_init((gs_text_enum_t *)penum, &textw_text_procs,
+                             dev, pgs, text, font, path, pdcolor, pcpath, mem);
+    if (code < 0) {
+        /* Belt and braces; I'm not certain this is required, but its safe */
+        gs_free(tdev->memory, penum->text_state, 1, sizeof(docx_list_entry_t), "txtwrite free text state");
+        penum->text_state = NULL;
+        gs_free_object(mem, penum, "textwrite_text_begin");
+        return code;
+    }
+
+    code = gx_path_current_point(penum->path, &penum->origin);
+    if (code != 0)
+       return code;
+
+    *ppenum = (gs_text_enum_t *)penum;
+
+    return 0;
+}
+
+static int
+docxwrite_strip_copy_rop(gx_device * dev,
+                    const byte * sdata, int sourcex, uint sraster,
+                    gx_bitmap_id id,
+                    const gx_color_index * scolors,
+                    const gx_strip_bitmap * textures,
+                    const gx_color_index * tcolors,
+                    int x, int y, int w, int h,
+                    int phase_x, int phase_y, gs_logical_operation_t lop)
+{
+    return 0;
+}
+
+int
+docxwrite_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
+{
+    switch (dev_spec_op) {
+        case gxdso_get_dev_param:
+            {
+                int code;
+                dev_param_req_t *request = (dev_param_req_t *)data;
+                code = docxwrite_get_param(pdev, request->Param, request->list);
+                if (code != gs_error_undefined)
+                    return code;
+            }
+    }
+    return gx_default_dev_spec_op(pdev, dev_spec_op, data, size);
+}
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c
index 6752fabb..35dc6dc2 100644
--- a/devices/vector/gdevpdf.c
+++ b/devices/vector/gdevpdf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -38,6 +38,8 @@
 #include "gxfcache.h"
 #include "gdevpdts.h"       /* for sync_text_state */
 
+#include "gdevpdfo.h"
+
 /* Define the default language level and PDF compatibility level. */
 /* Acrobat 8 (PDF 1.7) is the default. (1.7 for ICC V4.2.0 profile support) */
 #define PSDF_VERSION_INITIAL psdf_version_ll3
@@ -1090,11 +1092,18 @@ round_box_coord(double xy)
 static int
 pdf_write_page(gx_device_pdf *pdev, int page_num)
 {
-    long page_id = pdf_page_id(pdev, page_num);
-    pdf_page_t *page = &pdev->pages[page_num - 1];
+    long page_id;
+    pdf_page_t *page;
     double mediabox[4] = {0, 0};
     stream *s;
-    const cos_value_t *v_mediabox = cos_dict_find_c_key(page->Page, "/MediaBox");
+    const cos_value_t *v_mediabox;
+
+    if (pdev->pages == NULL)
+        return_error(gs_error_undefined);
+
+    page = &pdev->pages[page_num - 1];
+    v_mediabox = cos_dict_find_c_key(page->Page, "/MediaBox");
+    page_id = pdf_page_id(pdev, page_num);
 
     /* If we have not been given a MediaBox overriding pdfmark, use the current media size. */
     s = pdev->strm;
@@ -1383,8 +1392,29 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
     /* Write the annotations array if any. */
 
     if (page->Annots) {
+        const cos_value_t *value = NULL;
+        const cos_array_element_t *e = NULL, *next = NULL;
+        long index = 0;
+
         stream_puts(s, "/Annots");
         COS_WRITE(page->Annots, pdev);
+        /* More complications caused by cos objects. Simply calling COS_FREE
+         * will free the array, but it won't free the elements of the array
+         * if they have non-zero IDs (see the comments regarding cleanup of
+         * resources in pdf_close at around line 1090 below). Because we've
+         * already written out the annotations, the dictionary contents have
+         * already been freed, but we need the IDs until this point when we
+         * write out the array in the page dictionary. So after using them,
+         * we must go through the array and set the ids to 0 so that COS_FREE
+         * will free the array elements as well as the array itself.
+         */
+        e = cos_array_element_first(page->Annots);
+        while (e != NULL) {
+            next = cos_array_element_next(e, &index, &value);
+            if (value->contents.object != NULL)
+                value->contents.object->id = 0;
+            e = next;
+        }
         COS_FREE(page->Annots, "pdf_write_page(Annots)");
         page->Annots = 0;
     }
@@ -2554,10 +2584,10 @@ pdf_close(gx_device * dev)
 {
     gx_device_pdf *const pdev = (gx_device_pdf *) dev;
     gs_memory_t *mem = pdev->pdf_memory;
-    stream *s;
+    stream *s = NULL;
     gp_file *tfile = pdev->xref.file;
     gs_offset_t xref = 0;
-    gs_offset_t resource_pos;
+    gs_offset_t resource_pos = 0;
     long Catalog_id = 0, Info_id = 0,
         Pages_id = 0, Encrypt_id = 0;
     long Threads_id = 0;
@@ -2569,12 +2599,15 @@ pdf_close(gx_device * dev)
     bool file_per_page = false;
 
     if (!dev->is_open)
-      return_error(gs_error_undefined);
+        return_error(gs_error_undefined);
     dev->is_open = false;
 
-    Catalog_id = pdev->Catalog->id;
-    Info_id = pdev->Info->id;
-    Pages_id = pdev->Pages->id;
+    if (pdev->Catalog)
+        Catalog_id = pdev->Catalog->id;
+    if (pdev->Info)
+        Info_id = pdev->Info->id;
+    if (pdev->Pages)
+        Pages_id = pdev->Pages->id;
 
     memset(&linear_params, 0x00, sizeof(linear_params));
     linear_params.Info_id = Info_id;
@@ -2681,7 +2714,7 @@ pdf_close(gx_device * dev)
     }
 
     /* Create the Pages tree. */
-    if (!(pdev->ForOPDFRead && pdev->ProduceDSC)) {
+    if (!(pdev->ForOPDFRead && pdev->ProduceDSC) && pdev->strm != NULL) {
         pdf_open_obj(pdev, Pages_id, resourcePagesTree);
         pdf_record_usage(pdev, Pages_id, resource_usage_part9_structure);
 
@@ -2724,7 +2757,7 @@ pdf_close(gx_device * dev)
             if (code >= 0)
                 code = code1;
             pdf_open_obj(pdev, pdev->outlines_id, resourceOutline);
-            pprintd1(s, "<< /Count %d", pdev->outlines_open);
+            pprintd1(s, "<< /Type /Outlines /Count %d", pdev->outlines_open);
             pprintld2(s, " /First %ld 0 R /Last %ld 0 R >>\n",
                   pdev->outline_levels[0].first.id,
                   pdev->outline_levels[0].last.id);
@@ -2844,7 +2877,8 @@ pdf_close(gx_device * dev)
         pdf_record_usage(pdev, pdev->Info->id, resource_usage_part9_structure);
 
     } else {
-        pdev->Info->id = 0;	/* Don't write Info dict for DSC PostScript */
+        if (pdev->Info != NULL)
+            pdev->Info->id = 0;	/* Don't write Info dict for DSC PostScript */
     }
     /*
      * Write the definitions of the named objects.
@@ -2852,10 +2886,13 @@ pdf_close(gx_device * dev)
      * XObjects, and images named by NI.
      */
 
-    do {
-        cos_dict_objects_write(pdev->local_named_objects, pdev);
-    } while (pdf_pop_namespace(pdev) >= 0);
-    cos_dict_objects_write(pdev->global_named_objects, pdev);
+    if(pdev->local_named_objects != NULL) {
+        do {
+            cos_dict_objects_write(pdev->local_named_objects, pdev);
+        } while (pdf_pop_namespace(pdev) >= 0);
+    }
+    if (pdev->global_named_objects != NULL)
+        cos_dict_objects_write(pdev->global_named_objects, pdev);
 
     if (pdev->ForOPDFRead && pdev->ProduceDSC) {
         int pages;
@@ -2870,20 +2907,22 @@ pdf_close(gx_device * dev)
 
     /* Copy the resources into the main file. */
 
-    s = pdev->strm;
-    resource_pos = stell(s);
-    sflush(pdev->asides.strm);
-    {
-        gp_file *rfile = pdev->asides.file;
-        int64_t res_end = gp_ftell(rfile);
+    if (pdev->strm != NULL) {
+        s = pdev->strm;
+        resource_pos = stell(s);
+        sflush(pdev->asides.strm);
+        {
+            gp_file *rfile = pdev->asides.file;
+            int64_t res_end = gp_ftell(rfile);
 
-        gp_fseek(rfile, 0L, SEEK_SET);
-        code1 = pdf_copy_data(s, rfile, res_end, NULL);
-        if (code >= 0)
-            code = code1;
+            gp_fseek(rfile, 0L, SEEK_SET);
+            code1 = pdf_copy_data(s, rfile, res_end, NULL);
+            if (code >= 0)
+                code = code1;
+        }
     }
 
-    if (pdev->ForOPDFRead && pdev->ProduceDSC) {
+    if (pdev->ForOPDFRead && pdev->ProduceDSC && s != NULL) {
         int j;
 
         pagecount = 1;
@@ -2959,7 +2998,7 @@ pdf_close(gx_device * dev)
         memset(linear_params.Offsets, 0x00, linear_params.LastResource * sizeof(gs_offset_t));
     }
 
-    if (!(pdev->ForOPDFRead && pdev->ProduceDSC)) {
+    if (!(pdev->ForOPDFRead && pdev->ProduceDSC) && pdev->strm != NULL) {
         /* Write Encrypt. */
         if (pdev->OwnerPassword.size > 0) {
             Encrypt_id = pdf_obj_ref(pdev);
@@ -3037,7 +3076,7 @@ pdf_close(gx_device * dev)
         }
     }
 
-    if (pdev->Linearise) {
+    if (pdev->Linearise && pdev->strm != NULL) {
         int i;
 
         code = pdf_linearise(pdev, &linear_params);
@@ -3055,13 +3094,13 @@ pdf_close(gx_device * dev)
      */
 
     /* Memory management of resources in pdfwrite is bizarre and complex. Originally there was no means
-     * to free any resorucesw on completionj, pdfwrite simply relied on the garbage collector to clean up
+     * to free any resources on completion, pdfwrite simply relied on the garbage collector to clean up
      * and all the resource objects are GC-visible. However, this doesn't work well when the interpreter
      * does not use GC, ie PCL or XPS, and even when GC is available, the time taken to clean up the
      * (sometimes enormous numbers) of objects can be surprisingly significant. So code was added above
-     * to handle the simple cases useing pdf_free_resource_object(), and below to handle the more complex
+     * to handle the simple cases using pdf_free_resource_object(), and below to handle the more complex
      * situations.
-     * The way this works is that for each resrouce type we free the 'object', if the object is itself
+     * The way this works is that for each resource type we free the 'object', if the object is itself
      * a 'cos' object (array, dictionary) then we free each of its members. However, if any of the objects
      * have an ID which is not zero, then we don't free them (this is true only for contents, all the
      * objects of a given type are freed regardless of whether their ID is 0). These are taken to be
@@ -3069,7 +3108,7 @@ pdf_close(gx_device * dev)
      * that resource type is freed. For the simple resources, which is most of them, this works well.
      *
      * However, there are complications; colour spaces and functions can contain cos objects
-     * whose members pointers to other objects of the same resoruce type (eg a type 3 stitching function
+     * whose members pointers to other objects of the same resource type (eg a type 3 stitching function
      * can point to an array of type 0 functions). We can't afford to have these free the object, because
      * the resource chain is still pointing at it, and will try to free it again. The same is also true if
      * we should encounter the object which is referenced before we find the reference. So for these cases
@@ -3087,11 +3126,11 @@ pdf_close(gx_device * dev)
      * There is a 'gotcha' here; previously we used to free the 'resourceOther' resources *before* calling
      * pdf_document_metadata(), now we call it after. The problem is that the metadata is stored as a resourceOther
      * resource *and* referenced from the Catalog dictionary, which is a 'global named resource'. We free global
-     * named resoruces as the absolute last action. Previously because we had free resourceOther resoruces before
+     * named resoruces as the absolute last action. Previously because we had free resourceOther resources before
      * creating the new reference to the Metadata, the fact that it was freed by the action of releasing the
      * global named resources wasn't a problem, now it is. If we free the metadata as a 'resourceOther' then when
      * we try to free it as a global named resource we will run into trouble again. So pdf_document_metadata() has been
-     * specifally altered to remove the reference to the metadata from the resourceOther resource chain immediately
+     * specifically altered to remove the reference to the metadata from the resourceOther resource chain immediately
      * after it has been created. Ick.....
      */
     {
@@ -3170,7 +3209,7 @@ pdf_close(gx_device * dev)
 
             for (; pres != 0;) {
                 if (pres->object) {
-                    gs_free_object(pdev->pdf_memory, (byte *)pres->object, "Free CharProc");
+                    cos_free(pres->object, "free CharProc resource");
                     pres->object = 0;
                 }
                 pres = pres->next;
@@ -3366,23 +3405,30 @@ pdf_close(gx_device * dev)
 
     /* Free named objects. */
 
-    cos_release((cos_object_t *)pdev->NI_stack, "Release Name Index stack");
-    gs_free_object(mem, pdev->NI_stack, "Free Name Index stack");
-    pdev->NI_stack = 0;
+    if (pdev->NI_stack != NULL) {
+        cos_release((cos_object_t *)pdev->NI_stack, "Release Name Index stack");
+        gs_free_object(mem, pdev->NI_stack, "Free Name Index stack");
+        pdev->NI_stack = 0;
+    }
 
-    cos_dict_objects_delete(pdev->local_named_objects);
-    COS_FREE(pdev->local_named_objects, "pdf_close(local_named_objects)");
-    pdev->local_named_objects = 0;
+    if (pdev->local_named_objects != NULL) {
+        cos_dict_objects_delete(pdev->local_named_objects);
+        COS_FREE(pdev->local_named_objects, "pdf_close(local_named_objects)");
+        pdev->local_named_objects = 0;
+    }
 
-    /* global resources include the Catalog object and apparently the Info dict */
-    cos_dict_objects_delete(pdev->global_named_objects);
-    COS_FREE(pdev->global_named_objects, "pdf_close(global_named_objects)");
-    pdev->global_named_objects = 0;
+    if (pdev->global_named_objects != NULL) {
+        /* global resources include the Catalog object and apparently the Info dict */
+        cos_dict_objects_delete(pdev->global_named_objects);
+        COS_FREE(pdev->global_named_objects, "pdf_close(global_named_objects)");
+        pdev->global_named_objects = 0;
+    }
 
     /* Wrap up. */
 
     pdev->font_cache = 0;
 
+    if (pdev->pages != NULL)
     {
         int i;
         for (i=0;i < pdev->next_page;i++) {
@@ -3402,24 +3448,32 @@ pdf_close(gx_device * dev)
     gs_free_object(mem, pdev->sbstack, "Free sbstack");
     pdev->sbstack = 0;
 
-    text_data_free(mem, pdev->text);
+    if (pdev->text != NULL)
+        text_data_free(mem, pdev->text);
     pdev->text = 0;
 
-    cos_release((cos_object_t *)pdev->Pages, "release Pages dict");
-    gs_free_object(mem, pdev->Pages, "Free Pages dict");
-    pdev->Pages = 0;
+    if (pdev->Pages != NULL) {
+        cos_release((cos_object_t *)pdev->Pages, "release Pages dict");
+        gs_free_object(mem, pdev->Pages, "Free Pages dict");
+        pdev->Pages = 0;
+    }
 
+    if (pdev->vgstack != NULL)
     {
         int i;
-        for (i=0;i < pdev->vgstack_depth;i++)
-            gs_free_object(pdev->memory->non_gc_memory, pdev->vgstack[i].dash_pattern, "pdfwrite final free stored dash in gstate");
+        for (i=0;i < pdev->vgstack_size;i++) {
+            if (pdev->vgstack[i].dash_pattern != NULL)
+                gs_free_object(pdev->memory->non_gc_memory, pdev->vgstack[i].dash_pattern, "pdfwrite final free stored dash in gstate");
+        }
+        gs_free_object(pdev->pdf_memory, pdev->vgstack, "pdf_close(graphics state stack)");
+        pdev->vgstack = 0;
     }
-    gs_free_object(pdev->pdf_memory, pdev->vgstack, "pdf_close(graphics state stack)");
-    pdev->vgstack = 0;
 
-    cos_release((cos_object_t *)pdev->Namespace_stack, "release Name space stack");
-    gs_free_object(mem, pdev->Namespace_stack, "Free Name space stack");
-    pdev->Namespace_stack = 0;
+    if (pdev->Namespace_stack != NULL) {
+        cos_release((cos_object_t *)pdev->Namespace_stack, "release Name space stack");
+        gs_free_object(mem, pdev->Namespace_stack, "Free Name space stack");
+        pdev->Namespace_stack = 0;
+    }
 
     pdev->Catalog = 0;
     pdev->Info = 0;
@@ -3429,6 +3483,7 @@ pdf_close(gx_device * dev)
     pdev->outline_depth = -1;
     pdev->max_outline_depth = 0;
 
+    if (s != NULL)
     {
         /* pdf_open_dcument could set up filters for entire document.
            Removing them now. */
diff --git a/devices/vector/gdevpdfb.c b/devices/vector/gdevpdfb.c
index 20339038..a7b36d82 100644
--- a/devices/vector/gdevpdfb.c
+++ b/devices/vector/gdevpdfb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -496,7 +496,7 @@ gdev_pdf_copy_color(gx_device * dev, const byte * base, int sourcex,
 /* Fill a mask. */
 int
 gdev_pdf_fill_mask(gx_device * dev,
-                 const byte * data, int data_x, int raster, gx_bitmap_id id,
+                   const byte * data, int data_x, int raster, gx_bitmap_id id,
                    int x, int y, int width, int height,
                    const gx_drawing_color * pdcolor, int depth,
                    gs_logical_operation_t lop, const gx_clip_path * pcpath)
@@ -505,6 +505,50 @@ gdev_pdf_fill_mask(gx_device * dev,
 
     if (width <= 0 || height <= 0)
         return 0;
+
+    /* If OCRStage is 'OCR_Rendering' then we are handling an image which is a rendered glyph
+     * that we want to have OCR software process and return a Unicode code point for.
+     * We specifically do *not* want to send the image to the output PDF file!
+     */
+    if (pdev->OCRStage == OCR_Rendering) {
+        int code = 0;
+        ocr_glyph_t *new_glyph = NULL;
+        int index;
+
+        new_glyph = (ocr_glyph_t *)gs_alloc_bytes(pdev->pdf_memory, sizeof(ocr_glyph_t), "");
+        if (new_glyph == NULL)
+            return_error(gs_error_VMerror);
+        new_glyph->data = gs_alloc_bytes(pdev->pdf_memory, raster*height, "");
+        if (new_glyph->data == NULL)
+            return_error(gs_error_VMerror);
+        memcpy(new_glyph->data, data, raster * height);
+        new_glyph->height = height;
+        new_glyph->width = width;
+        new_glyph->raster = raster;
+        new_glyph->x = x;
+        new_glyph->y = y;
+        new_glyph->char_code = pdev->OCR_char_code;
+        new_glyph->glyph = pdev->OCR_glyph;
+        new_glyph->next = NULL;
+        new_glyph->is_space = true;
+        for(index = 0; index < height * raster;index++){
+            if(data[index] != 0x00) {
+                new_glyph->is_space = false;
+                break;
+            }
+        }
+        if (pdev->ocr_glyphs == NULL)
+            pdev->ocr_glyphs = new_glyph;
+        else {
+            ocr_glyph_t *next = pdev->ocr_glyphs;
+
+            while (next->next != NULL)
+                next = next->next;
+            next->next = new_glyph;
+        }
+        return code;
+    }
+
     if (depth > 1 || (!gx_dc_is_pure(pdcolor) != 0 && !(gx_dc_is_pattern1_color(pdcolor))))
         return gx_default_fill_mask(dev, data, data_x, raster, id,
                                     x, y, width, height, pdcolor, depth, lop,
diff --git a/devices/vector/gdevpdfb.h b/devices/vector/gdevpdfb.h
index 16521e0d..c0c3d220 100644
--- a/devices/vector/gdevpdfb.h
+++ b/devices/vector/gdevpdfb.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -116,11 +116,11 @@ const gx_device_pdf PDF_DEVICE_IDENT =
  -1,				/* EndPage */
  1,				/* StartPage */
  1 /*true*/,			/* Optimize */
- 0 /*false*/,			/* ParseDSCCommentsForDocInfo */
+ 1 /*true*/,			/* ParseDSCCommentsForDocInfo */
  1 /*true*/,			/* ParseDSCComments */
  0 /*false*/,			/* EmitDSCWarnings */
  0 /*false*/,			/* CreateJobTicket */
- 0 /*false*/,			/* PreserveEPSInfo */
+ 1 /*true*/,			/* PreserveEPSInfo */
  1 /*true*/,			/* AutoPositionEPSFiles */
  1 /*true*/,			/* PreserveCopyPage */
  0 /*false*/,			/* UsePrologue */
@@ -128,6 +128,8 @@ const gx_device_pdf PDF_DEVICE_IDENT =
  {0,0},				/* PDFXTrimBoxToMediaBoxOffset */
  {0,0},				/* PDFXBleedBoxToTrimBoxOffset */
  1 /* true */,			/* PDFXSetBleedBoxToMediaBox */
+ "",                            /* ocr_language */
+ 0,                             /* ocr_engine */
  1 /*true*/,			/* ReAssignCharacters */
  1 /*true*/,			/* ReEncodeCharacters */
  1,				/* FirstObjectNumber */
@@ -263,6 +265,7 @@ const gx_device_pdf PDF_DEVICE_IDENT =
  0,				/* image_mask_id */
  0,				/* image_mask_is_SMask */
  0,				/* image_mask_skip */
+ 0,             /* smask_construction */
  0,				/* image_with_SMask */
  {0,0,0,0,0,0}, 		/* gs_matrix converting_image_matrix */
  0,				/* image_mask_scale */
@@ -283,6 +286,7 @@ const gx_device_pdf PDF_DEVICE_IDENT =
  true,				/* DetectDuplicateImages */
  false,				/* AllowIncrementalCFF */
  !PDF_FOR_OPDFREAD,		/* WantsToUnicode */
+ !PDF_FOR_OPDFREAD,		/* PdfmarkCapable */
  !PDF_FOR_OPDFREAD,		/* WantsPageLabels */
  PDF_FOR_OPDFREAD,		/* AllowPSRepeatFunctions */
  true,				/* IsDistiller (true even for ps2write!) */
@@ -298,7 +302,14 @@ const gx_device_pdf PDF_DEVICE_IDENT =
  0,                     /* ExtensionMetadata */
  0,                     /* PDFFormName */
  0,                     /* PassThroughWriter */
- 1.0                    /* UserUnit */
+ 1.0,                   /* UserUnit */
+ 0,                     /* UseOCR */
+ NULL,                  /* OCRSaved */
+ 0,                     /* OCRStage */
+ NULL,                  /* OCRUnicode */
+ 0,                     /* OCR_char_code */
+ 0,                     /* OCR_glyph */
+ NULL                   /* ocr_glyphs */
 };
 
 #else
diff --git a/devices/vector/gdevpdfc.c b/devices/vector/gdevpdfc.c
index 3a3096c4..c573ad84 100644
--- a/devices/vector/gdevpdfc.c
+++ b/devices/vector/gdevpdfc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -527,7 +527,7 @@ pdf_separation_color_space(gx_device_pdf *pdev, const gs_gstate * pgs,
     }
 
     if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
-        (code = cos_array_add_no_copy(pca, snames)) < 0 ||
+        (code = cos_array_add(pca, snames)) < 0 ||
         (code = pdf_color_space_named(pdev, pgs, &v, &ranges, alt_space, pcsn, false, NULL, 0, false)) < 0 ||
         (code = cos_array_add(pca, &v)) < 0 ||
         (code = pdf_function_scaled(pdev, pfn, ranges, &v)) < 0 ||
@@ -1154,9 +1154,13 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
             for (i = 0; i < pcs->params.device_n.num_components; ++i) {
                 name_string = (byte *)pcs->params.device_n.names[i];
                 name_string_length = strlen(pcs->params.device_n.names[i]);
-                if ((code = pdf_string_to_cos_name(pdev, name_string,
-                                  name_string_length, &v)) < 0 ||
-                    (code = cos_array_add_no_copy(psna, &v)) < 0)
+
+                code = pdf_string_to_cos_name(pdev, name_string, name_string_length, &v);
+                if (code < 0)
+                    return code;
+                code = cos_array_add(psna, &v);
+                cos_value_free((const cos_value_t *)&v, pdev->pdf_memory, "pdf_color_space(DeviceN component)");
+                if (code < 0)
                     return code;
             }
             COS_OBJECT_VALUE(&v, psna);
@@ -1185,6 +1189,7 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
                         return gs_note_error(gs_error_typecheck);
                 }
                 code = cos_dict_put((cos_dict_t *)pres_attributes->object, (const byte *)"/Subtype", 8, &v_Subtype_name);
+                cos_value_free((const cos_value_t *)&v_Subtype_name, pdev->pdf_memory, "pdf_color_space(Subtype)");
                 if (code < 0)
                     return code;
             }
@@ -1212,6 +1217,7 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
                     return code;
                 code = cos_dict_put(process, v_process_name.contents.chars.data,
                                     v_process_name.contents.chars.size, &v_process_space);
+                cos_value_free((const cos_value_t *)&v_process_name, pdev->pdf_memory, "pdf_color_space(ColorSpace)");
                 if (code < 0)
                     return code;
 
@@ -1229,6 +1235,7 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
                     if (code < 0)
                         return code;
                     code = cos_array_put(components, m, &v_process_name);
+                    cos_value_free((const cos_value_t *)&v_process_name, pdev->pdf_memory, "pdf_color_space(process_name)");
                     if (code < 0)
                         return code;
                 }
@@ -1258,6 +1265,7 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
                         return code;
                     code = cos_dict_put(colorants, v_colorant_name.contents.chars.data,
                                         v_colorant_name.contents.chars.size, &v_separation);
+                    cos_value_free((const cos_value_t *)&v_colorant_name, pdev->pdf_memory, "pdf_color_space(Subtype)");
                     if (code < 0)
                         return code;
                 }
@@ -1270,9 +1278,14 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
                 va = &v_attributes;
                 COS_OBJECT_VALUE(va, pres_attributes->object);
             }
-            if ((code = pdf_separation_color_space(pdev, pgs, pca, "/DeviceN", &v,
+            code = pdf_separation_color_space(pdev, pgs, pca, "/DeviceN", &v,
                                                    pcs->base_space,
-                                        pfn, &pdf_color_space_names, va)) < 0)
+                                        pfn, &pdf_color_space_names, va);
+            if (v.value_type == COS_VALUE_SCALAR)
+                cos_value_free((const cos_value_t *)&v, pdev->pdf_memory, "pdf_color_space(Devicen)");
+            if (va != NULL && va->value_type == COS_VALUE_SCALAR)
+                cos_value_free((const cos_value_t *)&va, pdev->pdf_memory, "pdf_color_space(Devicen)");
+            if (code < 0)
                 return code;
         }
         break;
@@ -1285,12 +1298,18 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
         if (pfn == 0)
             return_error(gs_error_rangecheck);
         {
-            if ((code = pdf_string_to_cos_name(pdev, (const byte *)pcs->params.separation.sep_name,
-                                      strlen(pcs->params.separation.sep_name), &v)) < 0 ||
-                (code = pdf_separation_color_space(pdev, pgs, pca, "/Separation", &v,
+            code = pdf_string_to_cos_name(pdev, (const byte *)pcs->params.separation.sep_name,
+                                      strlen(pcs->params.separation.sep_name), &v);
+            if (code < 0)
+                return code;
+
+            code = pdf_separation_color_space(pdev, pgs, pca, "/Separation", &v,
                                             pcs->base_space,
-                                            pfn, &pdf_color_space_names, NULL)) < 0)
-            return code;
+                                            pfn, &pdf_color_space_names, NULL);
+            if (v.value_type == COS_VALUE_SCALAR)
+                cos_value_free((const cos_value_t *)&v, pdev->pdf_memory, "pdf_color_space(Separation name)");
+            if (code < 0)
+                return code;
         }
         break;
 
diff --git a/devices/vector/gdevpdfc.h b/devices/vector/gdevpdfc.h
index e9056be3..02a03634 100644
--- a/devices/vector/gdevpdfc.h
+++ b/devices/vector/gdevpdfc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfd.c b/devices/vector/gdevpdfd.c
index 32a6c41b..32f75555 100644
--- a/devices/vector/gdevpdfd.c
+++ b/devices/vector/gdevpdfd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfe.c b/devices/vector/gdevpdfe.c
index f9544c5d..e083ee11 100644
--- a/devices/vector/gdevpdfe.c
+++ b/devices/vector/gdevpdfe.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -492,6 +492,7 @@ pdf_xmp_write_translated(gx_device_pdf *pdev, stream *s, const byte *data, int d
         if (code < 0)
             return code;
         write(s, (const byte *)buf1, buf1b - buf1);
+        gs_free_object(pdev->memory, buf1, "pdf_xmp_write_translated");
     }
     gs_free_object(pdev->memory, buf0, "pdf_xmp_write_translated");
     return 0;
@@ -840,8 +841,6 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
 int
 pdf_document_metadata(gx_device_pdf *pdev)
 {
-    int j;
-
     if (pdev->CompatibilityLevel < 1.4)
         return 0;
     if (cos_dict_find_c_key(pdev->Catalog, "/Metadata"))
@@ -889,33 +888,6 @@ pdf_document_metadata(gx_device_pdf *pdev)
         if (code < 0)
             return code;
 
-        /* By storing the Metadata in the Catalog dictionary we have referenced it from the
-         * 'global named objects', and the object will be freed when we free those objects.
-         * We *don't* want it referenced by any resource because if it is then we will free
-         * it before we free the global named resources. So remove the Metadata cos_stream
-         * object from the resourceOther resource type chains.
-         */
-        for (j = 0; j < NUM_RESOURCE_CHAINS; ++j) {
-            pdf_resource_t *pres1, *head = pdev->resources[resourceOther].chains[j];
-
-            pres1 = head;
-
-            if (pres1 == pres) {
-                pdev->resources[resourceOther].chains[j] = pres1->next;
-                break;
-            } else {
-                while (pres1->next) {
-                    if (pres1->next == pres) {
-                        pres1->next = pres->next;
-                        break;
-                    }
-                    if (pres1->next == pres->next)
-                        break;
-
-                    pres1 = pres1->next;
-                }
-            }
-        }
     }
     return 0;
 }
diff --git a/devices/vector/gdevpdfg.c b/devices/vector/gdevpdfg.c
index 39da7ea4..f08acb7c 100644
--- a/devices/vector/gdevpdfg.c
+++ b/devices/vector/gdevpdfg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -2371,7 +2371,7 @@ pdf_write_spot_function(gx_device_pdf *pdev, const gx_ht_order *porder,
     return code;
 }
 
-/* if (memcmp(order.levels, porder->levels, order.num_levels * sizeof(*order.levels))) */ 
+/* if (memcmp(order.levels, porder->levels, order.num_levels * sizeof(*order.levels))) */
 static int
 compare_gx_ht_order_levels(const gx_ht_order *order1, const gx_ht_order *order2) {
   int i;
diff --git a/devices/vector/gdevpdfg.h b/devices/vector/gdevpdfg.h
index e9faa670..85e67d9f 100644
--- a/devices/vector/gdevpdfg.h
+++ b/devices/vector/gdevpdfg.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -296,6 +296,8 @@ pdf_complete_image_data(gx_device_pdf *pdev, pdf_image_writer *piw, int data_h,
 int pdf_end_image_binary(gx_device_pdf *pdev, pdf_image_writer *piw,
                          int data_h);
 
+int pdf_end_abort_image(gx_device_pdf * pdev, pdf_image_writer * piw);
+
 /*
  * Finish writing an image.  If in-line, write the BI/dict/ID/data/EI and
  * return 1; if a resource, write the resource definition and return 0.
diff --git a/devices/vector/gdevpdfi.c b/devices/vector/gdevpdfi.c
index c6bdee9d..08e217fa 100644
--- a/devices/vector/gdevpdfi.c
+++ b/devices/vector/gdevpdfi.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -958,6 +958,86 @@ static int setup_image_colorspace(gx_device_pdf *pdev, image_union_t *image, con
     return 0;
 }
 
+/* Basically, sets up the BBox for Eps2Write case */
+static int
+pdf_image_handle_eps(gx_device_pdf *pdev, const gs_gstate * pgs,
+                     const gs_matrix *pmat, const gs_image_common_t *pic,
+                     const gs_int_rect *prect,
+                     const gx_clip_path * pcpath)
+{
+    int code = 0;
+    gs_rect sbox, dbox, *Box;
+    gs_point corners[4];
+    gs_fixed_rect ibox;
+    gs_matrix * pmat1 = (gs_matrix *)pmat;
+    gs_matrix mat;
+
+    if (!pdev->Eps2Write)
+        return 0;
+
+    if (!pdev->accumulating_charproc)
+        Box = &pdev->BBox;
+    else
+        Box = &pdev->charproc_BBox;
+    if (pmat1 == 0)
+        pmat1 = (gs_matrix *)&ctm_only(pgs);
+    if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
+        (code = gs_matrix_multiply(&mat, pmat1, &mat)) < 0)
+        goto exit;
+    sbox.p.x = prect->p.x;
+    sbox.p.y = prect->p.y;
+    sbox.q.x = prect->q.x;
+    sbox.q.y = prect->q.y;
+    gs_bbox_transform_only(&sbox, &mat, corners);
+    gs_points_bbox(corners, &dbox);
+    ibox.p.x = float2fixed(dbox.p.x);
+    ibox.p.y = float2fixed(dbox.p.y);
+    ibox.q.x = float2fixed(dbox.q.x);
+    ibox.q.y = float2fixed(dbox.q.y);
+    if (pcpath != NULL &&
+        !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y,
+                                     ibox.q.x, ibox.q.y)
+        ) {
+        /* Let the target do the drawing, but drive two triangles */
+        /* through the clipping path to get an accurate bounding box. */
+        gx_device_clip cdev;
+        gx_drawing_color devc;
+
+        fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y);
+        fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0;
+
+        pdev->AccumulatingBBox++;
+        gx_make_clip_device_on_stack(&cdev, pcpath, (gx_device *)pdev);
+        set_nonclient_dev_color(&devc, gx_device_black((gx_device *)pdev));  /* any non-white color will do */
+        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
+                                 float2fixed(corners[1].x) - x0,
+                                 float2fixed(corners[1].y) - y0,
+                                 bx2, by2, &devc, lop_default);
+        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
+                                 float2fixed(corners[3].x) - x0,
+                                 float2fixed(corners[3].y) - y0,
+                                 bx2, by2, &devc, lop_default);
+        pdev->AccumulatingBBox--;
+    } else {
+        /* Just use the bounding box. */
+        float x0, y0, x1, y1;
+        x0 = fixed2float(ibox.p.x) / (pdev->HWResolution[0] / 72.0);
+        y0 = fixed2float(ibox.p.y) / (pdev->HWResolution[1] / 72.0);
+        x1 = fixed2float(ibox.q.x) / (pdev->HWResolution[0] / 72.0);
+        y1 = fixed2float(ibox.q.y) / (pdev->HWResolution[1] / 72.0);
+        if (Box->p.x > x0)
+            Box->p.x = x0;
+        if (Box->p.y > y0)
+            Box->p.y = y0;
+        if (Box->q.x < x1)
+            Box->q.x = x1;
+        if (Box->q.y < y1)
+            Box->q.y = y1;
+    }
+ exit:
+    return code;
+}
+
 static int
 pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
                       const gs_matrix *pmat, const gs_image_common_t *pic,
@@ -967,7 +1047,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
                       gx_image_enum_common_t ** pinfo,
                       pdf_typed_image_context_t context)
 {
-    int code, i;
+    int code = 0, i;
     unsigned int use_fallback  = 0, in_line = 0, is_mask = 0,
         force_lossless = 0, convert_to_process_colors = 0;
     int width, height;
@@ -976,9 +1056,9 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
     const gs_pixel_image_t *pim;
     gs_int_rect rect;
     gs_image_format_t format;
-    gs_color_space *pcs;
+    gs_color_space *pcs = NULL;
     int num_components;
-    pdf_image_enum *pie;
+    pdf_image_enum *pie = NULL;
     const pdf_color_space_names_t *names;
     gs_color_space *pcs_orig = NULL;
     gs_color_space *pcs_device = NULL;
@@ -1006,14 +1086,15 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
        until the mask is completed due to equal image merging. */
     pdev->image_mask_id = gs_no_id;
 
+    pim = (const gs_pixel_image_t *)pic;
+
     /* Check for the image types we can handle. */
     switch (pic->type->index) {
     case 1:
         is_mask = ((const gs_image_t *)pic)->ImageMask;
         code = setup_type1_image(pdev, pic, pdcolor, image, context);
-        if (code < 0) {
+        if (code < 0)
             use_fallback = 1;
-        }
         else
             in_line = code;
         break;
@@ -1039,55 +1120,107 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
             (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
                    prect->q.x == ((const gs_image3_t *)pic)->Width &&
                    prect->q.y == ((const gs_image3_t *)pic)->Height))) {
-            gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-            return (gx_default_begin_typed_image((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor,
-                pcpath, mem, pinfo));
+            use_fallback = 1;
+            goto exit;
         }
-        gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                          "pdf_begin_typed_image(image)");
-        return (setup_type3_image(pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image));
-        break;
+        code = setup_type3_image(pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image);
+        goto exit;
 
     case IMAGE3X_IMAGETYPE:
         pdev->JPEG_PassThrough = 0;
-        gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
         if (pdev->CompatibilityLevel < 1.4 ||
             (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
                        prect->q.x == ((const gs_image3x_t *)pic)->Width &&
                        prect->q.y == ((const gs_image3x_t *)pic)->Height))) {
-            return (gx_default_begin_typed_image((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor,
-                pcpath, mem, pinfo));
+            use_fallback = 1;
+            goto exit;
         }
         pdev->image_mask_is_SMask = true;
-        return gx_begin_image3x_generic((gx_device *)pdev, pgs, pmat, pic,
+        code = gx_begin_image3x_generic((gx_device *)pdev, pgs, pmat, pic,
                                         prect, pdcolor, pcpath, mem,
                                         pdf_image3x_make_mid,
                                         pdf_image3x_make_mcde, pinfo);
-        break;
+        goto exit;
 
     case 4:
+        /* If we are colour converting then we may not be able to preserve the
+         * type 4 image, if it has a /Mask entry which is a range of colours
+         * (chroma-key masking). If its a stencil mask then we can just conver the
+         * underlying image and leave the mask alone.
+         */
+        if (pdev->params.ColorConversionStrategy != ccs_LeaveColorUnchanged) {
+            gs_color_space *pcs2;
+            int csi = 0;
+            bool fallback = false;
+            gs_image4_t *pim4 = (gs_image4_t *)pic;
+
+            /* If the /Mask is chroma-key rather than a stencil */
+            if (pim4->MaskColor_is_range) {
+                /* Find the colour space */
+                pcs2 = pim->ColorSpace;
+                csi = gs_color_space_get_index(pcs2);
+                /* If its /Indexed, get the base space */
+                if (csi == gs_color_space_index_Indexed) {
+                    pcs2 = pim->ColorSpace->base_space;
+                    csi = gs_color_space_get_index(pcs2);
+                }
+                if (csi == gs_color_space_index_ICC)
+                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
+                /* If the base space matches the target for colour conversion
+                 * then no conversion is needed, so we can preserve the type
+                 * 4 image.
+                 */
+                switch(csi) {
+                    case gs_color_space_index_DeviceGray:
+                        if (pdev->params.ColorConversionStrategy != ccs_Gray)
+                            fallback = true;
+                        break;
+                    case gs_color_space_index_DeviceRGB:
+                        if (pdev->params.ColorConversionStrategy != ccs_RGB)
+                            fallback = true;
+                        break;
+                    case gs_color_space_index_DeviceCMYK:
+                        if (pdev->params.ColorConversionStrategy != ccs_CMYK)
+                            fallback = true;
+                        break;
+                    default:
+                        fallback = true;
+                        break;
+                }
+                if (fallback == true && pdev->CompatibilityLevel > 1.2) {
+                    /* We've arrived at the point where we have a chroma-keyed
+                     * type 4 image, and the image needs to be converted to a
+                     * different space. We can't do that, so fall back to a
+                     * default implementation, create a clip path and apply it to
+                     * the image.
+                     */
+                    pdev->JPEG_PassThrough = 0;
+                    use_fallback = 0;
+                    code = convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
+                                                         pcpath, mem,pinfo);
+                    goto exit;
+                }
+                /* Note that we fall through to the original code, so if we are not
+                 * producing at least PDF 1.2 (for image mask support) then we will
+                 * fall back further filled to rectangles.
+                 */
+            }
+        }
         pdev->JPEG_PassThrough = 0;
         code = convert_type4_image(pdev, pgs, pmat, pic, prect, pdcolor,
                       pcpath, mem, pinfo, context, image, pnamed);
-        if (code < 0) {
+        if (code < 0)
             use_fallback = 1;
-        }
-        if (code == 0) {
-            gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                                  "pdf_begin_typed_image(image)");
-            return code;
-        }
+        if (code == 0)
+            goto exit;
         /* No luck.  Masked images require PDF 1.3 or higher. */
-        if (pdev->CompatibilityLevel < 1.2) {
+        if (pdev->CompatibilityLevel < 1.2)
             use_fallback = 1;
-        }
         if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
-            gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                                  "pdf_begin_typed_image(image)");
-            return (convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
-                      pcpath, mem,pinfo));
+            use_fallback = 0;
+            code = convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
+                                                 pcpath, mem,pinfo);
+            goto exit;
         }
         image[0].type4 = *(const gs_image4_t *)pic;
         break;
@@ -1097,7 +1230,6 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         break;
     }
 
-    pim = (const gs_pixel_image_t *)pic;
     format = pim->format;
     switch (format) {
     case gs_image_format_chunky:
@@ -1115,14 +1247,12 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         case 2:
         case 4:
         case 8:
-            break;
         case 12:
         case 16:
             break;
         default:
-            gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-            return_error(gs_error_rangecheck);
+            code = gs_note_error(gs_error_rangecheck);
+            goto exit;
     }
     if (prect)
         rect = *prect;
@@ -1135,82 +1265,15 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         (is_mask && pim->CombineWithColor))
         use_fallback = 1;
 
-    if (pdev->Eps2Write) {
-        gs_rect sbox, dbox, *Box;
-        gs_point corners[4];
-        gs_fixed_rect ibox;
-        gs_matrix * pmat1 = (gs_matrix *)pmat;
-        gs_matrix mat;
-
-        if (!pdev->accumulating_charproc)
-            Box = &pdev->BBox;
-        else
-            Box = &pdev->charproc_BBox;
-        if (pmat1 == 0)
-            pmat1 = (gs_matrix *)&ctm_only(pgs);
-        if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
-            (code = gs_matrix_multiply(&mat, pmat1, &mat)) < 0)
-            return code;
-        sbox.p.x = rect.p.x;
-        sbox.p.y = rect.p.y;
-        sbox.q.x = rect.q.x;
-        sbox.q.y = rect.q.y;
-        gs_bbox_transform_only(&sbox, &mat, corners);
-        gs_points_bbox(corners, &dbox);
-        ibox.p.x = float2fixed(dbox.p.x);
-        ibox.p.y = float2fixed(dbox.p.y);
-        ibox.q.x = float2fixed(dbox.q.x);
-        ibox.q.y = float2fixed(dbox.q.y);
-        if (pcpath != NULL &&
-            !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y,
-            ibox.q.x, ibox.q.y)
-            ) {
-            /* Let the target do the drawing, but drive two triangles */
-            /* through the clipping path to get an accurate bounding box. */
-            gx_device_clip cdev;
-            gx_drawing_color devc;
-
-            fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y);
-            fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0;
-
-            pdev->AccumulatingBBox++;
-            gx_make_clip_device_on_stack(&cdev, pcpath, (gx_device *)pdev);
-            set_nonclient_dev_color(&devc, gx_device_black((gx_device *)pdev));  /* any non-white color will do */
-            gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
-                float2fixed(corners[1].x) - x0,
-                float2fixed(corners[1].y) - y0,
-                bx2, by2, &devc, lop_default);
-            gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
-                float2fixed(corners[3].x) - x0,
-                float2fixed(corners[3].y) - y0,
-                bx2, by2, &devc, lop_default);
-            pdev->AccumulatingBBox--;
-        } else {
-            /* Just use the bounding box. */
-            float x0, y0, x1, y1;
-            x0 = fixed2float(ibox.p.x) / (pdev->HWResolution[0] / 72.0);
-            y0 = fixed2float(ibox.p.y) / (pdev->HWResolution[1] / 72.0);
-            x1 = fixed2float(ibox.q.x) / (pdev->HWResolution[0] / 72.0);
-            y1 = fixed2float(ibox.q.y) / (pdev->HWResolution[1] / 72.0);
-            if (Box->p.x > x0)
-                Box->p.x = x0;
-            if (Box->p.y > y0)
-                Box->p.y = y0;
-            if (Box->q.x < x1)
-                Box->q.x = x1;
-            if (Box->q.y < y1)
-                Box->q.y = y1;
-        }
+    /* Handle BBox for Eps2Write, if applicable */
+    code = pdf_image_handle_eps(pdev, pgs, pmat, pic, &rect, pcpath);
+    if (code < 0) {
+        use_fallback = 0;
+        goto exit;
     }
 
-    if (use_fallback) {
-        pdev->JPEG_PassThrough = 0;
-        gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-        return gx_default_begin_typed_image
-            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
-            pinfo);
-    }
+    if (use_fallback)
+        goto exit;
 
     pcs = pim->ColorSpace;
     rc_increment_cs(pcs);
@@ -1218,19 +1281,13 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
 
     code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
     if (code < 0)
-        return code;
+        goto exit;
     if (pdf_must_put_clip_path(pdev, pcpath))
         code = pdf_unclip(pdev);
     else
         code = pdf_open_page(pdev, PDF_IN_STREAM);
-    if (code < 0) {
-        pdev->JPEG_PassThrough = 0;
-        gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-        return gx_default_begin_typed_image
-            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
-            pinfo);
-    }
+    if (code < 0)
+        goto fail_and_fallback;
 
     if (context == PDF_IMAGE_TYPE3_MASK) {
         /*
@@ -1247,21 +1304,14 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         code = pdf_prepare_imagemask(pdev, pgs, pdcolor);
     else
         code = pdf_prepare_image(pdev, pgs);
-    if (code < 0) {
-        pdev->JPEG_PassThrough = 0;
-        gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-        return gx_default_begin_typed_image
-            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
-            pinfo);
-    }
+    if (code < 0)
+        goto fail_and_fallback;
 
     pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
                         "pdf_begin_image");
     if (pie == 0) {
-        gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-        return_error(gs_error_VMerror);
+        code = gs_note_error(gs_error_VMerror);
+        goto exit;
     }
     memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
     *pinfo = (gx_image_enum_common_t *) pie;
@@ -1305,24 +1355,18 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
             (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
             (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
-            ) {
-            gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-            gs_free_object(mem, pie, "pdf_begin_image");
-            return code;
-        }
+            )
+            goto exit;
         /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
-        if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx)
+        if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx) {
+            use_fallback = 1;
             goto fail_and_fallback;
+        }
     }
 
     code = pdf_put_clip_path(pdev, pcpath);
-    if (code < 0) {
-        gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                          "pdf_begin_typed_image(image)");
-        gs_free_object(mem, pie, "pdf_begin_image");
-        return code;
-    }
+    if (code < 0)
+        goto exit;
     pdf_image_writer_init(&pie->writer);
     /* Note : Possible values for alt_writer_count are 1,2,3,4.
        1 means no alternative streams.
@@ -1352,8 +1396,10 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         if (image[0].pixel.ColorSpace != NULL && !(context == PDF_IMAGE_TYPE3_MASK))
             convert_to_process_colors = setup_image_colorspace(pdev, &image[0], pcs, &pcs_orig, names, &cs_value);
 
-        if (pim->BitsPerComponent > 8 && convert_to_process_colors)
+        if (pim->BitsPerComponent > 8 && convert_to_process_colors) {
+            use_fallback = 1;
             goto fail_and_fallback;
+        }
         if (convert_to_process_colors == 4) {
             code = convert_DeviceN_alternate(pdev, pgs, pcs, NULL, NULL, NULL, NULL, &cs_value, in_line);
             if (code < 0)
@@ -1368,6 +1414,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
             code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
             if (code < 0)
                 goto fail_and_fallback;
+            rc_decrement(image[0].pixel.ColorSpace, "pdf_begin_typed_image(pixel.ColorSpace)");
             image[0].pixel.ColorSpace = pcs_device;
             image[0].pixel.BitsPerComponent = 8;
             code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
@@ -1400,53 +1447,6 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
     if (code < 0)
         goto fail_and_fallback;
 
-    if (pdev->params.TransferFunctionInfo == tfi_Apply && pdev->transfer_not_identity && !is_mask)
-        pdev->JPEG_PassThrough = 0;
-
-    /* Code below here deals with setting up the multiple data stream writing.
-     * We can have up to 4 stream writers, which we keep in an array. We must
-     * always have at least one which writes the uncompressed stream. If we
-     * are writing compressed streams, we have one for the compressed stream
-     * and one for the compression chooser.
-     * For type 4 images being converted (for old versions of PDF or for ps2write)
-     * we need an additional stream to write a mask, which masks the real
-     * image.
-     * For colour conversion we will place an additional filter in front of all
-     * the streams which does the conversion.
-     */
-    if (in_line) {
-        pdev->JPEG_PassThrough = 0;
-        code = new_setup_lossless_filters((gx_device_psdf *) pdev,
-                                             &pie->writer.binary[0],
-                                             &image[0].pixel, in_line, convert_to_process_colors, (gs_matrix *)pmat, (gs_gstate *)pgs);
-    } else {
-        if (force_lossless) {
-            /*
-             * Some regrettable PostScript code (such as LanguageLevel 1 output
-             * from Microsoft's PSCRIPT.DLL driver) misuses the transfer
-             * function to accomplish the equivalent of indexed color.
-             * Downsampling (well, only averaging) or JPEG compression are not
-             * compatible with this.  Play it safe by using only lossless
-             * filters if the transfer function(s) is/are other than the
-             * identity and by setting the downsample type to Subsample..
-             */
-            int saved_downsample = pdev->params.ColorImage.DownsampleType;
-
-            pdev->params.ColorImage.DownsampleType = ds_Subsample;
-            code = new_setup_image_filters((gx_device_psdf *) pdev,
-                                          &pie->writer.binary[0], &image[0].pixel,
-                                          pmat, pgs, true, in_line, convert_to_process_colors);
-            pdev->params.ColorImage.DownsampleType = saved_downsample;
-        } else {
-            code = new_setup_image_filters((gx_device_psdf *) pdev,
-                                          &pie->writer.binary[0], &image[0].pixel,
-                                          pmat, pgs, true, in_line, convert_to_process_colors);
-        }
-    }
-
-    if (code < 0)
-        goto fail_and_fallback;
-
     if (!convert_to_process_colors)
     {
         gs_color_space_index csi;
@@ -1501,10 +1501,53 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
             }
         }
     }
-    /* If we are not preserving the colour space unchanged, thenwe can't pass through JPEG */
+    /* If we are not preserving the colour space unchanged, then we can't pass through JPEG */
     else
         pdev->JPEG_PassThrough = 0;
 
+    /* Code below here deals with setting up the multiple data stream writing.
+     * We can have up to 4 stream writers, which we keep in an array. We must
+     * always have at least one which writes the uncompressed stream. If we
+     * are writing compressed streams, we have one for the compressed stream
+     * and one for the compression chooser.
+     * For type 4 images being converted (for old versions of PDF or for ps2write)
+     * we need an additional stream to write a mask, which masks the real
+     * image.
+     * For colour conversion we will place an additional filter in front of all
+     * the streams which does the conversion.
+     */
+    if (in_line) {
+        pdev->JPEG_PassThrough = 0;
+        code = new_setup_lossless_filters((gx_device_psdf *) pdev,
+                                             &pie->writer.binary[0],
+                                             &image[0].pixel, in_line, convert_to_process_colors, (gs_matrix *)pmat, (gs_gstate *)pgs);
+    } else {
+        if (force_lossless) {
+            /*
+             * Some regrettable PostScript code (such as LanguageLevel 1 output
+             * from Microsoft's PSCRIPT.DLL driver) misuses the transfer
+             * function to accomplish the equivalent of indexed color.
+             * Downsampling (well, only averaging) or JPEG compression are not
+             * compatible with this.  Play it safe by using only lossless
+             * filters if the transfer function(s) is/are other than the
+             * identity and by setting the downsample type to Subsample..
+             */
+            int saved_downsample = pdev->params.ColorImage.DownsampleType;
+
+            pdev->params.ColorImage.DownsampleType = ds_Subsample;
+            code = new_setup_image_filters((gx_device_psdf *) pdev,
+                                          &pie->writer.binary[0], &image[0].pixel,
+                                          pmat, pgs, true, in_line, convert_to_process_colors);
+            pdev->params.ColorImage.DownsampleType = saved_downsample;
+        } else {
+            code = new_setup_image_filters((gx_device_psdf *) pdev,
+                                          &pie->writer.binary[0], &image[0].pixel,
+                                          pmat, pgs, true, in_line, convert_to_process_colors);
+        }
+    }
+
+    if (code < 0)
+        goto fail_and_fallback;
 
     if (convert_to_process_colors) {
         image[0].pixel.ColorSpace = pcs_orig;
@@ -1529,9 +1572,8 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
 
     if (pie->writer.alt_writer_count > 1) {
         code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
-        if (code) {
+        if (code < 0)
             goto fail_and_fallback;
-        }
         code = new_setup_image_filters((gx_device_psdf *) pdev,
                                   &pie->writer.binary[1], &image[1].pixel,
                                   pmat, pgs, force_lossless, in_line, convert_to_process_colors);
@@ -1542,8 +1584,11 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
                 cos_stream_t *pcos = cos_stream_from_pipeline(pie->writer.binary[i].strm);
                 s_close_filters(&s, NULL);
                 gs_free_object(pdev->pdf_memory, s, "compressed image stream");
-                if (pcos == 0L)
-                    return gs_note_error(gs_error_ioerror);
+                if (pcos == 0L) {
+                    /* TODO: Seems like something should be freed here */
+                    code = gs_note_error(gs_error_ioerror);
+                    goto exit;
+                }
                 pcos->cos_procs->release((cos_object_t *)pcos, "pdf_begin_typed_image_impl");
                 gs_free_object(pdev->pdf_memory, pcos, "compressed image cos_stream");
             }
@@ -1558,9 +1603,8 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
             image[1].pixel.BitsPerComponent = pim->BitsPerComponent;
             code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
                                               (gx_device_psdf *)pdev, pim, &image[1].pixel, pgs);
-            if (code < 0) {
+            if (code < 0)
                 goto fail_and_fallback;
-            }
             image[1].pixel.ColorSpace = pcs_device;
         }
     }
@@ -1588,7 +1632,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         /* Won't use image[2]. */
         code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
                     height, NULL, false);
-        if (code)
+        if (code < 0)
             goto fail_and_fallback;
         code = psdf_setup_image_filters((gx_device_psdf *) pdev,
                                   &pie->writer.binary[i], &image[i].pixel,
@@ -1609,20 +1653,38 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
         ++pie->writer.alt_writer_count;
     }
 
-    gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
-                                              "pdf_begin_typed_image(image)");
-    rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
-    return 0;
+    /* use_fallback = 0, so this will drop through the below labels, doing only the cleanup parts */
+    code = 0;
+
+    /* This label is used when code < 0 and we want to do the fallback code */
+ fail_and_fallback:
+    if (code != 0)
+        use_fallback = 1;
 
-fail_and_fallback:
+    /* This label is used either when there's no error and we are just exiting normally
+     * (possibly with use_fallback=1), or there is an error but we don't want to do
+     * the fallback code.
+     */
+ exit:
+    /* Free everything */
     rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
-    pdev->JPEG_PassThrough = 0;
+    rc_decrement(pcs_device, "pdf_begin_typed_image(pcs_device)");
     gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
                                       "pdf_begin_typed_image(image)");
-    gs_free_object(mem, pie, "pdf_begin_image");
-    return gx_default_begin_typed_image
-        ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
-        pinfo);
+
+    /* Free pie only if there was an error or we are falling back */
+    if (code < 0 || use_fallback) {
+        if (pie)
+            gs_free_object(mem, pie, "pdf_begin_typed_image(pie)");
+        *pinfo = NULL;
+    }
+    /* Do the fallback */
+    if (use_fallback) {
+        pdev->JPEG_PassThrough = 0;
+        code = gx_default_begin_typed_image
+            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo);
+    }
+    return code;
 }
 
 int
@@ -1730,7 +1792,7 @@ pdf_image_plane_data(gx_image_enum_common_t * info,
     if (pie->JPEG_PassThrough) {
         pie->rows_left -= height;
         *rows_used = height;
-        return 0;
+        return !pie->rows_left;
     }
 
     for (i = 0; i < pie->writer.alt_writer_count; i++) {
@@ -1922,6 +1984,10 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
         } else
             code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, do_image);
         pie->writer.alt_writer_count--; /* For GC. */
+    } else {
+        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
+        code = pdf_end_abort_image(pdev, &pie->writer);
+        pie->writer.alt_writer_count--; /* For GC. */
     }
     if (pie->initial_colorspace != pdev->pcm_color_info_index)
         pdf_set_process_color_model(pdev, pie->initial_colorspace);
@@ -2286,7 +2352,7 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
                 if (code < 0)
                     return code;
                 pcd = cos_stream_dict((cos_stream_t *)pres->object);
-                pcd_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)");
+                pcd_Resources = cos_dict_alloc(pdev, "pdf_form(Resources)");
                 if (pcd == NULL || pcd_Resources == NULL)
                     return_error(gs_error_VMerror);
                 code = cos_dict_put_c_strings(pcd, "/Type", "/XObject");
@@ -2467,6 +2533,13 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
                     pres->where_used |= pdev->used_mask;
                 } else if (pres->object->id < 0)
                     pdf_reserve_object_id(pdev, pres, 0);
+                pdev->LastFormID = pdf_resource_id(pres);
+                pdev->HighLevelForm--;
+                if (pdev->accumulating_substream_resource) {
+                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
+                    if (code < 0)
+                        return code;
+                }
                 if (pdev->PDFFormName) {
                     cos_value_t value;
 
@@ -2476,19 +2549,14 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
                     if (code < 0)
                         return code;
                     pdf_drop_resource_from_chain(pdev, pres, resourceXObject);
+                    pres->object = NULL;
+                    gs_free_object(pdev->pdf_memory, pres, "free redundant resource");
 
-                    gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name oof Form for pdfmark");
+                    gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
                     pdev->PDFFormName = 0x00;
                 } else {
                     pprintld1(pdev->strm, "/R%ld Do Q\n", pdf_resource_id(pres));
                 }
-                pdev->HighLevelForm--;
-                if (pdev->accumulating_substream_resource) {
-                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
-                    if (code < 0)
-                        return code;
-                }
-                pdev->LastFormID = pdf_resource_id(pres);
             }
             return 0;
         case gxdso_get_form_ID:
@@ -2690,6 +2758,8 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
                 return 0;
             }
             break;
+        case gxdso_in_smask_construction:
+            return pdev->smask_construction;
         case gxdso_get_dev_param:
             {
                 int code;
diff --git a/devices/vector/gdevpdfj.c b/devices/vector/gdevpdfj.c
index 4c73e171..6140d4d6 100644
--- a/devices/vector/gdevpdfj.c
+++ b/devices/vector/gdevpdfj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -528,6 +528,21 @@ smask_image_check(gx_device_pdf * pdev, pdf_resource_t *pres0, pdf_resource_t *p
     return 1;
 }
 
+
+/* Abort an image without writing it.
+ * Frees any associated memory.
+ */
+int
+pdf_end_abort_image(gx_device_pdf * pdev, pdf_image_writer * piw)
+{
+    pdf_resource_t *pres = piw->pres;
+
+    if (!pres) {
+        COS_FREE(piw->data, "pdf_end_write_image");
+    }
+    return 0;
+}
+
 /*
  * Finish writing an image.  If in-line, write the BI/dict/ID/data/EI and
  * return 1; if a resource, write the resource definition and return 0.
diff --git a/devices/vector/gdevpdfk.c b/devices/vector/gdevpdfk.c
index e48718d1..c682c6ea 100644
--- a/devices/vector/gdevpdfk.c
+++ b/devices/vector/gdevpdfk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -115,7 +115,7 @@ cie_to_xyz(const double *in, double out[3], const gs_color_space *pcs,
         handles mapping to CIE D50.  This forces an achromatic result */
         xyz_float[0] = pWhitePoint->u * xyz_float[1];
         xyz_float[2] = pWhitePoint->w * xyz_float[1];
-    } 
+    }
 
     /* Do wp mapping to D50 in XYZ for now.  We should do bradford correction.
        Will add that in next release */
diff --git a/devices/vector/gdevpdfm.c b/devices/vector/gdevpdfm.c
index 18ea50c5..ba00700a 100644
--- a/devices/vector/gdevpdfm.c
+++ b/devices/vector/gdevpdfm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -832,8 +832,10 @@ pdfmark_put_ao_pairs(gx_device_pdf * pdev, cos_dict_t *pcd,
                 cos_dict_put_string(adict, key.data, key.size,
                                     value.data, value.size);
             }
-            if (code <= 0 || !pdf_key_eq(&key, ">>"))
+            if (code <= 0 || !pdf_key_eq(&key, ">>")) {
+                cos_free((cos_object_t *)adict, "action dict");
                 return_error(gs_error_rangecheck);
+            }
             cos_dict_put(pcd, (const byte *)"/A", 2,
                          COS_OBJECT_VALUE(&avalue, adict));
         } else if (pdf_key_eq(Action + 1, "/GoTo"))
@@ -1174,20 +1176,28 @@ pdfmark_annot(gx_device_pdf * pdev, gs_param_string * pairs, uint count,
     if (code < 0)
         return code;
     code = cos_dict_put_c_strings(pcd, "/Type", "/Annot");
-    if (code < 0)
+    if (code < 0) {
+        cos_free((cos_object_t *)pcd, "pdfmark_annot");
         return code;
+    }
     code = pdfmark_put_ao_pairs(pdev, pcd, pairs, count, pctm, ¶ms, false);
-    if (code < 0)
+    if (code < 0) {
+        cos_free((cos_object_t *)pcd, "pdfmark_annot");
         return code;
+    }
     if (params.src_pg >= 0)
         page_index = params.src_pg;
-    if (pdf_page_id(pdev, page_index + 1) <= 0)
+    if (pdf_page_id(pdev, page_index + 1) <= 0) {
+        cos_free((cos_object_t *)pcd, "pdfmark_annot");
         return_error(gs_error_rangecheck);
+    }
     annots = pdev->pages[page_index].Annots;
     if (annots == 0) {
         annots = cos_array_alloc(pdev, "pdfmark_annot");
-        if (annots == 0)
+        if (annots == 0) {
+            cos_free((cos_object_t *)pcd, "pdfmark_annot");
             return_error(gs_error_VMerror);
+        }
         pdev->pages[page_index].Annots = annots;
     }
     if (!objname) {
@@ -1334,8 +1344,10 @@ pdfmark_OUT(gx_device_pdf * pdev, gs_param_string * pairs, uint count,
     ao.src_pg = -1;
     code = pdfmark_put_ao_pairs(pdev, node.action, pairs, count, pctm, &ao,
                                 true);
-    if (code < 0)
+    if (code < 0) {
+        cos_free((cos_object_t *)node.action, "pdfmark_OUT");
         return code;
+    }
     if (pdev->outlines_id == 0)
         pdev->outlines_id = pdf_obj_ref(pdev);
     node.id = pdf_obj_ref(pdev);
@@ -1944,25 +1956,41 @@ pdfmark_DOCINFO(gx_device_pdf * pdev, gs_param_string * pairs, uint count,
 
         if (pdev->PDFA !=0) {
             const gs_param_string *p = pairs + i + 1;
-            if (p->size > 9 && memcmp(p->data, "(\\376\\377", 9) == 0) {
+            bool abort = false;
+
+            if (p->size > 9 && memcmp(p->data, "(\\376\\377", 9) == 0)
+                abort = true;
+            else {
+                int j;
+                for (j = 0;j < p->size;j++)
+                {
+                    if (p->data[j] == '\\' || p->data[j] > 0x7F || p->data[j] < 0x20)
+                    {
+                        abort = true;
+                        break;
+                    }
+                }
+            }
+            if (abort == true)
+            {
                 /* Can't handle UTF16BE in PDF/A1, so abort this pair or abort PDF/A or just abort,
                  * depending on PDFACompatibilityPolicy
                  */
                 switch (pdev->PDFACompatibilityPolicy) {
                     case 0:
                         emprintf(pdev->memory,
-                         "UTF16BE text string detected in DOCINFO cannot be represented in XMP for PDF/A1, reverting to normal PDF output\n");
+                         "Text string detected in DOCINFO cannot be represented in XMP for PDF/A1, reverting to normal PDF output\n");
                         pdev->AbortPDFAX = true;
                         pdev->PDFX = 0;
                         break;
                     case 1:
                         emprintf(pdev->memory,
-                         "UTF16BE text string detected in DOCINFO cannot be represented in XMP for PDF/A1, discarding DOCINFO\n");
+                         "Text string detected in DOCINFO cannot be represented in XMP for PDF/A1, discarding DOCINFO\n");
                         continue;
                         break;
                     case 2:
                         emprintf(pdev->memory,
-                         "UTF16BE text string detected in DOCINFO cannot be represented in XMP for PDF/A1, aborting conversion.\n");
+                         "Text string detected in DOCINFO cannot be represented in XMP for PDF/A1, aborting conversion.\n");
                         /* If we don't return a fatal error then zputdeviceparams simply ignores it (!) */
                         return_error(gs_error_Fatal);
                         break;
@@ -2456,7 +2484,16 @@ pdfmark_BDC(gx_device_pdf *pdev, gs_param_string *pairs, uint count,
         /* strip << and >> */
         if ((pairs[1].data)[0]=='<'&&(pairs[1].data)[1]=='<')
         {
-            pairs[1].data=&(pairs[1].data[2]);
+            int ix = 0;
+            byte *p = (byte *)pairs[1].data;
+
+            /* Fortunately we don't use the 'size' when freeing the memory
+             * so we can quickly copy the string content up two places and reduce
+             * the size by 2 to remove the '<<'. This saves an alloc and free of the
+             * string data.
+             */
+            for (ix = 0; ix < pairs[1].size - 2;ix++)
+                p[ix] = pairs[1].data[ix + 2];
             pairs[1].size-=2;
         }
         else
@@ -2831,7 +2868,7 @@ pdfmark_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
             gs_memory_t *mem = pdev->pdf_memory;
             int odd_ok = (pmn->options & PDFMARK_ODD_OK) != 0;
             gs_param_string *pairs;
-            int j;
+            int j, index;
 
             /*
              * Our coordinate system is scaled so that user space is always
@@ -2866,9 +2903,25 @@ pdfmark_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
                                                 "pdfmark_process(pairs)");
                         if (!pairs)
                             return_error(gs_error_VMerror);
-                        memcpy(pairs, data, j * sizeof(*data));
-                        memcpy(pairs + j, data + j + 2,
-                               (size - j) * sizeof(*data));
+
+                        for (index=0;index < size;index++)
+                            pairs[index].data = NULL;
+                        for (index=0;index < j;index++) {
+                            pairs[index].data = gs_alloc_bytes(mem, data[index].size, "pdfmark_process(pairs)");
+                            if (pairs[index].data == NULL)
+                                goto error;
+                            memcpy((byte *)pairs[index].data, data[index].data, data[index].size);
+                            pairs[index].size = data[index].size;
+                            pairs[index].persistent = 1;
+                        }
+                        for (index=j+2;index < size + 2;index++) {
+                            pairs[index - 2].data = gs_alloc_bytes(mem, data[index].size, "pdfmark_process(pairs)");
+                            if (pairs[index - 2].data == NULL)
+                                goto error;
+                            memcpy((byte *)pairs[index - 2].data, data[index].data, data[index].size);
+                            pairs[index - 2].size = data[index].size;
+                            pairs[index - 2].persistent = 1;
+                        }
                         goto copied;
                     }
                 }
@@ -2879,8 +2932,17 @@ pdfmark_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
                                     "pdfmark_process(pairs)");
             if (!pairs)
                 return_error(gs_error_VMerror);
-            memcpy(pairs, data, size * sizeof(*data));
-        copied:		/* Substitute object references for names. */
+            for (j=0;j < size;j++)
+                pairs[j].data = NULL;
+            for (j=0;j < size;j++) {
+                pairs[j].data = gs_alloc_bytes(mem, data[j].size, "pdfmark_process(pairs)");
+                if (pairs[j].data == NULL)
+                    goto error;
+                memcpy((byte *)pairs[j].data, data[j].data, data[j].size);
+                pairs[j].size = data[j].size;
+                pairs[j].persistent = 1;
+            }
+copied:		/* Substitute object references for names. */
             if (!(pmn->options & PDFMARK_NO_REFS)) {
                 for (j = (pmn->options & PDFMARK_KEEP_NAME ? 1 : 1 - odd_ok);
                      j < size; j += 2 - odd_ok
@@ -2893,6 +2955,9 @@ pdfmark_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
                 }
             }
             code = (*pmn->proc) (pdev, pairs, size, &ctm, objname);
+error:
+            for (j=0;j < size;j++)
+                gs_free_object(mem, (byte *)pairs[j].data, "pdfmark_process(pairs)");
             gs_free_object(mem, pairs, "pdfmark_process(pairs)");
             break;
         }
diff --git a/devices/vector/gdevpdfo.c b/devices/vector/gdevpdfo.c
index 70b66c6b..a1c18012 100644
--- a/devices/vector/gdevpdfo.c
+++ b/devices/vector/gdevpdfo.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -281,12 +281,12 @@ cos_resource_value(cos_value_t *pcv, cos_object_t *pco)
 
 /* Free a value. */
 void
-cos_value_free(const cos_value_t *pcv, const cos_object_t *pco,
+cos_value_free(const cos_value_t *pcv, gs_memory_t *mem,
                client_name_t cname)
 {
     switch (pcv->value_type) {
     case COS_VALUE_SCALAR:
-        gs_free_string(cos_object_memory(pco), pcv->contents.chars.data,
+        gs_free_string(mem, pcv->contents.chars.data,
                        pcv->contents.chars.size, cname);
     case COS_VALUE_CONST:
         break;
@@ -517,7 +517,7 @@ cos_array_release(cos_object_t *pco, client_name_t cname)
 
     for (cur = pca->elements; cur; cur = next) {
         next = cur->next;
-        cos_value_free(&cur->value, pco, cname);
+        cos_value_free(&cur->value, cos_object_memory(pco), cname);
         gs_free_object(cos_object_memory(pco), cur, cname);
     }
     pca->elements = 0;
@@ -654,7 +654,7 @@ cos_array_put_no_copy(cos_array_t *pca, long index, const cos_value_t *pvalue)
         ppcae = &next->next;
     if (next && next->index == index) {
         /* We're replacing an existing element. */
-        cos_value_free(&next->value, COS_OBJECT(pca),
+        cos_value_free(&next->value, mem,
                        "cos_array_put(old value)");
         pcae = next;
     } else {
@@ -807,7 +807,7 @@ cos_dict_element_free(cos_dict_t *pcd, cos_dict_element_t *pcde,
 {
     gs_memory_t *mem = COS_OBJECT_MEMORY(pcd);
 
-    cos_value_free(&pcde->value, COS_OBJECT(pcd), cname);
+    cos_value_free(&pcde->value, mem, cname);
     if (pcde->owns_key)
         gs_free_string(mem, pcde->key.data, pcde->key.size, cname);
     gs_free_object(mem, pcde, cname);
@@ -1308,10 +1308,7 @@ cos_dict_put_copy(cos_dict_t *pcd, const byte *key_data, uint key_size,
                                       (flags & DICT_COPY_VALUE) != 0);
         if (code < 0)
             return code;
-        if (flags & DICT_FREE_KEY)
-            gs_free_const_string(mem, key_data, key_size,
-                                 "cos_dict_put(new key)");
-        cos_value_free(&next->value, COS_OBJECT(pcd),
+        cos_value_free(&next->value, mem,
                        "cos_dict_put(old value)");
         pcde = next;
     } else {
diff --git a/devices/vector/gdevpdfo.h b/devices/vector/gdevpdfo.h
index b30e9676..d358993b 100644
--- a/devices/vector/gdevpdfo.h
+++ b/devices/vector/gdevpdfo.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -347,7 +347,7 @@ int cos_write_object(cos_object_t *pco, gx_device_pdf *pdev, pdf_resource_type_t
 #define COS_WRITE_OBJECT(pc, pdev, type) cos_write_object(COS_OBJECT(pc), pdev, type)
 
 /* Free a Cos value owned by a Cos object. */
-void cos_value_free(const cos_value_t *, const cos_object_t *, client_name_t);
+void cos_value_free(const cos_value_t *, gs_memory_t *, client_name_t);
 
 /* Free a cos object. */
 void cos_free(cos_object_t *pco, client_name_t cname);
diff --git a/devices/vector/gdevpdfp.c b/devices/vector/gdevpdfp.c
index d06e585c..e78d9596 100644
--- a/devices/vector/gdevpdfp.c
+++ b/devices/vector/gdevpdfp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -119,6 +119,7 @@ static const gs_param_item_t pdf_param_items[] = {
     pi("DetectDuplicateImages", gs_param_type_bool, DetectDuplicateImages),
     pi("AllowIncrementalCFF", gs_param_type_bool, AllowIncrementalCFF),
     pi("WantsToUnicode", gs_param_type_bool, WantsToUnicode),
+    pi("PdfmarkCapable", gs_param_type_bool, PdfmarkCapable),
     pi("AllowPSRepeatFunctions", gs_param_type_bool, AllowPSRepeatFunctions),
     pi("IsDistiller", gs_param_type_bool, IsDistiller),
     pi("PreserveSMask", gs_param_type_bool, PreserveSMask),
@@ -254,6 +255,48 @@ gdev_pdf_get_param(gx_device *dev, char *Param, void *list)
             return(param_write_null(plist, "DSC"));
         }
     }
+
+#if OCR_VERSION > 0
+    if (strcmp(Param, "OCRLanguage") == 0) {
+        gs_param_string langstr;
+        if (pdev->ocr_language[0]) {
+            langstr.data = (const byte *)pdev->ocr_language;
+            langstr.size = strlen(pdev->ocr_language);
+            langstr.persistent = false;
+        } else {
+            langstr.data = (const byte *)"eng";
+            langstr.size = 3;
+            langstr.persistent = false;
+        }
+        return param_write_string(plist, "OCRLanguage", &langstr);
+    }
+    if (strcmp(Param, "OCREngine") == 0)
+        return param_write_int(plist, "OCREngine", &pdev->ocr_engine);
+
+    if (strcmp(Param, "UseOCR") == 0) {
+        gs_param_string ocrstr;
+
+        switch(pdev->UseOCR) {
+            case UseOCRNever:
+                ocrstr.data = (const byte *)"Never";
+                ocrstr.size = 5;
+                ocrstr.persistent = false;
+                break;
+            UseOCRAsNeeded:
+                ocrstr.data = (const byte *)"AsNeeded";
+                ocrstr.size = 8;
+                ocrstr.persistent = false;
+                break;
+            UseOCRAlways:
+                ocrstr.data = (const byte *)"Always";
+                ocrstr.size = 8;
+                ocrstr.persistent = false;
+                break;
+        }
+        return param_write_string(plist, "UseOCR", &ocrstr);
+    }
+#endif
+
     return gdev_psdf_get_param(dev, Param, list);
 }
 
@@ -268,6 +311,49 @@ gdev_pdf_get_params(gx_device * dev, gs_param_list * plist)
     int code;
     int cdv = CoreDistVersion;
 
+#if OCR_VERSION > 0
+    gs_param_string langstr;
+
+    if (pdev->ocr_language[0]) {
+        langstr.data = (const byte *)pdev->ocr_language;
+        langstr.size = strlen(pdev->ocr_language);
+        langstr.persistent = false;
+    } else {
+        langstr.data = (const byte *)"eng";
+        langstr.size = 3;
+        langstr.persistent = false;
+    }
+
+    {
+        gs_param_string ocrstr;
+
+        switch(pdev->UseOCR) {
+            case UseOCRNever:
+                ocrstr.data = (const byte *)"Never";
+                ocrstr.size = 5;
+                ocrstr.persistent = false;
+                break;
+            UseOCRAsNeeded:
+                ocrstr.data = (const byte *)"AsNeeded";
+                ocrstr.size = 8;
+                ocrstr.persistent = false;
+                break;
+            UseOCRAlways:
+                ocrstr.data = (const byte *)"Always";
+                ocrstr.size = 8;
+                ocrstr.persistent = false;
+                break;
+        }
+        code = param_write_string(plist, "UseOCR", &ocrstr);
+    }
+    code = param_write_string(plist, "OCRLanguage", &langstr);
+    if(code < 0)
+        return code;
+    code = param_write_int(plist, "OCREngine", &pdev->ocr_engine);
+    if(code < 0)
+        return code;
+#endif
+
     pdev->ParamCompatibilityLevel = cl;
     code = gdev_psdf_get_params(dev, plist);
     if (code < 0 ||
@@ -366,6 +452,83 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
         }
     }
 
+#if OCR_VERSION > 0
+    {
+        int len;
+        gs_param_string langstr;
+        switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
+            case 0:
+                len = langstr.size;
+                if (len >= sizeof(pdev->ocr_language))
+                    len = sizeof(pdev->ocr_language)-1;
+                memcpy(pdev->ocr_language, langstr.data, len);
+                pdev->ocr_language[len] = 0;
+                break;
+            case 1:
+                break;
+            default:
+                ecode = code;
+                param_signal_error(plist, param_name, ecode);
+        }
+    }
+
+    {
+        int engine;
+        switch (code = param_read_int(plist, (param_name = "OCREngine"), &engine)) {
+            case 0:
+                pdev->ocr_engine = engine;
+                break;
+            case 1:
+                break;
+            default:
+                ecode = code;
+                param_signal_error(plist, param_name, ecode);
+        }
+    }
+
+    {
+        gs_param_string ocrstr;
+
+        code = param_read_string(plist, (param_name = "UseOCR"), &ocrstr);
+        switch(code) {
+            case 0:
+                if (ocrstr.size == 5 && memcmp(ocrstr.data, "Never", 5) == 0)
+                    pdev->UseOCR = UseOCRNever;
+                if (ocrstr.size == 8 && memcmp(ocrstr.data, "AsNeeded", 8) == 0)
+                    pdev->UseOCR = UseOCRAsNeeded;
+                if (ocrstr.size == 6 && memcmp(ocrstr.data, "Always", 6) == 0)
+                    pdev->UseOCR = UseOCRAlways;
+                break;
+            case 1:
+                break;
+            default:
+                param_signal_error(plist, param_name, code);
+                break;
+        }
+    }
+
+    {
+        gs_param_string ocrstr;
+
+        code = param_read_string(plist, (param_name = "UseOCR"), &ocrstr);
+        switch(code) {
+            case 0:
+                if (ocrstr.size == 5 && memcmp(ocrstr.data, "Never", 5) == 0)
+                    pdev->UseOCR = UseOCRNever;
+                if (ocrstr.size == 8 && memcmp(ocrstr.data, "AsNeeded", 8) == 0)
+                    pdev->UseOCR = UseOCRAsNeeded;
+                if (ocrstr.size == 6 && memcmp(ocrstr.data, "Always", 6) == 0)
+                    pdev->UseOCR = UseOCRAlways;
+                break;
+            case 1:
+                break;
+            default:
+                param_signal_error(plist, param_name, code);
+                break;
+        }
+    }
+#endif
+
     /*
      * Check for LockDistillerParams before doing anything else.
      * If LockDistillerParams is true and is not being set to false,
@@ -594,9 +757,6 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
             if (pdev->params.ColorConversionStrategy == ccs_Gray) {
                 emprintf(pdev->memory, "ConvertCMYKImagesToRGB is not compatible with ColorConversionStrategy of Gray\n");
             } else {
-                if (pdev->icc_struct)
-                    rc_decrement(pdev->icc_struct,
-                                 "reset default profile\n");
                 pdf_set_process_color_model(pdev,1);
                 ecode = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
                 if (ecode < 0)
@@ -613,18 +773,12 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
             pdev->params.TransferFunctionInfo = tfi_Apply;
             break;
         case ccs_CMYK:
-            if (pdev->icc_struct)
-                rc_decrement(pdev->icc_struct,
-                             "reset default profile\n");
             pdf_set_process_color_model(pdev, 2);
             ecode = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
             if (ecode < 0)
                 goto fail;
             break;
         case ccs_Gray:
-            if (pdev->icc_struct)
-                rc_decrement(pdev->icc_struct,
-                             "reset default profile\n");
             pdf_set_process_color_model(pdev,0);
             ecode = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
             if (ecode < 0)
@@ -634,9 +788,6 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
         case ccs_RGB:
             /* Only bother to do this if we didn't handle it above */
             if (!pdev->params.ConvertCMYKImagesToRGB) {
-                if (pdev->icc_struct)
-                    rc_decrement(pdev->icc_struct,
-                                 "reset default profile\n");
                 pdf_set_process_color_model(pdev,1);
                 ecode = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
                 if (ecode < 0)
@@ -701,6 +852,11 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
         }
     }
 
+    if (pdev->Linearise && pdev->file != NULL && !gp_fseekable(pdev->file)) {
+        emprintf(pdev->memory, "Can't linearise a non-seekable output file, ignoring\n");
+        pdev->Linearise = false;
+    }
+
     if (pdev->Linearise && pdev->is_ps2write) {
         emprintf(pdev->memory, "Can't linearise PostScript output, ignoring\n");
         pdev->Linearise = false;
diff --git a/devices/vector/gdevpdfr.c b/devices/vector/gdevpdfr.c
index b0ee06c4..7aca15a6 100644
--- a/devices/vector/gdevpdfr.c
+++ b/devices/vector/gdevpdfr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -320,12 +320,12 @@ pdf_scan_token(const byte **pscan, const byte * end, const byte **ptoken)
         int status;
 
         s_PSSD_init((stream_state *)&ss);
-        r.ptr = p;		/* skip the '(' */
-        r.limit = end - 1;
-        w.limit = buf + sizeof(buf) - 1;
+
+        /* "p + 1" - skip the '(' */
+        stream_cursor_read_init(&r, p + 1, (end - p) - 1);
+
         do {
-            /* One picky compiler complains if we initialize to buf - 1. */
-            w.ptr = buf;  w.ptr--;
+            stream_cursor_write_init(&w, buf, sizeof(buf));
             status = (*s_PSSD_template.process)
                 ((stream_state *) & ss, &r, &w, true);
         }
@@ -337,6 +337,7 @@ pdf_scan_token(const byte **pscan, const byte * end, const byte **ptoken)
         if (end - p < 2)
             return_error(gs_error_syntaxerror);
         if (p[1] != '<') {
+            /* This is handling a hex string, just skips across the entire string to the '>' */
             /*
              * We need the cast because some compilers declare memchar as
              * returning a char * rather than a void *.
@@ -344,12 +345,19 @@ pdf_scan_token(const byte **pscan, const byte * end, const byte **ptoken)
             p = (const byte *)memchr(p + 1, '>', end - p - 1);
             if (p == 0)
                 return_error(gs_error_syntaxerror);
+            *pscan = p + 1;
+            return 1;
+        } else {
+            /* This case is is beginning of a dict, "<<". Return it as a token. */
+            *pscan = p + 2;
+            return 1;
         }
-        goto m2;
+        break;
     case '>':
+        /* This case is the end of a dict, ">>". Return it as a token. */
         if (end - p < 2 || p[1] != '>')
             return_error(gs_error_syntaxerror);
-m2:	*pscan = p + 2;
+        *pscan = p + 2;
         return 1;
     case '[': case ']': case '{': case '}':
         *pscan = p + 1;
@@ -447,7 +455,7 @@ pdf_replace_names(gx_device_pdf * pdev, const gs_param_string * from,
 {
     const byte *start = from->data;
     const byte *end = start + from->size;
-    const byte *scan;
+    const byte *scan, *to_free = NULL;
     uint size = 0;
     cos_object_t *pco;
     bool any = false;
@@ -477,13 +485,17 @@ pdf_replace_names(gx_device_pdf * pdev, const gs_param_string * from,
     }
     to->persistent = true;	/* ??? */
     if (!any) {
-        to->data = start;
+        if (to->data != start) {
+            gs_free_object(pdev->pdf_memory, (byte *)to->data, "pdf_replace_names");
+            to->data = start;
+        }
         to->size = size;
         return 0;
     }
     sto = gs_alloc_bytes(pdev->pdf_memory, size, "pdf_replace_names");
     if (sto == 0)
         return_error(gs_error_VMerror);
+    to_free = to->data;
     to->data = sto;
     to->size = size;
     /* Do a second pass to do the actual substitutions. */
@@ -508,5 +520,6 @@ pdf_replace_names(gx_device_pdf * pdev, const gs_param_string * from,
         }
         scan = next;
     }
+    gs_free_object(pdev->pdf_memory, (byte *)to_free, "pdf_replace_names");
     return 0;
 }
diff --git a/devices/vector/gdevpdft.c b/devices/vector/gdevpdft.c
index a963cb51..8b5a2094 100644
--- a/devices/vector/gdevpdft.c
+++ b/devices/vector/gdevpdft.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -334,6 +334,7 @@ pdf_begin_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
     } else {
         int code;
 
+        pdev->smask_construction = true;
         code = pdf_make_soft_mask_dict(pdev, pparams);
         if (code < 0)
             return code;
@@ -348,6 +349,7 @@ static int
 pdf_end_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
                                 const gs_pdf14trans_params_t * pparams)
 {
+    pdev->smask_construction = false;
     if (pdev->image_mask_skip)
         pdev->image_mask_skip = false;
     else {
diff --git a/devices/vector/gdevpdfu.c b/devices/vector/gdevpdfu.c
index e5a9df01..325af7c2 100644
--- a/devices/vector/gdevpdfu.c
+++ b/devices/vector/gdevpdfu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -39,12 +39,6 @@
 #include "sstring.h"
 #include "strmio.h"
 #include "szlibx.h"
-#ifdef USE_LDF_JB2
-#include "sjbig2_luratech.h"
-#endif
-#ifdef USE_LWF_JP2
-#include "sjpx_luratech.h"
-#endif
 
 #include "opdfread.h"
 #include "gdevagl.h"
@@ -768,6 +762,9 @@ pdf_open_obj(gx_device_pdf * pdev, long id, pdf_resource_type_t type)
 {
     stream *s = pdev->strm;
 
+    if (s == NULL)
+        return_error(gs_error_ioerror);
+
     if (id <= 0) {
         id = pdf_obj_ref(pdev);
     } else {
@@ -777,10 +774,10 @@ pdf_open_obj(gx_device_pdf * pdev, long id, pdf_resource_type_t type)
 
         if (gp_fseek(tfile, ((int64_t)(id - pdev->FirstObjectNumber)) * sizeof(pos),
               SEEK_SET) != 0)
-	  return_error(gs_error_ioerror);
+	        return_error(gs_error_ioerror);
         gp_fwrite(&pos, sizeof(pos), 1, tfile);
         if (gp_fseek(tfile, tpos, SEEK_SET) != 0)
-	  return_error(gs_error_ioerror);
+	        return_error(gs_error_ioerror);
     }
     if (pdev->ForOPDFRead && pdev->ProduceDSC) {
         switch(type) {
@@ -1887,7 +1884,7 @@ pdf_page_id(gx_device_pdf * pdev, int page_num)
 {
     cos_dict_t *Page;
 
-    if (page_num < 1)
+    if (page_num < 1 || pdev->pages == NULL)
         return 0;
     if (page_num >= pdev->num_pages) {	/* Grow the pages array. */
         uint new_num_pages;
@@ -2394,14 +2391,6 @@ pdf_put_filters(cos_dict_t *pcd, gx_device_pdf *pdev, stream *s,
             filter_name = pfn->FlateDecode;
         else if (TEMPLATE_IS(s_LZWE_template))
             filter_name = pfn->LZWDecode;
-#ifdef USE_LDF_JB2
-        else if (TEMPLATE_IS(s_jbig2encode_template))
-            filter_name = pfn->JBIG2Decode;
-#endif
-#ifdef USE_LWF_JP2
-        else if (TEMPLATE_IS(s_jpxe_template))
-            filter_name = pfn->JPXDecode;
-#endif
         else if (TEMPLATE_IS(s_PNGPE_template)) {
             /* This is a predictor for FlateDecode or LZWEncode. */
             const stream_PNGP_state *const ss =
diff --git a/devices/vector/gdevpdfv.c b/devices/vector/gdevpdfv.c
index dd7d4c7c..6b3c5c97 100644
--- a/devices/vector/gdevpdfv.c
+++ b/devices/vector/gdevpdfv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfx.h b/devices/vector/gdevpdfx.h
index c8b44b46..2db4f77a 100644
--- a/devices/vector/gdevpdfx.h
+++ b/devices/vector/gdevpdfx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -547,6 +547,33 @@ typedef enum {
     pdf_compress_Flate
 } pdf_compression_type;
 
+typedef enum {
+    OCR_UnInit,
+    OCR_Rendering,
+    OCR_Rendered,
+    OCR_UnicodeAvailable,
+    OCR_Failed
+} pdf_OCR_stage;
+
+typedef enum {
+    UseOCRNever,
+    UseOCRAsNeeded,
+    UseOCRAlways
+} pdf_OCR_usage;
+
+typedef struct ocr_glyph_s{
+    byte *data;
+    int x;
+    int y;
+    int width;
+    int height;
+    int raster;
+    void *next;
+    gs_char char_code;
+    gs_glyph glyph;
+    bool is_space;
+} ocr_glyph_t;
+
 /* Define the device structure. */
 struct gx_device_pdf_s {
     gx_device_psdf_common;
@@ -572,6 +599,9 @@ struct gx_device_pdf_s {
     gs_param_float_array PDFXTrimBoxToMediaBoxOffset;
     gs_param_float_array PDFXBleedBoxToTrimBoxOffset;
     bool PDFXSetBleedBoxToMediaBox;
+    /* OCR Parameters */
+    char ocr_language[1024];
+    int ocr_engine;
     /* Other parameters */
     bool ReAssignCharacters;
     bool ReEncodeCharacters;
@@ -838,6 +868,7 @@ struct gx_device_pdf_s {
     gs_id     image_mask_id;
     bool      image_mask_is_SMask;
     bool      image_mask_skip; /* A flag for pdf_begin_transparency_mask */
+    bool      smask_construction; /* True when pdfwrite is constructing a soft mask */
     uint      image_with_SMask; /* A flag for pdf_begin_transparency_group. In order to
                                  * deal with nested groups we set/test the bit according
                                  * to the FormDepth
@@ -863,6 +894,7 @@ struct gx_device_pdf_s {
     bool DetectDuplicateImages;
     bool AllowIncrementalCFF;
     bool WantsToUnicode;
+    bool PdfmarkCapable;
     bool WantsPageLabels;
     bool AllowPSRepeatFunctions;
     bool IsDistiller;
@@ -907,6 +939,13 @@ struct gx_device_pdf_s {
                                      * anything in the image processing routines.
                                      */
     float UserUnit;
+    pdf_OCR_usage UseOCR;                     /* Never, AsNeeded or Always */
+    gs_text_enum_t* OCRSaved;       /* Saved state of the text enumerator before rendering glyph bitmaps for later OCR */
+    pdf_OCR_stage OCRStage;         /* Used to control a (sort of) state machine when using OCR to get a Unicode value for a glyph */
+    int *OCRUnicode;                /* Used to pass back the Unicode value from the OCR engine to the text processing */
+    gs_char OCR_char_code;          /* Passes the current character code from text processing to the image processing code when rendering glyph bitmaps for OCR */
+    gs_glyph OCR_glyph;             /* Passes the current glyph code from text processing to the image processing code when rendering glyph bitmaps for OCR */
+    ocr_glyph_t *ocr_glyphs;        /* Records bitmaps and other data from text processing when doing OCR */
 };
 
 #define is_in_page(pdev)\
diff --git a/devices/vector/gdevpdt.c b/devices/vector/gdevpdt.c
index 970dd76a..754737ac 100644
--- a/devices/vector/gdevpdt.c
+++ b/devices/vector/gdevpdt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdt.h b/devices/vector/gdevpdt.h
index ee7a1c1e..1ce7e1d6 100644
--- a/devices/vector/gdevpdt.h
+++ b/devices/vector/gdevpdt.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtb.c b/devices/vector/gdevpdtb.c
index 61961c4a..c0a148c3 100644
--- a/devices/vector/gdevpdtb.c
+++ b/devices/vector/gdevpdtb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -29,6 +29,7 @@
 #include "gdevpdfo.h"
 #include "gdevpdtb.h"
 #include "gdevpdtf.h"
+#include "gdevpdtd.h"
 #include "smd5.h"
 #include "gxfcache.h"   /* for gs_purge_font_from_char_caches_completely */
 /*
@@ -372,7 +373,7 @@ pdf_base_font_alloc(gx_device_pdf *pdev, pdf_base_font_t **ppbfont,
     *ppbfont = pbfont;
     return 0;
  fail:
-    gs_free_object(mem, pbfont, "pdf_base_font_alloc");
+    pdf_base_font_free(pdev, pbfont);
     return code;
 }
 
@@ -412,6 +413,11 @@ pdf_base_font_is_subset(const pdf_base_font_t *pbfont)
 void
 pdf_base_font_drop_complete(pdf_base_font_t *pbfont)
 {
+    /* gs_font is a subset of gs_font_base and we only want to
+     * free the members which are common to both, so this cast is
+     * (at the time of writing) safe.
+     */
+    gs_free_copied_font((gs_font *)pbfont->complete);
     pbfont->complete = NULL;
 }
 
@@ -654,11 +660,18 @@ pdf_write_embedded_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, font_type
             /* Write the type 1 font with no converting to CFF. */
             int lengths[3];
 
-            code = psf_write_type1_font(writer.binary.strm,
+            if (pbfont->do_subset != DO_SUBSET_NO)
+                code = psf_write_type1_font(writer.binary.strm,
                                 (gs_font_type1 *)out_font,
                                 WRITE_TYPE1_WITH_LENIV | WRITE_TYPE1_EEXEC |
                                 WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_ASCIIHEX,
                                 NULL, 0, &fnstr, lengths);
+            else
+                code = psf_write_type1_font(writer.binary.strm,
+                                (gs_font_type1 *)out_font,
+                                WRITE_TYPE1_WITH_LENIV | WRITE_TYPE1_EEXEC |
+                                WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_ASCIIHEX | WRITE_TYPE1_XUID,
+                                NULL, 0, &fnstr, lengths);
             if (lengths[0] > 0) {
                 if (code < 0)
                     goto finish;
@@ -689,7 +702,8 @@ pdf_write_embedded_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, font_type
             code = psf_write_type2_font(writer.binary.strm,
                                         (gs_font_type1 *)out_font,
                                         TYPE2_OPTIONS |
-                            (pdev->CompatibilityLevel < 1.3 ? WRITE_TYPE2_AR3 : 0),
+                            (pdev->CompatibilityLevel < 1.3 ? WRITE_TYPE2_AR3 : 0) |
+                            (pbfont->do_subset == DO_SUBSET_NO ? WRITE_TYPE2_XUID : 0),
                                         NULL, 0, &fnstr, FontBBox);
         }
         goto finish;
diff --git a/devices/vector/gdevpdtb.h b/devices/vector/gdevpdtb.h
index 8753aa98..e8540c28 100644
--- a/devices/vector/gdevpdtb.h
+++ b/devices/vector/gdevpdtb.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtc.c b/devices/vector/gdevpdtc.c
index 5c6da535..c2b76b7c 100644
--- a/devices/vector/gdevpdtc.c
+++ b/devices/vector/gdevpdtc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtd.c b/devices/vector/gdevpdtd.c
index ce6efa05..33cb012b 100644
--- a/devices/vector/gdevpdtd.c
+++ b/devices/vector/gdevpdtd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -221,10 +221,8 @@ pdf_font_descriptor_alloc(gx_device_pdf *pdev, pdf_font_descriptor_t **ppfd,
     return 0;
 }
 
-int pdf_font_descriptor_free(gx_device_pdf *pdev, pdf_resource_t *pres)
+int pdf_base_font_free(gx_device_pdf *pdev, pdf_base_font_t *pbfont)
 {
-    pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres;
-    pdf_base_font_t *pbfont = pfd->base_font;
     gs_font *copied = NULL, *complete = NULL;
 
     if (pbfont) {
@@ -239,14 +237,27 @@ int pdf_font_descriptor_free(gx_device_pdf *pdev, pdf_resource_t *pres)
         gs_free_copied_font(copied);
 
     if (pbfont) {
+        if (pbfont->CIDSet)
+            gs_free_object(pdev->pdf_memory, pbfont->CIDSet, "Free base font CIDSet from FontDescriptor)");
+
         if (pbfont->font_name.size) {
             gs_free_string(pdev->pdf_memory, pbfont->font_name.data, pbfont->font_name.size, "Free BaseFont FontName string");
             pbfont->font_name.data = (byte *)0L;
             pbfont->font_name.size = 0;
         }
-        gs_free_object(cos_object_memory(pres->object), pbfont, "Free base font from FontDescriptor)");
-        pfd->base_font = 0;
+        gs_free_object(pdev->pdf_memory, pbfont, "Free base font from FontDescriptor)");
     }
+    return 0;
+}
+
+int pdf_font_descriptor_free(gx_device_pdf *pdev, pdf_resource_t *pres)
+{
+    pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres;
+    pdf_base_font_t *pbfont = pfd->base_font;
+
+    pdf_base_font_free(pdev, pbfont);
+    pfd->base_font = 0;
+
     if (pres->object) {
         gs_free_object(pdev->pdf_memory, pres->object, "free FontDescriptor object");
         pres->object = NULL;
diff --git a/devices/vector/gdevpdtd.h b/devices/vector/gdevpdtd.h
index 92e64758..abf76552 100644
--- a/devices/vector/gdevpdtd.h
+++ b/devices/vector/gdevpdtd.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -104,6 +104,8 @@ int pdf_font_descriptor_alloc(gx_device_pdf *pdev,
                               pdf_font_descriptor_t **ppfd,
                               gs_font_base *font, bool embed);
 
+int pdf_base_font_free(gx_device_pdf *pdev, pdf_base_font_t *pbfont);
+
 int pdf_font_descriptor_free(gx_device_pdf *pdev, pdf_resource_t *pres);
 
 /*
diff --git a/devices/vector/gdevpdte.c b/devices/vector/gdevpdte.c
index 6f0eb158..7a6b145e 100644
--- a/devices/vector/gdevpdte.c
+++ b/devices/vector/gdevpdte.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -43,6 +43,7 @@
 #include "gxcpath.h"
 
 #include "gsfcmap.h"
+#include "tessocr.h"
 
 static int pdf_char_widths(gx_device_pdf *const pdev,
                             pdf_font_resource_t *pdfont, int ch,
@@ -80,6 +81,216 @@ pdf_process_string_aux(pdf_text_enum_t *penum, gs_string *pstr,
     return pdf_process_string(penum, pstr, pfmat, ppts, gdata);
 }
 
+static int OCRText(gx_device_pdf *pdev, gs_glyph glyph, gs_char ch, gs_char *length, byte **unicode)
+{
+#if OCR_VERSION > 0
+    int code = 0;
+
+    if(pdev->OCRStage == OCR_Rendered) {
+        int llx, lly, urx, ury, char_count = 0, returned_count = 0, *returned;
+        ocr_glyph_t *next_glyph = pdev->ocr_glyphs;
+        int rows, stride, row, column;
+        byte *bitmap = NULL, *src, *dest, *rowptr, srcmask, destmask;
+        void *state;
+        const char *language = pdev->ocr_language;
+        gp_file *DbgFile;
+
+        if(language == NULL || language[0] == 0)
+            language = "eng";
+
+        /* We should alredy have rendered a bitmap for all the glyphs in the
+         * text operation, so this shuld be redundant, but best to be safe.
+         */
+        if(next_glyph == NULL)
+            return_error(gs_error_unknownerror);
+
+        /* Identify the bounding box of the returned glyphs by examing the bounds and position
+         * of each glyph. At the same time count the number of expected returned characters.
+         * We treat any empty bitmap (all 0x00 bytes) as a space because, obviously, the
+         * OCR engine can't tell differentiate between a space character and no character at all.
+         */
+        llx = next_glyph->x;
+        lly = next_glyph->y;
+        urx = llx + next_glyph->width;
+        ury = lly + next_glyph->height;
+        if(next_glyph != NULL && !next_glyph->is_space)
+            char_count++;
+        next_glyph = (ocr_glyph_t *)next_glyph->next;
+        while(next_glyph) {
+            if(!next_glyph->is_space)
+                char_count++;
+            if(next_glyph->x < llx)
+                llx = next_glyph->x;
+            if(next_glyph->y < lly)
+                lly = next_glyph->y;
+            if(next_glyph->x + next_glyph->width > urx)
+                urx = next_glyph->x + next_glyph->width;
+            if(next_glyph->y + next_glyph->height > ury)
+                ury = next_glyph->y + next_glyph->height;
+            next_glyph = next_glyph->next;
+        }
+
+        /* Allocate and initialise the 'strip' bitmap which will receive all the
+         * individual glyph bitmaps.
+         */
+        rows = ury - lly;
+        stride = (((urx - llx) + 7) / 8) + 1;
+        bitmap = gs_alloc_bytes(pdev->memory, rows * stride, "working OCR memory");
+        if(bitmap == NULL)
+            return_error(gs_error_VMerror);
+        memset(bitmap, 0x00, rows * stride);
+
+        /* Allocate a buffer for the OCR engine to return the Unicode code points. This needs work,
+         * we might want more information returned (bounding boxes and confidence levels) and we
+         * need to think about the possibility that the OCR engine finds more character than we
+         * expected (eg fi ligatures returned as 'f' and 'i'.
+         */
+        returned = (int *)gs_alloc_bytes(pdev->memory, char_count * sizeof(int), "returned unicodes");
+        if(returned == NULL) {
+            gs_free_object(pdev->memory, bitmap, "working OCR memory");
+            return_error(gs_error_VMerror);
+        }
+        memset(returned, 0x00, char_count * sizeof(int));
+
+        /* Now copy each glyph bitmap to the correct position in the strip. This is complicated
+         * by the fact that bitmaps are monochrome pcaked into bytes and so the destination
+         * may not be aligned on a byte boundary.
+         */
+        next_glyph = (ocr_glyph_t *)pdev->ocr_glyphs;
+        while(next_glyph) {
+            rowptr = bitmap + ((next_glyph->y - lly) * stride) + (int)floor((next_glyph->x - llx) / 8);
+            for(row = 0;row < next_glyph->height;row++) {
+                dest = rowptr + row * stride;
+                src = next_glyph->data + (row * next_glyph->raster);
+                destmask = 0x80 >> (next_glyph->x - llx) % 8;
+                srcmask = 0x80;
+                for(column = 0; column < next_glyph->width;column++) {
+                    if(*src & srcmask) {
+                        *dest = *dest | destmask;
+                    }
+                    srcmask = srcmask >> 1;
+                    if(srcmask == 0) {
+                        srcmask = 0x80;
+                        src++;
+                    }
+                    destmask = destmask >> 1;
+                    if(destmask == 0) {
+                        destmask = 0x80;
+                        dest++;
+                    }
+                }
+            }
+            next_glyph = next_glyph->next;
+        }
+
+#if 0
+        DbgFile = gp_fopen(pdev->memory, "d:/temp/bits.txt", "wb+");
+        for(row = 0;row < rows;row++) {
+            for(column = 0;column < stride;column++) {
+                dest = bitmap + (row * stride);
+                gp_fprintf(DbgFile, "%02x", dest[column]);
+            }
+            gp_fprintf(DbgFile, "\n");
+        }
+        gp_fclose(DbgFile);
+#endif
+        /* Initialise the OCR engine */
+        code = ocr_init_api(pdev->memory->non_gc_memory, language,
+            pdev->ocr_engine, &state);
+        if(code < 0) {
+            gs_free_object(pdev->memory, bitmap, "working OCR memory");
+            gs_free_object(pdev->memory, returned, "returned unicodes");
+            return 0;
+        }
+        returned_count = char_count;
+
+        /* Pass our strip to the OCR engine */
+        code = ocr_bitmap_to_unicodes(state,
+            bitmap, 0, stride * 8, rows, stride,
+            (int)pdev->HWResolution[0],
+            (int)pdev->HWResolution[1],
+            returned, &returned_count);
+
+        /* and close the engine back down again */
+        ocr_fin_api(pdev->memory->non_gc_memory, state);
+        gs_free_object(pdev->memory, bitmap, "working OCR memory");
+
+        if(code < 0) {
+            pdev->OCRStage = OCR_Failed;
+            gs_free_object(pdev->memory, returned, "returned unicodes");
+            return code;
+        }
+
+        /* Future enhancement we should fall back to trying the individual bitmap here */
+        if(returned_count != char_count) {
+            pdev->OCRStage = OCR_Failed;
+            gs_free_object(pdev->memory, returned, "returned unicodes");
+            return 0;
+        }
+        pdev->OCRUnicode = returned;
+
+        /* Actually perform OCR on the stored bitmaps */
+        pdev->OCRStage = OCR_UnicodeAvailable;
+    }
+
+    if(pdev->OCRStage == OCR_UnicodeAvailable) {
+        /* We've OCR'ed the bitmaps already, find the unicode value */
+        ocr_glyph_t *new_glyph = (ocr_glyph_t *)pdev->ocr_glyphs;
+        int ocr_index = 0;
+        uint mask = 0xFF;
+        int ix;
+        char *u;
+
+        /* Find the bitmap which matches the character/glyph we are processing */
+        while(new_glyph) {
+            if(new_glyph->char_code == ch || new_glyph->glyph == glyph) {
+                ocr_glyph_t *g1 = pdev->ocr_glyphs;
+
+                /* Spaces are handled specially, so just jump out now */
+                if(new_glyph->is_space)
+                    break;
+
+                /* Otherwise, find all the bitmaps which lie to the left of the
+                 * one we found (we are assuming for now that the returned
+                 * Unicode values are left to right)
+                 */
+                while(g1) {
+                    if(!g1->is_space) {
+                        if(g1->x < new_glyph->x)
+                            ocr_index++;
+                    }
+                    g1 = g1->next;
+                }
+                break;
+            }
+            new_glyph = new_glyph->next;
+        }
+
+        /* If we found a matching bitmap, get the corresponding unicode code point from
+         * the stored values returned by the OCR engine.
+         */
+        if(new_glyph) {
+            *unicode = (byte *)gs_alloc_bytes(pdev->memory, 2 * sizeof(ushort), "temporary Unicode array");
+            if(*unicode == NULL)
+                return_error(gs_error_VMerror);
+            u = (char *)(*unicode);
+            if(new_glyph->is_space) {
+                memset(u, 0x00, 3);
+                u[3] = 0x20;
+            }
+            else {
+                for(ix = 0;ix < 4;ix++) {
+                    u[3 - ix] = (pdev->OCRUnicode[ocr_index] & mask) >> (8 * ix);
+                    mask = mask << 8;
+                }
+            }
+            *length = 4;
+        }
+    }
+    #endif
+    return 0;
+}
+
 /*
  * Add char code pair to ToUnicode CMap,
  * creating the CMap on neccessity.
@@ -87,27 +298,43 @@ pdf_process_string_aux(pdf_text_enum_t *penum, gs_string *pstr,
 int
 pdf_add_ToUnicode(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_t *pdfont,
                   gs_glyph glyph, gs_char ch, const gs_const_string *gnstr)
-{   int code;
-    gs_char length;
+{   int code = 0;
+    gs_char length = 0;
     ushort *unicode = 0;
 
     if (glyph == GS_NO_GLYPH)
         return 0;
-    length = font->procs.decode_glyph((gs_font *)font, glyph, ch, NULL, 0);
-    if ((length == 0 || length == GS_NO_CHAR) && gnstr != NULL && gnstr->size == 7) {
-        if (!memcmp(gnstr->data, "uni", 3)) {
-            static const char *hexdigits = "0123456789ABCDEF";
-            char *d0 = strchr(hexdigits, gnstr->data[3]);
-            char *d1 = strchr(hexdigits, gnstr->data[4]);
-            char *d2 = strchr(hexdigits, gnstr->data[5]);
-            char *d3 = strchr(hexdigits, gnstr->data[6]);
-
-            unicode = (ushort *)gs_alloc_bytes(pdev->memory, sizeof(ushort), "temporary Unicode array");
-            if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
-                char *u = (char *)unicode;
-                u[0] = ((d0 - hexdigits) << 4) + ((d1 - hexdigits));
-                u[1] = ((d2 - hexdigits) << 4) + ((d3 - hexdigits));
-                length = 2;
+    if(pdev->UseOCR == UseOCRAlways) {
+        code = OCRText(pdev, glyph, ch, &length, (byte **)&unicode);
+        if(code < 0)
+            return code;
+    }
+    else {
+        length = font->procs.decode_glyph((gs_font *)font, glyph, ch, NULL, 0);
+        if(length == 0 || length == GS_NO_CHAR) {
+            if(gnstr != NULL && gnstr->size == 7) {
+                if(!memcmp(gnstr->data, "uni", 3)) {
+                    static const char *hexdigits = "0123456789ABCDEF";
+                    char *d0 = strchr(hexdigits, gnstr->data[3]);
+                    char *d1 = strchr(hexdigits, gnstr->data[4]);
+                    char *d2 = strchr(hexdigits, gnstr->data[5]);
+                    char *d3 = strchr(hexdigits, gnstr->data[6]);
+
+                    unicode = (ushort *)gs_alloc_bytes(pdev->memory, sizeof(ushort), "temporary Unicode array");
+                    if(d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
+                        char *u = (char *)unicode;
+                        u[0] = ((d0 - hexdigits) << 4) + ((d1 - hexdigits));
+                        u[1] = ((d2 - hexdigits) << 4) + ((d3 - hexdigits));
+                        length = 2;
+                    }
+                }
+            }
+            else {
+                if(pdev->UseOCR != UseOCRNever) {
+                    code = OCRText(pdev, glyph, ch, &length, (byte **)&unicode);
+                    if(code < 0)
+                        return code;
+                }
             }
         }
     }
@@ -163,6 +390,7 @@ pdf_add_ToUnicode(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_t *pdfon
         if (length > 2 && pdfont->u.simple.Encoding != NULL)
             pdfont->TwoByteToUnicode = 0;
     }
+
     if (unicode)
         gs_free_object(pdev->memory, unicode, "temporary Unicode array");
     return 0;
@@ -255,8 +483,11 @@ pdf_encode_string_element(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_
     pet = &pdfont->u.simple.Encoding[ch];
     glyph = (gdata == NULL ? font->procs.encode_char(font, ch, GLYPH_SPACE_NAME)
                            : *gdata);
-    if (glyph == GS_NO_GLYPH || glyph == pet->glyph)
+    if (glyph == GS_NO_GLYPH || glyph == pet->glyph) {
+        if((pdfont->cmap_ToUnicode == NULL || !gs_cmap_ToUnicode_check_pair(pdfont->cmap_ToUnicode, ch)) && pdev->UseOCR != UseOCRNever)
+            (void)pdf_add_ToUnicode(pdev, font, pdfont, glyph, ch, &gnstr);
         return 0;
+    }
     if (pet->glyph != GS_NO_GLYPH) { /* encoding conflict */
         return_error(gs_error_rangecheck);
         /* Must not happen because pdf_obtain_font_resource
@@ -358,7 +589,7 @@ pdf_encode_string_element(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_
         * The decision about writing it out is deferred until pdf_write_font_resource.
         */
     code = pdf_add_ToUnicode(pdev, font, pdfont, glyph, ch, &gnstr);
-    if (code < 0)
+    if(code < 0)
         return code;
     pet->glyph = glyph;
     pet->str = gnstr;
@@ -1035,6 +1266,7 @@ process_text_return_width(const pdf_text_enum_t *pte, gs_font_base *font,
         {  const gs_glyph *gdata_i = (gdata != NULL ? gdata + i : 0);
 
             code = pdf_encode_string_element(pdev, (gs_font *)font, pdfont, ch, gdata_i);
+
             if (code < 0)
                 return code;
         }
diff --git a/devices/vector/gdevpdtf.c b/devices/vector/gdevpdtf.c
index c823b18c..0972e02d 100644
--- a/devices/vector/gdevpdtf.c
+++ b/devices/vector/gdevpdtf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -32,6 +32,7 @@
 #include "gdevpdtf.h"
 #include "gdevpdtw.h"
 #include "gdevpdti.h"
+#include "gdevpdfo.h"       /* for cos_free() */
 #include "whitelst.h"		/* Checks whether protected fonta cna be embedded */
 
 #include "gscencs.h"
@@ -336,7 +337,9 @@ pdf_outline_fonts_alloc(gs_memory_t *mem)
 pdf_standard_font_t *
 pdf_standard_fonts(const gx_device_pdf *pdev)
 {
-    return pdev->text->outline_fonts->standard_fonts;
+    if (pdev->text != NULL && pdev->text->outline_fonts != NULL)
+        return pdev->text->outline_fonts->standard_fonts;
+    return NULL;
 }
 
 /*
@@ -347,7 +350,8 @@ pdf_clean_standard_fonts(const gx_device_pdf *pdev)
 {
     pdf_standard_font_t *ppsf = pdf_standard_fonts(pdev);
 
-    memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
+    if (ppsf != NULL)
+        memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
 }
 
 /* ---------------- Font resources ---------------- */
@@ -471,6 +475,14 @@ int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
                 pdf_free_charproc_ownership(pdev, (pdf_resource_t *)pdfont->u.simple.s.type3.char_procs);
                 pdfont->u.simple.s.type3.char_procs = 0;
             }
+            if (pdfont->u.simple.s.type3.cached) {
+                gs_free_object(pdev->pdf_memory, pdfont->u.simple.s.type3.cached, "Free type 3 cached array");
+                pdfont->u.simple.s.type3.cached = NULL;
+            }
+            if (pdfont->u.simple.s.type3.Resources != NULL) {
+                cos_free((cos_object_t *)pdfont->u.simple.s.type3.Resources, "Free type 3 Resources dictionary");
+                pdfont->u.simple.s.type3.Resources = NULL;
+            }
             break;
         case ft_CID_encrypted:
         case ft_CID_TrueType:
diff --git a/devices/vector/gdevpdtf.h b/devices/vector/gdevpdtf.h
index f0006641..f13c0eac 100644
--- a/devices/vector/gdevpdtf.h
+++ b/devices/vector/gdevpdtf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdti.c b/devices/vector/gdevpdti.c
index 0205604a..d1b39e99 100644
--- a/devices/vector/gdevpdti.c
+++ b/devices/vector/gdevpdti.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -557,7 +557,12 @@ pdf_do_char_image(gx_device_pdf * pdev, const pdf_char_proc_t * pcp,
 int
 pdf_write_bitmap_fonts_Encoding(gx_device_pdf *pdev)
 {
-    pdf_bitmap_fonts_t *pbfs = pdev->text->bitmap_fonts;
+    pdf_bitmap_fonts_t *pbfs;
+
+    if (pdev->text == NULL || pdev->text->bitmap_fonts == NULL)
+        return 0;
+
+    pbfs = pdev->text->bitmap_fonts;
 
     if (pbfs->bitmap_encoding_id) {
         stream *s;
diff --git a/devices/vector/gdevpdti.h b/devices/vector/gdevpdti.h
index 81409e67..ccee9fd2 100644
--- a/devices/vector/gdevpdti.h
+++ b/devices/vector/gdevpdti.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdts.c b/devices/vector/gdevpdts.c
index aa41f516..ec946ac4 100644
--- a/devices/vector/gdevpdts.c
+++ b/devices/vector/gdevpdts.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdts.h b/devices/vector/gdevpdts.h
index b3699eb2..9355473e 100644
--- a/devices/vector/gdevpdts.h
+++ b/devices/vector/gdevpdts.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtt.c b/devices/vector/gdevpdtt.c
index 5884115e..952f41db 100644
--- a/devices/vector/gdevpdtt.c
+++ b/devices/vector/gdevpdtt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -299,13 +299,29 @@ static void
 pdf_text_release(gs_text_enum_t *pte, client_name_t cname)
 {
     pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
+    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
+    ocr_glyph_t *next;
 
     if (penum->pte_default) {
-        gs_text_release(penum->pte_default, cname);
+        gs_text_release(NULL, penum->pte_default, cname);
         penum->pte_default = 0;
     }
     pdf_text_release_cgp(penum);
+
+    while (pdev->ocr_glyphs != NULL)
+    {
+        next = pdev->ocr_glyphs->next;
+
+        gs_free_object(pdev->memory, pdev->ocr_glyphs->data, "free bitmap");
+        gs_free_object(pdev->memory, pdev->ocr_glyphs, "free bitmap");
+        pdev->ocr_glyphs = next;
+    }
+    if (pdev->OCRUnicode != NULL)
+        gs_free_object(pdev->memory, pdev->OCRUnicode, "free returned unicodes");
+    pdev->OCRUnicode = NULL;
+
     gx_default_text_release(pte, cname);
+    pdev->OCRStage = 0;
 }
 void
 pdf_text_release_cgp(pdf_text_enum_t *penum)
@@ -591,7 +607,7 @@ gdev_pdf_text_begin(gx_device * dev, gs_gstate * pgs,
             if (penum->fstack.items[penum->fstack.depth].font->FontType == 3)
                 user_defined = 1;
         }
-        gs_text_release((gs_text_enum_t *)penum, "pdf_text_process");
+        gs_text_release(NULL, (gs_text_enum_t *)penum, "pdf_text_process");
     }
 
     if (!user_defined || !(text->operation & TEXT_DO_ANY_CHARPATH)) {
@@ -633,9 +649,12 @@ gdev_pdf_text_begin(gx_device * dev, gs_gstate * pgs,
     penum->cdevproc_callout = false;
     penum->returned.total_width.x = penum->returned.total_width.y = 0;
     penum->cgp = NULL;
+    penum->returned.current_glyph = GS_NO_GLYPH;
     penum->output_char_code = GS_NO_CHAR;
     code = gs_text_enum_init((gs_text_enum_t *)penum, &pdf_text_procs,
                              dev, pgs, text, font, path, pdcolor, pcpath, mem);
+    penum->k_text_release = 1; /* early release of black_text_state */
+
     if (code < 0) {
         gs_free_object(mem, penum, "gdev_pdf_text_begin");
         return code;
@@ -678,12 +697,23 @@ pdf_font_cache_elem_t **
 pdf_locate_font_cache_elem(gx_device_pdf *pdev, gs_font *font)
 {
     pdf_font_cache_elem_t **e = &pdev->font_cache;
+    pdf_font_cache_elem_t *prev = NULL;
     long id = pdf_font_cache_elem_id(font);
 
-    for (; *e != 0; e = &(*e)->next)
+    for (; *e != 0; e = &(*e)->next) {
         if ((*e)->font_id == id) {
-            return e;
+            if (prev != NULL) {
+                pdf_font_cache_elem_t *curr = *e;
+
+                /* move the curr font to head of list (Most Recently Used) */
+                prev->next = curr->next;
+                curr->next = pdev->font_cache;
+                pdev->font_cache = curr;
+            }
+            return &(pdev->font_cache);
         }
+        prev = *e;
+    }
     return 0;
 }
 
@@ -757,6 +787,13 @@ alloc_font_cache_elem_arrays(gx_device_pdf *pdev, pdf_font_cache_elem_t *e,
 
     font_cache_elem_array_sizes(pdev, font, &num_widths, &num_chars);
     len = (num_chars + 7) / 8;
+    if (e->glyph_usage != NULL)
+        gs_free_object(pdev->pdf_memory, e->glyph_usage,
+                            "pdf_attach_font_resource, reallocating");
+    if (e->real_widths != NULL)
+        gs_free_object(pdev->pdf_memory, e->real_widths,
+                            "alloc_font_cache_elem_arrays, reallocating");
+
     e->glyph_usage = gs_alloc_bytes(pdev->pdf_memory,
                         len, "alloc_font_cache_elem_arrays");
 
@@ -3085,7 +3122,7 @@ static int complete_charproc(gx_device_pdf *pdev, gs_text_enum_t *pte,
     code = gx_default_text_restore_state(pte_default);
     if (code < 0)
         return code;
-    gs_text_release(pte_default, "pdf_text_process");
+    gs_text_release(NULL, pte_default, "pdf_text_process");
     penum->pte_default = 0;
 
     return 0;
@@ -3132,6 +3169,57 @@ static int pdf_query_purge_cached_char(const gs_memory_t *mem, cached_char *cc,
     return 0;
 }
 
+static int ProcessTextForOCR(gs_text_enum_t *pte)
+{
+    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
+    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
+    gs_text_enum_t *pte_default;
+    int code;
+
+    if (pdev->OCRStage == OCR_UnInit) {
+        gs_gsave(pte->pgs);
+        pdev->OCRSaved = (gs_text_enum_t*)gs_alloc_bytes(pdev->memory,sizeof(gs_text_enum_t),"saved enumerator for OCR");
+        if(pdev->OCRSaved == NULL)
+            return_error(gs_error_VMerror);
+        *(pdev->OCRSaved) = *pte;
+        gs_text_enum_copy_dynamic(pdev->OCRSaved,pte,true);
+
+        code = pdf_default_text_begin(pte, &pte->text, &pte_default);
+        if (code < 0)
+            return code;
+        penum->pte_default = pte_default;
+        gs_text_enum_copy_dynamic(pte_default, pte, false);
+        pdev->OCRStage = OCR_Rendering;
+    }
+
+    if (pdev->OCRStage == OCR_Rendering) {
+        penum->pte_default->can_cache = 0;
+        code = gs_text_process(penum->pte_default);
+        pdev->OCR_char_code = penum->pte_default->returned.current_char;
+        pdev->OCR_glyph = penum->pte_default->returned.current_glyph;
+        gs_text_enum_copy_dynamic(pte, penum->pte_default, true);
+        if (code == TEXT_PROCESS_RENDER)
+            return code;
+        if (code != 0) {
+            gs_free_object(pdev->memory, pdev->OCRSaved,"saved enumerator for OCR");
+            pdev->OCRSaved = NULL;
+            gs_grestore(pte->pgs);
+            gs_text_release(pte->pgs, penum->pte_default, "pdf_text_process");
+            penum->pte_default = NULL;
+            return code;
+        }
+        gs_grestore(pte->pgs);
+        *pte = *(pdev->OCRSaved);
+        gs_text_enum_copy_dynamic(pte, pdev->OCRSaved, true);
+        gs_free_object(pdev->memory, pdev->OCRSaved,"saved enumerator for OCR");
+        pdev->OCRSaved = NULL;
+        gs_text_release(pte->pgs, penum->pte_default, "pdf_text_process");
+        penum->pte_default = NULL;
+        pdev->OCRStage = OCR_Rendered;
+    }
+    return 0;
+}
+
 /*
  * Continue processing text.  This is the 'process' procedure in the text
  * enumerator.  Per the check in pdf_text_begin, we know the operation is
@@ -3142,7 +3230,7 @@ pdf_text_process(gs_text_enum_t *pte)
 {
     pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
     uint operation = pte->text.operation;
-    uint size = pte->text.size - pte->index;
+    uint size = 0;
     gs_text_enum_t *pte_default;
     PROCESS_TEXT_PROC((*process));
     int code = 0, early_accumulator = 0;
@@ -3187,6 +3275,15 @@ pdf_text_process(gs_text_enum_t *pte)
             goto default_impl;
     }
 
+    if (pdev->UseOCR != UseOCRNever) {
+        code = ProcessTextForOCR(pte);
+        if (code != 0)
+            return code;
+    }
+
+    operation = pte->text.operation;
+    size = pte->text.size - pte->index;
+
     code = -1;                /* to force default implementation */
 
     /*
@@ -3352,10 +3449,13 @@ pdf_text_process(gs_text_enum_t *pte)
                 pdev->procs.get_initial_matrix = pdf_type3_get_initial_matrix;
 
                 pdev->pte = (gs_text_enum_t *)penum; /* CAUTION: See comment in gdevpdfx.h . */
+                /* In case of error, text_process will restore back to the enumerator 'level'
+                 * we must make certain we do not restore back too far!
+                 */
+                pte_default->level = penum->pgs->level;
                 code = gs_text_process(pte_default);
                 if (code < 0) {
                     (void)complete_charproc(pdev, pte, pte_default, penum, false);
-                    gs_grestore(pgs);
                     return code;
                 }
                 pdev->pte = NULL;         /* CAUTION: See comment in gdevpdfx.h . */
@@ -3524,9 +3624,10 @@ pdf_text_process(gs_text_enum_t *pte)
         }
 
         gs_text_enum_copy_dynamic(pte, pte_default, true);
+
         if (code)
             return code;
-        gs_text_release(pte_default, "pdf_text_process");
+        gs_text_release(NULL, pte_default, "pdf_text_process");
         penum->pte_default = 0;
         if (pdev->type3charpath)
             pdev->type3charpath = false;
diff --git a/devices/vector/gdevpdtt.h b/devices/vector/gdevpdtt.h
index 9a710151..9d25d48c 100644
--- a/devices/vector/gdevpdtt.h
+++ b/devices/vector/gdevpdtt.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtv.c b/devices/vector/gdevpdtv.c
index a16a48d7..47b9d798 100644
--- a/devices/vector/gdevpdtv.c
+++ b/devices/vector/gdevpdtv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtv.h b/devices/vector/gdevpdtv.h
index 5e27ecd1..54db170c 100644
--- a/devices/vector/gdevpdtv.h
+++ b/devices/vector/gdevpdtv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtw.c b/devices/vector/gdevpdtw.c
index 6d197bd5..19438685 100644
--- a/devices/vector/gdevpdtw.c
+++ b/devices/vector/gdevpdtw.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtw.h b/devices/vector/gdevpdtw.h
index 34feeed2..0bf3526d 100644
--- a/devices/vector/gdevpdtw.h
+++ b/devices/vector/gdevpdtw.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtx.h b/devices/vector/gdevpdtx.h
index d5fe6177..43ecca3d 100644
--- a/devices/vector/gdevpdtx.h
+++ b/devices/vector/gdevpdtx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsdf.h b/devices/vector/gdevpsdf.h
index a20c61b0..700278e2 100644
--- a/devices/vector/gdevpsdf.h
+++ b/devices/vector/gdevpsdf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsdi.c b/devices/vector/gdevpsdi.c
index f093edf1..8ac9735a 100644
--- a/devices/vector/gdevpsdi.c
+++ b/devices/vector/gdevpsdi.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -33,12 +33,6 @@
 #include "spngpx.h"
 #include "szlibx.h"
 #include "gsicc_manage.h"
-#ifdef USE_LDF_JB2
-#include "sjbig2_luratech.h"
-#endif
-#ifdef USE_LWF_JP2
-#include "sjpx_luratech.h"
-#endif
 #include "sisparam.h"
 
 /* Define parameter-setting procedures. */
@@ -250,10 +244,6 @@ setup_image_compression(psdf_binary_writer *pbw, const psdf_image_params *pdip,
     stream_state *st;
     int code;
 
-#   ifdef USE_LWF_JP2
-    if (lossless && templat == &s_jpxe_template && !Indexed)
-        lossless_template = &s_jpxe_template;
-#   endif
     if (!pdip->Encode)		/* no compression */
         return 0;
     if (pdip->AutoFilter) {
@@ -356,41 +346,6 @@ setup_image_compression(psdf_binary_writer *pbw, const psdf_image_params *pdip,
             goto fail;
         /* psdf_DCT_filter already did the psdf_encode_binary. */
         return 0;
-    } else {
-#	ifdef USE_LDF_JB2
-            if (templat == &s_jbig2encode_template) {
-                stream_jbig2encode_state *state = (stream_jbig2encode_state *)st;
-
-                state->width = pim->Width;
-                state->height = pim->Height;
-            }
-#	endif
-#	ifdef USE_LWF_JP2
-            if (templat == &s_jpxe_template) {
-                stream_jpxe_state *state = (stream_jpxe_state *)st;
-                int ncomps = pim->ColorSpace->type->num_components(pim->ColorSpace);
-
-                /* HACK : We choose a JPX color space from the number of components :
-                   CIEBasedA goes as gs_jpx_cs_gray,
-                   CIEBasedABC and DeviceN(3) go as gs_jpx_cs_rgb,
-                   CIEBasedABCD and DeviceN(4) go as gs_jpx_cs_cmyk.
-                */
-                switch (ncomps) {
-                    case 1 : state->colorspace = gs_jpx_cs_gray; break;
-                    case 3 : state->colorspace = gs_jpx_cs_rgb; break;
-                    case 4 : state->colorspace = gs_jpx_cs_cmyk; break;
-                    default:
-                        return_error(gs_error_unregistered); /* Must not happen. */
-                }
-                state->width = pim->Width;
-                state->height = pim->Height;
-                state->bpc = pim->BitsPerComponent;
-                state->components = ncomps;
-                state->lossless = lossless;
-                /* Other encode parameters are not implemented yet.
-                   Therefore ACSDict is being ignored. */
-            }
-#	endif
     }
     code = psdf_encode_binary(pbw, templat, st);
     if (code >= 0)
@@ -600,39 +555,6 @@ psdf_is_converting_image_to_RGB(const gx_device_psdf * pdev,
             gs_color_space_index_DeviceCMYK));
 }
 
-static inline void
-adjust_auto_filter_strategy(gx_device_psdf *pdev,
-                psdf_image_params *params, gs_c_param_list *plist,
-                const gs_pixel_image_t * pim, bool in_line)
-{
-#ifdef USE_LWF_JP2
-    if (!in_line && params->Depth > 1 && pdev->ParamCompatibilityLevel >= 1.5 &&
-            pim->ColorSpace->type->index != gs_color_space_index_Indexed &&
-            params->AutoFilter &&
-            params->AutoFilterStrategy != af_Jpeg) {
-        params->Filter = "/JPXEncode";
-        params->filter_template = &s_jpxe_template;
-        params->Dict = plist;
-    }
-#endif
-}
-
-static inline void
-adjust_auto_filter_strategy_mono(gx_device_psdf *pdev,
-                psdf_image_params *params, gs_c_param_list *plist,
-                const gs_pixel_image_t * pim, bool in_line)
-{
-#ifdef USE_LDF_JB2
-    if (!in_line && pdev->ParamCompatibilityLevel >= 1.5 &&
-            params->AutoFilter &&
-            pim->ColorSpace->type->index != gs_color_space_index_Indexed) {
-        params->Filter = "/JBIG2Encode";
-        params->filter_template = &s_jbig2encode_template;
-        params->Dict = plist;
-    }
-#endif
-}
-
 /* Set up compression and downsampling filters for an image. */
 /* Note that this may modify the image parameters. */
 int
@@ -714,16 +636,13 @@ psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
                 params.Filter = pdev->params.MonoImage.Filter;
                 params.filter_template = pdev->params.MonoImage.filter_template;
                 params.Dict = pdev->params.MonoImage.Dict;
-                adjust_auto_filter_strategy_mono(pdev, ¶ms, pdev->params.MonoImage.Dict, pim, in_line);
             } else {
                 params.Filter = pdev->params.GrayImage.Filter;
                 params.filter_template = pdev->params.GrayImage.filter_template;
                 params.Dict = pdev->params.GrayImage.Dict;
-                adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.GrayImage.Dict, pim, in_line);
             }
             code = setup_downsampling(pbw, ¶ms, pim, pgs, resolution, lossless);
         } else {
-            adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.GrayImage.Dict, pim, in_line);
             code = setup_image_compression(pbw, ¶ms, pim, pgs, lossless);
         }
         if (code < 0)
@@ -745,10 +664,8 @@ psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
         if (params.Depth == -1)
             params.Depth = (cmyk_to_rgb ? 8 : bpc_out);
         if (do_downsample(¶ms, pim, resolution)) {
-            adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.ColorImage.Dict, pim, in_line);
             code = setup_downsampling(pbw, ¶ms, pim, pgs, resolution, lossless);
         } else {
-            adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.ColorImage.Dict, pim, in_line);
             code = setup_image_compression(pbw, ¶ms, pim, pgs, lossless);
         }
         if (code < 0)
@@ -981,17 +898,16 @@ new_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
                 params.Filter = pdev->params.MonoImage.Filter;
                 params.filter_template = pdev->params.MonoImage.filter_template;
                 params.Dict = pdev->params.MonoImage.Dict;
-                adjust_auto_filter_strategy_mono(pdev, ¶ms, pdev->params.MonoImage.Dict, pim, in_line);
             } else {
+                if (params.Depth > 8)
+                    params.Depth = bpc_out;
                 params.Filter = pdev->params.GrayImage.Filter;
                 params.filter_template = pdev->params.GrayImage.filter_template;
                 params.Dict = pdev->params.GrayImage.Dict;
-                adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.GrayImage.Dict, pim, in_line);
             }
             pdev->JPEG_PassThrough = 0;
             code = setup_downsampling(pbw, ¶ms, pim, pgs, resolution, lossless);
         } else {
-            adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.GrayImage.Dict, pim, in_line);
             code = setup_image_compression(pbw, ¶ms, pim, pgs, lossless);
         }
         if (code < 0)
@@ -1002,11 +918,9 @@ new_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
         if (params.Depth == -1)
             params.Depth = (colour_conversion ? 8 : bpc_out);
         if (do_downsample(¶ms, pim, resolution)) {
-            adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.ColorImage.Dict, pim, in_line);
             pdev->JPEG_PassThrough = 0;
             code = setup_downsampling(pbw, ¶ms, pim, pgs, resolution, lossless);
         } else {
-            adjust_auto_filter_strategy(pdev, ¶ms, pdev->params.ColorImage.Dict, pim, in_line);
             code = setup_image_compression(pbw, ¶ms, pim, pgs, lossless);
         }
         if (code < 0)
diff --git a/devices/vector/gdevpsdp.c b/devices/vector/gdevpsdp.c
index c8a48ee5..d995dc5c 100644
--- a/devices/vector/gdevpsdp.c
+++ b/devices/vector/gdevpsdp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -30,12 +30,6 @@
 #include "srlx.h"
 #include "szlibx.h"
 #include "gdevvec.h"
-#ifdef USE_LDF_JB2
-#include "sjbig2_luratech.h"
-#endif
-#ifdef USE_LWF_JP2
-#include "sjpx_luratech.h"
-#endif
 
 /* Define a (bogus) GC descriptor for gs_param_string. */
 /* The only ones we use are GC-able and not persistent. */
@@ -98,9 +92,6 @@ static const psdf_image_filter_name Poly_filters[] = {
     {"DCTEncode", &s_DCTE_template},
     {"FlateEncode", &s_zlibE_template, psdf_version_ll3},
     {"LZWEncode", &s_LZWE_template},
-#ifdef USE_LWF_JP2
-    {"JPXEncode", &s_jpxe_template},
-#endif
     {0, 0}
 };
 
@@ -109,9 +100,6 @@ static const psdf_image_filter_name Mono_filters[] = {
     {"FlateEncode", &s_zlibE_template, psdf_version_ll3},
     {"LZWEncode", &s_LZWE_template},
     {"RunLengthEncode", &s_RLE_template},
-#ifdef USE_LDF_JB2
-    {"JBIG2Encode", &s_jbig2encode_template},
-#endif
     {0, 0}
 };
 
@@ -415,12 +403,6 @@ int gdev_psdf_get_image_param(gx_device_psdf *pdev, const psdf_image_param_names
                                    (params->Filter == 0 ?
                                     image_names->filter_names[0].pname :
                                     params->Filter));
-#ifdef USE_LWF_JP2
-    if (image_names->AutoFilterStrategy != 0)
-        if (strcmp(Param, image_names->AutoFilterStrategy) == 0)
-            return psdf_write_name(plist, image_names->AutoFilterStrategy,
-                    AutoFilterStrategy_names[params->AutoFilterStrategy]);
-#endif
     return_error(gs_error_undefined);
 }
 int
@@ -1055,11 +1037,8 @@ psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist,
  */
 static int psdf_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist, gs_param_string_array *sa, gs_param_string_array *da)
 {
-    int code;
-
     if (sa->size > 0) {
         int ix;
-        byte **dest;
 
         if (da->data != NULL) {
             for (ix = 0; ix < da->size;ix++)
@@ -1088,7 +1067,7 @@ static int psdf_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist,
     return 0;
 }
 
-static int psdf_read_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist, char *Key, gs_param_string_array *da)
+static int psdf_read_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist, const char *Key, gs_param_string_array *da)
 {
     gs_param_string_array sa;
     int code;
diff --git a/devices/vector/gdevpsds.c b/devices/vector/gdevpsds.c
index bc932902..6be0dd67 100644
--- a/devices/vector/gdevpsds.c
+++ b/devices/vector/gdevpsds.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsds.h b/devices/vector/gdevpsds.h
index 207e54c4..44e2e845 100644
--- a/devices/vector/gdevpsds.h
+++ b/devices/vector/gdevpsds.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsdu.c b/devices/vector/gdevpsdu.c
index c4be6ac0..c4957691 100644
--- a/devices/vector/gdevpsdu.c
+++ b/devices/vector/gdevpsdu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -408,8 +408,8 @@ psdf_DCT_filter(gs_param_list *plist /* may be NULL */,
         /* Make sure we get at least a full scan line of input. */
         ss->scan_line_size = jcdp->cinfo.input_components *
             jcdp->cinfo.image_width;
-        /* Profile not used in pdfwrite output */        
-        ss->icc_profile = NULL; 
+        /* Profile not used in pdfwrite output */
+        ss->icc_profile = NULL;
         jcdp->templat.min_in_size =
             max(s_DCTE_template.min_in_size, ss->scan_line_size);
         /* Make sure we can write the user markers in a single go. */
@@ -510,10 +510,6 @@ psdf_create_compositor(
     if (gs_is_overprint_compositor(pct)) {
         *pcdev = dev;
         return 0;
-    } else {
-        if (dev->parent)
-            return gx_default_create_compositor(dev->parent, pcdev, pct, pgs, mem, cdev);
-        else
-            return gx_default_create_compositor(dev, pcdev, pct, pgs, mem, cdev);
     }
+    return gx_default_create_compositor(dev, pcdev, pct, pgs, mem, cdev);
 }
diff --git a/devices/vector/gdevpsf.h b/devices/vector/gdevpsf.h
index 9105eb86..6db85801 100644
--- a/devices/vector/gdevpsf.h
+++ b/devices/vector/gdevpsf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -166,6 +166,7 @@ int psf_get_type1_glyphs(psf_outline_glyphs_t *pglyphs,
 #define WRITE_TYPE1_EEXEC_MARK 8  /* assume 512 0s will be added */
 #define WRITE_TYPE1_POSTSCRIPT 16  /* don't observe ATM restrictions */
 #define WRITE_TYPE1_WITH_LENIV 32  /* don't allow lenIV = -1 */
+#define WRITE_TYPE1_XUID 64
 int psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
                          gs_glyph *subset_glyphs, uint subset_size,
                          const gs_const_string *alt_font_name,
@@ -181,6 +182,7 @@ int psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
 #define WRITE_TYPE2_CHARSTRINGS 2 /* convert T1 charstrings to T2 */
 #define WRITE_TYPE2_AR3 4	/* work around bugs in Acrobat Reader 3 */
 #define WRITE_TYPE2_NO_GSUBRS 8	/* omit GlobalSubrs */
+#define WRITE_TYPE2_XUID 16
 int psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
                          gs_glyph *subset_glyphs, uint subset_size,
                          const gs_const_string *alt_font_name,
diff --git a/devices/vector/gdevpsf1.c b/devices/vector/gdevpsf1.c
index feed79eb..672ce241 100644
--- a/devices/vector/gdevpsf1.c
+++ b/devices/vector/gdevpsf1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -75,13 +75,19 @@ write_float_array(gs_param_list *plist, const char *key, const float *values,
 
 /* Write a UniqueID and/or XUID. */
 static void
-write_uid(stream *s, const gs_uid *puid)
+write_uid(stream *s, const gs_uid *puid, int options)
 {
     if (uid_is_UniqueID(puid))
         pprintld1(s, "/UniqueID %ld def\n", puid->id);
-    else if (uid_is_XUID(puid)) {
+    else if (uid_is_XUID(puid) && (options & WRITE_TYPE1_XUID) != 0) {
         uint i, n = uid_XUID_size(puid);
 
+        /* Adobe products (specifically Acrobat but the same limitation is mentioned
+         * in the PLRM) cannot handle XUIDs > 16 entries.
+         */
+        if (n > 16)
+            n = 16;
+
         stream_puts(s, "/XUID [");
         for (i = 0; i < n; ++i)
             pprintld1(s, "%ld ", uid_XUID_values(puid)[i]);
@@ -530,7 +536,7 @@ write_Private(stream *s, gs_font_type1 *pfont,
               gs_glyph *subset_glyphs, uint subset_size,
               gs_glyph notdef, int lenIV,
               int (*write_CharString)(stream *, const void *, uint),
-              const param_printer_params_t *ppp)
+              const param_printer_params_t *ppp, int options)
 {
     const gs_type1_data *const pdata = &pfont->data;
     printer_param_list_t rlist;
@@ -596,7 +602,7 @@ write_Private(stream *s, gs_font_type1 *pfont,
         write_float_array(plist, "StemSnapV", pdata->StemSnapV.values,
                           pdata->StemSnapV.count);
     }
-    write_uid(s, &pfont->UID);
+    write_uid(s, &pfont->UID, options);
     stream_puts(s, "/MinFeature{16 16} def\n");
     stream_puts(s, "/password 5839 def\n");
 
@@ -860,7 +866,7 @@ psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
              pfont->FontMatrix.xx, pfont->FontMatrix.xy,
              pfont->FontMatrix.yx, pfont->FontMatrix.yy,
              pfont->FontMatrix.tx, pfont->FontMatrix.ty);
-    write_uid(s, &pfont->UID);
+    write_uid(s, &pfont->UID, options);
     pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n",
              pfont->FontBBox.p.x, pfont->FontBBox.p.y,
              pfont->FontBBox.q.x, pfont->FontBBox.q.y);
@@ -929,7 +935,7 @@ psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
         stream_puts(es, "****");
     }
     code = write_Private(es, pfont, glyphs.subset_glyphs, glyphs.subset_size,
-                         glyphs.notdef, lenIV, write_CharString, &ppp);
+                         glyphs.notdef, lenIV, write_CharString, &ppp, options);
     if (code < 0)
         return code;
     stream_puts(es, "dup/FontName get exch definefont pop\n");
diff --git a/devices/vector/gdevpsf2.c b/devices/vector/gdevpsf2.c
index 3c38e988..4c56c450 100644
--- a/devices/vector/gdevpsf2.c
+++ b/devices/vector/gdevpsf2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -575,9 +575,14 @@ cff_write_Top_common(cff_writer_t *pcw, gs_font_base *pbfont,
       }
     if (uid_is_UniqueID(&pbfont->UID))
         cff_put_int_value(pcw, pbfont->UID.id, TOP_UniqueID);
-    else if (uid_is_XUID(&pbfont->UID)) {
-        int j;
+    else if (uid_is_XUID(&pbfont->UID) && (pcw->options & WRITE_TYPE2_XUID) != 0) {
+        int j, k = uid_XUID_size(&pbfont->UID);
 
+        /* Adobe products (specifically Acrobat but the same limitation is mentioned
+         * in the PLRM) cannot handle XUIDs > 16 entries.
+         */
+        if (k > 16)
+            k = 16;
         for (j = 0; j < uid_XUID_size(&pbfont->UID); ++j)
             cff_put_int(pcw, uid_XUID_values(&pbfont->UID)[j]);
         cff_put_op(pcw, TOP_XUID);
diff --git a/devices/vector/gdevpsfm.c b/devices/vector/gdevpsfm.c
index b38266c2..fc85c356 100644
--- a/devices/vector/gdevpsfm.c
+++ b/devices/vector/gdevpsfm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsft.c b/devices/vector/gdevpsft.c
index 9bc00312..ae6600be 100644
--- a/devices/vector/gdevpsft.c
+++ b/devices/vector/gdevpsft.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsfu.c b/devices/vector/gdevpsfu.c
index e848bdc8..52bd0395 100644
--- a/devices/vector/gdevpsfu.c
+++ b/devices/vector/gdevpsfu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsfx.c b/devices/vector/gdevpsfx.c
index 43459327..4420422e 100644
--- a/devices/vector/gdevpsfx.c
+++ b/devices/vector/gdevpsfx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsu.c b/devices/vector/gdevpsu.c
index 5e3e5a2b..83b8bdbb 100644
--- a/devices/vector/gdevpsu.c
+++ b/devices/vector/gdevpsu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsu.h b/devices/vector/gdevpsu.h
index c62ed8c6..b5927c2f 100644
--- a/devices/vector/gdevpsu.h
+++ b/devices/vector/gdevpsu.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpx.c b/devices/vector/gdevpx.c
index 5195339f..2002219d 100644
--- a/devices/vector/gdevpx.c
+++ b/devices/vector/gdevpx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -1353,7 +1353,7 @@ pclxl_setdash(gx_device_vector * vdev, const float *pattern, uint count,
             pattern_length += (uint) (pattern[i]);
         if (pattern_length == 0)
             return_error(gs_error_rangecheck);
-        
+
         spputc(s, pxt_uint16_array);
         px_put_ub(s, (byte) count);
         for (i = 0; i < count; ++i)
@@ -2078,7 +2078,7 @@ pclxl_begin_image(gx_device * dev,
             goto use_default;
     }
 
-    /* 
+    /*
      * NOTE: this predicate should be fixed to be readable and easily
      * debugged.  Each condition should be separate.  See the large
      * similar conditional in clist_begin_typed_image which has
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
index d46a935e..687581d5 100644
--- a/devices/vector/gdevtxtw.c
+++ b/devices/vector/gdevtxtw.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -36,30 +36,9 @@
 #include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and obejct filter */
 #include "gxchar.h"
 
-/* #define TRACE_TXTWRITE 1 */
+#include "doc_common.h"
 
-extern single_glyph_list_t SingleGlyphList[];
-extern double_glyph_list_t DoubleGlyphList[];
-extern treble_glyph_list_t TrebleGlyphList[];
-extern quad_glyph_list_t QuadGlyphList[];
-/*
- * Define the structure used to return glyph width information.  Note that
- * there are two different sets of width information: real-number (x,y)
- * values, which give the true advance width, and an integer value, which
- * gives an X advance width for WMode = 0 or a Y advance width for WMode = 1.
- * The return value from txt_glyph_width() indicates which of these is/are
- * valid.
- */
-typedef struct txt_glyph_width_s {
-    double w;
-    gs_point xy;
-    gs_point v;				/* glyph origin shift */
-} txt_glyph_width_t;
-typedef struct txt_glyph_widths_s {
-    txt_glyph_width_t Width;		/* unmodified, for Widths */
-    txt_glyph_width_t real_width;	/* possibly modified, for rendering */
-    bool replaced_v;
-} txt_glyph_widths_t;
+/* #define TRACE_TXTWRITE 1 */
 
 /* Structure to record the Unicode characters, the total width of the text
  * recorded, and various useful attributes such as the font, size, colour
@@ -75,6 +54,8 @@ typedef struct text_list_entry_s {
     gs_point FontBBox_bottomleft, FontBBox_topright;
     float *Widths;
     float *Advs;
+    float *GlyphWidths;
+    float *SpanDeltaX;
     unsigned short *Unicode_Text;
     int Unicode_Text_Size;
     int render_mode;
@@ -150,15 +131,17 @@ typedef struct textw_text_enum_s {
     double cdevproc_result[10];
     float *Widths;
     float *Advs;
+    float *GlyphWidths;
+    float *SpanDeltaX;
     unsigned short *TextBuffer;
     int TextBufferIndex;
     text_list_entry_t *text_state;
 } textw_text_enum_t;
 #define private_st_textw_text_enum()\
   extern_st(st_gs_text_enum);\
-  gs_private_st_suffix_add0(st_textw_text_enum, textw_text_enum_t,\
+  gs_private_st_suffix_add1(st_textw_text_enum, textw_text_enum_t,\
     "textw_text_enum_t", textw_text_enum_enum_ptrs, textw_text_enum_reloc_ptrs,\
-    st_gs_text_enum)
+    st_gs_text_enum, pte_fallback)
 
 private_st_textw_text_enum();
 
@@ -435,16 +418,30 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
 
             if (to->start.x - from->end.x < average_width / 2) {
                 /* consolidate fragments */
-                unsigned short *NewText;
-                float *NewWidths;
+                unsigned short *NewText = NULL;
+                float *NewWidths = NULL, *NewAdvs = NULL, *NewGlyphWidths = NULL, *NewSpanDeltaX = NULL;
 
                 NewText = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
                     (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(unsigned short), "txtwrite alloc working text buffer");
                 NewWidths = (float *)gs_malloc(tdev->memory->stable_memory,
                     (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc Widths array");
-                if (!NewText || !NewWidths) {
+                NewAdvs = (float *)gs_malloc(tdev->memory->stable_memory,
+                    (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc Advs array");
+                NewGlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+                    (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc GlyphWidths array");
+                NewSpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+                    (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc SpanDeltaX array");
+                if (!NewText || !NewWidths || !NewAdvs || !NewGlyphWidths || !NewSpanDeltaX) {
                     if (NewText)
                         gs_free(tdev->memory, NewText, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                    if (NewWidths)
+                        gs_free(tdev->memory, NewWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                    if (NewAdvs)
+                        gs_free(tdev->memory, NewAdvs, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                    if (NewGlyphWidths)
+                        gs_free(tdev->memory, NewGlyphWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                    if (NewSpanDeltaX)
+                        gs_free(tdev->memory, NewSpanDeltaX, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
                     /* ran out of memory, don't consolidate */
                     from = from->next;
                     to = to->next;
@@ -459,14 +456,31 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
                     memcpy(&NewText[from->Unicode_Text_Size], to->Unicode_Text, to->Unicode_Text_Size * sizeof(unsigned short));
                     memcpy(NewWidths, from->Widths, from->Unicode_Text_Size * sizeof(float));
                     memcpy(&NewWidths[from->Unicode_Text_Size], to->Widths, to->Unicode_Text_Size * sizeof(float));
+                    memcpy(NewAdvs, from->Advs, from->Unicode_Text_Size * sizeof(float));
+                    memcpy(&NewAdvs[from->Unicode_Text_Size], to->Advs, to->Unicode_Text_Size * sizeof(float));
+                    memcpy(NewGlyphWidths, from->GlyphWidths, from->Unicode_Text_Size * sizeof(float));
+                    memcpy(&NewGlyphWidths[from->Unicode_Text_Size], to->GlyphWidths, to->Unicode_Text_Size * sizeof(float));
+                    memcpy(NewSpanDeltaX, from->SpanDeltaX, from->Unicode_Text_Size * sizeof(float));
+                    memcpy(&NewSpanDeltaX[from->Unicode_Text_Size], to->SpanDeltaX, to->Unicode_Text_Size * sizeof(float));
+
                     gs_free(tdev->memory, from->Unicode_Text, from->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
                     gs_free(tdev->memory, to->Unicode_Text, to->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
                     gs_free(tdev->memory, from->Widths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
                     gs_free(tdev->memory, to->Widths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                    gs_free(tdev->memory, from->Advs, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                    gs_free(tdev->memory, to->Advs, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                    gs_free(tdev->memory, from->GlyphWidths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                    gs_free(tdev->memory, to->GlyphWidths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                    gs_free(tdev->memory, from->SpanDeltaX, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                    gs_free(tdev->memory, to->SpanDeltaX, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
                     gs_free(tdev->memory, to->FontName, 1, strlen(from->FontName) + 1, "free FontName");
+
                     from->Unicode_Text = NewText;
                     from->Unicode_Text_Size += to->Unicode_Text_Size;
                     from->Widths = NewWidths;
+                    from->Advs = NewAdvs;
+                    from->GlyphWidths = NewGlyphWidths;
+                    from->SpanDeltaX = NewSpanDeltaX;
 #ifdef TRACE_TXTWRITE
                     gp_fprintf(tdev->DebugFile, "After:\n\t");
                     gp_fwrite(from->Unicode_Text, sizeof(unsigned short), from->Unicode_Text_Size, tdev->DebugFile);
@@ -480,16 +494,30 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
                 }
             } else {
                 if (to->start.x - from->end.x < average_width *2){
-                    unsigned short *NewText;
-                    float *NewWidths;
+                    unsigned short *NewText = NULL;
+                    float *NewWidths = NULL, *NewAdvs = NULL, *NewGlyphWidths = NULL, *NewSpanDeltaX = NULL;
 
                     NewText = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
                         (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(unsigned short), "txtwrite alloc text state");
                     NewWidths = (float *)gs_malloc(tdev->memory->stable_memory,
                         (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc Widths array");
-                    if (!NewText || !NewWidths) {
+                    NewAdvs = (float *)gs_malloc(tdev->memory->stable_memory,
+                        (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc Advs array");
+                    NewGlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+                        (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc GlyphWidths array");
+                    NewSpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+                        (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc SpanDeltaX array");
+                    if (!NewText || !NewWidths || !NewAdvs || !NewGlyphWidths || !NewSpanDeltaX) {
                         if (NewText)
                             gs_free(tdev->memory, NewText, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                        if (NewWidths)
+                            gs_free(tdev->memory, NewWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                        if (NewAdvs)
+                            gs_free(tdev->memory, NewAdvs, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                        if (NewGlyphWidths)
+                            gs_free(tdev->memory, NewGlyphWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+                        if (NewSpanDeltaX)
+                            gs_free(tdev->memory, NewSpanDeltaX, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
                         /* ran out of memory, don't consolidate */
                         from = from->next;
                         to = to->next;
@@ -500,14 +528,34 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
                         memcpy(NewWidths, from->Widths, from->Unicode_Text_Size * sizeof(float));
                         NewWidths[from->Unicode_Text_Size] = to->start.x - from->end.x;
                         memcpy(&NewWidths[from->Unicode_Text_Size + 1], to->Widths, to->Unicode_Text_Size * sizeof(float));
+                        memcpy(NewAdvs, from->Advs, from->Unicode_Text_Size * sizeof(float));
+                        NewAdvs[from->Unicode_Text_Size] = to->start.x - from->end.x;
+                        memcpy(&NewAdvs[from->Unicode_Text_Size + 1], to->Advs, to->Unicode_Text_Size * sizeof(float));
+                        memcpy(NewGlyphWidths, from->GlyphWidths, from->Unicode_Text_Size * sizeof(float));
+                        NewGlyphWidths[from->Unicode_Text_Size] = 0.0;
+                        memcpy(&NewGlyphWidths[from->Unicode_Text_Size + 1], to->GlyphWidths, to->Unicode_Text_Size * sizeof(float));
+                        memcpy(NewSpanDeltaX, from->SpanDeltaX, from->Unicode_Text_Size * sizeof(float));
+                        NewSpanDeltaX[from->Unicode_Text_Size] = 0;
+                        memcpy(&NewSpanDeltaX[from->Unicode_Text_Size + 1], to->SpanDeltaX, to->Unicode_Text_Size * sizeof(float));
+
                         gs_free(tdev->memory, from->Unicode_Text, from->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
                         gs_free(tdev->memory, to->Unicode_Text, to->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
                         gs_free(tdev->memory, from->Widths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
                         gs_free(tdev->memory, to->Widths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                        gs_free(tdev->memory, from->Advs, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                        gs_free(tdev->memory, to->Advs, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                        gs_free(tdev->memory, from->GlyphWidths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                        gs_free(tdev->memory, to->GlyphWidths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                        gs_free(tdev->memory, from->SpanDeltaX, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+                        gs_free(tdev->memory, to->SpanDeltaX, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
                         gs_free(tdev->memory, to->FontName, 1, strlen(from->FontName) + 1, "free FontName");
+
                         from->Unicode_Text = NewText;
                         from->Unicode_Text_Size += to->Unicode_Text_Size + 1;
                         from->Widths = NewWidths;
+                        from->Advs = NewAdvs;
+                        from->GlyphWidths = NewGlyphWidths;
+                        from->SpanDeltaX = NewSpanDeltaX;
                         from->end = to->end;
                         from->next = to->next;
                         if (from->next)
@@ -839,34 +887,54 @@ static int decorated_text_output(gx_device_txtwrite_t *tdev)
 static int extract_text_output(gx_device_txtwrite_t *tdev)
 {
     text_list_entry_t* entry;
+    gp_fprintf(tdev->file, "\n");
     gp_fprintf(tdev->file, "\n");
     for (entry = tdev->PageData.unsorted_text_list;
             entry;
             entry = entry->next
             ) {
-        float x = entry->start.x;
+
         int i;
-        gp_fprintf(tdev->file,
-                "\n",
-                entry->start.x,
-                entry->start.y,
-                entry->end.x,
-                entry->end.y,
-                entry->FontName,
-                entry->size
+        float x = entry->start.x - entry->matrix.tx;
+        gp_fprintf(tdev->file, "file, " ctm=\"%f %f %f %f %f %f\"",
+                entry->matrix.xx,
+                entry->matrix.xy,
+                entry->matrix.yx,
+                entry->matrix.yy,
+                entry->matrix.tx,
+                entry->matrix.ty
+                );
+        gp_fprintf(tdev->file, " ctm_orig=\"%f %f %f %f %f %f\"",
+                entry->matrix.xx,
+                entry->matrix.xy,
+                entry->matrix.yx,
+                entry->matrix.yy,
+                entry->matrix.tx,
+                entry->matrix.ty
+                );
+        gp_fprintf(tdev->file, " trm=\"%lf %f %f %lf %f %f\"",
+                entry->size,
+                0.0f,
+                0.0f,
+                entry->size,
+                0.0f,
+                0.0f
                 );
+        gp_fprintf(tdev->file, " len=\"%i\"", entry->Unicode_Text_Size);
+        gp_fprintf(tdev->file, " wmode=\"%i\"", entry->wmode);
+        gp_fprintf(tdev->file, " font_name=\"%s\"", entry->FontName);
+        gp_fprintf(tdev->file, ">\n");
         for (i=0; iUnicode_Text_Size; i++) {
-            float x_next = x + entry->Widths[i];
-            char escaped[32];
-            escaped_Unicode(entry->Unicode_Text[i], escaped);
+            float x_next = x + entry->SpanDeltaX[i];
+            int c = entry->Unicode_Text[i];
             gp_fprintf(tdev->file,
-                    "\n",
+                    "\n",
                     x,
-                    entry->start.y,
-                    x_next,
-                    entry->end.y,
-                    escaped,
-                    entry->Advs[i]
+                    entry->start.y - entry->matrix.ty,
+                    (c >= 32 && c < 127 && c != '"') ? c : '.',
+                    c,
+                    entry->GlyphWidths[i] / entry->size
                     );
             x = x_next;
         }
@@ -935,6 +1003,8 @@ txtwrite_output_page(gx_device * dev, int num_copies, int flush)
             gs_free(tdev->memory, x_entry->Unicode_Text, x_entry->Unicode_Text_Size, sizeof (usnigned short), "txtwrite free text fragment text buffer");
             gs_free(tdev->memory, x_entry->Widths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
             gs_free(tdev->memory, x_entry->Advs, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
+            gs_free(tdev->memory, x_entry->GlyphWidths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
+            gs_free(tdev->memory, x_entry->SpanDeltaX, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
             gs_free(tdev->memory, x_entry->FontName, 1, strlen(x_entry->FontName) + 1, "txtwrite free Font Name");
             if (x_entry->next) {
                 x_entry = x_entry->next;
@@ -961,6 +1031,8 @@ txtwrite_output_page(gx_device * dev, int num_copies, int flush)
         gs_free(tdev->memory, x_entry->Unicode_Text, x_entry->Unicode_Text_Size, sizeof (usnigned short), "txtwrite free unsorted text fragment text buffer");
         gs_free(tdev->memory, x_entry->Widths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
         gs_free(tdev->memory, x_entry->Advs, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
+        gs_free(tdev->memory, x_entry->GlyphWidths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
+        gs_free(tdev->memory, x_entry->SpanDeltaX, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
         gs_free(tdev->memory, x_entry->FontName, 1, strlen(x_entry->FontName) + 1, "txtwrite free Font Name");
         gs_free(tdev->memory, x_entry, 1, sizeof(text_list_entry_t), "txtwrite free unsorted text fragment");
         x_entry = next_x;
@@ -1231,134 +1303,6 @@ txtwrite_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
 
 /* ------ Text imaging ------ */
 
-static int
-txtwrite_font_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
-{
-    int code;
-
-    switch (font->FontType) {
-    case ft_composite:                /* subfonts have their own FontMatrix */
-    case ft_TrueType:
-    case ft_CID_TrueType:
-        /* The TrueType FontMatrix is 1 unit per em, which is what we want. */
-        gs_make_identity(pmat);
-        return 0;
-    case ft_encrypted:
-    case ft_encrypted2:
-    case ft_CID_encrypted:
-    case ft_user_defined:
-    case ft_PCL_user_defined:
-    case ft_GL2_stick_user_defined:
-    case ft_GL2_531:
-        /*
-         * Type 1 fonts are supposed to use a standard FontMatrix of
-         * [0.001 0 0 0.001 0 0], with a 1000-unit cell.  However,
-         * Windows NT 4.0 creates Type 1 fonts, apparently derived from
-         * TrueType fonts, that use a 2048-unit cell and corresponding
-         * FontMatrix.  Also, some PS programs perform font scaling by
-         * replacing FontMatrix like this :
-         *
-         *   /f12 /Times-Roman findfont
-         *   copyfont          % (remove FID)
-         *   dup /FontMatrix [0.012 0 0 0.012 0 0] put
-         *   definefont
-         *   /f12 1 selectfont
-         *
-         * Such fonts are their own "base font", but the orig_matrix
-         * must still be set to 0.001, not 0.012 .
-         *
-         * The old code used a heuristic to detect and correct for this here.
-         * Unfortunately it doesn't work properly when it meets a font
-         * with FontMatrix like this :
-         *
-         *   /FontMatrix [1 2288 div 0 0 1 2288 div 0 0 ] def
-         *
-         * (the bug 686970). Also comparefiles\455690.pdf appears to
-         * have similar problem. Therefore we added a support to lib/gs_fonts.ps,
-         * src/zbfont.c, src/gsfont.c that provides an acces to the original
-         * font via a special key OrigFont added to the font dictionary while definefont.
-         * Now we work through this access with PS interpreter,
-         * but keep the old heuristic for other clients.
-         */
-        {
-            const gs_font *base_font = font;
-
-            while (base_font->base != base_font)
-                base_font = base_font->base;
-            if (font->FontType == ft_user_defined ||
-                font->FontType == ft_PCL_user_defined ||
-                font->FontType == ft_GL2_stick_user_defined ||
-                font->FontType == ft_GL2_531)
-                *pmat = base_font->FontMatrix;
-            else if (base_font->orig_FontMatrix.xx != 0 || base_font->orig_FontMatrix.xy != 0 ||
-                base_font->orig_FontMatrix.yx != 0 || base_font->orig_FontMatrix.yy != 0)
-                *pmat = base_font->orig_FontMatrix;
-            else {
-                /*  Must not happen with PS interpreter.
-                    Provide a hewuristic for other clients.
-                */
-                if (base_font->FontMatrix.xx == 1.0/2048 &&
-                    base_font->FontMatrix.xy == 0 &&
-                    base_font->FontMatrix.yx == 0 &&
-                    any_abs(base_font->FontMatrix.yy) == 1.0/2048
-                    )
-                    *pmat = base_font->FontMatrix;
-                else
-                    gs_make_scaling(0.001, 0.001, pmat);
-            }
-        }
-        if (font->FontType == ft_CID_encrypted && cid != -1) {
-            int fidx;
-
-            if (cid < GS_MIN_CID_GLYPH)
-                cid = GS_MIN_CID_GLYPH;
-            code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
-                                cid, NULL, &fidx);
-            if (code < 0) {
-                code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
-                                (gs_glyph)GS_MIN_CID_GLYPH, NULL, &fidx);
-            }
-            if (code >= 0) {
-                gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
-                                pmat, pmat);
-            }
-        }
-        return 0;
-    default:
-        return_error(gs_error_rangecheck);
-    }
-}
-
-/*
- * Special version of txtwrite_font_orig_matrix(), that considers FDArray font's FontMatrix too.
- * Called only by txt_glyph_width().
- * 'cid' is only consulted if 'font' is a CIDFontType 0 CID font.
- */
-static int
-glyph_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
-{
-    int code = txtwrite_font_orig_matrix(font, cid, pmat);
-    if (code >= 0) {
-        if (font->FontType == ft_CID_encrypted) {
-            int fidx;
-
-            if (cid < GS_MIN_CID_GLYPH)
-                cid = GS_MIN_CID_GLYPH;
-            code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
-                                cid, NULL, &fidx);
-            if (code < 0) {
-                code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
-                                (gs_glyph)GS_MIN_CID_GLYPH, NULL, &fidx);
-            }
-            if (code >= 0) {
-                gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
-                                pmat, pmat);
-            }
-        }
-    }
-    return code;
-}
-
 /*
  * Compute the cached values in the text processing state from the text
  * parameters, current_font, and pgs->ctm.  Return either an error code (<
@@ -1389,42 +1333,6 @@ transform_delta_inverse(const gs_point *pdelta, const gs_matrix *pmat,
     return 0;
 }
 
-static
-float txt_calculate_text_size(gs_gstate *pgs, gs_font *ofont,
-                              const gs_matrix *pfmat, gs_matrix *smat, gs_matrix *tmat,
-                              gs_font *font, gx_device *pdev)
-{
-    gs_matrix orig_matrix;
-    double
-        sx = pdev->HWResolution[0] / 72.0,
-        sy = pdev->HWResolution[1] / 72.0;
-    float size;
-
-    /* Get the original matrix of the base font. */
-
-    txtwrite_font_orig_matrix(ofont, -1, &orig_matrix);
-    /* Compute the scaling matrix and combined matrix. */
-
-    if (gs_matrix_invert(&orig_matrix, smat) < 0) {
-        gs_make_identity(smat);
-        return 1; /* Arbitrary */
-    }
-    gs_matrix_multiply(smat, pfmat, smat);
-    *tmat = ctm_only(pgs);
-    tmat->tx = tmat->ty = 0;
-    gs_matrix_multiply(smat, tmat, tmat);
-
-    /* Try to find a reasonable size value. */
-
-    size = hypot(tmat->yx, tmat->yy) / sy;
-    if (size < 0.01)
-        size = hypot(tmat->xx, tmat->xy) / sx;
-    if (size < 0.01)
-        size = 1;
-
-    return(size);
-}
-
 static int
 txt_update_text_state(text_list_entry_t *ppts,
                       const textw_text_enum_t *penum,
@@ -1474,13 +1382,6 @@ txt_update_text_state(text_list_entry_t *ppts,
 
     ppts->size = size;
     ppts->matrix = tmat;
-    ppts->render_mode = penum->pgs->text_rendering_mode;
-    ppts->FontName = (char *)gs_malloc(pdev->memory->stable_memory, 1,
-        font->font_name.size + 1, "txtwrite alloc font name");
-    if (!ppts->FontName)
-        return gs_note_error(gs_error_VMerror);
-    memcpy(ppts->FontName, font->font_name.chars, font->font_name.size);
-    ppts->FontName[font->font_name.size] = 0x00;
     ppts->render_mode = font->WMode;
 
     if (font->PaintType == 2 && penum->pgs->text_rendering_mode == 0)
@@ -1512,227 +1413,6 @@ txt_update_text_state(text_list_entry_t *ppts,
     return (code < 0 ? code : mask);
 }
 
-static int
-store_glyph_width(txt_glyph_width_t *pwidth, int wmode, const gs_matrix *scale,
-                  const gs_glyph_info_t *pinfo)
-{
-    double w, v;
-
-    gs_distance_transform(pinfo->width[wmode].x, pinfo->width[wmode].y, scale, &pwidth->xy);
-    if (wmode)
-        w = pwidth->xy.y, v = pwidth->xy.x;
-    else
-        w = pwidth->xy.x, v = pwidth->xy.y;
-    if (v != 0)
-        return 1;
-    pwidth->w = w;
-    gs_distance_transform(pinfo->v.x, pinfo->v.y, scale, &pwidth->v);
-    return 0;
-}
-
-static int
-get_missing_width(gs_font *font, int wmode, const gs_matrix *scale_c,
-                    txt_glyph_widths_t *pwidths)
-{
-    gs_font_info_t finfo;
-    int code;
-
-    code = font->procs.font_info((gs_font *)font, NULL,
-                                  FONT_INFO_MISSING_WIDTH, &finfo);
-    if (code < 0)
-        return code;
-    if (!(finfo.members & FONT_INFO_MISSING_WIDTH))
-        return_error(gs_error_undefined);
-
-    if (wmode) {
-        gs_distance_transform(0.0, -finfo.MissingWidth, scale_c, &pwidths->real_width.xy);
-        pwidths->Width.xy.x = 0;
-        pwidths->Width.xy.y = pwidths->real_width.xy.y;
-        pwidths->Width.w = pwidths->real_width.w =
-                pwidths->Width.xy.y;
-        pwidths->Width.v.x = - pwidths->Width.xy.y / 2;
-        pwidths->Width.v.y = - pwidths->Width.xy.y;
-    } else {
-        gs_distance_transform(finfo.MissingWidth, 0.0, scale_c, &pwidths->real_width.xy);
-        pwidths->Width.xy.x = pwidths->real_width.xy.x;
-        pwidths->Width.xy.y = 0;
-        pwidths->Width.w = pwidths->real_width.w =
-                pwidths->Width.xy.x;
-        pwidths->Width.v.x = pwidths->Width.v.y = 0;
-    }
-    /*
-     * Don't mark the width as known, just in case this is an
-     * incrementally defined font.
-     */
-    return 1;
-}
-
-/*
- * Get the widths (unmodified from the copied font,
- * and possibly modified from the original font) of a given glyph.
- * Return 1 if the width was defaulted to MissingWidth.
- * Return TEXT_PROCESS_CDEVPROC if a CDevProc callout is needed.
- * cdevproc_result != NULL if we restart after a CDevProc callout.
- */
-static int
-txt_glyph_widths(gs_font *font, int wmode, gs_glyph glyph,
-                 gs_font *orig_font, txt_glyph_widths_t *pwidths,
-                 const double cdevproc_result[10])
-{
-    gs_font *ofont = orig_font;
-    gs_glyph_info_t info;
-    gs_matrix scale_c, scale_o;
-    int code, rcode = 0;
-    gs_point v;
-    int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType
-                || orig_font->FontType == ft_CID_encrypted
-                ? GLYPH_INFO_CDEVPROC : 0); /* fixme : allow more font types. */
-
-    if (ofont->FontType == ft_composite)
-        return_error(gs_error_unregistered); /* Must not happen. */
-    code = glyph_orig_matrix((const gs_font *)font, glyph, &scale_c);
-    if (code < 0)
-        return code;
-    code = glyph_orig_matrix(ofont, glyph, &scale_o);
-    if (code < 0)
-        return code;
-    gs_matrix_scale(&scale_c, 1000.0, 1000.0, &scale_c);
-    gs_matrix_scale(&scale_o, 1000.0, 1000.0, &scale_o);
-    pwidths->Width.v.x = pwidths->Width.v.y = 0;
-    pwidths->real_width.v.x = pwidths->real_width.v.y = 0;
-    pwidths->replaced_v = false;
-    if (glyph == GS_NO_GLYPH)
-        return get_missing_width(font, wmode, &scale_c, pwidths);
-    code = font->procs.glyph_info((gs_font *)font, glyph, NULL,
-                                    GLYPH_INFO_WIDTH0 |
-                                    (GLYPH_INFO_WIDTH0 << wmode) |
-                                    GLYPH_INFO_OUTLINE_WIDTHS |
-                                    (GLYPH_INFO_VVECTOR0 << wmode),
-                                    &info);
-    /* For CID fonts the PDF spec requires the x-component of v-vector
-       to be equal to half glyph width, and AR5 takes it from W, DW.
-       So make a compatibe data here.
-     */
-    if (font->FontType != ft_PCL_user_defined && font->FontType != ft_GL2_stick_user_defined &&
-        font->FontType != ft_GL2_531
-        && (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))) {
-        code = get_missing_width(font, wmode, &scale_c, pwidths);
-        if (code < 0)
-            return code;
-        else
-            v.y = pwidths->Width.v.y;
-        if (wmode && (ofont->FontType == ft_CID_encrypted ||
-            ofont->FontType == ft_CID_TrueType)) {
-            txt_glyph_widths_t widths1;
-
-            if (get_missing_width(font, 0, &scale_c, &widths1) < 0)
-                v.x = 0;
-            else
-                v.x = widths1.Width.w / 2;
-        } else
-            v.x = pwidths->Width.v.x;
-    } else if (code < 0)
-        return code;
-    else {
-        code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
-        if (code < 0)
-            return code;
-        rcode |= code;
-        if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode))
-            gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
-        else
-            v.x = v.y = 0;
-        if (wmode && (ofont->FontType == ft_CID_encrypted ||
-            ofont->FontType == ft_CID_TrueType)) {
-            if (info.members & (GLYPH_INFO_WIDTH0 << wmode)) {
-                gs_point xy;
-
-                gs_distance_transform(info.width[0].x, info.width[0].y, &scale_c, &xy);
-                v.x = xy.x / 2;
-            } else {
-                txt_glyph_widths_t widths1;
-
-                if (get_missing_width(font, 0, &scale_c, &widths1) < 0)
-                    v.x = 0;
-                else
-                    v.x = widths1.Width.w / 2;
-            }
-        }
-    }
-    pwidths->Width.v = v;
-    /* Skip only if not paralel to the axis. */
-    if (code > 0 && ofont->FontType != ft_CID_encrypted &&
-            ofont->FontType != ft_CID_TrueType)
-        pwidths->Width.xy.x = pwidths->Width.xy.y = pwidths->Width.w = 0;
-    if (cdevproc_result == NULL) {
-        info.members = 0;
-        code = ofont->procs.glyph_info(ofont, glyph, NULL,
-                                            (GLYPH_INFO_WIDTH0 << wmode) |
-                                            (GLYPH_INFO_VVECTOR0 << wmode) |
-                                            allow_cdevproc_callout,
-                                            &info);
-        /* fixme : Move this call before cfont->procs.glyph_info. */
-        if (info.members & GLYPH_INFO_CDEVPROC) {
-            if (allow_cdevproc_callout)
-                return TEXT_PROCESS_CDEVPROC;
-        else
-            return_error(gs_error_rangecheck);
-        }
-    } else {
-        info.width[0].x = cdevproc_result[0];
-        info.width[0].y = cdevproc_result[1];
-        info.width[1].x = cdevproc_result[6];
-        info.width[1].y = cdevproc_result[7];
-        info.v.x = (wmode ? cdevproc_result[8] : 0);
-        info.v.y = (wmode ? cdevproc_result[9] : 0);
-        info.members = (GLYPH_INFO_WIDTH0 << wmode) |
-                       (wmode ? GLYPH_INFO_VVECTOR1 : 0);
-        code = 0;
-    }
-    if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))
-        pwidths->real_width = pwidths->Width;
-    else if (code < 0)
-        return code;
-    else {
-        if ((info.members & (GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1)) != 0)
-            pwidths->replaced_v = true;
-        else
-            info.v.x = info.v.y = 0;
-        code = store_glyph_width(&pwidths->real_width, wmode, &scale_o, &info);
-        if (code < 0)
-            return code;
-        rcode |= code;
-        gs_distance_transform(info.v.x, info.v.y, &scale_o, &pwidths->real_width.v);
-    }
-    return rcode;
-}
-
-static void
-txt_char_widths_to_uts(gs_font *font /* may be NULL for non-Type3 */,
-                       txt_glyph_widths_t *pwidths)
-{
-    if (font && (font->FontType == ft_user_defined ||
-        font->FontType == ft_PCL_user_defined ||
-        font->FontType == ft_GL2_stick_user_defined ||
-        font->FontType == ft_GL2_531)) {
-        gs_matrix *pmat = &font->orig_FontMatrix;
-
-        pwidths->Width.xy.x *= pmat->xx; /* formula simplified based on wy in glyph space == 0 */
-        pwidths->Width.xy.y  = 0.0; /* WMode == 0 for PDF Type 3 fonts */
-        gs_distance_transform(pwidths->real_width.xy.x, pwidths->real_width.xy.y, pmat, &pwidths->real_width.xy);
-    } else {
-        /*
-         * For other font types:
-         * - PDF design->text space is a simple scaling by 0.001.
-         * - The Width.xy.x/y that should be zeroed-out per 5.3.3 "Text Space Details" is already 0.
-         */
-        pwidths->Width.xy.x /= 1000.0;
-        pwidths->Width.xy.y /= 1000.0;
-        pwidths->real_width.xy.x /= 1000.0;
-        pwidths->real_width.xy.y /= 1000.0;
-    }
-}
-
 /* Simple routine to update the current point by the accumulated width of the
  * text.
  */
@@ -1744,142 +1424,6 @@ txt_shift_text_currentpoint(textw_text_enum_t *penum, gs_point *wpt)
                               fixed2float(penum->origin.y) + wpt->y);
 }
 
-/* Try to convert glyph names/character codes to Unicode. We first try to see
- * if we have any Unicode information either from a ToUnicode CMap or GlyphNames2Unicode
- * table. If that fails we look at the glyph name to see if it starts 'uni'
- * in which case we assume the remainder of the name is the Unicode value. If
- * its not a glyph of that form then we search a bunch of tables whcih map standard
- * glyph names to Unicode code points. If that fails we finally just return the character code.
- */
-static int get_unicode(textw_text_enum_t *penum, gs_font *font, gs_glyph glyph, gs_char ch, unsigned short *Buffer)
-{
-    int code;
-    gs_const_string gnstr;
-    unsigned short fallback = ch;
-    ushort *unicode = NULL;
-    int length;
-
-    length = font->procs.decode_glyph((gs_font *)font, glyph, ch, NULL, 0);
-    if (length == 0) {
-        if (glyph != GS_NO_GLYPH) {
-            code = font->procs.glyph_name(font, glyph, &gnstr);
-            if (code >= 0 && gnstr.size == 7) {
-                if (!memcmp(gnstr.data, "uni", 3)) {
-                    static const char *hexdigits = "0123456789ABCDEF";
-                    char *d0 = strchr(hexdigits, gnstr.data[3]);
-                    char *d1 = strchr(hexdigits, gnstr.data[4]);
-                    char *d2 = strchr(hexdigits, gnstr.data[5]);
-                    char *d3 = strchr(hexdigits, gnstr.data[6]);
-
-                    if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
-                        *Buffer++ = ((d0 - hexdigits) << 12) + ((d1 - hexdigits) << 8) + ((d2 - hexdigits) << 4) + (d3 - hexdigits);
-                        return 1;
-                    }
-                }
-            }
-            if (length == 0) {
-                single_glyph_list_t *sentry = SingleGlyphList;
-                double_glyph_list_t *dentry = DoubleGlyphList;
-                treble_glyph_list_t *tentry = TrebleGlyphList;
-                quad_glyph_list_t *qentry = QuadGlyphList;
-
-                /* Search glyph to single Unicode value table */
-                while (sentry->Glyph != 0) {
-                    if (sentry->Glyph[0] < gnstr.data[0]) {
-                        sentry++;
-                        continue;
-                    }
-                    if (sentry->Glyph[0] > gnstr.data[0]){
-                        break;
-                    }
-                    if (strlen(sentry->Glyph) == gnstr.size) {
-                        if(memcmp(gnstr.data, sentry->Glyph, gnstr.size) == 0) {
-                            *Buffer = sentry->Unicode;
-                            return 1;
-                        }
-                    }
-                    sentry++;
-                }
-
-                /* Search glyph to double Unicode value table */
-                while (dentry->Glyph != 0) {
-                    if (dentry->Glyph[0] < gnstr.data[0]) {
-                        dentry++;
-                        continue;
-                    }
-                    if (dentry->Glyph[0] > gnstr.data[0]){
-                        break;
-                    }
-                    if (strlen(dentry->Glyph) == gnstr.size) {
-                        if(memcmp(gnstr.data, dentry->Glyph, gnstr.size) == 0) {
-                            memcpy(Buffer, dentry->Unicode, 2);
-                            return 2;
-                        }
-                    }
-                    dentry++;
-                }
-
-                /* Search glyph to triple Unicode value table */
-                while (tentry->Glyph != 0) {
-                    if (tentry->Glyph[0] < gnstr.data[0]) {
-                        tentry++;
-                        continue;
-                    }
-                    if (tentry->Glyph[0] > gnstr.data[0]){
-                        break;
-                    }
-                    if (strlen(tentry->Glyph) == gnstr.size) {
-                        if(memcmp(gnstr.data, tentry->Glyph, gnstr.size) == 0) {
-                            memcpy(Buffer, tentry->Unicode, 3);
-                            return 3;
-                        }
-                    }
-                    tentry++;
-                }
-
-                /* Search glyph to quadruple Unicode value table */
-                while (qentry->Glyph != 0) {
-                    if (qentry->Glyph[0] < gnstr.data[0]) {
-                        qentry++;
-                        continue;
-                    }
-                    if (qentry->Glyph[0] > gnstr.data[0]){
-                        break;
-                    }
-                    if (strlen(qentry->Glyph) == gnstr.size) {
-                        if(memcmp(gnstr.data, qentry->Glyph, gnstr.size) == 0) {
-                            memcpy(Buffer, qentry->Unicode, 4);
-                            return 4;
-                        }
-                    }
-                    qentry++;
-                }
-            }
-        }
-        *Buffer = fallback;
-        return 1;
-    } else {
-        char *b, *u;
-        int l = length - 1;
-
-        unicode = (ushort *)gs_alloc_bytes(penum->dev->memory, length, "temporary Unicode array");
-        length = font->procs.decode_glyph((gs_font *)font, glyph, ch, unicode, length);
-#if ARCH_IS_BIG_ENDIAN
-        memcpy(Buffer, unicode, length);
-#else
-        b = (char *)Buffer;
-        u = (char *)unicode;
-
-        for (l=0;ldev->memory, unicode, "free temporary unicode buffer");
-        return length / sizeof(short);
-    }
-}
-
 /* Routines to enumerate each glyph/character code in turn, find its width
  * so that we can update the current point and find the end of the text, convert
  * to Unicode if at all possible, and store some state such as the font, colour
@@ -1930,7 +1474,7 @@ txtwrite_process_cmap_text(gs_text_enum_t *pte)
                 code = gs_matrix_multiply(&subfont->FontMatrix, &pte->orig_font->FontMatrix, &m3);
                 if (code < 0)
                     return code;
-                code = txt_update_text_state(penum->text_state, (textw_text_enum_t *)pte, pte->orig_font, &m3);
+                code = txt_update_text_state(penum->text_state, (textw_text_enum_t *)pte, subfont, &m3);
                 if (code < 0)
                     return code;
                 txt_char_widths_to_uts(pte->orig_font, &widths); /* convert design->text space */
@@ -1940,6 +1484,8 @@ txtwrite_process_cmap_text(gs_text_enum_t *pte)
                 pte->returned.total_width.x += wanted.x;
                 pte->returned.total_width.y += wanted.y;
                 penum->Widths[penum->TextBufferIndex] = wanted.x;
+                penum->GlyphWidths[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
+                penum->SpanDeltaX[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
 
                 if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
                     gs_point tpt;
@@ -1961,7 +1507,8 @@ txtwrite_process_cmap_text(gs_text_enum_t *pte)
                 pte->returned.total_width.y += dpt.y;
 
                 penum->Widths[penum->TextBufferIndex] += dpt.x;
-                penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, chr, &penum->TextBuffer[penum->TextBufferIndex]);
+                penum->GlyphWidths[penum->TextBufferIndex] += dpt.x;
+                penum->TextBufferIndex += txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, chr, &penum->TextBuffer[penum->TextBufferIndex]);
                 break;
             case 2:		/* end of string */
                 return 0;
@@ -2028,6 +1575,8 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
         pte->returned.total_width.y += wanted.y;
         penum->Widths[penum->TextBufferIndex] = wanted.x;
         penum->Advs[penum->TextBufferIndex] = wanted.x;
+        penum->GlyphWidths[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
+        penum->SpanDeltaX[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
 
         if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
             gs_point tpt;
@@ -2049,13 +1598,16 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
         pte->returned.total_width.y += dpt.y;
 
         penum->Widths[penum->TextBufferIndex] += dpt.x;
-        code = get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
+        penum->SpanDeltaX[penum->TextBufferIndex] += dpt.x;
+        code = txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
         /* If a single text code returned multiple Unicode values, then we need to set the
          * 'extra' code points' widths to 0.
          */
         if (code > 1) {
             memset(&penum->Widths[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
             memset(&penum->Advs[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
+            memset(&penum->GlyphWidths[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
+            memset(&penum->SpanDeltaX[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
         }
         penum->TextBufferIndex += code;
 /*        gs_moveto_aux(penum->pgs, gx_current_path(penum->pgs),
@@ -2169,6 +1721,7 @@ txt_add_sorted_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
 static int
 txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
 {
+    gs_font *font = penum->current_font;
     text_list_entry_t *unsorted_entry, *t;
 
 #ifdef TRACE_TXTWRITE
@@ -2216,10 +1769,28 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
         penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
     if (!penum->text_state->Advs)
         return gs_note_error(gs_error_VMerror);
+    penum->text_state->GlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+        penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+    if (!penum->text_state->GlyphWidths)
+        return gs_note_error(gs_error_VMerror);
+    penum->text_state->SpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+        penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+    if (!penum->text_state->SpanDeltaX)
+        return gs_note_error(gs_error_VMerror);
     memset(penum->text_state->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
     memcpy(penum->text_state->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
     memset(penum->text_state->Advs, 0x00, penum->TextBufferIndex * sizeof(float));
     memcpy(penum->text_state->Advs, penum->Advs, penum->TextBufferIndex * sizeof(float));
+    memset(penum->text_state->GlyphWidths, 0x00, penum->TextBufferIndex * sizeof(float));
+    memcpy(penum->text_state->GlyphWidths, penum->GlyphWidths, penum->TextBufferIndex * sizeof(float));
+    memset(penum->text_state->SpanDeltaX, 0x00, penum->TextBufferIndex * sizeof(float));
+    memcpy(penum->text_state->SpanDeltaX, penum->SpanDeltaX, penum->TextBufferIndex * sizeof(float));
+    penum->text_state->FontName = (char *)gs_malloc(tdev->memory->stable_memory, 1,
+        font->font_name.size + 1, "txtwrite alloc font name");
+    if (!penum->text_state->FontName)
+        return gs_note_error(gs_error_VMerror);
+    memcpy(penum->text_state->FontName, font->font_name.chars, font->font_name.size);
+    penum->text_state->FontName[font->font_name.size] = 0x00;
 
     unsorted_entry->Unicode_Text = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
         penum->TextBufferIndex, sizeof(unsigned short), "txtwrite alloc sorted text buffer");
@@ -2235,10 +1806,22 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
         penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
     if (!unsorted_entry->Advs)
         return gs_note_error(gs_error_VMerror);
+    unsorted_entry->GlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+        penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+    if (!unsorted_entry->GlyphWidths)
+        return gs_note_error(gs_error_VMerror);
+    unsorted_entry->SpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+        penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+    if (!unsorted_entry->SpanDeltaX)
+        return gs_note_error(gs_error_VMerror);
     memset(unsorted_entry->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
     memcpy(unsorted_entry->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
     memset(unsorted_entry->Advs, 0x00, penum->TextBufferIndex * sizeof(float));
     memcpy(unsorted_entry->Advs, penum->Advs, penum->TextBufferIndex * sizeof(float));
+    memset(unsorted_entry->GlyphWidths, 0x00, penum->TextBufferIndex * sizeof(float));
+    memcpy(unsorted_entry->GlyphWidths, penum->GlyphWidths, penum->TextBufferIndex * sizeof(float));
+    memset(unsorted_entry->SpanDeltaX, 0x00, penum->TextBufferIndex * sizeof(float));
+    memcpy(unsorted_entry->SpanDeltaX, penum->SpanDeltaX, penum->TextBufferIndex * sizeof(float));
 
     unsorted_entry->FontName = (char *)gs_malloc(tdev->memory->stable_memory,
         (strlen(penum->text_state->FontName) + 1), sizeof(unsigned char), "txtwrite alloc sorted text buffer");
@@ -2287,7 +1870,7 @@ textw_text_process(gs_text_enum_t *pte)
         code = gx_default_text_restore_state(pte_fallback);
         if (code < 0)
             return code;
-        gs_text_release(pte_fallback, "txtwrite_text_process");
+        gs_text_release(NULL, pte_fallback, "txtwrite_text_process");
     }
     pte_fallback = penum->pte_fallback = NULL;
 
@@ -2311,6 +1894,14 @@ textw_text_process(gs_text_enum_t *pte)
             pte->text.size * 4, sizeof(float), "txtwrite temporary advs array");
         if (!penum->Advs)
             return gs_note_error(gs_error_VMerror);
+        penum->GlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+            pte->text.size * 4, sizeof(float), "txtwrite temporary glyphwidths array");
+        if (!penum->GlyphWidths)
+            return gs_note_error(gs_error_VMerror);
+        penum->SpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+            pte->text.size * 4, sizeof(float), "txtwrite temporary spandeltax array");
+        if (!penum->SpanDeltaX)
+            return gs_note_error(gs_error_VMerror);
     }
     {
         switch (font->FontType) {
@@ -2378,7 +1969,7 @@ textw_text_process(gs_text_enum_t *pte)
                 penum->returned.current_glyph = pte_fallback->returned.current_glyph;
                 return code;
             }
-            gs_text_release(pte_fallback, "txtwrite_text_process");
+            gs_text_release(NULL, pte_fallback, "txtwrite_text_process");
             penum->pte_fallback = 0;
         }
     }
@@ -2446,14 +2037,29 @@ textw_text_release(gs_text_enum_t *pte, client_name_t cname)
         gs_free(tdev->memory, penum->TextBuffer, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
     if (penum->Widths)
         gs_free(tdev->memory, penum->Widths, sizeof(float), pte->text.size, "txtwrite free temporary widths array");
+    if (penum->Advs)
+        gs_free(tdev->memory, penum->Advs, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+    if (penum->GlyphWidths)
+        gs_free(tdev->memory, penum->GlyphWidths, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+    if (penum->SpanDeltaX)
+        gs_free(tdev->memory, penum->SpanDeltaX, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
     /* If this is copied away when we complete the text enumeration succesfully, then
      * we set the pointer to NULL, if we get here with it non-NULL , then there was
      * an error.
      */
-    if (penum->text_state)
+    if (penum->text_state) {
+        if (penum->text_state->Widths)
+            gs_free(tdev->memory, penum->text_state->Widths, sizeof(float), pte->text.size, "txtwrite free temporary widths array");
+        if (penum->text_state->Advs)
+            gs_free(tdev->memory, penum->text_state->Advs, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+        if (penum->text_state->GlyphWidths)
+            gs_free(tdev->memory, penum->text_state->GlyphWidths, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+        if (penum->text_state->SpanDeltaX)
+            gs_free(tdev->memory, penum->text_state->SpanDeltaX, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+        if (penum->text_state->FontName)
+            gs_free(tdev->memory, penum->text_state->FontName, 1, penum->TextBufferIndex, "txtwrite free temporary font name copy");
         gs_free(tdev->memory, penum->text_state, 1, sizeof(penum->text_state), "txtwrite free text state");
-
-    gs_text_release(pte, cname);
+    }
 }
 
 /* This is the list of methods for the text enumerator */
diff --git a/devices/vector/gdevxps.c b/devices/vector/gdevxps.c
index 8eb26196..c435cd47 100644
--- a/devices/vector/gdevxps.c
+++ b/devices/vector/gdevxps.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
@@ -118,9 +118,10 @@ typedef struct gx_device_xps_f2i_s {
     char *filename;
     gx_device_xps_zinfo_t *info;
     struct gx_device_xps_f2i_s *next;
+    gs_memory_t *memory;
 } gx_device_xps_f2i_t;
 
-/* Used for keeping track of icc profiles that we have written.   This way we 
+/* Used for keeping track of icc profiles that we have written.   This way we
    avoid writing the same one multiple times.  It would be nice to do this
    based upon the gs_id for images, but that id is really created after we
    have already drawn the path.  Not clear to me how to get a source ID. */
@@ -130,6 +131,16 @@ typedef struct xps_icc_data_s {
     struct xps_icc_data_s *next;
 } xps_icc_data_t;
 
+/* Add new page relationships to this linked list, avoiding duplicates.
+   When page is closed write out all the relationships */
+typedef struct xps_relations_s xps_relations_t;
+
+struct xps_relations_s {
+    char* relation;
+    xps_relations_t *next;
+    gs_memory_t *memory;
+};
+
 typedef enum {
     xps_solidbrush,
     xps_imagebrush,
@@ -169,7 +180,8 @@ typedef struct gx_device_xps_s {
     /* local state */
     int page_count;     /* how many output_page calls we've seen */
     int image_count;    /* number of images so far */
-    int relationship_count;  /* Pages relationships */
+    xps_relations_t *relations_head;
+    xps_relations_t *relations_tail;
     xps_icc_data_t *icc_data;
     gx_color_index strokecolor, fillcolor;
     xps_brush_t stroketype, filltype;
@@ -373,18 +385,19 @@ zip_new_info_node(gx_device_xps *xps_dev, const char *filename)
     int lenstr;
 
     /* NB should use GC */
-    gx_device_xps_zinfo_t *info = 
+    gx_device_xps_zinfo_t *info =
         (gx_device_xps_zinfo_t *)gs_alloc_bytes(mem->non_gc_memory, sizeof(gx_device_xps_zinfo_t), "zinfo");
-    gx_device_xps_f2i_t *f2i = 
+    gx_device_xps_f2i_t *f2i =
         (gx_device_xps_f2i_t *)gs_alloc_bytes(mem->non_gc_memory, sizeof(gx_device_xps_f2i_t), "zinfo node");
 
     if_debug1m('_', dev->memory, "new node %s\n", filename);
-    
+
     if (info == NULL || f2i == NULL)
-        return gs_throw_code(gs_error_Fatal);
+        return gs_throw_code(gs_error_VMerror);
 
     f2i->info = info;
     f2i->next = NULL;
+    f2i->memory = mem->non_gc_memory;
 
     if (xps_dev->f2i == 0) { /* no head */
         xps_dev->f2i = f2i;
@@ -396,8 +409,10 @@ zip_new_info_node(gx_device_xps *xps_dev, const char *filename)
 
     lenstr = strlen(filename);
     f2i->filename = (char*)gs_alloc_bytes(mem->non_gc_memory, lenstr + 1, "zinfo_filename");
+    if (f2i->filename == NULL)
+        return gs_throw_code(gs_error_VMerror);
     strcpy(f2i->filename, filename);
-        
+
     info->data.fp = 0;
     info->data.count = 0;
     info->saved = false;
@@ -408,7 +423,7 @@ zip_new_info_node(gx_device_xps *xps_dev, const char *filename)
         int node = 1;
         gx_device_xps_f2i_t *prev_f2i;
 #endif
-        
+
         while (f2i != NULL) {
             if_debug2m('_', dev->memory, "node:%d %s\n", node++, f2i->filename);
 #ifdef DEBUG
@@ -454,14 +469,14 @@ zip_append_data(gs_memory_t *mem, gx_device_xps_zinfo_t *info, byte *data, uint
        archive file, open a temporary file to store the data. */
     if (info->data.count == 0) {
         char *filename =
-          (char *)gs_alloc_bytes(mem->non_gc_memory, gp_file_name_sizeof, 
+          (char *)gs_alloc_bytes(mem->non_gc_memory, gp_file_name_sizeof,
                 "zip_append_data(filename)");
         gp_file *fp;
-        
+
         if (!filename) {
             return(gs_throw_code(gs_error_VMerror));
         }
-        
+
         fp = gp_open_scratch_file_rm(mem, "xpsdata-",
                                         filename, "wb+");
         gs_free_object(mem->non_gc_memory, filename, "zip_append_data(filename)");
@@ -737,7 +752,7 @@ zip_close_archive_file(gx_device_xps *xps_dev, const char *filename)
         }
         /* If this is a TIFF file, then update the data count information.
            During the writing of the TIFF directory there is seeking and
-           relocations that occur, which make data.count incorrect. 
+           relocations that occur, which make data.count incorrect.
            We could just do this for all the files and avoid the test. */
         len = strlen(filename);
         if (len > 3 && (strncmp("tif", &(filename[len - 3]), 3) == 0)) {
@@ -908,7 +923,8 @@ xps_open_device(gx_device *dev)
 
     /* xps-specific initialization goes here */
     xps->page_count = 0;
-    xps->relationship_count = 0;
+    xps->relations_head = NULL;
+    xps->relations_tail = NULL;
     xps->strokecolor = gx_no_color_index;
     xps->fillcolor = gx_no_color_index;
     xps_setstrokebrush(xps, xps_solidbrush);
@@ -934,7 +950,7 @@ xps_open_device(gx_device *dev)
                                  fixed_document_sequence);
     if (code < 0)
         return gs_rethrow_code(code);
-    
+
     code = write_str_to_zip_file(xps, (char *)"[Content_Types].xml",
                                  xps_content_types);
     if (code < 0)
@@ -969,7 +985,7 @@ write_str_to_current_page(gx_device_xps *xps, const char *str)
     int code = gs_sprintf(buf, page_template, xps->page_count+1);
     if (code < 0)
         return gs_rethrow_code(code);
-    
+
     return write_str_to_zip_file(xps, buf, str);
 }
 
@@ -977,26 +993,38 @@ write_str_to_current_page(gx_device_xps *xps, const char *str)
 static int
 add_new_relationship(gx_device_xps *xps, const char *str)
 {
-    const char *rels_template = "Documents/1/Pages/_rels/%d.fpage.rels";
-    char buf[128]; /* easily enough to accommodate the string and a page number */
-    char line[300];
-    const char *fmt;
+    xps_relations_t *rel;
 
-    int code = gs_sprintf(buf, rels_template, xps->page_count + 1);
-    if (code < 0)
-        return gs_rethrow_code(code);
+    /* See if we already have this one */
+    for (rel = xps->relations_head; rel; rel = rel->next)
+        if (!strcmp(rel->relation, str))
+            return 0;
 
-    /* Check if this is our first one */
-    if (xps->relationship_count == 0) 
-        write_str_to_zip_file(xps, buf, rels_header);
-
-    /* Now add the reference */
-    fmt = "\n";
-    gs_sprintf(line, fmt, str, xps->relationship_count, rels_req_type);
+    rel = (xps_relations_t*)gs_alloc_bytes(xps->memory->non_gc_memory,
+        sizeof(xps_relations_t), "add_new_relationship");
+    if (!rel) {
+        return gs_throw_code(gs_error_VMerror);
+    }
+    rel->memory = xps->memory->non_gc_memory;
+    rel->next = NULL;
+
+    rel->relation = (char*)gs_alloc_bytes(xps->memory->non_gc_memory,
+        strlen(str) + 1, "add_new_relationship");
+    if (!rel->relation) {
+        gs_free_object(rel->memory, rel, "add_new_relationship");
+        return gs_throw_code(gs_error_VMerror);
+    }
+    memcpy(rel->relation, str, strlen(str) + 1);
 
-    xps->relationship_count++;
+    if (!xps->relations_head) {
+        xps->relations_head = rel;
+        xps->relations_tail = rel;
+    } else {
+        xps->relations_tail->next = rel;
+        xps->relations_tail = rel;
+    }
 
-    return write_str_to_zip_file(xps, buf, line);
+    return 0;
 }
 
 static int
@@ -1013,6 +1041,51 @@ close_page_relationship(gx_device_xps *xps)
     return 0;
 }
 
+static int
+write_page_relationship(gx_device_xps* xps)
+{
+    const char* rels_template = "Documents/1/Pages/_rels/%d.fpage.rels";
+    char buf[128]; /* easily enough to accommodate the string and a page number */
+    char line[300];
+    const char* fmt;
+    int count = 0;
+    xps_relations_t *rel = xps->relations_head;
+
+    int code = gs_sprintf(buf, rels_template, xps->page_count + 1);
+    if (code < 0)
+        return gs_rethrow_code(code);
+
+    write_str_to_zip_file(xps, buf, rels_header);
+    fmt = "\n";
+
+    while (rel) {
+        gs_sprintf(line, fmt, rel->relation, count, rels_req_type);
+        write_str_to_zip_file(xps, buf, line);
+        rel = rel->next;
+        count++;
+    }
+
+    return 0;
+}
+
+static void
+release_relationship(gx_device_xps* xps)
+{
+    xps_relations_t *rel = xps->relations_head;
+    xps_relations_t *old;
+
+    while (rel) {
+        old = rel;
+        rel = rel->next;
+        gs_free_object(old->memory, old->relation, "release_relationship");
+        gs_free_object(old->memory, old, "release_relationship");
+    }
+
+    xps->relations_head = NULL;
+    xps->relations_tail = NULL;
+    return;
+}
+
         /* Page management */
 
 /* Complete a page */
@@ -1024,14 +1097,22 @@ xps_output_page(gx_device *dev, int num_copies, int flush)
     int code;
 
     write_str_to_current_page(xps, "");
-    if (xps->relationship_count > 0)
+
+    if (xps->relations_head)
     {
+        /* Write all the relations for the page */
+        code = write_page_relationship(xps);
+        if (code < 0)
+            return gs_rethrow_code(code);
+
         /* Close the relationship xml */
         code = close_page_relationship(xps);
         if (code < 0)
             return gs_rethrow_code(code);
-        xps->relationship_count = 0;  /* Reset for next page */
+
+        release_relationship(xps);
     }
+
     xps->page_count++;
 
     if (gp_ferror(xps->file))
@@ -1070,6 +1151,23 @@ xps_release_icc_info(gx_device *dev)
     return;
 }
 
+static void
+xps_release_achive_file_names(gx_device* dev)
+{
+    gx_device_xps* xps = (gx_device_xps*)dev;
+    gx_device_xps_f2i_t *curr;
+    gx_device_xps_f2i_t *f2i = xps->f2i;
+
+    while (f2i) {
+        curr = f2i;
+        f2i = f2i->next;
+        gs_free_object(curr->memory, curr->info, "xps_release_achive_file_names(info)");
+        gs_free_object(curr->memory, curr->filename, "xps_release_achive_file_names(filename)");
+        gs_free_object(curr->memory, curr, "xps_release_achive_file_names(f2i)");
+    }
+    return;
+}
+
 /* Close the device */
 static int
 xps_close_device(gx_device *dev)
@@ -1092,6 +1190,9 @@ xps_close_device(gx_device *dev)
     /* Release the icc info */
     xps_release_icc_info(dev);
 
+    /* Release the archive file names */
+    xps_release_achive_file_names(dev);
+
     code = gdev_vector_close_file((gx_device_vector*)dev);
     if (code < 0)
         return gs_rethrow_code(code);
@@ -1232,10 +1333,10 @@ static int
 set_state_color(gx_device_vector *vdev, const gx_drawing_color *pdc, gx_color_index *color)
 {
     gx_device_xps *xps = (gx_device_xps *)vdev;
-    
+
     /* hack so beginpage is called */
     (void)gdev_vector_stream((gx_device_vector*)xps);
- 
+
     /* Usually this is not an actual error but a signal to the
        graphics library to simplify the color */
     if (!gx_dc_is_pure(pdc)) {
@@ -1252,7 +1353,7 @@ xps_setfillcolor(gx_device_vector *vdev, const gs_gstate *pgs, const gx_drawing_
     gx_device_xps *xps = (gx_device_xps *)vdev;
 
     if_debug1m('_', xps->memory, "xps_setfillcolor:%06X\n", (uint32_t)gx_dc_pure_color(pdc));
-    
+
     return set_state_color(vdev, pdc, &xps->fillcolor);
 }
 
@@ -1260,9 +1361,9 @@ static int
 xps_setstrokecolor(gx_device_vector *vdev, const gs_gstate *pgs, const gx_drawing_color *pdc)
 {
     gx_device_xps *xps = (gx_device_xps *)vdev;
-    
+
     if_debug1m('_', xps->memory, "xps_setstrokecolor:%06X\n", (uint32_t)gx_dc_pure_color(pdc));
-    
+
     return set_state_color(vdev, pdc, &xps->strokecolor);
 }
 
@@ -1473,8 +1574,8 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
                 fixed2float(x0), fixed2float(y1),
                 fixed2float(x1), fixed2float(y1),
                 fixed2float(x1), fixed2float(y0));
-               
-    
+
+
     /* skip non-drawing paths for now */
     if (!drawing_path(type, xps->filltype)) {
         if_debug1m('_', xps->memory, "xps_dorect: type not supported %x\n", type);
@@ -1552,7 +1653,7 @@ gdev_xps_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
     }
     return gdev_vector_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath);
 }
-           
+
 static int
 xps_beginpath(gx_device_vector *vdev, gx_path_type_t type)
 {
@@ -1560,7 +1661,7 @@ xps_beginpath(gx_device_vector *vdev, gx_path_type_t type)
     gx_device_xps *xps = (gx_device_xps *)vdev;
     uint32_t c;
     const char *fmt;
-    
+
     (void)gdev_vector_stream((gx_device_vector*)xps);
 
     /* skip non-drawing paths for now */
@@ -1588,7 +1689,7 @@ xps_beginpath(gx_device_vector *vdev, gx_path_type_t type)
     else {
         write_str_to_current_page(xps, "memory, "xps_beginpath %s\n", line);
 
     return 0;
@@ -1623,7 +1724,7 @@ xps_lineto(gx_device_vector *vdev, double x0, double y0,
     char line[200];
 
     if_debug2m('_', xps->memory, "xps_lineto %g %g\n", x, y);
-    
+
     /* skip non-drawing paths for now */
     if (!drawing_path(type, xps->filltype)) {
         if_debug1m('_', xps->memory, "xps_lineto: type not supported %x\n", type);
@@ -1642,18 +1743,18 @@ xps_curveto(gx_device_vector *vdev, double x0, double y0,
 {
     gx_device_xps *xps = (gx_device_xps *)vdev;
     char line[200];
-    
+
     /* skip non-drawing paths for now */
     if (!drawing_path(type, xps->filltype)) {
         if_debug1m('_', xps->memory, "xps_curveto: type not supported %x\n", type);
         return 0;
     }
-    
+
     gs_sprintf(line, " C %g,%g %g,%g %g,%g", x1, y1,
             x2,y2,x3,y3);
     write_str_to_current_page(xps,line);
     if_debug1m('_', xps->memory, "xps_curveto %s\n", line);
-            
+
     return 0;
 }
 
@@ -1716,9 +1817,10 @@ static const gx_image_enum_procs_t xps_image_enum_procs = {
 /* Prototypes */
 static TIFF* tiff_from_name(gx_device_xps *dev, const char *name, int big_endian,
     bool usebigtiff);
-static int tiff_set_values(xps_image_enum_t *pie, TIFF *tif, 
+static int tiff_set_values(xps_image_enum_t *pie, TIFF *tif,
                             cmm_profile_t *profile, bool force8bit);
 static void xps_tiff_set_handlers(void);
+static void tiff_client_release(gx_device_xps* dev, TIFF* t);
 
 /* Check if we have the ICC profile in the package */
 static xps_icc_data_t*
@@ -1770,7 +1872,7 @@ xps_add_icc_relationship(xps_image_enum_t *pie)
     return 0;
 }
 
-static int 
+static int
 xps_add_image_relationship(xps_image_enum_t *pie)
 {
     gx_device_xps *xps = (gx_device_xps*) (pie->dev);
@@ -1796,8 +1898,8 @@ xps_write_profile(const gs_gstate *pgs, char *name, cmm_profile_t *profile, gx_d
 }
 
 static int
-xps_begin_image(gx_device *dev, const gs_gstate *pgs, 
-                const gs_image_t *pim, gs_image_format_t format, 
+xps_begin_image(gx_device *dev, const gs_gstate *pgs,
+                const gs_image_t *pim, gs_image_format_t format,
                 const gs_int_rect *prect, const gx_drawing_color *pdcolor,
                 const gx_clip_path *pcpath, gs_memory_t *mem,
                 gx_image_enum_common_t **pinfo)
@@ -1814,7 +1916,7 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
     int bits_per_pixel;
     int num_components;
     int bsize;
-    cmm_profile_t *icc_profile = NULL; 
+    cmm_profile_t *icc_profile = NULL;
     gs_color_space_index csindex;
     float index_decode[2];
     gsicc_rendering_param_t rendering_params;
@@ -1856,8 +1958,8 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
     /* We need this set a bit early for the ICC relationship writing */
     pie->dev = (gx_device*) xdev;
 
-    /* If the color space is DeviceN, Sep or indexed these end up getting 
-       mapped to the color space defined by the device profile.  XPS only 
+    /* If the color space is DeviceN, Sep or indexed these end up getting
+       mapped to the color space defined by the device profile.  XPS only
        support RGB indexed images so we just expand if for now. ICC link
        creation etc is handled during the remap/concretization of the colors */
     if (csindex == gs_color_space_index_Indexed ||
@@ -1927,7 +2029,7 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
             xdev->icc_data = icc_data;
         }
 
-        /* Get name for mark up and for relationship. Have to wait and do 
+        /* Get name for mark up and for relationship. Have to wait and do
            this after it is added to the package */
         code = xps_create_icc_name(xdev, icc_profile, &(pie->icc_name[0]));
         if (code < 0)
@@ -1944,10 +2046,13 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
         /* Add ICC relationship */
         xps_add_icc_relationship(pie);
     } else {
-        /* Get name for mark up.  We already have it in the relationship and list */
+        /* Get name for mark up.  We already have it in the resource list */
         code = xps_create_icc_name(xdev, icc_profile, &(pie->icc_name[0]));
         if (code < 0)
             return gs_rethrow_code(code);
+
+        /* Add ICC relationship.  It may not yet be present for this page. */
+        xps_add_icc_relationship(pie);
     }
 
     /* Get image name for mark up */
@@ -1965,8 +2070,8 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
         pcpath = &cpath;
     } else {
         /* Force vector device to do new path as the clip path is the image
-           path.  I had a case where the clip path ids were the same but the 
-           CTM was changing which resulted in subsequent images coming up 
+           path.  I had a case where the clip path ids were the same but the
+           CTM was changing which resulted in subsequent images coming up
            missing on the page. i.e. only the first one was shown. */
         ((gx_device_vector*) vdev)->clip_path_id = vdev->no_clip_path_id;
     }
@@ -1996,7 +2101,7 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
     pie->bytes_comp = (pie->decode_st.bps > 8 ? 2 : 1);
     pie->decode_st.spp = num_components;
     pie->decode_st.unpack = NULL;
-    get_unpack_proc((gx_image_enum_common_t*)pie, &(pie->decode_st), pim->format, 
+    get_unpack_proc((gx_image_enum_common_t*)pie, &(pie->decode_st), pim->format,
         pim->Decode);
 
     /* The decode mapping for index colors needs an adjustment */
@@ -2011,7 +2116,7 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
         }
         get_map(&(pie->decode_st), pim->format, index_decode);
     } else {
-        get_map(&(pie->decode_st), pim->format, pim->Decode); 
+        get_map(&(pie->decode_st), pim->format, pim->Decode);
     }
 
     /* Allocate our decode buffer. */
@@ -2173,9 +2278,11 @@ const gx_image_plane_t *planes, int height, int *rows_used)
             gsicc_init_buffer(&output_buff_desc, 3, bytes_comp,
                 false, false, false, 0, width * bytes_comp * 3,
                 1, width);
-            (pie->icc_link->procs.map_buffer)(pie->dev, pie->icc_link,
+            code = (pie->icc_link->procs.map_buffer)(pie->dev, pie->icc_link,
                 &input_buff_desc, &output_buff_desc, (void*)buffer,
                 (void*)pie->buffer);
+            if (code < 0)
+                return code;
             outbuffer = pie->buffer;
         }
         code = TIFFWriteScanline(pie->tif, outbuffer, pie->y, 0);
@@ -2207,6 +2314,7 @@ xps_image_end_image(gx_image_enum_common_t * info, bool draw_last)
     /* N.B. Write the final strip, if any. */
 
     code = TIFFWriteDirectory(pie->tif);
+    tiff_client_release((gx_device_xps*)(pie->dev), pie->tif);
     TIFFCleanup(pie->tif);
 
     /* Stuff the image into the zip archive and close the file */
@@ -2232,7 +2340,7 @@ exit:
 #define TIFF_PRINT_BUF_LENGTH 1024
 static const char tifs_msg_truncated[] = "\n*** Previous line has been truncated.\n";
 
-static int 
+static int
 tiff_set_values(xps_image_enum_t *pie, TIFF *tif, cmm_profile_t *profile,
                 bool force8bit)
 {
@@ -2283,7 +2391,7 @@ tiff_set_values(xps_image_enum_t *pie, TIFF *tif, cmm_profile_t *profile,
 typedef struct tifs_io_xps_t
 {
     gx_device_xps *pdev;
-    gp_file *fid; 
+    gp_file *fid;
 } tifs_io_xps;
 
 /* libtiff i/o hooks */
@@ -2384,7 +2492,7 @@ xps_tifsSizeProc(thandle_t fd)
 }
 
 static void
-xps_tifsWarningHandlerEx(thandle_t client_data, const char *module, 
+xps_tifsWarningHandlerEx(thandle_t client_data, const char *module,
                          const char *fmt, va_list ap)
 {
     tifs_io_xps *tiffio = (tifs_io_xps *)client_data;
@@ -2403,7 +2511,7 @@ xps_tifsWarningHandlerEx(thandle_t client_data, const char *module,
 }
 
 static void
-xps_tifsErrorHandlerEx(thandle_t client_data, const char *module, 
+xps_tifsErrorHandlerEx(thandle_t client_data, const char *module,
                        const char *fmt, va_list ap)
 {
     tifs_io_xps *tiffio = (tifs_io_xps *)client_data;
@@ -2483,6 +2591,13 @@ tiff_from_name(gx_device_xps *dev, const char *name, int big_endian, bool usebig
     return t;
 }
 
+static void
+tiff_client_release(gx_device_xps *dev, TIFF *t)
+{
+    gs_free_object(dev->memory->non_gc_memory, TIFFClientdata(t),
+        "tiff_client_release");
+}
+
 static void
 xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr)
 {
diff --git a/devices/vector/opdfread.ps b/devices/vector/opdfread.ps
index e0d6f112..36d2049f 100644
--- a/devices/vector/opdfread.ps
+++ b/devices/vector/opdfread.ps
@@ -1,6 +1,6 @@
 %!PS-Adobe-2.0
 %
-% Copyright (C) 2001-2020 Artifex Software, Inc.
+% Copyright (C) 2001-2021 Artifex Software, Inc.
 % All Rights Reserved.
 %
 % This software is provided AS-IS with no warranty, either express or
@@ -1040,10 +1040,10 @@ currentdict end readonly def
   } if                                                  % id obj node
   1 index exch /Context exch put                        % id obj
   dup /ImmediateExec true put
-  dup /IsPage true put
-  SetPageSize {dup /Context get //SetupPageView exec} if
   % This gets restored at the end of ExecuteStream if IsPage is true.
   /pagesave save def
+  dup /IsPage true put
+  SetPageSize {dup /Context get //SetupPageView exec} if
 } bind def
 
 /FontFileDaemon %    FontFileDaemon  
diff --git a/devices/vector/whitelst.c b/devices/vector/whitelst.c
index af4c14fc..e06941e4 100644
--- a/devices/vector/whitelst.c
+++ b/devices/vector/whitelst.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/whitelst.h b/devices/vector/whitelst.h
index a566da54..8212ff37 100644
--- a/devices/vector/whitelst.h
+++ b/devices/vector/whitelst.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
    All Rights Reserved.
 
    This software is provided AS-IS with no warranty, either express or
diff --git a/doc/API.htm b/doc/API.htm
index feffd7e7..5bbb9ec5 100644
--- a/doc/API.htm
+++ b/doc/API.htm
@@ -38,7 +38,6 @@
             
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -501,7 +500,7 @@ such parameter). If the display device is used, this must be called after gsapi_new_instance() and before gsapi_init_with_args(). -See gdevdsp.h +See gdevdsp.h for more details. @@ -824,7 +823,6 @@ typedef struct gp_file **file); } gsapi_fs_t;
    -

    If the filename (always given in utf-8 format) is recognised as being one that the filing system handles (perhaps by the prefix used), then it should open the file, fill in the gp_file @@ -906,7 +904,6 @@ other files too (perhaps the temporary files we produce) we'd need to define additional handlers (such as open_scratch).

    Our handler might look as follows: -

     int crypt_open_file(const gs_memory_t  *mem,
                               void         *secret,
    @@ -1321,7 +1318,7 @@ this is now powerful enough to provide a simple mechanism for
     getting rendered output suitable for use in all manner of
     output scenarios, including printing.

    Details of the API and options are given in the file -gdevdsp.h. +gdevdsp.h. This device provides you with access to the raster output of Ghostscript. It is the callers responsibility to copy this raster to a display window or printer.

    @@ -1507,7 +1504,7 @@ device.

    Next we tell the display device what output format to use. The format is flexible enough to support common Windows, OS/2, Linux and Mac raster formats.

    The format values are described in -gdevdsp.h. +gdevdsp.h. To select the display device with a Windows 24-bit RGB raster:

         sprintf(argv[argc++], "-dDisplayFormat=%d",
    @@ -1748,11 +1745,11 @@ Some examples of driving this code in full page mode are in
     dmmain.c (MacOS Classic or Carbon).

    Alternatively an example that drives this code in both full page and rectangle request mode can be found in -displaydevice_test.c.

    +api_test.c.

    On some platforms, the calling convention for the display device callbacks in -gdevdsp.h +gdevdsp.h is not the same as the exported gsapi_*() functions in iapi.h.

    @@ -1761,7 +1758,7 @@ functions in iapi.h.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved.

    +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -1774,7 +1771,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.23, 21 March 2018

    +Ghostscript version 9.54.0, 30 March 2021 @@ -1801,7 +1798,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/C-style.htm b/doc/C-style.htm index 38fb58f7..c600eac6 100644 --- a/doc/C-style.htm +++ b/doc/C-style.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -1597,7 +1596,7 @@ to PostScript error conditions.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved.

    +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -1610,7 +1609,8 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.23, 21 March 2018

    +Ghostscript version 9.54.0, 30 March 2021 + @@ -1636,7 +1636,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Commprod.htm b/doc/Commprod.htm index 2290e425..6b12e305 100644 --- a/doc/Commprod.htm +++ b/doc/Commprod.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -269,7 +268,7 @@ AGPL complies with the conditions set forth above.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    @@ -280,7 +279,7 @@ of the license contained in the file LICENSE in this distribution. For more info http://www.artifex.com/licensing/or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861.

    -Ghostscript version 9.23, 21 March 2018

    +Ghostscript version 9.54.0, 30 March 2021 @@ -307,7 +306,7 @@ http://www.artifex.com/licensing/or contact Artifex Software, Inc., 1305 Grant A

    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/DLL.htm b/doc/DLL.htm index 9bafe9d5..ce120ad2 100644 --- a/doc/DLL.htm +++ b/doc/DLL.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -754,7 +753,7 @@ if (!code) {

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -767,7 +766,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -794,7 +793,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Deprecated.htm b/doc/Deprecated.htm index 6003e601..4edc729d 100644 --- a/doc/Deprecated.htm +++ b/doc/Deprecated.htm @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -5751,7 +5750,7 @@ February 2001

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -5764,7 +5763,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -5791,7 +5790,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Develop.htm b/doc/Develop.htm index 542fed74..0e546f54 100644 --- a/doc/Develop.htm +++ b/doc/Develop.htm @@ -36,7 +36,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -531,17 +530,10 @@ DCT (JPEG): JBIG2: base/sjbig2.h, base/sjbig2.c -or -base/sjbig2_luratech.h, -base/sjbig2_luratech.c. -
    JPX (JPEG 2000): base/sjpx_openjpeg.h, base/sjpx_openjpeg.c -or -base/sjpx_luratech.h, -base/sjpx_luratech.c.
    Other compression/decompression:
    @@ -4748,7 +4740,7 @@ Edit the output file name in the line 5.

    -Copyright © 2001-2019 Artifex Software, Inc. All rights +Copyright © 2001-2021 Artifex Software, Inc. All rights reserved.

    @@ -4762,7 +4754,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -4790,7 +4782,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Devices.htm b/doc/Devices.htm index b8be9431..c1048e59 100644 --- a/doc/Devices.htm +++ b/doc/Devices.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -71,13 +70,18 @@
  • BMP file format
  • PCX file format
  • PSD file format (DeviceN color model)
  • +
  • Bitmap PDF output, PCLm output
  • + +
  • OCR Devices
  • +
  • High level formats
    • PDF file output
    • -
    • Bitmap PDF output, PCLm output
    • OCR devices
    • -
    • Bitmap PDF output (with OCR text)
    • PostScript file output
    • EPS file output
    • PCL-XL file output
    • @@ -955,7 +959,11 @@ of 'high-level' formats. These allow Ghostscript to preserve (as much as possible) the drawing elements of the input file maintaining flexibility, resolution independence, and editability.

      -

      Optical Character Recognition (OCR) output

      +
      + +

      Optical Character Recognition (OCR) devices

      + +

      OCR text output

      These devices render internally in 8 bit greyscale, and then @@ -967,18 +975,29 @@ resolution independence, and editability.

      The Tesseract engine relies on files to encapsulate each language and/or script. These "traineddata" files - are available in different forms, including fast - and best variants. + are available in different forms, including fast + and best variants. Alternatively, people can train their own data using the standard Tesseract tools.

      - These files are looked for from a variety of places. Firstly, - any files placed in "Resource/Tesseract/" will be - included in the binary for any standard (COMPILE_INITS=1) build. - Secondly, files will be searched for in the current directory. - Thirdly, files will be searched for in the directory given by - the environment variable TESSDATA_PREFIX. + These files are looked for from a variety of places. +

      +
        +
      • Firstly, files will be searched for in the directory given by the + environment variable TESSDATA_PREFIX. +
      • Next, they will be searched for within the ROM filing system. Any + files placed in "tessdata" will be included within the ROM + filing system in the binary for any standard (COMPILE_INITS=1) build. +
      • Next, files will be searched for in the configured 'tessdata' path. On + Unix, this can be specified at the configure stage using + '--with-tessdata=<path>' (where <path> is a list of + directories to search, separated by ':' (on Unix) or ';' (on Windows)). +
      • Finally, we resort to searching the current directory. +
      +

      + Please note, this pattern of directory searching differs from the original + release of the OCR devices.

      By default, the OCR process defaults to looking for English text, @@ -993,7 +1012,7 @@ resolution independence, and editability.

      Arabic:
    - gs -sDEVICE=ocr -r200 -sOCRLanguage="eng,ara" -o out.txt\
    + gs -sDEVICE=ocr -r200 -sOCRLanguage="eng+ara" -o out.txt\
           zlib/zlib.3.pdf
     
    @@ -1041,6 +1060,39 @@ resolution independence, and editability.

    +

    Vector PDF output (with OCR Unicode CMaps)

    +

    +The pdfwrite device has been augmented to use the OCR engine to analyse text +(not images!) in the input stream, and derive Unicode code points for it. +That information can then be used to create ToUnicode CMaps which are attached +to the Font (or CIDFont) objects embedded in the PDF file. +

    +

    +Fonts which have ToUnicode CMaps can be reliably (limited by the accuracy of +the CMap) used in search and copy/paste functions, as well as text extraction +from PDF files. Note that OCR is not a 100% perfect process; it is possible +that some text might be misidentified. +

    +

    +OCR is a slow operation! In addition it can (for Latin text at least) sometimes +be preferable not to add ToUnicode information which may be incorrect, but instead +to use the existing font Encoding. For English text this may give better results. +

    +

    For these reasons the OCR functionality of pdfwrite can be controlled by using a new +parameter -sUseOCR. This has three possible values; +

    +
    -sUseOCR=string
    +
    +
    +
    Never
    Default - don't use OCR at all even if support is built-in. +
    AsNeeded
    If there is no existing ToUnicode information, use OCR. +
    Always
    Ignore any existing information and always use OCR. +
    +
    +

    + +
    +

    High-level devices

    PDF writer

    @@ -2081,7 +2133,7 @@ spot colors.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -2094,7 +2146,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -2122,7 +2174,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Drivers.htm b/doc/Drivers.htm index 596fef6d..47c5b052 100644 --- a/doc/Drivers.htm +++ b/doc/Drivers.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -1831,20 +1830,36 @@ Devices will normally implement this in one of the following standard ways:
    • Devices that don't do any imaging and don't forward any imaging operations (for example, the null device, the hit detection device, and the -clipping list accumulation device) simply return themselves, which -effectively ignores the compositing function.
    • +clipping list accumulation device) simply set *pcdev to themselves, and +return 0, which effectively ignores the compositing function.
    • "Leaf" devices that do imaging and have no special optimizations for compositing (for example, some memory devices) ask the -gs_composite_t to create a default compositor.
    • +gs_composite_t to create a default compositor device that +'wraps' the current device. They put this in *pcdev and +return 1.
    • Leaf devices that can implement some kinds of compositing operation efficiently (for example, monobit memory devices and RasterOp) inspect the type and values of *pcte to determine whether it specifies such an operation: if so, they create a specialized compositor, and if not, -they ask the gs_composite_t to create a default compositor.
    • +they ask the gs_composite_t to create a default compositor. They +place this in *pcdev and return 1.
    +

    In short, on every non-error return, *pcdev will be set +either to the leaf device (in the case where no special compositing is +required), or to the device that does the compositing. If the return +code is 1, then *pcdev is a new device that was created +to wrap dev to perform the compositing for it. Callers +may need to spot this case so as to update which device future +operations are sent to.

    + +

    For forwarding devices, for example, if the call returns 1, then +they should update their target device to be the new device. For the +graphics library, if the call returns 1, then it should update the +current device to be the new one.

    +

    Other kinds of forwarding devices, which don't fall into any of these categories, require special treatment. In principle, what they do is ask @@ -3030,7 +3045,7 @@ error code as usual, or one of the following values (see

    -
    int gs_text_release(gs_text_enum_t *pte, +
    int gs_text_release(gs_gstate * pgs, gs_text_enum_t *pte, client_name_t cname)

    Finish processing text and release all associated structures. Clients must call this procedure after gs_text_process returns 0 or an error, and may call it at @@ -3656,7 +3671,7 @@ non-rotated case.

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -3669,7 +3684,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -3697,7 +3712,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Fonts.htm b/doc/Fonts.htm index 31900929..bfc948df 100644 --- a/doc/Fonts.htm +++ b/doc/Fonts.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -348,7 +347,7 @@ your own fonts that you distribute.)


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -361,7 +360,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -388,7 +387,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/GPDL.htm b/doc/GPDL.htm index d8fca2ea..20bc722d 100644 --- a/doc/GPDL.htm +++ b/doc/GPDL.htm @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -566,7 +565,7 @@ instance and free all the resources.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved.

    +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -579,7 +578,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.23, 21 March 2018

    +Ghostscript version 9.54.0, 30 March 2021 @@ -606,7 +605,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/GS9_Color_Management.tex b/doc/GS9_Color_Management.tex index 0f78532b..fc980e86 100644 --- a/doc/GS9_Color_Management.tex +++ b/doc/GS9_Color_Management.tex @@ -1181,7 +1181,7 @@ Reading Massachusetts, 1999. \end{thebibliography} \vspace*{1.25in} -Copyright (c) 2019, Artifex Software Inc. All rights reserved. +Copyright (c) 2019-2021, Artifex Software Inc. All rights reserved. \end{document} diff --git a/doc/History9.htm b/doc/History9.htm index 51e9db32..bede0e58 100644 --- a/doc/History9.htm +++ b/doc/History9.htm @@ -44,7 +44,6 @@ TOC to see how to edit it for visual conciseness.
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -70,7 +69,8 @@ TOC to see how to edit it for visual conciseness.

    Table of contents

    For other information, see the Ghostscript +

    See Enabling OCR for more details. +

    See Enabling OCR for more details. overview. @@ -126,66 +131,59 @@ overview. -

    Version 9.53.1 (2020-09-14)

    +

    Version 9.54.0 (2021-03-19)

    +

    The 9.54.0 release is a maintenance release, and also adds new functionality. +

    Highlights in this release include:

    • -

      The 9.53.1 release is primarily maintenance. +

      Overprint simulation is now available to all output devices, allowing +quality previewing/proofing of PostScript and PDF jobs that rely on overprint. +See the -dOverprint option documentation in: +Overprint

    • -

      The most obvious change is the (re-)introduction of the patch level to the version number, -this helps facilitate a revised policy on handling security related issues. -

    • -
    • -

      Our efforts in code hygiene and maintainability continue. +

      The "docxwrite" device adds the ability to output to Microsoft Word +"docx" (it currently only handles text). +See: docxwrite

    • -

      We have added the capability to build with the Tesseract OCR engine. In such -a build, new devices are available (pdfocr8/pdfocr24/pdfocr32) which render the -output file to an image, OCR that image, and output the image "wrapped" up as a -PDF file, with the OCR generated text information included as "invisible" text -(in PDF terms, text rendering mode 3). -

      Due to some patches to the Tesseract sources that are required (integrated -upstream, but awaiting release), time constraints, and the experimental nature -of the feature, we only support including Tesseract from source, not linking to -Tesseract shared libraries. Whether we add this capability will be largely -dependant on community demand for the feature. +

      The pdfwrite device is now capable of using the Tesseract OCR engine when it is +built into Ghostscript to improve searchability and copy and paste functionality when +the input lacks the metadata for that purpose. See: UseOCR

    • -

      We have added Python bindings for the gsapi interface, can be found -in demos/python. These are experimental, and we welcome feedback from -interested developers. +

      Ghostscript/GhostPDL now includes a "map text to black" +function, where text drawn by an input job (except when drawn using a +Type 3 font) can be forced to draw in solid black. See: +BlackText

    • -

      For those integrating Ghostscript/GhostPDL via the gsapi interface, we -have added new capabilities to that, specifically in terms of setting and interrogating -device parameters. These, along with the existing interface calls, are documented in: -Ghostscript Interpreter API +

      Ghostscript/GhostPDL now supports simple N-up imposition "internally". See: +NupControl

    • -

      IMPORTANT: In consultation with a representative of -(OpenPrinting) it is -our intention to deprecate and, in the not distant future, remove the -OpenPrinting Vector/Raster Printer Drivers (that is, the opvp -and oprp devices). -

      If you rely on either of these devices, please get in touch with -us, so we can discuss your use case, and revise our plans accordingly. +

      Our efforts in code hygiene and maintainability continue.

    • -

      IMPORTANT: We have forked LittleCMS2 into LittleCMS2mt (the "mt" indicating "multi-thread"). -LCMS2 is not thread safe and cannot be made thread safe without breaking the ABI. Our fork -will be thread safe and include performance enhancements (these changes have all be been -offered and rejected upstream). We will maintain compatibility between Ghostscript and LCMS2 -for a time, but not in perpetuity. If there is sufficient interest, our fork will be -available as its own package separately from Ghostscript (and MuPDF). +

      The usual round of bug fixes, compatibility changes, and incremental improvements.

    • -

      The usual round of bug fixes, compatibility changes, and incremental improvements. +

      (9.53.0) We have added the capability to build with the Tesseract OCR engine. In such +a build, new devices are available (pdfocr8/pdfocr24/pdfocr32) which render the +output file to an image, OCR that image, and output the image "wrapped" up as a +PDF file, with the OCR generated text information included as "invisible" text +(in PDF terms, text rendering mode 3). +

      Mainly due to time constraints, we only support including Tesseract from +source included in our release packages, and not linking to Tesseract/Leptonica +shared libraries. Whether we add this capability will be largely dependent on +community demand for the feature. +

      See Enabling OCR for more details.

    For a list of open issues, or to report problems, please visit bugs.ghostscript.com. -

    Incompatible changes

    +

    Incompatible changes

    Included below are incompatible changes from recent releases (the specific release in question listed in parentheses). We include these, for now, as we are aware that not everyone upgrades with every release.

    @@ -234,13 +232,8825 @@ operators may stop working or may change behaviour. or the gs-devel mailing list would be best), and we'll work with you to either find an alternative solution or return the previous functionality, if there is genuinely no other option. -

    One case we know this has occurred is GSView 5 (and earlier). GSView 5 support for PDF -files relied upon internal use only features which are no longer available. GSView 5 will -still work as previously for PostScript files. For PDF files, users are encouraged to look -at MuPDF. -

    Changelog

    +

    Changelog

    +

    2021-03-29 12:09:07 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +28f5ec9d1b374449c89f7200e87ba855a97ebdd2 +

    +

    + Bug 703741: clear xstate_change flag on gsave
    +
    + xstate_change is used (partly) to track whether ExtGState parameters have
    + changed since the last "q" op, and thus whether we need to set them back again
    + (for the benefit of the pdf14 compositor) on the "Q" op.
    +
    + Previously, the flag was inherited by the "new" gstate created by a gsave,
    + so we could end up trying to reset the ExGState params at the wrong point.
    +
    + This is especially problematic with internally triggered gsave/grestore for,
    + for example, rendering glyphs, or accumulating patterns, etc.
    +
    + In other words, we currently can end up with a sequence like:
    +
    + q
    + <change ExtGState params> <- set the xstate_change flag
    + q <- flag still set
    + q <- flag still set
    + Q <- reset the ExtGState params, flag still set
    + Q <- reset the ExtGState params, flag still set
    + Q <- reset the ExtGState params, restores to gstate without flag set
    +
    + Whereas what we want is:
    +
    + q
    + <change ExtGState params> <- sets the xstate_change flag
    + q <- flag not set (still set in a gstate lower down the stack)
    + q <- flag not set (still set in a gstate lower down the stack)
    + Q
    + Q <- this returns the gstate with the flag to the top of the gstate stack
    + Q <- reset the ExtGState params, restores to gstate without flag set
    +
    + So, reset the flag during the gsave.
    +
    +base/gsstate.c
    +

    +

    +
    +

    2021-03-24 13:07:41 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +906f906617067aaf42e4e995cc63acdf9bded7c0 +

    +

    + pdfwrite - fix FastWebView with multiple put_params() calls
    +
    + When testing this I must have used a setup which either set the
    + OutputFile before setting FastWebView, or set them simultaneously. If we
    + have the two assignments in different calls, and the first call is not
    + to set OutputFile, then the assignment of FastWebView will not work.
    +
    + This is because we didn't check whether OutputFile was set before
    + checking if it was seekable, obviously a NULL file is not seekable! This
    + caused us to reset 'Linearize'. The subsequent call to set OutputFile
    + could not re-enable Linearize, and so linearization would not be
    + enabled.
    +
    + The fix here is simply to check that pdev->flle is not NULL before
    + checking if it is seekable.
    +
    +devices/vector/gdevpdfp.c
    +

    +

    +
    +

    2021-03-20 20:00:33 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +49a8691f19e9d7d1370f157d0cd423b4b5d5a526 +

    +

    + Fix a performance regression introduced by commit 813b5f48e8
    +
    + The fix is to keep the PageUsesOverprint parameter in the device
    + dictionary, not in the outer dictionary, and use it from there.
    +
    + It isn't understood why storing in the outer dictionary causes such a
    + substantial performance hit, but profiling shows that the time comes
    + from "dstack_find_name_by_index". The performance hit showed up with
    + j9_acrobat.pdf of the performance test suite (about 8%).
    +
    +Resource/Init/pdf_main.ps
    +

    +

    +
    +

    2021-03-22 09:51:06 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +db2a48697289ae2d53aeb3bbbf82276f0e85a134 +

    +

    + Automate tesseract build compatibility with clang++
    +
    + On MacOS (at least), clang++ requires the addition of the -std=c++17 to enable
    + support of the features that tesseract uses.
    +
    + Also, on Linux (at least) clang++ requires -stdlib=libstdc++ in order to
    + pickup a usable stdc++ library.
    +
    + So, tweak configure to test whether the compiler accepts the options to do both
    + the above, and if so, add them to the CXXFLAGS used to build tesseract.
    +
    + In addition, in configure, pickup CXXFLAGS so custom options can be set on the
    + configure command line.
    +
    +configure.ac
    +

    +

    +
    +

    2021-03-22 09:12:19 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +f40d70eeb5194a51fc585cb9ac9037c12557a826 +

    +

    + Tweak gitlog2changelog.py to exclude the per-commit file list
    +
    +toolbin/gitlog2changelog.py
    +

    +

    +
    +

    2021-03-22 12:09:55 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +4a7db3c313f4c3e0e5ea87510b0d353b4441368f +

    +

    + Add /utf-8 command to TESSCXXFLAGS in msvc.mak.
    +
    + Suggested by Akira Kakuto. I don't need this myself, but then my
    + default windows codepage is probably different to Akira's. Adding
    + this shouldn't cause any problems.
    +
    +psi/msvc.mak
    +

    +

    +
    +

    2021-03-22 09:11:11 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +73c5567d62b6e9278818c3077c1c3ea3b5ee43ee +

    +

    + Update change log post-9.54.0rc1
    +
    +doc/History9.htm
    +

    +

    +
    +

    2021-03-19 16:14:33 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +26009e688cf4275c252a9e060f30f006c1f1b9de +

    +

    + Fix crash in display device (seen with apitest.c).
    +
    + When calculating the size for the display, we setup a
    + fake gx_device_memory to call the calculation routine
    + with. Because we hadn't initialised the graphics_type_tag
    + sometimes it would incorrectly assume there was 1 more
    + plane than there should be.
    +
    + In calculating the required size, it would therefore add
    + in bitmap_raster(plane[i].depth * width) more bytes for
    + that plane. If plane[i].depth was negative, this would
    + cause the amount of memory we allocate to shrink, and
    + accordingly, we'd allocate too little memory.
    +
    + The fix is to ensure that the fake device is always
    + zero'd to start with.
    +

    +

    +
    +

    2021-03-19 13:39:37 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +42d688a1c90685d2123540416c60bcdf6b0db7dc +

    +

    + Update man pages to reflect SAFER is now the default.
    +

    +

    +
    +

    2021-03-19 13:13:21 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +48a8946f886b18b182868a9866b4927f80860510 +

    +

    + Erasepage optimisation - fix invalid device ordering assumption
    +
    + The erasepage optimisation device, when checking to see whether the
    + underlying device permitted optimisaton, was assuming that its own child
    + would always be the 'final' device. If we have a chain of subclass
    + devices this might not be true.
    +
    + Run down the chain to the fist non-subclass device and check that
    + instead. In future this should be replaced by a spec_op or something
    + but this resolves the problem for now.
    +

    +

    +
    +

    2021-03-19 09:51:25 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +a96257ec48dc13a1404990c4a473db88545dcc71 +

    +

    + Update dates, and changelog for 9.54.0rc1
    +

    +

    +
    +

    2021-03-16 09:24:00 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +905d82cc03d74a69a850eac16596267ed96473a5 +

    +

    + Update dates and changelog for 9.54.0 rc1
    +

    +

    +
    +

    2021-03-18 15:39:30 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +38a768a651fd4d11a6c27792067f59713f141634 +

    +

    + Drop DynaLab special bbox stretching of metrics
    +
    + For historical reasons relating to glyph caching the zchar42_set_cache
    + code used the minimum and maximum of the glyph bounding box and font
    + bounding box when setting the metrics of a glyph.
    +
    + This was done for DynaLab (one of the FreeType 'tricky' font types),
    + because these fonts abuse the TrueType 'hinting' mechanism.
    + Unfortunately this results in the wrong origin 1 being sent to
    + setcachedevice2, and hence CDevProc when the font is vertically
    + oriented.
    +
    + We no longer use this function for clipping, and the remaining client
    + pdfwrite doesn't use it for clipping but very much does use it for
    + gathering font metrics, so it is vital that these be correct.
    +
    + Since it's only used by pdfwrite, and testing suggests that DynaLab
    + fonts are not a problem for this, the code has been removed here. If
    + it should ever prove to be required then we should check the Font to
    + see if it is a DynaLab font. MuPDF has a function is_dynalab() for this
    + and we should use that if we prove to need it.
    +

    +

    +
    +

    2021-03-17 20:18:44 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +109cae320d32df84b26d668bc03b0068be4482f4 +

    +

    + Fix bug 703704: Matte in SMask is indirect reference.
    +
    + Thanks to Peter Cherepanov for this fix. This also catches /null Matte
    + entries.
    +

    +

    +
    +

    2021-03-17 15:33:59 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +bd711e60fb48e0dbedd40742dde58ac1e85a91ec +

    +

    + Make --disable-threads incompatible with including OCR
    +
    + Tesseract requires threading, even though Ghostscript doesn't actually call any
    + of the parts of tesseract that use threading, there is no sensible way to
    + leave it out.
    +
    + So, throw an error if --disable-threads is used when tesseract/leptonica is
    + present. The error includes a note to use "--without-tesseract" to avoid the
    + error.
    +
    + Also, fix a typo from a03ce3d6a130c843cb4dd91b7e767706973b4e22
    +

    +

    +
    +

    2021-03-17 11:06:42 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +157aab06770e5b0f3255e45866d578cac8ff861d +

    +

    + Pick up C++ compiler from configure script
    +
    + Rather than rely on the GNU make predefine.
    +

    +

    +
    +

    2021-03-16 17:48:43 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +ef8fc3115ea0361db31599400129c0e980f79ab1 +

    +

    + Rejig clist_mutate_to_clist for Coverity.
    +
    + Coverity spotted us accessing *the_memory without having checked
    + that the_memory != NULL first.
    +
    + In fixing that, I've taken the chance to tidy up the function a bit.
    +

    +

    +
    +

    2021-03-15 13:09:13 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +0e0611db144ac91c7b1825f94d100b7505a33a5c +

    +

    + Fix merge error causing CAL SEGVs.
    +
    + We were detecting plugins as being old format. This only shows up
    + in testing with CAL.
    +

    +

    +
    +

    2021-03-11 14:59:05 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +1c60ca5e897375dcd3afbb886fba8808e2e09e12 +

    +

    + Update copyright to 2021
    +

    +

    +
    +

    2021-03-11 15:14:21 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +628909cfa7b776c81461c511a88ee002ec51fcdb +

    +

    + Bug 703414 : Halftone artifacts
    +
    + There are two different representations of the turn-on-sequence
    + in GS. One of them uses an array of unsigned short integers that
    + indicate what bits get turned on. The array stores an address
    + offset into the bitmap tile that is created for a particular level.
    + The decision to use this representation is made in gsht.c
    + in the gx_ht_alloc_theshold_order method and is based upon the
    + width and height of the threshold array which indicates the total
    + number of addresses or offsets into the tile to reference which
    + bits get turned on in the tile by the turn-on-sequence. The tiles
    + themselves however are forced to have their rows raster aligned meaning
    + that if w*h <= 65535 the offsets into the tile dots can be larger
    + than 65535, which will not fit in the short turn-on-sequence array.
    + The code uses a different representation for the TOS if the number
    + of elements is less than 2000. Then it stores a pointer to a structure
    + for every element. That is the "default" implementation. Here
    + a uint (32-bit) implementation is added for cases where the tile is
    + larger than 65536 (e.g. bigger than 256 x 256). The implementation is
    + the same as the ushort case, but just uses four byte offsets for the TOS.
    +

    +

    +
    +

    2021-03-11 16:46:13 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +9ba7e720143cc11bfd54c26a548860e738b97dfc +

    +

    + Fix SEGV with -sNupControl=1x2 to pbmraw -r300 Bug693331.pdf
    +
    + This was due to the pdf14 getting confused during clist playback when the
    + 'master' page contained more than one nested page with transparency. Each of
    + the nested pages would PUSH, then POP the pdf14 compositor, but since the pdf14
    + compositor remains as the current device, the first POP 'disables' the pdf14
    + compositor and the subsequent PUSH 'recreates' the pdf14 device in active
    + compositing mode. The problem was that the 'recreate' did not perform all of
    + the setup of color_info, cmap_procs, and device procs needed for all of the
    + subsequent clist playback through the compositor.
    +

    +

    +
    +

    2021-03-10 17:48:37 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +aa26ed7d8cf0edda3db6c15dc7947ee8bea5ba3d +

    +

    + Add additional debug for halftones
    +

    +

    +
    +

    2021-03-11 19:25:00 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +3f1195b0523a1d3c8b80a47d7101e31954770767 +

    +

    + Bug 703687: Fix logic for alpha bits in do_fill_stroke()
    +
    + We can only do the GraphicsAlphaBits anti-aliasing if we are drawing with a
    + "pure" color (or a DeviceN color). Basically, not a pattern.
    +
    + For fill_stroke that means checking for the fill and stroke colors, but the
    + conditional was erroneously using "or" rather than "and" - so if either
    + color was pure, we'd try to use the alpha buffer, causing incorrect results.
    +

    +

    +
    +

    2021-03-11 13:09:52 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +224cafab373865f96f49ac186012bad63b99ff3b +

    +

    + Bug 703324 - restore fill state after fill+stroke path operation
    +
    + The file in bug 703324 fills and strokes a rectangle ('B' operator)
    + and sets the fill constant alpha to 1, and the stroke constant alpha
    + to 0, so that the stroke is not drawn. Pointless but that's what it
    + does.
    +
    + It then draws some text.
    +
    + Now the clist maintains an 'opacity' member, which is set and reset by
    + (amongst other things) looking at the fill and stroke alpha values. When
    + we do a fill+stroke we set the opacity to the fill alpha, and do the
    + fill, then we set it to the stroke alpha and draw the stroke.
    +
    + We then do an 'image_fill_masked' operation to draw the text bitmaps.
    + This device method does not take a graphics state as a parameter and so
    + is unable to set the opacity in the device based on the fill alpha. It
    + simply uses whatever opacity is current at the time. Because the
    + fill+stroke left this at the 'stroke' alpha, this is applied to the text
    + which (because the alpha is 0) is then not drawn.
    +
    + In addition the graphics state fill constant alpha value was left with
    + the wrong value, but fixing that wasn't sufficient. However we should
    + do both, and this commit resets the fill constant alpha in the graphics
    + state and recalculates the 'opacity'.
    +

    +

    +
    +

    2021-03-11 17:05:37 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +e2f1611a14000d6a2927ac49a865e5a954dd88b2 +

    +

    + Extract clist setup code from prn and display device.
    +
    + Move to a common clist_mutatable function.
    +

    +

    +
    +

    2021-03-11 18:38:18 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +d15d0ea0873ca27d4f3410d18603bfd0ad890fd5 +

    +

    + Fix exports for GPL DLL.
    +
    + This was preventing api_test working on windows.
    +

    +

    +
    +

    2021-03-11 17:08:00 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +08215797e95bb9db1c19e42b644829afb04a43ca +

    +

    + Fix MSVC warning.
    +

    +

    +
    +

    2021-03-11 17:07:11 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +3657ca38aec1e0b77e9b6c9aae62f03e212475b3 +

    +

    + Fix some comment typos.
    +

    +

    +
    +

    2021-03-11 08:58:30 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +becd66c4064abad46a2c1d2f35710555362a1502 +

    +

    + Fix bug 703681. Illegal Mask for image in PDF.
    +
    + Thanks to Peter Cherepanov for this fix. Check for the type of the Mask
    + entry, and ignore it (with an Error message) if not array or dictionary.
    +

    +

    +
    +

    2021-03-11 15:10:21 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +a30569c455b412e2f5ee05ad7df69059886f0a7e +

    +

    + Fix ordering of operators in FitPage
    +
    + Bug #703685 "Crash when using -dPDFFitPage"
    +
    + The 'cvi' in pdf_PDF2PS_matrix in pdf_main.ps here was meant (I think)
    + to apply to the /Rotate value from the page dictionary, but instead
    + was applied to the divisor, 90, which isn't needed because 90 is
    + obviously already an integer.
    +
    + If the PDF file (illegally) had a floating point number then the cvi
    + should convert it to an integer, so we need to move the cvi so that it
    + applies to the /Rotate value.
    +

    +

    +
    +

    2021-03-10 09:11:08 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +91dd2c391c7c68c172d387bd7d2e5904296b68f5 +

    +

    + Fix rangecheck from pdf_info when -dDumpXML is used and lines are > 256 bytes.
    +
    + Just dump the XML metadata rather than trying to suppress blank lines.
    +

    +

    +
    +

    2021-03-10 01:38:44 +0100 + +
    Sebastian Rasmussen <sebras@gmail.com>
    +8d4390862d0391430efd65e2bb5f9336231d4ff2 +

    +

    + Bug 703653: jbig2dec: Use correct freeing function for JBIG2 images.
    +
    + When jbig2_image_compose() errors out, remember to release all allocated
    + pattern images. Previously the most recently allocated image would not
    + be release.
    +
    + Finally remember to free the array of images itself.
    +

    +

    +
    +

    2021-03-09 19:48:59 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +f6ba75df38529d3c3d9c57cb9c99429d36ee3072 +

    +

    + Slightly tidy the tessocr.h interface.
    +
    + Delete an unused function, and move the ocr and hocr functions
    + to using ocr_init_api and ocr_fin_api as the others do.
    +

    +

    +
    +

    2021-03-04 21:14:46 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +4d2bf7b009922bef2efdbc3d0c8dcfe5d3a8cdb0 +

    +

    + Fix Bug 703648. Commit 00e7143ce9 caused this to surface by changing allocator.
    +
    + The clist_make_accum_device previously used the target device's allocator which
    + was 'system' VM, and commit 00e7143ce9 changed it to use 'local' VM which is
    + subject to save/restore. The sample file resutled in an extra rc_decrement of
    + the device on page 4 (from gx_pattern_accum_finalize during the restore).
    +
    + Fix this by using 'stable_memory' (from the mem allocator passed in) prevents
    + the restore from affecting the pattern-clist accumulator.
    +
    + Note the simple command line to reproduce is:
    + bin/gs -r1200 -sDEVICE=pgmraw -dBufferSpace=16m -o /dev/null \
    + Ad_Quark.ps Ad_Quark.ps Ad_Quark.ps
    + which results in "corrupted double-linked list"
    +

    +

    +
    +

    2021-03-09 09:35:04 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +62c5e1b5b6079cabf9008f12f7e038c413dda2d0 +

    +

    + Prevent segfault from -Z^ debug output.
    +
    + Tripped over this while trying to use it for reference count debug.
    + Tested on linux and Windows. No more hackish than the other constants
    + in this function.
    +

    +

    +
    +

    2021-03-09 12:13:35 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +e8ae31abf5a2b365f086d3ccf34f64c47503f565 +

    +

    + Fix documentation for moved display device test.
    +

    +

    +
    +

    2021-03-09 11:54:31 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +8747ffd4e32faab3fd08b48bc443d4094ae21a5f +

    +

    + Documentation fix - gdevdsp.h is no longer in base
    +
    + The links to gdevdsp.h in use.htm were (mostly) referencing base when
    + in fact the file is in the devices sub-directory.
    +

    +

    +
    +

    2021-03-01 18:28:54 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a5185dc45dd8c1981fbe5f46a0577ec0378bf449 +

    +

    + Fix compositor operation with subclassing.
    +
    + Compositors/PS2Write/Subclassing/Clist interact badly, due to the need
    + for the subclass code to 'tightly' wrap the original device, rather
    + than wrapping the created compositor.
    +
    + Use a new gxdso to handle the insertion of the device lower down the
    + device chain.
    +
    + This frees the subclass device of the need to know how to insert itself
    + into different types of device.
    +
    + Unfortuntely, the pdf14clist devices, when popped, assume that they
    + tightly wrap the actual clist device. This causes SEGVs when there
    + is actually a subclass device in the way.
    +
    + Accordingly, we update that code to find the correct clist device
    + in the stack, by using a new gxdso added for this purpose.
    +

    +

    +
    +

    2021-03-04 09:27:34 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +8fe5fb55424ebcc3ed66e8ce9a0fbfaac57aaa85 +

    +

    + Do not allow psd devices to change color model
    +
    + This keeps the psdcmyk device cmyk based and the psdrgb device rgb based.
    +

    +

    +
    +

    2021-03-03 13:08:34 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +8d95baab43318d1feecb70ee326734a883545484 +

    +

    + Fix erasepage_optimization device to allow for other subclass devices.
    +
    + The epo device assumed that it was the current device, then checked the child
    + of that device to decide if it could optimize. If another subclass device was
    + the current device the decision could be invalid.
    +
    + Note that the comparison of the child's fillpage proc is not ideal, but the
    + change to that is more involved and risky, and left for a subsequent change.
    +

    +

    +
    +

    2021-03-01 10:26:57 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +7a3dd047a07ed3f24bd388b72432990d9cd508fb +

    +

    + Fix page independence logic on the examples PostScript files.
    +
    + Back in 2001, commit f78b0481 added save/restore around the examples files,
    + but did not follow the recommendations from the PostScript Language Reference
    + Manual about save/restore and page independence and Technical note #5001.
    + The PLRM states (in section 3.7.3): "Each page has a save at the beginning
    + and a restore at the end, immediately before the showpage operator."
    +
    + This fixes the files, and allows them to work properly with usage that
    + expects correct page independence including -sNupControl=WxH and the use
    + of setpagedevice BeginPage/EndPage actions.
    +

    +

    +
    +

    2021-01-28 08:20:57 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +d9a13c96f9ac0cfcaaa843b7e51780de114cf48a +

    +

    + NupControl improvements to prevent save/restore problems.
    +
    + The NupControl string needs to be a reference counted to work with save/
    + restore, and when the parameter is changed the new value needs to be
    + propagated to children devices. The structure containing the string is
    + adpated (simplified slightly) from the PageList implementation.
    +
    + Note that the parents and children references must be included in the ref_count
    + when the NupControl structure is updated (example if 'epo' is installed, when
    + it uninstalls itself, cannot free the the structure when it does rc_decrement).
    +
    + Minor comment change to devices/gdevbit.c to change NupList to NupControl.
    +

    +

    +
    +

    2021-03-03 10:29:33 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +648a17ed91e089c11621053201c97c93304086c9 +

    +

    + Update gen_ordered to provide improved debug output
    +

    +

    +
    +

    2021-03-03 12:28:02 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +359cf3ce11c32a5c05c24028d8785902799cb2fc +

    +

    + Add another nmake variant.
    +

    +

    +
    +

    2021-03-02 15:26:24 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +f74dcd064d5de5e13ad907d7ac270bc82bb7858b +

    +

    + Extract build: Ensure zlib is used as an include path for extract.
    +
    + Without this, the Windows build fails, and (presumably) the linux
    + build is picking up the system zlib.h.
    +

    +

    +
    +

    2021-03-02 16:33:13 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +4698574e2711da90888915f0c5a7dc4644153689 +

    +

    + History/News updates
    +
    + And add an html link target for BlackText
    +

    +

    +
    +

    2021-03-02 09:21:58 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +590d3744111e267e2cebc09f3f7f98e6410704be +

    +

    + Update changelog and dates for 9.54.0 RC 1
    +

    +

    +
    +

    2021-03-02 15:25:21 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +db7f4bfc013549b22d8c30fbb75fc639bfb35799 +

    +

    + MSVC build: Detect and use 'extract' directory if it exists.
    +
    + This can be overridden by setting EXTRACT_DIR.
    +

    +

    +
    +

    2021-03-02 12:20:24 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +4f11ff15600c9d6ed8032f671f2e693388d01cc1 +

    +

    + Check for extract in a "default" location
    +
    + i.e. ghostpdl/extract
    +
    + as well as still allowing --with-extract-dir for custom locations.
    +

    +

    +
    +

    2021-03-02 12:23:17 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +6ac61452f9717536430a315fc832b5c64b3c02eb +

    +

    + Fix tessocr.cpp building on linux.
    +
    + Missing include file.
    +

    +

    +
    +

    2021-03-02 09:17:53 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +6425f74266dd66f6064dc8f24d0b827e39a18855 +

    +

    + Tweaks and corrections for News.htm
    +

    +

    +
    +

    2021-03-01 11:17:29 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +59eea43bf3f3e09182c0457d94b91c347f54bfbd +

    +

    + Fix seg faults in subclassing
    +
    + Commit a754bd375a625368567947b1e1b77ce3e5c06a3f fixed a different class
    + of seg faults, but unfortunately removed a crucial line of code.
    +
    + When the child device has pushed a compositor, we still need to check
    + to see if the compositor is pointing at the child device. If it is not
    + then the compositor must have pushed more than a single device, so it
    + is not safe to behave as if the target of the compositor is our child
    + device.
    +
    + Originally I had hoped to walk down the forwarding devices until we
    + reach our device, but the actual behaviour of the pdf14 device in
    + combination with the clist, when the final device is ps2write renders
    + that all but impossible, as well as unnecessary.
    +
    + In this case the compositor action starts by defining a new device,
    + It then pushes a pdf14_accum device (there are 3, one per device space)
    + it then pushes the pdf14clist device in front of that. Finally it turns
    + the device it first created into a forwarding device, and points its
    + target at the original device.
    +
    + So we return with 3 new devices pushed, not just one. However, the
    + final forwarding device is in fact forwarding to the subclassing device
    + and the device reference counting magic is applied to the forwarding
    + device, which means we don't need to dance around with the references
    + to the subclassing device and child.
    +
    + We could detect this condition by checking the name of the target device
    + of the pdf14clist forwarding device, but that isn't really any better
    + than simply assuming that the compositor takes care of inserting new
    + devices correctly. The pdf14_accum devices are not forwarding devices,
    + they store the pdf14 device in a member called saved_pdev14, so we can't
    + readily follow that either. Finally there is no way to determine if a
    + device is a forwarding device, or a gx_device_pdf14_accum type which
    + limits the amount of checking we cna perform.
    +
    + This is an interim commit to work around the problem, because we are
    + about to do a release. A better fix which eliminates all (we hope)
    + of the hidden assumptions and magic knowledge in the code here
    + will be committed shortly, but may be too risky for the release.
    +

    +

    +
    +

    2021-03-01 14:35:15 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +109fb95822a5c4fa6d7dc99ed120149acafd8341 +

    +

    + Edit release highlights text
    +

    +

    +
    +

    2021-03-01 11:58:04 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +79d04193b05200e1dd606c583c0b4e0b46520217 +

    +

    + Tidy up/add labels for URL destinations
    +
    + A few in VectorDevices.htm were wrong, and I added one in that file and a couple
    + in Use.htm for convenience.
    +

    +

    +
    +

    2021-03-01 13:01:02 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +6a3a11e8e9a1420702867afdd555dff62ab7ba20 +

    +

    + doc/VectorDevices.htm: added information about DOCX device.
    +

    +

    +
    +

    2021-02-25 09:36:18 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +fa775ffdd2ab6dff3b3178f9d36975308eeb9893 +

    +

    + Add documentation for NupControl (N-up printing) feature.
    +

    +

    +
    +

    2021-02-27 14:51:38 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +f06760e64c088ea24cd6a41c07cb459ecc690b05 +

    +

    + Add Colorant name for HalftoneType 5 components to -Zh output
    +

    +

    +
    +

    2021-02-26 08:03:56 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +1e30bb81fae075519db85af1bc7fb1658891627d +

    +

    + Bug 703273: Prioritise Nonsymbolic over Symbolic font flag
    +
    + The font in this PDF has it descriptor flags set to 36, that is bit 3 (Symbolic)
    + and bit 6 (Nonsymbolic) are both set. Since the two flags are mutually exclusive
    + this is clearly broken!
    +
    + Previously, we only test the Symbolic flag, since !Symbolic should imply
    + Nonsymbolic, which caused us to use the wrong encoding scheme.
    +
    + Now, we'll act on the Symbolic flag iff the Nonsymbolic flag is not set.
    +
    + (Originally a mupdf report, that also exhibited in Ghostscript).
    +

    +

    +
    +

    2021-02-26 09:38:27 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +5d0bd867b7d9fce50119adeae293568375fa8847 +

    +

    + Fix a few typos in the documentation of UseOCR for pdfwrite
    +

    +

    +
    +

    2021-02-22 19:57:35 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +1aa6a230ecc56ee3cb02459fbf6fc5e400e26eba +

    +

    + Bug 703265: Tweak create_compositor device method.
    +
    + Update create_compositor device method, so that it always returns
    + the compositor device (or the leaf device if there is no specific
    + compositor device). The device now returns 1 if we created a
    + compositor device to wrap the given device.
    +
    + This should enable us to identify exactly the cases where forwarding
    + devices need to update which device they forward to.
    +
    + In particular, this allows us to remove the horribly fragile code
    + in apply_create_compositor in gxclrast.c, and to ensure that we
    + correctly identify the 'new compositor' case.
    +
    + This avoids us sending stuff to the wrong device, and having to
    + cope with a slew of warnings.
    +

    +

    +
    +

    2021-02-25 09:16:33 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +8bc7ba4ba7df15310d406d5a1d8f6b755b04d13b +

    +

    + Update dates/docs for 9.54.0 RC1
    +

    +

    +
    +

    2021-02-22 18:53:09 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +5fc905ca8f04aa2a1088c3af635fd38bf9c8c3a0 +

    +

    + Remove Luratech integration code/makefiles
    +

    +

    +
    +

    2021-02-22 14:11:46 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +af92546c044b18a1796e269aba58c246ca977290 +

    +

    + Change GS_PRODUCT string, and dates for release
    +

    +

    +
    +

    2021-02-22 10:32:13 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +1430230bdf35928e5fb75eba631db3e5b89ce845 +

    +

    + Bug 703589: handle overlapping ranges in TTF format 4 cmaps
    +
    + The fonts embedded in this file contain a large number of overlapping/repeated
    + ranges in the format 4 cmap table definition - which is *strictly* not permitted
    + according to the spec.
    +
    + For example:
    + scode=117 ecode=117
    + scode=117 ecode=117
    + scode=118 ecode=118
    + scode=118 ecode=118
    + scode=119 ecode=119
    + scode=119 ecode=119
    + scode=120 ecode=120
    + scode=120 ecode=120
    + scode=121 ecode=121
    + scode=121 ecode=121
    +
    + Turns out, other consumers use the *first* mapping they encounter where, because
    + we use a Postscript dictionary to store the cmap table, later definitions
    + overwrite earlier ones.
    +
    + Resolved by checking if the key already exists in the dictionary, and not
    + overwriting it if it does.
    +

    +

    +
    +

    2021-02-10 09:35:39 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +9c7347c8e1bb146b9ae27b35b8207e10a7c5dc43 +

    +

    + Bug 703326: Create a new clip path for clist typed image handling
    +
    + Stupid fuzzing file uses a Type 3 font with a sampled image in the glyph
    + proc. The image uses a procedure as a data source. The glyph proc does
    + gsave, and the image data source procedure does a grestore. So by the time we
    + clean up the image "samples", the gstate and the clip path it contains have
    + gone. So the image enumerator's reference to the clip path is left dangling.
    +
    + Copying, rather than referencing, that clip path solves the crash.
    +
    + Fixes oss-fuzz issue: 26987
    +

    +

    +
    +

    2021-02-19 17:34:35 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +2c7a78d3e2ae6a3053827e915735e29eb16e12ba +

    +

    + Catch potential NULL derefence in gdev_prn_close.
    +
    + Thanks to Robin for spotting this.
    +

    +

    +
    +

    2021-02-19 11:02:40 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +fc5aa3b392cbd7c879b049d805a2afd158a05eb6 +

    +

    + Fix buffer overrun in ASCIIHexEncode
    +
    + This exhibited as a memory corruption error (buffer overrun) in pdfi.
    +
    + The ASCIIHexEncode filter is required to write linfeed characters to the
    + output at least every 80 (output characters). Ghostscript chooses to do
    + so every 64 characters. So every 64 characters the filter emits a
    + linefeed, crucially without checking whether there is room in the
    + output buffer.
    +
    + In order to determine how many linefeed characters we are going to need
    + to write into any given output buffer we divide the number of characters
    + in the output buffer by 65 (64 characters + linefeed), taking into
    + account any character slaready emiitted (stored as 'count' in the stream
    + state). We subtract that from the size of the output buffer, in order
    + to ensure that there is enough spare space for the linefeeds.
    +
    + Unfortunately, this is not sufficient. Consider an output buffer 194
    + bytes in size, on the first pass. We divide that by 65, which tells us
    + that 2 complete buffers will fit, so we need to reserve space in the
    + output for 2 bytes. We subtract 2 from the count, giving 192, We then
    + proceed to write the output data. We write 64 bytes of data, then a
    + linefeed, then 64 bytes of data, then a linefeed, then 64 bytes of data.
    + Total 194 bytes.
    +
    + At this point we have exhausted the output buffer, but because we have
    + written 64 bytes, we unconditionally write a linefeed. This is written
    + one byte beyond the end of the buffer.
    +
    + There are many ways to address this but I've chosen to change the
    + divisor from 65 to 64. This may mean that occasionally we will write one
    + input character (2 output characters) less than the maximum possible
    + to the output, but it will prevent the possibility of a buffer overrun.
    +

    +

    +
    +

    2021-02-18 17:59:26 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +d4c0981839bb2194040a9d15c8772e266ae235e3 +

    +

    + Fix bug 703557. Replace .sort procedure for use in SAFER mode
    +
    + Thanks to Peter Cherepanov for this patch.
    +

    +

    +
    +

    2021-02-18 08:19:45 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +a32419cebfe2db81aa5e838b95e5770241a22fb1 +

    +

    + Add Page Spot color list to output info
    +

    +

    +
    +

    2021-02-18 08:07:22 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +32c912d6d6b12956f69056c0e7f3050c5aabf2d4 +

    +

    + Address Coverity 365984 -- 'code' variable set but not used before changed.
    +

    +

    +
    +

    2021-02-18 15:52:00 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +4fa213b9cd6f310bc6dd236ecce2d549ed3c5a55 +

    +

    + devices/vector/gdevdocxw.c: default to spacing=0 when calling extract_process().
    +
    + This gives better output, e.g. for zlib.3.pdf.
    +

    +

    +
    +

    2021-02-16 15:13:40 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +cda1ad8f402829c4677f73d8f805b119632dad5f +

    +

    + devices/vector/gdevdocxw.c: fixed creation of .docx when not using file-per-page.
    +

    +

    +
    +

    2021-02-16 15:01:27 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +4e9c31c3b6660d50afbca498ceddf0179ca2540c +

    +

    + toolbin/localcluster/clusterpush.pl: have rsync expand links if product is extractgs.
    +
    + This allows one to have ghostpdl:extract be a soft link, e.g.:
    + extract -> ../mupdf/thirdparty/extract
    +
    + Also use rsync -i instead of -v if $(verbose) is set so that one can see
    + exactly what files are being transferred etc.
    +

    +

    +
    +

    2021-02-16 14:58:47 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +895c5bc12814d4106a106afaddea5dcdd2d0519d +

    +

    + toolbin/localcluster/clusterpush.pl: fix exclude of extract binaries within ghostpdl.
    +
    + The previous exclude arg only worked when extract directory was
    + thirdparty/extract inside mupdf (typically a submodule).
    +
    + Also added exclusion of extract/test/generated/ to avoid locally-generated
    + files being uploaded.
    +
    + Restored exclude of /src/build/ because needed for product=extract.
    +

    +

    +
    +

    2021-02-16 14:55:36 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +2e06b811daafbc95487727f88b9ec7398a250963 +

    +

    + psi/msvc.mak: remove 'Not building with extract' diagnostic.
    +

    +

    +
    +

    2021-02-18 16:44:43 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +fafb962c4f57b4b7d8e724414e3762f209099b99 +

    +

    + Windows gpcl6/ufst project: use better/correct targets
    +
    + Firstly, the recursive call to nmake was using the wrong target name (an
    + internal use target), so fix that to use the "real" target.
    +
    + Secondly, give the "real" target a better name, more in keeping with other
    + equivalents.
    +

    +

    +
    +

    2021-02-18 09:51:01 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +a3cfccc2401222818dd4d587fd5c695811427bc4 +

    +

    + Initialise some PDF-specific portions of the graphics state
    +
    + The text rendering matrix and text line matrix, which are PDF-specific,
    + were not being initialised when the graphics state was created. This
    + should not be a problem in normal operation because the PDF interpreter
    + should always initialise them before use.
    +
    + However, during development on pdfi it did show up so this commit
    + initialises the matrices to the identity.
    +

    +

    +
    +

    2021-02-17 23:01:03 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +72fcae41c44e4cf33e57b34b748521a00612be21 +

    +

    + Bug 703578 : XPS to PDF missing stroke
    +
    + Caused by my "fix" for the pattern issue. I was inadvertently setting
    + ca and CA to 0 during the gradient strokes.
    +

    +

    +
    +

    2021-02-17 13:05:35 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +331fcb49b62a615976711cccdd3ff9796152a323 +

    +

    + Fix bug 703245: bitmap size exceeds buffer.
    +
    + The pdf14 compositor changes the color depth to 8 for a SMask, but the
    + compositor actions were not being put in all the bands needed. In this
    + case the copy_color_alpha was output from the interpolation logic because
    + the image gridfitting expanded the image. Fix it by expanding the top and
    + bottom limits for the "temp_cropping" which controls the RECT loop writing
    + the compositor info to the bands.
    +

    +

    +
    +

    2021-02-17 19:32:11 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +8608819c8531174290d6075ad5747bd0b0f32d4b +

    +

    + Bug 703577: Correctly initialise texture data pointer.
    +
    + The ROP in use was failing to initialise the texture data pointer.
    + Amazing that this doesn't show more problems.
    +

    +

    +
    +

    2021-02-17 08:16:25 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +a28c4d3d22156086db3b53011824a88847d114e1 +

    +

    + Minor improvement to gx_ht_construct_threshold debug
    +

    +

    +
    +

    2021-02-16 22:35:57 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +7a3df79b2b0e0725753a0eac84fb205341cc9fed +

    +

    + Bug 703404: XPS to pdfwrite patterns
    +
    + Patterns that are filled with glyphs and then subsequently
    + filled with another pattern (Visual brush in XPS) was not
    + working when going to pdfwrite due to the fact that
    + gs_text_begin gets called by the XPS interpreter
    + before we have finished the pattern fill of the glyph.
    + This ends up referencing the pattern that is not done
    + which ends badly for high level patterns. Instead
    + if we are already in a high level pattern, set the color
    + to just a gray. Then after the gs_text_begin, the XPS
    + interpreter sets the brush to the visual brush which is
    + subsequently collected. Fixing this, has revealed another
    + XPS to PDF bug where we are not doing shading fills of glyphs
    + correctly (at least when dealing with patterns).
    +

    +

    +
    +

    2021-02-17 17:28:29 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +66200b6fafe8b4de6fd11d1b38ccb85eb3d37d83 +

    +

    + Add the cup "images" directory back so the docs work
    +
    + The cups source has shtml documentation dotted through it, and that references
    + images in the "images" directory (which we removed originally, thinking it
    + wasn't necessary).
    +

    +

    +
    +

    2021-02-17 16:04:27 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +82dce7f8f6b5218f7943eadff0f01d0e278850fa +

    +

    + Update lcms2mt to lcms2 2.12.
    +

    +

    +
    +

    2021-02-16 14:28:52 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +5882f2d765a9348c6f6e2cc45353a06924930c88 +

    +

    + Chunk allocator was using unsigned int rather than size_t.
    +
    + Both in the main allocator routine and in the structures. Solved
    + here.
    +

    +

    +
    +

    2021-02-15 17:22:28 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a634d187722befab735da23957d938f156b6cf8f +

    +

    + Change macro names to be less confusing.
    +
    + The graphics state contains pairs of color/colorspaces. The 0th ones
    + are known as 'current' ones. The 1st ones have historically been known
    + as 'alt' ones.
    +
    + This nomenclature is held to be confusing, as 'alternate'
    + colors/colorspaces mean something quite different. We therefore update
    + the macros etc to refer to these as 'swapped' ones, which fits better
    + into our usage.
    +

    +

    +
    +

    2021-02-15 16:26:18 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a67862f2f7ec3826ac1f55947ebdbfe740c1829f +

    +

    + Fix 'cast away const' warning in gdevplnx.c
    +
    + We do this by splitting gstate_clone into gstate_clone_for_gsave
    + and gstate_clone_for_gstate. The latter can have the source gstate
    + as being const, as you'd expect.
    +
    + This enables gs_gstate_copy to similarly take a const gstate, as
    + you'd expect.
    +

    +

    +
    +

    2021-02-15 17:09:20 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +4618b1dea2e55fa0a39f8fa216e4965785ed8d21 +

    +

    + Squash warnings in gdevwpr2.c
    +

    +

    +
    +

    2021-02-15 16:24:41 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +83118eaa3e8733d8755eef21b3b404ce0ee97123 +

    +

    + Add cs_adjust_altcounts_icc.
    +
    + This enables us to avoid swapping colors twice in every
    + gstate_clone.
    +

    +

    +
    +

    2021-02-16 19:58:28 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +564e9365b8803903d077cd7deca247e65d8f7a29 +

    +

    + Memento fix: Memento_strdup was inconsistently defined.
    +

    +

    +
    +

    2021-02-15 19:09:50 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +f95b2611921546b424d899a5828341f6c4c9a52a +

    +

    + Add 'extractmu' and 'extractgs' to clusterpush.pl
    +

    +

    +
    +

    2021-02-09 17:48:35 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +eff4e8fca8ebbc75b00e7c1d2e672d17090b2222 +

    +

    + Quell Memento warnings in debug non-Memento builds.
    +

    +

    +
    +

    2021-02-15 12:34:05 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +19baed479febdc6372c7b3fccf6e97d71fca1b95 +

    +

    + Squash warnings in DEBUG code in gsalloc.c
    +

    +

    +
    +

    2021-02-11 09:27:23 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +1efe1f702f9723dec2803395cf4679593987c422 +

    +

    + Bug 703550: handle escaped percent chars in file access controls
    +
    + The separating devices make a (fairly blunt) effort to avoid attempting to use
    + proscribed characters in file names for separations (for example, '/', '\',
    + etc). As part of this some characters can be replaced with escaped percent
    + chars - so the single percent character survives a later call to a formatted
    + string function (sprintf).
    +
    + This ended up foxing the file access validation code which added the fully
    + escaped file name string to the permit write table, but later attempted to
    + validate a file name post sprintf, where the escaping had been undone.
    +
    + So, add code to remove escape '%' characters before adding the string to the
    + file access permit lists.
    +

    +

    +
    +

    2021-02-12 14:33:58 +0000 + +
    Peter Cherepanov <sphinx.pinastri@gmail.com>
    +0ca4ae94020a1e3b48c337759ccb9fc0b3af61ec +

    +

    + Bug 702910: Fix mkromfs for THREADSAFE build
    +
    + Since local versions of errprintf_nomem() and errprintf() are mostly
    + identical, we can just call errprintf() with a dummy mem argument.
    +
    + The "mem" argument for errprintf() inside GhostPDL is used to ensure
    + the error prints are directed to/through the correct gs_lib_ctx
    + instance for the current thread
    +
    + This is safe because, mkromfs is only using during the build, and won't
    + ever implement threading, thus has no need to worry about the extra
    + parameter.
    +
    + (slightly tweaked patch to keep working without THREADSAFE)
    +

    +

    +
    +

    2021-02-12 14:30:44 +0000 + +
    Peter Cherepanov <sphinx.pinastri@gmail.com>
    +28d3245fbaff5f6edc74fe3fc21237d69672e947 +

    +

    + Bug 703294: Fix Ghostscript build for Android
    +
    + Header files shifted around so that the redefinition of printf happens
    + after cdefs.
    +
    + Also removes redundant CONTDEVH definition from contrib/contrib.mak
    +

    +

    +
    +

    2020-11-23 14:09:31 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +b151406bbf22fb9001895f856168166f2ecf7fe2 +

    +

    + Added docxwrite device; uses extract library to write docx output.
    +
    + Summary:
    + This adds a new docxwrite device which generates docx files.
    +
    + Unlike the txtwrite device, we don't output xml for later use by
    + extract-exe or store information about spans in arrays. Instead we call
    + extract functions such as extract_add_char() directly.
    +
    + Code changes:
    + Have moved txtwrite and docxwrite common code into new devices/vector/doc_common.{c,h}.
    +
    + Shared types and functions are currently:
    + txt_glyph_width_t
    + txt_glyph_widths_t
    + txt_glyph_widths()
    + txt_get_unicode()
    + txt_char_widths_to_uts()
    + txt_calculate_text_size()
    +
    + Building:
    + By default we do not build with Extract and there will be no docxwrite
    + device in the final executables.
    +
    + To build with Extract, specify the location of the extract checkout to
    + build and link with.
    +
    + Unix:
    + ./autogen.sh --with-extract-dir=<extract-dir>
    +
    + Windows:
    + Set environmental variable EXTRACT_DIR=<extract-dir> when building,
    + e.g.:
    + EXTRACT_DIR=<extract-dir> devenv.com windows/GhostPDL.sln /Build Debug /Project ghostscript
    +
    + On both Unix and Windows we exit with an error message if the specified
    + location does not exist.
    +

    +

    +
    +

    2021-02-12 03:39:30 -0800 + +
    Robin Watts <Robin.Watts@artifex.com>
    +833dc8c9ffde58f001308b303c8d7956107633a1 +

    +

    + Fix build failure with HAVE_VALGRIND and not PACIFY_VALGRIND
    +

    +

    +
    +

    2021-02-12 15:25:56 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +180419375973b9ce4664286a67106d712260ef7f +

    +

    + Remove .setpdfwrite from the documentation
    +
    + Deprecated in 9.50 removed in the next release (9.54)
    +

    +

    +
    +

    2021-02-12 10:34:23 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +7861fcad13c497728189feafb41cd57b5b50ea25 +

    +

    + oss-fuzz 30715: Check stack limits after function evaluation.
    +
    + During function result sampling, after the callout to the Postscript
    + interpreter, make sure there is enough stack space available before pushing
    + or popping entries.
    +
    + In thise case, the Postscript procedure for the "function" is totally invalid
    + (as a function), and leaves the op stack in an unrecoverable state (as far as
    + function evaluation is concerned). We end up popping more entries off the
    + stack than are available.
    +
    + To cope, add in stack limit checking to throw an appropriate error when this
    + happens.
    +

    +

    +
    +

    2021-02-11 22:32:50 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +ea1624205c8e1ca936bd38a6095a0dd1880e7287 +

    +

    + Fix hang condition detected on Windows release build.
    +
    + The NupControl commit changed 'gx_device_set_hwsize_from_media' to call the
    + dev_spec_op of the parent device, but the body of the while loop to find the
    + uppermost parent could hang.
    +

    +

    +
    +

    2021-02-11 11:12:34 -0800 + +
    Robin Watts <Robin.Watts@artifex.com>
    +76b7cdd9c407afc5c620dbfb79770bb5583cf532 +

    +

    + Pad PDF14 buffer allocations when building with CAL.
    +
    + This allows for SSE/AVX to overread slightly when reading
    + 16 bytes at a time.
    +

    +

    +
    +

    2021-02-10 18:07:07 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +b5e44d6709642727ee524cccd2b5ab09f2e48572 +

    +

    + oss-fuzz 30795: handle remap_color failure in clist_begin_typed_image
    +
    + In this case "remap_color" is gx_concretize_ICC() and the link profile
    + creation fails. Previously we were ignoring the error, and trying to use the
    + resulting (invalid) color space.
    +

    +

    +
    +

    2021-02-09 14:17:01 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +7351373f5e3e8d9cd8c75be7d176570f95bd7c97 +

    +

    + Add a VS project to build gpcl6 with ufst
    +
    + (stemmed from Bug 703415)
    +

    +

    +
    +

    2021-02-09 14:08:54 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +7a92c21b4a842cfa90134eb46544d142cc4c13d0 +

    +

    + Bug 702362: "make soinstall" install GhostPDL
    +
    + If available, have "soinstall" the libs and binaries for gpcl6, gxps and
    + gpdl.
    +

    +

    +
    +

    2021-02-10 16:46:16 -0800 + +
    Robin Watts <Robin.Watts@artifex.com>
    +2abffa72c2ac815df38927431744232ae421d42d +

    +

    + Fix CAL CFLAGS.
    +

    +

    +
    +

    2021-02-10 16:03:40 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +7395ad17d12b0c8b420fd7a8d139baf52d9791e0 +

    +

    + Update docs.
    +

    +

    +
    +

    2021-02-10 14:24:24 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +7a469b14c88409b96614e6b8abe2b645078ded3a +

    +

    + Bug 703555 : Seg fault in pdf14_dev_spec_op
    +
    + So the issue is that the pdf14 clist device was not
    + doing its clean-up and set to forwarding when there was an
    + abort for the device sent by the interpreter.
    +

    +

    +
    +

    2021-02-10 14:44:51 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +9699aea5cf6491106a2ad1be260d9eb2e85903c3 +

    +

    + Remove .setpdfwrite
    +
    + This has basically done nothing for years and in September 2019 I
    + added a warning message that it was deprecated and would be removed.
    +
    + Time to make good on that promise.
    +

    +

    +
    +

    2021-02-03 09:25:37 -0700 + +
    Chris Liddell <chris.liddell@artifex.com>
    +6f6c88f92f98d0f8340c29201c7536ec1a521efd +

    +

    + Sort tifftop.c dependency on jpeg headers
    +
    + Spotted in testing the Apple M1 Mac builds
    +

    +

    +
    +

    2021-02-07 19:19:15 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +141e5067e40d25ed3aa191589d4a325941efa57a +

    +

    + pdfwrite - don't try to linearize when the output file is not seekabkle
    +
    + No bug report. The linearization (-dFastWebView) 'feature' of pdfwrite
    + relies upon being able to seek in the output file. If we can't do that
    + then we can't linearize the file.
    +
    + If linearization is enabled, check the output file is seekable; if it
    + is not then warn the user and abort linearization.
    +

    +

    +
    +

    2021-02-07 15:04:36 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +4ab5dd6c004a252e64f26d6238799004f70d4a35 +

    +

    + pdfwrite - further checks on Title for PDF/A
    +
    + Bug #703486 "PDF containing just a JPEG converted to PDF/A-1b fails rule 6.7.3-1"
    +
    + The PDF file, produced by ImageMagick 7 has a /Title in the Document
    + Information dictionary which appears to be UTF-16BE encoded, but is
    + lacking the BOM. It also has a 2-byte NULL appended which seems likely
    + to be an error as well (PDF strings are not NULL-terminated).
    +
    + This is valid (if not useful) as a string with PDFDocEncoding, though
    + Acrobat displays an empty string in the Document Properties, but when
    + converted to a text string for the output Document Information
    + dictionary, and a UTF-8 string for the XMP, the two strings are not
    + byte-for-byte identical, resulting in a PDF/A validation error.
    +
    + Add some more checking for character codes which will result in UTF-8
    + and PDFDocEncoding strings which do not match (anything outside the
    + range 0x20 to 0x7F, or escaped).
    +

    +

    +
    +

    2021-02-06 12:56:36 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +7e8b585e7577044dc1d6a9a36d715be12fc2524c +

    +

    + Fix bug 703487. pageusesoverprint needs self-reference check for Parent.
    +
    + Ken's fix for bug 698372 is needed in the procedure that I added to check
    + for overprint usage.
    +

    +

    +
    +

    2020-11-14 18:26:21 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +813b5f48e845d528d3070d9168aa51035a614c1c +

    +

    + Bug 695925: Implement overprint simulation for all devices
    +
    + This adds the capability to simulate overprint including that of
    + spot colors for all devices including gray and RGB devices. This
    + is achieved by having the PDF interpreter look if overprint
    + is present, the seting of -dOverprint (/simulate /enable /disable),
    + if the page has transparency, and if the page has spot colors. Depending upon
    + the color model of the device, and if transparency is present,
    + a special push of the pdf14 device may occur. The pdf14 device
    + buffer collects the data in a CMYK or CMYK+spots buffer and the
    + put_image method in the pdf14 device will map the buffer to
    + the target device color space. The code was tested with
    + devices that support and do not support spot colors, those that
    + support and do not support alpha channels, tag based devices,
    + gray, RGB, and CMYK devices. A special test file to check
    + multiple cases was added to the regression suite. By default
    + -dOverprint is set to /enable, which should result in the existing
    + behavior where by RGB and Gray devices do no show overprint or spot
    + colors and CMYK devices will handle CMYK overprinting and separation
    + devices will show spots and overprint of all colorants. With
    + -dOverprint set to /disable no device will show overprinting. With
    + -dOverprint set to /simulate all devices will show overprint and
    + spot colors. Ray Johnston did the work in the interpreter as
    + well as the device parameter default setup. I did the pdf14 device
    + changes and testing. Changes in a variety of locations were required
    + due to the fact that new combinations were encountered, for example
    + we had cases where devn colors were being used with a device that
    + supports tags (bitrgbtags device and pdf14 compositor setup for CMYK+spots).
    +
    + One file:
    + tests_private/xps/xpsfts-a4/fts_34xx.xps.pdf ppmraw 72 now produces
    + an error. This file should have been throwing an error all
    + along but was being quietly swallowed. Acrobat will not open
    + the created pdf file and throws and error. I will open a bug
    + for the issue as it is a problem with the XPS interpreter.
    +

    +

    +
    +

    2021-02-05 11:59:45 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +0bd6877f480a84657696a80adc13f9c5485dd996 +

    +

    + Remove vestigial documentation
    +
    + The NOCCFONTS feature was removed some years back and the documentation
    + removed from fonts.htm, but a vestige remained in use.htm.
    +

    +

    +
    +

    2021-02-04 16:34:58 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +8cac642a1caf0ff821b2f1f83ee322a1cffc9a3e +

    +

    + oss-fuzz 22842: sanity check the claimed number of objects in a PDF
    +
    + This test case is a file that we identify as a broken PDF, and attempt to
    + repair.
    +
    + As part of trying to repair the xref, we an extremely large value integer which
    + we take to mean the number of objects in the file, and then attempt to loop
    + over them. The result is, in practice, an endless loop.
    +
    + On the basis that the very barest PDF object:
    + 1 0 obj
    + endobj
    +
    + takes 15 bytes to define, we add a check: if the number of claimed objects is
    + greater than the number of bytes in the file divided by 15, then the number
    + is not to be trusted, and we dicard it.
    +

    +

    +
    +

    2021-02-04 13:42:51 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +180f35cecf582c0cd321e5d5cd8e11c4304ec519 +

    +

    + oss-fuzz 25846: Store "printable" refs for errors
    +
    + When we get an op/dict/exec stack overflow error, we take a copy of the stack
    + in question, and store it in an array (or as much of it as we feasibly can).
    + That allows us to clear enough stack space to allow the error handler(s) to run
    + without losing the information needed to report the error.
    +
    + With the exec stack, however, that can (and usually does) include references to
    + "internal" objects, which are really just pointers to arbitrary C structures,
    + (t_struct and t_astruct ref types). Those can contain pointers referencing
    + objects of unrelated and uncertain lifespans, so persistent storage of them is
    + potentially problematic.
    +
    + So, when we create that array representation, replace every t_struct and
    + t_astruct object with a printable string representation.
    +
    + This isn't a big problem for speed because a) exec stack overflow is a rare
    + error b) for exec stack overflow, we already have to traverse the objects
    + checking for another condition, and c) we already do (basically) the same
    + conversion considerably later, for the benefit of the error handler.
    +

    +

    +
    +

    2021-02-04 09:05:42 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +a9a440babc49ed54d0086cd9e5faa9bdd3452e51 +

    +

    + Fix build failure
    +
    + gsparamx.c is now required in the "base" configuration, since it contains
    + function(s) now being called from gsdparam.c
    +

    +

    +
    +

    2021-02-04 08:30:31 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +f9583327eeaf733cf44eb02790994308d4b9e91b +

    +

    + Fix Coverity ID C366347
    +
    + Removing some code revealed a pre-existing pointless operation; we were
    + setting the render mode twice.
    +

    +

    +
    +

    2021-02-03 16:38:39 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +6665826ff3b0ec30e3c084c5b550006a2b7c9bf5 +

    +

    + txtwrite - fix a load of memory leaks
    +
    + Noticed while working on some bug reports. The memory cleanup hadn't
    + been updated when a bunch of members were added to the tracking data.
    +
    + In addition the font name was allocated and recorded (and then over
    + written on the next pass) for every character in the text. Oops!
    +
    + All these are fixed here. I've run a couple of hundred random PDF
    + files from our test repository with memory leak checking and found
    + no leaks.
    +

    +

    +
    +

    2021-02-02 19:15:44 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +4021e019eaccffb809595b90d04626f337f5e237 +

    +

    + Bug 703452: Add type checks for error dicts
    +
    + This is, at best, a theoretical problem now, but for extra safety, ensure the
    + values we read back from systemdict for the /gserrordict and /errordict keys
    + are actually dictionary objects before looking up the error key in them.
    +

    +

    +
    +

    2021-02-02 19:06:12 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +32867dfea274afaf5e335ec8f2691b4cfed88b78 +

    +

    + Bug 703454: Handle multiple CharString definitions
    +
    + The test file for this has a number of Type 1 fonts whose CharStrings
    + dictionary definitions contain more than one entry for several glyph names.
    + According to Postscript rules (which Type 1 fonts are supposed to follow),
    + defining a key/value pair for which the key already exists in the dictionary
    + should overwrite the earlier value - i.e. the later definition takes
    + precedence.
    +
    + It appears that the non-Postscript based implementations used in other
    + PDF consumers do not honor that, and the earlier definition ends up taking
    + precedence.
    +
    + To work around various other PDF embedded Type 1 font breakages, we push an
    + extra dictionary onto the dict stack which contains definitions for missing
    + procedures, and various other "fixups".
    +
    + To work around this problem, we add a new definition of the Postscript "def"
    + operator which, *only* for the CharStrings dictionary, will not allow existing
    + keys to have their values replaced.
    +

    +

    +
    +

    2021-02-01 10:22:03 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +c23d68c1e8da7a4e4134b143f147427092b3d2f2 +

    +

    + Replace -dSimulateOverprint boolean with multi-valued -dOverprint
    +
    + Internally the name is changed to "overprint_control" which has enum values
    + of gs_overprint_control_t. This is in preparation for Michael Vrhel's
    + overprint simulation implementation.
    +
    + Documentation of the change and the new parameter specifics added to the
    + doc/Use.htm file. Also added change to gs_init.ps so that command line use
    + of -dSimulateOverprint=true maps to -dOverprint=/enable and similarly,
    + -dSimulateOverprint=false maps to -dOverprint=/disable with a warning.
    +

    +

    +
    +

    2021-02-01 09:44:14 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +322d21b4c04d2f64583630de4b190ce8d3b0721d +

    +

    + Fix building mkromfs in a memento build
    +
    + Adding malloc_.h to gp_ntfs.c means it gets the memento redefinitions of
    + malloc/free. That causes missing symbols errors when gp_ntfs.c is used in the
    + mkromfs build. So (as we do for other such cases) add those missing symbols
    + to mkromfs.c.
    +

    +

    +
    +

    2021-02-01 16:21:24 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +41130dd35b2dc43b07600b51d7c9fab466e8bf6c +

    +

    + PDF interpreter - work around broken ObjStms (again)
    +
    + Bug #703448 " Ghostscript can't read files that poppler, mupdf and Firefox and others can read"
    +
    + The problem is in an OObjStm, a compressed representation of various
    + PDF objects. In the example file the ObjStm returns a lone 'mark'
    + object for one of the compressed objects, which is not legal.
    +
    + This appears to be the font T1_2 on page 87.
    +
    + The mark confuses our counting of the returned objects and that leads
    + to the interpreter falling in a heap.
    +
    + There's no trivial way to address this, so I've chosen to use the
    + approach used for error handling in other places; push a specific name
    + onto the stack, and then use that instead of a mark to delimit the
    + portion of the stack of interest.
    +
    + Obviously nothing is going to rescue the broken font; but since this is
    + a PDF file which has been OCR'ed I don't think this is a problem as we
    + will not to try to use it for rendering as the text is all 'drawn' in
    + text rendering mode 3 (neither fill nor stroke).
    +
    + Because we keep using this I've also added a couple of utility procedures
    + CountToKey and ClearToKey, which work similarly to countomark and
    + cleartomark. Because I wanted to be able to detect a missing key on the
    + stack CountToKey returns a boolean, not just a number.
    +
    + I've also used that approach around the verify_page_tree call so that
    + we don't end up with a pile of junk on the stack if it should fall
    + over similar errors in future.
    +
    + Finally I tested with the customer supplied file which originally
    + inspired the changes in resolveobjectstream to detect the last kind of
    + broken ObjStm and that file continues to work.
    +

    +

    +
    +

    2021-02-01 14:47:07 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a6c2b025f820dd06cb94014ed5f040ddb203f97d +

    +

    + Update tesseract build for latest versions.
    +

    +

    +
    +

    2021-02-01 13:14:24 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +ce2fcde6d32586ef468fd56121ffd7d66d03b613 +

    +

    + Fix leptonica compilation due to removed file.
    +

    +

    +
    +

    2020-09-06 11:23:35 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +dfed81f5a657a67f672777389bff70d6d31253f7 +

    +

    + A customer (#584) file exposed a problem with Link handling
    +
    + Thanks to Ken Sharp for this fix. He discovered that if annotsetcolor
    + returns false, the annotation did not return false.
    +
    + This occurred with the test file received from that customer on 9/1/2020
    +
    + Note delayed commit due to proximity to release.
    +

    +

    +
    +

    2021-01-30 15:45:34 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +5bbb4c7e686ddfb28b27e0a790dabef6338ffa6d +

    +

    + txtwrite - fully initialise a structure
    +
    + Bug #702960 "Valgrind error in clamp_poin_aux on txtwrite device"
    +
    + Initialise all members of the structure to 0.
    +

    +

    +
    +

    2021-01-30 11:00:08 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +d787dad3cd310788ea7201eb2fe1fff9a0a263c2 +

    +

    + txtwrite - Address some memory handling problems
    +
    + Bug #703143 "segfault in ps2txt with certain large file"
    +
    + There are two problems here; firstly the textw_text_release()
    + function is called *from* gs_text_release, and should not be calling
    + that function. This was the initial cause of the seg fault.
    +
    + Secondly the txtwrite custom text enumerator was not declaring the
    + 'pte_fallback' text enumerator member, which meant that it could be
    + relocated without updating the txtwrite text enumerator, leading to
    + seg faults further through the processing.
    +
    + This resolves the seg faults on the supplied test file for me, but there
    + are still memory problems (memory leaks in fact) revealed by running
    + under Memento. I'll address these in a later commit or commits.
    +

    +

    +
    +

    2021-01-28 04:09:20 -0800 + +
    Robin Watts <Robin.Watts@artifex.com>
    +e21027b895f3ba6abda70cefb8facbc772bd7ea9 +

    +

    + Better fix for psdcmyk indeterminisms.
    +
    + When calculating buffer sizes, we now take the presence/absence of
    + tags into account. This must be copied into the temporary device
    + structure from the target.
    +
    + Simply setting it to 0 will stop the indeterminisms, but will give
    + problems with potential future devices (psdcmyktags?).
    +
    + Accordingly, I've removed the memset, and copied the value, meaning
    + we can rely on valgrind to help spot such problems in future.
    +

    +

    +
    +

    2021-01-28 09:31:29 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +a448691e97cc4b4b7040e8c7d7a39e13eedfc0c2 +

    +

    + oss-fuzz 27399: Handle NaN and Inf in object type conversions
    +
    + In the core of cvs detect unrepresentable floating point numbers and throw
    + an error (note: not using fpclassify or similar because they are C99 additions).
    +
    + If we hit such a case, throw an error, in this case undefinedresult - we
    + cannot use rangecheck because that gets special handling which also triggers
    + the uninitialized value error.
    +

    +

    +
    +

    2021-01-27 12:53:35 -0800 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +66a8ec27ede82a353cb2775c4be1904aca529b2a +

    +

    + Init mdev struct to 0 on stack -- fix psdcmyk non-determinism
    +
    + Big giant structure full of random stuff is probably not a good idea....
    +
    + This hopefully fixes non-determinisms seen in pdfi psdcmyk device.
    +

    +

    +
    +

    2021-01-27 13:14:10 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +2679ddae53883ba3c7129846494d921151527a74 +

    +

    + More jpeg passthrough error case fixes.
    +
    + Ensure that on an error return, we communicate the end of JPEG passthrough to
    + the (potential) recipient(s) of the data.
    +
    + Basically, we need to ensure that JPEG passthrough is completed before the
    + last time we return from s_DCTD_process for the current stream - i.e. whether
    + it is an EOD condition, or an error condition.
    +

    +

    +
    +

    2021-01-27 09:51:59 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +5d59986af2b7df560b85ccf54a491eb632022439 +

    +

    + Close down JPEG passthrough when finalizing DCT decoding.
    +
    + This doesn't seem too cause any problems with Ghostscript, but it
    + is implicated in seg faults in pdfi. Probably because the pdfwrite
    + streams are in a faulty state.
    +

    +

    +
    +

    2021-01-10 10:17:35 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +3eb6b9866aa1dae4c2778b450cc99b29e9d11d7e +

    +

    + Implement Nup subclass device to support nesting images on a page.
    +
    + By using a subclassing device to intercept a few of the device procs
    + (get_initial_matrix, output_page, fillpage, put_params, close_device, and
    + dev_spec_op) pages can be placed on to a page that is eventually output.
    +
    + This initial implementation scales the pages on the 'nest' as defined
    + by -sNupControl parameter that is a string of the form "HxV" where H
    + and V are integers controlling nesting across (H) and down (V) the page.
    +
    + All pages on the nest are the same size/orientation as the first page of
    + the nest, and if a different PageSize is encountered, any pages on the
    + current nest will be output before starting a new nest.
    +
    + In gx_device_set_hwsize_from_media dev_spec_op is used to prevent changing
    + the device width and height (HWSize) for PageSize or .MediaSize params.
    +
    + This requires that the graphics library should not assume that HWSize is
    + derived from PageSize and HWResolution, but it allows the intial clip_path
    + for the nested pages to be set from the MediaSize, Margins, and HWMargins
    + in gx_default_clip_box.
    +
    + There are a few files that have differences with the 'psdcmyk' devices when
    + tested with -sNupControl=1x1:
    + Bug688584.ps: Page 6 missing graphics,related to SeparationOrder usage.
    + (a bug will be opened for this once this is committed).
    + Bug692517.ps: subclass device barely switches to clist mode for 72.0
    + (don't care, page mode still works for larger MaxBitmap),
    +
    + tests_private/pdf/PDFIA1.7_SUBSET/CATX2975.pdf.ppmraw.300.0..gs
    + (seems to be a progression on page 9)
    +

    +

    +
    +

    2021-01-25 19:04:55 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +7f52ae74a19bf1076ebfb9ed1695b0077fc70ee7 +

    +

    + Bug 703320: Export cmsCloneTransformChangingFormats
    +

    +

    +
    +

    2021-01-25 16:33:26 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +181672f2faccccfd613837d0e60610301a1816ea +

    +

    + Bug 703378: Error handling for memory failures in gstate
    +

    +

    +
    +

    2021-01-25 11:24:46 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +14c51e628fc78f43aa9360ad94c359085583bec5 +

    +

    + Coverity 365590 Parameter set but not used.
    +

    +

    +
    +

    2021-01-23 12:03:29 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +730d1c410e38500f98ae11cad42d8672521588b4 +

    +

    + Initialize the current_glyph entry in pdfwrite text enumerator
    +
    + Also address a compiler warning about "operation" might be unintialised at
    + line 3682.
    +

    +

    +
    +

    2021-01-23 09:36:09 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +054d35268592bba2434dffdb3b36e4ad224adcf0 +

    +

    + Guard against indirect /Length in an XRef stream
    +
    + Bug #703372 "Unable to find Trailer"
    +
    + The file has an XRef stream (a compressed cross-reference), where the
    + /Length of the stream is itself an indirect object. We can't dereference
    + the Length, because to do so we would need to look up its object number
    + in the cross-reference!
    +
    + Oddly the PDF specification does not state that the /Length must be a
    + direct object.
    +
    + This commit wraps the code which retrieves the /Length in a stopped and
    + if it fails we fall back to the assumption that the length is invalid
    + and apply our normal recovery strategy.
    +

    +

    +
    +

    2021-01-21 09:52:31 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +98669b8da7d1dd925a1e3bc0bc785cffcb12acab +

    +

    + Fix PDF 'colorspacespotcolors' to handle uncolored Patterns.
    +
    + Michael Vrhel noticed that the PageSpotColor count was wrong for test
    + file Bug694385.pdf, finding the "Dieline" Separation, but missing the
    + "PANTONE 378 C" Separation that was the underlying colorspace for an
    + uncolored Pattern.
    +

    +

    +
    +

    2021-01-16 22:37:13 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +d020a4e75e351d1de387d13edebffc36ab54c6d5 +

    +

    + Fixes/changes to default subclass device procedures.
    +
    + The 'output_page' should pull the PageCount from the child device (that
    + is the only real fix.)
    +
    + The other changes are to get rid of all of the return statements that
    + cannot be reached. The 'else' is retained as a comment /* else */ in
    + case someone can't figure that out. It is sort of surprisng that we
    + don't get 'statement cannot be reached' messages out of any compiler or
    + static analysis tool.
    +

    +

    +
    +

    2021-01-20 20:54:10 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +cc676010ad929da40db4c89810ede2f5c4a0ed7b +

    +

    + Implement strip_tile_rect_devn for pdf14 device
    +
    + The default strip_tile_rect_devn method returns an error
    + and has a comment that the method is only implemented
    + for devices that support devn, which the comment says
    + are only the memory planar devices. However, the pdf14 device
    + also supports devn colors and has to be able to handle
    + pattern tiles that have spot colors. When such files
    + are encountered, the interpreter will just report an error in
    + the file and continue on its way if we are in non-clist mode.
    + When in clist mode, the error will cause ghostscript to stop
    + execution.
    +
    + This implementation borrows heavily from gx_default_strip_tile_rectangle
    + to deal with all the logic of where we are on the tile,
    + it then borrows heavily from pdf14_copy_mono but
    + using devn colors and dealing with the case of
    + one of the colors possibly being gx_no_color_index.
    +

    +

    +
    +

    2021-01-21 13:00:22 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +47ec79f910892810d0d72116667d9487093d5c34 +

    +

    + Add malloc_.h to gp_ntfs.c
    +
    + Bug #703310 "gp_ntfs.c uses malloc but does not include "malloc_.h""
    +
    + There doesn't seem to be a problem with adding malloc_.h to the C file
    + it matches what we do with other files, doesn't produce any warnings
    + and passes regression testing.
    +
    + Using WIN32_LEAN_AND_MEAN however causes the compiler to fail with a
    + number of errors, so we won't be adding that. The nature of the errors
    + look like these would be difficult to solve and the benefit of this
    + preprocessor directive is moot, even Microsoft insiders describe it
    + as 'largely useless'.
    +

    +

    +
    +

    2021-01-19 11:15:28 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +5c540233af993678154914eede088a42039ae745 +

    +

    + libtiff build fail in old VS versions
    +

    +

    +
    +

    2021-01-17 20:01:08 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +be18309f3ce815c21ce858527515e7765d672a9b +

    +

    + Fix issues with windows C# demos/csharp/api/ghostnet.cs
    +
    + Make sure to explicitly tell C# that the callback delegates will use a Cdecl
    + calling convention, which means that the caller (in this case the ghostscript)
    + will clean the stack. Also some minor changes to the project settings.
    + The default for debug is to use gpdldllxx.dll while the release versions will
    + use gsddllxx.dll just to help with the testing. Finally, make sure to *always*
    + copy the dll from the appropriate gs directory, even when the C# application
    + did not need to do a build (as it was already built)
    +

    +

    +
    +

    2021-01-15 15:13:05 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +b9ad2c23e6fd1f7cf0c4889504ac1642f077b660 +

    +

    + Tifflib fix: Thunder RLE can fail to decode last run.
    +
    + GPDL decode of tests_private/tiff/text.tif gives valgrind errors
    + due to the "thunder decode" failing to extract the last run of
    + bytes.
    +
    + The logic in the decoder, presumably intended to spot overruns of
    + data is incorrect, in that runs that end at the end of a row
    + (npixels == maxpixels) will not be decoded.
    +
    + Fix this by limiting 'n', the number of pixels to copy. Note that
    + npixels is updated by the 'unlimited' value to ensure the error
    + reporting at the end of the loop still works.
    +

    +

    +
    +

    2021-01-15 12:26:22 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +4e956a2ee5137812007a7862a6eb8fddd9b709d2 +

    +

    + Update libtiff to 4.2.0
    +
    + And then re-apply: ef66198ade77d5d551b3045cd36bed81c0b04f54
    +
    + Changes to libtiff for gpdl.
    +
    + 1) Ensure that libtiff doesn't mess with 'boolean' in GS builds
    + on Windows. Without this, the jpeg structures used by our JPEG
    + lib build are different in size when called from gs and libtiff,
    + resulting in runtime errors.
    +
    + 2) Update libtiff so that it can correctly call into the jpeg
    + library so that memory operations happen from our pools, not
    + malloc/free. Slightly horrid in that this is more complex with
    + OJPEG than JPEG files.
    +

    +

    +
    +

    2020-04-01 19:05:40 -0500 + +
    Rob Boehne <robb@datalogics.com>
    +35035761ffe178284c4ef9fc2ef75a4843e64a63 +

    +

    + Bug 703339: Fix libtiff name clash on AIX
    +
    + Patch grabbed from upstream:
    +
    + https://gitlab.com/libtiff/libtiff/-/commit/31ca59cb047353d7edf66d04fe052861b180e42d
    +
    + Rename itrunc to fix name clash with a different itrunc in math.h on AIX.
    +
    + Fixes issue #189
    +

    +

    +
    +

    2021-01-15 12:10:58 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +364a3883326b90bf078d488909ba3203450da3d3 +

    +

    + Bug 703301: Fix logic error in display device structure checks.
    +
    + Thanks to Pino Toscano for spotting this.
    +

    +

    +
    +

    2021-01-14 19:45:33 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +f9723a92bcb3ab1de8f5cf16da5b5e6c807eeda2 +

    +

    + Bug 703336: Fix GPL crash with jpg input on 64bit windows.
    +
    + The Jpeg code uses setjmp/longjmp for error handling. On Windows at
    + least, in 64bit builds, jmpbufs need to be 16 byte aligned. This is
    + generally achieved by malloc blocks being 16 byte aligned, and
    + structures have their offsets calculated so that their contents lie
    + at appropriate positions.
    +
    + Unfortunately, our malloc routines only align to 8 byte aligned.
    +
    + We therefore bend the jpgtop.c code to align the jmpbuf manually.
    +
    + Similar tricks are required in the pngtop.c code, which also uses
    + setjmp/longjmp, but a slightly different approach has to be taken
    + as the png routine allocates the structure with the callback in
    + itself, so we don't get to align just that. Instead, we modify the
    + allocation routines that we provide to pnglib so that blocks are
    + correctly padded.
    +

    +

    +
    +

    2021-01-14 16:42:03 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +496d1d927acfe2460b69552f372f9ec7a411a172 +

    +

    + Improve memory device bitmap size calculation in tagged planar cases.
    +
    + The planar calculations for memory device sizes were failing to take
    + the presence of tags into account. Fix those calculations here.
    +

    +

    +
    +

    2021-01-14 13:31:15 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +6376e75907ab7eff2248236333a10489cfad3787 +

    +

    + Remove paths stored in --permit-file* when sanitising.
    +
    + Bug #703338 "Hide permitted paths from invocation comment"
    +
    + As noted in the bug report, the --permit-file* control arguments are
    + not replaced with '?' when sanitising the arguments. This leads to an
    + information leak with the 'Invocation' comment emitted by pdfwrite.
    +
    + This commit adds checking for the -- switches and sanitises the
    + permit-file* cases.
    +

    +

    +
    +

    2021-01-13 13:03:22 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +f11882a4b09beb0d74f88df759841cb49ed63683 +

    +

    + MSVC: Yet another nmake version.
    +

    +

    +
    +

    2021-01-12 22:11:13 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +79decaf7eca50a7dc6201dc86ef487ee1e7563f9 +

    +

    + Fix GhostPDL TIFF reader to be able to handle tiff32nc output.
    +
    + The PHOTOMETRIC_SEPARATED case would only handle num_comps == 3, but the
    + tiff32c device creates 4 component images with PHOTOMETRIC_SEPARATED.
    + Allowing 3 or 4 components works.
    +

    +

    +
    +

    2021-01-07 17:24:44 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +904c546962cb749fa8136130612e1c0a9cf558af +

    +

    + Add CMYK equivalent colorants for Separation Spot colors to tiffsep device.
    +
    + This may be useful information -- adding the equivalent colors for the Spot
    + color names.
    +

    +

    +
    +

    2021-01-07 17:32:12 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +34ec1a4deb5275280184346ef877e6984da59da8 +

    +

    + Fix pdf_info.ps "write-doc-string" to handle names as well as strings.
    +

    +

    +
    +

    2020-12-09 10:32:36 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +ead8676f2b8686605b8f6976da4de677d99d39e0 +

    +

    + Fix yet another version number handling ommission
    +
    + From the introduction of the patch level to the version number.
    +

    +

    +
    +

    2021-01-06 16:23:05 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +a081833ac163dd6d6b404b679cf086f125847ef8 +

    +

    + oss-fuzz 26175: propagate error for invalid arc4 key
    +
    + Also, precautionary initialisation of a couple of variables in the arc4 stream
    + state.
    +

    +

    +
    +

    2020-12-04 10:38:29 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +b0b1b89c767809c05abbe118c47875743438580c +

    +

    + oss-fuzz 27985: Initialize the glyph lengths array
    +
    + Just memset to 0x00, so in the event of an error, we don't later use the memory
    + uninitialized.
    +

    +

    +
    +

    2021-01-06 16:22:15 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +62a98980772fde394c99e92bfc9c18d5407c06e1 +

    +

    + Update for another version of MSVC.
    +

    +

    +
    +

    2021-01-05 11:25:03 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +b01bdd87eb96b3d8db7ef2727d5a6ab7b122b8fc +

    +

    + Update openjpeg to 2.4.0
    +
    + Fixes:bugs 703275, 703276, 703277, 703278, 703279, 703280, 703281.
    +

    +

    +
    +

    2021-01-05 09:01:59 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +cc2f67265d1508a6cf953470ef7b2a0d9a1a14e3 +

    +

    + Update freetype to 2.10.4 (for real, this time!)
    +
    + (with zlib "Diagnostic functions" hack/fix in freetype/src/zutil.h)
    +

    +

    +
    +

    2021-01-01 17:50:54 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +6b4c229d4bf4bcccf8000611caaef59f859d04a6 +

    +

    + Build apitest demo with -DCLUSTER.
    +
    + This ensures that pdfwrite doesn't put timestamps in the
    + produced PDF files, which means the md5sums are consistent.
    +

    +

    +
    +

    2020-12-16 15:50:09 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +01194f9c8a0f2df53ad8f1815bfadc10ad247ba7 +

    +

    + PDF interpreter - check type of Group entries in Form XObjects
    +
    + Bug #703271 "Using oitsample to convert some pdf files to tif errors out with "The export process timed out.""
    +
    + This is for the larger (205 pages) of the two files. The file is badly
    + broken, 3 fonts point to objects which are not dictionaries but are
    + simply integers. In addition at least one of the Form XObjects has a
    + Group entry which also points to an object which is an integer, not a
    + dictionary.
    +
    + The Group was corrupting the operand stack leading to later errors. This
    + commit checks the type of the Group (and the BBox since we're making
    + changes anyway) and simply aborts the Group if the type is incorrect.
    +
    + Obviously this is going to lead to incorrect output, but at least we
    + can carry on to later pages.
    +
    + Note that Acrobat throws errors on pages 168, 169 and 171-175 of this
    + file and renders blank pages for them, so the file is clearly very badly
    + broken.
    +

    +

    +
    +

    2020-12-16 09:56:40 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +eef97dac4d6d6e88319c17af4f739e7d899776f3 +

    +

    + base/memento.h: fix Memento_listBlockInfo macro - needs to take one argument.
    +

    +

    +
    +

    2020-12-15 17:42:35 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +9912c583aba35b68e251a73861ead44b0dbd91b4 +

    +

    + Add Memento_blockInfo(void *addr).
    +
    + Show the history for a block.
    +

    +

    +
    +

    2020-12-15 16:46:56 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +e1dfb92cc593cd27ed593ffcc3a79711b7504563 +

    +

    + PDF interpreter - handle indirect objects in Encrypt dictionary
    +
    + Bug #703272 "This PDF files converts to tiff using the oitsample program, but the font turns from English to what looks like chinese"
    +
    + The Encrypt dictionary and the subsidiary StdCF dictionary are stored
    + as indirect objects (presumably in order to make the file larger). The
    + decryption code wasn't expecting that.
    +
    + Add code to dereference the objects. While we're here, add code to check
    + the types of the objects and ensure they are correct, and throw an
    + error if they are not.
    +

    +

    +
    +

    2020-12-11 11:19:22 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +4d91c6ad3e76e19f36d23a50dce253fbbc7d0560 +

    +

    + Update CFF strings "known" encoding in C
    +
    + There were a few missing strings.
    +

    +

    +
    +

    2020-12-11 10:55:29 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +87eed438b0cffba111371c25e1d169163f310465 +

    +

    + Reintroduce and update cff std strings "encoding" PS file
    +
    + and move it to "lib" since we don't actually use it in Postscript any more.
    +
    + It's only used if we ever need to regenerate the C representation of "known
    + encodings".
    +
    + Also, update to include missing strings.
    +
    + Finally, fix the tool that relies on this "encoding" - .namestring is no
    + longer exposed as a Postscript operator, so define a local equivalent. And
    + update the example invocation in the comments
    +

    +

    +
    +

    2020-12-14 20:15:25 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +bcd9f9d0126d07dc6f93e47618baa6d23fcaf1c2 +

    +

    + Mask off the transparency bits from the rop value
    +
    + before we use it as an index into a 256 entry rop table.
    +

    +

    +
    +

    2020-12-15 09:10:55 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +0fa1513841981e7d3bc4da11c93edeeedd452b72 +

    +

    + Fax Decode filter - add a simple sanity check
    +
    + I have a test file (source unknown) e249869cf6a250726711c21fda42763c_signal_sigsegv_a418b9_5694_4827.pdf
    + which has a number of type 3 bitmap glyphs with invalid CCITTFaxDecode
    + parameters. The (optional) Columns key in the dictionary has an
    + associated value of 2^32-1 in one case and an even larger value in
    + another.
    +
    + The new pdfi interpreter causes a seg fault in the CCITTFaxDecoder
    + because this breaks a 32-bit signed integer on Windows, causing the
    + 'raster' value to be negative, when added to the memory pointer this
    + causes us to try and read from before the beginning of the data buffer.
    +
    + Ghostscript's PDF interpreter doesn't trigger this because it fails
    + much earlier and doesn't try to execute these glyphs but I'm certain
    + it would be possible to modify the file so that it did.
    +
    + Adding a simple negative check and throwing an error if it is, resolves
    + the problem.
    +

    +

    +
    +

    2020-12-11 11:45:34 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +d8dd6797ba52cd8af28839d1f5f2a4a5fca055d7 +

    +

    + Fix -dAntidropuoutDownscaler for non-masked images.
    +
    + The masked image case set the polarity needed in order for the
    + ISpecialDownScale image interpolation to work, but the ordinary images
    + did not set the 'pol' leaving it set to GX_CINFO_POLARITY_UNKNOWN.
    +

    +

    +
    +

    2020-12-14 08:39:50 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +c6166768c6e963b0fe28ccdb266629443e521381 +

    +

    + Fix bug 703270: Wrong path for PostScript helper file in ps2epsi
    +
    + In the change mentioned in the bug, rather than rely on the LIBPATH
    + search method, the ps2epsi script assumed that pd2epsi.ps would be
    + in the same directory as the 'gs' executable, which is not correct.
    +
    + Change to use bare 'ps2epsi.ps' so that it will be found on the
    + LIBPATH as instialled by: make install
    +

    +

    +
    +

    2020-12-12 10:31:50 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +3f16ba6aa7c12ee469736f3c8e2205be81087f2a +

    +

    + PDF interpreter - improve commit for bug #703217
    +
    + In the event that the execution of a Form XObject for a transparency
    + Group consumed more operands than were pushed, we left the number
    + of operands on the stack. This just cleans up the stack.
    +
    + The file for bug #697655, with the pdfwrite device, is the only known
    + case of this, and the file fails with pdfwrite anyway, so this is not a
    + truly vital fix, but its best to tidy up.
    +

    +

    +
    +

    2020-12-12 09:29:36 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +96e881edc16d7ffe562f8e46354a16275008fe08 +

    +

    + Have Git ignore some more directories
    +
    + Add debugobjrt, memobj64 and windows./vs to the ignore list for Git.
    +

    +

    +
    +

    2020-12-10 11:01:55 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +d1be0cd16079c34c05b790683ea76b790486989b +

    +

    + pdfwrite - fix another memory leak on an error path
    +
    + Again this does not exhibit with the garbage-collecting memory allocator,
    + discovered by Nancy while working on pdfi.
    +

    +

    +
    +

    2020-12-08 11:27:10 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +733a8f209ecce61f31621ab87d1d1a81f4935602 +

    +

    + Bug 70716: ETS code clean up.
    +
    + Add checking for memory allocation failures, static code analysis findings,
    + and issue mentioned in 701716. Also update windows project to VS2019.
    +

    +

    +
    +

    2020-12-08 15:35:28 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +a1b4377ffe877fcd3ec2832ca670833cc45adb7a +

    +

    + pdfwrite - fix memory leak on error path
    +
    + When writing outlines via a pdfmark, if the code failed for any reason
    + then we would leak various objects. As usual this is cleaned up for us
    + by the garbage collector when running in PostScript but leaks when we
    + aren't using the garbage collector.
    +
    + There are likely to be many, many more paths that leak like this, the
    + only way to find them is going to be a complete audit of the pdfwrite
    + source, which would be a major undertaking. For now we'll fix them as
    + we find them.
    +

    +

    +
    +

    2020-12-08 09:35:26 +0000 + +
    Peter Cherepanov <sphinx.pinastri@gmail.com>
    +7a5ed5d0f3fd955bc5d0b1dbb18e63636f697a76 +

    +

    + PDF Interpreter - Clean up stack after Form Xobject for transparency Group
    +
    + Bug #703217 "Error: /typecheck in /--pdfshowpage_finish--"
    +
    + This is basically the patch supplied by Peter Cherepanov, which uses
    + the existing mechanism for restoring the stack to a count stored
    + before the execution of the Form XObject.
    +
    + However, Peter's patch caused a regression with the file for bug 697655
    + when run with pdfwrite, because that file consumes more operands from the
    + stack than it should, leading to us trying to pop -1 elements.
    +
    + This commit only pops a positive number of objects, and has a slightly
    + different error text.
    +

    +

    +
    +

    2020-12-07 09:25:05 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +fb78a833aeb27ddd59a88c799fde1e939fb43e5a +

    +

    + Fix bug 702786: Ignore null node in Page tree
    +
    + Thanks to Peter Cherepanov for this analysis and the patch,
    +
    + The sample file has an element in the /Pages array that cannot be resolved,
    + and following the PDF spec is interpreted as null.
    +
    + This patch makes Ghostscript ignore null nodes in the page tree. In turn,
    + this causes a missing page error, which was considered a fatal error before.
    +
    + -dPDFSTOPONERROR causes Ghostscript to not proceed with this broken file.
    +
    + Regression testing shows no differences with other files.
    +

    +

    +
    +

    2020-12-07 16:43:37 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +f4ef8bb9684bcc7d07c83b8ffabb607046930a7d +

    +

    + pdfwrite - Limit XUID to 16 values and don't emit it for subset fonts
    +
    + Bug 703225 "The document breaks after repeated processing"
    +
    + As noted by Peter Cherepanov, we currently preserve the XUID in the font
    + when writing it out from pdfwrite, and the PDF interpreter extends any
    + existing XUID (or adds a new one) every time we process the file.
    +
    + The PLRM documents an Adobe limitation of 16 entries in an XUID array
    + and it appears Acrobat has the same limitation.
    +
    + This commit adds new flags to the type 1 and type 2 font writers so that
    + we only write an XUID when we are *not* subsetting the font (as the use
    + of an XUID on two different subset fonts would be incorrect). It also
    + only emits the first 16 values from an XUID even if we aren't subsetting
    + the font.
    +

    +

    +
    +

    2020-12-07 09:59:35 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +7bfb672daea29645ee40c0facbd5f2eec7cf58e7 +

    +

    + pdfwrite - fix memory leak when converting names into references
    +
    + When writing certain kinds of metadata from pdfmarks we need to convert
    + a named object into an indirect reference. The code for doing this
    + assumed that the gs_param_string array was arranged so that each
    + gs_param_string's data member pointed to an individually allocated
    + chunk of memory, so it was safe to replace it.
    +
    + This had 2 problems; firstly the original data buffer was not freed,
    + leading to memory leaks. Secondly, and more seriously, not all
    + gs_param_string_arrays are organised this way. Sometimes the array
    + has a single data pointer containing all the entries sequentially,
    + each member of the array is a gs_param_string where the data member
    + points into a location in the string. We cannot free and reallocate
    + the data members from that kind of string array.
    +
    + SO this commit modifies the code to make a new copy of the data in the
    + param_string_array in the format expected by the remaining code, and
    + frees the copied data afterwards. This fixes the meory leak and avoids
    + the potential crashes caused by the incorrect assumption.
    +
    + Note that the assumption in the code is true when the input is from the
    + PostScript interpreter, but is not true for the input from pdfi and
    + obviously potentially any other front-end.
    +

    +

    +
    +

    2020-12-04 15:07:31 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +6dbcee4e0b4868843938233eb2c37c927f674d69 +

    +

    + Update MSVC makefiles.
    +
    + Firstly, another version of nmake to cope with. In fixing this, I
    + note that we haven't been setting MS_TOOLSET_VERSION in some cases.
    + For building from the IDE this evidently doesn't matter, but I suspect
    + it is required for building using nmake. Add those back in.
    +
    + Thanks also to Julian for spotting that the logic to cope with
    + "Community" vs "Professional" editions was failing due to extra
    + quotes. Fixed here.
    +
    + Also, msvclib.mak hadn't been updated for VS2017 or VS2019. Copy
    + the relevant sections across. Possibly we should pull this code out
    + to a separate file that we can !include so we only have to maintain
    + it in one place.
    +

    +

    +
    +

    2020-12-01 18:06:42 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +fb1a336ac4d2613a63dc0b6054f20f9a8a467fe9 +

    +

    + Bug 694692: Handle custom left-sidebearing values.
    +
    + Ghostscript was ending up ignoring LSB values read from Metrics dictionaries.
    +
    + This stemmed from some confusion about Freetype's incremental interface
    + API get_metrics call. We had taken the references to "overriding" the metrics
    + to mean it allowed for custom metrics to be passed into (and back out of)
    + Freetype. That is not the case: it is intended to allow integrations supporting
    + "incomplete" (primarily TrueType) fonts, such as PCL/XL embedded TTFs, that are
    + permitted to omit certain tables - specifically, in this case, the hmtx and vmtx
    + tables.
    +
    + So, this drops that approach, and applies custom LSB values in our code.
    +
    + Coincidentally, this also makes gs somewhat immune from a pending change in
    + Freetype related to that get_metrics call.
    +

    +

    +
    +

    2020-11-27 12:17:36 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +fce9bcfbda7acdf758fe6fb5264bb1e78eb39039 +

    +

    + FAPI: fix applying offsets for glyph paths
    +
    + If the renderer doesn't deal with replacing metrics, we apply an offset to the
    + glyph before we pass it back into Ghostscript....
    +
    + Except we weren't doing it for outline glyphs. Shouldn't (currently) affect
    + freetype, but nevertheless....
    +

    +

    +
    +

    2020-12-03 11:42:27 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +596394e2cdff74488fb53fc818d7f5ca4d3ac1da +

    +

    + Address a compiler warning from 2ed1184b7513
    +
    + If unrolling the just created, incomplete save state fails we are out of safe
    + options to carry on, so throw a fatal error.
    +

    +

    +
    +

    2020-11-20 13:07:00 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +2ed1184b75132c1ef10cfeec2415f13eaefc7f9e +

    +

    + oss-fuzz 27011: Improve handling of error during a "save".
    +
    + Previously, in the event of an error during a Postscript save operation, we
    + could end up leaving a half formed save object in existence. If the error
    + happened during the gs_gsave_for_save() function, that could end up leaving
    + the graphics state cleanup "out of sync" with the save state cleanup at the
    + final virtual memory cleanup as we shut down.
    +
    + To resolve that, destroy the partially formed save state at the point of the
    + error. This also means tweaking dorestore() to handle unrolling a save state
    + without the graphics state reference in it.
    +

    +

    +
    +

    2020-11-09 15:27:57 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +634d9c76a6c4c92273c7994cd228e01e263b9d7c +

    +

    + oss fuzz 27304: validate glyph offset against stream size
    +
    + When we retrieve a glyph offset, check it is within the size of the sfnt data
    + and if it is not, throw an error.
    +

    +

    +
    +

    2020-12-02 15:10:33 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +97152401c7d4490be8f8112829ea440b95411702 +

    +

    + Bug 703214 - treat some kinds of free objects as not free
    +
    + The file in Bug 703214 has been edited incrementally a number of times.
    + The bug is actually the creation of the initial file, which declares
    + its xref table as having a section 7 entries long starting at object
    + 1.
    +
    + In fact, as is normal, the xref table starts at object 0 with the free
    + entry at the start of the linked list. Because of the incorrect
    + subsection header though, a PDF consumer should read this as being
    + object 1, not object 0.
    +
    + Obviously *all* the objects are then incorrect.
    +
    + The incremental updates then redefined very object *except* object 1.
    + The result of this is that these objects are all correctly defined. The
    + file then attempts to render object 1, which is free. Acrobat can deal
    + with this, which must mean it is ignoring the 'free' status of the
    + object and reading the 'next free object' value as if it were the offset
    + of the object.
    +
    + Because the next free object is 0, and object 1 is the first object in
    + the PDF file, and the preceding line is a comment, this actually works
    + though I'm pretty certain its only by sheer luck, it really should not
    + work at all.
    +
    + Unfortunately, because of the way the the PDF interpreter reads PDF
    + files and stores xref entires, we cannot easily detect an attempt to
    + use a 'free' object and try to treat it as non-free. We have to do this
    + upfront when we read the xref table. Because this is such a fluke and I
    + believe not likely to be repeatable, I've tried to keep the condition
    + for ignoring the free flag as tight as possible; The generation number
    + must be exactly 65535 (the canonical value for the head of the free
    + list), and the object number must be not zero. In this case only we
    + will store the 'next free object number' as an offset.
    +
    + If the object is truly free then either it is unused (in which case we
    + will not use the xref entry) or it should have been superseded by a
    + later incremental update, in which case we still won't use this entry.
    + The only way we could try to use this entry is if the PDF file attempts
    + to use a free entry.
    +
    + This might change some handling of other broken files.
    +

    +

    +
    +

    2020-12-02 00:48:45 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +ed946acb20ec03426d35b0d9341c551e7e459184 +

    +

    + LGTM: Reduce goto use in zsort_continue.
    +

    +

    +
    +

    2020-12-02 00:22:20 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +4633ebbca0c9690003aebc9f4661c232c61cecdd +

    +

    + LGTM fix: Reduce goto use in s_hex_process.
    +

    +

    +
    +

    2020-12-01 12:56:09 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +4cbe8fa61a3dc7bb8f9e425024b79a66950664ec +

    +

    + ;Bug 703208 Make changes from bug 703164 gsicc_lcms2mt.c over to gsicc_lcms2.c
    +
    + Thanks to Stefano Rivera for catching this.
    +

    +

    +
    +

    2020-12-01 10:25:06 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +4ab2d212dba1475647508b085feb5ee93ea678f8 +

    +

    + LGTM: Reduce gotos in s_LZWD_process
    +

    +

    +
    +

    2020-12-01 09:39:42 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +cea43d89382fc253f64a7b942722a636080e8138 +

    +

    + pdfwrite - fix memory leak with high level forms
    +
    + As usual this does not exhibit with Ghostscript, because of garbage
    + collection, and was observed with pdfi.
    +
    + We transferred ownership of the form object to the local named
    + resources dictionary, and removed the resource from the XObject chain
    + of stored resources, but we didn't free the actual resource structure.
    +
    + Rejigged the code order slightly because we need the resource for a
    + few purposes before we transfer ownership and free it. Also fixed a
    + typo and a misleading string (only used for debug purposes in each case)
    +

    +

    +
    +

    2020-11-30 12:44:25 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +cbe110579288e1d54afd5fecd0abe6e59fe49caa +

    +

    + Bug 698848 Fix mismatch of color space and number of components in JPEG2000
    +
    + Peter Cherepanov and Ray Johnston had earlier patches. This fix builds
    + on those and runs cleanly on our test files including Bug694909, which
    + had an odd unknown cs jp2k image.
    +

    +

    +
    +

    2020-11-30 13:21:22 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +080a23c44808a93fa27ba2d4dfdf8d8748a8e84a +

    +

    + Fix bug 703198: SEGV's with psdcmykog device and --saved-pages-test
    +
    + This was a reference of a missing icc_table caused by the band count not
    + being adjusted during saved-page playback as it was during writing. The
    + orig_spec_op in the gx_device_printer structure was being set to the
    + gdev_prn_spec_op, but this did not call the target device's spec_op, so
    + it did not get the result from gxdso_adjust_bandheight that was needed.
    +
    + Caused by commit 8df410c26.
    +
    + Also clean up a left over extern in gxclrect.c (not related to the fix).
    +

    +

    +
    +

    2020-11-30 10:41:20 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +50a9fad340a659e64c5dbc74125b97e16cf529de +

    +

    + Bug 703197 : Seg fault in close of x windows
    +

    +

    +
    +

    2020-11-28 13:37:45 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +6c94917b4a36c19b30dc451f03715ec2c257d2e5 +

    +

    + lgtm fixes: Fix previous fix to s_A85E_process.
    +
    + continue in a do { } while (0); doesn't work.
    +

    +

    +
    +

    2020-10-01 15:58:25 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +bac9c5d2ed82390da058653afbac0d9e29e9bd3f +

    +

    + Searching for a marker in a stream, honor alignment
    +
    + When searching for markers in a stream buffer, we were "seeking" to the point
    + in the buffer, and casting to either a byte, ushort or a uint to make the
    + value comparison. But we cannot do that on SPARC because of the strict
    + alignment on that hardware.
    +
    + So, we have to "unpack" the individual bytes from the stream to do the value
    + comparison.
    +
    + Note: there are slightly confusing comments in the code that mention being
    + "on a 16 bit boundary" and "on a 32 bit boundary" - that's referring to the
    + offset into the buffer, *not* the actual memory address alignment.
    +
    + Found in testing on Solaris/SPARC
    +

    +

    +
    +

    2020-11-27 14:59:40 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +3d33e44d3d014ee78a4505c37b244957066d7b12 +

    +

    + Fix memory leak with copied type 1 fonts.
    +
    + If we copy a type 1 font (for the benefit of the pdfwrite family of
    + devices) then we make a copy of the Subrs and GSubrs as well, but the
    + routine to free the copied font wasn't freeing those copies.
    +
    + This isn't normally obvious because these are garbage collected, found
    + while checking pdfi.
    +

    +

    +
    +

    2020-11-27 10:19:23 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +fec1090d129630c23f425c6aae5a4a1308a973da +

    +

    + LGTM: Rejig s_A85E_process for goto's.
    +
    + All gotos are now forwards.
    +

    +

    +
    +

    2020-11-27 11:14:07 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +2c3b29a81c5cb0859ea567657c646b06f7df4039 +

    +

    + Fix compiler warning
    +
    + Explicitly cast gx_device_null pointer to a gx_device pointer.
    +

    +

    +
    +

    2020-11-26 16:23:17 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +f789ded2e122578af6e9e0350e487e7ff89e74ae +

    +

    + Ensure the nulldevice has a proper set of device methods
    +
    + gs_make_null_device uses the gs_null_device structure to create an
    + instance of the nulldevice, but it did not call gx_device_fill_in_procs
    + to set the device methods which are left as NULL in the declaration.
    +
    + Since all device methods (except fill_rectangle) are expected to be
    + real functions, not NULL, many places in the code do not check that
    + the device method is not NULL before calling it. This could (and in
    + pdfi did) lead to us attempting to execute 0x00 causing seg faults.
    +

    +

    +
    +

    2020-11-24 18:20:39 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +9aa09cbca96e722568be76c2de35b41ee9881ba5 +

    +

    + lgtm: Rejig gotos in gs_type2_interpret.
    +
    + All gotos are now forwards. No change to actual operation of code.
    +

    +

    +
    +

    2020-11-25 10:11:16 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +db51437d7799576dadeb91014b483d57a39e98ae +

    +

    + Coverity 364047: Structurally dead code.
    +
    + The previous fix to gs_type1_interpret to make lgtm happy has upset
    + Coverity. Coverity (incorrectly) believes that some code is now
    + structurally dead, when actually there is a goto jumping into it.
    +
    + I think we can make both happy by moving the code to the location of
    + the last goto.
    +

    +

    +
    +

    2020-11-25 08:07:28 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +09377ecc18f952fa7e29c1c884f5fcb493809577 +

    +

    + pdfwrite - fix a compiler warning
    +
    + remove a now unused variable
    +

    +

    +
    +

    2020-11-24 19:56:49 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +8e912ff13757dcff888319f78c05297b4fde8359 +

    +

    + pdfwrite - fix 2 memory leaks with metadata
    +
    + Discovered with pdfi. There is a temporary buffer which wasn't being
    + freed.
    +
    + A more complex problem involves the Metadata value stored in the
    + Catalog dictionary. A long comment describes why this is not freed as
    + an 'otherResource', but experience contradicts the comment, the
    + Metadata value is not freed along with the Catalog object.
    +
    + I've altered this here to solve the memory leak but this may need more
    + investigation.
    +

    +

    +
    +

    2020-11-23 01:10:54 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +437c020e8f99f429b3b95f11c47ef452b7da287b +

    +

    + LGTM fixes: Rejig gs_type1_interpret to avoid backward gotos.
    +

    +

    +
    +

    2020-11-23 00:27:52 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +63fc05354eae86931f5949086b1b11641f3e23c0 +

    +

    + LGTM: fn_PtCr_evaluate: Simplify gotos.
    +
    + All gotos are now forwards.
    +

    +

    +
    +

    2020-11-20 00:28:58 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +c5ae96a828fa459c0093c578ddbfefe0ce0da5de +

    +

    + Rework cf_decode_2d to minimise gotos.
    +

    +

    +
    +

    2020-11-19 19:26:22 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +0d6498f19173bf3213c289e3e4480e7eb0ee9868 +

    +

    + Reduce use of goto within cf_decode_1d.
    +
    + All gotos are now forwards. Hopefully this should assuage LGTM.
    +

    +

    +
    +

    2020-11-21 12:26:40 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +42ab76c9eb52d5c7dd5f96e0bbee495b84c9d3de +

    +

    + First Page/Last Page - fix a memory leak
    +
    + This doesn't exhibit on regular Ghostscript due to garbage collection,
    + noticed it while running a Memento build of pdfi to track down a
    + different memory leak.
    +
    + We allocate the enumerator in flp_begin_typed_image() and so we need
    + to free it in flp_image_end_image.
    +

    +

    +
    +

    2020-11-20 11:45:50 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +bd48c43be5f736393372dffbad627ed6fc486238 +

    +

    + Bug 703164: Endian issues with CMM
    +
    + The interface code to the CMM was corrected to indicate when a
    + endian swap was needed on the data. This should only occur
    + in the case when we are dealing with transparency buffers
    + during the put image blending operation that may include
    + a color conversion. The final blend bakes the data as BE
    + so if we are on a LE machine, the CMM will need to know to
    + swap the bytes (assuming the pdf14 device is using 16bit buffers).
    +
    + The code was rewritten to make it clear that this setting is no
    + BE vs LE but simply an endian swap. That was a source of confusion.
    +
    + Revealed in this testing was the lack of some proper error
    + reporting during buffer conversions, which were fixed.
    +

    +

    +
    +

    2020-11-20 16:01:33 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +bccfeb0626074ca7cf2a60b194509b8b94b38327 +

    +

    + Memento: Workaround VS2008 not having va_copy.
    +

    +

    +
    +

    2020-11-20 15:34:54 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +e2e50a951f3f06c48d908ea8f095e2d7ae2ee5e9 +

    +

    + Bug 703161: Fix unknown error when interpolating transparent imagemasks.
    +
    + Patch from Alex Cherepanov.
    +
    + Add a dev_spec_op to check for whether copy_alpha is disabled or not.
    + Clist devices with transparency disable it. Use this to bolster the
    + decision made in mask_suitable_for_interpolation.
    +

    +

    +
    +

    2020-11-20 12:35:59 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +86ed012049f58ef01d02c18b8f16c6f343be30db +

    +

    + demos/python: removed old unused code.
    +

    +

    +
    +

    2020-11-19 19:08:04 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +e83bc652ee4776b2c51878267f1c6f5aef0447db +

    +

    + LGTM: Suppress warnings about gotos.
    +
    + In these functions, for implementing state machines, gotos are
    + inevitable.
    +

    +

    +
    +

    2020-11-19 18:43:25 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +cae348d95825d65319a5127f39a954bf68de9ca3 +

    +

    + Rejig dict_find so that gotos are all forwards.
    +
    + Hopefully this will make lgtm happier.
    +

    +

    +
    +

    2020-11-19 17:50:04 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +5e23e7e9daab8498db642fc8ac241ba7f00a157b +

    +

    + LGTM: Attempt to avoid "Expression has no effect" warnings.
    +
    + Some calls may be NOPs in the lgtm tests, but might not be in
    + other builds. Attempt to label them as such.
    +
    + Possibly we may need to label the call sites rather than the
    + functions themselves.
    +

    +

    +
    +

    2020-11-19 13:26:12 -0800 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +905dc88bb9fb75e39dd81ff0268215a1305d94c0 +

    +

    + Change init values of PreserveEPSInfo and ParseDSCCommentsForDocInfo
    +
    + This is needed for pdfi.
    +
    + The docs (VectorDevices.htm) say these will defaulted to 'true' and
    + the gs/PostScript code sets them to true, but they were initialized to
    + false in the device itself.
    +
    + The only place these variables are actually used is in
    + pdf_document_metadata() where they are tested to decide whether to
    + emit the Metadata.
    +
    + This change makes no difference for gs and gs/pdf, but it will cause
    + gpcl to start including Metadata in its pdfwrite output.
    +

    +

    +
    +

    2020-11-17 11:24:28 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +385c2f5d06ec9f99be83d64e83b05296caa20051 +

    +

    + Fix bug 703142: typecheck error caused by Length value with decimal point
    +
    + Thanks to Peter Cherepanov for this patch.
    +

    +

    +
    +

    2020-11-17 17:55:48 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +c1a5382ab783cbae9fd5e069abcc89cb4195e89a +

    +

    + Bug 703027: Tweak previous fix.
    +
    + The previous fix was incomplete; the bounds for the overflow
    + check were incorrect. Corrected here.
    +

    +

    +
    +

    2020-11-17 13:32:10 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +658ddea8bc15f4ab7dd4cf1ff151828b9ce957f9 +

    +

    + Bug 703027: Avoid Infinite loop.
    +
    + The problem here is that the scale is so large that the width
    + overflows what will fit in an int, and becomes negative.
    +
    + Harden the code by watching for such overflows, and abandoning
    + interpolation if this happens.
    +

    +

    +
    +

    2020-11-17 11:47:31 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +0716daba34064520c2ae0a49edb88095aaceac3c +

    +

    + Update makefiles for new nmake version.
    +

    +

    +
    +

    2020-11-15 19:59:15 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +f82f5a5e381f18a76d7099611202a281e61f343f +

    +

    + Fix bug 703088. ASAN reports read outside allocated buffer of an image.
    +
    + There was an area in gx_begin_image3_generic setup for bug 700538 to
    + detect rangecheck but it did not check all extremes. Note that this
    + stems from an absurd CTM in the PDF: 548.0 0 0 -1.43262569e+37 0 0 cm
    +

    +

    +
    +

    2020-11-16 16:13:53 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +0e2d58de146abc7bbb5b4f420086b57e500e9181 +

    +

    + Fix lgtm issue: int * int used as a size_t.
    +
    + int * int can overflow, before being promoted. Best to promote one of
    + the ints to a size_t before the operation, so we don't lose any bits.
    +

    +

    +
    +

    2020-11-16 15:37:00 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +8acc8cf60d99cbd6c9da7c7fd7c2636b09e70624 +

    +

    + Tweak memento.c handling of memento.h header.
    +
    + Intended to remove differences between all the different versions
    + of memento.
    +
    + Rather than manually editing memento.c as we copy it between
    + gs/mupdf/extract we now have a MEMENTO_MUPDF_HACKS define to
    + enable the mupdf specific changes (currently just where we find
    + the header file).
    +

    +

    +
    +

    2020-11-16 15:10:51 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +b06da3dc08682c57001b3686af38eee0a49cb407 +

    +

    + Bug 703146: Fix assert in scan converter.
    +
    + This is caused by lines changing in x position by more than 1<<31,
    + and hence the sign bit of an int being confusing. (e.g. the difference
    + between 0x7fffffff and 0x80000000 is positive, but appears negative
    + when held in an int). Use an unsigned int instead.
    +
    + This doesn't affect normal operation as the value is promoted to an
    + int64_t before being used.
    +

    +

    +
    +

    2020-11-16 10:32:06 +0000 + +
    Julian Smith <julian.smith@artifex.com>
    +1f56cb0a80f9c0485ff224831c4db497da647c0a +

    +

    + base/memento.c: fix coverity warnings about need to call va_end().
    +
    + We now call va_end() for each va_list that we create with va_start() or
    + va_copy().
    +
    + We don't call va_end() for va_list's that are passed in as a function
    + argument.
    +

    +

    +
    +

    2020-11-13 22:39:26 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +07ff645bd83474f01c4fdb658df04f2626bafd7d +

    +

    + Bug 702952: Minor fixes to conversion to V2 ICC Profile
    +
    + The byte padding calculation was wrong and the padded bytes
    + were being left uninitialized. In addition, the profile dump
    + debug code had bit-rotted.
    +

    +

    +
    +

    2020-11-13 16:45:31 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +f0e2607a2c31f71a469c993b7c6c76db900ca5b1 +

    +

    + Update Memento to match MuPDF and Extract.
    +
    + Mostly this is pulling in enhancements from Julian Smith.
    +

    +

    +
    +

    2020-11-13 09:02:07 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +2f585295725c43827544352852a8ed2a357395b9 +

    +

    + Fix Coverity ID 363850
    +
    + Correct a return to actually return a value (no match found).
    +

    +

    +
    +

    2020-11-12 15:12:07 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +6b1ee0c65a8caf8f81d2534402af945d2916feb7 +

    +

    + pdfwrite - fix OCR processing
    +
    + We were not correctly updating the operation and size variables after
    + we had captured the bitmaps leading the code to error out and drop
    + content.
    +
    + Also, if the OCR engine initialisation fails, don't throw an error,
    + just do nothing. Throwing an error results in us falling back to
    + rendering the text as bitmaps.
    +

    +

    +
    +

    2020-06-25 13:56:08 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +75e260886473a74a8d8ec133b0bae9fdee30818b +

    +

    + Squashed commit of pdfwrite_ocr branch.
    +
    + This introduces OCR operation to the pdfwrite device.
    +
    + The full development history can be seen on the pdfwrite_ocr branch.
    +
    + The list of individual commits is as follows:
    +
    + --------------------------------------------
    + Interim commit for pdfwrite+OCR
    +
    + This is the initial framework for pdfwrite to send a bitmap of a glyph
    + to an OCR engine in order to generate a Unicode code point for it.
    +
    + This code must not be used as-is, in particular it prevents the function
    + gs_font_map_glyph_to_unicode from functioning properly in the absence
    + of OCR software, and the conenction between pdfwrite and the OCR engine
    + is not present.
    +
    + We need to add either compile-time or run-time detection of an OCR
    + engine and only use on if present, as well as some control to decide
    + when to use OCR. We might always use OCR, or only when there is no
    + Glyph2Unicode dictionary available, or simply when all other fallbacks
    + fail.
    +
    + --------------------------------------------
    + Hook Tesseract up to pdfwrite.
    +
    + --------------------------------------------
    + More work on pdfwrite + OCR
    +
    + Reset the stage of the state machine after processing a returned value
    +
    + Set the unicode value used by the ToUnicode processing from the value
    + returned by OCR.
    +
    + Much more complex than previously thought; process_text_return_width()
    + processes all the contents of the text in the enumerator on the first
    + pass, because its trying to decide if we can use a fast case (all
    + widths are default) or not.
    +
    + This means that if we want to jump out an OCR a glyph, we need to track
    + which index in the string process_text_return_width was dealing with,
    + rather than the text enumerator index. Fortunately we are already
    + using a copy of the enumerator to run the glyph, so we simply need
    + to capture the index and set the copied enumerator index from it.
    +
    + --------------------------------------------
    + Tweak Tesseract build to include legacy engine.
    +
    + Actually making use of the legacy engine requires a different set
    + of eng.traineddata be used, and for the engine to be selected away
    + from LSTM.
    +
    + Suitable traineddata can be found here, for instance (open the link,
    + and click the download button):
    +
    + https://github.com/tesseract-ocr/tessdata/blob/master/eng.traineddata
    +
    + --------------------------------------------
    + Add OCRLanguage and OCREngine parameters to pdfwrite.
    +
    + --------------------------------------------
    + Add gs_param_list_dump() debug function.
    +
    + --------------------------------------------
    + Improve use of pdfwrite with OCR
    +
    + Rework the pdfwrite OCR code extensively in order to create a large
    + 'strip' bitmap from a number of glyphs in a single call to the text
    + routine. The hope is that this will provide better context for
    + Tesseract and improved recognition.
    +
    + Due to the way that text enumerators work, and the requirement to exit
    + to the PostScript interpreter in order to render glyph bitmaps, I've had
    + to abandon efforts to run as a fully 'on demand' system. We can't wait
    + until we find a glyph with no Unicode value and then try to render all
    + the glyphs up to that point (and all the following ones as well). It is
    + probably possible to do this but it would mean rewriting the text
    + processing code which is quite hideous enough as it is.
    +
    + So now we render each glyph in the text string, and store them in a
    + linked list. When we're done with the text we free the memory. If we
    + find a glyph with no Unicode value then on the first pass we take the
    + list of glyphs, create a big bitmap from them and send it to Tesseract.
    + That should then return all the character codes, which we keep. On
    + subsequent missing Unicode values we consult the stored list.
    +
    + We need to deal specially with space glyphs (which make no marks) as
    + Tesseract (clearly!) can't spot those.
    +
    + Modify makefile (devs.mak) so that we have a preprocessor flag we can
    + use for conditional compilation. Currently OCR_VERSION is 0 for no OCR,
    + 1 for Tesseract, there may be higher numbers in future.
    +
    + Add a new function to the OCR interface to process and return multiple
    + glyphs at once from a bitmap. Don't delete the code for a single bitmap
    + because we may want to use that in future enhancements.
    +
    + If we don't get the expected number of characters back from the OCR
    + engine then we currently abort the processing. Future enhancements;
    + fall back to using a single bitmap instead of a strip of text, if we get
    + *more* characters than expected, check for ligatures (fi, ffi etc).
    +
    + Even if we've already seen a glyph, if we have not yet assigned it a
    + Unicode value then attempt to OCR it. So if we fail a character in one
    + place we may be able to recognise it in another. This requires new code
    + in gsfcmap.c to determine if we have a Unicode code point assigned.
    +
    + Make all the relevant code, especially the params code, only compile
    + if OCR is enabled (Tesseract and Leptonica present and built).
    +
    + Remove some debugging print code.
    +
    + Add documentation
    +
    + --------------------------------------------
    + Remove vestiges of earlier OCR attempt
    +
    + Trying to identify each glyph bitmap individually didn't work as well
    + and is replaced by the new 'all the characters in the text operation'
    + approach. There were a few vestiges of the old approach lying around
    + and one of them was causing problems when OCR was not enabled. Remove
    + all of that cruft here.
    +

    +

    +
    +

    2020-11-11 15:34:31 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +8aa60c55d789c9c4d9e600162a1233a2da7ba516 +

    +

    + Fix bug 703125: -dNOINTERPOLATE leaves 'true' boolean on the stack.
    +
    + Thanks to Peter Cherepanov for spotting this. This patch is slightly
    + different to his in that it makes -dNOINTERPOLATE=false enable interpolation
    + at the default level (the original patch and the old code would have
    + disabled interpolation even with 'false'. This version makes the NOINTEPOLATE
    + and DOINTERPOLATE options operate more symmetrically, however it is sort of
    + moot since both of these options are intended to be replaced by the better
    + control on image interpolation provided by -dInterpolateControl=#
    +
    + Operation tested with fts_17_1712.pdf using the various command line options.
    +

    +

    +
    +

    2020-11-10 23:38:08 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +7d1f774ccf8d3c96dc9a40d317e1448cb5a6475a +

    +

    + Bug 701804: Fix for device that causes buffer overflows
    +
    + This contributed device is odd how it changes its color model.
    + Unfortunately it does not change the ICC profile. This mismatch
    + between the ICC profile and the color information that is
    + being changed by the device causes all sorts of problems. This
    + should fix the issue.
    +

    +

    +
    +

    2020-11-11 12:22:39 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +d3a0d4c4c5e6c7c1662094500f25c11b27016268 +

    +

    + MSVC: Add sanitize configurations/targets.
    +
    + While we have 64bit configurations, these will only work for 32
    + bit builds at the moment, due to MSVC not supporting 64bit builds.
    +

    +

    +
    +

    2020-11-10 13:00:49 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +c2fa28dbaa4c238eba4c8236d7da3a12113b734c +

    +

    + PDF interpreter - fix searching for missing Resources in parent object
    +
    + Bug #703105 "PDF file gives "Unable to determine object number..." and output is missing some images."
    +
    + As per the bug thread; the PDF file has annotations which are deeply
    + nested forms. The final form stream draws an Image XObject but the
    + Form dictionary does not contain a /Resources dictionary so we are unable
    + to resolve the name.
    +
    + The form which calls the final form *does* define the missing XObject,
    + this is pretty clearly illegal but Acrobat copes with it. In fact the
    + Ghostscript PDF interpreter has code to deal with it too, but there
    + was a bug in it, it pops an object that was never pushed, resulting in
    + the code being unable to find the resource.
    +
    + Fixed very simple here. Also uploaded the simplified file for this bug
    + and the file for the original bug (700493) to the test repository.
    +

    +

    +
    +

    2020-11-09 15:39:41 +0000 + +
    Julian Smith <jules@op59.net>
    +9a7452d624e9ef8f284869a2943b3751ecb6dbd6 +

    +

    + toolbin/localcluster/clusterpush.pl: exclude extract's src/build.
    +

    +

    +
    +

    2020-11-09 13:53:46 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +5a3812294b479fbae21e7d0fa3e1c6e0887fe51e +

    +

    + api_test: Simplify pointer hiding.
    +
    + We can get pointer reuse that can vary from run to run, so we
    + resort to just using null/non-null pointer hiding.
    +

    +

    +
    +

    2020-11-09 13:31:23 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +40d306bf6707c365996eb1d41782ca3f063311d0 +

    +

    + ps2write - fix use of /.HWMargins with ps2write output
    +
    + Bug #703017 "When print a file created with pdf2ps command with a PDF driver, the image shifts to the upper right as the number of pages increases."
    +
    + The bug report here is, unfortunately, insufficient to duplicate and
    + resolve the problem. The missing information was supplied quite
    + independently by the user 'vyvup' on the #ghostscript IRC channel. See
    + the #ghostscript logs at around 08:45 on November 9th 2020.
    +
    + https://ghostscript.com/irclogs/20201109.html
    +
    + The important missing information is that the device must have the
    + Ghostscript-specific page device key /.HWMargins set. When this is set
    + and has non-zero values the offsets are applied cumulatively on every
    + page by the code in pdfread.ps. This is because we set up the page
    + 'view' before we save the current setup in the ps2write dictionary
    + under the 'pagesave' key. When we restore back to that at the end of the
    + page it therefore does not remove the translation applied to account
    + for the /.HWMargins.
    +
    + Here we just shift the save so that it occurs before we apply the page
    + size setup.
    +

    +

    +
    +

    2020-11-07 13:14:06 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +cceb68900b433e7ce518619b9dd2ceb01c4fed9d +

    +

    + Fix bug 688166. EPS DSC comment processing not terminating properly.
    +
    + The example files of this bug do not have %%EndComments before other
    + BoundingBox comments which confuse the image placement logic resulting
    + in a blank page.
    +
    + This patch, provided by Peter Cherepanov, fixes the problem by stopping
    + the DSC processing when (%%BeginProlog) (%%BeginSetup) or %%EndComments
    + is encountered.
    +
    + Cluster regression passes, showing only 1 file that rotates differently
    + when -dEPSFitPage is used (just to insure that DSC processing is OK).
    +

    +

    +
    +

    2020-11-06 16:31:11 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +abe5348a1de7793a5d4d6ecfa4d054e5f94731de +

    +

    + apitest: Hide pointer values in output.
    +
    + This should enable the runtests values to be consistent.
    +

    +

    +
    +

    2020-11-06 11:18:47 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +2f6d9adb2e1cf6d7043c1de6168fee42dcb2cb8f +

    +

    + Bug 702005 : rectfill and transparency
    +
    + If we end up in the rectfill operation and we have transparency
    + make sure that we take the path that uses gs_fill to ensure that
    + pdf14_fill_path is executed, which will update the marking parameters.
    +

    +

    +
    +

    2020-11-07 00:33:46 +0800 + +
    Sebastian Rasmussen <sebras@gmail.com>
    +63281fa98f6df0864315a9fc78ef436a6d96f90a +

    +

    + jbig2dec: Add casts to silence a compiler warning.
    +

    +

    +
    +

    2020-11-05 21:24:13 -0800 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +2a427e4dfb0b74f121b846e7d08e8c80db0f5f37 +

    +

    + Bug 703087: CIEBased color space with overprint
    +
    + If the source space is CIEBased PS type, then be
    + sure to use the equivalent ICC color space in
    + determining the overprint drawn components.
    +

    +

    +
    +

    2020-11-05 12:40:00 -0800 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +0132ddfb73e316303fe382aed939f1145052d15c +

    +

    + Bug 703086 -- Disable trying to preserve Movie annotations
    +
    + Movie annotations are not implemented. This fix just disables the attempt to
    + preserve them, so that the pdfwrite output will be valid.
    +
    + This file has a /Movie annotation that references a local file that
    + isn't included in the PDF, so it will never play properly anyway.
    +
    + The annotation tries to reference a stream in its /Poster entry (for
    + the image preview of the Movie), and this was not being handled
    + correctly.
    +

    +

    +
    +

    2020-11-03 22:00:17 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +bdf7cf8b6c7c97531aac14e16b9d2c16775ae8c8 +

    +

    + Fix Bug 702034. Missing image to DeviceN devices.
    +
    + The file from Bug 693300 has a blank image when going to DeviceN devices
    + such as psdcmyk and tiffsep. The CompatibleOverprint blend mode must be
    + set before the transparency group is pushed.
    +
    + Add a .special_op for SupportsDevn to let the PostScript PDF interpreter
    + detect that the device supports separations.
    +
    + Make sure the mark fill rect for the knockout case handles
    + the hybrid case of additive process colors with subtractive spots
    + and overprint.
    +
    + And make sure the group that is pushed in gstrans.c for text knockouts
    + uses compatible overprint if needed.
    +
    + Ray did the PS parts and Michael did the pdf14dev parts.
    +

    +

    +
    +

    2020-11-04 09:10:26 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +e6d34e7d08dac91b5b3b858c23e186a0d3bcbefc +

    +

    + pdfwrite - Fix potential seg faults with ColorConversionStrategy
    +
    + Bug #702885 " ICC profile management can lead to a crash due to lack of reference counting of profiles" ICC profile management can lead to a crash due to lack of reference counting of profiles
    +
    + See the bug report for details, this commit removes the dereference of
    + the ICC profile as recommended by Michael in that thread.
    +

    +

    +
    +

    2020-11-03 15:21:46 +0000 + +
    Robin Watts <Robin.Watts@artifex.com>
    +10036de9c385d900f2ec0312908954ab77664438 +

    +

    + Update clusterpush.pl for extract jobs.
    +

    +

    +
    +

    2020-11-03 09:24:37 -0800 + +
    Ray Johnston <ray.johnston@artifex.com>
    +b4c9f0004f950a7f55fff5777c6fa0d74d1f54bd +

    +

    + Fix bug 702957, 702971. PageList problems with PDF input files.
    +
    + Thanks to Peter Cherepanov for this fix.
    +
    + The page skipping was caused by not disabling the PageHabdler in
    + even or odd page selection modes due to a typo (Pagelist instead of
    + PageList). The PDF interpreter fed only the odd (or even pages),
    + and then the PageHandler also skipped every other page.
    +
    + Also correct log messages and associated operand stack mess-up.
    +

    +

    +
    +

    2020-10-31 18:38:51 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +3f191b620de1b1cdead14305aac09ad49340828f +

    +

    + Fix another SEGV with BGPrint due to device_unsubclass
    +
    + The printer device needs to have the bg_print structure external to the
    + device so that when the device is freed the bg_print communication area
    + shared with the thread doesn't get freed. This is similar to the clist
    + band_range_list issue.
    +
    + The SEGV was seen with 15-01.BIN as it unsubclasses the PCL_Mono_Palette
    + gs_pcl_mono_palette_device device.
    +

    +

    +
    +

    2020-10-31 10:48:22 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +8df410c269150bce143d3b8875ac9d60a013d206 +

    +

    + Set orig_spec_op for printer class devices so it forwards properly.
    +

    +

    +
    +

    2020-10-29 15:15:00 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +2c5a8a34dd741936469f0500cfebe364d8a1fdc3 +

    +

    + FIx SEGV with gx_device_unsubclass when child is a clist device.
    +
    + The 'band_range_list' was a structure of two pointers within the device
    + (gx_device_clist_writer) so when it was copied, the 'ccl' pointer could
    + point to the band_range_list structure in the child device. This pointer
    + would no longer be valid when the child device was freed as the device
    + unsubclass did.
    +
    + Detected with 15-01.BIN as it called gx_device_unsubclass for the PCL_mono
    + subclass device. With -Z@ the band_range_list would be overwritten with
    + (known, but invalid pointer) data resulting in the SEGV.
    +
    + Cured by putting the band_range_list into the clist_writer 'data' area.
    + This area is not GC'ed and since it points into other memory in the
    + clist writer 'cbuf' area, it is internal to the clist writer.
    +

    +

    +
    +

    2020-09-26 20:45:48 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +9848e66c0687645ed533e50557c233bf196ec9b9 +

    +

    + Make gs_next_ids thread safe by using the core->monitor.
    +
    + This cures data races with gs_next_ids seen with helgrind and BGPrint
    + and/or NumRenderingThreads.
    +

    +

    +
    +

    2020-09-26 18:36:16 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +eec6fd158ee477facfb4bf9edd4e99506c195732 +

    +

    + Pacify helgrind so that gs_heap_status is thread safe.
    +
    + The 'heap_available' is documented as a 'snapshot', but is not a
    + thead risk. This change locks around the collection of the info to
    + be returned in the gs_memory_status structure.
    +

    +

    +
    +

    2020-09-15 08:51:08 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +13ed12281b6b60804172a6844081a9ea3e067d2d +

    +

    + Fix problem with BGPrint and multi-threaded rendering caused by commit cca27988
    +
    + The unconditional call to enable multi-threaded rendering during set up of the
    + gx_device_printer as a clist caused the SEGV of bug 702181, but enabling
    + multi-threaded rendering here isn't correct since it is usually done when we
    + output the page (gdev_prn_output_page_aux). The problem is that BGPrint would
    + setup a new clist device to render the page, but needs to enable multi-threaded
    + rendering for the background clist device. Do this if NumRenderThreads > 0.
    +

    +

    +
    +

    2020-09-22 13:10:04 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +4ceaf92815302863a8c86fcfcf2347e0118dd3a5 +

    +

    + Fix gp_file allocations to use thread_safe_memory.
    +
    + The gpmisc.c does allocations for gp_file objects and buffers used by
    + gp_fprintf, as well as gp_validate_path_len. The helgrind run with
    + -dBGPrint -dNumRenderingThreads=4 and PCL input showed up the gp_fprintf
    + problem since the clist rendering would call gp_fprintf using the same
    + allocator (PCL's chunk allocator which is non_gc_memory). The chunk
    + allocator is intentionally not thread safe (for performance).
    +

    +

    +
    +

    2020-10-28 12:17:23 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +033ed8bf196b1cddd681a9b32d9398bf6bc02d24 +

    +

    + Bug 702671: Make sure X11 device cleans up with closure
    +
    + The issue is that the pdf14 device will close and reopen the
    + target device under certain cases and the X11 devices were not
    + cleaning themselves up sufficiently. Also added a finalize
    + method where the call to XCloseDisplay should actually be made.
    +
    + The pdf14 device does this close and open dance to ensure that
    + the page_has_transparency parameter will be set in the device.
    + It is possible that we could end up in the pdf14 device
    + push without page_has_transparency if the call is done from
    + Postscript code. The PDF interpreter
    + always sets the page_has_transparency value before doing the
    + push so this should not be a problem with PDF.
    +
    + Thanks to Chris Liddell for helping with this.
    +

    +

    +
    +

    2020-10-29 10:43:46 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +36568c21f45ed0686abec8316f56bc171ab416a8 +

    +

    + Add /Type /Outlines to Outlines entry for pdfwrite
    +
    + This is technically required, but appears to be harmless to omit it.
    + However, since the fix is trivial, I have fixed it.
    +

    +

    +
    +

    2020-10-29 15:49:11 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +14a3807f1a13d7a4fed1b1ef24852d55a4361431 +

    +

    + Fix ios build script and headers
    +
    + The predefined headers for the ios build were missing the size_t updates.
    +
    + We also don't want to try using CAL with ios (at least, for the moment).
    +

    +

    +
    +

    2020-10-28 17:07:20 +0000 + +
    Chris Liddell <chris.liddell@artifex.com>
    +10ff34748a56d521b5a901c11edb4b6408a2860a +

    +

    + Fix an option typo: "nonredundnat" -> "nonredundant"
    +

    +

    +
    +

    2020-10-28 15:31:28 +0000 + +
    Ken Sharp <ken.sharp@artifex.com>
    +ddd5cf4ddcfba1a3e85708b75efa0d8f8f4156f6 +

    +

    + pdfwrite - fix Type 4 Chroma-keyed images with Colour Conversion
    +
    + Bug #702698 "convert Grayscale error in output"
    +
    + Images with a /Mask where the Mask is a range of values, and hence a
    + chroma-keyed image, as opposed to the Mask being an external Image
    + Mask, and therefore a stencil cannot be preserved as such when we are
    + colour converting.
    +
    + There is no reliable way to be certain that the colour of the image
    + samples after conversion and the converted Mask values will relate in
    + the same way. Its entirely possible for multiple RGB values to map to
    + the same gray value for instance, and if that happens to be a masked
    + value then pixels will be masked which were not originally.
    +
    + This commit checks the ColorConversionStrategy and if it is not
    + LeaveColorUnchanged then we further examine the Mask. If the Mask is a
    + range of values then we consider the colour space of the image.
    +
    + If ColorConversionStrategy is not LeaveColorunchanged and the image has
    + a range of values and it is not in the target colour space, then we
    + cannot preserve it. In this case we fall back to either preserving the
    + image, and creating a clip path from the chroma key and the image
    + samples, or (if Version < 1.3) we fall right back to writing each image
    + sample as a filled rectangle.
    +
    + This does, of course, result in larger output.
    +

    +

    +
    +

    2020-10-13 08:16:11 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +81ed663a4a81a265afecbc7b7c7835ba4f5f24e1 +

    +

    + Change default ShowAcroForm to true to match Adobe Acrobat.
    +
    + Change it and the documentation. It may be that older Acrobat defaulted to
    + ignoring AcroForm, but current Adobe doesn't.
    +
    + Also fix pdf_draw draw_form_field to match check in pdf_main process_trailer_attrs
    + for the file from Bug 692447 which has null entries in Fields array.
    +
    + Fix indentation in pdf_main process_trailer_attrs area that processes
    + AcroForm dict.
    +

    +

    +
    +

    2020-10-17 12:52:36 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +8313e4f30bef7c50711cd503c3037184a7850d51 +

    +

    + Fix Bug702995: Inconsistent auto-rotation of EPS with EPSFitPage.
    +
    + We need to defer the EPSFitPage scaling, centering and rotation until
    + after both the the %%BoundingBox and/or the %%HiResBoundingBox have been
    + processed. Doing one after the other results in slight rounding diffs
    + depending on the resolution. Change to save the value (prefering the
    + HiResBoundingBox) and do the scaling/translate/rotate only once when
    + %%EndComments is processed.
    +

    +

    +
    +

    2020-10-13 08:21:05 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +76359f0c03e8b4d8db7359d521865894ac7a4592 +

    +

    + Fix bug 702951. Valgrind error in image_render_interpolate_landscape_icc
    +
    + Make the same adjustment in image_render_interpolate_landscape_icc() as
    + was done in image_render_interpolate_icc() by the commit a936cf76.
    +
    + Thanks to Peter Cherepanov for this bug report and the patch. Regression
    + testing looks fine and the previous code looks like it would bump the
    + p_cm_interp value twice in some cases previously.
    +

    +

    +
    +

    2020-10-23 08:54:02 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +9cdacf4e5efcf7b92ff7a02158a47ac04cc12fa7 +

    +

    + Revise font dir global_glyph_code callback API
    +
    + The global_glyph_code callback API relies on the name table being avaiable in
    + the gs_lib_ctx and accessible via the gs_memory_t object.
    +
    + This is not something that is true, nor can we make it true, for pdfi. Because
    + pdfi is required to integrate with the Postscript interpreter, we cannot have
    + the gs_lib_ctx "top_of_system" pointer point to the pdfi context.
    +
    + So, change the global_glyph_code API so it takes a gs_font pointer, instead of
    + a gs_memory_t pointer. The Postscript implementation will work exactly the same,
    + just accessing the gs_memory_t through the gs_font pointer.
    +
    + But it allows pdfi to grab it's own context through the gs_font "client_data"
    + pointer.
    +

    +

    +
    +

    2020-10-20 11:20:45 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +17cec404918eb458b63aba71fe680264f2a00179 +

    +

    + Update freetype to 2.10.4
    +
    + Also includes:
    + Work around a change in the zlib API for 1.2.11
    +
    + where it's used in the Freetype/zlib interface debugging code.
    +

    +

    +
    +

    2020-10-21 16:11:23 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +660aa7a7eaeca446d97332ae1655a3612c9bcfe6 +

    +

    + Add error check on gx_device_text_begin return_error
    +
    + gx_device_text_begin may return an error if there is still
    + work to be done on a pattern device. Catch that before
    + the check on *ppte, which will not be a valid value in this
    + case.
    +

    +

    +
    +

    2020-10-22 17:20:11 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +7670751b807e369e4bb768cce2812a8d8719b8fa +

    +

    + Fix typos in comments of zugferd program
    +
    + As (mostly) spotted by Lisa Fenn, fix comments in typos and messages.
    +

    +

    +
    +

    2020-10-21 19:20:43 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +b231780b739720451e8d6517b2e97a07908b7469 +

    +

    + lcms2: automatically align blocks appropriately on sparc.
    +
    + The sparc architecture requires pointers within structures to
    + be at 64bit alignment, even if they are 32bit pointers.
    +
    + LCMS2 allows for this by having a CMS_PTR_ALIGNMENT symbol
    + that can be predefined. If it's not predefined, it defaults to
    + sizeof(void *).
    +
    + We update the source here so that when building for sparc, it
    + defaults to 8. This shouldn't affect gs, as it sets the value
    + via configure/make. I believe our lcms2 repo as used in MuPDF
    + is autogenerated from this though, and this will help us there.
    +

    +

    +
    +

    2020-10-20 12:38:24 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +337be82addaaf8740b60e2a0cf354ae96d46468f +

    +

    + Correct OCR docs for multiple languages.
    +

    +

    +
    +

    2020-10-20 09:49:45 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +41ef9a0bc36b9db7115fbe9623f989bfb47bbade +

    +

    + Bug 702985: drop use of FT_CALLBACK_DEF() def
    +
    + From 2.10.3, Freetype disappeared the FT_CALLBACK_DEF() macro, which is what
    + we used when defining our callbacks from Freetype.
    +
    + No guidance forthcoming from the Freetype developer who made those changes,
    + so change to explicitly declaring the callbacks file static.
    +
    + Should fix the reported build failures.
    +

    +

    +
    +

    2020-07-31 11:07:18 +0100 + +
    Julian Smith <jules@op59.net>
    +3b2f9c53c8e5cebcf80a4158684b820d9a0a2f73 +

    +

    + devices/vector/gdevtxtw.c: updated extract output to match mupdf.
    +
    + Text extraction now works for Python2.pdf and zlib.3.pdf.
    +
    + Added GlyphWidths[] and SpanDeltaX[] arrays, containing information required
    + for generating intermediate format used by extract system.
    +

    +

    +
    +

    2020-07-30 13:09:51 +0100 + +
    Julian Smith <jules@op59.net>
    +de5cb392ad32d4e44646b144f435ad186f3dbabe +

    +

    + doc/VectorDevices.htm: added brief info about txtwrite TextFormat=4.
    +

    +

    +
    +

    2020-10-19 16:34:32 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +5c115ea0d27640b2a3940410c6eeef9e7d17f178 +

    +

    + Fix indeterminisms within halftoned rendering.
    +
    + When checking for pdf14 being in an opaque state, we check to see
    + whether we are either constructing an SMask or are within an
    + SMask. We need to use a dev spec op for this, as we might be within
    + a clipper device, and so not actually be directly a pdf14 device.
    +

    +

    +
    +

    2020-10-19 11:24:15 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +5fc95757e3f732d5806a9a74967d70571eec91db +

    +

    + New file - program to assist in creating ZUGFeRD electronic invoices
    +
    + While documenting the process for creating a ZUGFeRD invoice from a PDF
    + file and an XML invoice it became clear to me that it was beyond any
    + reasonable expectation of a user to be able to use it unaided. So this
    + program assists in the creation of a ZUGFeRD document.
    +
    + The program requires two command line parameters; -sZUGFeRDProfile=
    + which contains a fully qualified path to an appropriate (correct colour
    + space) ICC profile, and -sZUGFeRDXMLFile= which contains a fully
    + qualified path to the XML invoice file.
    +
    + Example command line is in the comments, and a usage message if the user
    + fails to provide either of the required elements. Obviously the user
    + must also set -dPDFA=3 and -sColorConversionStrategy in order to create
    + a valid PDF/A-3b file.
    +

    +

    +
    +

    2020-10-14 11:28:56 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +23afb36c6d8c5368a7df09718b872f83c510cab7 +

    +

    + Bug 702891 and Bug 700593 Fix pdf14 device color procs
    +
    + The pdf14 color mapping procs clearly had some issues as they are reading uninitialized
    + memory and using transfer functions that would not make sense with changing
    + color spaces. Also, the soft mask should not be going through the effective_transfer.
    + It has its own transfer function to deal with. Careful reading of the PDF spec revealed
    + that the transfer function is only to be used if the color being drawn is opaque. It
    + states that this is true if the blend mode is normal, stroke and fill alpha are 1.0, and
    + no soft mask is present. Also, an image that has a soft mask does not use the transfer
    + function. These changes resulted in a lot of diffs. I reviewed them and
    + did some checking of color values to verify things are ok.
    +

    +

    +
    +

    2020-10-14 15:05:04 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +fceb46d81b0277b335481368dcc5a62e6383575e +

    +

    + PDF interpreter (with pdfwrite) - another non-square scaling stroke fix
    +
    + Bug #702946 "Ghostscript creates PDF originals with black stripes"
    +
    + This is another case of the problem in bug #702900, The commit to fix
    + that problem (d5494de2cab28b91ba360d15b8afffef50a3f421) fixed four
    + places in the code, but missed a fifth place because it is distant from
    + the other four. The offending procedure is setstrokeforTrpreservation.
    +
    + This commit adds the required code to that location to go along with the
    + other four, at the same time:
    +
    + 1) Move the actual code to calculate the width into a procedure
    + 2) Have all 5 places use that procedure
    + 3) Improve the non-square calculation (hypotenuse/2 instead of hypotenuse)
    + 4) Add some 'tolerance' to the equality test.
    +
    + The tolerance is because both the test file here and in 702900 have a
    + CTM which is minutely non-square. In this case the c and y scaling
    + differ by less than 0.0001. The intention of this code is actually to
    + deal with non-square resolutions, rather than non-square CTM, and it
    + does so by calculating the hypotenuse of a triangle where the x an y
    + values are the linewidth in each direction. In fact the hypotenuse/2
    + seems a closer approximation. But in any event its incorrect, better to
    + simply use the linewidth if the difference between the two is not very
    + large. (eventually, with pdfi, we will probably do away with this
    + horrible kludge entirely)
    +
    + This causes minor but useful progressions in the test suite files
    + Bug695841.pdf, clipping_image_problem.pdf and
    + sumatra/712_-_image_not_displaying.pdf. most notably the latter.
    +
    + It also produces slightly less bold output for the test file here,
    + which Acrobat shows as matching precisely with the original.
    +

    +

    +
    +

    2020-10-07 17:41:36 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +c6ce09aa5c9ed0c66c597478a2c4fb75aa25267f +

    +

    + Revert "Remove deprecated opvp/oprp devices from default build"
    +
    + This reverts commit 66c2469c7d4543f32d6dc93edf1d649e809b8419.
    +
    + A user got in touch to say that he maintains a printer driver "back end" that
    + uses the opvp device. So reinstating it - at least we know it's getting
    + tested.
    +

    +

    +
    +

    2020-10-12 13:19:09 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +5af4f31bcda18c6fb7d14501c0a22697a7f49ac0 +

    +

    + Update tesseract traineddata loader with new path search.
    +
    + First, we look in TESSDATA_PREFIX (if defined).
    +
    + If not found there, we look in ROMFS (in tessdata).
    +
    + If not found there, we look at the configured "tessdata" path
    + (which defaults to ${datadir}/tessdata). (${datadir} defaults to
    + ${prefix}/share on unix, and ${gsrootdir} on windows.)
    +
    + If not found there, we look in the current directory.
    +
    + Update doc/Devices.html (and fix some indexing).
    +

    +

    +
    +

    2020-10-13 11:05:00 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +848077c4f7b8b9131263b483ba90b05e0ee4e9d2 +

    +

    + pdfwrite - reorder code to change evaluation order of image parameters
    +
    + Bug #702961 "GS produces significantly larger PDFs with same settings as Adobe Distiller"
    +
    + This is a problem with the interaction of various image parameters. The
    + relevant options are PassThroughJPEGImages, ColorConversionStrategy and
    + AutoFilterColorImages.
    +
    + Because PassThroughJPEGImages is true, we don't set up a compression
    + filter (we don't want to apply compression to a DCT compressed data
    + stream). But ColorConversionStrategy is /sRGB, so we then turn off the
    + PassThroughJPEGImages (we cannot change the colour model and still
    + pass through the original data, obviously). Ordinarily the compression
    + chooser would then select a compression based on the result, but
    + AutoFilterColorImages is false, so the compression chooser is disabled.
    +
    + The result is that we write uncompressed image data to the file.
    +
    + By reordering the code so that we check the ColorConversionStrategy
    + earlier we can turn off PassThroughJPEGImages before selecting the
    + initial compression which means that this p[articular sequence of
    + options will then work as expected.
    +

    +

    +
    +

    2020-05-26 12:05:46 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +02e3169b57724f63ce01c994d39c20647be5c20b +

    +

    + Bug 702192 Map text to black
    +
    + Map all text to black. This is achieved by altering the
    + color space to DeviceGray with a fill of black during
    + gs_text_begin. When gs_text_release occurs, the color space
    + is restored. This will only occur with the option -dBlackText
    + and if the text is actually to be drawn.
    +
    + When going to a raster device, the stroke and stroke fill of
    + the text is handled with a stroke or stroke fill command.
    + My original plan of storing the old color spaces and client
    + color in the text enumerator will not work in this
    + situation as it the enumerator will have already been
    + destroyed when the stroke or stroke/fill command occurs.
    + For this reason I store the old color space information
    + for the current and alternate color spaces
    + in the graphic state. The structure holding the information
    + is garbage collected as it is holding objects that may be
    + garbage collected. We also need to know if the target
    + was a high level device like pdfwrite, as that device
    + will handle the fill AND stroke, and we will need to restore
    + the color space when we tear down the text enumerator.
    +
    + gs_text_release needed to have the pgs added as a parameter
    + to allow the possible release of the blacktext structure
    + when the text is released from the other languages. This
    + did not seem to be too big of an issue as gs_text_begin
    + passes the pgs also. If the pgs is not available, NULL can
    + be passed, and that is done in several locations.
    +
    + A new special op was added to let us avoid doing the black
    + text setting if we are constructing a soft mask. If we did not
    + do this the mask could result in the loss of the text.
    +
    + Finally, Type 3 fonts will NOT be affected by this process.
    + Type 3 fonts are often used for actual graphic logos etc.
    + Ken Sharp suggested we not have them affected by this setting.
    + There were also issues with trying to do type 3 fonts in
    + in that the PDF interpreter does some color space settings
    + of its state when dealing with type 3 fonts and this put the
    + interpreter's state out of sync with the graphic library state.
    +
    + This was tested with a forced setting of black text enabled.
    + No seg faults or errors occurred. There were obviously a lot
    + of differences reported (over 33,000). All the images that were available
    + to me with bmpcmp were gone through. Problems were found
    + and addressed (the soft mask issue for example was found,
    + as were issues with color spaces not getting properly restored).
    +

    +

    +
    +

    2020-10-12 16:10:30 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +1ff2ddac001612df3d54b504b49f6ee8e0685be7 +

    +

    + PostScript interpreter - add a new IdiomSet for PPI 'ColorUtils'
    +
    + Bug #702964 "EPS file hangs with pdfwrite"
    +
    + This is not related to the hang, but to the remaining problem with this
    + file and pdfwrite.
    +
    + When using pdfwrite with PassThroughJPEGImages the output is incorrect.
    + The reason is that the PostScript program processes the JPEG compressed
    + data, turning a 4-component CMYK image into a single component gray
    + image.
    +
    + Obviously if we pass through the original CMYK data, but declare the
    + image a DeviceGray the result is incorrect.
    +
    + The only way to deal with this is to turn off the feature. There's no
    + simple way to do this in pdfwrite (where we normally decide to turn it
    + off, for downsampling etc) without disabling it for a number of other
    + useful cases. So instead add a new IdiomSet which replaces part of the
    + PPI ColorUtils ProcSet with a redefined procedure which turns off the
    + PassThroughJEPGImages feature if the ProcSet forces Gray output.
    +

    +

    +
    +

    2020-10-12 16:05:10 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +447d30a88cf38d623c9afa783ff0a16b98f9e4ff +

    +

    + pdfwrite - Terminate pass-through images when we have read enough data
    +
    + Bug #702964 "EPS file hangs with pdfwrite"
    +
    + This is only a partial fix for the bug report, the remaining problem
    + is addressed in a following commit.
    +
    + The problem here is that the EPS file includes a ProcSet which processes
    + the JPEG compressed data. It does so using a procedural DataSource for
    + the image operator. Unfortunately the procedure fails to spot that
    + readstring returns 0 bytes and identify this as en EOD. Instead it
    + continues to try and read data, which continuously fails.
    +
    + While the cause of the hang is in the PostScript program, it does not
    + normally exhibit because the image operator ceases to read data from the
    + DataSource when it has read enough samples to satisfy the declared
    + Width/Height/BPC. An oversight in the pass-through code meant that the
    + image operator wasn't properly terminating even when enough data had
    + been supplied.
    +
    + This commit correctly returns either 0 (require more data) or not-zero
    + (enough data read) so that the operator terminates.
    +

    +

    +
    +

    2020-10-12 13:18:16 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +d4777d3bfa3fe17297d52eb318b4b93e1b0485b6 +

    +

    + Update makefile for tesseract changes.
    +

    +

    +
    +

    2020-10-12 08:10:17 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +965f842329e697a945a40ba1ff9a578612bf9f16 +

    +

    + Coverity ID 363024: Check gs_sprintf() retrn value
    +
    + before we use it.
    +

    +

    +
    +

    2020-10-07 14:14:37 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +b2a7564bc80f61095e7dd3024f1ce51026366909 +

    +

    + Add/remove paths to permit-file-read automatically for tesseract.
    +

    +

    +
    +

    2020-10-07 11:50:23 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +1bbd20f2f099c63e5d325979e43182b617e9fb3a +

    +

    + Fix Tesseract build glitches.
    +

    +

    +
    +

    2020-10-02 15:03:32 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +9666e6206135b637b7545f074a25969972662252 +

    +

    + Squash a compiler warning (uninitialized variable)
    +

    +

    +
    +

    2020-10-02 14:52:33 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +5e85cde6eb20fc1f6ae13c69f80cc800cbacf164 +

    +

    + "Address" subscript -1 is outside array bounds warning
    +
    + There is no immediate prospect of resolving the underlying issue: that the
    + stream code requires the data pointer in the "cursor" to be initialised to the
    + address one byte *before* the beginning of the actual buffer.
    +
    + We also do not want to disable the array bounds warning completely, as that
    + risks missing real mistakes.
    +
    + So, define a static inline function which does the offending pointer assignment,
    + and disable the warning locally, for only that function. Then have everywhere
    + that uses such a buffer setup call that function, rather than do the assignment
    + itself.
    +
    + At the moment, it is only disabled for gcc (and compatible) compilers, we can
    + add others if/as required.
    +

    +

    +
    +

    2020-10-01 16:06:31 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +fd902c6702ef81008d7c91b09a0723661c0f9201 +

    +

    + oss-fuzz 23946: Move buffer bounds check to *before* using it!
    +
    + ASCII85Decode filter: We correctly bounds check the buffer size, but dumbly
    + were doing so *after* we'd used the relevant indices into the buffer. Change
    + that order, and add another check.
    +

    +

    +
    +

    2020-09-17 08:26:44 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +aaeccfffecee65225dabac32689a15a239d01681 +

    +

    + Change order of compiler options for third party libs
    +
    + Move the compiler parameters around so the third party lib specific -I options
    + come first - hopefully meaning we'll favor any included headers over those in
    + the system include path(s).
    +
    + This assumes the compiler searched include directives given on the command line
    + left to right. Apparently this used to be a problem, I've not found a recent
    + compiler that breaks that assumption (yet!).
    +
    + This applies to: expat, freetype, ijs, jbig2dec, jpeg, jpegxr, openjpeg, png
    + tiff and zlib
    +

    +

    +
    +

    2020-09-16 18:58:05 +0100 + +
    Julian Smith <jules@op59.net>
    +978df385c36ee4d65c9144924d0224243a5ebb71 +

    +

    + Added PDL_DYNAMIC_LDFLAGS to $host *bsd* section
    +
    + to match the other platforms.
    +

    +

    +
    +

    2020-09-16 18:49:42 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +477d315af46d9a7932108135137adc7aebfc77fe +

    +

    + Use pkg-config to get CFLAGS for libidn
    +
    + We already get the libs, missing the CFLAGS (mainly the -I) was just an
    + omission.
    +

    +

    +
    +

    2020-09-28 12:54:48 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +c97c4ebb08474e1fbd9a3a6db71da52330f2d67b +

    +

    + Bring master up to date 9.53.x branch
    +
    + Docs/dates/version for 9.53.3
    +

    +

    +
    +

    2020-10-01 10:18:33 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +f7646980a69dc3b302b0640220347b9865f49d0e +

    +

    + Fix preserving Line annotations without AP
    +
    + This only affects the pdfwrite device.
    +
    + It was rescaling the /L entry for no apparent reason, which meant the
    + Line annotations rendered incorrectly when they had no AP.
    +

    +

    +
    +

    2020-10-01 19:01:33 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +df537046c2130be285b213b5d0478159d1c5b16d +

    +

    + Initialise a variable to silence a compiler warning
    +

    +

    +
    +

    2020-10-01 18:01:00 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +dee305c09cb60af041c0cc0b301f5fa8347eccc2 +

    +

    + Update makefiles for another version of nmake.
    +

    +

    +
    +

    2020-10-01 09:15:37 -0700 + +
    Robin Watts <Robin.Watts@artifex.com>
    +1039ade1c0e0066f03a22598edb327648f59d578 +

    +

    + Squash a couple of compiler warnings.
    +

    +

    +
    +

    2020-10-01 15:48:19 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +61e227ed7bcdddd652f32f14539702773fcbcf33 +

    +

    + pdfimage devices - fix %Invocation and add /Info dictionary
    +
    + I'd thought that we had missed off the %Invocation from the PDF output
    + of the PDF image devices, but in fact it was only that the pdfocr
    + devices had it emitted in a surprising place in the file.
    +
    + That's fixed here just by moving when we write it so that its location
    + is consistent between the devices.
    +
    + Moved some definitions common to both pdfimage and pdfocr from the
    + device's .c files to the pdfimage.h file.
    +
    + Added emission of a very basic /Info dictionary. To facilitate future
    + enhancements the number of 'static' (ie predefined) objects has been
    + turned into a #define and we use that wherever possible instead of the
    + previous hard-coded magic number. Because of the font objects required
    + for pdfocr, and the fact that they refer to each other, these still
    + don't use the #define and will have to be manually adjusted if we ever
    + change this again.
    +
    + Acrobat ignores the /Info dictionary, apparently it only reads the XML
    + /Metadata values (at least in modern versions), so adding the Info
    + dictionary doesn't help. Creating the XMP metadata is unfortunately
    + quite complicated, we'd need to steal quite a bit of code from pdfwrite
    + and at the moment I think its more trouble than its worth. I may change
    + my mind in future.
    +

    +

    +
    +

    2020-09-29 20:16:10 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +6290ce42ac84767a84ddc949c9348a194477ab9b +

    +

    + Bug 702948: Ensure initial bitmap cache sizes are properly aligned
    +
    + Now that the allocations from the bitmap cache are aligned to the platform's
    + required alignment, see commit:
    +
    + 260c443bc14cdffa4d94e14c3a57e35bebee3a5b
    +
    + We also want the initial size of the memory pool used by the cache to be
    + "aligned".
    +
    + This is so that code that attempts to identify cache entries to evict by
    + requesting a size equal to the entire size of cache memory pool doesn't get an
    + unexpected failure, because we've rounded up that allocation request to a value
    + larger than the entire size of the memory pool.
    +
    + Because we don't expect an error to be possible at that point, a crash can
    + occur.
    +
    + Of the "normal" platforms we use, this only exhibits on Win32 because that is
    + the only platform where the align_bitmap_mod we use is less than the
    + obj_align_mod used for the memory managers.
    +

    +

    +
    +

    2020-09-28 20:10:16 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +c6f2518cd3331d7a64c79d533d525299683a57ac +

    +

    + Fix icc profile reference counting in transparency compositor
    +
    + Found during Windows testing for a release.
    +
    + The full test file for
    + https://bugs.ghostscript.com/show_bug.cgi?id=693365
    +
    + would cause Ghostscript to crash due to an ICC profile being freed whilst a
    + reference was still being held for it. That was not counting up a reference
    + count when restoring the device profile back to a previous value.
    +
    + Fixing that introduced a leak for other profiles. And that turned out to be
    + not decrementing the reference count when replacing a device profile.
    +

    +

    +
    +

    2020-09-28 10:21:47 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +660af5758360293e5c041ebf4500144c54521fc8 +

    +

    + Work around for (I think) a VS2019 optimiser bug
    +
    + VS2019 release builds crash with the input file from bug 702916 and several
    + other files, in copied_glyph_slot() because the pointer retrieved and stored
    + in *pslot is non-sensical.
    +
    + Debug/Profile builds and optimised builds with earler VS versions don't show
    + the problem.
    +
    + Adding debug code to assign the calculated index to an interim unsigned integer
    + variable also cause the problem to go away.
    +
    + So, use that as a workaround.
    +

    +

    +
    +

    2020-09-28 10:20:26 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +1a606b57f6eb9a38d355dcf8766f63be6140d42c +

    +

    + Fix some casting confusion for special glyph CID/index values
    +
    + And a whitespace/indentation issue.
    +
    + Noticed in passing....
    +

    +

    +
    +

    2020-09-24 10:28:07 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +aca94c29896f51198a98b1d3e831f7710295ee8c +

    +

    + First Page Last Page: Add strictly mono increasing error check
    +

    +

    +
    +

    2020-09-25 13:03:40 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +0cec771833490249af508823914be8b7d6931fbe +

    +

    + Fix Bug 702941 - Mispelled PDF interpreter variable name.
    +
    + s/RepiredAnError/RepairedAnError/ A simple typo that was missed because
    + we did not have a test file with a format error to trigger this code.
    +

    +

    +
    +

    2020-09-25 12:40:01 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +260c443bc14cdffa4d94e14c3a57e35bebee3a5b +

    +

    + Bug 702938: Allocating cached glyphs, account for alignment
    +
    + For efficiency, the glyph cache allocates "large" blocks of memory into which
    + it parcels out offsets for individual glyph cache bitmaps, as required.
    +
    + Since cached glyphs are usually fairly small, and potentially can be short
    + lived, this saves the overheads of "full" memory for every cached glyph.
    +
    + Unfortunately, in calculating the offsets for the cached glyph, it was failing
    + to account for the required alignment of the system. In any environment that
    + strictly enforces aligned memory accesses, this will potentially cause a bus
    + error.
    +
    + In this case, it was switching the gs_glyph type to a 64 bit type that triggered
    + the issue. But any changed to the contents of the cached_char struct could have
    + resulted in it happening.
    +

    +

    +
    +

    2020-09-24 15:27:10 -0700 + +
    evrhel <ethanvrhel@gmail.com>
    +9e7fcb56612746fa93f8d76fa4cb8ecc72f43f30 +

    +

    + Squashed commit of the java-demo branch:
    +
    + commit 385a750c39e3112f4b640f8dbfea28fbad9885a2
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Sun Sep 13 14:42:08 2020 -0700
    +
    + Added several devices, updated documentation, and README.txt.
    +
    + commit 64fad0d5035ccf7394c1863e369b108ca471b5fb
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Wed Sep 9 15:30:58 2020 -0700
    +
    + Worked on PDFPostscriptDeviceFamily implementation
    +
    + Added all of the parameter types specified in
    + https://ghostscript.com/doc/current/VectorDevices.htm for
    + PDF/Postscript devices.
    +
    + Added several devices, updated documentation, and README.txt.
    +
    + commit fc6593654f7d1e114d8fd0a8b2da89224e193c92
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Wed Sep 9 14:19:25 2020 -0700
    +
    + Added missing Settings class to viewer
    +
    + commit ea92fe4f172911dfe79e8423bd7b98d14d585393
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Wed Sep 9 14:19:25 2020 -0700
    +
    + Added missing Settings class to viewer
    +
    + commit 792ddf8525e903e55bf668b41b84f002ef4757cb
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Sat Sep 5 14:04:44 2020 -0700
    +
    + Added more implementations of Device class
    +
    + commit 4f2056eafb633f5e4aa9f6ac3bed99247110f556
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Sun Aug 30 16:11:20 2020 -0700
    +
    + Added device classes to allow easy device manipulation
    +
    + New abstract classes Device and FileDevice and several subclasses
    + to allow easy modification and output to devices.
    +
    + commit ea360f254e7638b37529b8db105f0a2b9b7e722f
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Mon Aug 24 21:16:56 2020 -0700
    +
    + Updated to newer Ghostscript version and fixed a bug
    +
    + Updated to the newest Ghostscript version and fixed an
    + ArrayIndexOutOfBoundsException bug when unloading zoomed pages.
    +
    + commit 34c47909939b4e85f18e2fc03088203c51bba292
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Sun Aug 23 15:58:44 2020 -0700
    +
    + Added better documentation
    +
    + commit eda31b70496337caefd0dc912c5a0850de769147
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Thu Aug 20 14:36:48 2020 -0700
    +
    + Updated how zooming is handled
    +
    + Zooming is now done through the SmartLoader and is no longer
    + a separate operation. Fixed an issue when the SmartLoader could
    + become out of date due to the condition variable being signaled
    + before the SmartLoader had finished.
    +
    + commit 5b08d9eadfe64d87cf26869c47a2a5f78755dd4b
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Wed Aug 19 17:38:34 2020 -0700
    +
    + Implemented distilling documents
    +
    + Users now have the option to distill a document if the desired
    + input is not a PDF.
    +
    + commit 4a78a968777521f23fefaeb277d378b9dc08b555
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Tue Aug 18 15:04:09 2020 -0700
    +
    + Fixed zooming and some other bugs in the viewer
    +
    + Zooming in on documents in the viewer no longer causes a crash.
    + Fixed a bug where documents would not display after being loaded.
    + Fixed a bug where closing a document when none was loaded would
    + crash.
    + Fixed a bug where gsapi_delete_instance would cause a crash.
    +
    + commit 9c9190192c1acdafbf4e9f277dba9e2079046cc7
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Sun Aug 16 16:28:44 2020 -0700
    +
    + Fixed JNI bugs and began updating viewer to use one GS instance
    +
    + Fixed JNI crashes when Ghostscript calls were made from different
    + threads. Migrated loading low res and high res images from using
    + multiple instances to using one global instance.
    +
    + commit fbe9a961e7fef31c79cfd8ed857643ad00798af8
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Sat Aug 15 14:36:34 2020 -0700
    +
    + Added init_with_args to the test code in Main.java
    +
    + commit 96ede7306ce8d71be3016e7d708c801c5718fdfe
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Sat Aug 15 14:33:40 2020 -0700
    +
    + Fixed a small error in test code in Main.java
    +
    + commit dcb1141da6901f0c42336861428cf13f6cc9b202
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Sat Aug 15 14:13:23 2020 -0700
    +
    + Finished updating to newer Ghostscript functions
    +
    + Replaced all Reference objects in Ghostcript calls in Java
    + and JNI to Reference<T>. Iteration over parameters now must be
    + done through GSInstance instead of creating an explicit iterator.
    +
    + commit aa9288fa60aa6030b88f909ac494b388737e1748
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Thu Aug 13 16:00:51 2020 -0700
    +
    + Finished implementing the rest of Ghostscript functions in Java
    +
    + All GS functions are now able to be called through GSAPI. Fixed
    + a possible memory leak related to exception checking in C++.
    +
    + commit b02df334fdbc14fb1ed4d75bcaddcf7091391ee7
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Thu Aug 13 12:49:33 2020 -0700
    +
    + Got gsapi_enumerate_params working in Java
    +
    + Got gsapi_enumerate_params working and added a utility class
    + to do the same work as gsapi_enumerate_params with a Java
    + iterator.
    +
    + commit 502baba9568406ce923944f693728af30c81473e
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Wed Aug 12 16:25:54 2020 -0700
    +
    + Got gsapi_set_param working
    +
    + Renamed java function to gsapi_set_param_once to distinguish from
    + the actual Ghostscript call. This method does the call to
    + gsapi_set_param twice in native code and is used to make it easier
    + to use the function in Java.
    +
    + commit 614c55f1989d04178c916db56cfc38753918097e
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Wed Aug 12 13:30:07 2020 -0700
    +
    + Worked on implementing new Ghoscript methods in Java
    +
    + Wrote out all native method signatures in Java and C++. Workekd
    + on gsapi_add_control_path and associated helper methods.
    +
    + commit 08cd824e589cf9cdd4848b9b3606898ac7141c9f
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Tue Aug 11 16:32:08 2020 -0700
    +
    + Worked on improving References in C++ code
    +
    + commit de7f2303372bed8b19ca401392151cba7f2ab013
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Tue Aug 11 13:58:54 2020 -0700
    +
    + Progress on updating Java bindings to newest version.
    +
    + Added some of the new methods, but currently none work.
    +
    + commit bcf2db77c8c106b1b3d80d647b0fe04201d9c645
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Mon Aug 10 14:08:42 2020 -0700
    +
    + Fixed some errors related to loading pages too fast
    +
    + An error would occasionally be thrown in the SmartLoader having to
    + do with the Document being modified while in the SmartLoader, causing
    + an error. Reconfigured how the SmartLoader handles documents and
    + is started and stopped.
    +
    + commit cb2be4f3b0635efd4616f567389b19a7351d078b
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Mon Aug 3 15:41:20 2020 -0700
    +
    + Added thread safety to the viewer.
    +
    + The viewer now ensures that no more than one ghostscript call is
    + happening at the same time and has multiple options for controlling
    + the behavior if multiple operations are attempting to be called.
    + Also began work on a utility class to make Ghostscript calls easier
    + by having a class carry around a instance and a caller handle.
    +
    + commit f81dfc177f71d0d12b38371fae54b45e158833ce
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Sat Aug 1 17:16:43 2020 -0700
    +
    + Progress on improving concurrency
    +
    + Added better exception handling. Began progress on handling
    + concurrent operations better.
    +
    + commit e0f4af0e59580dabca01cb9b932185475d4032a8
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Sat Aug 1 14:48:37 2020 -0700
    +
    + Viewer now will load a higher resolution image on zoom.
    +
    + The high resolution image loads correctly, but the viewer does
    + not correctly load the right page when in a zoom other than 1x.
    +
    + commit 843914f25b1a58841bac94e5df8cded8b47dd948
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Wed Jul 29 15:40:14 2020 -0700
    +
    + Optimizations to page loader
    +
    + Page loader now only loads around where the use is viewing and
    + does not load pages unless the user actually navigates to those
    + pages.
    +
    + commit 458f93f005920b9ca58bed67178dba26cd6d8a18
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Wed Jul 29 14:13:44 2020 -0700
    +
    + Progress on viewer
    +
    + Optimizations and easier user interface as well as basic zooming
    + implemented.
    +
    + commit ab65f0672d2be5f5c312b229af66d8d028661d08
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Mon Jul 27 15:12:45 2020 -0700
    +
    + Various bug fixes in viewer
    +
    + Added utility methods in ViewerWindow.java to help with changing
    + pages and zoom levels. Added framework for zooming pages.
    +
    + commit e3e7dbac2b5b271a4d4225ebae34d36f603b8a07
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Fri Jul 24 14:03:54 2020 -0700
    +
    + Got viewer working
    +
    + Viewer now works and can open files. Still does not "smartly"
    + target pages which the use is directly viewing or take
    + advantage of file-specific properties. It instead loads all
    + the pages' high-resolution images in order.
    +
    + commit f1441ed36302f75d94cf4aa4a8047150bf5b7585
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Thu Jul 23 18:57:52 2020 -0700
    +
    + Basic viewer working
    +
    + The viewer has basic capabilities, but still lacks loading
    + high resolution images, spacing components, and resizing correctly.
    +
    + commit ea3eecbc30b1a4a4747dfd2818262c2f6eea112c
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Thu Jul 23 16:13:13 2020 -0700
    +
    + Worked on creating GUI
    +
    + Added GUI (generated using NetBeans). Added support for callbacks
    + into the GUI specifically related to the wanted viewer operations.
    +
    + commit cb15f051db01135cf1eef8df6a8cfb53cb5ff840
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Wed Jul 22 16:24:13 2020 -0700
    +
    + Progress on Document class for handling a documentLoader
    +
    + Document class is a list of Pages which stores a low-resolution image
    + and a high-resolution image. The low-resolution image should always
    + be loaded while the high-resolution can be unloaded to save memory
    + usage.
    +
    + commit 99fa4ae3667cd58d6f2a72f01d1b9410929f4847
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Tue Jul 21 15:19:10 2020 -0700
    +
    + Converted original Java project to be used as a JAR library
    +
    + The original project should be compiled as a JAR library and
    + where needed, should be placed alongside the required native
    + libraries to run. The executable Java project has been moved
    + to the gsviewer project.
    +
    + commit 80dd426da705c160b79a57a161c5d95c3a57aca6
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Tue Jul 21 15:01:18 2020 -0700
    +
    + Colors now being displayed correctly after getting image
    +
    + Fixed drawing colors coming from ghostscript. Next: need to migrate
    + the current project into a jar file instead of a runnable application.
    + The viewer will use the Java library.
    +
    + commit 06a50542391c3f0ad64f20a0ae6a1f63d9aa61e0
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Mon Jul 20 17:10:36 2020 -0700
    +
    + Fixes to display callback and C++ and added window to display images
    +
    + Fixed Java methods not being found in C++ and added a window class
    + to start displaying images.
    +
    + commit 4b0e69075619f7c4ef8df850d0e85d125e2b67da
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Fri Jul 17 16:02:37 2020 -0700
    +
    + Implemented NativePointer methods in C++ and updated onDisplayPage
    +
    + onDisplayPage now uses a BytePointer object for the pimage parameter
    + to interface into native memory.
    +
    + commit 0d24844082f6c566af417ad35b394e3fd591c38e
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Fri Jul 17 15:03:06 2020 -0700
    +
    + Added new Java class allowing native access to memory blocks
    +
    + Added NativePointer and NativeArray as two base classes for low-level
    + memory-access alongside other classes to assist with this.
    +
    + commit 9643091f698293181dcb484e04e96d19df12950a
    + Author: Ethan Vrhel <ethanvrhel@gmail.com>
    + Date: Thu Jul 16 17:01:53 2020 -0700
    +
    + Security improvements in native code
    +
    + Fixed multiple points where the program could crash
    + and instead returned NULL and/or threw a (safer) Java
    + exception.
    +
    + commit fdade3eedc6469edd3da510bd648a39fdb9f9a93
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Tue Jul 14 15:52:22 2020 -0700
    +
    + Fixed how display_callback was being passed to Ghostscript
    +
    + The display_callback device did not have the correct values regarding its size,
    + major version, and minor version. Furthermore, the display_device structure
    + was not being dynamically allocated and ended up being freed too early.
    +
    + commit 5a3e822ca0e076708bed843a2578a18eebb37f3d
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Sun Jul 12 15:17:16 2020 -0700
    +
    + Fixed some bugs related to stdio
    +
    + Fixed stdio bugs and added some more utility methods to make calling
    + ghostscript functions easier in Java.
    +
    + commit 88fad771fcd4024a538f4bf6f6819d62d8180440
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Sat Jul 11 14:29:58 2020 -0700
    +
    + Completed JNI bindings to Ghostscript
    +
    + Added implementations for StdIO and display callback, and added
    + some testing in main().
    +
    + commit bb197f9ae65b39bf55ae6fd932203e514472ff8f
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Fri Jul 10 14:06:07 2020 -0700
    +
    + Finished writing JNI bindings.
    +
    + Finished writing JNI bindings and added more utility methods to
    + help with setting Reference objects in Java.
    +
    + commit 8a0074ea3624921cd8ff98684e5efa2fc0b4d5ce
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Thu Jul 9 18:27:52 2020 -0700
    +
    + Progress on linking Ghostscript functions to Java
    +
    + Added support for more functions and finished implementing display
    + callback functions.
    +
    + commit 32fee0e8ea1d82897ff4d2a3ce4b9ba92a680cd3
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Wed Jul 8 19:39:27 2020 -0700
    +
    + Worked on implementing display_callback in Java
    +
    + Added utility methods in C++ code to help with calling functions,
    + setting fields, and creating objects. Started to implement the functions
    + defined in display_callback.
    +
    + commit fe751db5f899c3e59c961d65ec013f307adef8f9
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Tue Jul 7 17:31:18 2020 -0700
    +
    + Implemented Ghostscript functions in Java in the C++ project
    +
    + Created a new C++ project which allows for Java calls into Ghostscript.
    + Current working functions are gsapi_revision, gsapi_new_instance, and gsapi_delete_instance.
    + gsapi_set_stdio_with_handle and gsapi_set_stdio are untested.
    +
    + commit 4c2bf73539f440bf8f6b45d85820cc84df2e6b28
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Tue Jul 7 14:52:47 2020 -0700
    +
    + Finished writing ghostscript api signatures in GSAPI.java
    +
    + commit 4850223d252d6e245104c42fafc0190b91177be2
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Mon Jul 6 18:16:15 2020 -0700
    +
    + Progress on creating the JNI bindings to Ghostscript.
    +
    + Started GSAPI class to store exported Ghostscript functions. Added error constants and declared
    + gsapi_revision, gsapi_new_instance, gsapi_delete_instance, gsapi_set_stdio_with_handle,
    + gsapi_set_stdio, gsapi_set_poll_with_handle, gsapi_set_poll, and gsapi_set_display_callback bindings.
    + Added multiple callback interfaces and a Java representation of struct display_callback_s.
    +
    + commit 8da16a603b124c15ce4dc7c7fccc97f711d75fb2
    + Author: evrhel <ethanvrhel@gmail.com>
    + Date: Mon Jul 6 15:18:32 2020 -0700
    +
    + Java demo: Initial commit with README
    +

    +

    +
    +

    2020-09-24 12:34:18 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +4f9c59a2875e4a5cd2b2160cfc507966795e0787 +

    +

    + Fix error in token parsing in pdfwrite
    +
    + I am trying to use a hex string <XXXXXXXX> in pdfi.
    + The code had a bug in it (probably because the ps code never generates
    + a hex string?) that was incrementing the token to be 1 longer than it
    + should have been. Logic was just mangled.
    +
    + I also simplified it to to take out the goto, which was egregious in
    + this case. Just put in two lines of code where it belongs, instead of
    + a goto to those two lines of code... (really?)
    +

    +

    +
    +

    2020-09-24 19:08:25 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +82aceb33f2521854bc781bdf0f47cbfe32d6ece8 +

    +

    + Remove links to ghostscript.com/release_history.html
    +
    + That page is now gone.
    +

    +

    +
    +

    2020-09-24 17:10:21 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +921f2737a72e64d9c8113fc9418422ab185cb60f +

    +

    + Remove dead end links from Readme.htm
    +

    +

    +
    +

    2020-09-24 16:59:20 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +e36e62c0631f73627ff3caec5752eefe37a14948 +

    +

    + Allow configure caller to choose a sanitizer
    +
    + Our "sanitize" target just uses address sanitizer.
    +
    + With this commit, we'll still default to address, but the caller can do:
    + --with-santizer=memory
    +
    + to opt for the "memory" sanitizer instead.
    +

    +

    +
    +

    2020-09-24 10:00:39 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +c210bb3d2a0c6131ebeedc44c1d8cc6fc92fb08f +

    +

    + Fix compiler warnings
    +
    + (unused variables)
    +

    +

    +
    +

    2020-09-23 20:20:59 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +d7d05e0ef54662054e038b421795e6e7dedd1e4a +

    +

    + Bug 702920: Fix type confusion in new param type code.
    +
    + In a few cases we were using the wrong element in the union to read the
    + value back from the param list (and to range check the values).
    +

    +

    +
    +

    2020-09-24 08:19:27 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +038df4baf368196942cd32aedcd29e4916a190c8 +

    +

    + WhatIsGS.htm updates from Lisa F
    +

    +

    +
    +

    2020-09-23 17:12:54 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +d178fa10548d101a248e3ec3fc6ddcf5bf044692 +

    +

    + XPS Interp: Fix missing initialization in XPS page reversal
    +

    +

    +
    +

    2020-09-23 14:18:59 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +b53045b45866fe5b41e9ca6b4fe8318f14178d3d +

    +

    + Fix a compiler warning
    +

    +

    +
    +

    2020-09-23 13:14:31 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +6a1f7167cf45d23c4e1faec3ef37fb4b9e5d7a53 +

    +

    + pdfwrite - fix memory leak with annotations
    +
    + Annotations are somewhat odd and don't quite fit the scheme of other
    + cos objects. Each annotation is created as a dictionary, which is
    + stored in the Annots array (also a cos object)) of the page.
    +
    + But we write the annots out to the file immediately, and free the
    + dictionary contents at that time. We cannot, however, free the dict
    + cos object, because we need the object number to write the Annots
    + array in the page dictionary, which we only do when writing the page
    + dictionary.
    +
    + So at the end of the page the annots array contains a number of empty
    + dictionaries. We free the array, which would free the dictionary
    + contents (except there are none) but it does *not* free the dictionaries
    + because they have an ID......
    +
    + So when we free the Annots array, we first need to set the ID of each
    + of the dictionary objects it contains to 0, so that the dictionary
    + will also be freed.
    +

    +

    +
    +

    2020-09-22 10:31:09 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +5ff586fa9e51ac7fdb306ff7b616d7cf23ed754d +

    +

    + Fix PolyLine annotation for pdfwrite device
    +
    + This implementation was missing, just copy-pasted the default for it.
    +
    + It was going through a code path that I think only works for Widgets.
    +

    +

    +
    +

    2020-08-26 16:53:36 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +9bfaeeace268f6a59f325e12efab9fb8273f64e0 +

    +

    + XPS interpreter: Have interpreter handle page range processing
    +
    + This has the obvious benefit that the interpreter will skip processing
    + pages except those that lie in the FirstPage LastPage range.
    + If the PageList is used, the XPS interpreter will create a new
    + list of linked pages to process. The XPS interpreter handles all
    + the PageList cases currently implemented by the PDF interpreter
    + including even and odd. In addition, the XPS interpreter will handle
    + backward indexing (e.g. 100-1), as well as starting from last page
    + to another page (e.g. -2 which means from last page to second page),
    + and page repeats (e.g. 1,2,1,2,1,2 or 1-3,3-1 or 1-,-1 which is
    + do page 1 to end and end to page 1) Also, setting -dFirstPage=4
    + -dLastPage=1 will create pages 4,3,2,1
    +

    +

    +
    +

    2020-09-16 17:33:30 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +c4e79952b42ebccb669063e053e3d7ce0f88cc22 +

    +

    + Fix compile failure due to missing header.
    +
    + A user reported (privately) that a pre-release of an upcoming XCode release
    + fails to compile due to a missing prototype/declation of abs() in the jpegxr
    + code. It's clearly a simple omission, as several files use abs() and do include
    + the relevant header.
    +
    + So adding it here.
    +

    +

    +
    +

    2020-09-22 11:18:22 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +71bbd0f12f48e1300a1e768483b5999099243f8d +

    +

    + Bug 702810: fix fapi buffer size parameter types
    +
    + The buffer size parameters for the fapi callbacks used to be unsigned short,
    + but were changed to ints a while back. The calls for the (g)subr data in
    + Type 2/CFF fonts hadn't had the casts to ushort removed, causing the values
    + to be trucated.
    +
    + There was also a Postscript/FAPI internal function that had not had the
    + buffer length parameter changed to int.
    +

    +

    +
    +

    2020-09-22 11:11:30 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +a5aa22546b191b9465b2d6f6aa00c2ad591238af +

    +

    + Remove pointless 'recopying' of CFF (g)subr strings
    +
    + For some reason, the Type 2 font serialisation (used for reassembling font
    + streams to pass to freetype) was using the FAPI callback to read the
    + (g)subr string data into it's main buffer, but then called the writing
    + function to write data to the buffer, using its own buffer as input -
    + effectively overwriting the bytes with the same bytes.
    +
    + The only purpose (it seems) was to move the current stream position forward by
    + the appropriate amount.
    +
    + Change it so we simply move the "current position" pointer on by the correct
    + offset.
    +

    +

    +
    +

    2020-09-22 08:58:31 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +3abfca2a925427962ed644872057f75c44afc0d8 +

    +

    + Fix memory leak in pcl pdfmark implementation
    +
    + The memory allocated by param_write_string_array() was never being
    + released.
    +
    + (Note: the cluster doesn't test this code path currently)
    +

    +

    +
    +

    2020-09-22 15:43:03 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +652c71e0f7766f3696330f654abf01c79a5493f2 +

    +

    + Updates to 'WhatIsGS.htm' document from Lisa.
    +

    +

    +
    +

    2020-09-22 08:25:36 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +b7a413e2d28540ca0113af1c783532ecea6f6ba0 +

    +

    + pdfwrite - remove erroneous free from cos_dict_put_copy
    +
    + Nancy discovered this one while working on annotations for pdfi. The
    + code here would attempt to free the memory pointing to the key name
    + which is passed as an argument to the function, if the *dictionary*
    + properties were set to free dictionary keys.
    +
    + Obviously the function argument is not the same thing as the key stored
    + in the dictionary, so even at first inspection this looks incorrect.
    +
    + The key is supplied (much higher up) from a param list, because the pdfi
    + code uses C param lists, where the data is stored in a single large
    + allocation, it is not possible to free an individual key and causes a
    + crash.
    +
    + Ghostscript gets away with this for two reasons; firstly it uses a
    + stack param list (which is basically a ref param list) where each key
    + is stored in its own allocation. Secondly the key is not actually
    + allocated, its an entry in the interpreter name table. So when the
    + code in cos_dict_put_copy 'frees' the memory, nothing actually happens,
    + the memory manager just notes that the memory is unused now. This
    + avoids double freeing the memory which would otherwise happen.
    +
    + So essentially this code is wrong, and we've been getting away with by
    + sheer luck for decades.
    +
    + I tested the modification extensively, including memory leak checks with
    + many files run through pdfwrite and can find no problems with simply
    + removing the line of code.
    +

    +

    +
    +

    2020-09-21 22:16:34 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +bbd106e8f9345296cb5b5a452487bda603d54173 +

    +

    + oss-fuzz 23637: Fix error code confusion
    +
    + Confusion of error codes meant we were allocating space for glyph data,
    + but never copying the data into it. Thus the memory sanitizer error.
    +

    +

    +
    +

    2020-09-21 15:14:55 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +42480ab92d9d31e7dc204e8f916165cc02480387 +

    +

    + Fix segfaults in UFST - use correct font name
    +
    + Omission from commit: a10a03a4c9713b38c4cfcd07f0ba3c722778aae0
    +

    +

    +
    +

    2020-09-20 16:35:41 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +7aff7d6a30544929de9d2f4bd775fb17303b86ff +

    +

    + Fix Coverity ID 362083 & 362084
    +
    + After the fixes for crashes with invalid filenames, Coverity can now
    + detect a potential NULL stream pointer (would have been uninitialised
    + previously).
    +
    + Prevent the code trying to write to that stream, thereby dereferencing
    + it.
    +

    +

    +
    +

    2020-09-18 23:18:41 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +ef118c5edc71ac6575260918d062e91ed3f8f067 +

    +

    + XPSWrite: Fix memory leaks and page resource relations
    +
    + The page resource relations information tells which of the
    + resources are used for each page. The information was not
    + getting written out correctly for the multi-page case. The
    + Microsoft viewer is very fussy about this and would not
    + display some pages, even though the item is in the resources.
    +
    + Made sure that each page writes out the proper relations to the
    + resources and that no duplicate relations are written.
    +
    + Also fixed memory leaks from the zip file information not getting
    + freed as well as some TIFF client information.
    +

    +

    +
    +

    2020-09-18 15:53:27 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +4dcbbd26d92a25705a1b835573faada8aa225448 +

    +

    + Fix a compiler warning by initialising a variable
    +

    +

    +
    +

    2020-09-18 15:16:46 +0100 + +
    Peter Cherepanov <sphinx.pinastri@gmail.com>
    +5425a7f56d0cb424370af82f18c3416a728f18ff +

    +

    + PDF interpreter & pdfwrite - better detection of per-page output
    +
    + Bug #702791 "%d vs. %03d and pdfmark destination page ... points beyond the last ..."
    +
    + The PostScript code in the PDF interpreter which looks for
    + file-per-page output, in order to drop Outlines and Dests was
    + only checking for %d not variants liek %03d. This could lead
    + to warnings about the Destination being dropped.
    +
    + The code provided by Peter checks for an odd number of '%'
    + characters instead. This isn't the same test as pdfwrite uses
    + but that is in C and not immediately available in PostScript.
    +
    + Since we plan eventually to drop the PostScript implementation
    + of the PDF interpreter and move to a C version, this is fine
    + for the interim.
    +

    +

    +
    +

    2020-09-18 14:17:00 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +4c58ce8f26096122eff7783da38a679a3ecd96c4 +

    +

    + pdfwrite - fix a number of seg faults when opening output file fails
    +
    + While investigating bug #702791 I discovered a number of ways to make
    + the opening of the output file fail (combinations of illegal characters)
    + which subsequently caused pdfwrite to seg fault.
    +
    + This commit addresses these.
    +

    +

    +
    +

    2020-09-17 16:37:43 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +cf49e978b9324866f61acce6b3cf399b356af6fb +

    +

    + Fix tesseract traineddata links in documentation.
    +

    +

    +
    +

    2020-09-17 15:34:02 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +d5494de2cab28b91ba360d15b8afffef50a3f421 +

    +

    + PDF interpreter with pdfwrite fix non-square scaling stroked text
    +
    + Bug #702900 "pdfwrite device causes bold text output"
    +
    + The PDF interpreter has special code for dealing with line widths and
    + stroked text, this is because we do not preserve the CTM in the input
    + through to the output in pdfwrite.
    +
    + What we need to do is figure out what line width with an identity CTM
    + would draw a line the same width as the current line width and CTM.
    + Normally pdfwrite takes care of this itself, but until relatively
    + recently it did not have access to the textmatrix, only the CTM. But for
    + text, by the time we get to the point of emitting the text,, the CTM
    + already includes the Text matrix (Tm).
    +
    + So the PDF interpreter (which does have the CTM before the TM is
    + applied) calculates a line width and sets that before sending the text.
    +
    + However, when the scaling was non-square we were not doing that, leading
    + pdfwrite to emit the unscaled linewidth. Intriguingly we have no files
    + in the test suite for which this is a problem, all the files where the
    + CTM is non-square it is also close to the identity so not visibly
    + incorrect.
    +
    + The file here, however, has a non-identity CTM which is slightly
    + non-square when the text is rendered, and very far from the identity.
    +
    + Since we can't tell which scaling to use for the linewidth we 'fudge'
    + it by using the transformed x and y values of the linewidth, as two
    + sides of a triangle, then calculating the hypotenuse. Obviously this
    + won't work for seriously skewed matrices but it seems unlikely we
    + could calculate a reasonable linewidth for that anyway.
    +

    +

    +
    +

    2020-08-26 16:50:51 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +b81a73c34e48a547dd881f07aa046646a472e13c +

    +

    + C# API: Fix a few minor issues related to printing
    +

    +

    +
    +

    2020-09-16 10:05:51 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +c035cc51926dbda7f013b7611d0cdddda986a47d +

    +

    + Clarify documentation
    +
    + It wasn't clear that the PJL implementation of pdfmark and
    + setdistillerparams required the PJL line to terminate with a linefeed
    + (specifically a linefeed, not a carriage return). Update the document
    + to make this clear.
    +

    +

    +
    +

    2020-09-16 07:48:47 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +d9369a388ae987b63d66fdd557f95b0073547846 +

    +

    + Bug 702904: Another fix to check for shared libjpeg/libtiff
    +
    + We cannot combine shared and not shared libjpeg and libtiff - they either both
    + need to be "local" or both shared, and configure checks that and fails when
    + the two are incompatible.
    +
    + However, that check would fail when either libjpeg or libtiff were not being
    + included at all. Since it is libtiff that is the "problem" for this
    + compatibility, now check if TIFF is included, and if not, skip the check.
    +

    +

    +
    +

    2020-08-25 16:47:10 +0100 + +
    ChrisL <cliddell@salvor-openbsd.lan>
    +24808eae80f0def1aeb7f727980d5e0852d3d0e0 +

    +

    + Fix the OpenBSD build
    +
    + Whilst hopefully not breaking the buildroot build.
    +

    +

    +
    +

    2020-09-14 16:52:22 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +7d08c3225879c0714217a7defd6f57f8a16ef615 +

    +

    + Bug 702901: initialize directory for tiff configure
    +
    + Previously the directory in which to run the libtiff configure script was
    + initialised to an empty string, but that, in some toolchains, resulted in an
    + error due to "unsafe header/library path used in cross-compilation".
    +
    + So initialise it something benign instead.
    +

    +

    +
    +

    2020-09-14 11:12:16 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +996d05b6f5010afda4b47b20ed4b8e1ee364402b +

    +

    + oss-fuzz 25486: Initialise device colors in graphics state
    +
    + Not all devices/color models require all the entries in a device color, so
    + sometimes they don't get set, in this case, the "phase" entry. Trouble is,
    + the clist code uses phase in a conditional.
    +
    + Initialise the dev_color so, in such cases, we're not hitting a UMR condition.
    +

    +

    +
    +

    2020-09-11 18:33:42 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +19ed8a965c016eda56057e29dfc373d1af87ca55 +

    +

    + oss-fuzz 25485: Validate Type 1 font hinting paramters.
    +
    + BlueValues, OtherBlues, FamilyBlues and FamilyOtherBlues are all made of up
    + pairs of values packed into arrays. Obviously, valid arrays for those must have
    + an even number of entries.
    +
    + Ensuring they do, and erroring out should they not, prevents us from accessing
    + off the end of the valid values, and encountering a UMR condition.
    +

    +

    +
    +

    2020-09-11 15:08:55 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +542e32e6aa630ad909c39304ba4e48870695781e +

    +

    + oss-fuzz 25480: CFF - cope with "empty" float number.
    +
    + If a CFF stream encoded a fractional number with no content (i.e. starting op
    + code, imediately followed by an ending op code), we were still trying to
    + parse meaning out of the emtpy temporary buffer. So, check we have actually
    + decoded bytes from the stream, before converting to a floating point value.
    +

    +

    +
    +

    2020-09-11 14:45:04 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +f4aae0832544e76d148db9eb52a24c34a416b56c +

    +

    + oss-fuzz 25474: Check the length of Coords in shading dict
    +
    + We weren't checking if the length of Coords array for shading was valid, meaning
    + we could end up using uninitialised entries in an array.
    +
    + Check it, and throw an error if it's invalid.
    +

    +

    +
    +

    2020-09-14 14:32:23 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +378e2071d77fad65ba0fe3beed974d1efbe180ac +

    +

    + Fix crashes with pdfwrite, TrueType input fonts and Windows 64-bit build
    +
    + With the change to 64-bits unconditionally for gs_glyph we can now
    + define GS_MIN_CID_GLYPH in 64-bit terms.
    +
    + Previously we were using the architecture size of a long_long to
    + determine which define to use, and we do not define long_long on Windows
    + leading to us using an essentially 32-bit definition. This caused
    + indexing off the end of an array in copied_glyph_slot()
    +

    +

    +
    +

    2020-09-14 09:40:30 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +f0d19bf181a156d011dba422ae4d165b36b0af7e +

    +

    + Bug 702897: Fix shared libtiff/libjpeg check
    +
    + For various reasons we cannot combine shared and not shared libjpeg and
    + libtiff - they either both need to be "local" or both shared.
    +
    + But the check for that compatibility was triggered during the recursive
    + configure call when setting up for cross compiling.
    +
    + Skip the check for that recursive configure call.
    +

    +

    +
    +

    2020-09-10 16:18:10 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +98379bb2752c64f47cc1de9f6f3c973b2c69562c +

    +

    + Bring changelog changes onto master from gs9.53.0
    +
    + (Tweak History9.htm with jbig2dec updates)
    +

    +

    +
    +

    2020-09-10 17:27:47 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +24cfe91c81b831d6d23fe0a1008285407a7adeb2 +

    +

    + Fix Coverity issue 361428.
    +
    + Don't strlen a possibly NULL path. Shouldn't ever be a problem,
    + but doesn't hurt to be safe.
    +

    +

    +
    +

    2020-09-10 17:25:02 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +1bd520eff4d5b8474d5aa962434dd398beb65dcc +

    +

    + Fix Coverity issue 361836.
    +
    + Check return code.
    +

    +

    +
    +

    2020-09-10 17:23:06 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +367dec7fb70f08603e37de5e1e07731a21fb4b73 +

    +

    + Fix Coverity issue 361837.
    +
    + Check return codes properly.
    +

    +

    +
    +

    2020-09-10 17:19:34 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +198846d0d28b0f462dc84d12f00f82d3d1d069db +

    +

    + Fix Coverity issue 361838.
    +
    + All destructors should accept NULL.
    +

    +

    +
    +

    2020-09-10 22:47:09 +0800 + +
    Sebastian Rasmussen <sebras@gmail.com>
    +a4a8406ff4618234095fc8ed4d6e8b313a5260e4 +

    +

    + Bug 702884: Require jbig2dec 0.19 when building ghostscript.
    +
    + In practice this has been required since commit
    + 9b5008aa2bc1c6a6acb2c6f90d1ef8d6bad9e66a.
    +

    +

    +
    +

    2020-09-10 22:41:20 +0800 + +
    Sebastian Rasmussen <sebras@gmail.com>
    +224ffe421044b6cff107bcb3e0460aac7e029c56 +

    +

    + Update jbig2dec stuff for 0.19 release.
    +

    +

    +
    +

    2020-09-10 15:42:49 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +89ff7003acfdc52e3d3bcca930de6961f33ae927 +

    +

    + pdfwrite - fix image downsampling when the input is a 16-bit image
    +
    + Bug #702868 "Segmentation fault when using dPDFSETTINGS"
    +
    + The problem is to do with image downsampling, and 16 bit images. When
    + the input image has 16 bits per component, and is sufficiently high
    + resolution on output that it triggers image downsampling, in this case
    + the image downsampling setup can't deal with the input. In addition we
    + *already* deal with 16-bit input by explicitly adding a filter to
    + reduce the input from 16 bits to 8, so its not necessary for the
    + downsampling code to do this.
    +
    + So fix it simply by altering the colour depth form 16 to 8 in the
    + params we pass to the setup code.
    +

    +

    +
    +

    2020-08-18 10:23:13 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +3441872e7e7e5e269d242605dbc0f47c024120a9 +

    +

    + Bring master up to date with 9.53.0 doc changes
    +
    + Update docs, version, dates, product family
    +
    + for 9.53.0 RC1
    +
    + Fox typos and stuff in the release highlights
    +
    + Update dates'n'docs for 9.53.0.RC2
    +
    + Docs and dates for 9.53.0
    +

    +

    +
    +

    2020-09-10 11:58:13 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +12ca7092b5b1cdd9e9d1fe3497e033bb01751a1a +

    +

    + Correct fix for stack smashing.
    +
    + Commit 4d9fa68df "Fix stack smashing in blending code." was the
    + wrong fix (and indeed didn't work in the weekly tests).
    +
    + We therefore back that out, and add the correct fix.
    +
    + When using a temporary array to allow us to Hue blend, we need
    + that array to be large enough to cope with all the components
    + we might have, including spots.
    +

    +

    +
    +

    2020-09-09 15:05:19 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +b2b45b74b4272092ca46d0210b0076a618b7979a +

    +

    + Strip trailing whitespace from html files
    +

    +

    +
    +

    2020-09-09 14:47:30 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +6a23ca3a97bcef0663d8855dc26f1a5041f2a5d4 +

    +

    + Strip trailing whitespace from makefiles.
    +

    +

    +
    +

    2020-09-09 18:40:56 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +4d9fa68df46a876e60d9677eafee66b0c596d8ab +

    +

    + Fix stack smashing in blending code.
    +
    + Page 17 of:
    +
    + gs -Ilib -sOutputFile=out%d.psd -dGraphicsAlphaBits=4
    + -dTextAlphaBits=4 -dMaxBitmap=400000000 -sDEVICE=psdcmyk
    + -r72 -Z: -sDEFAULTPAPERSIZE=letter -dNOPAUSE -dBATCH -K2000000
    + -dClusterJob -dJOBSERVER
    + ../tests_private/comparefiles/Altona_Technical_v20_x4.pdf
    +
    + crashes, due to do_pdf14_copy_alpha_color calling
    + art_blend_luminosity_cmyk_8 and art_blend_saturation_cmyk_8
    + with a temporary array of size 4, with n_chan=5.
    +
    + The reason for this is because we are forgetting to allow for the tag
    + plane. Fixed here.
    +

    +

    +
    +

    2020-09-09 14:12:57 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +9695dd9f5352abc2ba49174447824f474f06ada6 +

    +

    + Remove prototype for non-existent function.
    +

    +

    +
    +

    2020-09-09 12:46:51 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +81a0e93a723fe057d9ba56a2bf072e6b7adc2a7e +

    +

    + Strip trailing whitespace from .c and .h files.
    +

    +

    +
    +

    2020-09-09 11:50:12 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +9bd47d0ed0d012301e28e288a366408fa6aba386 +

    +

    + Bug 702871: Fix GraphicsAlphaBits + Fill/Stroke issue.
    +
    + When we flush the alphabuffer, mapped_start and mapped_height are
    + both set to zero. When we refill it, mapped_height is set to
    + non-zero. USUALLY mapped_start is set to non-zero too, but it can
    + be set to zero when we are close to the bottom of the page.
    +
    + Hence we should test for mapped_height != 0, rather than both
    + mapped_height and mapped_start being non-zero.
    +
    + So the 'quick hack' that Chris used is actually correct.
    +

    +

    +
    +

    2020-09-07 19:19:10 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +7222ff74e7d1249c06c163bc8b33ef5b485e8864 +

    +

    + Remove deprecated device-like image handling procedures.
    +
    + 22 years is probably long enough warning.
    +

    +

    +
    +

    2020-09-07 18:53:00 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +8f8e7df3adf63221d70cfff54aec9c56ffbd5385 +

    +

    + Rejig PCL/PXL to call graphics library rather than device functions.
    +
    + Also remove pl_begin_image2/pl_image_data2/pl_end_image2 etc
    + functions - might as well just call direct. This leaves pldraw.c and
    + pldraw.h empty, so remove them.
    +
    + Also, take the opportunity to fix some potential cleanup problems.
    +

    +

    +
    +

    2020-09-08 14:24:10 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +8b805ceb6fe15bd835a48dac227b85da401d7a81 +

    +

    + pdfwrite - fix error handling with broken type 3 fonts
    +
    + The test file tests_private\pdf\customer394\problems\normal_537.pdf has
    + a Type 3 font with a CharStrings entry where the value is not a
    + dictionary, it is the null object.
    +
    + When trying to capture the outlines of the glyphs in order to rebuild a
    + type 3 font in the output PDF file, pdfwrite detects the error. However
    + due to an oversight when writing the code, the graphics state is not
    + correctly preserved.
    +
    + This is because if an error occurs in gs_text_process it unwinds the
    + graphics state stack back to the level stored in the text enumerator
    + at the start of the text processing. But complete_charproc() then
    + proceeds to do another gs_grestore (and the code incorrectly did yet
    + another gs_grestore as well!). This results in the graphics save level
    + being different on exit form text processing to the state on entry.
    +
    + Remarkably this doesn't seem to cause a problem, except for the new pdfi
    + interpreter, where the gs_grestore restores back to a point before the
    + type 3 font was present in the graphics state. This leads to the type
    + 3 font having a reference count of 1 at the end of processing and the
    + font and all its contents leaking.
    +
    + Fix it by updating the 'level' stored in the enumerator actually being
    + used by gs_text_process (which, because this is for capturing glyphs,
    + is not the same enumerator as used by pdf_text_process). Also remove
    + the spurious extra gs_grestore in the error clause.
    +

    +

    +
    +

    2020-09-07 19:58:09 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +e8a6f1d98300fd06965dbdccd82a746adeb05b72 +

    +

    + Fix type slipup in OCR params handling.
    +

    +

    +
    +

    2020-09-07 09:54:28 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +2202026393550166416b4fd28daaa4f667a77301 +

    +

    + Fix memory leak with clip device and image width/height = 0
    +
    + When rendering masked images we can create a clip device in order to do
    + the actual masking before passing the result to the final device.
    +
    + After creating the device we store it in a 'gs_image_common_enum' for
    + later use. We then proceed to initialise the main image enumerator in
    + gs_image_common_init().
    +
    + As an optimisation, if the image width or height is 0, we don't waste
    + any time processing it but simply end the image and exit.
    +
    + However, if we had created a clip device, we did not free that device
    + leading to a memory leak.
    +
    + This commit simply 'un-retains' the device causing it to be freed.
    +

    +

    +
    +

    2020-09-03 16:20:34 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +2c2fab370060e84b55c74c1c99fa1a8046a5b4f8 +

    +

    + Font copying - fix memory leak
    +
    + When copying a glyph for a copied font, if we encountered the same glyph
    + twice, with the same name, we simply replaced the name in the name table
    + of the copied font. If there was already an entry then it would leak.
    +
    + Note that a second instance of the glyph with a different name would
    + end up in the extra names table and doesn't leak.
    +
    + Fix the leak by freeing the existing string copy if we have a new one.
    +

    +

    +
    +

    2020-09-02 13:50:44 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +bc0403425e55309fbf372a7ebc66037d74e140d8 +

    +

    + pdfwrite - add a new method to detect pdfmark-capable devices
    +
    + The existing method to determine if the current device is capable of
    + processing pdfmark operations only works in PostScript. Since pdfmark
    + is a PostScript operator this isn't unreasonable, but we need a way for
    + the pdfi interpreter to know that a device is capable of handling
    + pdfmarks, because some information from the current interpreter is
    + passed that way (eg DOCINFO).
    +
    + Add a new parameter "PdfmarkCapable" which can be retrieved via a
    + spec_op. Any device capable of handling pdfmarks (via put_param calls)
    + must return true for this parameter.
    +
    + Update the current PDF interpreter to use this instead of the PostScript
    + method.
    +
    + Note: the ps2write device is *not* PdfmarkCapable.
    +

    +

    +
    +

    2020-08-31 14:29:57 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +54304275c68abdf131d2e4f511bcc7475f611b30 +

    +

    + oss-fuzz 23113: Bounds check buffer in gs_scan_token()
    +
    + To handle malformed/multiply negated numbers (e.g. "---1") in PDF files,
    + the number scanning code skips over multiple leading minus signs (*only* for
    + PDFs), but code skipping the minus signs did not bounds check the buffer, so
    + could rattle off the end.
    +
    + Unfortunately, where this happens, there is no way for us to differentiate
    + between a (malformed) token that straddles a buffer boundary, or a (strange!)
    + token that is the entire buffer.
    +
    + As the code in question is only active for PDF interpreting, and the Postscript
    + PDF interpreter uses the "token" operator to tokenize stream contents, we can
    + assume (in this case) the buffer is the entire token.
    +
    + So, in the event we hit the end of the buffer without reaching something other
    + than a '-' then reset the buffer pointer, and "retry" it as a name.
    +

    +

    +
    +

    2020-08-31 09:39:02 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +86f8c00204342436a09d7fac2ea6d0bb551b9118 +

    +

    + CID 361525: Protect from NULL pointer deref (z_fontenum)
    +
    + In reality, the NULL pointer dereference here is not actually possible (barring
    + memory corruption issues), but the checks are trivial, the code only runs
    + at most once per job, enumerating the fonts is the slow part of the process,
    + rather than the linked list management, and it seems easiest to just placate
    + Coverity.
    +

    +

    +
    +

    2020-08-31 13:48:57 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +0b9dbbc38d1d0e5593452337b6a45431053a1ba0 +

    +

    + Fix crash with copied TrueType fonts and pdfwrite
    +
    + When freeing a copied font we now test for the data pointer being
    + non-NULL instead of checking the size of the string. This was because
    + we would still create strings for glyphs with a length of 0 and using
    + the size meant we would not free those strings, leading to a memory
    + leak.
    +
    + However this causes problems (only for 0 length data) with TrueType
    + fonts regarding ownership. We avoid this by not allocating any memory
    + for 0 length string data.
    +
    + We do need to fill in the remaining elements of the copied glyph though.
    +

    +

    +
    +

    2020-08-28 08:56:23 +0100 + +
    Peter Cherepanov <sphinx.pinastri@gmail.com>
    +0ab8e25b94c837c6128fff791b2a99486b1ee73c +

    +

    + Bug 702620: Fix linked list creation in z_fontenum
    +
    + Fixes memory leak.
    +

    +

    +
    +

    2020-08-28 09:31:58 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +9bd1cdde34a49e6c0b885db5e258a41a4fccda52 +

    +

    + Bug 702837 typo in warning message
    +
    + Thanks to Herbert Voss for spotting this. Fixed the typo and updated the
    + version number in the warning from 9.53 to 9.53.0 to match the actual
    + version and patch number of the release (the decision to add the patch
    + level was taken after the original commit)
    +

    +

    +
    +

    2020-08-27 20:35:06 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +1f6172705bb2811986175d72484705d68995fdd1 +

    +

    + Bug 700404: Make Windows usertime be CPU time, not elapsed time.
    +
    + Thanks to Peter Cherepanov for this patch (and his patience in having
    + it accepted). Tested with VS 2005, 2008, 2015 and 2019.
    +
    + WIth this change Windows operates like linux. Note that usertime always
    + returns 0 the first time it is called (refer to commit cc156631). This
    + is a bit confusing, but is intentional.
    +

    +

    +
    +

    2020-08-27 12:19:53 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +49c4fa7e6c1a750ed976c7f1f46e3f8474249993 +

    +

    + Fix pdfwrite memory leak in pattern clists
    +
    + This is for non-GC interpreters only.
    +
    + This code is very convoluted, but I think the ->retained flag can be
    + used to see if it's okay to safely free the memory.
    +
    + In the case of patterns, for at least some cases the ctile wasn't
    + in the cache so it didn't free anything in gx_pattern_cache_free_entry().
    +

    +

    +
    +

    2020-08-27 13:54:33 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +94c344c43b274c86f529916085e02d7dc50d5edb +

    +

    + Bug 702785: Add UTF-8 encoding for strings in Info dict to pdf_info.ps
    +
    + Thanks to Peter Cherepanov for this change.
    +

    +

    +
    +

    2020-08-26 10:15:58 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +d7a70f69851a071eb9dfe7a968e2cb2f6302f1ba +

    +

    + Bug 702806: Performance decreases throughout file, PS to PDF
    +
    + A sample file of 1,000 pages from the customer allowed us to reproduce
    + the issue. The file creates MANY fonts (3,398 over the 1,000 pages),
    + and the font_cache list (not really a cache) would have the newest
    + created fonts at the head of the list, but later pages would use
    + fonts created earlier that were at the end of the list.
    +
    + Fix this by moving the found font to the head of the list (MRU).
    + On this file, the time on a fast machine went from 152 to 65 seconds
    + and the times for pages does not show the growth seen originally.
    +

    +

    +
    +

    2020-08-27 15:31:19 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +225de4d2960f187a49521097a4235872d94a8fb3 +

    +

    + pdfwrite - fix memory leak in copied font
    +
    + This really should have been fixed by an earlier commit, but it had a
    + dumb error. We were freeing cfdata->names after we'd checked the
    + first entry in the table, instead of checking *every* entry in the
    + table first. In fact the memory was already freed blow so we didn't
    + need this at all.
    +
    + In addition the code to free extra_names was inside the loop and didn't
    + need to be as its a linked list not an array. So move it outside where
    + it will only execute once. Should be a tiny bit faster.
    +

    +

    +
    +

    2020-08-27 14:11:06 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +53c10bd88f272c25fc5475dc63ea55140b9616db +

    +

    + pdfwrite - fix several memory leaks with colour spaces
    +
    + The colour space creation code uses pdf_string_to_cos_name() quite
    + frequently, and it often then passes the resulting cos_value_t to
    + functions such as cos_array_put and cos_dict_put.
    +
    + The basic 'put' functions actually copy scalar objects when they are
    + put in an array or dictionary (but they don't copy other composite
    + objects!) so we need to free the object created by
    + pdf_string_to_cos_name() after we've 'put' it.
    +
    + The only function to do that is cos_value_free() but that (unreasonably)
    + requires a cos_object_t parameter, even though the cos_value may not
    + be in a cos_object. Since the only use for the cos_object is to
    + retrieve a memory_t pointer in order to free the data used, we can
    + simply replace the cos_object_t * with a gs_memory_t * and use that
    + directly.
    +
    + This meant a few places needed to change where cos_value_free() was
    + already being used.
    +
    + After that I rationalised the code in gdevpdfc.c to some extent. Instead
    + of the existing mixture of *_put() and *_put_no_copy() calls I've chosen
    + to use *_put() calls throughout and then explicitly free the data which
    + has supposedly been copied.
    +
    + We could have used _nop_copy() throughout but that would have meant
    + checking the return value and freeing the original data if the copy
    + failed. It seems simpler just to unconditionally free the original
    + data.
    +
    + In one place we also need to check that the original data was not NULL
    + and that it was a scalar type. This is because (as noted above) if it
    + isn't a scalar type the *_put() functions *don't* copy the value, so we
    + don't want to free the original data in this case as it has been
    + transferred to the cos_object.
    +
    + Nancy did most of the original work on discovering the actual memory leak
    + here, and suggesting the basic fix, so many thanks!
    +

    +

    +
    +

    2020-08-27 14:00:56 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +73856faec1a4e1ed7d4099ec4a05f30d53c7c429 +

    +

    + pdfwrite - fix memory leak when allocation of a base font fails
    +
    + When the allocation of a PDF base font (pbfont) fails we were only
    + freeing the memory used by the structure, not any of the components
    + stored in it.
    +
    + There are quite a few subsidiary elements which need to be free and
    + there is already code to handle this, but its bundled up in
    + pdf_font_descripto_free(). So to make this easier, break out the code
    + to free the base font from pdf_fotn_descriptor_free() into its own
    + routine, pdf_base_font_free() and call that from both
    + pdf_font_descriptor_free() and pdf_base_font_alloc().
    +

    +

    +
    +

    2020-08-27 13:57:21 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +346ea731a43062662e57038aceea28859de51be6 +

    +

    + pdfwrite - fix memory leak when gs_copy_font fails
    +
    + If we can't copy the /.notdef glyph into a font we fail (its a
    + requirement for a valid font in a PDF file to have at least a /.notdef).
    +
    + If that happened we did not free the newly made copy of the font. Fix
    + that by freeing the copy.
    +

    +

    +
    +

    2020-08-25 15:17:45 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +367c3858886d1c43b75e3ea48f770d80db800d15 +

    +

    + Add OCREngine parameter.
    +

    +

    +
    +

    2020-08-27 12:33:35 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +30c56c669b05dd09518fad60a8f0ae8de4bcf186 +

    +

    + Add runtests to clustermaster.pl
    +

    +

    +
    +

    2020-08-26 16:11:27 -0700 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a5a9da62c49f1881186b2528f45f3ef846ad70ed +

    +

    + Add Makefile for api_test
    +

    +

    +
    +

    2020-08-26 12:44:03 -0700 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a69fc03408010df05732af7da229b64a181b7edf +

    +

    + Fix api_test.c for compiling on Linux.
    +

    +

    +
    +

    2020-08-25 14:17:50 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +99a34d86e93eb482c12c2143a31cfc227042dcf9 +

    +

    + Fix memory leak in pdfwrite images with errors in them.
    +
    + This was only a problem in non-GC interpreters (e.g. pdfi)
    +
    + This was an error that specifically affected images that got an
    + error during the first row (so data_height == 0).
    +
    + Added pdf_end_abort_image() to abort an image without writing it.
    + Also make sure to clean up the streams.
    +
    + Sample file: Bug 688023 test_out.pdf
    + Also: tests/pdf/Jbig2_042_13.pdf
    +

    +

    +
    +

    2020-08-24 17:43:05 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +3812280c5b021b16cce184b7aa6981d51a6ee5be +

    +

    + Bug 702761: Improve handline of PS file with many large ReusableStreams
    +
    + This file, with its original, non-optimal, method collected 1,000 ReusableStream
    + files, each of which was 7.5Mb, stored as 1,000 arrays of 180 40,000 byte strings.
    + As the file progressed, the load on the GC (garbage collector) to mark-and-sweep
    + all of those strings got slower and slower.
    +
    + This change collects the strings in the array of strings into a single large
    + string (up to max_string_size, currently 16Mb), so the load on the GC is cut
    + down to finding and freeing the array-of-strings since the last GC, and the
    + (at most) 1,000 strings, one for each ReusableStreamDecode "file" object.
    +
    + The submitter has already accepted the change to avoid storing the expanded
    + raw Image data, but there are other usages of ReusableStreamDecode that may
    + be used with large files (e.g. streamed PDF input files) that can benefit
    + from not loading down the GC.
    +

    +

    +
    +

    2020-08-25 12:16:10 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +e9104765e434280d4de3c781dfa5b9bebd5a524f +

    +

    + pdfwrite - fix another memory leak
    +
    + When we close down pdfwrite we check the stack of saved gstates to
    + see if there are any dash patterns to be freed. We must check the
    + entire potential stack, not just to the current level, in case we
    + allocated a dash pattern copy at a deeper level than we were at when
    + we exited.
    +
    + Because dash_patttern is allocated in non-gc memory this leak affects
    + all interpreters.
    +

    +

    +
    +

    2020-08-25 12:13:49 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +e59bed1d7e3481e74168fdaa0b3e1293acc30d2b +

    +

    + pdfwrite - more memory leak fixes with fonts
    +
    + When we free a font copy we need to:
    +
    + 1) Free the client_data 'names' array as well as the strings it contains
    + 2) Free the extra_names linked list.
    +

    +

    +
    +

    2020-08-24 22:41:41 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +fc3184789d23b42ba7ded18b2626c59e7d176624 +

    +

    + C# API demo. Make printing (creation of XPS content) a different process
    +
    + Since we are limited to one instance, we will go ahead and launch a different
    + process which will be handed arguments to do the printing, which involves the
    + creation of XPS content via the xpswrite device which is then fed through
    + the Windows XPS printing pipeline.
    +

    +

    +
    +

    2020-08-24 10:01:58 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +e7d5f25fc87573361cf5ec3a533021562659bff2 +

    +

    + C# API. Minor cleanup of viewer demo application.
    +

    +

    +
    +

    2020-08-24 18:55:30 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +ad0678d3d34948eb7c316b5511ffdb098e3afab2 +

    +

    + Fix Tesseract traineddata file loading.
    +
    + If it was finding any Tesseract data in ROM it was then not looking
    + for files.
    +

    +

    +
    +

    2020-08-21 18:44:33 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +f26bb372f3c2d8e564074c08943b60682bc8ed8c +

    +

    + Fix gs_main_set_language_param to escape encapsulation.
    +
    + If we are running in JOBSERVER mode, then postscript can't set stuff
    + into systemdict while in a job. We need to exit the encapsulation,
    + set the param, then reenter.
    +
    + (Contrary to my memory, dnit_job does not exit the encapsulation - or
    + rather it does, but it unsets the device, and then immediately reenters
    + encapsulation again.)
    +
    + Thanks are due to Ray for identifying the problem, and to Chris
    + for being a sounding board.
    +

    +

    +
    +

    2020-08-21 18:57:41 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +302aa9db9f03c2d0795ec8a8c249571bf86cd555 +

    +

    + Tidy up setting user params for PDF processing
    +

    +

    +
    +

    2020-08-21 18:50:55 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +6153b859d1fd3780cb95d20f678843ab1ba470a1 +

    +

    + PDF interp: Consolidate disabling of page handler device
    +

    +

    +
    +

    2020-08-24 09:24:31 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +9daf042fd7bb19e93388d89d9686a2fa4496f382 +

    +

    + Coverity 361429: move "break" to correct place.
    +
    + We had to add the outputfile to the "control" file permission list (as well
    + as write), but for the "pipe" case, I accidentally added the call after the
    + break out of loop that checks for a pipe.
    +

    +

    +
    +

    2020-08-20 18:31:00 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +2e3540010069071c8f9d52d2486067940a23b6e3 +

    +

    + Rejig gs_pattern1_make_pattern TilingType != 2 behaviour.
    +
    + Firstly, we change the rounding on bbw so as to give minimum
    + distortion to the pattern size.
    +
    + Secondly, we scale the contents to avoid either nasty gaps around
    + the edges, or lost content around the edges.
    +

    +

    +
    +

    2020-08-20 17:46:13 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +fb6a8352a2ba5b1c5b866b27638db4eaf2acac0f +

    +

    + Whitespace/Layout changes to gs_pattern1_make_pattern.
    +

    +

    +
    +

    2020-08-19 19:24:19 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +3e74ad126ee3983c634b8254dec0fc3b6544f0bd +

    +

    + Rejig internals of gs_pattern1_make_pattern.
    +
    + Previously we called "compute_inst_matrix" once at the start, then
    + maybe either called it again (if we ADJUST_SCALE_BY_GS_TRADITION)
    + or manually did part of it (retransforming the bbox) (if we
    + ADJUST_AS_ADOBE).
    +
    + Due to the vagaries of floating point, we can't be sure that
    + retransforming the bbox will give exactly the same result (as
    + our attempt to move the bbox onto a pixel origin may result
    + in future transformations may give x +/- epsilon rather x,
    + for example). Consequently, when we retransform, follow the
    + same procedure as we did before.
    +
    + This produces some diffs. We choose to accept these (minor) diffs
    + to give us consistent results.
    +

    +

    +
    +

    2020-08-19 19:15:00 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a3e7fa93b5f6afe7d74bf7c654dec1cff1adb76d +

    +

    + Simplify parameter passing in compute_inst_matrix.
    +

    +

    +
    +

    2020-08-24 14:40:01 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +65942618d083d49467f3dd6d9a802e94c6ae0796 +

    +

    + pdfwrite - fix another type 3 memory leak this time with CharProcs
    +
    + CharProcs are a cos object, not a simple byte array, so when we free
    + them we need to use cos_free() not gs_free_object().
    +

    +

    +
    +

    2020-08-24 14:38:38 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +2fdd3c0b9140dd8bd5a9b9bfdcc5ba4683a6eea0 +

    +

    + pdfwrite - fix memory leak with type 3 fonts
    +
    + When freeing type 3 font *resources* (ie the copy pdfwrite keeps to
    + write into the PDF file) we were not freeing some of the allocated
    + objects, the 'cached' array and the Resources (which are a dictionary
    + and so need to be freed by cos_free).
    +
    + Include gdevpdfo.h for the definition of cos_free()
    +

    +

    +
    +

    2020-08-24 09:01:35 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +a7cd4bbf979f2ecbaf19485cbfef42dcb179a927 +

    +

    + pdfwrite - fix some typos in comments
    +

    +

    +
    +

    2020-08-24 09:01:02 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +c5ae29c5b4ae5d4d9488842275d229b39f445bf1 +

    +

    + Coverity ID 361427 fix uninitialised variable.
    +

    +

    +
    +

    2020-08-22 13:57:58 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +3f04eaa6230cfe22b944bde4eaeed6c3087d5189 +

    +

    + pdfwrite - fix numerous font-related memory leaks
    +
    + The pdfwrite device was originally written to do all its memory
    + management via garbage collection, Unfortunately this leads to numerous
    + memory leaks when using an interpreter which doesn't implement a
    + garbage collecting memory model. Currently that's everything except
    + the PostScript interpreter.
    +
    + Many of these leaks cannot be exercised by anything except the
    + PostScript interpreter (and the new pdfi interpreter) but I think some
    + certainly could be.
    +
    + Don't increment the 'subst' structure when copying a TrueType CIDFont,
    + this leads to the structure never being freed.
    +
    + The code to free the 'subst' CID when freeing a TrueType CIDFont was
    + incorrect, leading to memory crashes (previously it was simply never
    + executed, and leaked).
    +
    + When increasing the size of the CIDMap entry for a TrueType CIDFont,
    + free the memory used by the original map after copying the data and
    + before overwriting the stored pointer.
    +
    + When freeing a copied font, if the font is a TrueType CIDFont decrement
    + the 'subst_CID_on_WMode' member so that it gets freed.
    +
    + When freeing a copied font, use the copied glyph data 'data' member
    + rather than the 'size' member to decide if we should free the data.
    + Sometimes we allocate memory for a size of 0.
    +
    + When freeing a copied font, if we created a names array for the glyphs
    + we need to free the string copies of the names we created as well.
    +
    + When freeing a copied font, if the CIDFMap entry has been created we
    + must free that too.
    +
    + When dropping a 'complete' font copy because we won't be using it, do
    + not simply set the pointer to NULL but actually call code to free the
    + copied font properly.
    +
    + When freeing a pdfwrite copy of a base font, if the CIDSet member has
    + been allocated we need to free it.
    +
    + When adding to the pdfwrite font cache, if the glyph_usage and
    + real_widths members have already been allocated we must free them before
    + assigning newly allocated memory.
    +

    +

    +
    +

    2020-08-21 12:16:26 -0700 + +
    Michael Vrhel <michael.vrhel@artifex.com>
    +8fcc3e370c3aca71691d48c92d57d7c2ca80672d +

    +

    + C# API: Addition of gsapi_get_param and gsapi_set_param
    +
    + Preliminary use of these. Which has revealed issues in GPDL with first page
    + last page use for PDF files.
    +

    +

    +
    +

    2020-08-21 11:13:33 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +d55c0edd6c1671d3a09a6061a81e25c0d414cc3f +

    +

    + More version number fixes
    +
    + The code to retrieve the Ghostscript paths from the Windows Registry
    + was generating a key based on the version number, but since we added the
    + patch the generation was incorrect.
    +
    + Since this is the third (!) case of this, scan the code for any usage of
    + gs_version, gs_version_number, GS_VERSION, GS_VERSION_NUMBER,
    + gs_revision, gs_revision_number, GS_REVISION and GS_REVISION_NUMBER.
    +
    + This reveals two more places, neither serious but we might as well fix
    + them while we're here.
    +
    + Thanks to Akira Kakuto for finding this problem and suggesting a patch.
    + I chose to use the code we were already using in two other places, just
    + for consistency, but the supplied patch was equally good.
    +

    +

    +
    +

    2020-08-20 14:46:07 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +34259c34410f7903981d61f1fc9c0b00fd9b3ed1 +

    +

    + Fix memory leak in freeing dash_pattern from pdfwrite device state
    +
    + The vgstack_depth = 0 still means that the entry needs to be freed.
    + (off by one error)
    +
    + This was a leak in both gs and pdfi
    +

    +

    +
    +

    2020-08-20 18:33:00 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +fae04c94708feb693e7582a9707ca2791e30334e +

    +

    + Delete binary files from lcms2mt tree
    +
    + There were left over binary libraries, remove them.
    +

    +

    +
    +

    2020-08-20 17:19:09 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +3920a727fb19e19f597e518610ce2416d08cb75f +

    +

    + Fix pdfwrite "%d" mode with file permissions
    +
    + Firstly, in gx_device_delete_output_file the iodev pointer was being passed
    + to the delete_method incorrectly (passing a pointer to that pointer). Thus
    + when we attempted to use that to confirm permission to delete the file, it
    + crashed. Credit to Ken for finding that.
    +
    + Secondly, due to the way pdfwrite works, when running with an output file per
    + page, it creates the current output file immediately it has completed writing
    + the previous one. Thus, it has to delete that partial file on exit.
    +
    + Previously, the output file was not added to the "control" permission list,
    + so an attempt to delete it would result in an error. So add the output file
    + to the "control" as well as "write" list.
    +

    +

    +
    +

    2020-08-13 09:47:09 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +cb93fa6079796d99b3fb3cfbdd0b919f57d34f58 +

    +

    + Fix memory leaks associated with pdfwrite, type3x images
    +
    + These leaks are only an issue for non-GC interpreters such as pdfi.
    +

    +

    +
    +

    2020-08-19 14:31:50 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +ac67c85c93703d6883f6d32a6996f33a51293640 +

    +

    + Bug702727 -- Fix rc counting of penum->pcs for image1 and image4
    +
    + This relates to the structure gx_image_enum_s which is used by image1
    + and image4.
    +
    + The fix is unfortunately scattered around the code, but I think I found
    + appropriate places. It is ugly because type1 and type4 images
    + apparently share a lot of the same code, so the module layers are not
    + as they should be.
    +
    + Need to increment and decrement the rc since the enum struct wants to
    + keep it around (especially in gs where it literally goes back out into
    + the gs interpreter between when the enum is built and when it is
    + used!).
    +
    + This is part of cleaning up memory leaks for non-GC interpreters
    + (pdfi).
    +
    + Changed the pcs entry in the enum struct to not be const, since it
    + needs to be reference counted.
    +
    + Cleaned up an unrelated compiler warning in gxidata.c
    + There are also some unrelated whitespace changes.
    +

    +

    +
    +

    2020-08-20 13:53:59 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +d434639da425b6172fe1230bbc331ec057daff6f +

    +

    + Trim trailing white space
    +

    +

    +
    +

    2020-08-20 12:12:38 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +3808bc680a35b6a19b75555539f66fdd874138f5 +

    +

    + txtwrite - improve CIDFont handling
    +
    + The calculation of the font size for modes 0 & 1 was incorrect when the
    + font was a CIDFont. The size calculation relied upon the FontMatrix of
    + the type 0 font and did not consider the descendant.
    +
    + For PDF files we can ignore the type 0 font and simply use the
    + descendant font matrix. For PostScript input we will probably have to
    + be more careful so this is an interim fix for PDF input only.
    +

    +

    +
    +

    2020-08-20 12:10:23 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +39a9388184d1788d48e35c47a3e92a4411d106f7 +

    +

    + PDF interpreter - reject non-dictionary /Annots array entries
    +
    + Bug #702745 "Error: /typecheck in --runpdf--"
    +
    + The PDF file has an invalid /Annots array entry:
    +
    + 5 0 obj
    + <</Annots[5 0 41 0 R]
    +
    + The entries should be dictionaries or indirect references to
    + dictionaries, integers aren't valid. This causes a typecheck error when
    + trying to read keys from the dictionary.
    +
    + This commit checks that the entry is a dictionary before trying to
    + process it; if it isn't we raise a warning and ignore it.
    +

    +

    +
    +

    2020-08-20 09:12:12 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +c935055b6b5d20fceb6175877bee9b529dddb199 +

    +

    + Fix PDF /Producer for new patch level
    +
    + Bug #702772 "Strange /Producer attribute"
    +
    + The change to include a patch level for Ghostscript in the gs_revision
    + value wasn't being reflected in the code to generate the version
    + number used in the PDF /Producer string.
    +
    + Copied the code from printf_program_ident() in base/gsmisc.c to the
    + code in pdf_store_default_Producer() and commented both pieces of code
    + to note the existence of each other so that in future hopefully we won't
    + forget to keep them in sync.
    +
    + Thanks to Peter Cherepanov for spotting the flaw.
    +

    +

    +
    +

    2020-08-19 11:49:39 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +d07b9485b2bb3a70552aee9407fcff8fa52698df +

    +

    + Fix memory leak in pdf_begin_typed_image()
    +
    + Need to decrement the ColorSpace before overwriting it.
    +

    +

    +
    +

    2020-08-19 11:38:03 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +99e437e619fbd3d91242cba98cc462dadb9a5b8e +

    +

    + Fix some compiler warnings
    +
    + This also has some whitespace changes -- not my fault! :)
    +

    +

    +
    +

    2020-08-18 14:49:41 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +a111d7316b0cb2dea8f840e8387fc47b9e252c36 +

    +

    + Refactor pdf_begin_typed_image()
    +
    + Mainly just cleaning up the error handling so it all exits at the
    + bottom.
    +
    + Reduced the amount of duplicate code.
    +
    + Fixed a bunch of memory leaks that would only happen on error
    + paths.
    +
    + Broke out the Eps2Write code to reduce size of main function a bit.
    +

    +

    +
    +

    2020-08-18 11:15:26 -0700 + +
    Nancy Durgin <nancy.durgin@artifex.com>
    +4ccf8a357a8fce8998ad8d4ab5abb3a4c6b63374 +

    +

    + Fix one of several memory leaks in pdfwrite images
    +
    + The leak is in non-GC interpreters such as pdfi.
    +
    + This is a 1600 line function. I think it is in drastic need of
    + refactoring in order to be maintainable.
    +

    +

    +
    +

    2020-08-19 18:21:01 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +cc90efbe4abce945e36a68876218a46606b84015 +

    +

    + Tweak type1 pattern code to remove some needless fabs.
    +

    +

    +
    +

    2020-08-18 23:23:40 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +ec2699f50aa3ada4ef2c477c7577331a3950bcc8 +

    +

    + Fix Bug 702381: Hang due to cyclic PDF resources.
    +
    + The loop is caused by a circular /ParentResources attribute.
    + This branch of code is triggered by an error in the sample file:
    + misplaced /Form resources in a Type 3 font. This font has /Resource
    + dictionaries added to /CharProcs entries rather than the font dictionary.
    +
    + Note that this patch fixes the hang issue, but does not correct the
    + issue of not being able to find the correct resource (in the CharProc)
    + so that the file still output does not match Adobe (mupdf has that
    + same issue).
    +
    + Thanks to Peter Cherepanov for this patch.
    +

    +

    +
    +

    2020-08-17 15:44:01 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +9619c8fc8d1e2548c737adfb7f6b8b15d49d20a4 +

    +

    + Bug 702744: Add windows utf-8 handling for unlink and rename.
    +
    + To do this, we introduce gp_unlink and gp_rename, and call those
    + as appropriate.
    +
    + Also, make gp_open_scratch_file add the file to the permit list.
    + When such a file is closed, it will be deleted from the permit list.
    +
    + It will also be removed from the permit list if the file is deleted
    + using the PS deletefile operator.
    +
    + On closedown, if scratch files haven't been deleted, then we'll
    + delete them as part of the closedown of gs_lib_ctx.
    +
    + This means that 'purging' the control lists must not remove scratch
    + file paths from the list.
    +
    + Also, ensure that gsapi callers can't maliciously (or accidentally)
    + remove scratch path paths from the list so as to leave them around
    + after closedown.
    +

    +

    +
    +

    2020-08-18 10:18:11 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +df245b46c1a5290239b2932e2a5d1bdeae710c48 +

    +

    + Bump version number
    +

    +

    +
    +

    2020-09-28 12:54:48 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +5f75977a0da7b8e92f2b8241440c43cc44863f63 +

    +

    + Docs/dates/version for 9.53.3
    +

    +

    +
    +

    2020-09-24 08:19:27 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +c876777dcadbb0acbc8cc887e94360c6f5adbc0d +

    +

    + WhatIsGS.htm updates from Lisa F
    +

    +

    +
    +

    2020-09-29 20:16:10 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +be33716b4a6d42f9bd5a5485514dbaeb9e9524b2 +

    +

    + Bug 702948: Ensure initial bitmap cache sizes are properly aligned
    +
    + Now that the allocations from the bitmap cache are aligned to the platform's
    + required alignment, see commit:
    +
    + 260c443bc14cdffa4d94e14c3a57e35bebee3a5b
    +
    + We also want the initial size of the memory pool used by the cache to be
    + "aligned".
    +
    + This is so that code that attempts to identify cache entries to evict by
    + requesting a size equal to the entire size of cache memory pool doesn't get an
    + unexpected failure, because we've rounded up that allocation request to a value
    + larger than the entire size of the memory pool.
    +
    + Because we don't expect an error to be possible at that point, a crash can
    + occur.
    +
    + Of the "normal" platforms we use, this only exhibits on Win32 because that is
    + the only platform where the align_bitmap_mod we use is less than the
    + obj_align_mod used for the memory managers.
    +

    +

    +
    +

    2020-09-28 20:10:16 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +27824a749775a233725cf3f302ce8156c478f7e1 +

    +

    + Fix icc profile reference counting in transparency compositor
    +
    + Found during Windows testing for a release.
    +
    + The full test file for
    + https://bugs.ghostscript.com/show_bug.cgi?id=693365
    +
    + would cause Ghostscript to crash due to an ICC profile being freed whilst a
    + reference was still being held for it. That was not counting up a reference
    + count when restoring the device profile back to a previous value.
    +
    + Fixing that introduced a leak for other profiles. And that turned out to be
    + not decrementing the reference count when replacing a device profile.
    +

    +

    +
    +

    2020-09-28 10:21:47 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +d2fa2e186a6cdbdc011a44275532e2f1071111ec +

    +

    + Work around for (I think) a VS2019 optimiser bug
    +
    + VS2019 release builds crash with the input file from bug 702916 and several
    + other files, in copied_glyph_slot() because the pointer retrieved and stored
    + in *pslot is non-sensical.
    +
    + Debug/Profile builds and optimised builds with earler VS versions don't show
    + the problem.
    +
    + Adding debug code to assign the calculated index to an interim unsigned integer
    + variable also cause the problem to go away.
    +
    + So, use that as a workaround.
    +

    +

    +
    +

    2020-09-28 10:20:26 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +cd36db788b73674e9a18803f451ed910ddd66dba +

    +

    + Fix some casting confusion for special glyph CID/index values
    +
    + And a whitespace/indentation issue.
    +
    + Noticed in passing....
    +

    +

    +
    +

    2020-09-25 13:03:40 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +787be772d87089ee8224b17ba50ac4adccc75ffe +

    +

    + Fix Bug 702941 - Mispelled PDF interpreter variable name.
    +
    + s/RepiredAnError/RepairedAnError/ A simple typo that was missed because
    + we did not have a test file with a format error to trigger this code.
    +

    +

    +
    +

    2020-09-25 08:41:03 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +4f9cce5953cae92014ef6652894c183080dd5d19 +

    +

    + Version, doc and date updates for 9.53.2
    +

    +

    +
    +

    2020-09-25 12:40:01 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +167c75d35336fcfe7c94cf5fb0258406443cdc6b +

    +

    + Bug 702938: Allocating cached glyphs, account for alignment
    +
    + For efficiency, the glyph cache allocates "large" blocks of memory into which
    + it parcels out offsets for individual glyph cache bitmaps, as required.
    +
    + Since cached glyphs are usually fairly small, and potentially can be short
    + lived, this saves the overheads of "full" memory for every cached glyph.
    +
    + Unfortunately, in calculating the offsets for the cached glyph, it was failing
    + to account for the required alignment of the system. In any environment that
    + strictly enforces aligned memory accesses, this will potentially cause a bus
    + error.
    +
    + In this case, it was switching the gs_glyph type to a 64 bit type that triggered
    + the issue. But any changed to the contents of the cached_char struct could have
    + resulted in it happening.
    +

    +

    +
    +

    2020-09-24 19:08:25 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +104dffc4aec03598257c14ab33b292c8e7149d59 +

    +

    + Remove links to ghostscript.com/release_history.html
    +
    + That page is now gone.
    +

    +

    +
    +

    2020-09-24 17:10:21 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +b1c4631aa8910f6da923367984491fc2b883d7a0 +

    +

    + Remove dead end links from Readme.htm
    +

    +

    +
    +

    2020-09-23 20:20:59 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +334f24a4a8529f8476dfe74dd2b47f1274269263 +

    +

    + Bug 702920: Fix type confusion in new param type code.
    +
    + In a few cases we were using the wrong element in the union to read the
    + value back from the param list (and to range check the values).
    +

    +

    +
    +

    2020-09-15 08:51:08 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +ab2505e19cf36ffc780f6824a50c8e7eacf7af8f +

    +

    + Fix problem with BGPrint and multi-threaded rendering caused by commit cca27988
    +
    + The unconditional call to enable multi-threaded rendering during set up of the
    + gx_device_printer as a clist caused the SEGV of bug 702181, but enabling
    + multi-threaded rendering here isn't correct since it is usually done when we
    + output the page (gdev_prn_output_page_aux). The problem is that BGPrint would
    + setup a new clist device to render the page, but needs to enable multi-threaded
    + rendering for the background clist device. Do this if NumRenderThreads > 0.
    +

    +

    +
    +

    2020-09-22 13:10:04 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +a7d7b4f9ea347de35cbbec69a58c3a0a43fda447 +

    +

    + Fix gp_file allocations to use thread_safe_memory.
    +
    + The gpmisc.c does allocations for gp_file objects and buffers used by
    + gp_fprintf, as well as gp_validate_path_len. The helgrind run with
    + -dBGPrint -dNumRenderingThreads=4 and PCL input showed up the gp_fprintf
    + problem since the clist rendering would call gp_fprintf using the same
    + allocator (PCL's chunk allocator which is non_gc_memory). The chunk
    + allocator is intentionally not thread safe (for performance).
    +

    +

    +
    +

    2020-09-23 07:39:04 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +7a3f5d5ab9cc94ee433dafb5331519855f6671e6 +

    +

    + Temporarily disable BGPrint for pcl, xps and gpdl.
    +
    + In order to safely allow for a 9.53.2 patch release that fixes BGPrint
    + with NumRenderingThreads while the issues with PCL and friends are
    + fixed, just ignore BGPrint in pcl/pl/plmain.c
    +

    +

    +
    +

    2020-09-16 07:48:47 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +7250256e29355b1ceccd06b3b937b7d0e739d1f7 +

    +

    + Bug 702904: Another fix to check for shared libjpeg/libtiff
    +
    + We cannot combine shared and not shared libjpeg and libtiff - they either both
    + need to be "local" or both shared, and configure checks that and fails when
    + the two are incompatible.
    +
    + However, that check would fail when either libjpeg or libtiff were not being
    + included at all. Since it is libtiff that is the "problem" for this
    + compatibility, now check if TIFF is included, and if not, skip the check.
    +

    +

    +
    +

    2020-08-25 16:47:10 +0100 + +
    ChrisL <cliddell@salvor-openbsd.lan>
    +1264b6debb1d48e2b9ea0eae8fda86c04f4def9d +

    +

    + Fix the OpenBSD build
    +
    + Whilst hopefully not breaking the buildroot build.
    +

    +

    +
    +

    2020-09-14 16:52:22 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +6011a3d8096c51ae795b436f17b141cceba4d77b +

    +

    + Bug 702901: initialize directory for tiff configure
    +
    + Previously the directory in which to run the libtiff configure script was
    + initialised to an empty string, but that, in some toolchains, resulted in an
    + error due to "unsafe header/library path used in cross-compilation".
    +
    + So initialise it something benign instead.
    +

    +

    +
    +

    2020-08-24 09:01:02 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +0712379d88c2697fef35e60107bf0201a5f1a790 +

    +

    + Coverity ID 361427 fix uninitialised variable.
    +

    +

    +
    +

    2020-09-14 14:12:23 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +09763e4d082755436bb36bbef912193357058535 +

    +

    + Update docs for 9.53.1 release
    +

    +

    +
    +

    2020-09-14 14:32:23 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +6d1440b2dabde655a2fe48ddbf0c09a82de4d423 +

    +

    + Fix crashes with pdfwrite, TrueType input fonts and Windows 64-bit build
    +
    + With the change to 64-bits unconditionally for gs_glyph we can now
    + define GS_MIN_CID_GLYPH in 64-bit terms.
    +
    + Previously we were using the architecture size of a long_long to
    + determine which define to use, and we do not define long_long on Windows
    + leading to us using an essentially 32-bit definition. This caused
    + indexing off the end of an array in copied_glyph_slot()
    +

    +

    +
    +

    2020-09-14 09:40:30 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +e54e9c5eaebc0bf06e57f754a3c16278de412459 +

    +

    + Bug 702897: Fix shared libtiff/libjpeg check
    +
    + For various reasons we cannot combine shared and not shared libjpeg and
    + libtiff - they either both need to be "local" or both shared.
    +
    + But the check for that compatibility was triggered during the recursive
    + configure call when setting up for cross compiling.
    +
    + Skip the check for that recursive configure call.
    +

    +

    +
    +

    2020-09-10 16:18:10 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +f157ed49512438c95635e6340933bbcb14cea524 +

    +

    + Tweak History9.htm with jbig2dec updates
    +

    +

    +
    +

    2020-09-10 22:47:09 +0800 + +
    Sebastian Rasmussen <sebras@gmail.com>
    +9a5ace846c8af91d047e59c87722d0c36e79e5d3 +

    +

    + Bug 702884: Require jbig2dec 0.19 when building ghostscript.
    +
    + In practice this has been required since commit
    + 9b5008aa2bc1c6a6acb2c6f90d1ef8d6bad9e66a.
    +

    +

    +
    +

    2020-09-10 22:41:20 +0800 + +
    Sebastian Rasmussen <sebras@gmail.com>
    +53db58bd227c80375f00135045d36b66868732f4 +

    +

    + Update jbig2dec stuff for 0.19 release.
    +

    +

    +
    +

    2020-09-10 08:49:46 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +1af88d327daa9392f5c6542dc7e247ddab7c9b0b +

    +

    + Docs and dates for 9.53.0
    +

    +

    +
    +

    2020-09-09 11:50:12 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +45884ca68488ac470b894702bdd8da232743d8e4 +

    +

    + Bug 702871: Fix GraphicsAlphaBits + Fill/Stroke issue.
    +
    + When we flush the alphabuffer, mapped_start and mapped_height are
    + both set to zero. When we refill it, mapped_height is set to
    + non-zero. USUALLY mapped_start is set to non-zero too, but it can
    + be set to zero when we are close to the bottom of the page.
    +
    + Hence we should test for mapped_height != 0, rather than both
    + mapped_height and mapped_start being non-zero.
    +
    + So the 'quick hack' that Chris used is actually correct.
    +

    +

    +
    +

    2020-08-28 09:31:58 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +4ba6aa1d7253e8ecd7cd796c95306f1203f70879 +

    +

    + Bug 702837 typo in warning message
    +
    + Thanks to Herbert Voss for spotting this. Fixed the typo and updated the
    + version number in the warning from 9.53 to 9.53.0 to match the actual
    + version and patch number of the release (the decision to add the patch
    + level was taken after the original commit)
    +

    +

    +
    +

    2020-08-27 09:35:15 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +bd6b59984ad713d2b1d48f3b81bf1e631bf9ee2b +

    +

    + Update dates'n'docs for 9.53.0.RC2
    +

    +

    +
    +

    2020-08-24 18:55:30 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +197eb511b5d81a662f801333709199495abe61cf +

    +

    + Fix Tesseract traineddata file loading.
    +
    + If it was finding any Tesseract data in ROM it was then not looking
    + for files.
    +

    +

    +
    +

    2020-08-24 09:24:31 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +cb279d8a0e356542f6829ed429269ce07ec838a9 +

    +

    + Coverity 361429: move "break" to correct place.
    +
    + We had to add the outputfile to the "control" file permission list (as well
    + as write), but for the "pipe" case, I accidentally added the call after the
    + break out of loop that checks for a pipe.
    +

    +

    +
    +

    2020-08-21 18:50:55 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +bad72741aad21b17a3965673f3e7949a2fc7c256 +

    +

    + PDF interp: Consolidate disabling of page handler device
    +

    +

    +
    +

    2020-08-21 11:13:33 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +60bbe61efc97c208f31c2d2d617753232ed1881d +

    +

    + More version number fixes
    +
    + The code to retrieve the Ghostscript paths from the Windows Registry
    + was generating a key based on the version number, but since we added the
    + patch the generation was incorrect.
    +
    + Since this is the third (!) case of this, scan the code for any usage of
    + gs_version, gs_version_number, GS_VERSION, GS_VERSION_NUMBER,
    + gs_revision, gs_revision_number, GS_REVISION and GS_REVISION_NUMBER.
    +
    + This reveals two more places, neither serious but we might as well fix
    + them while we're here.
    +
    + Thanks to Akira Kakuto for finding this problem and suggesting a patch.
    + I chose to use the code we were already using in two other places, just
    + for consistency, but the supplied patch was equally good.
    +

    +

    +
    +

    2020-08-21 08:14:49 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +45baf1a5b71c2ddad8e16ae2f895c4244e6af9e6 +

    +

    + Fox typos and stuff in the release highlights
    +

    +

    +
    +

    2020-08-20 18:33:00 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +58ea17fd3032584e04f4e844e2d9991af87f114e +

    +

    + Delete binary files from lcms2mt tree
    +
    + There were left over binary libraries, remove them.
    +

    +

    +
    +

    2020-08-20 17:19:09 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +2ddd9d68bb0831ec8c9dd5e4e2e94bb44f8e5028 +

    +

    + Fix pdfwrite "%d" mode with file permissions
    +
    + Firstly, in gx_device_delete_output_file the iodev pointer was being passed
    + to the delete_method incorrectly (passing a pointer to that pointer). Thus
    + when we attempted to use that to confirm permission to delete the file, it
    + crashed. Credit to Ken for finding that.
    +
    + Secondly, due to the way pdfwrite works, when running with an output file per
    + page, it creates the current output file immediately it has completed writing
    + the previous one. Thus, it has to delete that partial file on exit.
    +
    + Previously, the output file was not added to the "control" permission list,
    + so an attempt to delete it would result in an error. So add the output file
    + to the "control" as well as "write" list.
    +

    +

    +
    +

    2020-08-18 10:23:13 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +a12a526799a32c9fc17c7f6c5f37e21246e2d4e7 +

    +

    + Update docs, version, dates, product family
    +
    + for 9.53.0 RC1
    +

    +

    +
    +

    2020-08-20 09:12:12 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +f797ac99d0b0a337b5a57c37cdd026f4a9dbf897 +

    +

    + Fix PDF /Producer for new patch level
    +
    + Bug #702772 "Strange /Producer attribute"
    +
    + The change to include a patch level for Ghostscript in the gs_revision
    + value wasn't being reflected in the code to generate the version
    + number used in the PDF /Producer string.
    +
    + Copied the code from printf_program_ident() in base/gsmisc.c to the
    + code in pdf_store_default_Producer() and commented both pieces of code
    + to note the existence of each other so that in future hopefully we won't
    + forget to keep them in sync.
    +
    + Thanks to Peter Cherepanov for spotting the flaw.
    +

    +

    +
    +

    2020-08-18 23:23:40 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +ec82d2aa95dc8eb764483ff9011585bfc47a0f1b +

    +

    + Fix Bug 702381: Hang due to cyclic PDF resources.
    +
    + The loop is caused by a circular /ParentResources attribute.
    + This branch of code is triggered by an error in the sample file:
    + misplaced /Form resources in a Type 3 font. This font has /Resource
    + dictionaries added to /CharProcs entries rather than the font dictionary.
    +
    + Note that this patch fixes the hang issue, but does not correct the
    + issue of not being able to find the correct resource (in the CharProc)
    + so that the file still output does not match Adobe (mupdf has that
    + same issue).
    +
    + Thanks to Peter Cherepanov for this patch.
    +

    +

    +
    +

    2020-08-17 15:44:01 +0100 + +
    Robin Watts <Robin.Watts@artifex.com>
    +a01320e4d57d984f5bf65126534dbb3c33b416a4 +

    +

    + Bug 702744: Add windows utf-8 handling for unlink and rename.
    +
    + To do this, we introduce gp_unlink and gp_rename, and call those
    + as appropriate.
    +
    + Also, make gp_open_scratch_file add the file to the permit list.
    + When such a file is closed, it will be deleted from the permit list.
    +
    + It will also be removed from the permit list if the file is deleted
    + using the PS deletefile operator.
    +
    + On closedown, if scratch files haven't been deleted, then we'll
    + delete them as part of the closedown of gs_lib_ctx.
    +
    + This means that 'purging' the control lists must not remove scratch
    + file paths from the list.
    +
    + Also, ensure that gsapi callers can't maliciously (or accidentally)
    + remove scratch path paths from the list so as to leave them around
    + after closedown.
    +

    +

    +
    +
    +

    Changelog

    +

    2020-09-28 12:54:48 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +1da1144e165aa1643a440e45f238c2301982bf79 +

    +

    + Docs/dates/version for 9.53.3
    +
    +Resource/Init/gs_init.ps
    +base/version.mak
    +doc/DLL.htm
    +doc/Deprecated.htm
    +doc/Develop.htm
    +doc/Devices.htm
    +doc/Drivers.htm
    +doc/Fonts.htm
    +doc/History9.htm
    +doc/Install.htm
    +doc/Internal.htm
    +doc/Language.htm
    +doc/Lib.htm
    +doc/Make.htm
    +doc/News.htm
    +doc/Ps-style.htm
    +doc/Ps2epsi.htm
    +doc/Psfiles.htm
    +doc/Readme.htm
    +doc/Release.htm
    +doc/SavedPages.htm
    +doc/Source.htm
    +doc/Unix-lpr.htm
    +doc/Use.htm
    +doc/VectorDevices.htm
    +doc/WhatIsGS.htm
    +doc/gs-vms.hlp
    +doc/sample_downscale_device.htm
    +doc/subclass.htm
    +doc/thirdparty.htm
    +man/dvipdf.1
    +man/gs.1
    +man/gslp.1
    +man/gsnd.1
    +man/pdf2dsc.1
    +man/pdf2ps.1
    +man/pf2afm.1
    +man/pfbtopfa.1
    +man/printafm.1
    +man/ps2ascii.1
    +man/ps2epsi.1
    +man/ps2pdf.1
    +man/ps2pdfwr.1
    +man/ps2ps.1
    +

    +

    +
    +

    2020-09-29 20:16:10 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +ae7767cd15946cd4058037acf965848a5bd5cb33 +

    +

    + Bug 702948: Ensure initial bitmap cache sizes are properly aligned
    +
    + Now that the allocations from the bitmap cache are aligned to the platform's
    + required alignment, see commit:
    +
    + 260c443bc14cdffa4d94e14c3a57e35bebee3a5b
    +
    + We also want the initial size of the memory pool used by the cache to be
    + "aligned".
    +
    + This is so that code that attempts to identify cache entries to evict by
    + requesting a size equal to the entire size of cache memory pool don't get an
    + unexpected failure, because we've rounded up that allocation request to a value
    + larger than the entire size of the memory pool.
    +
    + Because we don't expect an error to be possible at that point, a crash can
    + occur.
    +
    + Of the "normal" platforms we use, this only exhibits on Win32 because that is
    + the only platform where the align_bitmap_mod we use is less than the
    + obj_align_mod used for the memory managers.
    +
    +base/gxccman.c
    +base/gxclist.c
    +base/lib.mak
    +

    +

    +
    +

    2020-09-28 20:10:16 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +27824a749775a233725cf3f302ce8156c478f7e1 +

    +

    + Fix icc profile reference counting in transparency compositor
    +
    + Found during Windows testing for a release.
    +
    + The full test file for
    + https://bugs.ghostscript.com/show_bug.cgi?id=693365
    +
    + would cause Ghostscript to crash due to an ICC profile being freed whilst a
    + reference was still being held for it. That was not counting up a reference
    + count when restoring the device profile back to a previous value.
    +
    + Fixing that introduced a leak for other profiles. And that turned out to be
    + not decrementing the reference count when replacing a device profile.
    +
    +base/gdevp14.c
    +

    +

    +
    +

    2020-09-28 10:21:47 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +d2fa2e186a6cdbdc011a44275532e2f1071111ec +

    +

    + Work around for (I think) a VS2019 optimiser bug
    +
    + VS2019 release builds crash with the input file from bug 702916 and several
    + other files, in copied_glyph_slot() because the pointer retrieved and stored
    + in *pslot is non-sensical.
    +
    + Debug/Profile builds and optimised builds with earler VS versions don't show
    + the problem.
    +
    + Adding debug code to assign the calculated index to an interim unsigned integer
    + variable also cause the problem to go away.
    +
    + So, use that as a workaround.
    +
    +devices/gxfcopy.c
    +

    +

    +
    +

    2020-09-28 10:20:26 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +cd36db788b73674e9a18803f451ed910ddd66dba +

    +

    + Fix some casting confusion for special glyph CID/index values
    +
    + And a whitespace/indentation issue.
    +
    + Noticed in passing....
    +
    +base/gsccode.h
    +

    +

    +
    +

    2020-09-25 13:03:40 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +787be772d87089ee8224b17ba50ac4adccc75ffe +

    +

    + Fix Bug 702941 - Mispelled PDF interpreter variable name.
    +
    + s/RepiredAnError/RepairedAnError/ A simple typo that was missed because
    + we did not have a test file with a format error to trigger this code.
    +
    +Resource/Init/pdf_base.ps
    +

    +

    +
    +

    2020-09-25 08:41:03 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +6b2b35fbbc230be106190c3948b14553410c29e0 +

    +

    + Version, doc and date updates for 9.53.2
    +
    +Resource/Init/gs_init.ps
    +base/version.mak
    +doc/DLL.htm
    +doc/Deprecated.htm
    +doc/Develop.htm
    +doc/Devices.htm
    +doc/Drivers.htm
    +doc/Fonts.htm
    +doc/History9.htm
    +doc/Install.htm
    +doc/Internal.htm
    +doc/Language.htm
    +doc/Lib.htm
    +doc/Make.htm
    +doc/News.htm
    +doc/Ps-style.htm
    +doc/Ps2epsi.htm
    +doc/Psfiles.htm
    +doc/Readme.htm
    +doc/Release.htm
    +doc/SavedPages.htm
    +doc/Source.htm
    +doc/Unix-lpr.htm
    +doc/Use.htm
    +doc/VectorDevices.htm
    +doc/WhatIsGS.htm
    +doc/gs-vms.hlp
    +doc/sample_downscale_device.htm
    +doc/subclass.htm
    +doc/thirdparty.htm
    +man/dvipdf.1
    +man/gs.1
    +man/gslp.1
    +man/gsnd.1
    +man/pdf2dsc.1
    +man/pdf2ps.1
    +man/pf2afm.1
    +man/pfbtopfa.1
    +man/printafm.1
    +man/ps2ascii.1
    +man/ps2epsi.1
    +man/ps2pdf.1
    +man/ps2pdfwr.1
    +man/ps2ps.1
    +

    +

    +
    +

    2020-09-25 12:40:01 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +167c75d35336fcfe7c94cf5fb0258406443cdc6b +

    +

    + Bug 702938: Allocating cached glyphs, account for alignment
    +
    + For efficiency, the glyph cache allocates "large" blocks of memory into which
    + it parcels out offsets for individual glyph cache bitmaps, as required.
    +
    + Since cached glyphs are usually fairly small, and potentially can be short
    + lived, this saves the overheads of "full" memory for every cached glyph.
    +
    + Unfortunately, in calculating the offsets for the cached glyph, it was failing
    + to account for the required alignment of the system. In any environment that
    + strictly enforces aligned memory accesses, this will potentially cause a bus
    + error.
    +
    + In this case, it was switching the gs_glyph type to a 64 bit type that triggered
    + the issue. But any changed to the contents of the cached_char struct could have
    + resulted in it happening.
    +
    +base/gxbcache.c
    +base/lib.mak
    +

    +

    +
    +

    2020-09-24 17:10:21 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +b1c4631aa8910f6da923367984491fc2b883d7a0 +

    +

    + Remove dead end links from Readme.htm
    +
    +doc/Readme.htm
    +

    +

    +
    +

    2020-09-23 20:20:59 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +334f24a4a8529f8476dfe74dd2b47f1274269263 +

    +

    + Bug 702920: Fix type confusion in new param type code.
    +
    + In a few cases we were using the wrong element in the union to read the
    + value back from the param list (and to range check the values).
    +
    +base/gsparam.c
    +

    +

    +
    +

    2020-09-15 08:51:08 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +ab2505e19cf36ffc780f6824a50c8e7eacf7af8f +

    +

    + Fix problem with BGPrint and multi-threaded rendering caused by commit cca27988
    +
    + The unconditional call to enable multi-threaded rendering during set up of the
    + gx_device_printer as a clist caused the SEGV of bug 702181, but enabling
    + multi-threaded rendering here isn't correct since it is usually done when we
    + output the page (gdev_prn_output_page_aux). The problem is that BGPrint would
    + setup a new clist device to render the page, but needs to enable multi-threaded
    + rendering for the background clist device. Do this if NumRenderThreads > 0.
    +
    +base/gdevprn.c
    +

    +

    +
    +

    2020-09-22 13:10:04 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +a7d7b4f9ea347de35cbbec69a58c3a0a43fda447 +

    +

    + Fix gp_file allocations to use thread_safe_memory.
    +
    + The gpmisc.c does allocations for gp_file objects and buffers used by
    + gp_fprintf, as well as gp_validate_path_len. The helgrind run with
    + -dBGPrint -dNumRenderingThreads=4 and PCL input showed up the gp_fprintf
    + problem since the clist rendering would call gp_fprintf using the same
    + allocator (PCL's chunk allocator which is non_gc_memory). The chunk
    + allocator is intentionally not thread safe (for performance).
    +
    +base/gpmisc.c
    +

    +

    +
    +

    2020-09-23 07:39:04 -0700 + +
    Ray Johnston <ray.johnston@artifex.com>
    +7a3f5d5ab9cc94ee433dafb5331519855f6671e6 +

    +

    + Temporarily disable BGPrint for pcl, xps and gpdl.
    +
    + In order to safely allow for a 9.53.2 patch release that fixes BGPrint
    + with NumRenderingThreads while the issues with PCL and friends are
    + fixed, just ignore BGPrint in pcl/pl/plmain.c
    +
    +pcl/pl/plmain.c
    +

    +

    +
    +

    2020-09-16 07:48:47 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +7250256e29355b1ceccd06b3b937b7d0e739d1f7 +

    +

    + Bug 702904: Another fix to check for shared libjpeg/libtiff
    +
    + We cannot combine shared and not shared libjpeg and libtiff - they either both
    + need to be "local" or both shared, and configure checks that and fails when
    + the two are incompatible.
    +
    + However, that check would fail when either libjpeg or libtiff were not being
    + included at all. Since it is libtiff that is the "problem" for this
    + compatibility, now check if TIFF is included, and if not, skip the check.
    +
    +configure.ac
    +

    +

    +
    +

    2020-08-25 16:47:10 +0100 + +
    ChrisL <cliddell@salvor-openbsd.lan>
    +1264b6debb1d48e2b9ea0eae8fda86c04f4def9d +

    +

    + Fix the OpenBSD build
    +
    + Whilst hopefully not breaking the buildroot build.
    +
    +Makefile.in
    +base/freetype.mak
    +configure.ac
    +

    +

    +
    +

    2020-09-14 16:52:22 +0100 + +
    Chris Liddell <chris.liddell@artifex.com>
    +6011a3d8096c51ae795b436f17b141cceba4d77b +

    +

    + Bug 702901: initialize directory for tiff configure
    +
    + Previously the directory in which to run the libtiff configure script was
    + initialised to an empty string, but that, in some toolchains, resulted in an
    + error due to "unsafe header/library path used in cross-compilation".
    +
    + So initialise it something benign instead.
    +
    +configure.ac
    +

    +

    +
    +

    2020-08-24 09:01:02 +0100 + +
    Ken Sharp <ken.sharp@artifex.com>
    +0712379d88c2697fef35e60107bf0201a5f1a790 +

    +

    + Coverity ID 361427 fix uninitialised variable.
    +
    +base/gdevflp.c
    +

    +

    +

    2020-09-14 14:32:23 +0100
    Ken Sharp <ken.sharp@artifex.com>
    @@ -241849,7 +250659,7 @@ Bump the versioning after the 8.71 release.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -241862,7 +250672,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -241889,7 +250699,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Install.htm b/doc/Install.htm index 15ed5c1a..c3da7e60 100644 --- a/doc/Install.htm +++ b/doc/Install.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -418,7 +417,7 @@ comment at the beginning of the latter file for more information.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -431,7 +430,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -458,7 +457,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Internal.htm b/doc/Internal.htm index 0afa6494..0361a485 100644 --- a/doc/Internal.htm +++ b/doc/Internal.htm @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -96,7 +95,7 @@ at the beginning of the procedure.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -109,7 +108,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -136,7 +135,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Language.htm b/doc/Language.htm index 3d27fdda..51965ae6 100644 --- a/doc/Language.htm +++ b/doc/Language.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -449,12 +448,12 @@ class="offsite">Adobe Technical Note #5407, "Transparency -in PDF". Previously (in 9.52 and earlier), Ghostscript's model +in PDF". Previously (in 9.52 and earlier), Ghostscript's model maintained separate alpha and mask values for opacity and shape. This model has been changed (as of 9.53) and instead Ghostscript maintains separate float values for stroke and fill alpha values with a boolean that indicates if these should be interpreted as shape or alpha values to be more in line with the -PDF specification. +PDF specification.

    What follows is a subset of all the custom operators related to transparency, but @@ -1026,24 +1025,6 @@ activated, false if not.

    -
    -
    -.setpdfwrite
    -
    -This operator is now deprecated, and its use is discouraged -

    This operator conditions the environment for the pdfwrite output device. -It is a shorthand for setting parameters that have been deemed benificial. While not strictly necessary, it is usually helpful to set call this when using the pdfwrite device. -For example, this is how the ps2pdf script calls Ghostscript: -

    -gs -q -dSAFER -dNOPAUSE -dBATCH -sOutputFile=file.pdf [more options] \
    -  -sDEVICE=pdfwrite -c .setpdfwrite -f
    source1.ps [more files] -
    -

    Currently, the operator just sets a minimum 3 MB vmthreshold to allow for -accumulating shared object data and to reduce the incidence of garbage -collection as a performance improvement. Additional settings may be added in the future.

    -
    -
    -
    <dict> .genordered <dict> (default: /OutputType /Type3).
    @@ -2066,7 +2047,7 @@ will install resource files into /gs/Resource.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -2079,7 +2060,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -2106,7 +2087,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Lib.htm b/doc/Lib.htm index 30484f8c..c5fed2c4 100644 --- a/doc/Lib.htm +++ b/doc/Lib.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -1025,7 +1024,7 @@ is finished, it should execute:

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -1038,7 +1037,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -1066,7 +1065,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Make.htm b/doc/Make.htm index ffb859ae..b8be1e18 100644 --- a/doc/Make.htm +++ b/doc/Make.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -401,32 +400,6 @@ directory.

    Supporting third party libraries will also be in their own sub-directories (e.g. jpeg, freetype and so on).

    -

    Luratech compressor libraries

    - -

    Ghostscript has optional support for the Luratech proprietary JBIG2 -and JPEG 2000 implementations. If you have the source code for these -and wish the compile them into Ghostscript, the build system expects -them to be in directories named luratech/ldf_jb2 and -luratech/lwf_jp2 in the top level gs source directory, alongside -the other third-party libraries. With the Luratech source directories in the -expected place, the build system will automatically include them.

    -

    -If you have the Luratech code but wish to build without it, on "configure" -based builds you can achieve this by doing:

    -
    -./configure --without-luratech -
    -

    -On Windows, you can achieve it by adding:

    - -
    -NO_LURATECH=1 -
    -to your nmake command line. -

    -With either of these options, the build will fall back to the defaults for -both JBIG2 and JPEG2000 decoding.

    -

    How to check for post-release bug fixes

    @@ -511,21 +484,6 @@ options, here we don't duplicate most of that documentation: we recommend strongly that you review the entire makefile specific for your operating system and compiler before building Ghostscript.

    -

    Building against the Luratech compression libraries

    - -

    -To compile Ghostscript against the proprietary Luratech JBIG2 and JPEG -2000 implementations, simply ensure that the luratech/ldf_jb2 and -luratech/lwf_jp2 containing the Luratech code exist in the top level -gs source directory, and (re-)run configure (ensuring to make clean before -re-running make). The configure -script will detect the presence of the directories, and apply the appropriate -settings in the Makefile.

    -

    -If you have the Luratech directories in place, but want Ghostscript built -without it, you can run configure with the --without-luratech option, and -the script will behave as if the directories did not exist.

    -

    Changes for your environment

    @@ -787,10 +745,15 @@ time with the -DDEBUG or

    make so
    On some platforms (Linux, *BSD, Darwin/Mac OS X, SunOS), - it is possible to build ghostscript as a shared object library. + it is possible to build Ghostscript as a shared object library. There is a corresponding "make soclean" for cleaning up.
    +
    +
    make sanitize
    +
    Builds Ghostscript with AddressSanitizer. Output is placed in ./sanbin .
    +
    +

    Note: on most platforms some of these simple instructions don't quite work in one way or another. Read the section on your specific @@ -997,25 +960,6 @@ in the makefiles, and are applied when building with all versions of Visual Studio, but not all options are supported (or required) by all versions of Visual Studio. These warnings are benign and can be ignored.

    -

    Building with the Luratech compression libraries

    - -

    -If you wish to compile Ghostscript with the Luratech JBIG2 and JPEG 2000 -implementations, the source should be installed in the top-level -directory of the Ghostscript source. -If you have an appropriately licensed source distribution this should -already have been done.

    - -

    -With the Luratech source in the luratech/ldf_jb2 and -luratech/lwf_jp2 directories in the top level gs source -directory, the nmake makefile will detect their presence, and use them -automatically.

    -

    -If you have the Luratech code in place, but wish Ghostsrcipt to be built -without the Luratech decoders, you can do so by passing NO_LURATECH=1 on -the nmake command line, or add the define to your Visual Studio project.

    -

    Microsoft Environment for 64-bit

    Building Ghostscript for 64-bit Windows (AMD64 processor) requires @@ -1505,7 +1449,7 @@ msvc.mak sets the other options automatically.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -1518,7 +1462,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -1545,7 +1489,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/News.htm b/doc/News.htm index de256246..b73856a5 100644 --- a/doc/News.htm +++ b/doc/News.htm @@ -45,7 +45,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -86,66 +85,58 @@ overview. -

    Version 9.53.1 (2020-09-14)

    +

    Version 9.54.0 (2021-03-30)

    +

    The 9.54.0 release is a maintenance release, and also adds new functionality. +

    Highlights in this release include:

    • -

      The 9.53.1 release is primarily maintenance. -

    • -
    • -

      The most obvious change is the (re-)introduction of the patch level to the version number, -this helps facilitate a revised policy on handling security related issues. +

      Overprint simulation is now available to all output devices, allowing +quality previewing/proofing of PostScript and PDF jobs that rely on overprint. +See the -dOverprint option documentation in: +Overprint

    • -

      Our efforts in code hygiene and maintainability continue. +

      The "docxwrite" device adds the ability to output to Microsoft Word +"docx" format. See: docxwrite

    • -

      We have added the capability to build with the Tesseract OCR engine. In such -a build, new devices are available (pdfocr8/pdfocr24/pdfocr32) which render the -output file to an image, OCR that image, and output the image "wrapped" up as a -PDF file, with the OCR generated text information included as "invisible" text -(in PDF terms, text rendering mode 3). -

      Due to some patches to the Tesseract sources that are required (integrated -upstream, but awaiting release), time constraints, and the experimental nature -of the feature, we only support including Tesseract from source, not linking to -Tesseract shared libraries. Whether we add this capability will be largely -dependant on community demand for the feature. +

      The pdfwrite device is now capable of using the Tesseract OCR engine when it is +built into Ghostscript to improve searchability and copy and paste functionality when +the input lacks the metadata for that purpose. See: UseOCR

    • -

      We have added Python bindings for the gsapi interface, can be found -in demos/python. These are experimental, and we welcome feedback from -interested developers. +

      Ghostscript/GhostPDL now includes a "map text to black" +function, where text drawn by an input job (except when drawn using a +Type 3 font) can be forced to draw in solid black. See: +BlackText

    • -

      For those integrating Ghostscript/GhostPDL via the gsapi interface, we -have added new capabilities to that, specifically in terms of setting and interrogating -device parameters. These, along with the existing interface calls, are documented in: -Ghostscript Interpreter API +

      Ghostscript/GhostPDL now supports simple N-up imposition "internally". See: +NupControl

    • -

      IMPORTANT: In consultation with a representative of -(OpenPrinting) it is -our intention to deprecate and, in the not distant future, remove the -OpenPrinting Vector/Raster Printer Drivers (that is, the opvp -and oprp devices). -

      If you rely on either of these devices, please get in touch with -us, so we can discuss your use case, and revise our plans accordingly. +

      Our efforts in code hygiene and maintainability continue.

    • -

      IMPORTANT: We have forked LittleCMS2 into LittleCMS2mt (the "mt" indicating "multi-thread"). -LCMS2 is not thread safe and cannot be made thread safe without breaking the ABI. Our fork -will be thread safe and include performance enhancements (these changes have all be been -offered and rejected upstream). We will maintain compatibility between Ghostscript and LCMS2 -for a time, but not in perpetuity. If there is sufficient interest, our fork will be -available as its own package separately from Ghostscript (and MuPDF). +

      The usual round of bug fixes, compatibility changes, and incremental improvements.

    • -

      The usual round of bug fixes, compatibility changes, and incremental improvements. +

      (9.53.0) We have added the capability to build with the Tesseract OCR engine. In such +a build, new devices are available (pdfocr8/pdfocr24/pdfocr32) which render the +output file to an image, OCR that image, and output the image "wrapped" up as a +PDF file, with the OCR generated text information included as "invisible" text +(in PDF terms, text rendering mode 3). +

      Mainly due to time constraints, we only support including Tesseract from +source included in our release packages, and not linking to Tesseract/Leptonica +shared libraries. Whether we add this capability will be largely dependent on +community demand for the feature. +

      See Enabling OCR for more details.

    For a list of open issues, or to report problems, please visit bugs.ghostscript.com. -

    Incompatible changes

    +

    Incompatible changes

    Included below are incompatible changes from recent releases (the specific release in question listed in parentheses). We include these, for now, as we are aware that not everyone upgrades with every release.

    @@ -194,13 +185,9 @@ operators may stop working or may change behaviour. or the gs-devel mailing list would be best), and we'll work with you to either find an alternative solution or return the previous functionality, if there is genuinely no other option. -

    One case we know this has occurred is GSView 5 (and earlier). GSView 5 support for PDF -files relied upon internal use only features which are no longer available. GSView 5 will -still work as previously for PostScript files. For PDF files, users are encouraged to look -at MuPDF. -

    Changelog

    +

    Changelog

    See the history file for complete log of changes. @@ -211,7 +198,7 @@ of changes.


    -Copyright © 2005-2020 Artifex Software, Inc. +Copyright © 2005-2021 Artifex Software, Inc. All rights reserved.

    @@ -225,7 +212,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -252,7 +239,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Ps-style.htm b/doc/Ps-style.htm index 559c6758..84f7dd43 100644 --- a/doc/Ps-style.htm +++ b/doc/Ps-style.htm @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -527,7 +526,7 @@ that could be made into a procedure.

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -540,7 +539,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -567,7 +566,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Ps2epsi.htm b/doc/Ps2epsi.htm index 9af6fd87..7a545a9c 100644 --- a/doc/Ps2epsi.htm +++ b/doc/Ps2epsi.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -207,7 +206,7 @@ encapsulation fails because of the nature of the original PostScript file.

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -220,7 +219,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -247,7 +246,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Psfiles.htm b/doc/Psfiles.htm index 73aa9f14..07cccb25 100644 --- a/doc/Psfiles.htm +++ b/doc/Psfiles.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -872,7 +871,7 @@ when passing files with -dJOBSERVER.

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -885,7 +884,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -912,7 +911,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Readme.htm b/doc/Readme.htm index 2d5f5f0a..de4d7e7e 100644 --- a/doc/Readme.htm +++ b/doc/Readme.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -76,8 +75,6 @@ source code (which is necessary before installing it on Unix and VMS
  • What is GhostXPS?
  • What is GhostSVG?
  • What is GhostPDL?
  • -
  • What is MuPDF?
  • -
  • What is MuXPS?
  • Document roadmap by theme
    • @@ -559,7 +556,7 @@ command-line options.

      -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

      This software is provided AS-IS with no warranty, either express or @@ -572,7 +569,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

      -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -599,7 +596,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Release.htm b/doc/Release.htm index e164517f..4d10992d 100644 --- a/doc/Release.htm +++ b/doc/Release.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -823,7 +822,7 @@ These are included in the Ghostscript release archive.

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -836,7 +835,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -863,7 +862,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/SavedPages.htm b/doc/SavedPages.htm index cbce7ce1..383548b6 100644 --- a/doc/SavedPages.htm +++ b/doc/SavedPages.htm @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -291,7 +290,7 @@ Print two collated copies of the first file, followed by 5 copies of the second

    -Copyright © 2013-2019 Artifex Software, Inc. All rights +Copyright © 2013-2021 Artifex Software, Inc. All rights reserved.

    @@ -308,7 +307,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -335,7 +334,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Source.htm b/doc/Source.htm index 9d82f391..e998bf78 100644 --- a/doc/Source.htm +++ b/doc/Source.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -443,7 +442,7 @@ and so on.

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -456,7 +455,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -484,7 +483,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Unix-lpr.htm b/doc/Unix-lpr.htm index cf1e69a7..ce3bc4d3 100644 --- a/doc/Unix-lpr.htm +++ b/doc/Unix-lpr.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -282,7 +281,7 @@ is responsible for the number-of-colours part of the script.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -295,7 +294,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -323,7 +322,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/Use.htm b/doc/Use.htm index b09927fd..64339dfc 100644 --- a/doc/Use.htm +++ b/doc/Use.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -713,12 +712,11 @@ be drawn, whilst those not listed will not be drawn.

    -
    -dShowAcroForm
    +
    -dShowAcroForm=false
    - Show annotations referred from the Interactive Form Dictionary (AcroForm dictionary). - By default, AcroForm is not enumerated because Adobe Acrobat doesn't do this. - This option may be useful for debugging or recovery of incorrect PDF files - that don't associate all annotations with the page objects.
    + Don't show annotations from the Interactive Form Dictionary (AcroForm dictionary). + By default, AcroForm processing is now enabled because Adobe Acrobat does this. This option + is provided to restore the previous behavior which corresponded to older Acrobat.
    @@ -794,6 +792,18 @@ is applied to each PDF file separately. So if you were to set -sPageList=1 exercise caution when using this switch, and probably should not use it at all when processing a mixture of PostScript and PDF files on the same command line.

    +

    +The XPS language like the PDF language allows random access to pages. The XPS interpreter handles all the PageList cases +discussed above. It also handles cases such as: +

    +-sPageList=1,2,1,2 indicates repeated pages.  Pages processed in order 1, 2, 1, 2.
    +-sPageList=10-5 indicates pages will be processed in the order 10, 9, 8, 7, 6, 5.
    +-sPageList=1-,-1 indicates first processing from page 1 to end and then from end to page 1.
    +
    +In addition, the XPS interpreter allows the use of a -dLastPage < -dFirstPage. In this +case the pages will be processed backwards from LastPage to FirstPage. +

    +
    @@ -2619,6 +2629,15 @@ processing of PostScript source files. Note: in releases 7.30 and earlier, processing of DoPS was always enabled. + +
    +
    -dBlackText
    +
    Forces text to be drawn with black. This occurs for text fill and +text stroke operations. PDF output created with this setting will be +updated to be drawn with gray values of 0. Type 3 fonts, which are +sometimes used for graphics, are not affected by this parameter.
    +
    +

    Page parameters

    @@ -2741,6 +2760,39 @@ This option sets the -dEPSFitPage, -dPDFFitPage, and the -dFitPage options.

    + +
    + +
    -sNupControl=Nup_option_string
    +
    This option specifies the N-up nesting to be performed. The pages are scaled +and arranged on the current PageSize "master" page according the the option. +

    +The only option strings are as follows: +

      +
    • +
      -sNupControl=number1xnumber2
      + will fit number1 nested pages across the master page, and number2 + down the master page, from the upper left, then to the right to fill the row, moving down + to the leftmost place on the next row until the nest is complete. +

      + A partially filled nest will be output when the -sNupControl= string is changed, + or when Ghostscript exits. +

      + Pages are scaled to fit the requested number horizontally and vertically, maintaining the + aspect ratio. If the scaling selected for fitting the nested pages leaves space horizontally + on the master page, the blank area will be added to the left and right of the entire + row of nested pages. If the fit results in vertical space, the blank area will be added + above and below all of the rows. +

    • +
    • +
      -sNupControl=
      + An empty string will turn off nesting. If there are any nested pages on the master page, + the partially filled master page will be output. +
    • +
    +
    +
    +

    Font-related parameters

    @@ -2750,14 +2802,6 @@ VM -- instead of always being loaded into global VM. Useful only for compatibility with Adobe printers for loading some obsolete fonts.
    -
    -
    -dNOCCFONTS
    -
    Suppresses the use of fonts precompiled into the Ghostscript executable. -See "Precompiling fonts" in the -documentation on fonts for details. This is probably useful only for - debugging.
    -
    -
    -dNOFONTMAP
    Suppresses the normal loading of the Fontmap file. This may be useful @@ -3131,7 +3175,7 @@ Separation and DeviceN colors. For the general user this command option be specified within which the color blending operations are to take place. Some files lack this specification, in which case the blending occurs in the output device's native color space. This -dependency of blending color space on the device color model +dependency of blending color space on the device color model can be avoided by using the above command to force a specific color space in which to perform the blending.
    @@ -3310,15 +3354,32 @@ are used to convert between RGB and CMYK with black generation and undercolor
    -dSimulateOverprint=true/false
    -This option enables continous tone CMYK devices (e.g. tiff32nc) the capability to -provide a simulation of spot color overprinting. The default setting is true. +This option has been replaced by -dOverprint= +
    +
    + + +
    + +
    -dOverprint=/enable | /disable | /simulate
    +
    +This option provides control of overprinting. The default setting is /enable +which allows devices such as CMYK that can support overprint to leave planes unchanged +under control of PostScript and PDF overprint settings. +

    +The /disable setting ignores all overprint (and overprint mode) from the input. +

    +If /simulate is set, then pages with overprint (or overprint mode) set for +CMYK or Separation colors will be internally maintained and output to RGB or Gray +devices. +

    Note that not all spot color overprint cases can be accurately simulated with a CMYK only device. For example, a case where you have a spot color overprinted with CMYK colors will be indistiguishable from a case where you have spot color equivalent CMYK colorants overprinted with CMYK colors, even though they may need to show significantly different overprint simulations. To obtain a full overprint simulation, -use the psdcmyk or tiffsep device, where the spot colors are kept in their own - individual planes.

    +use the /simulate setting or the psdcmyk or tiffsep device, where the spot +colors are kept in their own individual planes.
    @@ -3730,9 +3791,7 @@ memory. For example, to allow use of 30Mb of extra RAM use: -c 30000000 setvmthreshold -f.

    This can also be useful in processing large documents when using a high-level (vector) output device (like pdfwrite) that maintains significant internal -state. In fact, the .setpdfwrite -operator used by the ps2pdf script and others sets a vmthreshold value of -3 MB to account for this.

    +state.

  • @@ -5295,7 +5354,7 @@ PCLEOs. (see the FAPI-related source code for details).


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -5308,7 +5367,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -5335,7 +5394,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/VectorDevices.htm b/doc/VectorDevices.htm index 23a1fdf0..c457150e 100644 --- a/doc/VectorDevices.htm +++ b/doc/VectorDevices.htm @@ -38,7 +38,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -59,10 +58,11 @@
  • Overview
  • PCL-XL file output
  • Text output +
  • DOCX file output
  • XPS file output
  • PDF file output -
  • PostScript file output -
  • EPS file output +
  • PostScript file output +
  • EPS file output
  • PDF/X-3 file output
  • PDF/A file output
  • Ghostscript PDF printer description @@ -89,7 +89,8 @@

    High level devices are Ghostscript output devices which do not render to a raster, in general they produce 'vector' as opposed to bitmap output. Such devices currently -include: pdfwrite, ps2write, eps2write, txtwrite, xpswrite, pxlmono and pxlcolor. +include: pdfwrite, ps2write, eps2write, txtwrite, xpswrite, pxlmono, pxlcolor and +docxwrite.

    @@ -175,7 +176,7 @@ document as Unicode.

    Options

    -
    -dTextFormat=0 | 1 | 2 | 3 (default is 3) +
    -dTextFormat=0 | 1 | 2 | 3 | 4 (default is 3)

    Format 0 is intended for use by developers and outputs XML-escaped Unicode along with information regarding the format of the text (position, font name, point size, etc). The XML output is the same format as the MuPDF output, but @@ -186,10 +187,25 @@ as the MuPDF code, and so the results will not be identical.

    Format 2 outputs Unicode (UCS2) text (with a Byte Order Mark) which approximates the layout of the text in the original document.

    Format 3 is the same as format 2, but the text is encoded in UTF-8.

    +

    Format 4 is internal format similar to Format 0 but with extra information.

    +


    +

    DOCX output

    + +

    The docxwrite device creates a DOCX file suitable for use with applications +such as Word or LibreOffice, containing the text in the original document. +

    +

    Rotated text is placed into textboxes. Heuristics are used to group +glyphs into words, lines and paragraphs; for some types of formatting, these +heuristics may not be able to recover all of the original document structure. +

    +

    This device currently has no special configuration parameters.

    + +

    +


    XPS file output

    @@ -699,7 +715,8 @@ Where pdfa.pjl contains the PJL commands to create a PDF/A-1b file (see example

    Example creation of a PDF/A output file

    For readability the line has been bisected, when used for real this must be a single line. The 'ESC' represents -a single byte, value 0x1B an escape character in ASCII.

    +a single byte, value 0x1B, an escape character in ASCII. The line must end with an ASCII newline (\n, 0x0A) and this must be the only newline following the @PJL. +The line breaks between "" below should be replaced with space characters, the double quote charcters (") are required.

    @@ -985,6 +1002,61 @@ displaying document's properties,
     so we recommend this value.
     
  • + + +
    -sUseOCR=string +
    Controls the use of OCR in pdfwrite. If enabled this will use an OCR +engine to analyse the glyph bitmaps used to draw text in a PDF file, and +the resulting Unicode code points are then used to construct a ToUnicode +CMap. +

    +PDF files containing ToUnicode CMaps can be searched, use copy/paste and +extract the text, subject to the accuracy of the ToUnicode CMap. Since not all +PDF files contain these it can be beneficial to create them. +

    +

    +Note that, for English text, it is possible that the existing standard character +encoding (which most PDF consumers will fall back to in the absence of Unicode +information) is better than using OCR, as OCR is not a 100% reliable process. +OCR processing is also comparatively slow. +

    +

    +For the reasons above it is useful to be able to exercise some control over the +action of pdfwrite when OCR processing is available, and the UseOCR +parameter provides that control. There are three possible values: +

    +
  • Never Default - don't use OCR at all even if support is built-in. +
  • AsNeeded If there is no existing ToUnicode information, use OCR. +
  • Always Ignore any existing information and always use OCR. +

    +Our experimentation with the Tesseract OCR engine has shown that the more text we +can supply for the engine to look at, the better the result we get. We are, unfortunately, +limited to the graphics library operations for text as follows. +

    +

    +The code works on text 'fragments'; these are the text sequences sent to the text +operators of the source language. Generally most input languages will try to send +text in its simplest form, eg "Hello", but the requirements of justification, kerning +and so on mean that sometimes each character is positioned independently on the page. +

    +

    +So pdfwrite renders all the bitmaps for every charcter in the text document, when +set up to use OCR. Later, if any character in the font does not have a Unicode +value already we use the bitmaps to assemble a 'strip' of text which we then send +to the OCR engine. If the engine returns a different number of recognised characters +than we expected then we ignore that result. We've found that (for English text) +constructions such as ". The" tend to ignore the full stop, presumably because the OCR +engine thinks that it is simply noise. In contrast "text." does identify the full +stop correctly. So by ignoring the failed result we can potentially get a better result +later in the document. +

    +

    +Obviously this is all heuristic and undoubtedly there is more we can do to improve the +functionality here, but we need concrete examples to work from. +

    +
  • + +

    PostScript file output

    The ps2write device handles the same set of distiller @@ -1388,7 +1460,7 @@ not affected.


    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -1401,7 +1473,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -1428,7 +1500,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/WhatIsGS.htm b/doc/WhatIsGS.htm index 967934d6..ed897ad2 100644 --- a/doc/WhatIsGS.htm +++ b/doc/WhatIsGS.htm @@ -24,7 +24,7 @@ @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -51,25 +50,23 @@
    - -

    -There are various different products in the Ghostscript family; this document -attempts to explain what they are, and how they are related. +

    +There are various products in the Ghostscript family; this document describes what they are, and how they are related.


    -

    Table of contents

    @@ -80,94 +77,86 @@ attempts to explain what they are, and how they are related. -

    What is Ghostscript?

    +

    Ghostscript/GhostPDF

    -

    Ghostscript is an interpreter for PostScript and Portable Document Format -(PDF) files. It is available both under the GNU GPL Affero license -and for commercial licensing -from Artifex. It has been under active -development for over 20 years and has been ported to many different systems -during this time. +

    Ghostscript is an interpreter for PostScript® and Portable Document Format (PDF) files.

    -

    Ghostscript consists of a PostScript interpreter layer, and a graphics -library. Sometimes the Ghostscript graphics library is confusingly also referred -to simply as Ghostscript. Even more confusingly, sometimes people say Ghostscript -when they really mean GhostPDL. - -

    Binaries for Ghostscript for various systems can be downloaded from -www.ghostscript.com/download. The -source code is included in both the Ghostscript and GhostPDL downloads from -the same site. -


    -

    What is GhostPDF?

    +

    Ghostscript consists of a PostScript interpreter layer, and a graphics library. The graphics library is shared with all the other products in the Ghostscript family, so all of these technologies are sometimes referred to as Ghostscript, rather than the more correct GhostPDL.

    -

    GhostPDF is an interpreter built on top of Ghostscript that handles PDF files. +

    GhostPDF is an interpreter built on top of Ghostscript to handle PDF files. Currently GhostPDF relies on extensions to the PostScript language/imaging model, and so cannot be used independently of the Ghostscript PostScript interpreter component. As such GhostPDF is an umbrella term used to refer to both these -extensions and the interpreter code. +extensions and the interpreter code.

    Many people (including the authors) frequently just refer to Ghostscript as supporting PDF and only specifically mention GhostPDF when wanting to make -the distinction between the PostScript and PDF support. +the distinction between the PostScript and PDF support.

    -

    GhostPDF is included in the Ghostscript binaries for various systems available -from www.ghostscript.com/download. +

    Binaries for Ghostscript and GhostPDF (included in the Ghostscript binaries) for various systems can be downloaded from here. The source can be found in both the Ghostscript and GhostPDL downloads from -the same site. +the same site.


    -

    What is GhostPCL?

    -

    GhostPCL is an interpreter for PCL and PXL files. This consists of an -PCL/PXL interpreter hooked up to the Ghostscript graphics library. +

    GhostPDL

    + +

    Historically, we’ve used GhostPDL as an umbrella term to encompass our entire line of products. We've now brought all these disparate products together into a single package, called, appropriately enough, GhostPDL.

    + +

    When running on a printer (or server) GhostPDL now automatically detects the type of data being fed to it and processes it accordingly. The individual interpreters all plug into a top-level module that handles both automatic language detection and Printer Job Language (PJL) based configuration.

    -

    GhostPCL is available both under the GNU Affero GPL license +

    The exact set of interpreters present in an installation can be tuned by the integrator for their specific product/use cases.

    + +

    In addition to our existing PDL modules (PS, PDF, PCL, PXL, and XPS) we have now added new modules to handle a range of common image formats. With these installed, GhostPDL will handle JPEGs (both JFIF and EXIF), PWGs, TIFFs, PNGs, JBIG2s, and JPEG2000s.

    + +

    GhostPDL is available both under the GNU Affero GPL license and for commercial licensing from Artifex. -

    Binaries for GhostPCL for various systems can be downloaded from -www.ghostscript.com/download. The -source can be found in the GhostPCL/GhostPDL downloads from the same site. +

    The source code for GhostPDL can be found on +here. +


    + +

    GhostPCL

    + +

    GhostPCL is an interpreter for PCL and PXL files. This consists of an +PCL/PXL interpreter hooked up to the Ghostscript graphics library.

    + +

    GhostPCL is available both under the GNU Affero GPL license and for commercial licensing from Artifex.

    + + +

    Binaries for GhostPCL for various systems can be downloaded from here. The source can be found in the GhostPCL/GhostPDL downloads from the same site.

    +
    -

    What is GhostXPS?

    +

    GhostXPS

    GhostXPS is an interpreter for XPS (XML Paper Specfication) files. This -consists of an XPS interpreter hooked up to the Ghostscript graphics library. +consists of an XPS interpreter hooked up to the Ghostscript graphics library.

    GhostXPS is available both under the GNU Affero GPL license and for commercial licensing -from Artifex. +from Artifex.

    Binaries for GhostXPS for various systems can be downloaded from -www.ghostscript.com/download. The -source can be found in the GhostXPS/GhostPDL downloads from the same site. +here. The +source can be found in the GhostXPS/GhostPDL downloads from the same site.


    -

    What is GhostPDL?

    -

    GhostPDL (Ghost Page Description Languages) is an umbrella term for all -the above technologies. As all the above interpreters are built upon a -single graphics library, there are size and portability benefits to using -two of more of the languages in a given project. A product that -includes more than one such language in a single binary and automatically -chooses between them is sometimes referred to as a "Language Switch" build. +

    URW Font Information

    -

    GhostPDL is available both under the GNU Affero GPL license -and for commercial licensing -from Artifex. +

    The set of truetype fonts in the urwfonts directory are necessary for the PCL/XL interpreter to function properly but they ARE NOT FREE SOFTWARE and are NOT distributed under the GNU GPL/AGPL. They can instead be redistributed under the AFPL license which bars commercial use.

    -

    The source code for GhostPDL can be found on -www.ghostscript.com/download. +

    If your copy of GhostPDL includes these fonts, you should have received a copy of the the Aladdin Free Pubilc License, usually in a file called COPYING.AFPL. If not, please contact Artifex Software, Inc. 1305 Grant Avenue - Suite 200, Novato, CA 94945 USA, or visit http://www.artifex.com/

    +
    -
    -

    PostScript is a registered trademark of Adobe Systems Inc. -

    PCL is a registered trademark of Hewlett-Packard Company. -


    +

    PostScript is a registered trademark of Adobe Systems Inc.

    +

    PCL is a registered trademark of Hewlett-Packard Company.

    +

    -Copyright © 2000-2020 Artifex Software, Inc. All rights reserved. +Copyright © 2000-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -180,7 +169,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -207,7 +196,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/gdevds32.c b/doc/gdevds32.c index 30ac5fde..a59ea7a6 100644 --- a/doc/gdevds32.c +++ b/doc/gdevds32.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2019 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or diff --git a/doc/gs-vms.hlp b/doc/gs-vms.hlp index c04994bd..36eaa74e 100644 --- a/doc/gs-vms.hlp +++ b/doc/gs-vms.hlp @@ -1,6 +1,6 @@ 1 gs gs - GPL Ghostscript interpreter/previewer -! Ghostscript version 9.53.1, 14 September 2020 +! Ghostscript version 9.54.0, 30 March 2021 Usage: $ gs [options] [file ...] diff --git a/doc/sample_downscale_device.htm b/doc/sample_downscale_device.htm index ea4c6da9..31340887 100644 --- a/doc/sample_downscale_device.htm +++ b/doc/sample_downscale_device.htm @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -241,7 +240,7 @@ The source for this device driver is in: doc/gdevds32.c

    - Copyright © 2016-2019 Artifex Software, Inc. All rights reserved. + Copyright © 2016-2021 Artifex Software, Inc. All rights reserved.

    This software is provided AS-IS with no warranty, either express or @@ -254,7 +253,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -280,7 +279,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/subclass.htm b/doc/subclass.htm index 74a98c86..09dc9403 100644 --- a/doc/subclass.htm +++ b/doc/subclass.htm @@ -37,7 +37,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -786,7 +785,7 @@ int black_text_text_begin(gx_device *dev, gs_imager_state *pis, const gs_text_pa

    -Copyright © 2013-2019 Artifex Software, Inc. All rights +Copyright © 2013-2021 Artifex Software, Inc. All rights reserved.

    @@ -803,7 +802,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -830,7 +829,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/doc/thirdparty.htm b/doc/thirdparty.htm index 593164a0..fca4ca7d 100644 --- a/doc/thirdparty.htm +++ b/doc/thirdparty.htm @@ -45,7 +45,6 @@
  • Home
  • Licensing
  • Releases
  • -
  • Release History
  • Documentation
  • Download
  • Performance
  • @@ -192,26 +191,6 @@ the relevant license, and the "upstream" URL. http://www.monotypeimaging.com/ - -Luratech LuraDocument JBIG2 C-SDK
    -Included in commercial release -1.08
    -with patches -Replacement JBIG2 image decoder for the PDF interpreter -Commercial -http://www.luratech.com/ - - - -Luratech LuraWave JP2 C-SDK
    -Included in commercial release -2.10
    -with patches -Replacement JPEG2000 image decoder for the PDF interpreter -Commercial -http://www.luratech.com/ - - LittleCMS
    (lcms2) @@ -230,7 +209,7 @@ the relevant license, and the "upstream" URL.

    -Copyright © 2005-2020 Artifex Software, Inc. +Copyright © 2005-2021 Artifex Software, Inc. All rights reserved.

    @@ -244,7 +223,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.

    -Ghostscript version 9.53.1, 14 September 2020 +Ghostscript version 9.54.0, 30 March 2021 @@ -271,7 +250,7 @@ Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.


    - © Copyright 2019 Artifex Software, Inc.
    + © Copyright 2019-2021 Artifex Software, Inc.
    All rights reserved.
    diff --git a/examples/alphabet.ps b/examples/alphabet.ps index 33069fe5..002d920b 100644 --- a/examples/alphabet.ps +++ b/examples/alphabet.ps @@ -68,7 +68,8 @@ NumSizes FontName findfont CurrentSize scalefont setfont /Ratio Ratio dup mul def } repeat -showpage clear cleardictstack alphabetsave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage diff --git a/examples/colorcir.ps b/examples/colorcir.ps index 78cca026..ec57be6c 100644 --- a/examples/colorcir.ps +++ b/examples/colorcir.ps @@ -120,6 +120,7 @@ hsvcircle 0.8 0.8 scale graycircle -showpage clear cleardictstack colorcirsave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage diff --git a/examples/doretree.ps b/examples/doretree.ps index aecbb4aa..5e03f1e0 100644 --- a/examples/doretree.ps +++ b/examples/doretree.ps @@ -2476,10 +2476,11 @@ gsave 0.2 20 20 592 592 BDR grestore -showpage %%Trailer %%Pages: 1 end clear cleardictstack doretreesave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage %%EOF diff --git a/examples/escher.ps b/examples/escher.ps index 9a01f4ff..17c95345 100644 --- a/examples/escher.ps +++ b/examples/escher.ps @@ -378,7 +378,7 @@ N neg 1 N { } for } for -showpage - clear cleardictstack eschersave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage diff --git a/examples/golfer.eps b/examples/golfer.eps index 5b136e4b..be8719c4 100644 --- a/examples/golfer.eps +++ b/examples/golfer.eps @@ -1396,6 +1396,7 @@ s U %%Trailer _E end -showpage golfersave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage %%EOF diff --git a/examples/grayalph.ps b/examples/grayalph.ps index 2a834745..67aa2e61 100644 --- a/examples/grayalph.ps +++ b/examples/grayalph.ps @@ -60,6 +60,7 @@ end (a) show } for -showpage clear cleardictstack grayalphsave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage diff --git a/examples/snowflak.ps b/examples/snowflak.ps index cc4bbec2..00e621d5 100644 --- a/examples/snowflak.ps +++ b/examples/snowflak.ps @@ -93,7 +93,8 @@ inheight { boxsize inwidth mul neg boxsize translate } repeat - -showpage clear cleardictstack snowflaksave restore + +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage diff --git a/examples/tiger.eps b/examples/tiger.eps index f86aea3a..eebd7af5 100644 --- a/examples/tiger.eps +++ b/examples/tiger.eps @@ -2729,9 +2729,10 @@ S 322 466.5 310.5 453.5 v S -showpage - %%Trailer end tigersave restore + +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage %%EOF diff --git a/examples/vasarely.ps b/examples/vasarely.ps index 18c0429f..1b2207ac 100644 --- a/examples/vasarely.ps +++ b/examples/vasarely.ps @@ -583,6 +583,8 @@ def } def -page showpage +page clear cleardictstack vasarelysave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage diff --git a/examples/waterfal.ps b/examples/waterfal.ps index 2a7a481f..9fc3d19c 100644 --- a/examples/waterfal.ps +++ b/examples/waterfal.ps @@ -79,6 +79,7 @@ Fonts 6 array astore setmatrix } forall -showpage clear cleardictstack waterfalsave restore +% Per page independence description in the PLRM Section 3.7.3, showpage follows restore +showpage diff --git a/extract/COPYING b/extract/COPYING new file mode 100644 index 00000000..dba13ed2 --- /dev/null +++ b/extract/COPYING @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program 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 this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/extract/Makefile b/extract/Makefile new file mode 100644 index 00000000..a39d413a --- /dev/null +++ b/extract/Makefile @@ -0,0 +1,482 @@ +# Example commands: +# +# make +# make test +# Runs all tests. +# +# make test-exe +# Runs exe regression tests. These use $(gs) and $(mutool) to generate +# intermediate data about pdf content, then uses $(exe) to convert to +# docx. +# +# make test-mutool +# Runs mutool regression tests. This uses $(mutool) to convert directly +# from pdf to docx. We require that $(mutool) was built with extract=yes. +# +# make test-gs +# Runs gs regression tests. This uses $(gs) to convert directly from pdf +# to docx. We require that $(gs) was built with --with-extract-dir=... We +# also do a simple test of output-file-per-page. +# +# make test-buffer test-misc test-src +# Runs unit tests etc. +# +# make build=debug-opt ... +# Set build flags. +# +# make build=memento msqueeze +# Run memento squeeze test. + + +# Build flags. +# +# Note that OpenBSD's clang-8 appears to ignore -Wdeclaration-after-statement. +# +build = debug + +flags_link = -W -Wall -lm +flags_compile = -W -Wall -Wextra -Wpointer-sign -Wmissing-declarations -Wmissing-prototypes -Wdeclaration-after-statement -Wpointer-arith -Wconversion -Wno-sign-conversion -Werror -MMD -MP + +uname = $(shell uname) + +ifeq ($(build),) + $(error Need to specify build=debug|opt|debug-opt|memento) +else ifeq ($(build),debug) + flags_link += -g + flags_compile += -g +else ifeq ($(build),opt) + flags_link += -O2 + flags_compile += -O2 +else ifeq ($(build),debug-opt) + flags_link += -g -O2 + flags_compile += -g -O2 +else ifeq ($(build),memento) + flags_link += -g -dl + ifeq ($(uname),OpenBSD) + flags_link += -L /usr/local/lib -l execinfo + endif + flags_compile += -g -D MEMENTO +else + $(error unrecognised $$(build)=$(build)) +endif + + +# Locations of mutool and gs. By default we assume these are not available. +# +# If this extract checkout is within a mupdf tree (typically as a git +# submodule) we assume ghostpdl is checked out nearby and both mutool gs and gs +# binaries are available and built with extract enabled. +# +# Disable this by running: make we_are_mupdf_thirdparty= ... +# +we_are_mupdf_thirdparty = $(findstring /mupdf/thirdparty/extract, $(abspath .)) +ifneq ($(we_are_mupdf_thirdparty),) + $(warning we are mupdf thirdparty) + mutool := ../../build/debug-extract/mutool + gs := ../../../ghostpdl/debug-extract-bin/gs + libbacktrace = ../../../libbacktrace/.libs +endif + +# If mutool/gs are specified, they must exist. +# +ifneq ($(mutool),) +ifeq ($(wildcard $(mutool)),) + $(error mutool does not exist: $(mutool)) +endif +$(warning mutool=$(mutool)) +endif + +ifneq ($(gs),) +ifeq ($(wildcard $(gs)),) + $(error gs does not exist: $(gs)) +endif +$(warning gs=$(gs)) +endif + + +# Default target - run all tests. +# +test: test-buffer test-misc test-src test-exe test-mutool test-gs + @echo $@: passed + +# Define the main test targets. +# +# test/Python2clipped.pdf is same as test/Python2.pdf except it as a modified +# MediaBox that excludes some glyphs. +# +pdfs = test/Python2.pdf test/Python2clipped.pdf test/zlib.3.pdf test/text_graphic_image.pdf +pdfs_generated = $(patsubst test/%, test/generated/%, $(pdfs)) + +# Generate targets that check all combinations of mu/gs and the various +# rotate/autosplit options of extract-exe. +# +tests_exe := +ifneq ($(mutool),) + tests_exe := $(tests_exe) $(patsubst %, %.intermediate-mu.xml, $(pdfs_generated)) +endif +ifneq ($(gs),) + tests_exe := $(tests_exe) $(patsubst %, %.intermediate-gs.xml, $(pdfs_generated)) +endif + +tests_exe := \ + $(patsubst %, %.extract.docx, $(tests_exe)) \ + $(patsubst %, %.extract-rotate.docx, $(tests_exe)) \ + $(patsubst %, %.extract-rotate-spacing.docx, $(tests_exe)) \ + $(patsubst %, %.extract-autosplit.docx, $(tests_exe)) \ + $(patsubst %, %.extract-template.docx, $(tests_exe)) \ + +tests_exe := $(patsubst %, %.diff, $(tests_exe)) + +ifneq ($(mutool),) +# Targets that test direct conversion with mutool. +# + tests_mutool := \ + $(patsubst %, %.mutool.docx.diff, $(pdfs_generated)) \ + $(patsubst %, %.mutool-norotate.docx.diff, $(pdfs_generated)) \ + +endif +ifneq ($(gs),) +# Targets that test direct conversion with gs. +# + tests_gs := \ + $(patsubst %, %.gs.docx.diff, $(pdfs_generated)) \ + test_gs_fpp + + # We don't yet do clipping with gs so exclude Python2clipped.pdf.*: + tests_gs := $(filter-out test/generated/Python2clipped.pdf.%, $(tests_gs)) + + #$(warning tests_gs: $(tests_gs)) +endif +#$(warning $(pdfs_generated_intermediate_docx_diffs)) +#$(warning $(tests)) + +test-exe: $(tests_exe) + @echo $@: passed + +# Checks output of mutool conversion from .pdf to .docx. Requires that mutool +# was built with extract as a third-party library. +# +test-mutool: $(tests_mutool) + @echo $@: passed + +# Checks output of gs conversion from .pdf to .docx. Requires that mutool +# was built with extract as a third-party library. As of 2021-02-10 this +# requires, for example ghostpdl/extract being a link to an extract checkout +# and configuring with --with-extract-dir=extract. +# +test-gs: $(tests_gs) + @echo $@: passed + +# Check behaviour of gs when writing file-per-page. +# +test_gs_fpp: $(gs) + @echo + @echo == Testing gs file-page-page + rm test/generated/text_graphic_image.pdf.gs.*.docx || true + $(gs) -sDEVICE=docxwrite -o test/generated/Python2.pdf.gs.%i.docx test/Python2.pdf + rm test/generated/text_graphic_image.pdf.gs.*.docx || true + $(gs) -sDEVICE=docxwrite -o test/generated/zlib.3.pdf.gs.%i.docx test/zlib.3.pdf + rm test/generated/text_graphic_image.pdf.gs.*.docx || true + $(gs) -sDEVICE=docxwrite -o test/generated/text_graphic_image.pdf.gs.%i.docx test/text_graphic_image.pdf + @echo Checking for correct number of generated files. + ls -l test/generated/*.pdf.gs.*.docx + ls test/generated/text_graphic_image.pdf.gs.*.docx | wc -l | grep '^ *1$$' + ls test/generated/Python2.pdf.gs.*.docx | wc -l | grep '^ *1$$' + ls test/generated/zlib.3.pdf.gs.*.docx | wc -l | grep '^ *2$$' + + +# Main executable. +# +exe = src/build/extract-$(build).exe +exe_src = \ + src/alloc.c \ + src/astring.c \ + src/buffer.c \ + src/docx.c \ + src/docx_template.c \ + src/extract-exe.c \ + src/extract.c \ + src/join.c \ + src/mem.c \ + src/outf.c \ + src/xml.c src/zip.c \ + +ifeq ($(build),memento) + exe_src += src/memento.c + ifeq ($(uname),Linux) + flags_compile += -D HAVE_LIBDL + flags_link += -L $(libbacktrace) -l backtrace -l dl + endif +endif +exe_obj = $(patsubst src/%.c, src/build/%.c-$(build).o, $(exe_src)) +exe_dep = $(exe_obj:.o=.d) +exe: $(exe) +$(exe): $(exe_obj) + $(CC) $(flags_link) -o $@ $^ -lz -lm + +run_exe = $(exe) +ifeq ($(build),memento) + ifeq ($(uname),Linux) + run_exe = LD_LIBRARY_PATH=$(libbacktrace) MEMENTO_ABORT_ON_LEAK=1 MEMENTO_HIDE_MULTIPLE_REALLOCS=1 $(exe) + #run_exe = LD_LIBRARY_PATH=../libbacktrace/.libs $(exe) + endif + ifeq ($(uname),OpenBSD) + run_exe = MEMENTO_ABORT_ON_LEAK=1 $(exe) + endif +endif + + +# Rules that make the various intermediate targets required by $(tests). +# + +test/generated/%.pdf.intermediate-mu.xml: test/%.pdf $(mutool) + @echo + @echo == Generating intermediate file for $< with mutool. + @mkdir -p test/generated + $(mutool) draw -F xmltext -o $@ $< + +test/generated/%.pdf.intermediate-gs.xml: test/%.pdf $(gs) + @echo + @echo == Generating intermediate file for $< with gs. + @mkdir -p test/generated + $(gs) -sDEVICE=txtwrite -dTextFormat=4 -o $@ $< + +%.extract.docx: % $(exe) + @echo + @echo == Generating docx with extract.exe + $(run_exe) -r 0 -i $< -o $@ + +%.extract-rotate.docx: % $(exe) Makefile + @echo + @echo == Generating docx with rotation with extract.exe + $(run_exe) -r 1 -s 0 -i $< -o $@ + +%.extract-rotate-spacing.docx: % $(exe) Makefile + @echo + @echo == Generating docx with rotation with extract.exe + $(run_exe) -r 1 -s 1 -i $< -o $@ + +%.extract-autosplit.docx: % $(exe) + @echo + @echo == Generating docx with autosplit with extract.exe + $(run_exe) -r 0 -i $< --autosplit 1 -o $@ + +%.extract-template.docx: % $(exe) + @echo + @echo == Generating docx using src/template.docx with extract.exe + $(run_exe) -r 0 -i $< -t src/template.docx -o $@ + +test/generated/%.docx.diff: test/generated/%.docx.dir/ test/%.docx.dir.ref/ + @echo + @echo == Checking $< + diff -ru $^ + +# This checks that -t src/template.docx gives identical results. +# +test/generated/%.extract-template.docx.diff: test/generated/%.extract-template.docx.dir/ test/%.extract.docx.dir.ref/ + @echo + @echo == Checking $< + diff -ru $^ + +# Unzips .docx into .docx.dir/ directory. Note that we requires a trailing '/' +# in target. +# +%.docx.dir/: %.docx + @echo + @echo == Extracting .docx into directory. + @rm -r $@ 2>/dev/null || true + unzip -q -d $@ $< + +# Uses zip to create .docx file by zipping up a directory. Useful to recreate +# .docx from reference directory test/*.docx.dir.ref. +%.docx: % + @echo + @echo == Zipping directory into .docx file. + @rm -r $@ 2>/dev/null || true + cd $< && zip -r ../$(notdir $@) . + +# Prettifies each .xml file within .docx.dir/ directory. +%.docx.dir.pretty: %.docx.dir/ + @rm -r $@ $@- 2>/dev/null || true + cp -pr $< $@- + ./src/docx_template_build.py --docx-pretty $@- + mv $@- $@ + +# Converts .pdf directly to .docx using mutool. +test/generated/%.pdf.mutool.docx: test/%.pdf $(mutool) + @echo + @echo == Converting .pdf directly to .docx using mutool. + @mkdir -p test/generated + $(mutool) convert -O mediabox-clip=yes -o $@ $< + +test/generated/%.pdf.mutool-norotate.docx: test/%.pdf $(mutool) + @echo + @echo == Converting .pdf directly to .docx using mutool. + @mkdir -p test/generated + $(mutool) convert -O mediabox-clip=yes,rotation=no -o $@ $< + +test/generated/%.pdf.mutool-spacing.docx: test/%.pdf $(mutool) + @echo + @echo == Converting .pdf directly to .docx using mutool. + @mkdir -p test/generated + $(mutool) convert -O mediabox-clip=yes,spacing=yes -o $@ $< + +# Converts .pdf directly to .docx using gs. +test/generated/%.pdf.gs.docx: test/%.pdf $(gs) + @echo + @echo == Converting .pdf directly to .docx using gs. + @mkdir -p test/generated + $(gs) -sDEVICE=docxwrite -o $@ $< + + +# Valgrind test +# +valgrind: $(exe) test/generated/Python2.pdf.intermediate-mu.xml + valgrind --leak-check=full $(exe) -h -r 1 -s 0 -i test/generated/Python2.pdf.intermediate-mu.xml -o test/generated/valgrind-out.docx + @echo $@: passed + +# Memento tests. +# +ifeq ($(build),memento) +msqueeze: $(exe) test/generated/Python2.pdf.intermediate-mu.xml + MEMENTO_SQUEEZEAT=1 $(run_exe) --alloc-exp-min 0 -r 1 -s 0 -i test/generated/Python2.pdf.intermediate-mu.xml -o test/generated/msqueeze-out.docx 2>&1 | src/memento.py -q 1 -o msqueeze-raw + @echo $@: passed +mfailat: $(exe) test/generated/Python2.pdf.intermediate-mu.xml + MEMENTO_FAILAT=61463 $(run_exe) --alloc-exp-min 0 -r 1 -s 0 -i test/generated/Python2.pdf.intermediate-mu.xml -o test/generated/msqueeze-out.docx + @echo $@: passed +mutool_memento_extract = ../../build/memento-extract/mutool +msqueeze-mutool: + MEMENTO_SQUEEZEAT=1 $(mutool_memento_extract) convert -o test/generated/text_graphic_image.pdf.mutool.docx test/text_graphic_image.pdf 2>&1 | src/memento.py -q 1 -o msqueeze-raw +msqueeze-mutool2: + MEMENTO_SQUEEZEAT=1 $(mutool_memento_extract) convert -o test/generated/Python2.pdf.mutool.docx test/Python2.pdf 2>&1 | src/memento.py -q 1 -o msqueeze-raw +endif + + +# Temporary rules for generating reference files. +# +#temp_ersdr = \ +# $(patsubst %, %.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref, $(pdfs)) \ +# $(patsubst %, %.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref, $(pdfs)) \ +# +#temp: $(temp_ersdr) +#test/%.xml.extract-rotate-spacing.docx.dir.ref: test/generated/%.xml.extract-rotate-spacing.docx.dir +# @echo +# @echo copying $< to %@ +# rsync -ai $/dev/null || true + +# Cleans test/generated except for intermediate files, which are slow to create +# (when using gs). +clean2: + rm -r test/generated/*.pdf.intermediate-*.xml.* 2>/dev/null || true + rm -r test/generated/*.pdf.mutool*.docx* 2>/dev/null || true + rm -r src/build 2>/dev/null || true +.PHONY: clean + + +# Include dynamic dependencies. +# +# We use $(sort ...) to remove duplicates +# +dep = $(sort $(exe_dep) $(exe_buffer_test_dep) $(exe_misc_test_dep) $(exe_ziptest_dep)) + +-include $(dep) diff --git a/extract/README b/extract/README new file mode 100644 index 00000000..5917f045 --- /dev/null +++ b/extract/README @@ -0,0 +1,12 @@ +Directory tree: + + Makefile Builds and runs tests. + include/ Public API. + src/ Scripts, C implementattion and internal headers. + build/ Generated object files, executables etc. + test/ Test files. + generated/ Files generated by tests. + +Build and run tests with: + make + diff --git a/extract/include/extract.h b/extract/include/extract.h new file mode 100644 index 00000000..97f43cd6 --- /dev/null +++ b/extract/include/extract.h @@ -0,0 +1,212 @@ +#ifndef ARITFEX_EXTRACT_H +#define ARITFEX_EXTRACT_H + +#include "extract_alloc.h" +#include "extract_buffer.h" + + +/* Functions for creating docx archives. + +We can accept images and paragraphs of text from intermediate format data, for +example created by these commands: + + mutool draw -F xmltext ... + gs -sDEVICE=txtwrite -dTextFormat=4 ... + +Unless otherwise stated, all functions return 0 on success or -1 with errno +set. +*/ + + +typedef struct extract_t extract_t; +/* State for processing a document. */ + + +int extract_begin( + extract_alloc_t* alloc, + extract_t** pextract + ); +/* Creates a new extract_t* for use by other extract_*() functions. All +allocation will be done with (which can be NULL in which case we use +malloc/free, or from extract_alloc_create()). */ + + +int extract_read_intermediate( + extract_t* extract, + extract_buffer_t* buffer, + int autosplit + ); +/* Reads XML specification of spans and images from and adds to +. + +(Makes internal calls to extract_span_begin(), extract_add_image() etc.) */ + + +int extract_page_begin(extract_t* extract); +/* Must be called before extract_span_begin(). */ + + +int extract_span_begin( + extract_t* extract, + const char* font_name, + int font_bold, + int font_italic, + int wmode, + double ctm_a, + double ctm_b, + double ctm_c, + double ctm_d, + double ctm_e, + double ctm_f, + double trm_a, + double trm_b, + double trm_c, + double trm_d, + double trm_e, + double trm_f + ); +/* Starts a new span. +extract + As passed to earlier call to extract_begin(). +font_name + . +font_bold + 0 or 1. +font_italic + 0 or 1. +wmode + 0 or 1. +ctm_* + Matrix values. +trm_* + Matrix values. +*/ + + +int extract_add_char( + extract_t* extract, + double x, + double y, + unsigned ucs, + double adv, + int autosplit + ); +/* Appends specified character to current span. +extract + As passed to earlier call to extract_begin(). +autosplit +x +y + Position on page. +ucs + Unicode value. +adv + Advance of this character. +autosplit + If non-zero, we do additional splitting to stress the join algorithm. +*/ + + +int extract_span_end(extract_t* extract); +/* Must be called before starting a new span or ending current page. */ + + +typedef void (*extract_image_data_free)(void* handle, void* image_data); +/* Callback for freeing image data. See extract_add_image(). */ + + +int extract_add_image( + extract_t* extract, + const char* type, + double x, + double y, + double w, + double h, + char* data, + size_t data_size, + extract_image_data_free data_free, + void* data_free_handle + ); +/* Adds an image to the current page. + +type + E.g. 'png'. Is copied so need to persist after we return. +x y w h + Location and size of image. +data data_size + The raw image data. +data_free + If not NULL, extract code will call data_free(data) when it has finished + with . Otherwise the lifetime of is the responsibility of the + caller and it must persist for at least the lifetime of . +*/ + + +int extract_page_end(extract_t* extract); +/* Must be called to finish page started by extract_page_begin(). */ + + +int extract_process( + extract_t* extract, + int spacing, + int rotation, + int images + ); +/* Evaluates all un-processed pages to generate docx data and frees internal +page data (individual spans, lines, paragraphs etc). E.g. call this after +extract_page_end() to reduce internal data use. */ + + +int extract_write(extract_t* extract, extract_buffer_t* buffer); +/* Writes docx archive to buffer. The docx archive will contain text and images +from extract_process(). + +Uses an internal template docx archive. */ + + +int extract_write_content(extract_t* extract, extract_buffer_t* buffer); +/* Writes docx xml for paragraphs into buffer. + +(This is the xml containing paragraphs of text that is inserted into +the template word/document.xml object within the docx zip archive by +extract_write()). */ + + +int extract_write_template( + extract_t* extract, + const char* path_template, + const char* path_out, + int preserve_dir + ); +/* Like extract_write() but uses a provided template document. + +Uses the 'zip' and 'unzip' commands internally. + +extract: + . +path_template: + Name of docx file to use as a template. +path_out: + Name of docx file to create. Must not contain single-quote, double quote, + space or ".." sequence - these will force EINVAL error because they could + make internal shell commands unsafe. +preserve_dir: + If true, we don't delete the temporary directory .dir containing +*/ + + +void extract_end( extract_t** pextract); +/* Frees all data associated with *pextract and sets *pextract to NULL. */ + + +void extract_internal_end(void); +/* Cleans up internal singelton state that can look like a memory leak when +running under Memento or valgrind. */ + +void extract_exp_min(extract_t* extract, size_t size); +/* If size is non-zero, sets minimum actual allocation size, and we only +allocate in powers of two times this size. This is an attempt to improve speed +with memento squeeze. Default is 0 (every call to extract_realloc() calls +realloc(). */ + +#endif diff --git a/extract/include/extract_alloc.h b/extract/include/extract_alloc.h new file mode 100644 index 00000000..28a52a3c --- /dev/null +++ b/extract/include/extract_alloc.h @@ -0,0 +1,76 @@ +#ifndef EXTRACT_ALLOC_H +#define EXTRACT_ALLOC_H + +/* Allocation support. */ + +#include + +typedef void* (*extract_realloc_fn_t)(void* state, void* prev, size_t size); +/* An allocation function to be provided by user of the extract library. + +Should behave like realloc(), except for taking the additional 'void* state' +arg. */ + +typedef struct extract_alloc_t extract_alloc_t; +/* Abstract allocator, created by extract_alloc_create(). */ + +int extract_alloc_create(extract_realloc_fn_t realloc_fn, void* realloc_state, extract_alloc_t** palloc); +/* Creates a new extract_alloc_t* for use with extract_malloc() etc. */ + +void extract_alloc_destroy(extract_alloc_t** palloc); +/* Destroys an extract_alloc_t* that was created by extract_alloc_create(). + +Returns with *palloc set to NULL. Does nothing if *palloc is already NULL. */ + +int extract_malloc(extract_alloc_t* alloc, void** pptr, size_t size); +/* Sets *pptr to point to new allocated memory and returns 0. On error return +-1 with errno set and *pptr=NULL. + +Uses malloc() if is NULL, otherwise must have been created by +extract_alloc_create() and we use the extract_realloc_fn_t that was originally +passed to extract_alloc_create(). */ + +int extract_realloc(extract_alloc_t* alloc, void** pptr, size_t newsize); +/* Sets *pptr to point to reallocated memory and returns 0. On error return -1 +with errno set and *pptr=NULL. + +Uses realloc() if is NULL, otherwise must have been created by +extract_alloc_create() and we use the extract_realloc_fn_t that was originally +passed to extract_alloc_create(). */ + +void extract_free(extract_alloc_t* alloc, void** pptr); +/* Frees block pointed to by *pptr and sets *pptr to NULL. + +Uses free() if is NULL, otherwise must have been created by +extract_alloc_create() and we use the extract_realloc_fn_t that was originally +passed to extract_alloc_create(). */ + +#define extract_malloc(alloc, pptr, size) (extract_malloc)(alloc, (void**) pptr, size) +#define extract_realloc(alloc, pptr, newsize) (extract_realloc)(alloc, (void**) pptr, newsize) +#define extract_free(alloc, pptr) (extract_free)(alloc, (void**) pptr) +/* These allow callers to use any pointer type, not just void*. */ + +typedef struct +{ + int num_malloc; + int num_realloc; + int num_free; + int num_libc_realloc; +} extract_alloc_stats_t; + +extract_alloc_stats_t* extract_alloc_stats(extract_alloc_t* alloc); +/* Retrieve statistics. */ + +int extract_realloc2(extract_alloc_t* alloc, void** pptr, size_t oldsize, size_t newsize); +/* A realloc variant that takes the existing buffer size. + +If is not zero and *pptr is not NULL, must be the size of +the existing buffer and may used internally to over-allocate in order to avoid +too many calls to realloc(). See extract_alloc_exp_min() for more information. +*/ + +#define extract_realloc2(alloc, pptr, oldsize, newsize) (extract_realloc2)(alloc, (void**) pptr, oldsize, newsize) + +void extract_alloc_exp_min(extract_alloc_t* alloc, size_t size); + +#endif diff --git a/extract/include/extract_buffer.h b/extract/include/extract_buffer.h new file mode 100644 index 00000000..b0abbec3 --- /dev/null +++ b/extract/include/extract_buffer.h @@ -0,0 +1,278 @@ +#ifndef ARTIFEX_EXTRACT_BUFFER_H +#define ARTIFEX_EXTRACT_BUFFER_H + +#include "extract_alloc.h" + +#include + +/* Work around MSVS issues with our use of 'inline'. */ +#ifdef _MSC_VER + #include "extract_compat_inline.h" +#endif + +/* Reading and writing abstractions. + +We use inline code in the common case where reading or writing can be satisfied +using a cache. +*/ + + +typedef struct extract_buffer_t extract_buffer_t; +/* Abstract state for a buffer. */ + + +static inline int extract_buffer_read( + extract_buffer_t* buffer, + void* data, + size_t numbytes, + size_t* o_actual + ); +/* Reads specified number of bytes from buffer into data..+bytes, making multiple calls to +the underlying extract_buffer_fn_read function until we have read or reached +EOF. If we reach EOF, . Returns +1 if +short read due to EOF. + +buffer: + As returned by earlier call to extract_buffer_open(). +data: + Location of transferred data. +bytes: + Number of bytes transferred. +o_actual: + Optional out-param, set to actual number of bytes read. If we return zero + this will always be ; otherwise will be less than . + +For speed reasons, this is implemented in extract_buffer_impl.h and uses only +inline code if the requested data can be read from the cache. +*/ + + +static inline int extract_buffer_write( + extract_buffer_t* buffer, + const void* data, + size_t numbytes, + size_t* o_actual + ); +/* Writes specified data into buffer. Returns +1 if short write due to EOF. + +buffer: + As returned by earlier call to extract_buffer_open(). +data: + Location of source data. +bytes: + Number of bytes to copy. +out_actual: + Optional out-param, set to actual number of bytes written. If we return + zero this will always be ; otherwise will be less than + and can even be negative if internal cache-flush using fn_write() fails or + returns EOF. + +For speed reasons, this is implemented in extract_buffer_impl.h and uses only +inline code if there is space in the cache for the data. +*/ + + +size_t extract_buffer_pos(extract_buffer_t* buffer); +/* Returns number of bytes read or number of bytes written so far. */ + + +int extract_buffer_close(extract_buffer_t** io_buffer); +/* Closes down an extract_buffer_t and frees all internal resources. + +Can return error or +1 for EOF if write buffer and fn_write() fails when +flushing cache. + +Always sets *io_buffer to NULL. Does nothing if *io_buffer is already NULL. +*/ + + +typedef int (*extract_buffer_fn_read)(void* handle, void* destination, size_t numbytes, size_t* o_actual); +/* Callback used by read buffer. Should read data from buffer into the supplied +destination. Short reads are not an error. + +E.g. used to fill cache or to handle large reads. + +Should returns 0 on success (including short read or EOF) or -1 with errno set. + +handle: + As passed to extract_buffer_open(). +destination: + Start of destination. +bytes: + Number of bytes in destination. +o_actual: + Out-param, set to zero if EOF. Otherwise set to the number of bytes + transferred in the range 1.. inclusive. +*/ + +typedef int (*extract_buffer_fn_write)(void* handle, const void* source, size_t numbytes, size_t* o_actual); +/* Callback used by write buffer. Should write data from the supplied source +into the buffer; short writes are not an error. + +E.g. used to flush cache or to handle large writes. + +Should return 0 on success (including short write or EOF) or -1 with errno set. + +handle: + As passed to extract_buffer_open(). +source: + Start of source. +bytes: + Number of bytes in source. +o_actual: + Out-param, set to zero if EOF. Otherwise set to the number of bytes + transferred in the range 1.. inclusive. +*/ + +typedef int (*extract_buffer_fn_cache)(void* handle, void** o_cache, size_t* o_numbytes); +/* Callback to flush/populate cache. + +If the buffer is for writing: + Should return a memory region to which data can be written. Any data + written to a previous cache will have already been passed to fn_write() so + this can overlap or be the same as any previously-returned cache. + +If the buffer is for reading: + Should return a memory region containing more data to be read. All data in + any previously-returned cache has been read so this can overlap or be the + same as any previous cache. + +handle: + As passed to extract_buffer_open(). +o_data: + Out-param, set to point to new cache. +o_numbytes: + Out-param, set to size of new cache. + +If no data is available due to EOF, should return with *o_numbytes set to zero. +*/ + +typedef void (*extract_buffer_fn_close)(void* handle); +/* Called by extract_buffer_close(). + +handle: + As passed to extract_buffer_open(). +*/ + +extract_alloc_t* extract_buffer_alloc(extract_buffer_t* buffer); +/* Returns the extract_alloc_t* originally passed to extract_buffer_open*(). */ + + +int extract_buffer_open( + extract_alloc_t* alloc, + void* handle, + extract_buffer_fn_read fn_read, + extract_buffer_fn_write fn_write, + extract_buffer_fn_cache fn_cache, + extract_buffer_fn_close fn_close, + extract_buffer_t** o_buffer + ); +/* Creates an extract_buffer_t that uses specified callbacks. + +If fn_read is non-NULL the buffer is a read buffer, else if fn_write is +non-NULL the buffer is a write buffer. Passing non-NULL for both or neither is +not supported. + +alloc: + NULL or from extract_alloc_create(). Is only used to allocate the + extract_buffer_t returned in *o_buffer. +handle: + Passed to fn_read, fn_write, fn_cache and fn_close callbacks. +fn_read: + Callback for reading data. +fn_write: + Callback for writing data. +fn_cache: + Optional cache callback. +fn_close: + Optional close callback. +o_buffer: + Out-param. Set to NULL on error. +*/ + + +int extract_buffer_open_simple( + extract_alloc_t* alloc, + const void* data, + size_t numbytes, + void* handle, + extract_buffer_fn_close fn_close, + extract_buffer_t** o_buffer + ); +/* Creates an extract_buffer_t that reads from or writes to a single fixed +block of memory. + +The address region data..+data_length must exist for the lifetime of the +returned extract_buffer_t. + +alloc: + NULL or from extract_alloc_create(). Is only used to allocate the + extract_buffer_t returned in *o_buffer. +data: + Start of memory region. Note that if the extract_buffer_t is used as a + write buffer then data[] will be written-to, despite the 'const'. [This + use of const avoids the need for the caller to use a cast when creating a + read-buffer.] +bytes: + Size of memory region. +handle: + Passed to fn_close. +fn_close: + Optional callback called by extract_buffer_close(). E.g. could copy the + memory region elsewhere if the buffer was used as a write buffer. +o_buffer: + Out-param. +*/ + + +int extract_buffer_open_file( + extract_alloc_t* alloc, + const char* path, + int writable, + extract_buffer_t** o_buffer + ); +/* Creates a buffer that reads from, or writes to, a file. For portability +uses an internal FILE* rather than an integer file descriptor, so doesn't use +extract_buffer's caching support because FILE* already provides caching. + +path: + Path of file to read from. +writable: + We create read buffer if zero, else a write buffer. +o_buffer: + Out-param. Set to NULL on error. +*/ + + +typedef struct +{ + extract_buffer_t* buffer; + char* data; + size_t alloc_size; + size_t data_size; +} extract_buffer_expanding_t; +/* A write buffer that writes to an automatically-growing contiguous area of +memory. */ + +int extract_buffer_expanding_create( + extract_alloc_t* alloc, + extract_buffer_expanding_t* buffer_expanding + ); +/* Creates a writable buffer that writes into an automatically-growing +contiguous area of memory. + +alloc: + NULL or from extract_alloc_create(). +buffer_expanding: + Out-param; *buffer_expanding is initialised. + +Initialises buffer_expanding. buffer_expanding->buffer can be passed to +extract_buffer_*() functions. After buffer_close(), the written data is +available in buffer_expanding->data..+data_size, which will have been allocated +using . */ + + +/* Include implementations of inline-functions. */ +#include "extract_buffer_impl.h" + +#endif diff --git a/extract/include/extract_buffer_impl.h b/extract/include/extract_buffer_impl.h new file mode 100644 index 00000000..25f533dd --- /dev/null +++ b/extract/include/extract_buffer_impl.h @@ -0,0 +1,72 @@ +/* Implementation of inline functions. + +We expose some implementation details to allow extract_buffer_read() and +extract_buffer_write() to be inline; specifically we allow the compiler to +optimise the common case where reading/writing uses the cache only. */ + + +#include + +typedef struct +{ + void* cache; + size_t numbytes; + size_t pos; +} extract_buffer_cache_t; + + +int extract_buffer_read_internal( + extract_buffer_t* buffer, + void* data, + size_t numbytes, + size_t* o_actual + ); +/* Internal use only. */ + +static inline int extract_buffer_read( + extract_buffer_t* buffer, + void* data, + size_t numbytes, + size_t* o_actual + ) +{ + extract_buffer_cache_t* cache = (void*) buffer; + if (cache->numbytes - cache->pos < numbytes) { + /* Can't use just the cache. */ + return extract_buffer_read_internal(buffer, data, numbytes, o_actual); + } + /* We can use just the cache. */ + memcpy(data, (char*) cache->cache + cache->pos, numbytes); + cache->pos += numbytes; + if (o_actual) *o_actual = numbytes; + return 0; +} + + +int extract_buffer_write_internal( + extract_buffer_t* buffer, + const void* data, + size_t numbytes, + size_t* o_actual + ); +/* Internal use only. */ + +static inline int extract_buffer_write( + extract_buffer_t* buffer, + const void* data, + size_t numbytes, + size_t* o_actual + ) +{ + extract_buffer_cache_t* cache = (void*) buffer; + if (cache->numbytes - cache->pos < numbytes) { + /* Can't use just the cache. */ + return extract_buffer_write_internal(buffer, data, numbytes, o_actual); + } + /* We can use just the cache. */ + memcpy((char*) cache->cache + cache->pos, data, numbytes); + cache->pos += numbytes; + if (o_actual) *o_actual = numbytes; + return 0; +} + diff --git a/extract/include/extract_compat_inline.h b/extract/include/extract_compat_inline.h new file mode 100644 index 00000000..bb82ead2 --- /dev/null +++ b/extract/include/extract_compat_inline.h @@ -0,0 +1,15 @@ +#ifndef ARTIFEX_EXTRACT_COMPAT_INLINE +#define ARTIFEX_EXTRACT_COMPAT_INLINE + +#if !defined __cplusplus && defined(_MSC_VER) + #if (_MSC_VER < 1500) + /* inline and inline__ not available so remove all mention of + inline. This may result in warnings about unused static functions. */ + #define inline + #else + /* __inline is always available. */ + #define inline __inline + #endif +#endif + +#endif diff --git a/extract/src/alloc.c b/extract/src/alloc.c new file mode 100644 index 00000000..dee2f99a --- /dev/null +++ b/extract/src/alloc.c @@ -0,0 +1,120 @@ +#include "../include/extract_alloc.h" +#include "memento.h" + +#include +#include +#include +#include + + +struct extract_alloc_t +{ + extract_realloc_fn_t realloc_fn; + void* realloc_state; + size_t exp_min_alloc_size; + extract_alloc_stats_t stats; +}; + +int extract_alloc_create(extract_realloc_fn_t realloc_fn, void* realloc_state, extract_alloc_t** palloc) +{ + assert(realloc_fn); + assert(palloc); + *palloc = realloc_fn(realloc_state, NULL /*ptr*/, sizeof(**palloc)); + if (!*palloc) { + errno = ENOMEM; + return -1; + } + memset(*palloc, 0, sizeof(**palloc)); + (*palloc)->realloc_fn = realloc_fn; + (*palloc)->realloc_state = realloc_state; + (*palloc)->exp_min_alloc_size = 0; + return 0; +} + +void extract_alloc_destroy(extract_alloc_t** palloc) +{ + if (!*palloc) return; + (*palloc)->realloc_fn((*palloc)->realloc_state, *palloc, 0 /*newsize*/); + *palloc = NULL; +} + +extract_alloc_stats_t* extract_alloc_stats(extract_alloc_t* alloc) +{ + return &alloc->stats; +} + +static size_t round_up(extract_alloc_t* alloc, size_t n) +{ + if (alloc && alloc->exp_min_alloc_size) { + /* Round up to power of two. */ + size_t ret; + if (n==0) return 0; + ret = alloc->exp_min_alloc_size; + for(;;) { + size_t ret_old; + if (ret >= n) return ret; + ret_old = ret; + ret *= 2; + assert(ret > ret_old); + (void) ret_old; + } + } + else { + return n; + } +} + +int (extract_malloc)(extract_alloc_t* alloc, void** pptr, size_t size) +{ + void* p; + size = round_up(alloc, size); + p = (alloc) ? alloc->realloc_fn(alloc->realloc_state, NULL, size) : malloc(size); + *pptr = p; + if (!p && size) + { + if (alloc) errno = ENOMEM; + return -1; + } + if (alloc) alloc->stats.num_malloc += 1; + return 0; +} + +int (extract_realloc)(extract_alloc_t* alloc, void** pptr, size_t newsize) +{ + void* p = (alloc) ? alloc->realloc_fn(alloc->realloc_state, *pptr, newsize) : realloc(*pptr, newsize); + if (!p && newsize) + { + if (alloc) errno = ENOMEM; + return -1; + } + *pptr = p; + if (alloc) alloc->stats.num_realloc += 1; + return 0; +} + +int (extract_realloc2)(extract_alloc_t* alloc, void** pptr, size_t oldsize, size_t newsize) +{ + /* We ignore if is NULL - allows callers to not worry about + edge cases e.g. with strlen+1. */ + oldsize = (*pptr) ? round_up(alloc, oldsize) : 0; + newsize = round_up(alloc, newsize); + if (newsize == oldsize) return 0; + return (extract_realloc)(alloc, pptr, newsize); +} + +void (extract_free)(extract_alloc_t* alloc, void** pptr) +{ + if (alloc) { + (void) alloc->realloc_fn(alloc->realloc_state, *pptr, 0); + } + else { + free(*pptr); + } + *pptr = NULL; + if (alloc) alloc->stats.num_free += 1; +} + +void extract_alloc_exp_min(extract_alloc_t* alloc, size_t size) +{ + alloc->exp_min_alloc_size = size; +} diff --git a/extract/src/astring.c b/extract/src/astring.c new file mode 100644 index 00000000..1d273c9e --- /dev/null +++ b/extract/src/astring.c @@ -0,0 +1,41 @@ +#include "../include/extract_alloc.h" + +#include "astring.h" +#include "memento.h" + +#include +#include + + +void extract_astring_init(extract_astring_t* string) +{ + string->chars = NULL; + string->chars_num = 0; +} + +void extract_astring_free(extract_alloc_t* alloc, extract_astring_t* string) +{ + extract_free(alloc, &string->chars); + extract_astring_init(string); +} + + +int extract_astring_catl(extract_alloc_t* alloc, extract_astring_t* string, const char* s, size_t s_len) +{ + if (extract_realloc2(alloc, &string->chars, string->chars_num+1, string->chars_num + s_len + 1)) return -1; + memcpy(string->chars + string->chars_num, s, s_len); + string->chars[string->chars_num + s_len] = 0; + string->chars_num += s_len; + return 0; +} + +int extract_astring_catc(extract_alloc_t* alloc, extract_astring_t* string, char c) +{ + return extract_astring_catl(alloc, string, &c, 1); +} + +int extract_astring_cat(extract_alloc_t* alloc, extract_astring_t* string, const char* s) +{ + return extract_astring_catl(alloc, string, s, strlen(s)); +} + diff --git a/extract/src/astring.h b/extract/src/astring.h new file mode 100644 index 00000000..947e6587 --- /dev/null +++ b/extract/src/astring.h @@ -0,0 +1,23 @@ +#ifndef ARTIFEX_EXTRACT_AUTOSTRING_XML +#define ARTIFEX_EXTRACT_AUTOSTRING_XML + +/* Only for internal use by extract code. */ + +/* A simple string struct that reallocs as required. */ +typedef struct +{ + char* chars; /* NULL or zero-terminated. */ + size_t chars_num; /* Length of string pointed to by .chars. */ +} extract_astring_t; + +void extract_astring_init(extract_astring_t* string); + +void extract_astring_free(extract_alloc_t* alloc, extract_astring_t* string); + +int extract_astring_catl(extract_alloc_t* alloc, extract_astring_t* string, const char* s, size_t s_len); + +int extract_astring_catc(extract_alloc_t* alloc, extract_astring_t* string, char c); + +int extract_astring_cat(extract_alloc_t* alloc, extract_astring_t* string, const char* s); + +#endif diff --git a/extract/src/buffer-test.c b/extract/src/buffer-test.c new file mode 100644 index 00000000..6701fbab --- /dev/null +++ b/extract/src/buffer-test.c @@ -0,0 +1,306 @@ +#include "../include/extract_buffer.h" +#include "../include/extract_alloc.h" + +#include "mem.h" +#include "memento.h" +#include "outf.h" + +#include +#include +#include + + +static int rand_int(int max) +/* Returns random int from 0..max-1. */ +{ + return (int) (rand() / (RAND_MAX+1.0) * max); +} + + +/* Support for an extract_buffer_t that reads from / writes to a fixed block of +memory, with a fn_cache() that returns a randomly-sized cache each time it is +called, and read/write functions that do random short reads and writes. */ + +typedef struct +{ + extract_alloc_t* alloc; + char* data; + size_t bytes; /* Size of data[]. */ + size_t pos; /* Current position in data[]. */ + char cache[137]; + int num_calls_cache; + int num_calls_read; + int num_calls_write; +} mem_t; + +static int s_read(void* handle, void* destination, size_t bytes, size_t* o_actual) +/* Does a randomised short read. */ +{ + mem_t* r = handle; + size_t n = 91; + assert(bytes > 0); + r->num_calls_read += 1; + assert(r->pos <= r->bytes); + if (n > bytes) n = bytes; + if (n > r->bytes - r->pos) n = r->bytes - r->pos; + if (n) n = rand_int((int) n-1) + 1; + memcpy(destination, r->data + r->pos, n); + r->pos += n; + *o_actual = n; + return 0; +} + +static int s_read_cache(void* handle, void** o_cache, size_t* o_numbytes) +/* Returns a cache with randomised size. */ +{ + mem_t* r = handle; + int n; + r->num_calls_cache += 1; + *o_cache = r->cache; + n = (int) (r->bytes - r->pos); + if (n > (int) sizeof(r->cache)) n = sizeof(r->cache); + if (n) n = rand_int( n - 1) + 1; + memcpy(r->cache, r->data + r->pos, n); + r->pos += n; + *o_cache = r->cache; + *o_numbytes = n; + return 0; +} + +static void s_read_buffer_close(void* handle) +{ + mem_t* r = handle; + extract_free(r->alloc, &r->data); +} + +static void s_create_read_buffer(extract_alloc_t* alloc, int bytes, mem_t* r, extract_buffer_t** o_buffer) +/* Creates extract_buffer_t that reads from randomised data using randomised +short reads and cache with randomised sizes. */ +{ + int i; + int e; + if (extract_malloc(alloc, &r->data, bytes)) abort(); + for (i=0; idata[i] = (char) rand(); + } + r->alloc = alloc; + r->bytes = bytes; + r->pos = 0; + r->num_calls_cache = 0; + r->num_calls_read = 0; + r->num_calls_write = 0; + e = extract_buffer_open(alloc, r, s_read, NULL /*write*/, s_read_cache, s_read_buffer_close, o_buffer); + assert(!e); +} + +static void test_read(void) +{ + /* Create read buffer with randomised content. */ + int len = 12345; + mem_t r; + char* out_buffer; + int out_pos; + int its; + int e; + extract_buffer_t* buffer; + s_create_read_buffer(NULL /*alloc*/, len, &r, &buffer); + + /* Repeatedly read from read-buffer until we get EOF, and check we read the + original content. */ + if (extract_malloc(r.alloc, &out_buffer, len)) abort(); + out_pos = 0; + for (its=0;; ++its) { + size_t actual; + int n = rand_int(120)+1; + int e = extract_buffer_read(buffer, out_buffer + out_pos, n, &actual); + out_pos += (int) actual; + assert(out_pos == (int) extract_buffer_pos(buffer)); + if (e == 1) break; + assert(!e); + assert(!memcmp(out_buffer, r.data, out_pos)); + } + assert(out_pos == len); + assert(!memcmp(out_buffer, r.data, len)); + outf("its=%i num_calls_read=%i num_calls_write=%i num_calls_cache=%i", + its, r.num_calls_read, r.num_calls_write, r.num_calls_cache); + extract_free(r.alloc, &out_buffer); + out_buffer = NULL; + e = extract_buffer_close(&buffer); + assert(!e); + + outf("Read test passed.\n"); +} + + +static int s_write(void* handle, const void* source, size_t bytes, size_t* o_actual) +/* Does a randomised short write. */ +{ + mem_t* r = handle; + int n = 61; + r->num_calls_write += 1; + if (n > (int) bytes) n = (int) bytes; + if (n > (int) (r->bytes - r->pos)) n = (int) (r->bytes - r->pos); + assert(n); + n = rand_int((int) n-1) + 1; + memcpy(r->data + r->pos, source, n); + r->data[r->bytes] = 0; + r->pos += n; + *o_actual = n; + return 0; +} + +static int s_write_cache(void* handle, void** o_cache, size_t* o_numbytes) +/* Returns a cache with randomised size. */ +{ + mem_t* r = handle; + int n; + r->num_calls_cache += 1; + assert(r->bytes >= r->pos); + *o_cache = r->cache; + n = (int) (r->bytes - r->pos); + if (n > (int) sizeof(r->cache)) n = sizeof(r->cache); + if (n) n = rand_int( n - 1) + 1; + *o_cache = r->cache; + *o_numbytes = n; + /* We will return a zero-length cache at EOF. */ + return 0; +} + +static void s_write_buffer_close(void* handle) +{ + mem_t* mem = handle; + outf("*** freeing mem->data=%p", mem->data); + extract_free(mem->alloc, &mem->data); +} + +static void s_create_write_buffer(extract_alloc_t* alloc, size_t bytes, mem_t* r, extract_buffer_t** o_buffer) +/* Creates extract_buffer_t that reads from randomised data using randomised +short reads and cache with randomised sizes. */ +{ + int e; + if (extract_malloc(alloc, &r->data, bytes+1)) abort(); + extract_bzero(r->data, bytes); + r->alloc = alloc; + r->bytes = bytes; + r->pos = 0; + r->num_calls_cache = 0; + r->num_calls_read = 0; + r->num_calls_write = 0; + e = extract_buffer_open(r->alloc, r, NULL /*read*/, s_write, s_write_cache, s_write_buffer_close, o_buffer); + assert(!e); +} + + +static void test_write(void) +{ + /* Create write buffer. */ + size_t len = 12345; + mem_t r; + extract_buffer_t* buffer; + char* out_buffer; + unsigned i; + size_t out_pos = 0; + int its; + int e; + + s_create_write_buffer(NULL /*alloc*/, len, &r, &buffer); + + /* Write to read-buffer, and check it contains the original content. */ + if (extract_malloc(r.alloc, &out_buffer, len)) abort(); + for (i=0; i +#include +#include +#include +#include + + +struct extract_buffer_t +{ + /* First member must be extract_buffer_cache_t - required by inline + implementations of extract_buffer_read() and extract_buffer_write(). */ + extract_buffer_cache_t cache; + extract_alloc_t* alloc; + void* handle; + extract_buffer_fn_read fn_read; + extract_buffer_fn_write fn_write; + extract_buffer_fn_cache fn_cache; + extract_buffer_fn_close fn_close; + size_t pos; /* Does not include bytes currently read/written to cache. */ +}; + + +extract_alloc_t* extract_buffer_alloc(extract_buffer_t* buffer) +{ + return buffer->alloc; +} + + +int extract_buffer_open( + extract_alloc_t* alloc, + void* handle, + extract_buffer_fn_read fn_read, + extract_buffer_fn_write fn_write, + extract_buffer_fn_cache fn_cache, + extract_buffer_fn_close fn_close, + extract_buffer_t** o_buffer + ) +{ + int e = -1; + extract_buffer_t* buffer; + if (extract_malloc(alloc, &buffer, sizeof(*buffer))) goto end; + + buffer->alloc = alloc; + buffer->handle = handle; + buffer->fn_read = fn_read; + buffer->fn_write = fn_write; + buffer->fn_cache = fn_cache; + buffer->fn_close = fn_close; + buffer->cache.cache = NULL; + buffer->cache.numbytes = 0; + buffer->cache.pos = 0; + buffer->pos = 0; + e = 0; + + end: + if (e) { + extract_free(alloc, &buffer); + } + else { + *o_buffer = buffer; + } + return e; +} + + +size_t extract_buffer_pos(extract_buffer_t* buffer) +{ + size_t ret = buffer->pos; + if (buffer->cache.cache) { + ret += buffer->cache.pos; + } + return ret; +} + + +static int s_cache_flush(extract_buffer_t* buffer, size_t* o_actual) +/* Sends contents of cache to fn_write() using a loop to cope with short +writes. Returns with *o_actual containing the number of bytes successfully +sent, and buffer->cache.{cache,numbytes,pos} all set to zero. + +If we return zero but *actual is less than original buffer->cache.numbytes, +then fn_write returned EOF. */ +{ + int e = -1; + size_t p = 0; + assert(buffer->cache.pos <= buffer->cache.numbytes); + for(;;) { + size_t actual; + if (p == buffer->cache.pos) break; + if (buffer->fn_write( + buffer->handle, + (char*) buffer->cache.cache + p, + buffer->cache.pos - p, + &actual + )) goto end; + buffer->pos += actual; + p += actual; + if (actual == 0) { + /* EOF while flushing cache. We set to the number of bytes + in data..+numbytes that we know have been successfully handled by + buffer->fn_write(). This can be negative if we failed to flush + earlier data. */ + outf("*** buffer->fn_write() EOF\n"); + e = 0; + goto end; + } + } + outfx("cache flush, buffer->pos=%i p=%i buffer->cache.pos=%i\n", + buffer->pos, p, buffer->cache.pos); + assert(p == buffer->cache.pos); + buffer->cache.cache = NULL; + buffer->cache.numbytes = 0; + buffer->cache.pos = 0; + e = 0; + end: + + *o_actual = p; + return e; +} + +int extract_buffer_close(extract_buffer_t** p_buffer) +{ + extract_buffer_t* buffer = *p_buffer; + int e = -1; + + if (!buffer) { + return 0; + } + + if (buffer->cache.cache && buffer->fn_write) { + /* Flush cache. */ + size_t cache_bytes = buffer->cache.pos; + size_t actual; + if (s_cache_flush(buffer, &actual)) goto end; + if (actual != cache_bytes) { + e = +1; + goto end; + } + } + if (buffer->fn_close) buffer->fn_close(buffer->handle); + e = 0; + end: + extract_free(buffer->alloc, &buffer); + *p_buffer = NULL; + return e; +} + +static int s_simple_cache(void* handle, void** o_cache, size_t* o_numbytes) +{ + /* Indicate EOF. */ + (void) handle; + *o_cache = NULL; + *o_numbytes = 0; + return 0; +} + +int extract_buffer_open_simple( + extract_alloc_t* alloc, + const void* data, + size_t numbytes, + void* handle, + extract_buffer_fn_close fn_close, + extract_buffer_t** o_buffer + ) +{ + extract_buffer_t* buffer; + if (extract_malloc(alloc, &buffer, sizeof(*buffer))) return -1; + + /* We need cast away the const here. data[] will be written-to if caller + uses us as a write buffer. */ + buffer->alloc = alloc; + buffer->cache.cache = (void*) data; + buffer->cache.numbytes = numbytes; + buffer->cache.pos = 0; + buffer->handle = handle; + buffer->fn_read = NULL; + buffer->fn_write = NULL; + buffer->fn_cache = s_simple_cache; + buffer->fn_close = fn_close; + *o_buffer = buffer; + return 0; +} + + +/* Implementation of extract_buffer_file*. */ + +static int s_file_read(void* handle, void* data, size_t numbytes, size_t* o_actual) +{ + FILE* file = handle; + size_t n = fread(data, 1, numbytes, file); + outfx("file=%p numbytes=%i => n=%zi", file, numbytes, n); + assert(o_actual); /* We are called by other extract_buffer fns, not by user code. */ + *o_actual = n; + if (!n && ferror(file)) { + errno = EIO; + return -1; + } + return 0; +} + +static int s_file_write(void* handle, const void* data, size_t numbytes, size_t* o_actual) +{ + FILE* file = handle; + size_t n = fwrite(data, 1 /*size*/, numbytes /*nmemb*/, file); + outfx("file=%p numbytes=%i => n=%zi", file, numbytes, n); + assert(o_actual); /* We are called by other extract_buffer fns, not by user code. */ + *o_actual = n; + if (!n && ferror(file)) { + errno = EIO; + return -1; + } + return 0; +} + +static void s_file_close(void* handle) +{ + FILE* file = handle; + if (!file) return; + fclose(file); +} + +int extract_buffer_open_file(extract_alloc_t* alloc, const char* path, int writable, extract_buffer_t** o_buffer) +{ + int e = -1; + FILE* file = fopen(path, (writable) ? "wb" : "rb"); + if (!file) { + outf("failed to open '%s': %s", path, strerror(errno)); + goto end; + } + + if (extract_buffer_open( + alloc, + file /*handle*/, + writable ? NULL : s_file_read, + writable ? s_file_write : NULL, + NULL /*fn_cache*/, + s_file_close, + o_buffer + )) goto end; + e = 0; + + end: + if (e) { + if (file) fclose(file); + *o_buffer = NULL; + } + return e; +} + + +/* Support for read/write. */ + +int extract_buffer_read_internal( + extract_buffer_t* buffer, + void* destination, + size_t numbytes, + size_t* o_actual + ) +/* Called by extract_buffer_read() if not enough space in buffer->cache. */ +{ + int e = -1; + size_t pos = 0; /* Number of bytes read so far. */ + + /* In each iteration we either read from cache, or use buffer->fn_read() + directly or repopulate the cache. */ + for(;;) { + size_t n; + if (pos == numbytes) break; + n = buffer->cache.numbytes - buffer->cache.pos; + if (n) { + /* There is data in cache. */ + if (n > numbytes - pos) n = numbytes - pos; + memcpy((char*) destination + pos, (char*) buffer->cache.cache + buffer->cache.pos, n); + pos += n; + buffer->cache.pos += n; + } + else { + /* No data in cache. */ + int use_read = 0; + if (buffer->fn_read) { + if (!buffer->fn_cache) { + use_read = 1; + } + else if (buffer->cache.numbytes && numbytes - pos > buffer->cache.numbytes / 2) { + /* This read is large compared to previously-returned + cache size, so let's ignore buffer->fn_cache and use + buffer->fn_read() directly instead. */ + use_read = 1; + } + } + if (use_read) { + /* Use buffer->fn_read() directly, carrying on looping in case + of short read. */ + size_t actual; + outfx("using buffer->fn_read() directly for numbytes-pos=%i\n", numbytes-pos); + if (buffer->fn_read(buffer->handle, (char*) destination + pos, numbytes - pos, &actual)) goto end; + if (actual == 0) break; /* EOF. */ + pos += actual; + buffer->pos += actual; + } + else { + /* Repopulate cache. */ + outfx("using buffer->fn_cache() for buffer->cache.numbytes=%i\n", buffer->cache.numbytes); + if (buffer->fn_cache(buffer->handle, &buffer->cache.cache, &buffer->cache.numbytes)) goto end; + buffer->pos += buffer->cache.pos; + buffer->cache.pos = 0; + if (buffer->cache.numbytes == 0) break; /* EOF. */ + } + } + } + e = 0; + + end: + if (o_actual) *o_actual = pos; + if (e == 0 && pos != numbytes) return +1; /* EOF. */ + return e; +} + + +int extract_buffer_write_internal( + extract_buffer_t* buffer, + const void* source, + size_t numbytes, + size_t* o_actual + ) +{ + int e = -1; + size_t pos = 0; /* Number of bytes written so far. */ + + if (!buffer->fn_write) { + errno = EINVAL; + return -1; + } + + /* In each iteration we either write to cache, or use buffer->fn_write() + directly or flush the cache. */ + for(;;) { + size_t n; + outfx("numbytes=%i pos=%i. buffer->cache.numbytes=%i buffer->cache.pos=%i\n", + numbytes, pos, buffer->cache.numbytes, buffer->cache.pos); + if (pos == numbytes) break; + n = buffer->cache.numbytes - buffer->cache.pos; + if (n) { + /* There is space in cache for writing. */ + if (n > numbytes - pos) n = numbytes - pos; + outfx("writing to cache: numbytes=%i n=%i\n", numbytes, n); + memcpy((char*) buffer->cache.cache + buffer->cache.pos, (char*) source + pos, n); + pos += n; + buffer->cache.pos += n; + } + else { + /* No space left in cache. */ + int use_write = 0; + outfx("cache empty. pos=%i. buffer->cache.numbytes=%i buffer->cache.pos=%i\n", + pos, buffer->cache.numbytes, buffer->cache.pos); + { + /* Flush the cache. */ + size_t actual; + int ee; + size_t b = buffer->cache.numbytes; + ptrdiff_t delta; + ee = s_cache_flush(buffer, &actual); + assert(actual <= b); + delta = actual - b; + pos += delta; + buffer->pos += delta; + if (delta) { + /* We have only partially flushed the cache. This is + not recoverable. will be the number of bytes in + source..+numbytes that have been successfully flushed, and + could be negative if we failed to flush earlier data. */ + outf("failed to flush. actual=%i delta=%i\n", actual, delta); + e = 0; + goto end; + } + if (ee) goto end; + } + + if (!buffer->fn_cache) { + use_write = 1; + } + else if (buffer->cache.numbytes && numbytes - pos > buffer->cache.numbytes / 2) { + /* This write is large compared to previously-returned cache + size, so let's ignore the cache and call buffer->fn_write() + directly instead. */ + use_write = 1; + } + if (use_write) { + /* Use buffer->fn_write() directly, carrying on looping in case + of short write. */ + size_t actual; + if (buffer->fn_write(buffer->handle, (char*) source + pos, numbytes - pos, &actual)) goto end; + if (actual == 0) break; /* EOF. */ + outfx("direct write numbytes-pos=%i actual=%i buffer->pos=%i => %i\n", + numbytes-pos, actual, buffer->pos, buffer->pos + actual); + pos += actual; + buffer->pos += actual; + } + else { + /* Repopulate cache. */ + outfx("repopulating cache buffer->pos=%i", buffer->pos); + if (buffer->fn_cache(buffer->handle, &buffer->cache.cache, &buffer->cache.numbytes)) goto end; + buffer->cache.pos = 0; + if (buffer->cache.numbytes == 0) break; /* EOF. */ + } + } + } + e = 0; + + end: + if (o_actual) *o_actual = pos; + if (e == 0 && pos != numbytes) e = +1; /* EOF. */ + return e; +} + + +static int expanding_memory_buffer_write(void* handle, const void* source, size_t numbytes, size_t* o_actual) +{ + /* We realloc our memory region as required. For efficiency, we also use + any currently-unused region of our memory buffer as an extract_buffer + cache. So we can be called either to 'flush the cache' (in which case we + don't actually copy any data) or to accept data from somewhere else (in + which case we need to increase the size of our memory region. */ + extract_buffer_expanding_t* ebe = handle; + if ((char*) source >= ebe->data && (char*) source < ebe->data + ebe->alloc_size) { + /* Source is inside our memory region so we are being called by + extract_buffer_write_internal() to re-populate the cache. We don't + actually have to copy anything. */ + assert((size_t) ((char*) source - ebe->data) == ebe->data_size); + assert((size_t) ((char*) source - ebe->data + numbytes) <= ebe->alloc_size); + ebe->data_size += numbytes; + } + else { + /* Data is external, so copy into our buffer. We will have already been + called to flush the cache. */ + if (extract_realloc2(ebe->buffer->alloc, &ebe->data, ebe->alloc_size, ebe->data_size + numbytes)) return -1; + ebe->alloc_size = ebe->data_size + numbytes; + memcpy(ebe->data + ebe->data_size, source, numbytes); + ebe->data_size += numbytes; + } + *o_actual = numbytes; + return 0; +} + +static int expanding_memory_buffer_cache(void* handle, void** o_cache, size_t* o_numbytes) +{ + extract_buffer_expanding_t* ebe = handle; + size_t delta = 4096; + if (extract_realloc2(ebe->buffer->alloc, &ebe->data, ebe->alloc_size, ebe->data_size + delta)) return -1; + ebe->alloc_size = ebe->data_size + delta; + *o_cache = ebe->data + ebe->data_size; + *o_numbytes = delta; + return 0; +} + +int extract_buffer_expanding_create(extract_alloc_t* alloc, extract_buffer_expanding_t* ebe) +{ + ebe->data = NULL; + ebe->data_size = 0; + ebe->alloc_size = 0; + if (extract_buffer_open( + alloc, + ebe, + NULL /*fn_read*/, + expanding_memory_buffer_write, + expanding_memory_buffer_cache, + NULL /*fn_close*/, + &ebe->buffer + )) return -1; + return 0; +} diff --git a/extract/src/compat_stdint.h b/extract/src/compat_stdint.h new file mode 100644 index 00000000..174c72ae --- /dev/null +++ b/extract/src/compat_stdint.h @@ -0,0 +1,25 @@ +#ifndef ARTIFEX_EXTRACT_COMPAT_STDINT_H +#define ARTIFEX_EXTRACT_COMPAT_STDINT_H + +/* Fake what we need from stdint.h on MSVS. */ + +#if defined(_MSC_VER) && (_MSC_VER < 1700) /* MSVC older than VS2012 */ + typedef signed char int8_t; + typedef short int int16_t; + typedef int int32_t; + typedef __int64 int64_t; + typedef unsigned char uint8_t; + typedef unsigned short int uint16_t; + typedef unsigned int uint32_t; + typedef unsigned __int64 uint64_t; + #ifndef INT64_MAX + #define INT64_MAX 9223372036854775807i64 + #endif + #ifndef SIZE_MAX + #define SIZE_MAX ((size_t) -1) + #endif +#else + #include +#endif + +#endif diff --git a/extract/src/compat_strtoll.h b/extract/src/compat_strtoll.h new file mode 100644 index 00000000..76ed3530 --- /dev/null +++ b/extract/src/compat_strtoll.h @@ -0,0 +1,9 @@ +#ifndef ARTIFEX_EXTRACT_COMPAT_STRTOLL_H +#define ARTIFEX_EXTRACT_COMPAT_STRTOLL_H + +#if defined(_MSC_VER) && (_MSC_VER < 1800) /* MSVC older than VS2013 */ + #define strtoll( text, end, base) (long long) _strtoi64(text, end, base) + #define strtoull( text, end, base) (unsigned long long) _strtoi64(text, end, base) +#endif + +#endif diff --git a/extract/src/compat_va_copy.h b/extract/src/compat_va_copy.h new file mode 100644 index 00000000..9b9ae8dc --- /dev/null +++ b/extract/src/compat_va_copy.h @@ -0,0 +1,8 @@ +#ifndef ARTIFEX_EXTRACT_COMPAT_VA_COPY_H +#define ARTIFEX_EXTRACT_COMPAT_VA_COPY_H + +#if defined(_MSC_VER) && (_MSC_VER < 1800) /* MSVC older than VS2013 */ + #define va_copy(dst, src) ((dst) = (src)) +#endif + +#endif diff --git a/extract/src/document.h b/extract/src/document.h new file mode 100644 index 00000000..7a1470e4 --- /dev/null +++ b/extract/src/document.h @@ -0,0 +1,150 @@ +#ifndef ARTIFEX_EXTRACT_DOCUMENT_H +#define ARTIFEX_EXTRACT_DOCUMENT_H + +static const double pi = 3.141592653589793; + +typedef struct +{ + double x; + double y; +} point_t; + +typedef struct +{ + double a; + double b; + double c; + double d; + double e; + double f; +} matrix_t; + +double matrix_expansion(matrix_t m); + +int matrix_cmp4(const matrix_t* lhs, const matrix_t* rhs) +; +/* Returns zero if first four members of *lhs and *rhs are equal, otherwise ++/-1. */ + +typedef struct +{ + /* (x,y) before transformation by ctm and trm. */ + double pre_x; + double pre_y; + + /* (x,y) after transformation by ctm and trm. */ + double x; + double y; + + unsigned ucs; + double adv; +} char_t; +/* A single char in a span. +*/ + +typedef struct +{ + matrix_t ctm; + matrix_t trm; + char* font_name; + + /* font size is matrix_expansion(trm). */ + + struct { + unsigned font_bold : 1; + unsigned font_italic : 1; + unsigned wmode : 1; + }; + + char_t* chars; + int chars_num; +} span_t; +/* List of chars that have same font and are usually adjacent. */ + +char_t* span_char_last(span_t* span); +/* Returns last character in span. */ + +int span_append_c(extract_alloc_t* alloc, span_t* span, int c); +/* Appends new char_t to an span_t with .ucs=c and all other +fields zeroed. */ + +const char* span_string(extract_alloc_t* alloc, span_t* span); +/* Returns static string containing info about span_t. */ + +typedef struct +{ + span_t** spans; + int spans_num; +} line_t; +/* List of spans that are aligned on same line. */ + +span_t* line_span_first(line_t* line); +/* Returns first span in a line. */ + +span_t* line_span_last(line_t* line); +/* Returns last span in a line. */ + +typedef struct +{ + line_t** lines; + int lines_num; +} paragraph_t; +/* List of lines that are aligned and adjacent to each other so as to form a +paragraph. */ + +typedef struct +{ + char* type; /* jpg, png etc. */ + char* name; /* Name of image file within docx. */ + char* id; /* ID of image within docx. */ + char* data; + size_t data_size; + + extract_image_data_free data_free; + void* data_free_handle; + +} image_t; +/* Information about an image. is as passed to extract_add_image(); + and are created to be unique identifiers for use in generated docx +file. */ + +typedef struct +{ + span_t** spans; + int spans_num; + + image_t* images; + int images_num; + + line_t** lines; + int lines_num; + /* These refer to items in .spans. Initially empty, then set by + extract_join(). */ + + paragraph_t** paragraphs; + int paragraphs_num; + /* These refer to items in .lines. Initially empty, then set + by extract_join(). */ + +} page_t; +/* A page. Contains different representations of the list of spans. */ + +typedef struct +{ + page_t** pages; + int pages_num; +} document_t; +/* A list of pages. */ + + +typedef struct +{ + image_t* images; + int images_num; + char** imagetypes; + int imagetypes_num; +} images_t; + +int extract_document_join(extract_alloc_t* alloc, document_t* document); + +#endif diff --git a/extract/src/docx.c b/extract/src/docx.c new file mode 100644 index 00000000..238e81d4 --- /dev/null +++ b/extract/src/docx.c @@ -0,0 +1,1097 @@ +/* These extract_docx_*() functions generate docx content and docx zip archive +data. + +Caller must call things in a sensible order to create valid content - +e.g. don't call docx_paragraph_start() twice without intervening call to +docx_paragraph_finish(). */ + +#include "../include/extract.h" + +#include "docx_template.h" + +#include "astring.h" +#include "document.h" +#include "docx.h" +#include "mem.h" +#include "memento.h" +#include "outf.h" +#include "zip.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + + +static int extract_docx_paragraph_start(extract_alloc_t* alloc, extract_astring_t* content) +{ + return extract_astring_cat(alloc, content, "\n\n"); +} + +static int extract_docx_paragraph_finish(extract_alloc_t* alloc, extract_astring_t* content) +{ + return extract_astring_cat(alloc, content, "\n"); +} + +static int extract_docx_run_start( + extract_alloc_t* alloc, + extract_astring_t* content, + const char* font_name, + double font_size, + int bold, + int italic + ) +/* Starts a new run. Caller must ensure that extract_docx_run_finish() was +called to terminate any previous run. */ +{ + int e = 0; + if (!e) e = extract_astring_cat(alloc, content, "\n"); + if (!e && bold) e = extract_astring_cat(alloc, content, ""); + if (!e && italic) e = extract_astring_cat(alloc, content, ""); + { + char font_size_text[32]; + if (0) font_size = 10; + + if (!e) e = extract_astring_cat(alloc, content, ""); + + if (!e) e = extract_astring_cat(alloc, content, ""); + } + if (!e) e = extract_astring_cat(alloc, content, ""); + return e; + +} + +static int extract_docx_run_finish(extract_alloc_t* alloc, extract_astring_t* content) +{ + return extract_astring_cat(alloc, content, ""); +} + +static int extract_docx_char_append_string(extract_alloc_t* alloc, extract_astring_t* content, const char* text) +{ + return extract_astring_cat(alloc, content, text); +} + +static int extract_docx_char_append_stringf(extract_alloc_t* alloc, extract_astring_t* content, const char* format, ...) +{ + char* buffer = NULL; + int e; + va_list va; + va_start(va, format); + e = extract_vasprintf(alloc, &buffer, format, va); + va_end(va); + if (e < 0) return e; + e = extract_astring_cat(alloc, content, buffer); + extract_free(alloc, &buffer); + return e; +} + +static int extract_docx_char_append_char(extract_alloc_t* alloc, extract_astring_t* content, char c) +{ + return extract_astring_catc(alloc, content, c); +} + +static int extract_docx_paragraph_empty(extract_alloc_t* alloc, extract_astring_t* content) +/* Append an empty paragraph to *content. */ +{ + int e = -1; + if (extract_docx_paragraph_start(alloc, content)) goto end; + /* It seems like our choice of font size here doesn't make any difference + to the ammount of vertical space, unless we include a non-space + character. Presumably something to do with the styles in the template + document. */ + if (extract_docx_run_start( + alloc, + content, + "OpenSans", + 10 /*font_size*/, + 0 /*font_bold*/, + 0 /*font_italic*/ + )) goto end; + //docx_char_append_string(content, " "); /*   is non-break space. */ + if (extract_docx_run_finish(alloc, content)) goto end; + if (extract_docx_paragraph_finish(alloc, content)) goto end; + e = 0; + end: + return e; +} + + +/* Removes last chars. */ +static int docx_char_truncate(extract_astring_t* content, int len) +{ + assert((size_t) len <= content->chars_num); + content->chars_num -= len; + content->chars[content->chars_num] = 0; + return 0; +} + +static int extract_docx_char_truncate_if(extract_astring_t* content, char c) +/* Removes last char if it is . */ +{ + if (content->chars_num && content->chars[content->chars_num-1] == c) { + docx_char_truncate(content, 1); + } + return 0; +} + + +static double matrices_to_font_size(matrix_t* ctm, matrix_t* trm) +{ + double font_size = matrix_expansion(*trm) + * matrix_expansion(*ctm); + /* Round font_size to nearest 0.01. */ + font_size = (double) (int) (font_size * 100.0f + 0.5f) / 100.0f; + return font_size; +} + +typedef struct +{ + const char* font_name; + double font_size; + int font_bold; + int font_italic; + matrix_t* ctm_prev; +} content_state_t; +/* Used to keep track of font information when writing paragraphs of docx +content, e.g. so we know whether a font has changed so need to start a new docx +span. */ + + +static int extract_document_to_docx_content_paragraph( + extract_alloc_t* alloc, + content_state_t* state, + paragraph_t* paragraph, + extract_astring_t* content + ) +/* Append docx xml for to . Updates *state if we change +font. */ +{ + int e = -1; + int l; + if (extract_docx_paragraph_start(alloc, content)) goto end; + + for (l=0; llines_num; ++l) { + line_t* line = paragraph->lines[l]; + int s; + for (s=0; sspans_num; ++s) { + int si; + span_t* span = line->spans[s]; + double font_size_new; + state->ctm_prev = &span->ctm; + font_size_new = matrices_to_font_size(&span->ctm, &span->trm); + if (!state->font_name + || strcmp(span->font_name, state->font_name) + || span->font_bold != state->font_bold + || span->font_italic != state->font_italic + || font_size_new != state->font_size + ) { + if (state->font_name) { + if (extract_docx_run_finish(alloc, content)) goto end; + } + state->font_name = span->font_name; + state->font_bold = span->font_bold; + state->font_italic = span->font_italic; + state->font_size = font_size_new; + if (extract_docx_run_start( + alloc, + content, + state->font_name, + state->font_size, + state->font_bold, + state->font_italic + )) goto end; + } + + for (si=0; sichars_num; ++si) { + char_t* char_ = &span->chars[si]; + int c = char_->ucs; + + if (0) {} + + /* Escape XML special characters. */ + else if (c == '<') extract_docx_char_append_string(alloc, content, "<"); + else if (c == '>') extract_docx_char_append_string(alloc, content, ">"); + else if (c == '&') extract_docx_char_append_string(alloc, content, "&"); + else if (c == '"') extract_docx_char_append_string(alloc, content, """); + else if (c == '\'') extract_docx_char_append_string(alloc, content, "'"); + + /* Expand ligatures. */ + else if (c == 0xFB00) { + if (extract_docx_char_append_string(alloc, content, "ff")) goto end; + } + else if (c == 0xFB01) { + if (extract_docx_char_append_string(alloc, content, "fi")) goto end; + } + else if (c == 0xFB02) { + if (extract_docx_char_append_string(alloc, content, "fl")) goto end; + } + else if (c == 0xFB03) { + if (extract_docx_char_append_string(alloc, content, "ffi")) goto end; + } + else if (c == 0xFB04) { + if (extract_docx_char_append_string(alloc, content, "ffl")) goto end; + } + + /* Output ASCII verbatim. */ + else if (c >= 32 && c <= 127) { + if (extract_docx_char_append_char(alloc, content, (char) c)) goto end; + } + + /* Escape all other characters. */ + else { + char buffer[32]; + snprintf(buffer, sizeof(buffer), "&#x%x;", c); + if (extract_docx_char_append_string(alloc, content, buffer)) goto end; + } + } + /* Remove any trailing '-' at end of line. */ + if (extract_docx_char_truncate_if(content, '-')) goto end; + } + } + if (state->font_name) { + if (extract_docx_run_finish(alloc, content)) goto end; + state->font_name = NULL; + } + if (extract_docx_paragraph_finish(alloc, content)) goto end; + + e = 0; + + end: + return e; +} + +static int extract_document_append_image( + extract_alloc_t* alloc, + extract_astring_t* content, + image_t* image + ) +/* Write reference to image into docx content. */ +{ + extract_docx_char_append_string(alloc, content, "\n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_stringf(alloc, content," \n", image->id); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + //extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, "\n"); + return 0; +} + + +static int extract_document_output_rotated_paragraphs( + extract_alloc_t* alloc, + page_t* page, + int paragraph_begin, + int paragraph_end, + int rot, + int x, + int y, + int w, + int h, + int text_box_id, + extract_astring_t* content, + content_state_t* state + ) +/* Writes paragraph to content inside rotated text box. */ +{ + int e = 0; + int p; + outf("x,y=%ik,%ik = %i,%i", x/1000, y/1000, x, y); + extract_docx_char_append_string(alloc, content, "\n"); + extract_docx_char_append_string(alloc, content, "\n"); + extract_docx_char_append_string(alloc, content, "\n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_stringf(alloc, content," %i\n", x); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_stringf(alloc, content," %i\n", y); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_stringf(alloc, content," \n", w, h); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_stringf(alloc, content," \n", text_box_id, text_box_id); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_stringf(alloc, content," \n", rot); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + + /* Give box a solid background. */ + if (0) { + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + } + + /* Draw line around box. */ + if (0) { + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + } + + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " "); + + #if 0 + if (0) { + /* Output inline text describing the rotation. */ + extract_docx_char_append_stringf(content, "\n" + "*** rotate: %f rad, %f deg. rot=%i\n" + "\n", + rotate, + rotate * 180 / pi, + rot + ); + } + #endif + + /* Output paragraphs p0..p2-1. */ + for (p=paragraph_begin; pparagraphs[p]; + if (extract_document_to_docx_content_paragraph(alloc, state, paragraph, content)) goto end; + } + + extract_docx_char_append_string(alloc, content, "\n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + + /* This fallback is copied from a real Word document. Not sure + whether it works - both Libreoffice and Word use the above + choice. */ + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_stringf(alloc, content," \n", text_box_id); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " "); + + for (p=paragraph_begin; pparagraphs[p]; + if (extract_document_to_docx_content_paragraph(alloc, state, paragraph, content)) goto end; + } + + extract_docx_char_append_string(alloc, content, "\n"); + extract_docx_char_append_string(alloc, content, "\n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, " \n"); + extract_docx_char_append_string(alloc, content, ""); + e = 0; + end: + return e; +} + + +int extract_document_to_docx_content( + extract_alloc_t* alloc, + document_t* document, + int spacing, + int rotation, + int images, + extract_astring_t* content + ) +{ + int ret = -1; + int text_box_id = 0; + int p; + + /* Write paragraphs into . */ + for (p=0; ppages_num; ++p) { + page_t* page = document->pages[p]; + int p; + content_state_t state; + state.font_name = NULL; + state.font_size = 0; + state.font_bold = 0; + state.font_italic = 0; + state.ctm_prev = NULL; + + for (p=0; pparagraphs_num; ++p) { + paragraph_t* paragraph = page->paragraphs[p]; + const matrix_t* ctm = ¶graph->lines[0]->spans[0]->ctm; + double rotate = atan2(ctm->b, ctm->a); + + if (spacing + && state.ctm_prev + && paragraph->lines_num + && paragraph->lines[0]->spans_num + && matrix_cmp4( + state.ctm_prev, + ¶graph->lines[0]->spans[0]->ctm + ) + ) { + /* Extra vertical space between paragraphs that were at + different angles in the original document. */ + if (extract_docx_paragraph_empty(alloc, content)) goto end; + } + + if (spacing) { + /* Extra vertical space between paragraphs. */ + if (extract_docx_paragraph_empty(alloc, content)) goto end; + } + + if (rotation && rotate != 0) { + + /* Find extent of paragraphs with this same rotation. extent + will contain max width and max height of paragraphs, in units + before application of ctm, i.e. before rotation. */ + point_t extent = {0, 0}; + int p0 = p; + int p1; + + outf("rotate=%.2frad=%.1fdeg ctm: ef=(%f %f) abcd=(%f %f %f %f)", + rotate, rotate * 180 / pi, + ctm->e, + ctm->f, + ctm->a, + ctm->b, + ctm->c, + ctm->d + ); + + { + /* We assume that first span is at origin of text + block. This assumes left-to-right text. */ + double rotate0 = rotate; + const matrix_t* ctm0 = ctm; + point_t origin = { + paragraph->lines[0]->spans[0]->chars[0].x, + paragraph->lines[0]->spans[0]->chars[0].y + }; + matrix_t ctm_inverse = {1, 0, 0, 1, 0, 0}; + double ctm_det = ctm->a*ctm->d - ctm->b*ctm->c; + if (ctm_det != 0) { + ctm_inverse.a = +ctm->d / ctm_det; + ctm_inverse.b = -ctm->b / ctm_det; + ctm_inverse.c = -ctm->c / ctm_det; + ctm_inverse.d = +ctm->a / ctm_det; + } + else { + outf("cannot invert ctm=(%f %f %f %f)", + ctm->a, ctm->b, ctm->c, ctm->d); + } + + for (p=p0; pparagraphs_num; ++p) { + paragraph = page->paragraphs[p]; + ctm = ¶graph->lines[0]->spans[0]->ctm; + rotate = atan2(ctm->b, ctm->a); + if (rotate != rotate0) { + break; + } + + /* Update . */ + { + int l; + for (l=0; llines_num; ++l) { + line_t* line = paragraph->lines[l]; + span_t* span = line_span_last(line); + char_t* char_ = span_char_last(span); + double adv = char_->adv * matrix_expansion(span->trm); + double x = char_->x + adv * cos(rotate); + double y = char_->y + adv * sin(rotate); + + double dx = x - origin.x; + double dy = y - origin.y; + + /* Position relative to origin and before box rotation. */ + double xx = ctm_inverse.a * dx + ctm_inverse.b * dy; + double yy = ctm_inverse.c * dx + ctm_inverse.d * dy; + yy = -yy; + if (xx > extent.x) extent.x = xx; + if (yy > extent.y) extent.y = yy; + if (0) outf("rotate=%f p=%i: origin=(%f %f) xy=(%f %f) dxy=(%f %f) xxyy=(%f %f) span: %s", + rotate, p, origin.x, origin.y, x, y, dx, dy, xx, yy, span_string(alloc, span)); + } + } + } + p1 = p; + rotate = rotate0; + ctm = ctm0; + outf("rotate=%f p0=%i p1=%i. extent is: (%f %f)", + rotate, p0, p1, extent.x, extent.y); + } + + /* Paragraphs p0..p1-1 have same rotation. We output them into + a single rotated text box. */ + + /* We need unique id for text box. */ + text_box_id += 1; + + { + /* Angles are in units of 1/60,000 degree. */ + int rot = (int) (rotate * 180 / pi * 60000); + + /* about the middle. */ + double point_to_emu = 12700; /* https://en.wikipedia.org/wiki/Office_Open_XML_file_formats#DrawingML */ + int x = (int) (ctm->e * point_to_emu); + int y = (int) (ctm->f * point_to_emu); + int w = (int) (extent.x * point_to_emu); + int h = (int) (extent.y * point_to_emu); + int dx; + int dy; + + if (0) outf("rotate: %f rad, %f deg. rot=%i", rotate, rotate*180/pi, rot); + + h *= 2; + /* We can't predict how much space Word will actually + require for the rotated text, so make the box have the + original width but allow text to take extra vertical + space. There doesn't seem to be a way to make the text box + auto-grow to contain the text. */ + + dx = (int) ((1-cos(rotate)) * w / 2.0 + sin(rotate) * h / 2.0); + dy = (int) ((cos(rotate)-1) * h / 2.0 + sin(rotate) * w / 2.0); + outf("ctm->e,f=%f,%f rotate=%f => x,y=%ik %ik dx,dy=%ik %ik", + ctm->e, + ctm->f, + rotate * 180/pi, + x/1000, + y/1000, + dx/1000, + dy/1000 + ); + x -= dx; + y -= -dy; + + if (extract_document_output_rotated_paragraphs(alloc, page, p0, p1, rot, x, y, w, h, text_box_id, content, &state)) goto end; + } + p = p1 - 1; + //p = page->paragraphs_num - 1; + } + else { + if (extract_document_to_docx_content_paragraph(alloc, &state, paragraph, content)) goto end; + } + + } + + if (images) { + int i; + for (i=0; iimages_num; ++i) { + extract_document_append_image(alloc, content, &page->images[i]); + } + } + } + ret = 0; + + end: + + return ret; +} + + + +static int systemf(extract_alloc_t* alloc, const char* format, ...) +/* Like system() but takes printf-style format and args. Also, if we return +ve +we set errno to EIO. */ +{ + int e; + char* command; + va_list va; + va_start(va, format); + e = extract_vasprintf(alloc, &command, format, va); + va_end(va); + if (e < 0) return e; + outf("running: %s", command); + e = system(command); + extract_free(alloc, &command); + if (e > 0) { + errno = EIO; + } + return e; +} + +static int read_all(extract_alloc_t* alloc, FILE* in, char** o_out) +/* Reads until eof into zero-terminated malloc'd buffer. */ +{ + size_t len = 0; + size_t delta = 128; + for(;;) { + size_t n; + if (extract_realloc2(alloc, o_out, len, len + delta + 1)) { + extract_free(alloc, o_out); + return -1; + } + n = fread(*o_out + len, 1 /*size*/, delta /*nmemb*/, in); + len += n; + if (feof(in)) { + (*o_out)[len] = 0; + return 0; + } + if (ferror(in)) { + /* It's weird that fread() and ferror() don't set errno. */ + errno = EIO; + extract_free(alloc, o_out); + return -1; + } + } +} + +static int read_all_path(extract_alloc_t* alloc, const char* path, char** o_text) +/* Reads entire file into zero-terminated malloc'd buffer. */ +{ + int e = -1; + FILE* f = NULL; + f = fopen(path, "rb"); + if (!f) goto end; + if (read_all(alloc, f, o_text)) goto end; + e = 0; + end: + if (f) fclose(f); + if (e) extract_free(alloc, &o_text); + return e; +} + +static int write_all(const void* data, size_t data_size, const char* path) +{ + int e = -1; + FILE* f = fopen(path, "w"); + if (!f) goto end; + if (fwrite(data, data_size, 1 /*nmemb*/, f) != 1) goto end; + e = 0; + end: + if (f) fclose(f); + return e; +} + +static int extract_docx_content_insert( + extract_alloc_t* alloc, + const char* original, + const char* mid_begin_name, + const char* mid_end_name, + extract_astring_t* contentss, + int contentss_num, + char** o_out + ) +/* Creates a string consisting of with all strings in +inserted into 's ... region, and +appends this string to *o_out. */ +{ + int e = -1; + const char* mid_begin; + const char* mid_end; + extract_astring_t out; + extract_astring_init(&out); + + mid_begin = strstr(original, mid_begin_name); + if (!mid_begin) { + outf("error: could not find '%s' in docx content", + mid_begin_name); + errno = ESRCH; + goto end; + } + mid_begin += strlen(mid_begin_name); + + mid_end = strstr(mid_begin, mid_end_name); + if (!mid_end) { + outf("error: could not find '%s' in docx content", + mid_end_name); + errno = ESRCH; + goto end; + } + + if (extract_astring_catl(alloc, &out, original, mid_begin - original)) goto end; + { + int i; + for (i=0; i in , and *o_end to +beginning of first occurtence of in . */ +{ + *o_begin = strstr(text, begin); + if (!*o_begin) goto fail; + *o_begin += strlen(begin); + *o_end = strstr(*o_begin, end); + if (!*o_end) goto fail; + return 0; + fail: + errno = ESRCH; + return -1; +} + + +int extract_docx_content_item( + extract_alloc_t* alloc, + extract_astring_t* contentss, + int contentss_num, + images_t* images, + const char* name, + const char* text, + char** text2 + ) +{ + int e = -1; + extract_astring_t temp; + extract_astring_init(&temp); + *text2 = NULL; + + if (0) + {} + else if (!strcmp(name, "[Content_Types].xml")) { + /* Add information about all image types that we are going to use. */ + const char* begin; + const char* end; + const char* insert; + int it; + extract_astring_free(alloc, &temp); + outf("text: %s", text); + if (s_find_mid(text, "", &begin, &end)) goto end; + + insert = begin; + insert = strchr(insert, '>'); + assert(insert); + insert += 1; + + if (extract_astring_catl(alloc, &temp, text, insert - text)) goto end; + outf("images->imagetypes_num=%i", images->imagetypes_num); + for (it=0; itimagetypes_num; ++it) { + const char* imagetype = images->imagetypes[it]; + if (extract_astring_cat(alloc, &temp, "")) goto end; + } + if (extract_astring_cat(alloc, &temp, insert)) goto end; + *text2 = temp.chars; + extract_astring_init(&temp); + } + else if (!strcmp(name, "word/_rels/document.xml.rels")) { + /* Add relationships between image ids and image names within docx + archive. */ + const char* begin; + const char* end; + int j; + extract_astring_free(alloc, &temp); + if (s_find_mid(text, "", &begin, &end)) goto end; + if (extract_astring_catl(alloc, &temp, text, end - text)) goto end; + outf("images.images_num=%i", images->images_num); + for (j=0; jimages_num; ++j) { + image_t* image = &images->images[j]; + if (extract_astring_cat(alloc, &temp, "id)) goto end; + if (extract_astring_cat(alloc, &temp, "\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/")) goto end; + if (extract_astring_cat(alloc, &temp, image->name)) goto end; + if (extract_astring_cat(alloc, &temp, "\"/>")) goto end; + } + if (extract_astring_cat(alloc, &temp, end)) goto end; + *text2 = temp.chars; + extract_astring_init(&temp); + } + else if (!strcmp(name, "word/document.xml")) { + /* Insert paragraphs content. */ + if (extract_docx_content_insert( + alloc, + text, + "", + "", + contentss, + contentss_num, + text2 + )) goto end; + } + else { + *text2 = NULL; + } + e = 0; + end: + if (e) { + /* We might have set to new content. */ + extract_free(alloc, text2); + /* We might have used as a temporary buffer. */ + extract_astring_free(alloc, &temp); + } + extract_astring_init(&temp); + return e; +} + + + +static int check_path_shell_safe(const char* path) +/* Returns -1 with errno=EINVAL if contains sequences that could make it +unsafe in shell commands. */ +{ + if (0 + || strstr(path, "..") + || strchr(path, '\'') + || strchr(path, '"') + || strchr(path, ' ') + ) { + errno = EINVAL; + return -1; + } + return 0; +} + +static int remove_directory(extract_alloc_t* alloc, const char* path) +{ + if (check_path_shell_safe(path)) { + outf("path_out is unsafe: %s", path); + return -1; + } + return systemf(alloc, "rm -r '%s'", path); +} + +#ifdef _WIN32 +#include +static int s_mkdir(const char* path, int mode) +{ + (void) mode; + return _mkdir(path); +} +#else +static int s_mkdir(const char* path, int mode) +{ + return mkdir(path, mode); +} +#endif + + +int extract_docx_write_template( + extract_alloc_t* alloc, + extract_astring_t* contentss, + int contentss_num, + images_t* images, + const char* path_template, + const char* path_out, + int preserve_dir + ) +{ + int e = -1; + int i; + char* path_tempdir = NULL; + FILE* f = NULL; + char* path = NULL; + char* text = NULL; + char* text2 = NULL; + + assert(path_out); + assert(path_template); + + if (check_path_shell_safe(path_out)) { + outf("path_out is unsafe: %s", path_out); + goto end; + } + + outf("images->images_num=%i", images->images_num); + if (extract_asprintf(alloc, &path_tempdir, "%s.dir", path_out) < 0) goto end; + if (systemf(alloc, "rm -r '%s' 2>/dev/null", path_tempdir) < 0) goto end; + + if (s_mkdir(path_tempdir, 0777)) { + outf("Failed to create directory: %s", path_tempdir); + goto end; + } + + outf("Unzipping template document '%s' to tempdir: %s", + path_template, path_tempdir); + e = systemf(alloc, "unzip -q -d '%s' '%s'", path_tempdir, path_template); + if (e) { + outf("Failed to unzip %s into %s", + path_template, path_tempdir); + goto end; + } + + /* Might be nice to iterate through all items in path_tempdir, but for now + we look at just the items that we know extract_docx_content_item() will + modify. */ + + { + const char* names[] = { + "word/document.xml", + "[Content_Types].xml", + "word/_rels/document.xml.rels", + }; + int names_num = sizeof(names) / sizeof(names[0]); + for (i=0; i/media/. */ + extract_free(alloc, &path); + if (extract_asprintf(alloc, &path, "%s/word/media", path_tempdir) < 0) goto end; + if (s_mkdir(path, 0777)) goto end; + + for (i=0; iimages_num; ++i) { + image_t* image = &images->images[i]; + extract_free(alloc, &path); + if (extract_asprintf(alloc, &path, "%s/word/media/%s", path_tempdir, image->name) < 0) goto end; + if (write_all(image->data, image->data_size, path)) goto end; + } + + outf("Zipping tempdir to create %s", path_out); + { + const char* path_out_leaf = strrchr(path_out, '/'); + if (!path_out_leaf) path_out_leaf = path_out; + e = systemf(alloc, "cd '%s' && zip -q -r -D '../%s' .", path_tempdir, path_out_leaf); + if (e) { + outf("Zip command failed to convert '%s' directory into output file: %s", + path_tempdir, path_out); + goto end; + } + } + + if (!preserve_dir) { + if (remove_directory(alloc, path_tempdir)) goto end; + } + + e = 0; + + end: + outf("e=%i", e); + extract_free(alloc, &path_tempdir); + extract_free(alloc, &path); + extract_free(alloc, &text); + extract_free(alloc, &text2); + if (f) fclose(f); + + if (e) { + outf("Failed to create %s", path_out); + } + return e; +} diff --git a/extract/src/docx.h b/extract/src/docx.h new file mode 100644 index 00000000..6e26568f --- /dev/null +++ b/extract/src/docx.h @@ -0,0 +1,84 @@ +#ifndef ARTIFEX_EXTRACT_DOCX_H +#define ARTIFEX_EXTRACT_DOCX_H + +/* Only for internal use by extract code. */ + +/* Things for creating docx files. */ + +int extract_document_to_docx_content( + extract_alloc_t* alloc, + document_t* document, + int spacing, + int rotation, + int images, + extract_astring_t* content + ); +/* Makes *o_content point to a string containing all paragraphs in *document in +docx XML format. + +This string can be passed to extract_docx_content_item() or +extract_docx_write_template() to be inserted into a docx archive's +word/document.xml. */ + + +int extract_docx_write_template( + extract_alloc_t* alloc, + extract_astring_t* contentss, + int contentss_num, + images_t* images, + const char* path_template, + const char* path_out, + int preserve_dir + ); +/* Creates a new docx file using a provided template document. + +Uses the 'zip' and 'unzip' commands internally. + +contents +contentss_num + Content to be inserted into word/document.xml. +document + . +images + Information about images. +path_template + Name of docx file to use as a template. +path_out + Name of docx file to create. Must not contain single-quote, double quote, + space or ".." sequence - these will force EINVAL error because they could + make internal shell commands unsafe. +preserve_dir + If true, we don't delete the temporary directory .dir containing + unzipped docx content. +*/ + + +int extract_docx_content_item( + extract_alloc_t* alloc, + extract_astring_t* contentss, + int contentss_num, + images_t* images, + const char* name, + const char* text, + char** text2 + ); +/* Determines content of in docx archive. + +content +content_length + Text to insert if is word/document.xml. +images + Information about images. If is word/document.xml we insert + relationship information mapping from image ids to image names; + should already contain reference ids for images. If is + [Content_Types].xml we insert information about image types. +name + Path within the docx zip archive. +text + Content of in template docx file. +text2 + Out-param. Set to NULL if should be used unchanged. Otherwise set to + point to desired text, allocated with malloc() which caller should free. +*/ + +#endif diff --git a/extract/src/docx_template.c b/extract/src/docx_template.c new file mode 100644 index 00000000..73ab5b71 --- /dev/null +++ b/extract/src/docx_template.c @@ -0,0 +1,910 @@ +/* THIS IS AUTO-GENERATED CODE, DO NOT EDIT. */ + +#include "docx_template.h" + +const docx_template_item_t docx_template_items[] = +{ + { + "[Content_Types].xml", + "" + "\r\n" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + }, + + { + "_rels/.rels", + "" + "\r\n" + "" + "" + "" + "" + "" + }, + + { + "docProps/app.xml", + "" + "\r\n" + "" + "" + "" + "3" + "1" + "2" + "18" + "Microsoft Office Word" + "0" + "1" + "1" + "false" + "" + "false" + "19" + "false" + "false" + "16.0000" + }, + + { + "docProps/core.xml", + "" + "\r\n" + "" + "" + "" + "" + "" + "" + "" + "" + "1" + "2020-09-25T17:04:00Z" + "2020-09-25T17:07:00Z" + }, + + { + "word/document.xml", + "" + "\r\n" + "" + "" + "" + "" + "" + "Hello world" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "904875" + "" + "619125" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "Hello. Qwerty. World" + "" + "" + "" + "mupdf" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "Hello. Qwerty. World" + "" + "" + "" + "mupdf" + "" + "" + "qwerty" + "" + "" + "" + "" + "" + }, + + { + "word/fontTable.xml", + "" + "\r\n" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + }, + + { + "word/settings.xml", + "" + "\r\n" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + }, + + { + "word/styles.xml", + "" + "\r\n" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + }, + + { + "word/webSettings.xml", + "" + "\r\n" + "" + "" + "" + "" + }, + + { + "word/_rels/document.xml.rels", + "" + "\r\n" + "" + "" + "" + "" + "" + "" + "" + }, + + { + "word/theme/theme1.xml", + "" + "\r\n" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + }, + +}; + +int docx_template_items_num = 11; diff --git a/extract/src/docx_template.h b/extract/src/docx_template.h new file mode 100644 index 00000000..8a73d5b2 --- /dev/null +++ b/extract/src/docx_template.h @@ -0,0 +1,17 @@ +#ifndef EXTRACT_DOCX_TEMPLATE_H +#define EXTRACT_DOCX_TEMPLATE_H + +/* THIS IS AUTO-GENERATED CODE, DO NOT EDIT. */ + + +typedef struct +{ + const char* name; /* Name of item in docx archive. */ + const char* text; /* Contents of item in docx archive. */ +} docx_template_item_t; + +extern const docx_template_item_t docx_template_items[]; +extern int docx_template_items_num; + + +#endif diff --git a/extract/src/docx_template_build.py b/extract/src/docx_template_build.py new file mode 100755 index 00000000..b528bcb5 --- /dev/null +++ b/extract/src/docx_template_build.py @@ -0,0 +1,210 @@ +#! /usr/bin/env python3 + +''' +Creates C code for creating docx files using internal template docx content. + +Args: + + -i + Set template docx file to extract from. + + -o + Set name of output files. + + We write to .c and .h. +''' + +import io +import os +import re +import sys +import textwrap + + +def system(command): + ''' + Like os.system() but raises exception if command fails. + ''' + e = os.system(command) + if e: + print(f'command failed: {command}') + assert 0 + +def read(path): + ''' + Returns contents of file. We assume it is utf-8. + ''' + with open(path, 'rb') as f: + raw = f.read() + return raw.decode('utf-8') + +def write(text, path): + ''' + Writes text to file. + ''' + parent = os.path.dirname(path) + if parent: + os.makedirs(parent, exist_ok=True) + with open(path, 'w') as f: + f.write(text) + +def write_if_diff(text, path): + try: + old = read(path) + except Exception: + old = None + if text != old: + write(text, path) + +def check_path_safe(path): + ''' + Raises exception unless path consists only of characters and sequences that + are known to be safe for shell commands. + ''' + if '..' in path: + raise Exception(f'Path is unsafe because contains "..": {path!r}') + for c in path: + if not c.isalnum() and c not in '/._-': + #print(f'unsafe character {c} in: {path}') + raise Exception(f'Path is unsafe because contains "{c}": {path!r}') + +def path_safe(path): + ''' + Returns True if path is safe else False. + ''' + try: + check_path_safe(path) + except Exception: + return False + else: + return True + +assert not path_safe('foo;rm -rf *') +assert not path_safe('..') +assert path_safe('foo/bar.x') + + +def main(): + + path_in = None + path_out = None + args = iter(sys.argv[1:]) + while 1: + try: arg = next(args) + except StopIteration: break + if arg == '-h' or arg == '--help': + print(__doc__) + return + elif arg == '--docx-pretty': + d = next(args) + for dirpath, dirnames, filenames in os.walk(d): + for filename in filenames: + if not filename.endswith('.xml'): + continue + path = os.path.join(dirpath, filename) + system(f'xmllint --format {path} > {path}-') + system(f'mv {path}- {path}') + elif arg == '-i': + path_in = next(args) + elif arg == '-o': + path_out = next(args) + else: + assert 0 + + if not path_in: + return + + if not path_in: + raise Exception('Need to specify -i ') + if not path_out: + raise Exception('Need to specify -o ') + + check_path_safe(path_in) + check_path_safe(path_out) + path_temp = f'{path_in}.dir' + os.system(f'rm -r "{path_temp}" 2>/dev/null') + system(f'unzip -q -d {path_temp} {path_in}') + + out_c = io.StringIO() + out_c.write(f'/* THIS IS AUTO-GENERATED CODE, DO NOT EDIT. */\n') + out_c.write(f'\n') + out_c.write(f'#include "{os.path.basename(path_out)}.h"\n') + out_c.write(f'\n') + + + out_c.write('const docx_template_item_t docx_template_items[] =\n') + out_c.write(f'{{\n') + + num_items = 0 + for dirpath, dirnames, filenames in os.walk(path_temp): + dirnames.sort() + + if 0: + # Write code to create directory item in zip. This isn't recognised by zipinfo, and doesn't + # make Word like the file. + # + name = dirpath[ len(path_temp)+1: ] + if name: + if not name.endswith('/'): + name += '/' + out_c3.write(f' if (extract_zip_write_file(zip, NULL, 0, "{name}")) goto end;\n') + + for filename in sorted(filenames): + num_items += 1 + path = os.path.join(dirpath, filename) + name = path[ len(path_temp)+1: ] + text = read(os.path.join(dirpath, filename)) + #print(f'first line is: %r' % text.split("\n")[0]) + text = text.replace('"', '\\"') + + # Looks like template files use \r\n when we interpret them as + # utf-8, so we preserve this in the generated strings. + # + text = text.replace('\r\n', '\\r\\n"\n "') + + # Split on '<' to avoid overly-long lines, which break windows + # compiler. + # + text = re.sub('([<][^/])', '"\n "\\1', text) + + # Remove name of document creator. + # + for tag in 'dc:creator', 'cp:lastModifiedBy': + text = re.sub(f'[<]{tag}[>][^<]*[<]/{tag}[>]', f'<{tag}>', text) + + out_c.write(f' {{\n') + out_c.write(f' "{name}",\n') + out_c.write(f' "{text}"\n') + out_c.write(f' }},\n') + out_c.write(f' \n') + + out_c.write(f'}};\n') + out_c.write(f'\n') + out_c.write(f'int docx_template_items_num = {num_items};\n') + + out_c = out_c.getvalue() + write_if_diff(out_c, f'{path_out}.c') + + out_h = io.StringIO() + out_h.write(f'#ifndef EXTRACT_DOCX_TEMPLATE_H\n') + out_h.write(f'#define EXTRACT_DOCX_TEMPLATE_H\n') + out_h.write(f'\n') + out_h.write(f'/* THIS IS AUTO-GENERATED CODE, DO NOT EDIT. */\n') + out_h.write(f'\n') + out_h.write(f'\n') + out_h.write(f'typedef struct\n') + out_h.write(f'{{\n') + out_h.write(f' const char* name; /* Name of item in docx archive. */\n') + out_h.write(f' const char* text; /* Contents of item in docx archive. */\n') + out_h.write(f'}} docx_template_item_t;\n') + out_h.write(f'\n') + out_h.write(f'extern const docx_template_item_t docx_template_items[];\n') + out_h.write(f'extern int docx_template_items_num;\n') + out_h.write(f'\n') + out_h.write(f'\n') + out_h.write(f'#endif\n') + write_if_diff(out_h.getvalue(), f'{path_out}.h') + #os.system(f'rm -r "{path_temp}"') + +if __name__ == '__main__': + main() diff --git a/extract/src/extract-exe.c b/extract/src/extract-exe.c new file mode 100644 index 00000000..d3ac81d0 --- /dev/null +++ b/extract/src/extract-exe.c @@ -0,0 +1,244 @@ +/* Command-line programme for extract_ API. */ + +#include "../include/extract.h" +#include "../include/extract_alloc.h" + +#include "memento.h" +#include "outf.h" + +#include +#include +#include +#include +#include + + +/* Error-detecting equivalent to *out = argv[++i]. +*/ +static int arg_next_string(char** argv, int argc, int* i, const char** out) +{ + if (*i + 1 >= argc) { + printf("Expected arg after: %s\n", argv[*i]); + errno = EINVAL; + return -1; + } + *i += 1; + *out = argv[*i]; + return 0; +} + +/* Error-detecting equivalent to *out = atoi(argv[++i]). +*/ +static int arg_next_int(char** argv, int argc, int* i, int* out) +{ + if (*i + 1 >= argc) { + printf("Expected integer arg after: %s\n", argv[*i]); + errno = EINVAL; + return -1; + } + *i += 1; + *out = atoi(argv[*i]); + return 0; +} + +static void* s_realloc(void* state, void* prev, size_t size) +{ + assert(state == (void*) 123); + return realloc(prev, size); +} + +int main(int argc, char** argv) +{ + int e = -1; + const char* docx_out_path = NULL; + const char* input_path = NULL; + const char* docx_template_path = NULL; + const char* content_path = NULL; + int preserve_dir = 0; + int spacing = 1; + int rotation = 1; + int autosplit = 0; + int images = 1; + int alloc_stats = 0; + int i; + + extract_alloc_t* alloc = NULL; + extract_buffer_t* out_buffer = NULL; + extract_buffer_t* intermediate = NULL; + extract_t* extract = NULL; + + /* Create an allocator so we test the allocation code. */ + if (extract_alloc_create(s_realloc, (void*) 123, &alloc)) + { + assert(0); + } + + for (i=1; i\n" + " Internal: set exponential allocation with minimum alloc size.\n" + " --autosplit 0|1\n" + " If 1, we initially split spans when y coordinate changes. This\n" + " stresses our handling of spans when input is from mupdf.\n" + " -i \n" + " Path of XML file containing intermediate text spans.\n" + " -o \n" + " If specified, we generate the specified docx file.\n" + " --o-content \n" + " If specified, we write raw docx content to ; this is the\n" + " text that we embed inside the template word/document.xml file\n" + " when generating the docx file.\n" + " -p 0|1\n" + " If 1 and -t is specified, we preserve the\n" + " uncompressed .lib/ directory.\n" + " -r 0|1\n" + " If 1, we we output rotated text inside a rotated drawing. Otherwise\n" + " output text is always horizontal.\n" + " -s 0|1\n" + " If 1, we insert extra vertical space between paragraphs and extra\n" + " vertical space between paragraphs that had different ctm matrices\n" + " in the original document.\n" + " -t \n" + " If specified we use as template. Otheerwise we use" + " an internal template.\n" + " -v \n" + " Set verbose level.\n" + " -v-alloc\n" + " Show alloc stats.\n" + ); + if (i + 1 == argc) { + e = 0; + goto end; + } + } + else if (!strcmp(arg, "--alloc-exp-min")) { + int size; + if (arg_next_int(argv, argc, &i, &size)) goto end; + outf("Calling alloc_set_min_alloc_size(%i)", size); + extract_exp_min(extract, size); + } + else if (!strcmp(arg, "--autosplit")) { + if (arg_next_int(argv, argc, &i, &autosplit)) goto end; + } + else if (!strcmp(arg, "-i")) { + if (arg_next_string(argv, argc, &i, &input_path)) goto end; + } + else if (!strcmp(arg, "-o")) { + if (arg_next_string(argv, argc, &i, &docx_out_path)) goto end; + } + else if (!strcmp(arg, "--o-content")) { + if (arg_next_string(argv, argc, &i, &content_path)) goto end; + } + else if (!strcmp(arg, "-p")) { + if (arg_next_int(argv, argc, &i, &preserve_dir)) goto end; + } + else if (!strcmp(arg, "-r")) { + if (arg_next_int(argv, argc, &i, &rotation)) goto end; + } + else if (!strcmp(arg, "-s")) { + if (arg_next_int(argv, argc, &i, &spacing)) goto end; + } + else if (!strcmp(arg, "-t")) { + if (arg_next_string(argv, argc, &i, &docx_template_path)) goto end; + } + else if (!strcmp(arg, "-v")) { + int verbose; + if (arg_next_int(argv, argc, &i, &verbose)) goto end; + outf_verbose_set(verbose); + outf("Have changed verbose to %i", verbose); + } + else if (!strcmp(arg, "--v-alloc")) { + if (arg_next_int(argv, argc, &i, &alloc_stats)) goto end; + } + else { + printf("Unrecognised arg: '%s'\n", arg); + errno = EINVAL; + goto end; + } + + assert(i < argc); + } + + if (!input_path) { + printf("-i not specified.\n"); + errno = EINVAL; + goto end; + } + + if (extract_buffer_open_file(alloc, input_path, 0 /*writable*/, &intermediate)) { + printf("Failed to open intermediate file: %s\n", input_path); + goto end; + } + + if (extract_begin(alloc, &extract)) goto end; + if (extract_read_intermediate(extract, intermediate, autosplit)) goto end; + if (extract_process(extract, spacing, rotation, images)) goto end; + + if (content_path) { + if (extract_buffer_open_file(alloc, content_path, 1 /*writable*/, &out_buffer)) goto end; + if (extract_write_content(extract, out_buffer)) goto end; + if (extract_buffer_close(&out_buffer)) goto end; + } + if (docx_out_path) { + if (docx_template_path) { + if (extract_write_template( + extract, + docx_template_path, + docx_out_path, + preserve_dir + )) { + printf("Failed to create docx file: %s\n", docx_out_path); + goto end; + } + } + else { + if (extract_buffer_open_file(alloc, docx_out_path, 1 /*writable*/, &out_buffer)) goto end; + if (extract_write(extract, out_buffer)) { + printf("Failed to create docx file: %s\n", docx_out_path); + goto end; + } + if (extract_buffer_close(&out_buffer)) goto end; + } + } + + e = 0; + end: + + extract_buffer_close(&intermediate); + extract_buffer_close(&out_buffer); + extract_end(&extract); + + if (e) { + printf("Failed (errno=%i): %s\n", errno, strerror(errno)); + return 1; + } + + extract_internal_end(); + + if (alloc_stats) { + extract_alloc_stats_t* stats = extract_alloc_stats(alloc); + printf("Alloc stats: num_malloc=%i num_realloc=%i num_free=%i num_libc_realloc=%i\n", + stats->num_malloc, + stats->num_realloc, + stats->num_free, + stats->num_libc_realloc + ); + } + + extract_alloc_destroy(&alloc); + assert(alloc == NULL); + + printf("Finished.\n"); + return 0; +} diff --git a/extract/src/extract.c b/extract/src/extract.c new file mode 100644 index 00000000..adb3565e --- /dev/null +++ b/extract/src/extract.c @@ -0,0 +1,1226 @@ +#include "../include/extract.h" +#include "../include/extract_alloc.h" + +#include "astring.h" +#include "document.h" +#include "docx.h" +#include "docx_template.h" +#include "mem.h" +#include "memento.h" +#include "outf.h" +#include "xml.h" +#include "zip.h" + + +#include +#include +#include +#include +#include +#include +#include + + + + +double matrix_expansion(matrix_t m) +{ + return sqrt(fabs(m.a * m.d - m.b * m.c)); +} + + +static void char_init(char_t* item) +{ + item->pre_x = 0; + item->pre_y = 0; + item->x = 0; + item->y = 0; + item->ucs = 0; + item->adv = 0; +} + + +const char* span_string(extract_alloc_t* alloc, span_t* span) +{ + static extract_astring_t ret = {0}; + double x0 = 0; + double y0 = 0; + double x1 = 0; + double y1 = 0; + int c0 = 0; + int c1 = 0; + int i; + extract_astring_free(alloc, &ret); + if (!span) { + /* This frees our internal data, and is used by extract_internal_end(). + */ + return NULL; + } + if (span->chars_num) { + c0 = span->chars[0].ucs; + x0 = span->chars[0].x; + y0 = span->chars[0].y; + c1 = span->chars[span->chars_num-1].ucs; + x1 = span->chars[span->chars_num-1].x; + y1 = span->chars[span->chars_num-1].y; + } + { + char buffer[200]; + snprintf(buffer, sizeof(buffer), + "span chars_num=%i (%c:%f,%f)..(%c:%f,%f) font=%s:(%f,%f) wmode=%i chars_num=%i: ", + span->chars_num, + c0, x0, y0, + c1, x1, y1, + span->font_name, + span->trm.a, + span->trm.d, + span->wmode, + span->chars_num + ); + extract_astring_cat(alloc, &ret, buffer); + for (i=0; ichars_num; ++i) { + snprintf( + buffer, + sizeof(buffer), + " i=%i {x=%f adv=%f}", + i, + span->chars[i].x, + span->chars[i].adv + ); + extract_astring_cat(alloc, &ret, buffer); + } + } + extract_astring_cat(alloc, &ret, ": "); + extract_astring_catc(alloc, &ret, '"'); + for (i=0; ichars_num; ++i) { + extract_astring_catc(alloc, &ret, (char) span->chars[i].ucs); + } + extract_astring_catc(alloc, &ret, '"'); + return ret.chars; +} + +int span_append_c(extract_alloc_t* alloc, span_t* span, int c) +{ + char_t* item; + if (extract_realloc2( + alloc, + &span->chars, + sizeof(*span->chars) * span->chars_num, + sizeof(*span->chars) * (span->chars_num + 1) + )) { + return -1; + } + item = &span->chars[span->chars_num]; + span->chars_num += 1; + char_init(item); + item->ucs = c; + return 0; +} + +char_t* span_char_last(span_t* span) +{ + assert(span->chars_num > 0); + return &span->chars[span->chars_num-1]; +} + +/* Unused but useful to keep code here. */ +#if 0 +/* Returns static string containing info about line_t. */ +static const char* line_string(line_t* line) +{ + static extract_astring_t ret = {0}; + char buffer[32]; + extract_astring_free(&ret); + snprintf(buffer, sizeof(buffer), "line spans_num=%i:", line->spans_num); + extract_astring_cat(&ret, buffer); + int i; + for (i=0; ispans_num; ++i) { + extract_astring_cat(&ret, " "); + extract_astring_cat(&ret, span_string(line->spans[i])); + } + return ret.chars; +} +#endif + +/* Returns first span in a line. */ +span_t* line_span_last(line_t* line) +{ + assert(line->spans_num > 0); + return line->spans[line->spans_num - 1]; +} + +span_t* line_span_first(line_t* line) +{ + assert(line->spans_num > 0); + return line->spans[0]; +} + +static void page_free(extract_alloc_t* alloc, page_t* page) +{ + int s; + if (!page) return; + + for (s=0; sspans_num; ++s) { + span_t* span = page->spans[s]; + if (span) { + extract_free(alloc, &span->chars); + extract_free(alloc, &span->font_name); + } + extract_free(alloc, &span); + } + extract_free(alloc, &page->spans); + + { + int l; + for (l=0; llines_num; ++l) { + line_t* line = page->lines[l]; + extract_free(alloc, &line->spans); + extract_free(alloc, &line); + /* We don't free line->spans->chars[] because already freed via + page->spans. */ + } + } + extract_free(alloc, &page->lines); + + { + int p; + for (p=0; pparagraphs_num; ++p) { + paragraph_t* paragraph = page->paragraphs[p]; + if (paragraph) extract_free(alloc, ¶graph->lines); + extract_free(alloc, ¶graph); + } + } + extract_free(alloc, &page->paragraphs); + + { + int i; + for (i=0; iimages_num; ++i) { + extract_free(alloc, &page->images[i].data); + extract_free(alloc, &page->images[i].type); + extract_free(alloc, &page->images[i].id); + extract_free(alloc, &page->images[i].name); + } + } + extract_free(alloc, &page->images); +} + +static span_t* page_span_append(extract_alloc_t* alloc, page_t* page) +/* Appends new empty span_ to an page_t; returns NULL with errno set on error. +*/ +{ + span_t* span; + if (extract_malloc(alloc, &span, sizeof(*span))) return NULL; + span->font_name = NULL; + span->chars = NULL; + span->chars_num = 0; + if (extract_realloc2( + alloc, + &page->spans, + sizeof(*page->spans) * page->spans_num, + sizeof(*page->spans) * (page->spans_num + 1) + )) { + extract_free(alloc, &span); + return NULL; + } + page->spans[page->spans_num] = span; + page->spans_num += 1; + return span; +} + + +static void extract_images_free(extract_alloc_t* alloc, images_t* images) +{ + int i; + for (i=0; iimages_num; ++i) { + image_t* image = &images->images[i]; + extract_free(alloc, &image->type); + extract_free(alloc, &image->name); + extract_free(alloc, &image->id); + if (image->data_free) { + image->data_free(image->data_free_handle, image->data); + } + extract_free(alloc, &images->images[i]); + } + extract_free(alloc, &images->images); + extract_free(alloc, &images->imagetypes); + images->images_num = 0; + images->imagetypes_num = 0; +} + + +static int extract_document_images(extract_alloc_t* alloc, document_t* document, images_t* o_images) +/* Moves image_t's from document->page[] to *o_images. + +On return document->page[].images* will be NULL etc. +*/ +{ + int e = -1; + int p; + images_t images = {0}; + outf("images.images_num=%i", images.images_num); + for (p=0; ppages_num; ++p) { + page_t* page = document->pages[p]; + int i; + for (i=0; iimages_num; ++i) { + image_t* image; + if (extract_realloc2( + alloc, + &images.images, + sizeof(image_t) * images.images_num, + sizeof(image_t) * (images.images_num + 1) + )) goto end; + image = &page->images[i]; + outf("p=%i i=%i image->name=%s image->id=%s", p, i, image->name, image->id); + assert(image->name); + images.images[images.images_num] = *image; + images.images_num += 1; + + /* Add image type if we haven't seen it before. */ + { + int it; + for (it=0; ittype=%s", + it, images.imagetypes[it], image->type); + if (!strcmp(images.imagetypes[it], image->type)) { + break; + } + } + if (it == images.imagetypes_num) { + if (extract_realloc2( + alloc, + &images.imagetypes, + sizeof(char*) * images.imagetypes_num, + sizeof(char*) * (images.imagetypes_num + 1) + )) goto end; + assert(image->type); + images.imagetypes[images.imagetypes_num] = image->type; + images.imagetypes_num += 1; + outf("have added images.imagetypes_num=%i", images.imagetypes_num); + } + } + + /* We've taken ownership of image->* so NULL the original values + here to ensure we can't use things after free. */ + image->type = NULL; + image->name = NULL; + image->id = NULL; + image->data = NULL; + image->data_size = 0; + } + extract_free(alloc, &page->images); + page->images_num = 0; + } + e = 0; + end: + if (e) { + } + else { + *o_images = images; + } + return e; +} + +static void extract_document_free(extract_alloc_t* alloc, document_t* document) +{ + int p; + if (!document) { + return; + } + for (p=0; ppages_num; ++p) { + page_t* page = document->pages[p]; + page_free(alloc, page); + extract_free(alloc, &page); + } + extract_free(alloc, &document->pages); + document->pages = NULL; + document->pages_num = 0; +} + + +/* Returns +1, 0 or -1 depending on sign of x. */ +static int s_sign(double x) +{ + if (x < 0) return -1; + if (x > 0) return +1; + return 0; +} + +int matrix_cmp4(const matrix_t* lhs, const matrix_t* rhs) +{ + int ret; + ret = s_sign(lhs->a - rhs->a); if (ret) return ret; + ret = s_sign(lhs->b - rhs->b); if (ret) return ret; + ret = s_sign(lhs->c - rhs->c); if (ret) return ret; + ret = s_sign(lhs->d - rhs->d); if (ret) return ret; + return 0; +} + + +static point_t multiply_matrix_point(matrix_t m, point_t p) +{ + double x = p.x; + p.x = m.a * x + m.c * p.y; + p.y = m.b * x + m.d * p.y; + return p; +} + +static int s_matrix_read(const char* text, matrix_t* matrix) +{ + int n; + if (!text) { + outf("text is NULL in s_matrix_read()"); + errno = EINVAL; + return -1; + } + n = sscanf(text, + "%lf %lf %lf %lf %lf %lf", + &matrix->a, + &matrix->b, + &matrix->c, + &matrix->d, + &matrix->e, + &matrix->f + ); + if (n != 6) { + errno = EINVAL; + return -1; + } + return 0; +} + + +static void s_document_init(document_t* document) +{ + document->pages = NULL; + document->pages_num = 0; +} + + +static int page_span_end_clean(extract_alloc_t* alloc, page_t* page) +/* Does preliminary processing of the end of the last span in a page; intended +to be called as we load span information. + +Looks at last two char_t's in last span_t of , and either +leaves unchanged, or removes space in last-but-one position, or moves last +char_t into a new span_t. */ +{ + int ret = -1; + span_t* span; + char_t* char_; + double font_size; + double x; + double y; + double err_x; + double err_y; + point_t dir; + + assert(page->spans_num); + span = page->spans[page->spans_num-1]; + assert(span->chars_num); + + /* Last two char_t's are char_[-2] and char_[-1]. */ + char_ = &span->chars[span->chars_num]; + + if (span->chars_num == 1) { + return 0; + } + + font_size = matrix_expansion(span->trm) + * matrix_expansion(span->ctm); + + if (span->wmode) { + dir.x = 0; + dir.y = 1; + } + else { + dir.x = 1; + dir.y = 0; + } + dir = multiply_matrix_point(span->trm, dir); + + x = char_[-2].pre_x + char_[-2].adv * dir.x; + y = char_[-2].pre_y + char_[-2].adv * dir.y; + + err_x = (char_[-1].pre_x - x) / font_size; + err_y = (char_[-1].pre_y - y) / font_size; + + if (span->chars_num >= 2 && span->chars[span->chars_num-2].ucs == ' ') { + int remove_penultimate_space = 0; + if (err_x < -span->chars[span->chars_num-2].adv / 2 + && err_x > -span->chars[span->chars_num-2].adv + ) { + remove_penultimate_space = 1; + } + if ((char_[-1].pre_x - char_[-2].pre_x) / font_size < char_[-1].adv / 10) { + outfx( + "removing penultimate space because space very narrow:" + "char_[-1].pre_x-char_[-2].pre_x=%f font_size=%f" + " char_[-1].adv=%f", + char_[-1].pre_x - char_[-2].pre_x, + font_size, + char_[-1].adv + ); + remove_penultimate_space = 1; + } + if (remove_penultimate_space) { + /* This character overlaps with previous space + character. We discard previous space character - these + sometimes seem to appear in the middle of words for some + reason. */ + outfx("removing space before final char in: %s", + span_string(span)); + span->chars[span->chars_num-2] = span->chars[span->chars_num-1]; + span->chars_num -= 1; + outfx("span is now: %s", span_string(span)); + return 0; + } + } + else if (fabs(err_x) > 0.01 || fabs(err_y) > 0.01) { + /* This character doesn't seem to be a continuation of + previous characters, so split into two spans. This often + splits text incorrectly, but this is corrected later when + we join spans into lines. */ + outfx( + "Splitting last char into new span. font_size=%f dir.x=%f" + " char[-1].pre=(%f, %f) err=(%f, %f): %s", + font_size, + dir.x, + char_[-1].pre_x, + char_[-1].pre_y, + err_x, + err_y, + span_string2(span) + ); + { + span_t* span2 = page_span_append(alloc, page); + if (!span2) goto end; + *span2 = *span; + if (extract_strdup(alloc, span->font_name, &span2->font_name)) goto end; + span2->chars_num = 1; + if (extract_malloc(alloc, &span2->chars, sizeof(char_t) * span2->chars_num)) goto end; + span2->chars[0] = char_[-1]; + span->chars_num -= 1; + } + return 0; + } + ret = 0; + end: + return ret; +} + + +struct extract_t +{ + extract_alloc_t* alloc; + + document_t document; + + int num_spans_split; + /* Number of extra spans from page_span_end_clean(). */ + + int num_spans_autosplit; + /* Number of extra spans from autosplit=1. */ + + double span_offset_x; + double span_offset_y; + /* Only used if autosplit is non-zero. */ + + int image_n; + /* Used to generate unique ids for images. */ + + /* List of strings that are the generated docx content for each page. When + zip_* can handle appending of data, we will be able to remove this list. */ + extract_astring_t* contentss; + int contentss_num; + + images_t images; +}; + + + +int extract_begin( + extract_alloc_t* alloc, + extract_t** pextract + ) +{ + int e = -1; + extract_t* extract; + + /* Use a temporary extract_alloc_t to allocate space for the extract_t. */ + if (extract_malloc(alloc, &extract, sizeof(*extract))) goto end; + + extract_bzero(extract, sizeof(*extract)); + extract->alloc = alloc; + s_document_init(&extract->document); + + /* Start at 10 because template document might use some low-numbered IDs. + */ + extract->image_n = 10; + + e = 0; + + end: + *pextract = (e) ? NULL : extract; + return e; +} + +static void image_free_fn(void* handle, void* image_data) +{ + (void) handle; + free(image_data); +} + +int extract_read_intermediate(extract_t* extract, extract_buffer_t* buffer, int autosplit) +{ + int ret = -1; + + document_t* document = &extract->document; + char* image_data = NULL; + int num_spans = 0; + + extract_xml_tag_t tag; + extract_xml_tag_init(&tag); + + if (extract_xml_pparse_init(extract->alloc, buffer, NULL /*first_line*/)) { + outf("Failed to read start of intermediate data: %s", strerror(errno)); + goto end; + } + /* Data read from is expected to be XML looking like: + + + + + + ... + + + ... + + ... + + + ... + + ... + + We convert this into a list of page_t's, each containing a list of + span_t's, each containing a list of char_t's. + + While doing this, we do some within-span processing by calling + page_span_end_clean(): + Remove spurious spaces. + Split spans in two where there seem to be large gaps between glyphs. + */ + for(;;) { + page_t* page; + int e = extract_xml_pparse_next(buffer, &tag); + if (e == 1) break; /* EOF. */ + if (e) goto end; + if (!strcmp(tag.name, "?xml")) { + /* We simply skip this if we find it. As of 2020-07-31, mutool adds + this header to mupdf raw output, but gs txtwrite does not include + it. */ + continue; + } + if (strcmp(tag.name, "page")) { + outf("Expected but tag.name='%s'", tag.name); + errno = ESRCH; + goto end; + } + outfx("loading spans for page %i...", document->pages_num); + if (extract_page_begin(extract)) goto end; + page = extract->document.pages[extract->document.pages_num-1]; + if (!page) goto end; + + for(;;) { + if (extract_xml_pparse_next(buffer, &tag)) goto end; + if (!strcmp(tag.name, "/page")) { + num_spans += page->spans_num; + break; + } + if (!strcmp(tag.name, "image")) { + const char* type = extract_xml_tag_attributes_find(&tag, "type"); + if (!type) { + errno = EINVAL; + goto end; + } + outf("image type=%s", type); + if (!strcmp(type, "pixmap")) { + int w; + int h; + int y; + if (extract_xml_tag_attributes_find_int(&tag, "w", &w)) goto end; + if (extract_xml_tag_attributes_find_int(&tag, "h", &h)) goto end; + for (y=0; y but tag.name='%s'", tag.name); + errno = ESRCH; + goto end; + } + if (extract_xml_tag_attributes_find_int(&tag, "y", &yy)) goto end; + if (yy != y) { + outf("Expected but found ", y, yy); + errno = ESRCH; + goto end; + } + if (extract_xml_pparse_next(buffer, &tag)) goto end; + if (strcmp(tag.name, "/line")) { + outf("Expected but tag.name='%s'", tag.name); + errno = ESRCH; + goto end; + } + } + } + else { + /* Compressed. */ + size_t image_data_size; + const char* c; + size_t i; + if (extract_xml_tag_attributes_find_size(&tag, "datasize", &image_data_size)) goto end; + if (extract_malloc(extract->alloc, &image_data, image_data_size)) goto end; + c = tag.text.chars; + for(i=0;;) { + int byte = 0; + int cc; + cc = *c; + c += 1; + if (cc == ' ' || cc == '\n') continue; + if (cc >= '0' && cc <= '9') byte += cc-'0'; + else if (cc >= 'a' && cc <= 'f') byte += 10 + cc - 'a'; + else goto compressed_error; + byte *= 16; + + cc = *c; + c += 1; + if (cc >= '0' && cc <= '9') byte += cc-'0'; + else if (cc >= 'a' && cc <= 'f') byte += 10 + cc - 'a'; + else goto compressed_error; + + image_data[i] = (char) byte; + i += 1; + if (i == image_data_size) { + break; + } + continue; + + compressed_error: + outf("Unrecognised hex character '%x' at offset %lli in image data", cc, (long long) (c-tag.text.chars)); + errno = EINVAL; + goto end; + } + if (extract_add_image( + extract, + type, + 0 /*x*/, + 0 /*y*/, + 0 /*w*/, + 0 /*h*/, + image_data, + image_data_size, + image_free_fn, + NULL + )) + { + goto end; + } + image_data = NULL; + } + if (extract_xml_pparse_next(buffer, &tag)) goto end; + if (strcmp(tag.name, "/image")) { + outf("Expected but tag.name='%s'", tag.name); + errno = ESRCH; + goto end; + } + continue; + } + if (strcmp(tag.name, "span")) { + outf("Expected but tag.name='%s'", tag.name); + errno = ESRCH; + goto end; + } + + { + matrix_t ctm; + matrix_t trm; + char* font_name; + char* font_name2; + int font_bold; + int font_italic; + int wmode; + if (s_matrix_read(extract_xml_tag_attributes_find(&tag, "ctm"), &ctm)) goto end; + if (s_matrix_read(extract_xml_tag_attributes_find(&tag, "trm"), &trm)) goto end; + font_name = extract_xml_tag_attributes_find(&tag, "font_name"); + if (!font_name) { + outf("Failed to find attribute 'font_name'"); + goto end; + } + font_name2 = strchr(font_name, '+'); + if (font_name2) font_name = font_name2 + 1; + font_bold = strstr(font_name, "-Bold") ? 1 : 0; + font_italic = strstr(font_name, "-Oblique") ? 1 : 0; + if (extract_xml_tag_attributes_find_int(&tag, "wmode", &wmode)) goto end; + if (extract_span_begin( + extract, + font_name, + font_bold, + font_italic, + wmode, + ctm.a, + ctm.b, + ctm.c, + ctm.d, + ctm.e, + ctm.f, + trm.a, + trm.b, + trm.c, + trm.d, + trm.e, + trm.f + )) goto end; + + for(;;) { + double x; + double y; + double adv; + unsigned ucs; + + if (extract_xml_pparse_next(buffer, &tag)) { + outf("Failed to find but tag.name='%s'", tag.name); + goto end; + } + + if (extract_xml_tag_attributes_find_double(&tag, "x", &x)) goto end; + if (extract_xml_tag_attributes_find_double(&tag, "y", &y)) goto end; + if (extract_xml_tag_attributes_find_double(&tag, "adv", &adv)) goto end; + if (extract_xml_tag_attributes_find_uint(&tag, "ucs", &ucs)) goto end; + + if (extract_add_char(extract, x, y, ucs, adv, autosplit)) goto end; + } + + extract_xml_tag_free(extract->alloc, &tag); + } + } + if (extract_page_end(extract)) goto end; + outf("page=%i page->num_spans=%i", + document->pages_num, page->spans_num); + } + + outf("num_spans=%i num_spans_split=%i num_spans_autosplit=%i", + num_spans, + extract->num_spans_split, + extract->num_spans_autosplit + ); + + ret = 0; + + end: + extract_xml_tag_free(extract->alloc, &tag); + extract_free(extract->alloc, &image_data); + + return ret; +} + + +int extract_span_begin( + extract_t* extract, + const char* font_name, + int font_bold, + int font_italic, + int wmode, + double ctm_a, + double ctm_b, + double ctm_c, + double ctm_d, + double ctm_e, + double ctm_f, + double trm_a, + double trm_b, + double trm_c, + double trm_d, + double trm_e, + double trm_f + ) +{ + int e = -1; + page_t* page; + span_t* span; + assert(extract->document.pages_num > 0); + page = extract->document.pages[extract->document.pages_num-1]; + span = page_span_append(extract->alloc, page); + if (!span) goto end; + span->ctm.a = ctm_a; + span->ctm.b = ctm_b; + span->ctm.c = ctm_c; + span->ctm.d = ctm_d; + span->ctm.e = ctm_e; + span->ctm.f = ctm_f; + span->trm.a = trm_a; + span->trm.b = trm_b; + span->trm.c = trm_c; + span->trm.d = trm_d; + span->trm.e = trm_e; + span->trm.f = trm_f; + { + const char* ff = strchr(font_name, '+'); + const char* f = (ff) ? ff+1 : font_name; + if (extract_strdup(extract->alloc, f, &span->font_name)) goto end; + span->font_bold = font_bold ? 1 : 0; + span->font_italic = font_italic ? 1 : 0; + span->wmode = wmode ? 1 : 0; + extract->span_offset_x = 0; + extract->span_offset_y = 0; + } + e = 0; + end: + return e; +} + + +int extract_add_char( + extract_t* extract, + double x, + double y, + unsigned ucs, + double adv, + int autosplit + ) +{ + int e = -1; + char_t* char_; + page_t* page = extract->document.pages[extract->document.pages_num-1]; + span_t* span = page->spans[page->spans_num - 1]; + + if (autosplit && y - extract->span_offset_y != 0) { + + double e = span->ctm.e + span->ctm.a * (x - extract->span_offset_x) + + span->ctm.b * (y - extract->span_offset_y); + double f = span->ctm.f + span->ctm.c * (x - extract->span_offset_x) + + span->ctm.d * (y - extract->span_offset_y); + extract->span_offset_x = x; + extract->span_offset_y = y; + outfx("autosplit: char_pre_y=%f offset_y=%f", + char_pre_y, offset_y); + outfx( + "autosplit: changing ctm.{e,f} from (%f, %f) to (%f, %f)", + span->ctm.e, + span->ctm.f, + e, f + ); + if (span->chars_num > 0) { + /* Create new span. */ + span_t* span0 = span; + extract->num_spans_autosplit += 1; + span = page_span_append(extract->alloc, page); + if (!span) goto end; + *span = *span0; + span->chars = NULL; + span->chars_num = 0; + if (extract_strdup(extract->alloc, span0->font_name, &span->font_name)) goto end; + } + span->ctm.e = e; + span->ctm.f = f; + outfx("autosplit: char_pre_y=%f offset_y=%f", + char_pre_y, offset_y); + } + + if (span_append_c(extract->alloc, span, 0 /*c*/)) goto end; + char_ = &span->chars[ span->chars_num-1]; + + char_->pre_x = x - extract->span_offset_x; + char_->pre_y = y - extract->span_offset_y; + + char_->x = span->ctm.a * char_->pre_x + span->ctm.b * char_->pre_y; + char_->y = span->ctm.c * char_->pre_x + span->ctm.d * char_->pre_y; + + char_->adv = adv; + char_->ucs = ucs; + + char_->x += span->ctm.e; + char_->y += span->ctm.f; + + { + int page_spans_num_old = page->spans_num; + if (page_span_end_clean(extract->alloc, page)) goto end; + span = page->spans[page->spans_num-1]; /* fixme: unnecessary. */ + if (page->spans_num != page_spans_num_old) { + extract->num_spans_split += 1; + } + } + e = 0; + + end: + return e; +} + + +int extract_span_end(extract_t* extract) +{ + page_t* page = extract->document.pages[extract->document.pages_num-1]; + span_t* span = page->spans[page->spans_num - 1]; + if (span->chars_num == 0) { + /* Calling code called extract_span_begin() then extract_span_end() + without any call to extract_add_char(). Our joining code assumes that + all spans are non-empty, so we need to delete this span. */ + extract_free(extract->alloc, &page->spans[page->spans_num - 1]); + page->spans_num -= 1; + } + return 0; +} + + +int extract_add_image( + extract_t* extract, + const char* type, + double x, + double y, + double w, + double h, + char* data, + size_t data_size, + extract_image_data_free data_free, + void* data_free_handle + ) +{ + int e = -1; + page_t* page = extract->document.pages[extract->document.pages_num-1]; + image_t image_temp = {0}; + + (void) x; + (void) y; + (void) w; + (void) h; + + extract->image_n += 1; + image_temp.data = data; + image_temp.data_size = data_size; + image_temp.data_free = data_free; + image_temp.data_free_handle = data_free_handle; + if (extract_strdup(extract->alloc, type, &image_temp.type)) goto end; + if (extract_asprintf(extract->alloc, &image_temp.id, "rId%i", extract->image_n) < 0) goto end; + if (extract_asprintf(extract->alloc, &image_temp.name, "image%i.%s", extract->image_n, image_temp.type) < 0) goto end; + + if (extract_realloc2( + extract->alloc, + &page->images, + sizeof(image_t) * page->images_num, + sizeof(image_t) * (page->images_num + 1) + )) goto end; + + page->images[page->images_num] = image_temp; + page->images_num += 1; + outf("page->images_num=%i", page->images_num); + + e = 0; + + end: + + if (e) { + extract_free(extract->alloc, &image_temp.type); + extract_free(extract->alloc, &image_temp.data); + extract_free(extract->alloc, &image_temp.id); + extract_free(extract->alloc, &image_temp.name); + } + + return e; +} + +int extract_page_begin(extract_t* extract) +{ + /* Appends new empty page_t to an extract->document. */ + page_t* page; + if (extract_malloc(extract->alloc, &page, sizeof(page_t))) return -1; + page->spans = NULL; + page->spans_num = 0; + page->lines = NULL; + page->lines_num = 0; + page->paragraphs = NULL; + page->paragraphs_num = 0; + page->images = NULL; + page->images_num = 0; + if (extract_realloc2( + extract->alloc, + &extract->document.pages, + sizeof(page_t*) * extract->document.pages_num + 1, + sizeof(page_t*) * (extract->document.pages_num + 1) + )) { + extract_free(extract->alloc, &page); + return -1; + } + extract->document.pages[extract->document.pages_num] = page; + extract->document.pages_num += 1; + return 0; +} + + +int extract_page_end(extract_t* extract) +{ + (void) extract; + return 0; +} + +int extract_process( + extract_t* extract, + int spacing, + int rotation, + int images + ) +{ + int e = -1; + + if (extract_realloc2( + extract->alloc, + &extract->contentss, + sizeof(*extract->contentss) * extract->contentss_num, + sizeof(*extract->contentss) * (extract->contentss_num + 1) + )) goto end; + extract_astring_init(&extract->contentss[extract->contentss_num]); + extract->contentss_num += 1; + + if (extract_document_join(extract->alloc, &extract->document)) goto end; + + if (extract_document_to_docx_content( + extract->alloc, + &extract->document, + spacing, + rotation, + images, + &extract->contentss[extract->contentss_num - 1] + )) goto end; + + if (extract_document_images(extract->alloc, &extract->document, &extract->images)) goto end; + + { + int i; + for (i=0; idocument.pages_num; ++i) { + page_free(extract->alloc, extract->document.pages[i]); + extract_free(extract->alloc, &extract->document.pages[i]); + } + extract_free(extract->alloc, &extract->document.pages); + extract->document.pages_num = 0; + } + + e = 0; + + end: + return e; +} + +int extract_write(extract_t* extract, extract_buffer_t* buffer) +{ + int e = -1; + extract_zip_t* zip = NULL; + char* text2 = NULL; + int i; + + if (extract_zip_open(buffer, &zip)) goto end; + for (i=0; ialloc, &text2); + outf("i=%i item->name=%s", i, item->name); + if (extract_docx_content_item( + extract->alloc, + extract->contentss, + extract->contentss_num, + &extract->images, + item->name, + item->text, + &text2 + )) { + goto end; + } + + { + const char* text3 = (text2) ? text2 : item->text; + if (extract_zip_write_file(zip, text3, strlen(text3), item->name)) goto end; + } + } + + for (i=0; iimages.images_num; ++i) { + image_t* image = &extract->images.images[i]; + extract_free(extract->alloc, &text2); + if (extract_asprintf(extract->alloc, &text2, "word/media/%s", image->name) < 0) goto end; + if (extract_zip_write_file(zip, image->data, image->data_size, text2)) goto end; + } + + if (extract_zip_close(&zip)) goto end; + assert(!zip); + + e = 0; + + end: + if (e) outf("failed: %s", strerror(errno)); + extract_free(extract->alloc, &text2); + extract_zip_close(&zip); + + return e; +} + +int extract_write_content(extract_t* extract, extract_buffer_t* buffer) +{ + int i; + for (i=0; icontentss_num; ++i) { + if (extract_buffer_write( + buffer, + extract->contentss[i].chars, + extract->contentss[i].chars_num, + NULL /*o_actual*/ + )) return -1; + } + return 0; +} + +int extract_write_template( + extract_t* extract, + const char* path_template, + const char* path_out, + int preserve_dir + ) +{ + return extract_docx_write_template( + extract->alloc, + extract->contentss, + extract->contentss_num, + &extract->images, + path_template, + path_out, + preserve_dir + ); +} + +void extract_end(extract_t** pextract) +{ + extract_t* extract = *pextract; + if (!extract) return; + extract_document_free(extract->alloc, &extract->document); + + { + int i; + for (i=0; icontentss_num; ++i) { + extract_astring_free(extract->alloc, &extract->contentss[i]); + } + extract_free(extract->alloc, &extract->contentss); + } + extract_images_free(extract->alloc, &extract->images); + extract_free(extract->alloc, pextract); +} + +void extract_internal_end(void) +{ + span_string(NULL, NULL); +} + +void extract_exp_min(extract_t* extract, size_t size) +{ + extract_alloc_exp_min(extract->alloc, size); +} diff --git a/extract/src/join.c b/extract/src/join.c new file mode 100644 index 00000000..bc02ea21 --- /dev/null +++ b/extract/src/join.c @@ -0,0 +1,951 @@ +#include "../include/extract.h" +#include "../include/extract_alloc.h" + +#include "astring.h" +#include "document.h" +#include "mem.h" +#include "outf.h" + +#include +#include +#include + + +static char_t* span_char_first(span_t* span) +{ + assert(span->chars_num > 0); + return &span->chars[0]; +} + +/* Returns first char_t in a line. */ +static char_t* line_item_first(line_t* line) +{ + span_t* span = line_span_first(line); + return span_char_first(span); +} + +/* Returns last char_t in a line. */ +static char_t* line_item_last(line_t* line) +{ + span_t* span = line_span_last(line); + return span_char_last(span); +} + +static const char* matrix_string(const matrix_t* matrix) +{ + static char ret[64]; + snprintf(ret, sizeof(ret), "{%f %f %f %f %f %f}", + matrix->a, + matrix->b, + matrix->c, + matrix->d, + matrix->e, + matrix->f + ); + return ret; +} + +/* Returns total width of span. */ +static double span_adv_total(span_t* span) +{ + double dx = span_char_last(span)->x - span_char_first(span)->x; + double dy = span_char_last(span)->y - span_char_first(span)->y; + /* We add on the advance of the last item; this avoids us returning zero if + there's only one item. */ + double adv = span_char_last(span)->adv * matrix_expansion(span->trm); + return sqrt(dx*dx + dy*dy) + adv; +} + +/* Returns distance between end of and beginning of . */ +static double spans_adv( + span_t* a_span, + char_t* a, + char_t* b + ) +{ + double delta_x = b->x - a->x; + double delta_y = b->y - a->y; + double s = sqrt( delta_x*delta_x + delta_y*delta_y); + double a_size = a->adv * matrix_expansion(a_span->trm); + s -= a_size; + return s; +} + +static double span_angle(span_t* span) +{ + /* Assume ctm is a rotation matix. */ + double ret = atan2(-span->ctm.c, span->ctm.a); + outfx("ctm.a=%f ctm.b=%f ret=%f", span->ctm.a, span->ctm.b, ret); + return ret; + /* Not sure whether this is right. Inclined text seems to be done by + setting the ctm matrix, so not really sure what trm matrix does. This code + assumes that it also inclines text, but maybe it only rotates individual + glyphs? */ + /*if (span->wmode == 0) { + return atan2(span->trm.b, span->trm.a); + } + else { + return atan2(span->trm.d, span->trm.c); + }*/ +} + +/* Returns static string containing brief info about span_t. */ +static const char* span_string2(extract_alloc_t* alloc, span_t* span) +{ + static extract_astring_t ret = {0}; + int i; + extract_astring_free(alloc, &ret); + extract_astring_catc(alloc, &ret, '"'); + for (i=0; ichars_num; ++i) { + extract_astring_catc(alloc, &ret, (char) span->chars[i].ucs); + } + extract_astring_catc(alloc, &ret, '"'); + return ret.chars; +} + +/* Returns angle of . */ +static double line_angle(line_t* line) +{ + /* All spans in a line must have same angle, so just use the first span. */ + assert(line->spans_num > 0); + return span_angle(line->spans[0]); +} + +/* Returns static string containing brief info about line_t. */ +static const char* line_string2(extract_alloc_t* alloc, line_t* line) +{ + static extract_astring_t ret = {0}; + char buffer[256]; + int i; + extract_astring_free(alloc, &ret); + snprintf(buffer, sizeof(buffer), "line x=%f y=%f spans_num=%i:", + line->spans[0]->chars[0].x, + line->spans[0]->chars[0].y, + line->spans_num + ); + extract_astring_cat(alloc, &ret, buffer); + for (i=0; ispans_num; ++i) { + extract_astring_cat(alloc, &ret, " "); + extract_astring_cat(alloc, &ret, span_string2(alloc, line->spans[i])); + } + return ret.chars; +} + +/* Array of pointers to lines that are aligned and adjacent to each other so as +to form a paragraph. */ +static const char* paragraph_string(extract_alloc_t* alloc, paragraph_t* paragraph) +{ + static extract_astring_t ret = {0}; + extract_astring_free(alloc, &ret); + extract_astring_cat(alloc, &ret, "paragraph: "); + if (paragraph->lines_num) { + extract_astring_cat(alloc, &ret, line_string2(alloc, paragraph->lines[0])); + if (paragraph->lines_num > 1) { + extract_astring_cat(alloc, &ret, ".."); + extract_astring_cat( + alloc, + &ret, + line_string2(alloc, paragraph->lines[paragraph->lines_num-1]) + ); + } + } + return ret.chars; +} + +/* Returns first line in paragraph. */ +static line_t* paragraph_line_first(const paragraph_t* paragraph) +{ + assert(paragraph->lines_num); + return paragraph->lines[0]; +} + +/* Returns last line in paragraph. */ +static line_t* paragraph_line_last(const paragraph_t* paragraph) +{ + assert(paragraph->lines_num); + return paragraph->lines[ paragraph->lines_num-1]; +} + + + +/* Things for direct conversion of text spans into lines and paragraphs. */ + +/* Returns 1 if lines have same wmode and are at the same angle, else 0. + +todo: allow small epsilon? */ +static int lines_are_compatible( + line_t* a, + line_t* b, + double angle_a, + int verbose + ) +{ + if (a == b) return 0; + if (!a->spans || !b->spans) return 0; + if (line_span_first(a)->wmode != line_span_first(b)->wmode) { + return 0; + } + if (matrix_cmp4( + &line_span_first(a)->ctm, + &line_span_first(b)->ctm + )) { + if (verbose) { + outf("ctm's differ:"); + outf(" %f %f %f %f %f %f", + line_span_first(a)->ctm.a, + line_span_first(a)->ctm.b, + line_span_first(a)->ctm.c, + line_span_first(a)->ctm.d, + line_span_first(a)->ctm.e, + line_span_first(a)->ctm.f + ); + outf(" %f %f %f %f %f %f", + line_span_first(b)->ctm.a, + line_span_first(b)->ctm.b, + line_span_first(b)->ctm.c, + line_span_first(b)->ctm.d, + line_span_first(b)->ctm.e, + line_span_first(b)->ctm.f + ); + } + return 0; + } + { + double angle_b = span_angle(line_span_first(b)); + if (angle_b != angle_a) { + outfx("%s:%i: angles differ"); + return 0; + } + } + return 1; +} + + +/* Creates representation of span_t's that consists of a list of line_t's, with +each line_t contains pointers to a list of span_t's. + +We only join spans that are at the same angle and are aligned. + +On entry: + Original value of *o_lines and *o_lines_num are ignored. + + points to array of span_t*'s, each pointing to + an span_t. + +On exit: + If we succeed, we return 0, with *o_lines pointing to array of *o_lines_num + line_t*'s, each pointing to an line_t. + + Otherwise we return -1 with errno set. *o_lines and *o_lines_num are + undefined. +*/ +static int make_lines( + extract_alloc_t* alloc, + span_t** spans, + int spans_num, + line_t*** o_lines, + int* o_lines_num + ) +{ + int ret = -1; + + /* Make an line_t for each span. Then we will join some of these + line_t's together before returning. */ + int lines_num = spans_num; + line_t** lines = NULL; + int a; + int num_compatible; + int num_joins; + if (extract_malloc(alloc, &lines, sizeof(*lines) * lines_num)) goto end; + + /* Ensure we can clean up after error. */ + for (a=0; aspans_num = 0; + if (extract_malloc(alloc, &lines[a]->spans, sizeof(span_t*) * 1)) goto end; + lines[a]->spans_num = 1; + lines[a]->spans[0] = spans[a]; + outfx("initial line a=%i: %s", a, line_string(lines[a])); + } + + num_compatible = 0; + + /* For each line, look for nearest aligned line, and append if found. */ + num_joins = 0; + for (a=0; actm), + line_string2(alloc, line_a) + ); + + for (b=0; bx - span_char_last(span_a)->x; + double dy = span_char_first(span_b)->y - span_char_last(span_a)->y; + double angle_a_b = atan2(-dy, dx); + const double angle_tolerance_deg = 1; + if (verbose) { + outf("delta=(%f %f) alast=(%f %f) bfirst=(%f %f): angle_a=%f angle_a_b=%f", + dx, + dy, + span_char_last(span_a)->x, + span_char_last(span_a)->y, + span_char_first(span_b)->x, + span_char_first(span_b)->y, + angle_a * 180 / pi, + angle_a_b * 180 / pi + ); + } + /* Might want to relax this when we test on non-horizontal lines. + */ + if (fabs(angle_a_b - angle_a) * 180 / pi <= angle_tolerance_deg) { + /* Find distance between end of line_a and beginning of line_b. */ + double adv = spans_adv( + span_a, + span_char_last(span_a), + span_char_first(span_b) + ); + if (verbose) outf("nearest_adv=%f. angle_a_b=%f adv=%f", + nearest_adv, + angle_a_b, + adv + ); + if (!nearest_line || adv < nearest_adv) { + nearest_line = line_b; + nearest_adv = adv; + nearest_line_b = b; + } + } + else { + if (verbose) outf( + "angle beyond tolerance: span_a last=(%f,%f) span_b first=(%f,%f) angle_a_b=%g angle_a=%g span_a.trm{a=%f b=%f}", + span_char_last(span_a)->x, + span_char_last(span_a)->y, + span_char_first(span_b)->x, + span_char_first(span_b)->y, + angle_a_b * 180 / pi, + angle_a * 180 / pi, + span_a->trm.a, + span_a->trm.b + ); + } + } + } + + if (nearest_line) { + /* line_a and nearest_line are aligned so we can move line_b's + spans on to the end of line_a. */ + span_t* span_b = line_span_first(nearest_line); + b = nearest_line_b; + if (verbose) outf("found nearest line. a=%i b=%i", a, b); + + if (1 + && span_char_last(span_a)->ucs != ' ' + && span_char_first(span_b)->ucs != ' ' + ) { + /* Find average advance of the two adjacent spans in the two + lines we are considering joining, so that we can decide whether + the distance between them is large enough to merit joining with + a space character). */ + double average_adv = ( + (span_adv_total(span_a) + span_adv_total(span_b)) + / + (double) (span_a->chars_num + span_b->chars_num) + ); + + int insert_space = (nearest_adv > 0.25 * average_adv); + if (insert_space) { + /* Append space to span_a before concatenation. */ + char_t* item; + if (verbose) { + outf("(inserted space) nearest_adv=%f average_adv=%f", + nearest_adv, + average_adv + ); + outf(" a: %s", span_string(alloc, span_a)); + outf(" b: %s", span_string(alloc, span_b)); + } + if (extract_realloc2( + alloc, + &span_a->chars, + sizeof(char_t) * span_a->chars_num, + sizeof(char_t) * (span_a->chars_num + 1) + )) goto end; + item = &span_a->chars[span_a->chars_num]; + span_a->chars_num += 1; + extract_bzero(item, sizeof(*item)); + item->ucs = ' '; + item->adv = nearest_adv; + } + + if (verbose) { + outf("Joining spans a=%i b=%i:", a, b); + outf(" %s", span_string2(alloc, span_a)); + outf(" %s", span_string2(alloc, span_b)); + } + if (0) { + /* Show details about what we're joining. */ + outf( + "joining line insert_space=%i a=%i (y=%f) to line b=%i (y=%f). nearest_adv=%f average_adv=%f", + insert_space, + a, + span_char_last(span_a)->y, + b, + span_char_first(span_b)->y, + nearest_adv, + average_adv + ); + outf("a: %s", span_string(alloc, span_a)); + outf("b: %s", span_string(alloc, span_b)); + } + } + + /* We might end up with two adjacent spaces here. But removing a + space could result in an empty line_t, which could break various + assumptions elsewhere. */ + + if (verbose) { + outf("Joining spans a=%i b=%i:", a, b); + outf(" %s", span_string2(alloc, span_a)); + outf(" %s", span_string2(alloc, span_b)); + } + if (extract_realloc2( + alloc, + &line_a->spans, + sizeof(span_t*) * line_a->spans_num, + sizeof(span_t*) * (line_a->spans_num + nearest_line->spans_num) + )) goto end; + { + int k; + for (k=0; kspans_num; ++k) { + line_a->spans[ line_a->spans_num + k] = nearest_line->spans[k]; + } + } + line_a->spans_num += nearest_line->spans_num; + + /* Ensure that we ignore nearest_line from now on. */ + extract_free(alloc, &nearest_line->spans); + extract_free(alloc, &nearest_line); + outfx("setting line[b=%i] to NULL", b); + lines[b] = NULL; + + num_joins += 1; + + if (b > a) { + /* We haven't yet tried appending any spans to nearest_line, so + the new extended line_a needs checking again. */ + a -= 1; + } + outfx("new line is:\n %s", line_string2(line_a)); + } + } + + { + /* Remove empty lines left behind after we appended pairs of lines. */ + int from; + int to; + int lines_num_old; + for (from=0, to=0; fromspans); + extract_free(alloc, &lines[a]); + } + } + extract_free(alloc, &lines); + } + return ret; +} + + +/* Returns max font size of all span_t's in an line_t. */ +static double line_font_size_max(line_t* line) +{ + double size_max = 0; + int i; + for (i=0; ispans_num; ++i) { + span_t* span = line->spans[i]; + /* fixme: should be double, which changes some output. */ + double size = matrix_expansion(span->trm); + if (size > size_max) { + size_max = size; + } + } + return size_max; +} + + + +/* Find distance between parallel lines line_a and line_b, both at . + + _-R + _- + A------------_P + \ _- + \ _B + \_- + Q + +A is (ax, ay) +B is (bx, by) +APB and PAR are both . + +AR and QBP are parallel, and are the lines of text a and b +respectively. + +AQB is a right angle. We need to find AQ. +*/ +static double line_distance( + double ax, + double ay, + double bx, + double by, + double angle + ) +{ + double dx = bx - ax; + double dy = by - ay; + + + return dx * sin(angle) + dy * cos(angle); +} + + +/* A comparison function for use with qsort(), for sorting paragraphs within a +page. */ +static int paragraphs_cmp(const void* a, const void* b) +{ + const paragraph_t* const* a_paragraph = a; + const paragraph_t* const* b_paragraph = b; + line_t* a_line = paragraph_line_first(*a_paragraph); + line_t* b_line = paragraph_line_first(*b_paragraph); + + span_t* a_span = line_span_first(a_line); + span_t* b_span = line_span_first(b_line); + + /* If ctm matrices differ, always return this diff first. Note that we + ignore .e and .f because if data is from ghostscript then .e and .f vary + for each span, and we don't care about these differences. */ + int d = matrix_cmp4(&a_span->ctm, &b_span->ctm); + if (d) return d; + + { + double a_angle = line_angle(a_line); + double b_angle = line_angle(b_line); + if (fabs(a_angle - b_angle) > 3.14/2) { + /* Give up if more than 90 deg. */ + return 0; + } + { + double angle = (a_angle + b_angle) / 2; + double ax = line_item_first(a_line)->x; + double ay = line_item_first(a_line)->y; + double bx = line_item_first(b_line)->x; + double by = line_item_first(b_line)->y; + double distance = line_distance(ax, ay, bx, by, angle); + if (distance > 0) return -1; + if (distance < 0) return +1; + } + } + return 0; +} + + +/* Creates a representation of line_t's that consists of a list of +paragraph_t's. + +We only join lines that are at the same angle and are adjacent. + +On entry: + Original value of *o_paragraphs and *o_paragraphs_num are ignored. + + points to array of line_t*'s, each pointing to + a line_t. + +On exit: + On sucess, returns zero, *o_paragraphs points to array of *o_paragraphs_num + paragraph_t*'s, each pointing to an paragraph_t. In the + array, paragraph_t's with same angle are sorted. + + On failure, returns -1 with errno set. *o_paragraphs and *o_paragraphs_num + are undefined. +*/ +static int make_paragraphs( + extract_alloc_t* alloc, + line_t** lines, + int lines_num, + paragraph_t*** o_paragraphs, + int* o_paragraphs_num + ) +{ + int ret = -1; + int a; + int num_joins; + paragraph_t** paragraphs = NULL; + + /* Start off with an paragraph_t for each line_t. */ + int paragraphs_num = lines_num; + if (extract_malloc(alloc, ¶graphs, sizeof(*paragraphs) * paragraphs_num)) goto end; + /* Ensure we can clean up after error when setting up. */ + for (a=0; alines_num = 0; + if (extract_malloc(alloc, ¶graphs[a]->lines, sizeof(line_t*) * 1)) goto end; + paragraphs[a]->lines_num = 1; + paragraphs[a]->lines[0] = lines[a]; + } + + num_joins = 0; + for (a=0; alines_num > 0); + + line_a = paragraph_line_last(paragraph_a); + angle_a = line_angle(line_a); + + verbose = 0; + + /* Look for nearest paragraph_t that could be appended to + paragraph_a. */ + for (b=0; bx; + double ay = line_item_last(line_a)->y; + double bx = line_item_first(line_b)->x; + double by = line_item_first(line_b)->y; + double distance = line_distance(ax, ay, bx, by, angle_a); + if (verbose) { + outf( + "angle_a=%f a=(%f %f) b=(%f %f) delta=(%f %f) distance=%f:", + angle_a * 180 / pi, + ax, ay, + bx, by, + bx - ax, + by - ay, + distance + ); + outf(" line_a=%s", line_string2(alloc, line_a)); + outf(" line_b=%s", line_string2(alloc, line_b)); + } + if (distance > 0) { + if (nearest_paragraph_distance == -1 + || distance < nearest_paragraph_distance) { + if (verbose) { + outf("updating nearest. distance=%f:", distance); + outf(" line_a=%s", line_string2(alloc, line_a)); + outf(" line_b=%s", line_string2(alloc, line_b)); + } + nearest_paragraph_distance = distance; + nearest_paragraph_b = b; + nearest_paragraph = paragraph_b; + } + } + } + } + + if (nearest_paragraph) { + double line_b_size = line_font_size_max( + paragraph_line_first(nearest_paragraph) + ); + line_t* line_b = paragraph_line_first(nearest_paragraph); + (void) line_b; /* Only used in outfx(). */ + if (nearest_paragraph_distance < 1.4 * line_b_size) { + /* Paragraphs are close together vertically compared to maximum + font size of first line in second paragraph, so we'll join them + into a single paragraph. */ + span_t* a_span; + int a_lines_num_new; + if (verbose) { + outf( + "joing paragraphs. a=(%f,%f) b=(%f,%f) nearest_paragraph_distance=%f line_b_size=%f", + line_item_last(line_a)->x, + line_item_last(line_a)->y, + line_item_first(line_b)->x, + line_item_first(line_b)->y, + nearest_paragraph_distance, + line_b_size + ); + outf(" %s", paragraph_string(alloc, paragraph_a)); + outf(" %s", paragraph_string(alloc, nearest_paragraph)); + outf("paragraph_a ctm=%s", + matrix_string(¶graph_a->lines[0]->spans[0]->ctm) + ); + outf("paragraph_a trm=%s", + matrix_string(¶graph_a->lines[0]->spans[0]->trm) + ); + } + /* Join these two paragraph_t's. */ + a_span = line_span_last(line_a); + if (span_char_last(a_span)->ucs == '-') { + /* remove trailing '-' at end of prev line. char_t doesn't + contain any malloc-heap pointers so this doesn't leak. */ + a_span->chars_num -= 1; + } + else { + /* Insert space before joining adjacent lines. */ + char_t* c_prev; + char_t* c; + if (span_append_c(alloc, line_span_last(line_a), ' ')) goto end; + c_prev = &a_span->chars[ a_span->chars_num-2]; + c = &a_span->chars[ a_span->chars_num-1]; + c->x = c_prev->x + c_prev->adv * a_span->ctm.a; + c->y = c_prev->y + c_prev->adv * a_span->ctm.c; + } + + a_lines_num_new = paragraph_a->lines_num + nearest_paragraph->lines_num; + if (extract_realloc2( + alloc, + ¶graph_a->lines, + sizeof(line_t*) * paragraph_a->lines_num, + sizeof(line_t*) * a_lines_num_new + )) goto end; + { + int i; + for (i=0; ilines_num; ++i) { + paragraph_a->lines[paragraph_a->lines_num + i] + = nearest_paragraph->lines[i]; + } + } + paragraph_a->lines_num = a_lines_num_new; + + /* Ensure that we skip nearest_paragraph in future. */ + extract_free(alloc, &nearest_paragraph->lines); + extract_free(alloc, &nearest_paragraph); + paragraphs[nearest_paragraph_b] = NULL; + + num_joins += 1; + outfx( + "have joined paragraph a=%i to snearest_paragraph_b=%i", + a, + nearest_paragraph_b + ); + + if (nearest_paragraph_b > a) { + /* We haven't yet tried appending any paragraphs to + nearest_paragraph_b, so the new extended paragraph_a needs + checking again. */ + a -= 1; + } + } + else { + outfx( + "Not joining paragraphs. nearest_paragraph_distance=%f line_b_size=%f", + nearest_paragraph_distance, + line_b_size + ); + } + } + } + + { + /* Remove empty paragraphs. */ + int from; + int to; + int paragraphs_num_old; + for (from=0, to=0; from %i", paragraphs_num, to); + paragraphs_num_old = paragraphs_num; + paragraphs_num = to; + if (extract_realloc2( + alloc, + ¶graphs, + sizeof(paragraph_t*) * paragraphs_num_old, + sizeof(paragraph_t*) * paragraphs_num + )) { + /* Should always succeed because we're not increasing allocation size, but + can fail with memento squeeze. */ + goto end; + } + } + + /* Sort paragraphs so they appear in correct order, using paragraphs_cmp(). + */ + qsort( + paragraphs, + paragraphs_num, + sizeof(paragraph_t*), paragraphs_cmp + ); + + *o_paragraphs = paragraphs; + *o_paragraphs_num = paragraphs_num; + ret = 0; + outf("Turned %i lines into %i paragraphs", + lines_num, + paragraphs_num + ); + + + end: + + if (ret) { + if (paragraphs) { + for (a=0; alines); + extract_free(alloc, ¶graphs[a]); + } + } + extract_free(alloc, ¶graphs); + } + return ret; +} + +int extract_document_join(extract_alloc_t* alloc, document_t* document) +{ + int ret = -1; + + /* For each page in we join spans into lines and paragraphs. A + line is a list of spans that are at the same angle and on the same line. A + paragraph is a list of lines that are at the same angle and close together. + */ + int p; + for (p=0; ppages_num; ++p) { + page_t* page = document->pages[p]; + outf("processing page %i: num_spans=%i", p, page->spans_num); + + if (make_lines( + alloc, + page->spans, + page->spans_num, + &page->lines, + &page->lines_num + )) goto end; + + if (make_paragraphs( + alloc, + page->lines, + page->lines_num, + &page->paragraphs, + &page->paragraphs_num + )) goto end; + } + + ret = 0; + + end: + + return ret; +} diff --git a/extract/src/mem.c b/extract/src/mem.c new file mode 100644 index 00000000..83b5032c --- /dev/null +++ b/extract/src/mem.c @@ -0,0 +1,51 @@ +#include "../include/extract_alloc.h" + +#include "mem.h" + +#include +#include +#include + +#ifdef _MSC_VER + #include "compat_va_copy.h" +#endif + + +void extract_bzero(void *b, size_t len) +{ + memset(b, 0, len); +} + +int extract_vasprintf(extract_alloc_t* alloc, char** out, const char* format, va_list va) +{ + int n; + int n2; + va_list va2; + va_copy(va2, va); + n = vsnprintf(NULL, 0, format, va); + if (n < 0) return n; + if (extract_malloc(alloc, out, n + 1)) return -1; + n2 = vsnprintf(*out, n + 1, format, va2); + va_end(va2); + assert(n2 == n); + return n2; +} + + +int extract_asprintf(extract_alloc_t* alloc, char** out, const char* format, ...) +{ + va_list va; + int ret; + va_start(va, format); + ret = extract_vasprintf(alloc, out, format, va); + va_end(va); + return ret; +} + +int extract_strdup(extract_alloc_t* alloc, const char* s, char** o_out) +{ + size_t l = strlen(s) + 1; + if (extract_malloc(alloc, o_out, l)) return -1; + memcpy(*o_out, s, l); + return 0; +} diff --git a/extract/src/mem.h b/extract/src/mem.h new file mode 100644 index 00000000..59729b1a --- /dev/null +++ b/extract/src/mem.h @@ -0,0 +1,14 @@ +#ifndef EXTRACT_MEM_H +#define EXTRACT_MEM_H + +#include +#include + +void extract_bzero(void *b, size_t len); + +int extract_vasprintf(extract_alloc_t* alloc, char** out, const char* format, va_list va); +int extract_asprintf(extract_alloc_t* alloc, char** out, const char* format, ...); + +int extract_strdup(extract_alloc_t* alloc, const char* s, char** o_out); + +#endif diff --git a/extract/src/memento.c b/extract/src/memento.c new file mode 100644 index 00000000..e62744be --- /dev/null +++ b/extract/src/memento.c @@ -0,0 +1,3574 @@ +/* Copyright (C) 2009-2020 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Inspired by Fortify by Simon P Bullen. */ + +/* Set the following if you're only looking for leaks, not memory overwrites + * to speed the operation */ +/* #define MEMENTO_LEAKONLY */ + +/* Set the following to keep extra details about the history of blocks */ +#define MEMENTO_DETAILS + +/* Don't keep blocks around if they'd mean losing more than a quarter of + * the freelist. */ +#define MEMENTO_FREELIST_MAX_SINGLE_BLOCK (MEMENTO_FREELIST_MAX/4) + +#define COMPILING_MEMENTO_C + +/* SHUT UP, MSVC. I KNOW WHAT I AM DOING. */ +#define _CRT_SECURE_NO_WARNINGS + +/* We have some GS specific tweaks; more for the GS build environment than + * anything else. */ +/* #define MEMENTO_GS_HACKS */ + +#ifdef MEMENTO_GS_HACKS +/* For GS we include malloc_.h. Anyone else would just include memento.h */ +#include "malloc_.h" +#include "memory_.h" +int atexit(void (*)(void)); +#else +#ifdef MEMENTO_MUPDF_HACKS +#include "mupdf/memento.h" +#else +#include "memento.h" +#endif +#include +#endif +#ifndef _MSC_VER +#include +#include +#include +#endif + +#include +#include +#include +#include + +#ifdef __ANDROID__ +#define MEMENTO_ANDROID +#include +#endif + +/* Hacks to portably print large sizes */ +#ifdef _MSC_VER +#define FMTZ "%llu" +#define FMTZ_CAST _int64 +#define FMTP "0x%p" +#else +#define FMTZ "%zu" +#define FMTZ_CAST size_t +#define FMTP "%p" +#endif + +#define UB(x) ((intptr_t)((x) & 0xFF)) +#define B2I(x) (UB(x) | (UB(x)<<8) | (UB(x)<<16) | (UB(x)<<24)) +#define B2P(x) ((void *)(B2I(x) | ((B2I(x)<<16)<<16))) +#define MEMENTO_PREFILL_UBYTE ((unsigned char)(MEMENTO_PREFILL)) +#define MEMENTO_PREFILL_USHORT (((unsigned short)MEMENTO_PREFILL_UBYTE) | (((unsigned short)MEMENTO_PREFILL_UBYTE)<<8)) +#define MEMENTO_PREFILL_UINT (((unsigned int)MEMENTO_PREFILL_USHORT) | (((unsigned int)MEMENTO_PREFILL_USHORT)<<16)) +#define MEMENTO_PREFILL_PTR (void *)(((uintptr_t)MEMENTO_PREFILL_UINT) | ((((uintptr_t)MEMENTO_PREFILL_UINT)<<16)<<16)) +#define MEMENTO_POSTFILL_UBYTE ((unsigned char)(MEMENTO_POSTFILL)) +#define MEMENTO_POSTFILL_USHORT (((unsigned short)MEMENTO_POSTFILL_UBYTE) | (((unsigned short)MEMENTO_POSTFILL_UBYTE)<<8)) +#define MEMENTO_POSTFILL_UINT (((unsigned int)MEMENTO_POSTFILL_USHORT) | (((unsigned int)MEMENTO_POSTFILL_USHORT)<<16)) +#define MEMENTO_POSTFILL_PTR (void *)(((uintptr_t)MEMENTO_POSTFILL_UINT) | ((((uintptr_t)MEMENTO_POSTFILL_UINT)<<16)<<16)) +#define MEMENTO_ALLOCFILL_UBYTE ((unsigned char)(MEMENTO_ALLOCFILL)) +#define MEMENTO_ALLOCFILL_USHORT (((unsigned short)MEMENTO_ALLOCFILL_UBYTE) | (((unsigned short)MEMENTO_ALLOCFILL_UBYTE)<<8)) +#define MEMENTO_ALLOCFILL_UINT (((unsigned int)MEMENTO_ALLOCFILL_USHORT) | (((unsigned int)MEMENTO_ALLOCFILL_USHORT)<<16)) +#define MEMENTO_ALLOCFILL_PTR (void *)(((uintptr_t)MEMENTO_ALLOCFILL_UINT) | ((((uintptr_t)MEMENTO_ALLOCFILL_UINT)<<16)<<16)) +#define MEMENTO_FREEFILL_UBYTE ((unsigned char)(MEMENTO_FREEFILL)) +#define MEMENTO_FREEFILL_USHORT (((unsigned short)MEMENTO_FREEFILL_UBYTE) | (((unsigned short)MEMENTO_FREEFILL_UBYTE)<<8)) +#define MEMENTO_FREEFILL_UINT (((unsigned int)MEMENTO_FREEFILL_USHORT) | (((unsigned int)MEMENTO_FREEFILL_USHORT)<<16)) +#define MEMENTO_FREEFILL_PTR (void *)(((uintptr_t)MEMENTO_FREEFILL_UINT) | ((((uintptr_t)MEMENTO_FREEFILL_UINT)<<16)<<16)) + +#ifdef MEMENTO + +#ifndef MEMENTO_CPP_EXTRAS_ONLY + +#ifdef MEMENTO_ANDROID +#include + +static char log_buffer[4096]; +static int log_fill = 0; + +static char log_buffer2[4096]; + +static int +android_fprintf(FILE *file, const char *fmt, ...) +{ + va_list args; + char *p, *q; + + va_start(args, fmt); + vsnprintf(log_buffer2, sizeof(log_buffer2)-1, fmt, args); + va_end(args); + + /* Ensure we are always null terminated */ + log_buffer2[sizeof(log_buffer2)-1] = 0; + + p = log_buffer2; + q = p; + do + { + /* Find the end of the string, or the next \n */ + while (*p && *p != '\n') + p++; + + /* We need to output from q to p. Limit ourselves to what + * will fit in the existing */ + if (p - q >= sizeof(log_buffer)-1 - log_fill) + p = q + sizeof(log_buffer)-1 - log_fill; + + memcpy(&log_buffer[log_fill], q, p-q); + log_fill += p-q; + if (*p == '\n') + { + log_buffer[log_fill] = 0; + __android_log_print(ANDROID_LOG_ERROR, "memento", "%s", log_buffer); + usleep(1); + log_fill = 0; + p++; /* Skip over the \n */ + } + else if (log_fill >= sizeof(log_buffer)-1) + { + log_buffer[sizeof(log_buffer2)-1] = 0; + __android_log_print(ANDROID_LOG_ERROR, "memento", "%s", log_buffer); + usleep(1); + log_fill = 0; + } + q = p; + } + while (*p); + + return 0; +} + +#define fprintf android_fprintf +#define MEMENTO_STACKTRACE_METHOD 3 +#endif + +/* _WIN64 defined implies _WIN32 will be */ +#ifdef _WIN32 +#include + +static int +windows_fprintf(FILE *file, const char *fmt, ...) +{ + va_list args; + char text[4096]; + int ret; + + va_start(args, fmt); + ret = vfprintf(file, fmt, args); + va_end(args); + + va_start(args, fmt); + vsnprintf(text, 4096, fmt, args); + OutputDebugStringA(text); + va_end(args); + + return ret; +} + +#define fprintf windows_fprintf +#endif + +#ifndef MEMENTO_STACKTRACE_METHOD +#ifdef __GNUC__ +#define MEMENTO_STACKTRACE_METHOD 1 +#endif +#ifdef _WIN32 +#define MEMENTO_STACKTRACE_METHOD 2 +#endif +#endif + +#if defined(__linux__) || defined(__OpenBSD__) +#define MEMENTO_HAS_FORK +#elif defined(__APPLE__) && defined(__MACH__) +#define MEMENTO_HAS_FORK +#endif + +/* Define the underlying allocators, just in case */ +void *MEMENTO_UNDERLYING_MALLOC(size_t); +void MEMENTO_UNDERLYING_FREE(void *); +void *MEMENTO_UNDERLYING_REALLOC(void *,size_t); +void *MEMENTO_UNDERLYING_CALLOC(size_t,size_t); + +/* And some other standard functions we use. We don't include the header + * files, just in case they pull in unexpected others. */ +int atoi(const char *); +char *getenv(const char *); + +/* How far to search for pointers in each block when calculating nestings */ +/* mupdf needs at least 34000ish (sizeof(fz_shade))/ */ +#define MEMENTO_PTRSEARCH 65536 + +#ifndef MEMENTO_MAXPATTERN +#define MEMENTO_MAXPATTERN 0 +#endif + +#ifdef MEMENTO_GS_HACKS +#include "valgrind.h" +#else +#ifdef HAVE_VALGRIND +#include "valgrind/memcheck.h" +#else +#define VALGRIND_MAKE_MEM_NOACCESS(p,s) do { } while (0==1) +#define VALGRIND_MAKE_MEM_UNDEFINED(p,s) do { } while (0==1) +#define VALGRIND_MAKE_MEM_DEFINED(p,s) do { } while (0==1) +#endif +#endif + +enum { + Memento_PreSize = 16, + Memento_PostSize = 16 +}; + +/* Some compile time checks */ +typedef struct +{ + char MEMENTO_PRESIZE_MUST_BE_A_MULTIPLE_OF_4[Memento_PreSize & 3 ? -1 : 1]; + char MEMENTO_POSTSIZE_MUST_BE_A_MULTIPLE_OF_4[Memento_PostSize & 3 ? -1 : 1]; + char MEMENTO_POSTSIZE_MUST_BE_AT_LEAST_4[Memento_PostSize >= 4 ? 1 : -1]; + char MEMENTO_PRESIZE_MUST_BE_AT_LEAST_4[Memento_PreSize >= 4 ? 1 : -1]; +} MEMENTO_SANITY_CHECK_STRUCT; + +#define MEMENTO_UINT32 unsigned int +#define MEMENTO_UINT16 unsigned short + +#define MEMENTO_PREFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_PREFILL | (MEMENTO_PREFILL <<8) | (MEMENTO_PREFILL <<16) |(MEMENTO_PREFILL <<24))) +#define MEMENTO_POSTFILL_UINT16 ((MEMENTO_UINT16)(MEMENTO_POSTFILL | (MEMENTO_POSTFILL<<8))) +#define MEMENTO_POSTFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_POSTFILL | (MEMENTO_POSTFILL<<8) | (MEMENTO_POSTFILL<<16) |(MEMENTO_POSTFILL<<24))) +#define MEMENTO_FREEFILL_UINT16 ((MEMENTO_UINT16)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8))) +#define MEMENTO_FREEFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8) | (MEMENTO_FREEFILL<<16) |(MEMENTO_FREEFILL<<24))) + +enum { + Memento_Flag_OldBlock = 1, + Memento_Flag_HasParent = 2, + Memento_Flag_BreakOnFree = 4, + Memento_Flag_BreakOnRealloc = 8, + Memento_Flag_Freed = 16, + Memento_Flag_KnownLeak = 32, + Memento_Flag_Reported = 64 +}; + +enum { + Memento_EventType_malloc = 0, + Memento_EventType_calloc = 1, + Memento_EventType_realloc = 2, + Memento_EventType_free = 3, + Memento_EventType_new = 4, + Memento_EventType_delete = 5, + Memento_EventType_newArray = 6, + Memento_EventType_deleteArray = 7, + Memento_EventType_takeRef = 8, + Memento_EventType_dropRef = 9, + Memento_EventType_reference = 10, + Memento_EventType_strdup = 11, + Memento_EventType_asprintf = 12, + Memento_EventType_vasprintf = 13 +}; + +static const char *eventType[] = +{ + "malloc", + "calloc", + "realloc", + "free", + "new", + "delete", + "new[]", + "delete[]", + "takeRef", + "dropRef", + "reference", + "strdup", + "asprintf", + "vasprintf" +}; + +/* When we list leaked blocks at the end of execution, we search for pointers + * between blocks in order to be able to give a nice nested view. + * Unfortunately, if you have are running your own allocator (such as + * postscript's chunk allocator) you can often find that the header of the + * block always contains pointers to next or previous blocks. This tends to + * mean the nesting displayed is "uninteresting" at best :) + * + * As a hack to get around this, we have a define MEMENTO_SKIP_SEARCH that + * indicates how many bytes to skip over at the start of the chunk. + * This may cause us to miss true nestings, but such is life... + */ +#ifndef MEMENTO_SEARCH_SKIP +#ifdef MEMENTO_GS_HACKS +#define MEMENTO_SEARCH_SKIP (2*sizeof(void *)) +#else +#define MEMENTO_SEARCH_SKIP 0 +#endif +#endif + +#define MEMENTO_CHILD_MAGIC ((Memento_BlkHeader *)('M' | ('3' << 8) | ('m' << 16) | ('3' << 24))) +#define MEMENTO_SIBLING_MAGIC ((Memento_BlkHeader *)('n' | ('t' << 8) | ('0' << 16) | ('!' << 24))) + +#ifdef MEMENTO_DETAILS +typedef struct Memento_BlkDetails Memento_BlkDetails; + +struct Memento_BlkDetails +{ + Memento_BlkDetails *next; + char type; + char count; + int sequence; + void *stack[1]; +}; +#endif /* MEMENTO_DETAILS */ + +typedef struct Memento_BlkHeader Memento_BlkHeader; + +struct Memento_BlkHeader +{ + size_t rawsize; + int sequence; + int lastCheckedOK; + int flags; + Memento_BlkHeader *next; + Memento_BlkHeader *prev; /* Reused as 'parent' when printing nested list */ + + const char *label; + + /* Entries for nesting display calculations. Set to magic + * values at all other time. */ + Memento_BlkHeader *child; + Memento_BlkHeader *sibling; + +#ifdef MEMENTO_DETAILS + Memento_BlkDetails *details; + Memento_BlkDetails **details_tail; +#endif + + char preblk[Memento_PreSize]; +}; + +/* In future this could (should) be a smarter data structure, like, say, + * splay trees. For now, we use a list. + */ +typedef struct Memento_Blocks +{ + Memento_BlkHeader *head; + Memento_BlkHeader *tail; +} Memento_Blocks; + +/* What sort of Mutex should we use? */ +#ifdef MEMENTO_LOCKLESS +typedef int Memento_mutex; + +static void Memento_initMutex(Memento_mutex *m) +{ + (void)m; +} + +#define MEMENTO_DO_LOCK() do { } while (0) +#define MEMENTO_DO_UNLOCK() do { } while (0) + +#else +#if defined(_WIN32) || defined(_WIN64) +/* Windows */ +typedef CRITICAL_SECTION Memento_mutex; + +static void Memento_initMutex(Memento_mutex *m) +{ + InitializeCriticalSection(m); +} + +#define MEMENTO_DO_LOCK() \ + EnterCriticalSection(&memento.mutex) +#define MEMENTO_DO_UNLOCK() \ + LeaveCriticalSection(&memento.mutex) + +#else +#include +typedef pthread_mutex_t Memento_mutex; + +static void Memento_initMutex(Memento_mutex *m) +{ + pthread_mutex_init(m, NULL); +} + +#define MEMENTO_DO_LOCK() \ + pthread_mutex_lock(&memento.mutex) +#define MEMENTO_DO_UNLOCK() \ + pthread_mutex_unlock(&memento.mutex) + +#endif +#endif + +typedef struct { + int begin; + int end; +} Memento_range; + +/* And our global structure */ +static struct { + int inited; + Memento_Blocks used; + Memento_Blocks free; + size_t freeListSize; + int sequence; + int paranoia; + int paranoidAt; + int countdown; + int lastChecked; + int breakAt; + int failAt; + int failing; + int nextFailAt; + int squeezeAt; + int squeezing; + int segv; + int pattern; + int nextPattern; + int patternBit; + int leaking; + int hideMultipleReallocs; + int abortOnLeak; + int abortOnCorruption; + size_t maxMemory; + size_t alloc; + size_t peakAlloc; + size_t totalAlloc; + size_t numMallocs; + size_t numFrees; + size_t numReallocs; + Memento_mutex mutex; + Memento_range *squeezes; + int squeezes_num; + int squeezes_pos; +} memento; + +#define MEMENTO_EXTRASIZE (sizeof(Memento_BlkHeader) + Memento_PostSize) + +/* Round up size S to the next multiple of N (where N is a power of 2) */ +#define MEMENTO_ROUNDUP(S,N) ((S + N-1)&~(N-1)) + +#define MEMBLK_SIZE(s) MEMENTO_ROUNDUP(s + MEMENTO_EXTRASIZE, MEMENTO_MAXALIGN) + +#define MEMBLK_FROMBLK(B) (&((Memento_BlkHeader*)(void *)(B))[-1]) +#define MEMBLK_TOBLK(B) ((void*)(&((Memento_BlkHeader*)(void*)(B))[1])) +#define MEMBLK_POSTPTR(B) \ + (&((unsigned char *)(void *)(B))[(B)->rawsize + sizeof(Memento_BlkHeader)]) + +enum +{ + SkipStackBackTraceLevels = 4 +}; + +#if defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 1 +extern size_t backtrace(void **, int); +extern void backtrace_symbols_fd(void **, size_t, int); +extern char **backtrace_symbols(void **, size_t); + +#define MEMENTO_BACKTRACE_MAX 256 +static void (*print_stack_value)(void *address); + +/* Libbacktrace gubbins - relies on us having libdl to load the .so */ +#ifdef HAVE_LIBDL +#include + +typedef void (*backtrace_error_callback) (void *data, const char *msg, int errnum); + +typedef struct backtrace_state *(*backtrace_create_state_type)( + const char *filename, int threaded, + backtrace_error_callback error_callback, void *data); + +typedef int (*backtrace_full_callback) (void *data, uintptr_t pc, + const char *filename, int lineno, + const char *function); + +typedef int (*backtrace_pcinfo_type)(struct backtrace_state *state, + uintptr_t pc, + backtrace_full_callback callback, + backtrace_error_callback error_callback, + void *data); + +typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc, + const char *symname, + uintptr_t symval, + uintptr_t symsize); + +typedef int (*backtrace_syminfo_type)(struct backtrace_state *state, + uintptr_t addr, + backtrace_syminfo_callback callback, + backtrace_error_callback error_callback, + void *data); + +static backtrace_syminfo_type backtrace_syminfo; +static backtrace_create_state_type backtrace_create_state; +static backtrace_pcinfo_type backtrace_pcinfo; +static struct backtrace_state *my_backtrace_state; +static void *libbt; +static char backtrace_exe[4096]; +static void *current_addr; + +static void error2_cb(void *data, const char *msg, int errnum) +{ + (void)data; + (void)msg; + (void)errnum; +} + +static void syminfo_cb(void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize) +{ + (void)data; + (void)symval; + (void)symsize; + if (sizeof(void *) == 4) + fprintf(stderr, " 0x%08lx %s\n", pc, symname?symname:"?"); + else + fprintf(stderr, " 0x%016lx %s\n", pc, symname?symname:"?"); +} + +static void error_cb(void *data, const char *msg, int errnum) +{ + (void)data; + (void)msg; + (void)errnum; + backtrace_syminfo(my_backtrace_state, + (uintptr_t)current_addr, + syminfo_cb, + error2_cb, + NULL); +} + +static int full_cb(void *data, uintptr_t pc, const char *fname, int line, const char *fn) +{ + (void)data; + if (sizeof(void *) == 4) + fprintf(stderr, " 0x%08lx %s(%s:%d)\n", pc, fn?fn:"?", fname?fname:"?", line); + else + fprintf(stderr, " 0x%016lx %s(%s:%d)\n", pc, fn?fn:"?", fname?fname:"?", line); + return 0; +} + +static void print_stack_libbt(void *addr) +{ + current_addr = addr; + backtrace_pcinfo(my_backtrace_state, + (uintptr_t)addr, + full_cb, + error_cb, + NULL); +} + +static void print_stack_libbt_failed(void *addr) +{ + char **strings; +#if 0 + /* Let's use a hack from Julian Smith to call gdb to extract the information */ + /* Disabled for now, as I can't make this work. */ + static char command[1024]; + int e; + static int gdb_invocation_failed = 0; + + if (gdb_invocation_failed == 0) + { + snprintf(command, sizeof(command), + //"gdb -q --batch -p=%i -ex 'info line *%p' -ex quit 2>/dev/null", + "gdb -q --batch -p=%i -ex 'info line *%p' -ex quit 2>/dev/null| egrep -v '(Thread debugging using)|(Using host libthread_db library)|(A debugging session is active)|(will be detached)|(Quit anyway)|(No such file or directory)|(^0x)|(^$)'", + getpid(), addr); + printf("%s\n", command); + e = system(command); + if (e == 0) + return; /* That'll do! */ + gdb_invocation_failed = 1; /* If it's failed once, it'll probably keep failing. */ + } +#endif + + /* We couldn't even get gdb! Make do. */ + strings = backtrace_symbols(&addr, 1); + + if (strings == NULL || strings[0] == NULL) + { + if (sizeof(void *) == 4) + fprintf(stderr, " [0x%08lx]\n", (uintptr_t)addr); + else + fprintf(stderr, " [0x%016lx]\n", (uintptr_t)addr); + } + else + { + fprintf(stderr, " %s\n", strings[0]); + } + (free)(strings); +} + +static int init_libbt(void) +{ + static int libbt_inited = 0; + + if (libbt_inited) + return 0; + libbt_inited = 1; + + libbt = dlopen("libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/opt/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/usr/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/usr/local/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + goto fail; + + backtrace_create_state = dlsym(libbt, "backtrace_create_state"); + backtrace_syminfo = dlsym(libbt, "backtrace_syminfo"); + backtrace_pcinfo = dlsym(libbt, "backtrace_pcinfo"); + + if (backtrace_create_state == NULL || + backtrace_syminfo == NULL || + backtrace_pcinfo == NULL) + { + goto fail; + } + + my_backtrace_state = backtrace_create_state(backtrace_exe, + 1 /*BACKTRACE_SUPPORTS_THREADS*/, + error_cb, + NULL); + if (my_backtrace_state == NULL) + goto fail; + + print_stack_value = print_stack_libbt; + + return 1; + + fail: + fprintf(stderr, + "MEMENTO: libbacktrace.so failed to load; backtraces will be sparse.\n" + "MEMENTO: See memento.h for how to rectify this.\n"); + libbt = NULL; + backtrace_create_state = NULL; + backtrace_syminfo = NULL; + print_stack_value = print_stack_libbt_failed; + return 0; +} +#endif + +static void print_stack_default(void *addr) +{ + char **strings = backtrace_symbols(&addr, 1); + + if (strings == NULL || strings[0] == NULL) + { + fprintf(stderr, " ["FMTP"]\n", addr); + } +#ifdef HAVE_LIBDL + else if (strchr(strings[0], ':') == NULL) + { + /* Probably a "path [address]" format string */ + char *s = strchr(strings[0], ' '); + + if (s != strings[0]) + { + memcpy(backtrace_exe, strings[0], s - strings[0]); + backtrace_exe[s-strings[0]] = 0; + init_libbt(); + print_stack_value(addr); + } + } +#endif + else + { + fprintf(stderr, " %s\n", strings[0]); + } + free(strings); +} + +static void Memento_initStacktracer(void) +{ + print_stack_value = print_stack_default; +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + size_t num; + + num = backtrace(&stack[0], MEMENTO_BACKTRACE_MAX); + + *skip = SkipStackBackTraceLevels; + if (num <= SkipStackBackTraceLevels) + return 0; + return (int)(num-SkipStackBackTraceLevels); +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ + int i; + + for (i = 0; i < numberOfFrames; i++) + { + print_stack_value(stack[i]); + } +} +#elif defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 2 +#include + +/* We use DbgHelp.dll rather than DbgHelp.lib. This avoids us needing + * extra link time complications, and enables us to fall back gracefully + * if the DLL cannot be found. + * + * To achieve this we have our own potted versions of the required types + * inline here. + */ +#ifdef _WIN64 +typedef DWORD64 DWORD_NATIVESIZED; +#else +typedef DWORD DWORD_NATIVESIZED; +#endif + +#define MEMENTO_BACKTRACE_MAX 64 + +typedef USHORT (__stdcall *My_CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG); + +typedef struct MY_IMAGEHLP_LINE { + DWORD SizeOfStruct; + PVOID Key; + DWORD LineNumber; + PCHAR FileName; + DWORD_NATIVESIZED Address; +} MY_IMAGEHLP_LINE, *MY_PIMAGEHLP_LINE; + +typedef BOOL (__stdcall *My_SymGetLineFromAddrType)(HANDLE hProcess, DWORD_NATIVESIZED dwAddr, PDWORD pdwDisplacement, MY_PIMAGEHLP_LINE Line); + +typedef struct MY_SYMBOL_INFO { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG info; + ULONG Size; + ULONG64 ModBase; // Base Address of module containing this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + CHAR Name[1]; // Name of symbol +} MY_SYMBOL_INFO, *MY_PSYMBOL_INFO; + +typedef BOOL (__stdcall *My_SymFromAddrType)(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, MY_PSYMBOL_INFO Symbol); +typedef BOOL (__stdcall *My_SymInitializeType)(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess); + +static My_CaptureStackBackTraceType Memento_CaptureStackBackTrace; +static My_SymGetLineFromAddrType Memento_SymGetLineFromAddr; +static My_SymFromAddrType Memento_SymFromAddr; +static My_SymInitializeType Memento_SymInitialize; +static HANDLE Memento_process; + +static void Memento_initStacktracer(void) +{ + HMODULE mod = LoadLibrary("kernel32.dll"); + + if (mod == NULL) + return; + Memento_CaptureStackBackTrace = (My_CaptureStackBackTraceType)(GetProcAddress(mod, "RtlCaptureStackBackTrace")); + if (Memento_CaptureStackBackTrace == NULL) + return; + mod = LoadLibrary("Dbghelp.dll"); + if (mod == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_SymGetLineFromAddr = + (My_SymGetLineFromAddrType)(GetProcAddress(mod, +#ifdef _WIN64 + "SymGetLineFromAddr64" +#else + "SymGetLineFromAddr" +#endif + )); + if (Memento_SymGetLineFromAddr == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_SymFromAddr = (My_SymFromAddrType)(GetProcAddress(mod, "SymFromAddr")); + if (Memento_SymFromAddr == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_SymInitialize = (My_SymInitializeType)(GetProcAddress(mod, "SymInitialize")); + if (Memento_SymInitialize == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_process = GetCurrentProcess(); + Memento_SymInitialize(Memento_process, NULL, TRUE); +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + if (Memento_CaptureStackBackTrace == NULL) + return 0; + + *skip = 0; + /* Limit us to 63 levels due to windows bug */ + return Memento_CaptureStackBackTrace(SkipStackBackTraceLevels, 63-SkipStackBackTraceLevels, stack, NULL); +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ + MY_IMAGEHLP_LINE line; + int i; + char symbol_buffer[sizeof(MY_SYMBOL_INFO) + 1024 + 1]; + MY_SYMBOL_INFO *symbol = (MY_SYMBOL_INFO *)symbol_buffer; + + symbol->MaxNameLen = 1024; + symbol->SizeOfStruct = sizeof(MY_SYMBOL_INFO); + line.SizeOfStruct = sizeof(MY_IMAGEHLP_LINE); + for (i = 0; i < numberOfFrames; i++) + { + DWORD64 dwDisplacement64; + DWORD dwDisplacement; + Memento_SymFromAddr(Memento_process, (DWORD64)(stack[i]), &dwDisplacement64, symbol); + Memento_SymGetLineFromAddr(Memento_process, (DWORD_NATIVESIZED)(stack[i]), &dwDisplacement, &line); + fprintf(stderr, " %s in %s:%d\n", symbol->Name, line.FileName, line.LineNumber); + } +} +#elif defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 3 + +#include +#include + +/* From cxxabi.h */ +extern char* __cxa_demangle(const char* mangled_name, + char* output_buffer, + size_t* length, + int* status); + +static void Memento_initStacktracer(void) +{ +} + +#define MEMENTO_BACKTRACE_MAX 256 + +typedef struct +{ + int count; + void **addr; +} my_unwind_details; + +static _Unwind_Reason_Code unwind_populate_callback(struct _Unwind_Context *context, + void *arg) +{ + my_unwind_details *uw = (my_unwind_details *)arg; + int count = uw->count; + + if (count >= MEMENTO_BACKTRACE_MAX) + return _URC_END_OF_STACK; + + uw->addr[count] = (void *)_Unwind_GetIP(context); + uw->count++; + + return _URC_NO_REASON; +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + my_unwind_details uw = { 0, stack }; + + *skip = 0; + + /* Collect the backtrace. Deliberately only unwind once, + * and avoid using malloc etc until this completes just + * in case. */ + _Unwind_Backtrace(unwind_populate_callback, &uw); + if (uw.count <= SkipStackBackTraceLevels) + return 0; + + *skip = SkipStackBackTraceLevels; + return uw.count-SkipStackBackTraceLevels; +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ + int i; + + for (i = 0; i < numberOfFrames; i++) + { + Dl_info info; + if (dladdr(stack[i], &info)) + { + int status = 0; + const char *sym = info.dli_sname ? info.dli_sname : ""; + char *demangled = __cxa_demangle(sym, NULL, 0, &status); + int offset = stack[i] - info.dli_saddr; + fprintf(stderr, " ["FMTP"]%s(+0x%x)\n", stack[i], demangled && status == 0 ? demangled : sym, offset); + free(demangled); + } + else + { + fprintf(stderr, " ["FMTP"]\n", stack[i]); + } + } +} + +#else +static void Memento_initStacktracer(void) +{ +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + *skip = 0; + return 0; +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ +} +#endif /* MEMENTO_STACKTRACE_METHOD */ + +#ifdef MEMENTO_DETAILS +static void Memento_storeDetails(Memento_BlkHeader *head, int type) +{ + void *stack[MEMENTO_BACKTRACE_MAX]; + Memento_BlkDetails *details; + int count; + int skip; + + if (head == NULL) + return; + +#ifdef MEMENTO_STACKTRACE_METHOD + count = Memento_getStacktrace(stack, &skip); +#else + skip = 0; + count = 0; +#endif + + details = MEMENTO_UNDERLYING_MALLOC(sizeof(*details) + (count-1) * sizeof(void *)); + if (details == NULL) + return; + + if (count) + memcpy(&details->stack, &stack[skip], count * sizeof(void *)); + + details->type = (char)type; + details->count = (char)count; + details->sequence = memento.sequence; + details->next = NULL; + VALGRIND_MAKE_MEM_DEFINED(&head->details_tail, sizeof(head->details_tail)); + *head->details_tail = details; + head->details_tail = &details->next; + VALGRIND_MAKE_MEM_NOACCESS(&head->details_tail, sizeof(head->details_tail)); +} +#endif + +void (Memento_bt)(void) +{ +#ifdef MEMENTO_STACKTRACE_METHOD + void *stack[MEMENTO_BACKTRACE_MAX]; + int count; + int skip; + + count = Memento_getStacktrace(stack, &skip); + Memento_showStacktrace(&stack[skip-2], count-skip+2); +#endif +} + +static void Memento_bt_internal(int skip2) +{ +#ifdef MEMENTO_STACKTRACE_METHOD + void *stack[MEMENTO_BACKTRACE_MAX]; + int count; + int skip; + + count = Memento_getStacktrace(stack, &skip); + Memento_showStacktrace(&stack[skip+skip2], count-skip-skip2); +#endif +} + +static int Memento_checkAllMemoryLocked(void); + +void Memento_breakpoint(void) +{ + /* A handy externally visible function for breakpointing */ +#if 0 /* Enable this to force automatic breakpointing */ +#ifndef NDEBUG +#ifdef _MSC_VER + __asm int 3; +#endif +#endif +#endif +} + +static void Memento_init(void); + +#define MEMENTO_LOCK() \ +do { if (!memento.inited) Memento_init(); MEMENTO_DO_LOCK(); } while (0) + +#define MEMENTO_UNLOCK() \ +do { MEMENTO_DO_UNLOCK(); } while (0) + +/* Do this as a macro to prevent another level in the callstack, + * which is annoying while stepping. */ +#define Memento_breakpointLocked() \ +do { MEMENTO_UNLOCK(); Memento_breakpoint(); MEMENTO_LOCK(); } while (0) + +static void Memento_addBlockHead(Memento_Blocks *blks, + Memento_BlkHeader *b, + int type) +{ + if (blks->tail == NULL) + blks->tail = b; + b->next = blks->head; + b->prev = NULL; + if (blks->head) + { + VALGRIND_MAKE_MEM_DEFINED(&blks->head->prev, sizeof(blks->head->prev)); + blks->head->prev = b; + VALGRIND_MAKE_MEM_NOACCESS(&blks->head->prev, sizeof(blks->head->prev)); + } + blks->head = b; +#ifndef MEMENTO_LEAKONLY + memset(b->preblk, MEMENTO_PREFILL, Memento_PreSize); + memset(MEMBLK_POSTPTR(b), MEMENTO_POSTFILL, Memento_PostSize); +#endif + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(b), Memento_PostSize); + if (type == 0) { /* malloc */ + VALGRIND_MAKE_MEM_UNDEFINED(MEMBLK_TOBLK(b), b->rawsize); + } else if (type == 1) { /* free */ + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_TOBLK(b), b->rawsize); + } + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); +} + +static void Memento_addBlockTail(Memento_Blocks *blks, + Memento_BlkHeader *b, + int type) +{ + VALGRIND_MAKE_MEM_DEFINED(&blks->tail, sizeof(Memento_BlkHeader *)); + if (blks->head == NULL) + blks->head = b; + b->prev = blks->tail; + b->next = NULL; + if (blks->tail) { + VALGRIND_MAKE_MEM_DEFINED(&blks->tail->next, sizeof(blks->tail->next)); + blks->tail->next = b; + VALGRIND_MAKE_MEM_NOACCESS(&blks->tail->next, sizeof(blks->tail->next)); + } + blks->tail = b; +#ifndef MEMENTO_LEAKONLY + memset(b->preblk, MEMENTO_PREFILL, Memento_PreSize); + memset(MEMBLK_POSTPTR(b), MEMENTO_POSTFILL, Memento_PostSize); +#endif + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(b), Memento_PostSize); + if (type == 0) { /* malloc */ + VALGRIND_MAKE_MEM_UNDEFINED(MEMBLK_TOBLK(b), b->rawsize); + } else if (type == 1) { /* free */ + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_TOBLK(b), b->rawsize); + } + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); + VALGRIND_MAKE_MEM_NOACCESS(&blks->tail, sizeof(Memento_BlkHeader *)); +} + +typedef struct BlkCheckData { + int found; + int preCorrupt; + int postCorrupt; + int freeCorrupt; + size_t index; +} BlkCheckData; + +#ifndef MEMENTO_LEAKONLY +static int Memento_Internal_checkAllocedBlock(Memento_BlkHeader *b, void *arg) +{ + int i; + MEMENTO_UINT32 *ip; + unsigned char *p; + BlkCheckData *data = (BlkCheckData *)arg; + + ip = (MEMENTO_UINT32 *)(void *)(b->preblk); + i = Memento_PreSize>>2; + do { + if (*ip++ != MEMENTO_PREFILL_UINT32) + goto pre_corrupt; + } while (--i); + if (0) { +pre_corrupt: + data->preCorrupt = 1; + } + /* Postfill may not be aligned, so have to be slower */ + p = MEMBLK_POSTPTR(b); + i = Memento_PostSize-4; + if ((intptr_t)p & 1) + { + if (*p++ != MEMENTO_POSTFILL) + goto post_corrupt; + i--; + } + if ((intptr_t)p & 2) + { + if (*(MEMENTO_UINT16 *)p != MEMENTO_POSTFILL_UINT16) + goto post_corrupt; + p += 2; + i -= 2; + } + do { + if (*(MEMENTO_UINT32 *)p != MEMENTO_POSTFILL_UINT32) + goto post_corrupt; + p += 4; + i -= 4; + } while (i >= 0); + if (i & 2) + { + if (*(MEMENTO_UINT16 *)p != MEMENTO_POSTFILL_UINT16) + goto post_corrupt; + p += 2; + } + if (i & 1) + { + if (*p != MEMENTO_POSTFILL) + goto post_corrupt; + } + if (0) { +post_corrupt: + data->postCorrupt = 1; + } + if ((data->freeCorrupt | data->preCorrupt | data->postCorrupt) == 0) { + b->lastCheckedOK = memento.sequence; + } + data->found |= 1; + return 0; +} + +static int Memento_Internal_checkFreedBlock(Memento_BlkHeader *b, void *arg) +{ + size_t i; + unsigned char *p; + BlkCheckData *data = (BlkCheckData *)arg; + + p = MEMBLK_TOBLK(b); /* p will always be aligned */ + i = b->rawsize; + /* Attempt to speed this up by checking an (aligned) int at a time */ + if (i >= 4) { + i -= 4; + do { + if (*(MEMENTO_UINT32 *)p != MEMENTO_FREEFILL_UINT32) + goto mismatch4; + p += 4; + i -= 4; + } while (i > 0); + i += 4; + } + if (i & 2) { + if (*(MEMENTO_UINT16 *)p != MEMENTO_FREEFILL_UINT16) + goto mismatch; + p += 2; + i -= 2; + } + if (0) { +mismatch4: + i += 4; + } +mismatch: + while (i) { + if (*p++ != (unsigned char)MEMENTO_FREEFILL) + break; + i--; + } + if (i) { + data->freeCorrupt = 1; + data->index = b->rawsize-i; + } + return Memento_Internal_checkAllocedBlock(b, arg); +} +#endif /* MEMENTO_LEAKONLY */ + +static void Memento_removeBlock(Memento_Blocks *blks, + Memento_BlkHeader *b) +{ + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b)); + if (b->next) { + VALGRIND_MAKE_MEM_DEFINED(&b->next->prev, sizeof(b->next->prev)); + b->next->prev = b->prev; + VALGRIND_MAKE_MEM_NOACCESS(&b->next->prev, sizeof(b->next->prev)); + } + if (b->prev) { + VALGRIND_MAKE_MEM_DEFINED(&b->prev->next, sizeof(b->prev->next)); + b->prev->next = b->next; + VALGRIND_MAKE_MEM_NOACCESS(&b->prev->next, sizeof(b->prev->next)); + } + if (blks->tail == b) + blks->tail = b->prev; + if (blks->head == b) + blks->head = b->next; +} + +static void free_block(Memento_BlkHeader *head) +{ +#ifdef MEMENTO_DETAILS + Memento_BlkDetails *details = head->details; + + while (details) + { + Memento_BlkDetails *next = details->next; + MEMENTO_UNDERLYING_FREE(details); + details = next; + } +#endif + MEMENTO_UNDERLYING_FREE(head); +} + +static int Memento_Internal_makeSpace(size_t space) +{ + /* If too big, it can never go on the freelist */ + if (space > MEMENTO_FREELIST_MAX_SINGLE_BLOCK) + return 0; + /* Pretend we added it on. */ + memento.freeListSize += space; + /* Ditch blocks until it fits within our limit */ + while (memento.freeListSize > MEMENTO_FREELIST_MAX) { + Memento_BlkHeader *head = memento.free.head; + VALGRIND_MAKE_MEM_DEFINED(head, sizeof(*head)); + memento.free.head = head->next; + memento.freeListSize -= MEMBLK_SIZE(head->rawsize); + free_block(head); + } + /* Make sure we haven't just completely emptied the free list */ + /* (This should never happen, but belt and braces... */ + if (memento.free.head == NULL) + memento.free.tail = NULL; + return 1; +} + +static int Memento_appBlocks(Memento_Blocks *blks, + int (*app)(Memento_BlkHeader *, + void *), + void *arg) +{ + Memento_BlkHeader *head = blks->head; + Memento_BlkHeader *next; + int result; + while (head) { + VALGRIND_MAKE_MEM_DEFINED(head, sizeof(Memento_BlkHeader)); + VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(head), + head->rawsize + Memento_PostSize); + result = app(head, arg); + next = head->next; + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize); + VALGRIND_MAKE_MEM_NOACCESS(head, sizeof(Memento_BlkHeader)); + if (result) + return result; + head = next; + } + return 0; +} + +#ifndef MEMENTO_LEAKONLY +/* Distrustful - check the block is a real one */ +static int Memento_appBlockUser(Memento_Blocks *blks, + int (*app)(Memento_BlkHeader *, + void *), + void *arg, + Memento_BlkHeader *b) +{ + Memento_BlkHeader *head = blks->head; + Memento_BlkHeader *next; + int result; + while (head && head != b) { + VALGRIND_MAKE_MEM_DEFINED(head, sizeof(Memento_BlkHeader)); + next = head->next; + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize); + head = next; + } + if (head == b) { + VALGRIND_MAKE_MEM_DEFINED(head, sizeof(Memento_BlkHeader)); + VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(head), + head->rawsize + Memento_PostSize); + result = app(head, arg); + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize); + VALGRIND_MAKE_MEM_NOACCESS(head, sizeof(Memento_BlkHeader)); + return result; + } + return 0; +} + +static int Memento_appBlock(Memento_Blocks *blks, + int (*app)(Memento_BlkHeader *, + void *), + void *arg, + Memento_BlkHeader *b) +{ + int result; + (void)blks; + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader)); + VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(b), + b->rawsize + Memento_PostSize); + result = app(b, arg); + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(b), Memento_PostSize); + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); + return result; +} +#endif /* MEMENTO_LEAKONLY */ + +static int showBlock(Memento_BlkHeader *b, int space) +{ + int seq; + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader)); + fprintf(stderr, FMTP":(size=" FMTZ ",num=%d)", + MEMBLK_TOBLK(b), (FMTZ_CAST)b->rawsize, b->sequence); + if (b->label) + fprintf(stderr, "%c(%s)", space, b->label); + if (b->flags & Memento_Flag_KnownLeak) + fprintf(stderr, "(Known Leak)"); + seq = b->sequence; + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); + return seq; +} + +static void blockDisplay(Memento_BlkHeader *b, int n) +{ + n++; + while (n > 40) + { + fprintf(stderr, "*"); + n -= 40; + } + while(n > 0) + { + int i = n; + if (i > 32) + i = 32; + n -= i; + fprintf(stderr, "%s", &" "[32-i]); + } + showBlock(b, '\t'); + fprintf(stderr, "\n"); +} + +static int Memento_listBlock(Memento_BlkHeader *b, + void *arg) +{ + size_t *counts = (size_t *)arg; + blockDisplay(b, 0); + counts[0]++; + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader)); + counts[1]+= b->rawsize; + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); + return 0; +} + +static void doNestedDisplay(Memento_BlkHeader *b, + int depth) +{ + /* Try and avoid recursion if we can help it */ + do { + Memento_BlkHeader *c = NULL; + blockDisplay(b, depth); + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader)); + if (b->sibling) { + c = b->child; + b = b->sibling; + } else { + b = b->child; + depth++; + } + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); + if (c) + doNestedDisplay(c, depth+1); + } while (b); +} + +static int ptrcmp(const void *a_, const void *b_) +{ + const char **a = (const char **)a_; + const char **b = (const char **)b_; + return (int)(*a-*b); +} + +static +int Memento_listBlocksNested(void) +{ + int count, i; + size_t size; + Memento_BlkHeader *b, *prev; + void **blocks, *minptr, *maxptr; + intptr_t mask; + + /* Count the blocks */ + count = 0; + size = 0; + for (b = memento.used.head; b; b = b->next) { + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b)); + size += b->rawsize; + count++; + } + + /* Make our block list */ + blocks = MEMENTO_UNDERLYING_MALLOC(sizeof(void *) * count); + if (blocks == NULL) + return 1; + + /* Populate our block list */ + b = memento.used.head; + minptr = maxptr = MEMBLK_TOBLK(b); + mask = (intptr_t)minptr; + for (i = 0; b; b = b->next, i++) { + void *p = MEMBLK_TOBLK(b); + mask &= (intptr_t)p; + if (p < minptr) + minptr = p; + if (p > maxptr) + maxptr = p; + blocks[i] = p; + b->flags &= ~Memento_Flag_HasParent; + b->child = NULL; + b->sibling = NULL; + b->prev = NULL; /* parent */ + } + qsort(blocks, count, sizeof(void *), ptrcmp); + + /* Now, calculate tree */ + for (b = memento.used.head; b; b = b->next) { + char *p = MEMBLK_TOBLK(b); + size_t end = (b->rawsize < MEMENTO_PTRSEARCH ? b->rawsize : MEMENTO_PTRSEARCH); + size_t z; + VALGRIND_MAKE_MEM_DEFINED(p, end); + end -= sizeof(void *)-1; + for (z = MEMENTO_SEARCH_SKIP; z < end; z += sizeof(void *)) { + void *q = *(void **)(&p[z]); + void **r; + + /* Do trivial checks on pointer */ + if ((mask & (intptr_t)q) != mask || q < minptr || q > maxptr) + continue; + + /* Search for pointer */ + r = bsearch(&q, blocks, count, sizeof(void *), ptrcmp); + if (r) { + /* Found child */ + Memento_BlkHeader *child = MEMBLK_FROMBLK(*r); + Memento_BlkHeader *parent; + + /* We're assuming tree structure, not graph - ignore second + * and subsequent pointers. */ + if (child->prev != NULL) /* parent */ + continue; + if (child->flags & Memento_Flag_HasParent) + continue; + + /* Not interested in pointers to ourself! */ + if (child == b) + continue; + + /* We're also assuming acyclicness here. If this is one of + * our parents, ignore it. */ + parent = b->prev; /* parent */ + while (parent != NULL && parent != child) + parent = parent->prev; /* parent */ + if (parent == child) + continue; + + child->sibling = b->child; + b->child = child; + child->prev = b; /* parent */ + child->flags |= Memento_Flag_HasParent; + } + } + } + + /* Now display with nesting */ + for (b = memento.used.head; b; b = b->next) { + if ((b->flags & Memento_Flag_HasParent) == 0) + doNestedDisplay(b, 0); + } + fprintf(stderr, " Total number of blocks = %d\n", count); + fprintf(stderr, " Total size of blocks = "FMTZ"\n", (FMTZ_CAST)size); + + MEMENTO_UNDERLYING_FREE(blocks); + + /* Now put the blocks back for valgrind, and restore the prev + * and magic values. */ + prev = NULL; + for (b = memento.used.head; b;) { + Memento_BlkHeader *next = b->next; + b->prev = prev; + b->child = MEMENTO_CHILD_MAGIC; + b->sibling = MEMENTO_SIBLING_MAGIC; + prev = b; + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(*b)); + b = next; + } + + return 0; +} + +void Memento_listBlocks(void) +{ + MEMENTO_LOCK(); + fprintf(stderr, "Allocated blocks:\n"); + if (Memento_listBlocksNested()) + { + size_t counts[2]; + counts[0] = 0; + counts[1] = 0; + Memento_appBlocks(&memento.used, Memento_listBlock, &counts[0]); + fprintf(stderr, " Total number of blocks = "FMTZ"\n", (FMTZ_CAST)counts[0]); + fprintf(stderr, " Total size of blocks = "FMTZ"\n", (FMTZ_CAST)counts[1]); + } + MEMENTO_UNLOCK(); +} + +static int Memento_listNewBlock(Memento_BlkHeader *b, + void *arg) +{ + if (b->flags & Memento_Flag_OldBlock) + return 0; + b->flags |= Memento_Flag_OldBlock; + return Memento_listBlock(b, arg); +} + +void Memento_listNewBlocks(void) +{ + size_t counts[2]; + MEMENTO_LOCK(); + counts[0] = 0; + counts[1] = 0; + fprintf(stderr, "Blocks allocated and still extant since last list:\n"); + Memento_appBlocks(&memento.used, Memento_listNewBlock, &counts[0]); + fprintf(stderr, " Total number of blocks = "FMTZ"\n", (FMTZ_CAST)counts[0]); + fprintf(stderr, " Total size of blocks = "FMTZ"\n", (FMTZ_CAST)counts[1]); + MEMENTO_UNLOCK(); +} + +static void Memento_endStats(void) +{ + fprintf(stderr, "Total memory malloced = "FMTZ" bytes\n", (FMTZ_CAST)memento.totalAlloc); + fprintf(stderr, "Peak memory malloced = "FMTZ" bytes\n", (FMTZ_CAST)memento.peakAlloc); + fprintf(stderr, FMTZ" mallocs, "FMTZ" frees, "FMTZ" reallocs\n", (FMTZ_CAST)memento.numMallocs, + (FMTZ_CAST)memento.numFrees, (FMTZ_CAST)memento.numReallocs); + fprintf(stderr, "Average allocation size "FMTZ" bytes\n", (FMTZ_CAST) + (memento.numMallocs != 0 ? memento.totalAlloc/memento.numMallocs: 0)); +} + +void Memento_stats(void) +{ + MEMENTO_LOCK(); + fprintf(stderr, "Current memory malloced = "FMTZ" bytes\n", (FMTZ_CAST)memento.alloc); + Memento_endStats(); + MEMENTO_UNLOCK(); +} + +#ifdef MEMENTO_DETAILS +static int showInfo(Memento_BlkHeader *b, void *arg) +{ + Memento_BlkDetails *details; + + (void)arg; + + fprintf(stderr, FMTP":(size="FMTZ",num=%d)", + MEMBLK_TOBLK(b), (FMTZ_CAST)b->rawsize, b->sequence); + if (b->label) + fprintf(stderr, " (%s)", b->label); + fprintf(stderr, "\nEvents:\n"); + + for (details = b->details; details; details = details->next) + { + if (memento.hideMultipleReallocs && + details->type == Memento_EventType_realloc && + details->next && + details->next->type == Memento_EventType_realloc) { + continue; + } + fprintf(stderr, " Event %d (%s)\n", details->sequence, eventType[(int)details->type]); + Memento_showStacktrace(details->stack, details->count); + } + return 0; +} +#endif + +void Memento_listBlockInfo(void) +{ +#ifdef MEMENTO_DETAILS + MEMENTO_LOCK(); + fprintf(stderr, "Details of allocated blocks:\n"); + Memento_appBlocks(&memento.used, showInfo, NULL); + MEMENTO_UNLOCK(); +#endif +} + +static int Memento_nonLeakBlocksLeaked(void) +{ + Memento_BlkHeader *blk = memento.used.head; + while (blk) + { + Memento_BlkHeader *next; + int leaked; + VALGRIND_MAKE_MEM_DEFINED(blk, sizeof(*blk)); + leaked = ((blk->flags & Memento_Flag_KnownLeak) == 0); + next = blk->next; + VALGRIND_MAKE_MEM_DEFINED(blk, sizeof(*blk)); + if (leaked) + return 1; + blk = next; + } + return 0; +} + +void Memento_fin(void) +{ + Memento_checkAllMemory(); + if (!memento.segv) + { + Memento_endStats(); + if (Memento_nonLeakBlocksLeaked()) { + Memento_listBlocks(); +#ifdef MEMENTO_DETAILS + fprintf(stderr, "\n"); + Memento_listBlockInfo(); +#endif + Memento_breakpoint(); + } + } + if (memento.squeezing) { + if (memento.pattern == 0) + fprintf(stderr, "Memory squeezing @ %d complete%s\n", memento.squeezeAt, memento.segv ? " (with SEGV)" : ""); + else + fprintf(stderr, "Memory squeezing @ %d (%d) complete%s\n", memento.squeezeAt, memento.pattern, memento.segv ? " (with SEGV)" : ""); + } else if (memento.segv) { + fprintf(stderr, "Memento completed (with SEGV)\n"); + } + if (memento.failing) + { + fprintf(stderr, "MEMENTO_FAILAT=%d\n", memento.failAt); + fprintf(stderr, "MEMENTO_PATTERN=%d\n", memento.pattern); + } + if (memento.nextFailAt != 0) + { + fprintf(stderr, "MEMENTO_NEXTFAILAT=%d\n", memento.nextFailAt); + fprintf(stderr, "MEMENTO_NEXTPATTERN=%d\n", memento.nextPattern); + } + if (Memento_nonLeakBlocksLeaked() && memento.abortOnLeak) { + fprintf(stderr, "Calling abort() because blocks were leaked and MEMENTO_ABORT_ON_LEAK is set.\n"); + abort(); + } +} + +/* Reads number from using strtol(). + * + * Params: + * text: + * text to read. + * out: + * pointer to output value. + * relative: + * *relative set to 1 if starts with '+' or '-', else set to 0. + * end: + * *end is set to point to next unread character after number. + * + * Returns 0 on success, else -1. + */ +static int read_number(const char *text, int *out, int *relative, char **end) +{ + if (text[0] == '+' || text[0] == '-') + *relative = 1; + else + *relative = 0; + errno = 0; + *out = (int)strtol(text, end, 0 /*base*/); + if (errno || *end == text) + { + fprintf(stderr, "Failed to parse number at start of '%s'.\n", text); + return -1; + } + if (0) + fprintf(stderr, "text='%s': *out=%i *relative=%i\n", + text, *out, *relative); + return 0; +} + +/* Reads number plus optional delta value from . + * + * Evaluates or [+|-]. E.g. text='1234+2' sets *out=1236, + * text='1234-1' sets *out=1233. + * + * Params: + * text: + * text to read. + * out: + * pointer to output value. + * end: + * *end is set to point to next unread character after number. + * + * Returns 0 on success, else -1. + */ +static int read_number_delta(const char *text, int *out, char **end) +{ + int e; + int relative; + + e = read_number(text, out, &relative, end); + if (e) + return e; + if (relative) { + fprintf(stderr, "Base number should not start with '+' or '-' at start of '%s'.\n", + text); + return -1; + } + if (*end) { + if (**end == '-' || **end == '+') { + int delta; + e = read_number(*end, &delta, &relative, end); + if (e) + return e; + *out += delta; + } + } + if (0) fprintf(stderr, "text='%s': *out=%i\n", text, *out); + + return 0; +} + +/* Reads range. + * + * E.g.: + * text='115867-2' sets *begin=115865 *end=115866. + * text='115867-1..+3' sets *begin=115866 *end=115869. + * + * Supported patterns for text: + * + * - returns *begin=value *end=*begin+1. + * .. - returns *begin=value1 *end=value2. + * ..+ - returns *begin=value *end=*begin+number. + * + * + * + + * - + * + * : [0-9]+ + * + * If not specified, *end defaults to *begin+1. + * + * Returns 0 on success, else -1, with *string_end pointing to first unused + * character. + */ +static int read_number_range(const char *text, int *begin, int *end, char **string_end) +{ + int e; + e = read_number_delta(text, begin, string_end); + if (e) + return e; + if (string_end && (*string_end)[0] == '.' && (*string_end)[1] == '.') { + int relative; + e = read_number((*string_end) + 2, end, &relative, string_end); + if (e) + return e; + if (relative) + *end += *begin; + } else { + *end = *begin + 1; + } + if (*end < *begin) { + fprintf(stderr, "Range %i..%i has negative extent, at start of '%s'.\n", + *begin, *end, text); + return -1; + } + if (0) fprintf(stderr, "text='%s': *begin=%i *end=%i\n", text, *begin, *end); + + return 0; +} + +/* Format: [,]+ + * + * For description of , see read_number_range() above. + * + * E.g.: + * MEMENTO_SQUEEZES=1234-2..+4,2345,2350..+2 + */ +static int Memento_add_squeezes(const char *text) +{ + int e = 0; + for(;;) { + int begin; + int end; + char *string_end; + if (!*text) + break; + e = read_number_range(text, &begin, &end, &string_end); + if (e) + break; + if (*string_end && *string_end != ',') { + fprintf(stderr, "Expecting comma at start of '%s'.\n", string_end); + e = -1; + break; + } + fprintf(stderr, "Adding squeeze range %i..%i.\n", + begin, end); + memento.squeezes_num += 1; + memento.squeezes = MEMENTO_UNDERLYING_REALLOC( + memento.squeezes, + memento.squeezes_num * sizeof(*memento.squeezes) + ); + if (!memento.squeezes) { + fprintf(stderr, "Failed to allocate memory for memento.squeezes_num=%i\n", + memento.squeezes_num); + e = -1; + break; + } + memento.squeezes[memento.squeezes_num-1].begin = begin; + memento.squeezes[memento.squeezes_num-1].end = end; + + if (*string_end == 0) + break; + text = string_end + 1; + } + + return e; +} + +static void Memento_init(void) +{ + char *env; + memset(&memento, 0, sizeof(memento)); + memento.inited = 1; + memento.used.head = NULL; + memento.used.tail = NULL; + memento.free.head = NULL; + memento.free.tail = NULL; + memento.sequence = 0; + memento.countdown = 1024; + memento.squeezes = NULL; + memento.squeezes_num = 0; + memento.squeezes_pos = 0; + + env = getenv("MEMENTO_FAILAT"); + memento.failAt = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_BREAKAT"); + memento.breakAt = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_PARANOIA"); + memento.paranoia = (env ? atoi(env) : 0); + if (memento.paranoia == 0) + memento.paranoia = -1024; + + env = getenv("MEMENTO_PARANOIDAT"); + memento.paranoidAt = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_SQUEEZEAT"); + memento.squeezeAt = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_PATTERN"); + memento.pattern = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_HIDE_MULTIPLE_REALLOCS"); + memento.hideMultipleReallocs = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_ABORT_ON_LEAK"); + memento.abortOnLeak = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_ABORT_ON_CORRUPTION"); + memento.abortOnCorruption = (env ? atoi(env) : 0); + + env = getenv("MEMENTO_SQUEEZES"); + if (env) { + int e; + fprintf(stderr, "Parsing squeeze ranges in MEMENTO_SQUEEZES=%s\n", env); + e = Memento_add_squeezes(env); + if (e) { + fprintf(stderr, "Failed to parse MEMENTO_SQUEEZES=%s\n", env); + exit(1); + } + } + + env = getenv("MEMENTO_MAXMEMORY"); + memento.maxMemory = (env ? atoi(env) : 0); + + atexit(Memento_fin); + + Memento_initMutex(&memento.mutex); + + Memento_initStacktracer(); + + Memento_breakpoint(); +} + +typedef struct findBlkData { + void *addr; + Memento_BlkHeader *blk; + int flags; +} findBlkData; + +static int Memento_containsAddr(Memento_BlkHeader *b, + void *arg) +{ + findBlkData *data = (findBlkData *)arg; + char *blkend = &((char *)MEMBLK_TOBLK(b))[b->rawsize]; + if ((MEMBLK_TOBLK(b) <= data->addr) && + ((void *)blkend > data->addr)) { + data->blk = b; + data->flags = 1; + return 1; + } + if (((void *)b <= data->addr) && + (MEMBLK_TOBLK(b) > data->addr)) { + data->blk = b; + data->flags = 2; + return 1; + } + if (((void *)blkend <= data->addr) && + ((void *)(blkend + Memento_PostSize) > data->addr)) { + data->blk = b; + data->flags = 3; + return 1; + } + return 0; +} + +void Memento_info(void *addr) +{ +#ifdef MEMENTO_DETAILS + findBlkData data; + + MEMENTO_LOCK(); + data.addr = addr; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk != NULL) + showInfo(data.blk, NULL); + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); + if (data.blk != NULL) + showInfo(data.blk, NULL); + MEMENTO_UNLOCK(); +#else + printf("Memento not compiled with details support\n"); +#endif +} + +#ifdef MEMENTO_HAS_FORK +#include +#include +#include +#ifdef MEMENTO_STACKTRACE_METHOD +#if MEMENTO_STACKTRACE_METHOD == 1 +#include +#endif +#endif + +/* FIXME: Find some portable way of getting this */ +/* MacOSX has 10240, Ubuntu seems to have 256 */ +#ifndef OPEN_MAX +#define OPEN_MAX 10240 +#endif + +/* stashed_map[j] = i means that file descriptor i-1 was duplicated to j */ +int stashed_map[OPEN_MAX]; + +static void Memento_signal(int sig) +{ + (void)sig; + fprintf(stderr, "SEGV at:\n"); + memento.segv = 1; + Memento_bt_internal(0); + + exit(1); +} + +static int squeeze(void) +{ + pid_t pid; + int i, status; + + if (memento.patternBit < 0) + return 1; + if (memento.squeezing && memento.patternBit >= MEMENTO_MAXPATTERN) + return 1; + + if (memento.patternBit == 0) + memento.squeezeAt = memento.sequence; + + if (!memento.squeezing) { + fprintf(stderr, "Memory squeezing @ %d\n", memento.squeezeAt); + } else + fprintf(stderr, "Memory squeezing @ %d (%x,%x)\n", memento.squeezeAt, memento.pattern, memento.patternBit); + + /* When we fork below, the child is going to snaffle all our file pointers + * and potentially corrupt them. Let's make copies of all of them before + * we fork, so we can restore them when we restart. */ + for (i = 0; i < OPEN_MAX; i++) { + if (stashed_map[i] == 0) { + int j = dup(i); + if (j >= 0) { + stashed_map[j] = i+1; + } + } + } + + fprintf(stderr, "Failing at:\n"); + Memento_bt_internal(2); + pid = fork(); + if (pid == 0) { + /* Child */ + signal(SIGSEGV, Memento_signal); + /* Close the dup-licated fds to avoid them getting corrupted by faulty + * code. */ + for (i = 0; i < OPEN_MAX; i++) { + if (stashed_map[i] != 0) { + /* We close duplicated fds, just in case child has some bad + * code that modifies/closes random fds. */ + close(i); + } + } + /* In the child, we always fail the next allocation. */ + if (memento.patternBit == 0) { + memento.patternBit = 1; + } else + memento.patternBit <<= 1; + memento.squeezing = 1; + + /* This is necessary to allow Memento_failThisEventLocked() near the + * end to do 'return squeeze();'. */ + memento.squeezes_num = 0; + + return 1; + } + + /* In the parent if we hit another allocation, pass it (and record the + * fact we passed it in the pattern. */ + memento.pattern |= memento.patternBit; + memento.patternBit <<= 1; + + /* Wait for pid to finish, with a timeout. */ + { + struct timespec tm = { 0, 10 * 1000 * 1000 }; /* 10ms = 100th sec */ + int timeout = 30 * 1000 * 1000; /* time out in microseconds! */ + while (waitpid(pid, &status, WNOHANG) == 0) { + nanosleep(&tm, NULL); + timeout -= (int)(tm.tv_nsec/1000); + tm.tv_nsec *= 2; + if (tm.tv_nsec > 999999999) + tm.tv_nsec = 999999999; + if (timeout <= 0) { + char text[32]; + fprintf(stderr, "Child is taking a long time to die. Killing it.\n"); + sprintf(text, "kill %d", pid); + system(text); + break; + } + } + } + + if (status != 0) { + fprintf(stderr, "Child status=%d\n", status); + } + + /* Put the files back */ + for (i = 0; i < OPEN_MAX; i++) { + if (stashed_map[i] != 0) { + dup2(i, stashed_map[i]-1); + close(i); + stashed_map[i] = 0; + } + } + + return 0; +} +#else +#include + +static void Memento_signal(int sig) +{ + (void)sig; + memento.segv = 1; + /* If we just return from this function the SEGV will be unhandled, and + * we'll launch into whatever JIT debugging system the OS provides. At + * least fprintf(stderr, something useful first. If MEMENTO_NOJIT is set, then + * just exit to avoid the JIT (and get the usual atexit handling). */ + if (getenv("MEMENTO_NOJIT")) + exit(1); + else + Memento_fin(); +} + +static int squeeze(void) +{ + fprintf(stderr, "Memento memory squeezing disabled as no fork!\n"); + return 0; +} +#endif + +static void Memento_startFailing(void) +{ + if (!memento.failing) { + fprintf(stderr, "Starting to fail...\n"); + Memento_bt(); + fflush(stderr); + memento.failing = 1; + memento.failAt = memento.sequence; + memento.nextFailAt = memento.sequence+1; + memento.pattern = 0; + memento.patternBit = 0; + signal(SIGSEGV, Memento_signal); + signal(SIGABRT, Memento_signal); + Memento_breakpointLocked(); + } +} + +static int Memento_event(void) +{ + memento.sequence++; + if ((memento.sequence >= memento.paranoidAt) && (memento.paranoidAt != 0)) { + memento.paranoia = 1; + memento.countdown = 1; + } + if (--memento.countdown == 0) { + Memento_checkAllMemoryLocked(); + if (memento.paranoia > 0) + memento.countdown = memento.paranoia; + else + { + memento.countdown = -memento.paranoia; + if (memento.paranoia > INT_MIN/2) + memento.paranoia *= 2; + } + } + + if (memento.sequence == memento.breakAt) { + fprintf(stderr, "Breaking at event %d\n", memento.breakAt); + return 1; + } + return 0; +} + +int Memento_sequence(void) +{ + return memento.sequence; +} + +int Memento_breakAt(int event) +{ + MEMENTO_LOCK(); + memento.breakAt = event; + MEMENTO_UNLOCK(); + return event; +} + +static void *safe_find_block(void *ptr) +{ + Memento_BlkHeader *block; + int valid; + + if (ptr == NULL) + return NULL; + + block = MEMBLK_FROMBLK(ptr); + /* Sometimes wrapping allocators can mean Memento_label + * is called with a value within the block, rather than + * at the start of the block. If we detect this, find it + * the slow way. */ + VALGRIND_MAKE_MEM_DEFINED(&block->child, sizeof(block->child)); + VALGRIND_MAKE_MEM_DEFINED(&block->sibling, sizeof(block->sibling)); + valid = (block->child == MEMENTO_CHILD_MAGIC && + block->sibling == MEMENTO_SIBLING_MAGIC); + VALGRIND_MAKE_MEM_NOACCESS(&block->child, sizeof(block->child)); + VALGRIND_MAKE_MEM_NOACCESS(&block->sibling, sizeof(block->sibling)); + if (!valid) + { + findBlkData data; + + data.addr = ptr; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk == NULL) + return NULL; + block = data.blk; + } + return block; +} + +void *Memento_label(void *ptr, const char *label) +{ + Memento_BlkHeader *block; + + if (ptr == NULL) + return NULL; + MEMENTO_LOCK(); + block = safe_find_block(ptr); + if (block != NULL) + { + VALGRIND_MAKE_MEM_DEFINED(&block->label, sizeof(block->label)); + block->label = label; + VALGRIND_MAKE_MEM_NOACCESS(&block->label, sizeof(block->label)); + } + MEMENTO_UNLOCK(); + return ptr; +} + +void Memento_tick(void) +{ + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); + MEMENTO_UNLOCK(); +} + +static int Memento_failThisEventLocked(void) +{ + int failThisOne; + + if (Memento_event()) Memento_breakpointLocked(); + + if (!memento.squeezing && memento.squeezes_num) { + /* Move to next relevant squeeze region if appropriate. */ + for ( ; memento.squeezes_pos != memento.squeezes_num; memento.squeezes_pos++) { + if (memento.sequence < memento.squeezes[memento.squeezes_pos].end) + break; + } + + /* See whether memento.sequence is within this squeeze region. */ + if (memento.squeezes_pos < memento.squeezes_num) { + int begin = memento.squeezes[memento.squeezes_pos].begin; + int end = memento.squeezes[memento.squeezes_pos].end; + if (memento.sequence >= begin && memento.sequence < end) { + if (1) { + fprintf(stderr, + "squeezes match memento.sequence=%i: memento.squeezes_pos=%i/%i %i..%i\n", + memento.sequence, + memento.squeezes_pos, + memento.squeezes_num, + memento.squeezes[memento.squeezes_pos].begin, + memento.squeezes[memento.squeezes_pos].end + ); + } + return squeeze(); + } + } + } + + if ((memento.sequence >= memento.failAt) && (memento.failAt != 0)) + Memento_startFailing(); + if ((memento.squeezes_num==0) && (memento.sequence >= memento.squeezeAt) && (memento.squeezeAt != 0)) + return squeeze(); + + if (!memento.failing) + return 0; + failThisOne = ((memento.patternBit & memento.pattern) == 0); + /* If we are failing, and we've reached the end of the pattern and we've + * still got bits available in the pattern word, and we haven't already + * set a nextPattern, then extend the pattern. */ + if (memento.failing && + ((~(memento.patternBit-1) & memento.pattern) == 0) && + (memento.patternBit != 0) && + memento.nextPattern == 0) + { + /* We'll fail this one, and set the 'next' one to pass it. */ + memento.nextFailAt = memento.failAt; + memento.nextPattern = memento.pattern | memento.patternBit; + } + memento.patternBit = (memento.patternBit ? memento.patternBit << 1 : 1); + + return failThisOne; +} + +int Memento_failThisEvent(void) +{ + int ret; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + ret = Memento_failThisEventLocked(); + MEMENTO_UNLOCK(); + return ret; +} + +static void *do_malloc(size_t s, int eventType) +{ + Memento_BlkHeader *memblk; + size_t smem = MEMBLK_SIZE(s); + + (void)eventType; + + if (Memento_failThisEventLocked()) { + errno = ENOMEM; + return NULL; + } + + if (s == 0) + return NULL; + + memento.numMallocs++; + + if (memento.maxMemory != 0 && memento.alloc + s > memento.maxMemory) { + errno = ENOMEM; + return NULL; + } + + memblk = MEMENTO_UNDERLYING_MALLOC(smem); + if (memblk == NULL) + return NULL; + + memento.alloc += s; + memento.totalAlloc += s; + if (memento.peakAlloc < memento.alloc) + memento.peakAlloc = memento.alloc; +#ifndef MEMENTO_LEAKONLY + memset(MEMBLK_TOBLK(memblk), MEMENTO_ALLOCFILL, s); +#endif + memblk->rawsize = s; + memblk->sequence = memento.sequence; + memblk->lastCheckedOK = memblk->sequence; + memblk->flags = 0; + memblk->label = 0; + memblk->child = MEMENTO_CHILD_MAGIC; + memblk->sibling = MEMENTO_SIBLING_MAGIC; +#ifdef MEMENTO_DETAILS + memblk->details = NULL; + memblk->details_tail = &memblk->details; + Memento_storeDetails(memblk, eventType); +#endif /* MEMENTO_DETAILS */ + Memento_addBlockHead(&memento.used, memblk, 0); + + if (memento.leaking > 0) + memblk->flags |= Memento_Flag_KnownLeak; + + return MEMBLK_TOBLK(memblk); +} + +char *Memento_strdup(const char *text) +{ + size_t len = strlen(text) + 1; + char *ret; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + ret = do_malloc(len, Memento_EventType_strdup); + MEMENTO_UNLOCK(); + + if (ret != NULL) + memcpy(ret, text, len); + + return ret; +} + +int Memento_asprintf(char **ret, const char *format, ...) +{ + va_list va; + int n; + int n2; + + if (!memento.inited) + Memento_init(); + + va_start(va, format); + n = vsnprintf(NULL, 0, format, va); + va_end(va); + if (n < 0) + return n; + + MEMENTO_LOCK(); + *ret = do_malloc(n+1, Memento_EventType_asprintf); + MEMENTO_UNLOCK(); + if (*ret == NULL) + return -1; + + va_start(va, format); + n2 = vsnprintf(*ret, n + 1, format, va); + va_end(va); + + return n2; +} + +int Memento_vasprintf(char **ret, const char *format, va_list ap) +{ + int n; + va_list ap2; + va_copy(ap2, ap); + + if (!memento.inited) + Memento_init(); + + n = vsnprintf(NULL, 0, format, ap); + if (n < 0) { + va_end(ap2); + return n; + } + + MEMENTO_LOCK(); + *ret = do_malloc(n+1, Memento_EventType_vasprintf); + MEMENTO_UNLOCK(); + if (*ret == NULL) { + va_end(ap2); + return -1; + } + + n = vsnprintf(*ret, n + 1, format, ap2); + va_end(ap2); + + return n; +} + +void *Memento_malloc(size_t s) +{ + void *ret; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + ret = do_malloc(s, Memento_EventType_malloc); + MEMENTO_UNLOCK(); + + return ret; +} + +void *Memento_calloc(size_t n, size_t s) +{ + void *block; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + block = do_malloc(n*s, Memento_EventType_calloc); + MEMENTO_UNLOCK(); + if (block) + memset(block, 0, n*s); + + return block; +} + +static void do_reference(Memento_BlkHeader *blk, int event) +{ +#ifdef MEMENTO_DETAILS + Memento_storeDetails(blk, event); +#endif /* MEMENTO_DETAILS */ +} + +int Memento_checkPointerOrNull(void *blk) +{ + if (blk == NULL) + return 0; + if (blk == MEMENTO_PREFILL_PTR) + fprintf(stderr, "Prefill value found as pointer - buffer underrun?\n"); + else if (blk == MEMENTO_POSTFILL_PTR) + fprintf(stderr, "Postfill value found as pointer - buffer overrun?\n"); + else if (blk == MEMENTO_ALLOCFILL_PTR) + fprintf(stderr, "Allocfill value found as pointer - use of uninitialised value?\n"); + else if (blk == MEMENTO_FREEFILL_PTR) + fprintf(stderr, "Allocfill value found as pointer - use after free?\n"); + else + return 0; +#ifdef MEMENTO_DETAILS + fprintf(stderr, "Current backtrace:\n"); + Memento_bt(); + fprintf(stderr, "History:\n"); + Memento_info(blk); +#endif + return 1; +} + +int Memento_checkBytePointerOrNull(void *blk) +{ + unsigned char i; + if (blk == NULL) + return 0; + Memento_checkPointerOrNull(blk); + + i = *(unsigned char *)blk; + + if (i == MEMENTO_PREFILL_UBYTE) + fprintf(stderr, "Prefill value found - buffer underrun?\n"); + else if (i == MEMENTO_POSTFILL_UBYTE) + fprintf(stderr, "Postfill value found - buffer overrun?\n"); + else if (i == MEMENTO_ALLOCFILL_UBYTE) + fprintf(stderr, "Allocfill value found - use of uninitialised value?\n"); + else if (i == MEMENTO_FREEFILL_UBYTE) + fprintf(stderr, "Allocfill value found - use after free?\n"); + else + return 0; +#ifdef MEMENTO_DETAILS + fprintf(stderr, "Current backtrace:\n"); + Memento_bt(); + fprintf(stderr, "History:\n"); + Memento_info(blk); +#endif + Memento_breakpoint(); + return 1; +} + +int Memento_checkShortPointerOrNull(void *blk) +{ + unsigned short i; + if (blk == NULL) + return 0; + Memento_checkPointerOrNull(blk); + + i = *(unsigned short *)blk; + + if (i == MEMENTO_PREFILL_USHORT) + fprintf(stderr, "Prefill value found - buffer underrun?\n"); + else if (i == MEMENTO_POSTFILL_USHORT) + fprintf(stderr, "Postfill value found - buffer overrun?\n"); + else if (i == MEMENTO_ALLOCFILL_USHORT) + fprintf(stderr, "Allocfill value found - use of uninitialised value?\n"); + else if (i == MEMENTO_FREEFILL_USHORT) + fprintf(stderr, "Allocfill value found - use after free?\n"); + else + return 0; +#ifdef MEMENTO_DETAILS + fprintf(stderr, "Current backtrace:\n"); + Memento_bt(); + fprintf(stderr, "History:\n"); + Memento_info(blk); +#endif + Memento_breakpoint(); + return 1; +} + +int Memento_checkIntPointerOrNull(void *blk) +{ + unsigned int i; + if (blk == NULL) + return 0; + Memento_checkPointerOrNull(blk); + + i = *(unsigned int *)blk; + + if (i == MEMENTO_PREFILL_UINT) + fprintf(stderr, "Prefill value found - buffer underrun?\n"); + else if (i == MEMENTO_POSTFILL_UINT) + fprintf(stderr, "Postfill value found - buffer overrun?\n"); + else if (i == MEMENTO_ALLOCFILL_UINT) + fprintf(stderr, "Allocfill value found - use of uninitialised value?\n"); + else if (i == MEMENTO_FREEFILL_UINT) + fprintf(stderr, "Allocfill value found - use after free?\n"); + else + return 0; +#ifdef MEMENTO_DETAILS + fprintf(stderr, "Current backtrace:\n"); + Memento_bt(); + fprintf(stderr, "History:\n"); + Memento_info(blk); +#endif + Memento_breakpoint(); + return 1; +} + +static void *do_takeRef(void *blk) +{ + MEMENTO_LOCK(); + do_reference(safe_find_block(blk), Memento_EventType_takeRef); + MEMENTO_UNLOCK(); + return blk; +} + +void *Memento_takeByteRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + (void)Memento_checkBytePointerOrNull(blk); + + return do_takeRef(blk); +} + +void *Memento_takeShortRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + (void)Memento_checkShortPointerOrNull(blk); + + return do_takeRef(blk); +} + +void *Memento_takeIntRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + (void)Memento_checkIntPointerOrNull(blk); + + return do_takeRef(blk); +} + +void *Memento_takeRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + return do_takeRef(blk); +} + +static void *do_dropRef(void *blk) +{ + MEMENTO_LOCK(); + do_reference(safe_find_block(blk), Memento_EventType_dropRef); + MEMENTO_UNLOCK(); + return blk; +} + +void *Memento_dropByteRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + Memento_checkBytePointerOrNull(blk); + + return do_dropRef(blk); +} + +void *Memento_dropShortRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + Memento_checkShortPointerOrNull(blk); + + return do_dropRef(blk); +} + +void *Memento_dropIntRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + Memento_checkIntPointerOrNull(blk); + + return do_dropRef(blk); +} + +void *Memento_dropRef(void *blk) +{ + if (!memento.inited) + Memento_init(); + + if (Memento_event()) Memento_breakpoint(); + + if (!blk) + return NULL; + + return do_dropRef(blk); +} + +void *Memento_adjustRef(void *blk, int adjust) +{ + if (Memento_event()) Memento_breakpoint(); + + if (blk == NULL) + return NULL; + + while (adjust > 0) + { + do_takeRef(blk); + adjust--; + } + while (adjust < 0) + { + do_dropRef(blk); + adjust++; + } + + return blk; + } + +void *Memento_reference(void *blk) +{ + if (!blk) + return NULL; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + do_reference(safe_find_block(blk), Memento_EventType_reference); + MEMENTO_UNLOCK(); + return blk; +} + +/* Treat blocks from the user with suspicion, and check them the slow + * but safe way. */ +static int checkBlockUser(Memento_BlkHeader *memblk, const char *action) +{ +#ifndef MEMENTO_LEAKONLY + BlkCheckData data; + + memset(&data, 0, sizeof(data)); + Memento_appBlockUser(&memento.used, Memento_Internal_checkAllocedBlock, + &data, memblk); + if (!data.found) { + /* Failure! */ + fprintf(stderr, "Attempt to %s block ", action); + showBlock(memblk, 32); + fprintf(stderr, "\n"); + Memento_breakpointLocked(); + return 1; + } else if (data.preCorrupt || data.postCorrupt) { + fprintf(stderr, "Block "); + showBlock(memblk, ' '); + fprintf(stderr, " found to be corrupted on %s!\n", action); + if (data.preCorrupt) { + fprintf(stderr, "Preguard corrupted\n"); + } + if (data.postCorrupt) { + fprintf(stderr, "Postguard corrupted\n"); + } + fprintf(stderr, "Block last checked OK at allocation %d. Now %d.\n", + memblk->lastCheckedOK, memento.sequence); + if ((memblk->flags & Memento_Flag_Reported) == 0) + { + memblk->flags |= Memento_Flag_Reported; + Memento_breakpointLocked(); + } + return 1; + } +#endif + return 0; +} + +static int checkBlock(Memento_BlkHeader *memblk, const char *action) +{ +#ifndef MEMENTO_LEAKONLY + BlkCheckData data; +#endif + + if (memblk->child != MEMENTO_CHILD_MAGIC || + memblk->sibling != MEMENTO_SIBLING_MAGIC) + { + /* Failure! */ + fprintf(stderr, "Attempt to %s invalid block ", action); + showBlock(memblk, 32); + fprintf(stderr, "\n"); + Memento_breakpointLocked(); + return 1; + } + +#ifndef MEMENTO_LEAKONLY + memset(&data, 0, sizeof(data)); + Memento_appBlock(&memento.used, Memento_Internal_checkAllocedBlock, + &data, memblk); + if (!data.found) { + /* Failure! */ + fprintf(stderr, "Attempt to %s block ", action); + showBlock(memblk, 32); + fprintf(stderr, "\n"); + Memento_breakpointLocked(); + return 1; + } else if (data.preCorrupt || data.postCorrupt) { + fprintf(stderr, "Block "); + showBlock(memblk, ' '); + fprintf(stderr, " found to be corrupted on %s!\n", action); + if (data.preCorrupt) { + fprintf(stderr, "Preguard corrupted\n"); + } + if (data.postCorrupt) { + fprintf(stderr, "Postguard corrupted\n"); + } + fprintf(stderr, "Block last checked OK at allocation %d. Now %d.\n", + memblk->lastCheckedOK, memento.sequence); + if ((memblk->flags & Memento_Flag_Reported) == 0) + { + memblk->flags |= Memento_Flag_Reported; + Memento_breakpointLocked(); + } + return 1; + } +#endif + return 0; +} + +static void do_free(void *blk, int eventType) +{ + Memento_BlkHeader *memblk; + + (void)eventType; + + if (Memento_event()) Memento_breakpointLocked(); + + if (blk == NULL) + return; + + memblk = MEMBLK_FROMBLK(blk); + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + if (checkBlock(memblk, "free")) + { + if (memento.abortOnCorruption) { + fprintf(stderr, "*** memblk corrupted, calling abort()\n"); + abort(); + } + return; + } + +#ifdef MEMENTO_DETAILS + Memento_storeDetails(memblk, eventType); +#endif + + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + if (memblk->flags & Memento_Flag_BreakOnFree) + Memento_breakpointLocked(); + + memento.alloc -= memblk->rawsize; + memento.numFrees++; + + Memento_removeBlock(&memento.used, memblk); + + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + if (Memento_Internal_makeSpace(MEMBLK_SIZE(memblk->rawsize))) { + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(memblk), + memblk->rawsize + Memento_PostSize); +#ifndef MEMENTO_LEAKONLY + memset(MEMBLK_TOBLK(memblk), MEMENTO_FREEFILL, memblk->rawsize); +#endif + memblk->flags |= Memento_Flag_Freed; + Memento_addBlockTail(&memento.free, memblk, 1); + } else { + free_block(memblk); + } +} + +void Memento_free(void *blk) +{ + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + do_free(blk, Memento_EventType_free); + MEMENTO_UNLOCK(); +} + +static void *do_realloc(void *blk, size_t newsize, int type) +{ + Memento_BlkHeader *memblk, *newmemblk; + size_t newsizemem; + int flags; + + if (Memento_failThisEventLocked()) { + errno = ENOMEM; + return NULL; + } + + memblk = MEMBLK_FROMBLK(blk); + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + if (checkBlock(memblk, "realloc")) { + errno = ENOMEM; + return NULL; + } + +#ifdef MEMENTO_DETAILS + Memento_storeDetails(memblk, type); +#endif + + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + if (memblk->flags & Memento_Flag_BreakOnRealloc) + Memento_breakpointLocked(); + + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + if (memento.maxMemory != 0 && memento.alloc - memblk->rawsize + newsize > memento.maxMemory) { + errno = ENOMEM; + return NULL; + } + + newsizemem = MEMBLK_SIZE(newsize); + Memento_removeBlock(&memento.used, memblk); + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + flags = memblk->flags; + newmemblk = MEMENTO_UNDERLYING_REALLOC(memblk, newsizemem); + if (newmemblk == NULL) + { + Memento_addBlockHead(&memento.used, memblk, 2); + return NULL; + } + memento.numReallocs++; + memento.totalAlloc += newsize; + memento.alloc -= newmemblk->rawsize; + memento.alloc += newsize; + if (memento.peakAlloc < memento.alloc) + memento.peakAlloc = memento.alloc; + newmemblk->flags = flags; +#ifndef MEMENTO_LEAKONLY + if (newmemblk->rawsize < newsize) { + char *newbytes = ((char *)MEMBLK_TOBLK(newmemblk))+newmemblk->rawsize; + VALGRIND_MAKE_MEM_DEFINED(newbytes, newsize - newmemblk->rawsize); + memset(newbytes, MEMENTO_ALLOCFILL, newsize - newmemblk->rawsize); + VALGRIND_MAKE_MEM_UNDEFINED(newbytes, newsize - newmemblk->rawsize); + } +#endif + newmemblk->rawsize = newsize; +#ifndef MEMENTO_LEAKONLY + VALGRIND_MAKE_MEM_DEFINED(newmemblk->preblk, Memento_PreSize); + memset(newmemblk->preblk, MEMENTO_PREFILL, Memento_PreSize); + VALGRIND_MAKE_MEM_UNDEFINED(newmemblk->preblk, Memento_PreSize); + VALGRIND_MAKE_MEM_DEFINED(MEMBLK_POSTPTR(newmemblk), Memento_PostSize); + memset(MEMBLK_POSTPTR(newmemblk), MEMENTO_POSTFILL, Memento_PostSize); + VALGRIND_MAKE_MEM_UNDEFINED(MEMBLK_POSTPTR(newmemblk), Memento_PostSize); +#endif + Memento_addBlockHead(&memento.used, newmemblk, 2); + return MEMBLK_TOBLK(newmemblk); +} + +void *Memento_realloc(void *blk, size_t newsize) +{ + void *ret; + + if (!memento.inited) + Memento_init(); + + if (blk == NULL) + { + MEMENTO_LOCK(); + ret = do_malloc(newsize, Memento_EventType_realloc); + MEMENTO_UNLOCK(); + if (!ret) errno = ENOMEM; + return ret; + } + if (newsize == 0) { + MEMENTO_LOCK(); + do_free(blk, Memento_EventType_realloc); + MEMENTO_UNLOCK(); + return NULL; + } + + MEMENTO_LOCK(); + ret = do_realloc(blk, newsize, Memento_EventType_realloc); + MEMENTO_UNLOCK(); + if (!ret) errno = ENOMEM; + return ret; +} + +int Memento_checkBlock(void *blk) +{ + Memento_BlkHeader *memblk; + int ret; + + if (blk == NULL) + return 0; + + MEMENTO_LOCK(); + memblk = MEMBLK_FROMBLK(blk); + ret = checkBlockUser(memblk, "check"); + MEMENTO_UNLOCK(); + return ret; +} + +#ifndef MEMENTO_LEAKONLY +static int Memento_Internal_checkAllAlloced(Memento_BlkHeader *memblk, void *arg) +{ + BlkCheckData *data = (BlkCheckData *)arg; + + Memento_Internal_checkAllocedBlock(memblk, data); + if (data->preCorrupt || data->postCorrupt) { + if ((data->found & 2) == 0) { + fprintf(stderr, "Allocated blocks:\n"); + data->found |= 2; + } + fprintf(stderr, " Block "); + showBlock(memblk, ' '); + if (data->preCorrupt) { + fprintf(stderr, " Preguard "); + } + if (data->postCorrupt) { + fprintf(stderr, "%s Postguard ", + (data->preCorrupt ? "&" : "")); + } + fprintf(stderr, "corrupted.\n " + "Block last checked OK at allocation %d. Now %d.\n", + memblk->lastCheckedOK, memento.sequence); + data->preCorrupt = 0; + data->postCorrupt = 0; + data->freeCorrupt = 0; + if ((memblk->flags & Memento_Flag_Reported) == 0) + { + memblk->flags |= Memento_Flag_Reported; + Memento_breakpointLocked(); + } + } + else + memblk->lastCheckedOK = memento.sequence; + return 0; +} + +static int Memento_Internal_checkAllFreed(Memento_BlkHeader *memblk, void *arg) +{ + BlkCheckData *data = (BlkCheckData *)arg; + + Memento_Internal_checkFreedBlock(memblk, data); + if (data->preCorrupt || data->postCorrupt || data->freeCorrupt) { + if ((data->found & 4) == 0) { + fprintf(stderr, "Freed blocks:\n"); + data->found |= 4; + } + fprintf(stderr, " "); + showBlock(memblk, ' '); + if (data->freeCorrupt) { + fprintf(stderr, " index %d (address "FMTP") onwards", (int)data->index, + &((char *)MEMBLK_TOBLK(memblk))[data->index]); + if (data->preCorrupt) { + fprintf(stderr, "+ preguard"); + } + if (data->postCorrupt) { + fprintf(stderr, "+ postguard"); + } + } else { + if (data->preCorrupt) { + fprintf(stderr, " preguard"); + } + if (data->postCorrupt) { + fprintf(stderr, "%s Postguard", + (data->preCorrupt ? "+" : "")); + } + } + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(Memento_BlkHeader)); + fprintf(stderr, " corrupted.\n" + " Block last checked OK at allocation %d. Now %d.\n", + memblk->lastCheckedOK, memento.sequence); + if ((memblk->flags & Memento_Flag_Reported) == 0) + { + memblk->flags |= Memento_Flag_Reported; + Memento_breakpointLocked(); + } + VALGRIND_MAKE_MEM_NOACCESS(memblk, sizeof(Memento_BlkHeader)); + data->preCorrupt = 0; + data->postCorrupt = 0; + data->freeCorrupt = 0; + } + else + memblk->lastCheckedOK = memento.sequence; + return 0; +} +#endif /* MEMENTO_LEAKONLY */ + +static int Memento_checkAllMemoryLocked(void) +{ +#ifndef MEMENTO_LEAKONLY + BlkCheckData data; + + memset(&data, 0, sizeof(data)); + Memento_appBlocks(&memento.used, Memento_Internal_checkAllAlloced, &data); + Memento_appBlocks(&memento.free, Memento_Internal_checkAllFreed, &data); + return data.found; +#else + return 0; +#endif +} + +int Memento_checkAllMemory(void) +{ +#ifndef MEMENTO_LEAKONLY + int ret; + + MEMENTO_LOCK(); + ret = Memento_checkAllMemoryLocked(); + MEMENTO_UNLOCK(); + if (ret & 6) { + Memento_breakpoint(); + return 1; + } + return 0; +#endif +} + +int Memento_setParanoia(int i) +{ + memento.paranoia = i; + if (memento.paranoia > 0) + memento.countdown = memento.paranoia; + else + memento.countdown = -memento.paranoia; + return i; +} + +int Memento_paranoidAt(int i) +{ + memento.paranoidAt = i; + return i; +} + +int Memento_getBlockNum(void *b) +{ + Memento_BlkHeader *memblk; + if (b == NULL) + return 0; + memblk = MEMBLK_FROMBLK(b); + return (memblk->sequence); +} + +int Memento_check(void) +{ + int result; + + fprintf(stderr, "Checking memory\n"); + result = Memento_checkAllMemory(); + fprintf(stderr, "Memory checked!\n"); + return result; +} + +int Memento_find(void *a) +{ + findBlkData data; + int s; + + MEMENTO_LOCK(); + data.addr = a; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk != NULL) { + fprintf(stderr, "Address "FMTP" is in %sallocated block ", + data.addr, + (data.flags == 1 ? "" : (data.flags == 2 ? + "preguard of " : "postguard of "))); + s = showBlock(data.blk, ' '); + fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); + return s; + } + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); + if (data.blk != NULL) { + fprintf(stderr, "Address "FMTP" is in %sfreed block ", + data.addr, + (data.flags == 1 ? "" : (data.flags == 2 ? + "preguard of " : "postguard of "))); + s = showBlock(data.blk, ' '); + fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); + return s; + } + MEMENTO_UNLOCK(); + return 0; +} + +void Memento_breakOnFree(void *a) +{ + findBlkData data; + + MEMENTO_LOCK(); + data.addr = a; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk != NULL) { + fprintf(stderr, "Will stop when address "FMTP" (in %sallocated block ", + data.addr, + (data.flags == 1 ? "" : (data.flags == 2 ? + "preguard of " : "postguard of "))); + showBlock(data.blk, ' '); + fprintf(stderr, ") is freed\n"); + VALGRIND_MAKE_MEM_DEFINED(data.blk, sizeof(Memento_BlkHeader)); + data.blk->flags |= Memento_Flag_BreakOnFree; + VALGRIND_MAKE_MEM_NOACCESS(data.blk, sizeof(Memento_BlkHeader)); + MEMENTO_UNLOCK(); + return; + } + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); + if (data.blk != NULL) { + fprintf(stderr, "Can't stop on free; address "FMTP" is in %sfreed block ", + data.addr, + (data.flags == 1 ? "" : (data.flags == 2 ? + "preguard of " : "postguard of "))); + showBlock(data.blk, ' '); + fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); + return; + } + fprintf(stderr, "Can't stop on free; address "FMTP" is not in a known block.\n", a); + MEMENTO_UNLOCK(); +} + +void Memento_breakOnRealloc(void *a) +{ + findBlkData data; + + MEMENTO_LOCK(); + data.addr = a; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk != NULL) { + fprintf(stderr, "Will stop when address "FMTP" (in %sallocated block ", + data.addr, + (data.flags == 1 ? "" : (data.flags == 2 ? + "preguard of " : "postguard of "))); + showBlock(data.blk, ' '); + fprintf(stderr, ") is freed (or realloced)\n"); + VALGRIND_MAKE_MEM_DEFINED(data.blk, sizeof(Memento_BlkHeader)); + data.blk->flags |= Memento_Flag_BreakOnFree | Memento_Flag_BreakOnRealloc; + VALGRIND_MAKE_MEM_NOACCESS(data.blk, sizeof(Memento_BlkHeader)); + MEMENTO_UNLOCK(); + return; + } + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); + if (data.blk != NULL) { + fprintf(stderr, "Can't stop on free/realloc; address "FMTP" is in %sfreed block ", + data.addr, + (data.flags == 1 ? "" : (data.flags == 2 ? + "preguard of " : "postguard of "))); + showBlock(data.blk, ' '); + fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); + return; + } + fprintf(stderr, "Can't stop on free/realloc; address "FMTP" is not in a known block.\n", a); + MEMENTO_UNLOCK(); +} + +int Memento_failAt(int i) +{ + memento.failAt = i; + if ((memento.sequence > memento.failAt) && + (memento.failing != 0)) + Memento_startFailing(); + return i; +} + +size_t Memento_setMax(size_t max) +{ + memento.maxMemory = max; + return max; +} + +void Memento_startLeaking(void) +{ + memento.leaking++; +} + +void Memento_stopLeaking(void) +{ + memento.leaking--; +} + +int Memento_squeezing(void) +{ + return memento.squeezing; +} + +#endif /* MEMENTO_CPP_EXTRAS_ONLY */ + +#ifdef __cplusplus +/* Dumb overrides for the new and delete operators */ + +void *operator new(size_t size) +{ + void *ret; + + if (!memento.inited) + Memento_init(); + + if (size == 0) + size = 1; + MEMENTO_LOCK(); + ret = do_malloc(size, Memento_EventType_new); + MEMENTO_UNLOCK(); + return ret; +} + +void operator delete(void *pointer) +{ + if (!pointer) + return; + + MEMENTO_LOCK(); + do_free(pointer, Memento_EventType_delete); + MEMENTO_UNLOCK(); +} + +/* Some C++ systems (apparently) don't provide new[] or delete[] + * operators. Provide a way to cope with this */ +#ifndef MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS +void *operator new[](size_t size) +{ + void *ret; + if (!memento.inited) + Memento_init(); + + if (size == 0) + size = 1; + MEMENTO_LOCK(); + ret = do_malloc(size, Memento_EventType_newArray); + MEMENTO_UNLOCK(); + return ret; +} + +void operator delete[](void *pointer) +{ + MEMENTO_LOCK(); + do_free(pointer, Memento_EventType_deleteArray); + MEMENTO_UNLOCK(); +} +#endif /* MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS */ +#endif /* __cplusplus */ + +#else + +/* Just in case anyone has left some debugging code in... */ +void (Memento_breakpoint)(void) +{ +} + +int (Memento_checkBlock)(void *b) +{ + return 0; +} + +int (Memento_checkAllMemory)(void) +{ + return 0; +} + +int (Memento_check)(void) +{ + return 0; +} + +int (Memento_setParanoia)(int i) +{ + return 0; +} + +int (Memento_paranoidAt)(int i) +{ + return 0; +} + +int (Memento_breakAt)(int i) +{ + return 0; +} + +int (Memento_getBlockNum)(void *i) +{ + return 0; +} + +int (Memento_find)(void *a) +{ + return 0; +} + +int (Memento_failAt)(int i) +{ + return 0; +} + +void (Memento_breakOnFree)(void *a) +{ +} + +void (Memento_breakOnRealloc)(void *a) +{ +} + +void *(Memento_takeRef)(void *a) +{ + return a; +} + +void *(Memento_dropRef)(void *a) +{ + return a; +} + +void *(Memento_adjustRef)(void *a, int adjust) +{ + return a; +} + +void *(Memento_reference)(void *a) +{ + return a; +} + +#undef Memento_malloc +#undef Memento_free +#undef Memento_realloc +#undef Memento_calloc +#undef Memento_strdup + +void *Memento_malloc(size_t size) +{ + return MEMENTO_UNDERLYING_MALLOC(size); +} + +void Memento_free(void *b) +{ + MEMENTO_UNDERLYING_FREE(b); +} + +void *Memento_realloc(void *b, size_t s) +{ + return MEMENTO_UNDERLYING_REALLOC(b, s); +} + +void *Memento_calloc(size_t n, size_t s) +{ + return MEMENTO_UNDERLYING_CALLOC(n, s); +} + +/* Avoid calling strdup, in case our compiler doesn't support it. + * Yes, I'm looking at you, early Visual Studios. */ +char *Memento_strdup(const char *s) +{ + size_t len = strlen(s)+1; + char *ret = MEMENTO_UNDERLYING_MALLOC(len); + if (ret != NULL) + memcpy(ret, s, len); + return ret; +} + +/* Avoid calling asprintf, in case our compiler doesn't support it. + * Vaguely unhappy about relying on vsnprintf, but... */ +int Memento_asprintf(char **ret, const char *format, ...) +{ + va_list va; + int n; + int n2; + + va_start(va, format); + n = vsnprintf(NULL, 0, format, va); + va_end(va); + if (n < 0) + return n; + + *ret = MEMENTO_UNDERLYING_MALLOC(n+1); + if (*ret == NULL) + return -1; + + va_start(va, format); + n2 = vsnprintf(*ret, n + 1, format, va); + va_end(va); + + return n2; +} + +/* Avoid calling vasprintf, in case our compiler doesn't support it. + * Vaguely unhappy about relying on vsnprintf, but... */ +int Memento_vasprintf(char **ret, const char *format, va_list ap) +{ + int n; + va_list ap2; + va_copy(ap2, ap); + + n = vsnprintf(NULL, 0, format, ap); + if (n < 0) { + va_end(ap2); + return n; + } + + *ret = MEMENTO_UNDERLYING_MALLOC(n+1); + if (*ret == NULL) { + va_end(ap2); + return -1; + } + + n = vsnprintf(*ret, n + 1, format, ap2); + va_end(ap2); + + return n; +} + +void (Memento_listBlocks)(void) +{ +} + +void (Memento_listNewBlocks)(void) +{ +} + +size_t (Memento_setMax)(size_t max) +{ + return 0; +} + +void (Memento_stats)(void) +{ +} + +void *(Memento_label)(void *ptr, const char *label) +{ + return ptr; +} + +void (Memento_info)(void *addr) +{ +} + +void (Memento_listBlockInfo)(void) +{ +} + +void (Memento_startLeaking)(void) +{ +} + +void (Memento_stopLeaking)(void) +{ +} + +int (Memento_squeezing)(void) +{ + return 0; +} + +#endif diff --git a/extract/src/memento.h b/extract/src/memento.h new file mode 100644 index 00000000..2dc1271d --- /dev/null +++ b/extract/src/memento.h @@ -0,0 +1,343 @@ +/* Copyright (C) 2009-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Memento: A library to aid debugging of memory leaks/heap corruption. + * + * Usage (with C): + * First, build your project with MEMENTO defined, and include this + * header file wherever you use malloc, realloc or free. + * This header file will use macros to point malloc, realloc and free to + * point to Memento_malloc, Memento_realloc, Memento_free. + * + * Run your program, and all mallocs/frees/reallocs should be redirected + * through here. When the program exits, you will get a list of all the + * leaked blocks, together with some helpful statistics. You can get the + * same list of allocated blocks at any point during program execution by + * calling Memento_listBlocks(); + * + * Every call to malloc/free/realloc counts as an 'allocation event'. + * On each event Memento increments a counter. Every block is tagged with + * the current counter on allocation. Every so often during program + * execution, the heap is checked for consistency. By default this happens + * after 1024 events, then after 2048 events, then after 4096 events, etc. + * This can be changed at runtime by using Memento_setParanoia(int level). + * 0 turns off such checking, 1 sets checking to happen on every event, + * any positive number n sets checking to happen once every n events, + * and any negative number n sets checking to happen after -n events, then + * after -2n events etc. + * + * The default paranoia level is therefore -1024. + * + * Memento keeps blocks around for a while after they have been freed, and + * checks them as part of these heap checks to see if they have been + * written to (or are freed twice etc). + * + * A given heap block can be checked for consistency (it's 'pre' and + * 'post' guard blocks are checked to see if they have been written to) + * by calling Memento_checkBlock(void *blockAddress); + * + * A check of all the memory can be triggered by calling Memento_check(); + * (or Memento_checkAllMemory(); if you'd like it to be quieter). + * + * A good place to breakpoint is Memento_breakpoint, as this will then + * trigger your debugger if an error is detected. This is done + * automatically for debug windows builds. + * + * If a block is found to be corrupt, information will be printed to the + * console, including the address of the block, the size of the block, + * the type of corruption, the number of the block and the event on which + * it last passed a check for correctness. + * + * If you rerun, and call Memento_paranoidAt(int event); with this number + * the code will wait until it reaches that event and then start + * checking the heap after every allocation event. Assuming it is a + * deterministic failure, you should then find out where in your program + * the error is occurring (between event x-1 and event x). + * + * Then you can rerun the program again, and call + * Memento_breakAt(int event); and the program will call + * Memento_Breakpoint() when event x is reached, enabling you to step + * through. + * + * Memento_find(address) will tell you what block (if any) the given + * address is in. + * + * An example: + * Suppose we have a gs invocation that crashes with memory corruption. + * * Build with -DMEMENTO. + * * In your debugger put a breakpoint on Memento_breakpoint. + * * Run the program. It will stop in Memento_inited. + * * Execute Memento_setParanoia(1); (In VS use Ctrl-Alt-Q). (Note #1) + * * Continue execution. + * * It will detect the memory corruption on the next allocation event + * after it happens, and stop in Memento_breakpoint. The console should + * show something like: + * + * Freed blocks: + * 0x172e610(size=288,num=1415) index 256 (0x172e710) onwards corrupted + * Block last checked OK at allocation 1457. Now 1458. + * + * * This means that the block became corrupted between allocation 1457 + * and 1458 - so if we rerun and stop the program at 1457, we can then + * step through, possibly with a data breakpoint at 0x172e710 and see + * when it occurs. + * * So restart the program from the beginning. When we stop after + * initialisation execute Memento_breakAt(1457); (and maybe + * Memento_setParanoia(1), or Memento_setParanoidAt(1457)) + * * Continue execution until we hit Memento_breakpoint. + * * Now you can step through and watch the memory corruption happen. + * + * Note #1: Using Memento_setParanoia(1) can cause your program to run + * very slowly. You may instead choose to use Memento_setParanoia(100) + * (or some other figure). This will only exhaustively check memory on + * every 100th allocation event. This trades speed for the size of the + * average allocation event range in which detection of memory corruption + * occurs. You may (for example) choose to run once checking every 100 + * allocations and discover that the corruption happens between events + * X and X+100. You can then rerun using Memento_paranoidAt(X), and + * it'll only start exhaustively checking when it reaches X. + * + * More than one memory allocator? + * + * If you have more than one memory allocator in the system (like for + * instance the ghostscript chunk allocator, that builds on top of the + * standard malloc and returns chunks itself), then there are some things + * to note: + * + * * If the secondary allocator gets its underlying blocks from calling + * malloc, then those will be checked by Memento, but 'subblocks' that + * are returned to the secondary allocator will not. There is currently + * no way to fix this other than trying to bypass the secondary + * allocator. One way I have found to do this with the chunk allocator + * is to tweak its idea of a 'large block' so that it puts every + * allocation in its own chunk. Clearly this negates the point of having + * a secondary allocator, and is therefore not recommended for general + * use. + * + * * Again, if the secondary allocator gets its underlying blocks from + * calling malloc (and hence Memento) leak detection should still work + * (but whole blocks will be detected rather than subblocks). + * + * * If on every allocation attempt the secondary allocator calls into + * Memento_failThisEvent(), and fails the allocation if it returns true + * then more useful features can be used; firstly memory squeezing will + * work, and secondly, Memento will have a "finer grained" paranoia + * available to it. + * + * Usage with C++: + * + * Memento has some experimental code in it to trap new/delete (and + * new[]/delete[] if required) calls. + * + * In order for this to work, either: + * + * 1) Build memento.c with the c++ compiler. + * + * or + * + * 2) Build memento.c as normal with the C compiler, then from any + * one of your .cpp files, do: + * + * #define MEMENTO_CPP_EXTRAS_ONLY + * #include "memento.c" + * + * In the case where MEMENTO is not defined, this will not do anything. + * + * Both Windows and GCC provide separate new[] and delete[] operators + * for arrays. Apparently some systems do not. If this is the case for + * your system, define MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS. + * + * "libbacktrace.so failed to load" + * + * In order to give nice backtraces on unix, Memento will try to use + * a libbacktrace dynamic library. If it can't find it, you'll see + * that warning, and your backtraces won't include file/line information. + * + * To fix this you'll need to build your own libbacktrace. Don't worry + * it's really easy: + * git clone git://github.com/ianlancetaylor/libbacktrace + * cd libbacktrace + * ./configure + * make + * + * This leaves the build .so as .libs/libbacktrace.so + * + * Memento will look for this on LD_LIBRARY_PATH, or in /opt/lib/, + * or in /lib/, or in /usr/lib/, or in /usr/local/lib/. I recommend + * using /opt/lib/ as this won't conflict with anything that you + * get via a package manager like apt. + * + * sudo mkdir /opt + * sudo mkdir /opt/lib + * sudo cp .libs/libbacktrace.so /opt/lib/ + */ + +#ifndef MEMENTO_H + +#include +#include + +#define MEMENTO_H + +#ifndef MEMENTO_UNDERLYING_MALLOC +#define MEMENTO_UNDERLYING_MALLOC malloc +#endif +#ifndef MEMENTO_UNDERLYING_FREE +#define MEMENTO_UNDERLYING_FREE free +#endif +#ifndef MEMENTO_UNDERLYING_REALLOC +#define MEMENTO_UNDERLYING_REALLOC realloc +#endif +#ifndef MEMENTO_UNDERLYING_CALLOC +#define MEMENTO_UNDERLYING_CALLOC calloc +#endif + +#ifndef MEMENTO_MAXALIGN +#define MEMENTO_MAXALIGN (sizeof(int)) +#endif + +#define MEMENTO_PREFILL 0xa6 +#define MEMENTO_POSTFILL 0xa7 +#define MEMENTO_ALLOCFILL 0xa8 +#define MEMENTO_FREEFILL 0xa9 + +#define MEMENTO_FREELIST_MAX 0x2000000 + +int Memento_checkBlock(void *); +int Memento_checkAllMemory(void); +int Memento_check(void); + +int Memento_setParanoia(int); +int Memento_paranoidAt(int); +int Memento_breakAt(int); +void Memento_breakOnFree(void *a); +void Memento_breakOnRealloc(void *a); +int Memento_getBlockNum(void *); +int Memento_find(void *a); +void Memento_breakpoint(void); +int Memento_failAt(int); +int Memento_failThisEvent(void); +void Memento_listBlocks(void); +void Memento_listNewBlocks(void); +size_t Memento_setMax(size_t); +void Memento_stats(void); +void *Memento_label(void *, const char *); +void Memento_tick(void); + +void *Memento_malloc(size_t s); +void *Memento_realloc(void *, size_t s); +void Memento_free(void *); +void *Memento_calloc(size_t, size_t); +char *Memento_strdup(const char*); +int Memento_asprintf(char **ret, const char *format, ...); +int Memento_vasprintf(char **ret, const char *format, va_list ap); + +void Memento_info(void *addr); +void Memento_listBlockInfo(void); +void *Memento_takeByteRef(void *blk); +void *Memento_dropByteRef(void *blk); +void *Memento_takeShortRef(void *blk); +void *Memento_dropShortRef(void *blk); +void *Memento_takeIntRef(void *blk); +void *Memento_dropIntRef(void *blk); +void *Memento_takeRef(void *blk); +void *Memento_dropRef(void *blk); +void *Memento_adjustRef(void *blk, int adjust); +void *Memento_reference(void *blk); + +int Memento_checkPointerOrNull(void *blk); +int Memento_checkBytePointerOrNull(void *blk); +int Memento_checkShortPointerOrNull(void *blk); +int Memento_checkIntPointerOrNull(void *blk); + +void Memento_startLeaking(void); +void Memento_stopLeaking(void); + +/* Returns number of allocation events so far. */ +int Memento_sequence(void); + +/* Returns non-zero if our process was forked by Memento squeeze. */ +int Memento_squeezing(void); + +void Memento_fin(void); + +void Memento_bt(void); + +#ifdef MEMENTO + +#ifndef COMPILING_MEMENTO_C +#define malloc Memento_malloc +#define free Memento_free +#define realloc Memento_realloc +#define calloc Memento_calloc +#define strdup Memento_strdup +#define asprintf Memento_asprintf +#define vasprintf Memento_vasprintf +#endif + +#else + +#define Memento_malloc MEMENTO_UNDERLYING_MALLOC +#define Memento_free MEMENTO_UNDERLYING_FREE +#define Memento_realloc MEMENTO_UNDERLYING_REALLOC +#define Memento_calloc MEMENTO_UNDERLYING_CALLOC +#define Memento_strdup strdup +#define Memento_asprintf asprintf +#define Memento_vasprintf vasprintf + +#define Memento_checkBlock(A) 0 +#define Memento_checkAllMemory() 0 +#define Memento_check() 0 +#define Memento_setParanoia(A) 0 +#define Memento_paranoidAt(A) 0 +#define Memento_breakAt(A) 0 +#define Memento_breakOnFree(A) 0 +#define Memento_breakOnRealloc(A) 0 +#define Memento_getBlockNum(A) 0 +#define Memento_find(A) 0 +#define Memento_breakpoint() do {} while (0) +#define Memento_failAt(A) 0 +#define Memento_failThisEvent() 0 +#define Memento_listBlocks() do {} while (0) +#define Memento_listNewBlocks() do {} while (0) +#define Memento_setMax(A) 0 +#define Memento_stats() do {} while (0) +#define Memento_label(A,B) (A) +#define Memento_info(A) do {} while (0) +#define Memento_listBlockInfo() do {} while (0) +#define Memento_takeByteRef(A) (A) +#define Memento_dropByteRef(A) (A) +#define Memento_takeShortRef(A) (A) +#define Memento_dropShortRef(A) (A) +#define Memento_takeIntRef(A) (A) +#define Memento_dropIntRef(A) (A) +#define Memento_takeRef(A) (A) +#define Memento_dropRef(A) (A) +#define Memento_adjustRef(A,V) (A) +#define Memento_reference(A) (A) +#define Memento_checkPointerOrNull(A) 0 +#define Memento_checkBytePointerOrNull(A) 0 +#define Memento_checkShortPointerOrNull(A) 0 +#define Memento_checkIntPointerOrNull(A) 0 + +#define Memento_tick() do {} while (0) +#define Memento_startLeaking() do {} while (0) +#define Memento_stopLeaking() do {} while (0) +#define Memento_fin() do {} while (0) +#define Memento_bt() do {} while (0) +#define Memento_sequence() (0) +#define Memento_squeezing() (0) + +#endif /* MEMENTO */ + +#endif /* MEMENTO_H */ diff --git a/extract/src/memento.py b/extract/src/memento.py new file mode 100755 index 00000000..987cd4fd --- /dev/null +++ b/extract/src/memento.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +''' +Post-processor for Memento. + +Args: + -q + Controls how often we output 'Memory squeezing @ ...' lines. E.g. '-q + 10' outputs for multiples of 10. +''' + +import os +import re +import sys + + +def main(): + quiet = 1 + out_raw = None + args = iter(sys.argv[1:]) + while 1: + try: + arg = next(args) + except StopIteration: + break + if arg == '-h': + print(__doc__) + elif arg == '-o': + out_raw = open(next(args), 'w') + elif arg == '-q': + quiet = int(next(args)) + else: + raise Exception(f'unrecognised arg: {arg}') + + openbsd = os.uname()[0] == 'OpenBSD' + n = None + segv = 0 + leaks = 0 + lines = [] + for line in sys.stdin: + if out_raw: + out_raw.write(line) + m = re.match('^Memory squeezing @ ([0-9]+)( complete)?', line) + if m: + if not m.group(2): + # Start of squeeze. + + if not openbsd: + # Looks like memento's forked processes might terminate + # before they get to output the 'Memory squeezing @ + # complete' line. + # + assert n is None, f'n={n} line={line!r}' + + n = int(m.group(1)) + if n % quiet == 0: + sys.stdout.write(line) + sys.stdout.flush() + else: + # End of squeeze. + assert n == int(m.group(1)) + # Output info about any failure: + if segv or leaks: + print(f'Failure at squeeze {n}: segv={segv} leaks={leaks}:') + for l in lines: + if l.endswith('\n'): + l = l[:-1] + print(f' {l}') + lines = [] + segv = 0 + leaks = 0 + n = None + else: + if n is not None: + lines.append(line) + if line.startswith('SEGV at:'): + segv = 1 + if line.startswith('Allocated blocks'): + leaks = 1 + + +if __name__ == '__main__': + main() diff --git a/extract/src/misc-test.c b/extract/src/misc-test.c new file mode 100644 index 00000000..58b098ff --- /dev/null +++ b/extract/src/misc-test.c @@ -0,0 +1,86 @@ +#include "memento.h" +#include "xml.h" + +#include +#include + + +static int s_num_fails = 0; + +static void s_check( + int values_equal, + const char* text, + int ret, + const char* value_s, + int errno_, + const char* value_expected_s, + int errno_expected + ) +{ + int ok; + if (errno_expected) { + ok = (ret == -1 && errno_ == errno_expected); + } + else { + ok = (ret == 0 && values_equal); + } + + if (ok) printf(" ok: "); + else printf(" fail:"); + printf(" text=%16s", text); + if (errno_expected) printf(" errno_expected=%6i", errno_expected); + else printf(" value_expected=%6s", value_expected_s); + printf(". result: ret=%2i value=%6s errno=%3i", ret, value_s, errno_); + printf(".\n"); + if (!ok) s_num_fails += 1; +} + +static void s_check_int(const char* text, int value_expected, int expected_errno) +{ + int value; + int ret = extract_xml_str_to_int(text, &value); + char value_s[32]; + char value_expected_s[32]; + snprintf(value_s, sizeof(value_s), "%i", value); + snprintf(value_expected_s, sizeof(value_expected_s), "%i", value_expected); + s_check(value == value_expected, text, ret, value_s, errno, value_expected_s, expected_errno); + return; +} + +static void s_check_uint(const char* text, unsigned expected_value, int expected_errno) +{ + unsigned value; + int ret = extract_xml_str_to_uint(text, &value); + char value_s[32]; + char value_expected_s[32]; + snprintf(value_s, sizeof(value_s), "%u", value); + snprintf(value_expected_s, sizeof(value_expected_s), "%u", value); + s_check(value == expected_value, text, ret, value_s, errno, value_expected_s, expected_errno); + return; +} + +int main(void) +{ + printf("testing extract_xml_str_to_int():\n"); + s_check_int("2", 2, 0); + s_check_int("-20", -20, 0); + s_check_int("-20b", 0, EINVAL); + s_check_int("123456789123", 0, ERANGE); + + printf("testing extract_xml_str_to_uint():\n"); + s_check_uint("2", 2, 0); + s_check_uint("-20", 0, ERANGE); + s_check_uint("-20b", 0, EINVAL); + s_check_uint("123456789123", 0, ERANGE); + + printf("s_num_fails=%i\n", s_num_fails); + + if (s_num_fails) { + printf("Failed\n"); + return 1; + } + else { + printf("Succeeded\n"); + return 0; + } +} diff --git a/extract/src/outf.c b/extract/src/outf.c new file mode 100644 index 00000000..95575c16 --- /dev/null +++ b/extract/src/outf.c @@ -0,0 +1,42 @@ +#include "memento.h" +#include "outf.h" + +#include +#include +#include + +static int s_verbose = 0; + +void outf_verbose_set(int verbose) +{ + s_verbose = verbose; +} + +void (outf)( + int level, + const char* file, + int line, + const char* fn, + int ln, + const char* format, + ... + ) +{ + va_list va; + if (level > s_verbose) { + return; + } + + if (ln) { + fprintf(stderr, "%s:%i:%s: ", file, line, fn); + } + va_start(va, format); + vfprintf(stderr, format, va); + va_end(va); + if (ln) { + size_t len = strlen(format); + if (len == 0 || format[len-1] != '\n') { + fprintf(stderr, "\n"); + } + } +} diff --git a/extract/src/outf.h b/extract/src/outf.h new file mode 100644 index 00000000..a2b6c078 --- /dev/null +++ b/extract/src/outf.h @@ -0,0 +1,32 @@ +#ifndef ARTIFEX_EXTRACT_OUTF_H +#define ARTIFEX_EXTRACT_OUTF_H + +/* Only for internal use by extract code. */ + +void (outf)( + int level, + const char* file, int line, + const char* fn, + int ln, + const char* format, + ... + ); +/* Outputs text if is less than or equal to verbose value set by +outf_level_set(). */ + +#define outf(format, ...) \ + (outf)(1, __FILE__, __LINE__, __FUNCTION__, 1 /*ln*/, format, ##__VA_ARGS__) + +#define outf0(format, ...) \ + (outf)(0, __FILE__, __LINE__, __FUNCTION__, 1 /*ln*/, format, ##__VA_ARGS__) + +#define outfx(format, ...) + +/* Simple printf-style debug output. */ + +#define outfx(format, ...) + +void outf_verbose_set(int verbose); +/* Set verbose value. Higher values are more verbose. Initial value is 0. */ + +#endif diff --git a/extract/src/template.docx b/extract/src/template.docx new file mode 100644 index 00000000..8ad94155 Binary files /dev/null and b/extract/src/template.docx differ diff --git a/extract/src/xml.c b/extract/src/xml.c new file mode 100644 index 00000000..8dab511b --- /dev/null +++ b/extract/src/xml.c @@ -0,0 +1,505 @@ +#include "../include/extract_alloc.h" + +#include "mem.h" +#include "memento.h" +#include "outf.h" +#include "xml.h" + +#include +#include +#include +#include + +#ifdef _MSC_VER + #include "compat_stdint.h" + #include "compat_strtoll.h" +#else + #include +#endif + +#include +#include + + +/* These str_*() functions realloc buffer as required. All return 0 or -1 with +errno set. */ + +/* Appends first chars of string to *p. */ +static int str_catl(extract_alloc_t* alloc, char** p, const char* s, int s_len) +{ + size_t p_len = (*p) ? strlen(*p) : 0; + if (extract_realloc2( + alloc, + p, + p_len + 1, + p_len + s_len + 1 + )) return -1; + memcpy(*p + p_len, s, s_len); + (*p)[p_len + s_len] = 0; + return 0; +} + +/* Appends a char. */ +static int str_catc(extract_alloc_t* alloc, char** p, char c) +{ + return str_catl(alloc, p, &c, 1); +} + +/* Unused but usefult o keep code here. */ +#if 0 +/* Appends a string. */ +static int str_cat(extract_alloc_t* alloc, char** p, const char* s) +{ + return str_catl(alloc, p, s, strlen(s)); +} +#endif + +char* extract_xml_tag_attributes_find(extract_xml_tag_t* tag, const char* name) +{ + int i; + for (i=0; iattributes_num; ++i) { + if (!strcmp(tag->attributes[i].name, name)) { + char* ret = tag->attributes[i].value; + return ret; + } + } + outf("Failed to find attribute '%s'",name); + return NULL; +} + +int extract_xml_tag_attributes_find_float( + extract_xml_tag_t* tag, + const char* name, + float* o_out + ) +{ + const char* value = extract_xml_tag_attributes_find(tag, name); + if (!value) { + errno = ESRCH; + return -1; + } + if (extract_xml_str_to_float(value, o_out)) return -1; + return 0; +} + +int extract_xml_tag_attributes_find_double( + extract_xml_tag_t* tag, + const char* name, + double* o_out + ) +{ + const char* value = extract_xml_tag_attributes_find(tag, name); + if (!value) { + errno = ESRCH; + return -1; + } + if (extract_xml_str_to_double(value, o_out)) return -1; + return 0; +} + +int extract_xml_tag_attributes_find_int( + extract_xml_tag_t* tag, + const char* name, + int* o_out + ) +{ + const char* text = extract_xml_tag_attributes_find(tag, name); + return extract_xml_str_to_int(text, o_out); +} + +int extract_xml_tag_attributes_find_uint( + extract_xml_tag_t* tag, + const char* name, + unsigned* o_out + ) +{ + const char* text = extract_xml_tag_attributes_find(tag, name); + return extract_xml_str_to_uint(text, o_out); +} + +int extract_xml_tag_attributes_find_size( + extract_xml_tag_t* tag, + const char* name, + size_t* o_out + ) +{ + const char* text = extract_xml_tag_attributes_find(tag, name); + return extract_xml_str_to_size(text, o_out); +} + +int extract_xml_str_to_llint(const char* text, long long* o_out) +{ + char* endptr; + long long x; + if (!text) { + errno = ESRCH; + return -1; + } + if (text[0] == 0) { + errno = EINVAL; + return -1; + } + errno = 0; + x = strtoll(text, &endptr, 10 /*base*/); + if (errno) { + return -1; + } + if (*endptr) { + errno = EINVAL; + return -1; + } + *o_out = x; + return 0; +} + +int extract_xml_str_to_ullint(const char* text, unsigned long long* o_out) +{ + char* endptr; + unsigned long long x; + if (!text) { + errno = ESRCH; + return -1; + } + if (text[0] == 0) { + errno = EINVAL; + return -1; + } + errno = 0; + x = strtoull(text, &endptr, 10 /*base*/); + if (errno) { + return -1; + } + if (*endptr) { + errno = EINVAL; + return -1; + } + *o_out = x; + return 0; +} + +int extract_xml_str_to_int(const char* text, int* o_out) +{ + long long x; + if (extract_xml_str_to_llint(text, &x)) return -1; + if (x > INT_MAX || x < INT_MIN) { + errno = ERANGE; + return -1; + } + *o_out = (int) x; + return 0; +} + +int extract_xml_str_to_uint(const char* text, unsigned* o_out) +{ + unsigned long long x; + if (extract_xml_str_to_ullint(text, &x)) return -1; + if (x > UINT_MAX) { + errno = ERANGE; + return -1; + } + *o_out = (unsigned) x; + return 0; +} + +int extract_xml_str_to_size(const char* text, size_t* o_out) +{ + unsigned long long x; + if (extract_xml_str_to_ullint(text, &x)) return -1; + if (x > SIZE_MAX) { + errno = ERANGE; + return -1; + } + *o_out = (size_t) x; + return 0; +} + +int extract_xml_str_to_double(const char* text, double* o_out) +{ + char* endptr; + double x; + if (!text) { + errno = ESRCH; + return -1; + } + if (text[0] == 0) { + errno = EINVAL; + return -1; + } + errno = 0; + x = strtod(text, &endptr); + if (errno) { + return -1; + } + if (*endptr) { + errno = EINVAL; + return -1; + } + *o_out = x; + return 0; +} + +int extract_xml_str_to_float(const char* text, float* o_out) +{ + double x; + if (extract_xml_str_to_double(text, &x)) { + return -1; + } + if (x > FLT_MAX || x < -FLT_MAX) { + errno = ERANGE; + return -1; + } + *o_out = (float) x; + return 0; +} + +static int extract_xml_tag_attributes_append( + extract_alloc_t* alloc, + extract_xml_tag_t* tag, + char* name, + char* value + ) +{ + if (extract_realloc2( + alloc, + &tag->attributes, + sizeof(extract_xml_attribute_t) * tag->attributes_num, + sizeof(extract_xml_attribute_t) * (tag->attributes_num+1) + )) return -1; + tag->attributes[tag->attributes_num].name = name; + tag->attributes[tag->attributes_num].value = value; + tag->attributes_num += 1; + return 0; +} + +void extract_xml_tag_init(extract_xml_tag_t* tag) +{ + tag->name = NULL; + tag->attributes = NULL; + tag->attributes_num = 0; + extract_astring_init(&tag->text); +} + +void extract_xml_tag_free(extract_alloc_t* alloc, extract_xml_tag_t* tag) +{ + int i; + extract_free(alloc, &tag->name); + for (i=0; iattributes_num; ++i) { + extract_xml_attribute_t* attribute = &tag->attributes[i]; + extract_free(alloc, &attribute->name); + extract_free(alloc, &attribute->value); + } + extract_free(alloc, &tag->attributes); + extract_astring_free(alloc, &tag->text); + extract_xml_tag_init(tag); +} + +/* Unused but useful to keep code here. */ +#if 0 +/* Like strcmp() but also handles NULL. */ +static int extract_xml_strcmp_null(const char* a, const char* b) +{ + if (!a && !b) return 0; + if (!a) return -1; + if (!b) return 1; + return strcmp(a, b); +} +#endif + +/* Unused but usefult o keep code here. */ +#if 0 +/* Compares tag name, then attributes; returns -1, 0 or +1. Does not compare +extract_xml_tag_t::text members. */ +int extract_xml_compare_tags(const extract_xml_tag_t* lhs, const extract_xml_tag_t* rhs) +{ + int d; + int i; + d = extract_xml_strcmp_null(lhs->name, rhs->name); + if (d) return d; + for(i=0;; ++i) { + if (i >= lhs->attributes_num || i >= rhs->attributes_num) { + break; + } + const extract_xml_attribute_t* lhs_attribute = &lhs->attributes[i]; + const extract_xml_attribute_t* rhs_attribute = &rhs->attributes[i]; + d = extract_xml_strcmp_null(lhs_attribute->name, rhs_attribute->name); + if (d) return d; + d = extract_xml_strcmp_null(lhs_attribute->value, rhs_attribute->value); + if (d) return d; + } + if (lhs->attributes_num > rhs->attributes_num) return +1; + if (lhs->attributes_num < rhs->attributes_num) return -1; + return 0; +} +#endif + + +int extract_xml_pparse_init(extract_alloc_t* alloc, extract_buffer_t* buffer, const char* first_line) +{ + char* first_line_buffer = NULL; + int e = -1; + + if (first_line) { + size_t first_line_len = strlen(first_line); + size_t actual; + if (extract_malloc(alloc, &first_line_buffer, first_line_len + 1)) goto end; + + if (extract_buffer_read(buffer, first_line_buffer, first_line_len, &actual)) { + outf("error: failed to read first line."); + goto end; + } + first_line_buffer[actual] = 0; + if (strcmp(first_line, first_line_buffer)) { + outf("Unrecognised prefix: ", first_line_buffer); + errno = ESRCH; + goto end; + } + } + + for(;;) { + char c; + int ee = extract_buffer_read(buffer, &c, 1, NULL); + if (ee) { + if (ee==1) errno = ESRCH; /* EOF. */ + goto end; + } + if (c == '<') { + break; + } + else if (c == ' ' || c == '\n') {} + else { + outf("Expected '<' but found c=%i", c); + goto end; + } + } + e = 0; + + end: + extract_free(alloc, &first_line_buffer); + return e; +} + +static int s_next(extract_buffer_t* buffer, int* ret, char* o_c) +/* Reads next char, but if EOF sets *ret=+1, errno=ESRCH and returns +1. */ +{ + int e = extract_buffer_read(buffer, o_c, 1, NULL); + if (e == +1) { + *ret = +1; + errno = ESRCH; + } + return e; +} + +static const char* extract_xml_tag_string(extract_alloc_t* alloc, extract_xml_tag_t* tag) +{ + static char* buffer = NULL; + extract_free(alloc, &buffer); + extract_asprintf(alloc, &buffer, "", tag->name ? tag->name : ""); + return buffer; +} + +int extract_xml_pparse_next(extract_buffer_t* buffer, extract_xml_tag_t* out) +{ + int ret = -1; + char* attribute_name = NULL; + char* attribute_value = NULL; + char c; + int i; + extract_alloc_t* alloc = extract_buffer_alloc(buffer); + + if (0) outf("out is: %s", extract_xml_tag_string(extract_buffer_alloc(buffer), out)); + assert(buffer); + extract_xml_tag_free(alloc, out); + + /* Read tag name. */ + for( i=0;; ++i) { + int e = extract_buffer_read(buffer, &c, 1, NULL); + if (e) { + if (e == +1) ret = 1; /* EOF is not an error here. */ + goto end; + } + if (c == '>' || c == ' ') break; + if (str_catc(alloc, &out->name, c)) goto end; + } + if (c == ' ') { + + /* Read attributes. */ + for(;;) { + + /* Read attribute name. */ + for(;;) { + if (s_next(buffer, &ret, &c)) goto end; + if (c == '=' || c == '>' || c == ' ') break; + if (str_catc(alloc, &attribute_name, c)) goto end; + } + if (c == '>') break; + + if (c == '=') { + /* Read attribute value. */ + int quote_single = 0; + int quote_double = 0; + size_t l; + for(;;) { + if (s_next(buffer, &ret, &c)) goto end; + if (c == '\'') quote_single = !quote_single; + else if (c == '"') quote_double = !quote_double; + else if (!quote_single && !quote_double + && (c == ' ' || c == '/' || c == '>') + ) { + /* We are at end of attribute value. */ + break; + } + else if (c == '\\') { + // Escape next character. + if (s_next(buffer, &ret, &c)) goto end; + } + if (str_catc(alloc, &attribute_value, c)) goto end; + } + + /* Remove any enclosing quotes. */ + l = strlen(attribute_value); + if (l >= 2) { + if ( + (attribute_value[0] == '"' && attribute_value[l-1] == '"') + || + (attribute_value[0] == '\'' && attribute_value[l-1] == '\'') + ) { + memmove(attribute_value, attribute_value+1, l-2); + attribute_value[l-2] = 0; + } + } + } + + if (extract_xml_tag_attributes_append(alloc, out, attribute_name, attribute_value)) goto end; + attribute_name = NULL; + attribute_value = NULL; + if (c == '/') { + if (s_next(buffer, &ret, &c)) goto end; + } + if (c == '>') break; + } + } + + /* Read plain text until next '<'. */ + for(;;) { + /* We don't use s_next() here because EOF is not an error. */ + int e = extract_buffer_read(buffer, &c, 1, NULL); + if (e == +1) { + break; /* EOF is not an error here. */ + } + if (e) goto end; + if (c == '<') break; + if (extract_astring_catc(alloc, &out->text, c)) goto end; + } + + ret = 0; + + end: + + extract_free(alloc, &attribute_name); + extract_free(alloc, &attribute_value); + if (ret) { + extract_xml_tag_free(alloc, out); + } + return ret; +} + diff --git a/extract/src/xml.h b/extract/src/xml.h new file mode 100644 index 00000000..d11fd886 --- /dev/null +++ b/extract/src/xml.h @@ -0,0 +1,123 @@ +#ifndef ARTIFEX_EXTRACT_XML +#define ARTIFEX_EXTRACT_XML + +/* Only for internal use by extract code. */ + +#include "../include/extract_buffer.h" + +#include "astring.h" + + +/* Things for representing XML. */ + +typedef struct { + char* name; + char* value; +} extract_xml_attribute_t; + +/* Represents a single <...> XML tag plus trailing text. */ +typedef struct { + char* name; + extract_xml_attribute_t* attributes; + int attributes_num; + extract_astring_t text; +} extract_xml_tag_t; + + +void extract_xml_tag_init(extract_xml_tag_t* tag); +/* Initialises tag. Will cause leak if tag contains data - in this case call +extract_xml_tag_free(). */ + +void extract_xml_tag_free(extract_alloc_t* alloc, extract_xml_tag_t* tag); +/* Frees tag and then calls extract_xml_tag_init(). */ + + +int extract_xml_pparse_init(extract_alloc_t* alloc, extract_buffer_t* buffer, const char* first_line); +/* extract_xml_pparse_*(): simple XML 'pull' parser. + +extract_xml_pparse_init() merely consumes the initial '<'. Thereafter +extract_xml_pparse_next() consumes the next '<' before returning the previous +tag. */ + +/* Opens specified file. + +If first_line is not NULL, we check that it matches the first line in the file. + +Returns -1 with errno=ESRCH if we fail to read the first '<' due to EOF. +*/ + + +int extract_xml_pparse_next(extract_buffer_t* buffer, extract_xml_tag_t* out); +/* Returns the next XML tag. + +Returns 0 with *out containing next tag; or -1 with errno set if error; or +1 +with errno=ESRCH if EOF. + +*out is initially passed to extract_xml_tag_free(), so *out must have been +initialised, e.g. by by extract_xml_tag_init(). */ + + +char* extract_xml_tag_attributes_find(extract_xml_tag_t* tag, const char* name); +/* Returns pointer to value of specified attribute, or NULL if not found. */ + +int extract_xml_tag_attributes_find_float( + extract_xml_tag_t* tag, + const char* name, + float* o_out + ); +/* Finds float value of specified attribute, returning error if not found or +there is trailing text. */ + +int extract_xml_tag_attributes_find_double( + extract_xml_tag_t* tag, + const char* name, + double* o_out + ); +/* Finds double value of specified attribute, returning error if not found or there is +trailing text. */ + + +/* Next few functions write to out-param and return zero on success, else +return -1 with errno set. + +An error is returned if value is out of range or there is any trailing text. */ + +int extract_xml_str_to_llint(const char* text, long long* o_out); + +int extract_xml_str_to_ullint(const char* text, unsigned long long* o_out); + +int extract_xml_str_to_int(const char* text, int* o_out); + +int extract_xml_str_to_uint(const char* text, unsigned* o_out); + +int extract_xml_str_to_size(const char* text, size_t* o_out); + +int extract_xml_str_to_double(const char* text, double* o_out); + +int extract_xml_str_to_float(const char* text, float* o_out); + + +int extract_xml_tag_attributes_find_int( + extract_xml_tag_t* tag, + const char* name, + int* o_out + ); +/* Finds int value of specified attribute, returning error if not found. */ + +int extract_xml_tag_attributes_find_uint( + extract_xml_tag_t* tag, + const char* name, + unsigned* o_out + ); +/* Finds unsigned int value of specified attribute, returning error if not +found. */ + +int extract_xml_tag_attributes_find_size( + extract_xml_tag_t* tag, + const char* name, + size_t* o_out + ); +/* Finds unsigned int value of specified attribute, returning error if not +found. */ + +#endif diff --git a/extract/src/zip-test.c b/extract/src/zip-test.c new file mode 100644 index 00000000..67082342 --- /dev/null +++ b/extract/src/zip-test.c @@ -0,0 +1,224 @@ +/* Crude programme to show detailed information about a zip file. */ + +#include "memento.h" +#include "outf.h" + +#include +#include +#include +#include +#include + + +static int s_native_little_endinesss(void) +{ + static const char a[] = { 1, 2}; + uint16_t b = *(uint16_t*) a; + if (b == 1 + 2*256) { + /* Native little-endiness. */ + return 1; + } + else if (b == 2 + 1*256) { + return 0; + } + abort(); +} + + +static int s_show(const char* filename) +{ + outf("Looking at filename=%s", filename); + assert(s_native_little_endinesss()); + FILE* f = fopen(filename, "r"); + assert(f); + size_t datasize = 10*1000*1000; + char* data = extract_malloc(datasize); + assert(data); + size_t n = fread(data, 1, datasize, f); + assert(n < datasize); + datasize = n; + outf("datasize=%zi", datasize); + fclose(f); + + /* look for End of central directory (EOCD) record. */ + uint32_t magic = 0x06054b50; + char* pos = data + datasize - 22; + for(;;) { + if (!memcmp(pos, &magic, sizeof(magic))) break; + assert(pos > data); + pos -= 1; + } + outf("found EOCD at offset=%li", pos-data); + uint16_t disk_number = *(uint16_t*)(pos+4); + uint16_t disk_cd = *(uint16_t*)(pos+6); + uint16_t num_records_on_disk = *(uint16_t*)(pos+8); + uint16_t num_records = *(uint16_t*)(pos+10); + uint32_t size_cd = *(uint32_t*)(pos+12); + uint32_t offset_cd = *(uint32_t*)(pos+16); + uint16_t comment_length = *(uint16_t*)(pos+20); + char* comment = extract_malloc(comment_length + 1); + assert(comment); + memcpy(comment, pos+22, comment_length); + comment[comment_length] = 0; + assert(strlen(comment) == comment_length); + outf(" EOCD:"); + outf(" disk_number=%i", disk_number); + outf(" disk_cd=%i", disk_cd); + outf(" num_records_on_disk=%i", num_records_on_disk); + outf(" num_records=%i", num_records); + outf(" size_cd=%i", size_cd); + outf(" offset_cd=%i", offset_cd); + outf(" comment_length=%i", comment_length); + outf(" comment=%s", comment); + + if (pos != data + datasize - 22 - comment_length) { + outf("file does not end with EOCD. datasize=%zi pos-data=%li datasize-22-comment_length=%zi", + datasize, + pos-data, + datasize-22-comment_length + ); + /* I think this isn't actually an error according to the Zip standard, + but zip files created by us should always pass this test. Note that + Word doesn't like trailing data after the EOCD record, but will repair + the file. */ + assert(0); + } + + pos = data + offset_cd; + int i; + for (i=0; i +/* For crc32(). */ + +#include +#include +#include + +#ifdef _MSC_VER + #include "compat_stdint.h" +#else + #include +#endif + + +typedef struct +{ + int16_t mtime; + int16_t mdate; + int32_t crc_sum; + int32_t size_compressed; + int32_t size_uncompressed; + char* name; + uint32_t offset; + uint16_t attr_internal; + uint32_t attr_external; + +} extract_zip_cd_file_t; + +struct extract_zip_t +{ + extract_buffer_t* buffer; + extract_zip_cd_file_t* cd_files; + int cd_files_num; + + /* errno_ is set to non-zero if any operation fails; avoids need to check + after every small output operation. */ + int errno_; + int eof; + + /* Defaults for various values in zip file headers etc. */ + uint16_t mtime; + uint16_t mdate; + uint16_t version_creator; + uint16_t version_extract; + uint16_t general_purpose_bit_flag; + uint16_t file_attr_internal; + uint32_t file_attr_external; + char* archive_comment; +}; + +int extract_zip_open(extract_buffer_t* buffer, extract_zip_t** o_zip) +{ + int e = -1; + extract_zip_t* zip; + extract_alloc_t* alloc = extract_buffer_alloc(buffer); + + if (extract_malloc(alloc, &zip, sizeof(*zip))) goto end; + + zip->cd_files = NULL; + zip->cd_files_num = 0; + zip->buffer = buffer; + zip->errno_ = 0; + zip->eof = 0; + + /* We could maybe convert current date/time to the ms-dos format required + here, but using zeros doesn't seem to make a difference to Word etc. */ + zip->mtime = 0; + zip->mdate = 0; + + /* These are all copied from command-line zip on unix. */ + zip->version_creator = (0x3 << 8) + 30; /* 0x3 is unix, 30 means 3.0. */ + zip->version_extract = 10; /* 10 means 1.0. */ + zip->general_purpose_bit_flag = 0; + zip->file_attr_internal = 0; + + /* We follow command-line zip which uses 0x81a40000 which is octal + 0100644:0. (0100644 is S_IFREG (regular file) plus rw-r-r. See stat(2) for + details.) */ + zip->file_attr_external = (0100644 << 16) + 0; + if (extract_strdup(alloc, "Artifex", &zip->archive_comment)) goto end; + + e = 0; + + end: + if (e) { + if (zip) extract_free(alloc, &zip->archive_comment); + extract_free(alloc, &zip); + *o_zip = NULL; + } + else { + *o_zip = zip; + } + return e; +} + +static int s_native_little_endinesss(void) +{ + static const char a[] = { 1, 2}; + uint16_t b = *(uint16_t*) a; + if (b == 1 + 2*256) { + /* Native little-endiness. */ + return 1; + } + else if (b == 2 + 1*256) { + /* Native big-endiness. */ + return 0; + } + abort(); +} + +static int s_write(extract_zip_t* zip, const void* data, size_t data_length) +{ + size_t actual; + int e; + if (zip->errno_) return -1; + if (zip->eof) return +1; + e = extract_buffer_write(zip->buffer, data, data_length, &actual); + if (e == -1) zip->errno_ = errno; + if (e == +1) zip->eof = 1; + return e; +} + +static int s_write_uint32(extract_zip_t* zip, uint32_t value) +{ + if (s_native_little_endinesss()) { + return s_write(zip, &value, sizeof(value)); + } + else { + unsigned char value2[4] = { + (unsigned char) (value >> 0), + (unsigned char) (value >> 8), + (unsigned char) (value >> 16), + (unsigned char) (value >> 24) + }; + return s_write(zip, &value2, sizeof(value2)); + } +} + +static int s_write_uint16(extract_zip_t* zip, uint16_t value) +{ + if (s_native_little_endinesss()) { + return s_write(zip, &value, sizeof(value)); + } + else { + unsigned char value2[2] = { + (unsigned char) (value >> 0), + (unsigned char) (value >> 8) + }; + return s_write(zip, &value2, sizeof(value2)); + } +} + +static int s_write_string(extract_zip_t* zip, const char* text) +{ + return s_write(zip, text, strlen(text)); +} + + +int extract_zip_write_file( + extract_zip_t* zip, + const void* data, + size_t data_length, + const char* name + ) +{ + int e = -1; + extract_zip_cd_file_t* cd_file = NULL; + extract_alloc_t* alloc = extract_buffer_alloc(zip->buffer); + + if (data_length > INT_MAX) { + assert(0); + errno = EINVAL; + return -1; + } + /* Create central directory file header for later. */ + if (extract_realloc2( + alloc, + &zip->cd_files, + sizeof(extract_zip_cd_file_t) * zip->cd_files_num, + sizeof(extract_zip_cd_file_t) * (zip->cd_files_num+1) + )) goto end; + cd_file = &zip->cd_files[zip->cd_files_num]; + cd_file->name = NULL; + + cd_file->mtime = zip->mtime; + cd_file->mdate = zip->mtime; + cd_file->crc_sum = (int32_t) crc32(crc32(0, NULL, 0), data, (int) data_length); + cd_file->size_compressed = (int) data_length; + cd_file->size_uncompressed = (int) data_length; + if (extract_strdup(alloc, name, &cd_file->name)) goto end; + cd_file->offset = (int) extract_buffer_pos(zip->buffer); + cd_file->attr_internal = zip->file_attr_internal; + cd_file->attr_external = zip->file_attr_external; + if (!cd_file->name) goto end; + + /* Write local file header. */ + { + const char extra_local[] = ""; /* Modify for testing. */ + s_write_uint32(zip, 0x04034b50); + s_write_uint16(zip, zip->version_extract); /* Version needed to extract (minimum). */ + s_write_uint16(zip, zip->general_purpose_bit_flag); /* General purpose bit flag */ + s_write_uint16(zip, 0); /* Compression method */ + s_write_uint16(zip, cd_file->mtime); /* File last modification time */ + s_write_uint16(zip, cd_file->mdate); /* File last modification date */ + s_write_uint32(zip, cd_file->crc_sum); /* CRC-32 of uncompressed data */ + s_write_uint32(zip, cd_file->size_compressed); /* Compressed size */ + s_write_uint32(zip, cd_file->size_uncompressed); /* Uncompressed size */ + s_write_uint16(zip, (uint16_t) strlen(name)); /* File name length (n) */ + s_write_uint16(zip, sizeof(extra_local)-1); /* Extra field length (m) */ + s_write_string(zip, cd_file->name); /* File name */ + s_write(zip, extra_local, sizeof(extra_local)-1); /* Extra field */ + } + /* Write the (uncompressed) data. */ + s_write(zip, data, data_length); + + if (zip->errno_) e = -1; + else if (zip->eof) e = +1; + else e = 0; + + + end: + + if (e) { + /* Leave zip->cd_files_num unchanged, so calling extract_zip_close() + will write out any earlier files. Free cd_file->name to avoid leak. */ + if (cd_file) extract_free(alloc, &cd_file->name); + } + else { + /* cd_files[zip->cd_files_num] is valid. */ + zip->cd_files_num += 1; + } + + return e; +} + +int extract_zip_close(extract_zip_t** pzip) +{ + int e = -1; + size_t pos; + size_t len; + int i; + extract_zip_t* zip = *pzip; + extract_alloc_t* alloc; + if (!zip) { + return 0; + } + alloc = extract_buffer_alloc(zip->buffer); + pos = extract_buffer_pos(zip->buffer); + len = 0; + + /* Write Central directory file headers, freeing data as we go. */ + for (i=0; icd_files_num; ++i) { + const char extra[] = ""; + size_t pos2 = extract_buffer_pos(zip->buffer); + extract_zip_cd_file_t* cd_file = &zip->cd_files[i]; + s_write_uint32(zip, 0x02014b50); + s_write_uint16(zip, zip->version_creator); /* Version made by, copied from command-line zip. */ + s_write_uint16(zip, zip->version_extract); /* Version needed to extract (minimum). */ + s_write_uint16(zip, zip->general_purpose_bit_flag); /* General purpose bit flag */ + s_write_uint16(zip, 0); /* Compression method */ + s_write_uint16(zip, cd_file->mtime); /* File last modification time */ + s_write_uint16(zip, cd_file->mdate); /* File last modification date */ + s_write_uint32(zip, cd_file->crc_sum); /* CRC-32 of uncompressed data */ + s_write_uint32(zip, cd_file->size_compressed); /* Compressed size */ + s_write_uint32(zip, cd_file->size_uncompressed); /* Uncompressed size */ + s_write_uint16(zip, (uint16_t) strlen(cd_file->name)); /* File name length (n) */ + s_write_uint16(zip, sizeof(extra)-1); /* Extra field length (m) */ + s_write_uint16(zip, 0); /* File comment length (k) */ + s_write_uint16(zip, 0); /* Disk number where file starts */ + s_write_uint16(zip, cd_file->attr_internal); /* Internal file attributes */ + s_write_uint32(zip, cd_file->attr_external); /* External file attributes. */ + s_write_uint32(zip, cd_file->offset); /* Offset of local file header. */ + s_write_string(zip, cd_file->name); /* File name */ + s_write(zip, extra, sizeof(extra)-1); /* Extra field */ + len += extract_buffer_pos(zip->buffer) - pos2; + extract_free(alloc, &cd_file->name); + } + extract_free(alloc, &zip->cd_files); + + /* Write End of central directory record. */ + s_write_uint32(zip, 0x06054b50); + s_write_uint16(zip, 0); /* Number of this disk */ + s_write_uint16(zip, 0); /* Disk where central directory starts */ + s_write_uint16(zip, (uint16_t) zip->cd_files_num); /* Number of central directory records on this disk */ + s_write_uint16(zip, (uint16_t) zip->cd_files_num); /* Total number of central directory records */ + s_write_uint32(zip, (int) len); /* Size of central directory (bytes) */ + s_write_uint32(zip, (int) pos); /* Offset of start of central directory, relative to start of archive */ + + s_write_uint16(zip, (uint16_t) strlen(zip->archive_comment)); /* Comment length (n) */ + s_write_string(zip, zip->archive_comment); + extract_free(alloc, &zip->archive_comment); + + if (zip->errno_) e = -1; + else if (zip->eof) e = +1; + else e = 0; + + extract_free(alloc, pzip); + + return e; +} diff --git a/extract/src/zip.h b/extract/src/zip.h new file mode 100644 index 00000000..570f475a --- /dev/null +++ b/extract/src/zip.h @@ -0,0 +1,64 @@ +#ifndef ARTIFEX_EXTRACT_ZIP +#define ARTIFEX_EXTRACT_ZIP + +/* Only for internal use by extract code. */ + +#include "../include/extract_buffer.h" + +#include + + +/* Support for creating zip file content. + +Content is uncompressed. + +Unless otherwise stated, all functions return 0 on success or -1 with errno +set. +*/ + +typedef struct extract_zip_t extract_zip_t; +/* Abstract handle for zipfile state. */ + + +int extract_zip_open(extract_buffer_t* buffer, extract_zip_t** o_zip); +/* Creates an extract_zip_t that writes to specified buffer. + +buffer: + Destination for zip file content. +o_zip: + Out-param. +*/ + +int extract_zip_write_file( + extract_zip_t* zip, + const void* data, + size_t data_length, + const char* name + ); +/* Writes specified data into the zip file. + +Returns same as extract_buffer_write(): 0 on success, +1 if short write due to +EOF or -1 with errno set. + +zip: + From extract_zip_open(). +data: + File contents. +data_length: + Length in bytes of file contents. +name: + Name of file within the zip file. +*/ + + +int extract_zip_close(extract_zip_t** pzip); +/* Finishes writing the zip file (e.g. appends Central directory file headers +and End of central directory record). + +Does not call extract_buffer_close(). + +zip: + From extract_zip_open(). +*/ + +#endif diff --git a/extract/test/Python2.pdf b/extract/test/Python2.pdf new file mode 100644 index 00000000..e49ad4d2 Binary files /dev/null and b/extract/test/Python2.pdf differ diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.gs.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.gs.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..6f6d1748 --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/word/document.xml @@ -0,0 +1,834 @@ + + + + + + + + + + + + 781084 + + + 2932470 + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + 1971571 + + + 5069271 + + + + + + + + + + + + + + + + + + + + + + + +forty-two + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + + + + + + + + + + + + + + + + +forty-two + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + + + + + + + + + + 3428886 + + + 2213021 + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a !" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a ! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a ! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a !" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a ! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a ! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + 4868048 + + + 2477902 + + + + + + + + + + + + + + + + + + + + + + + +Snark + + + +Snark + + + +Snark + + + + + + + + + + + + + + + + + + + + + + + + + + +Snark + + + +Snark + + + +Snark + + + + + + + + + + + + + + + + + + + + 4205387 + + + 954592 + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + 1670565 + + + 437549 + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + 1302772 + + + 1384466 + + + + + + + + + + + + + + + + + + + + + + + +you feel + + + + + + + + + + + + + + + + + + + + + + + + + + +you feel + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.gs.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.gs.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.gs.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..32b69d9f --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + + + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + + + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had +forty-two +With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + + + + + As he landed his crew with care; + + + + + + + +Supporting each man on the top of the tide + + + + + + + + By a finger entwined in his hair. + + + + + + + +"Just the place for a +Snark +! I have said it twice: + + + + + + + + That alone should encourage the crew. + + + + + + + +Just the place for a +Snark +! I have said it thrice: + + + + + + + + What I tell you +three +times is true." + + + + + + + + + + + +There was a young man of +Madras +, + + + + + + + +Whose balls were +constructed +of brass, + + + + + + + +When jangled together, + + + + + + + +They played “ +Stormy Weather +”, + + + + + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + +A Python, I should not advise, + + + + + + + +For it needs a doctor for its eyes, + + + + + + + +And has the Measles yearly. + + + + + + + +However, if +you feel + inclined + + + + + + + +To get one (to improve your mind, + + + + + + + +And not from fashion merely), + + + + + + + +Allow no +music + near its cage; + + + + + + + +And when it +flies + into a rage + + + + + + + +Chastise it, most severely. + + + + + + + +I had an Aunt in Yucatan + + + + + + + +Who bought a Python from a man + + + + + + + +And kept it for a pet. + + + + + + + +She +died +, because she never knew + + + + + + + +These simple little rules and few; — + + + + + + + +The snake is living yet. + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a2ae4c0a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml @@ -0,0 +1,718 @@ + + + + + + + + + + + + + + + + 781084 + + + 2932470 + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1630060 + + + 1727386 + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had +forty-two +With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had +forty-two +With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3428887 + + + 2213022 + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4205387 + + + 954592 + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1670565 + + + 437549 + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..7285c2ae --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml @@ -0,0 +1,682 @@ + + + + + + + + + + + + 781084 + + + 2932470 + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + 1630060 + + + 1727386 + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had +forty-two +With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had +forty-two +With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + + + + + + + + + + 3428887 + + + 2213022 + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + 4205387 + + + 954592 + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + 1670565 + + + 437549 + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..32b69d9f --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + + + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + + + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + +There was one who was famed for the number of things He His umbrella, his watch, all his jewels and rings, +forgot + And the clothes he had bought for the trip. when he entered the ship: He had +forty-two +With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. boxes, all carefully packed, + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + + + + + As he landed his crew with care; + + + + + + + +Supporting each man on the top of the tide + + + + + + + + By a finger entwined in his hair. + + + + + + + +"Just the place for a +Snark +! I have said it twice: + + + + + + + + That alone should encourage the crew. + + + + + + + +Just the place for a +Snark +! I have said it thrice: + + + + + + + + What I tell you +three +times is true." + + + + + + + + + + + +There was a young man of +Madras +, + + + + + + + +Whose balls were +constructed +of brass, + + + + + + + +When jangled together, + + + + + + + +They played “ +Stormy Weather +”, + + + + + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + +A Python, I should not advise, + + + + + + + +For it needs a doctor for its eyes, + + + + + + + +And has the Measles yearly. + + + + + + + +However, if +you feel + inclined + + + + + + + +To get one (to improve your mind, + + + + + + + +And not from fashion merely), + + + + + + + +Allow no +music + near its cage; + + + + + + + +And when it +flies + into a rage + + + + + + + +Chastise it, most severely. + + + + + + + +I had an Aunt in Yucatan + + + + + + + +Who bought a Python from a man + + + + + + + +And kept it for a pet. + + + + + + + +She +died +, because she never knew + + + + + + + +These simple little rules and few; — + + + + + + + +The snake is living yet. + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..d18a0195 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + + + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + + + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + + + + + As he landed his crew with care; + + + + + + + +Supporting each man on the top of the tide + + + + + + + + By a finger entwined in his hair. + + + + + + + +"Just the place for a +Snark +! I have said it twice: + + + + + + + + That alone should encourage the crew. + + + + + + + +Just the place for a +Snark +! I have said it thrice: + + + + + + + + What I tell you +three +times is true." + + + + + + + + + + + +There was a young man of +Madras +, + + + + + + + +Whose balls were +constructed +of brass, + + + + + + + +When jangled together, + + + + + + + +They played “ +Stormy Weather +”, + + + + + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + +A Python, I should not advise, + + + + + + + +For it needs a doctor for its eyes, + + + + + + + +And has the Measles yearly. + + + + + + + +However, if +you feel + inclined + + + + + + + +To get one (to improve your mind, + + + + + + + +And not from fashion merely), + + + + + + + +Allow no +music + near its cage; + + + + + + + +And when it +flies + into a rage + + + + + + + +Chastise it, most severely. + + + + + + + +I had an Aunt in Yucatan + + + + + + + +Who bought a Python from a man + + + + + + + +And kept it for a pet. + + + + + + + +She +died +, because she never knew + + + + + + + +These simple little rules and few; — + + + + + + + +The snake is living yet. + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..19ab95bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml @@ -0,0 +1,718 @@ + + + + + + + + + + + + + + + + 3197324 + + + 5504612 + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + + + + + + + + + 840434 + + + 2977603 + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3428932 + + + 2211673 + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4205387 + + + 953182 + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1670564 + + + 436158 + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..850561f9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml @@ -0,0 +1,682 @@ + + + + + + + + + + + + 3197324 + + + 5504612 + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + 840434 + + + 2977603 + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + 3428932 + + + 2211673 + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + 4205387 + + + 953182 + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + 1670564 + + + 436158 + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..d18a0195 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + + + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + + + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + + + + + As he landed his crew with care; + + + + + + + +Supporting each man on the top of the tide + + + + + + + + By a finger entwined in his hair. + + + + + + + +"Just the place for a +Snark +! I have said it twice: + + + + + + + + That alone should encourage the crew. + + + + + + + +Just the place for a +Snark +! I have said it thrice: + + + + + + + + What I tell you +three +times is true." + + + + + + + + + + + +There was a young man of +Madras +, + + + + + + + +Whose balls were +constructed +of brass, + + + + + + + +When jangled together, + + + + + + + +They played “ +Stormy Weather +”, + + + + + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + +A Python, I should not advise, + + + + + + + +For it needs a doctor for its eyes, + + + + + + + +And has the Measles yearly. + + + + + + + +However, if +you feel + inclined + + + + + + + +To get one (to improve your mind, + + + + + + + +And not from fashion merely), + + + + + + + +Allow no +music + near its cage; + + + + + + + +And when it +flies + into a rage + + + + + + + +Chastise it, most severely. + + + + + + + +I had an Aunt in Yucatan + + + + + + + +Who bought a Python from a man + + + + + + + +And kept it for a pet. + + + + + + + +She +died +, because she never knew + + + + + + + +These simple little rules and few; — + + + + + + + +The snake is living yet. + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..63dc18ad --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/document.xml @@ -0,0 +1,177 @@ + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/[Content_Types].xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/_rels/.rels b/extract/test/Python2.pdf.mutool.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/app.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/core.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/word/document.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..9790a3ff --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/document.xml @@ -0,0 +1,682 @@ + + + + + + + + + + + + 3197324 + + + 5504612 + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + 840434 + + + 2977602 + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + 3428932 + + + 2211673 + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + 4205387 + + + 953182 + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was a young man of +Madras +, + + + +Whose balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + 1670564 + + + 436157 + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + + + + + + + +A Python, I should not advise, + + + +For it needs a doctor for its eyes, + + + +And has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/word/fontTable.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/word/settings.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/word/styles.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2.pdf.mutool.docx.dir.ref/word/webSettings.xml b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2.pdf.mutool.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf b/extract/test/Python2clipped.pdf new file mode 100644 index 00000000..b8e372cc Binary files /dev/null and b/extract/test/Python2clipped.pdf differ diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/_rels/.rels b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/document.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..0227a661 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/document.xml @@ -0,0 +1,173 @@ + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + a young man of +Madras +, + + + +e balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + +A Python, I sho + + + +For it needs a doctorAnd has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/settings.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/styles.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/[Content_Types].xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/_rels/.rels b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/app.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/core.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/document.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..69456c2b --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/document.xml @@ -0,0 +1,674 @@ + + + + + + + + + + + + 3197324 + + + 4602912 + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + + + + + + + +There was one who was famed for the number of things He +forgot +when he entered the ship: His umbrella, his watch, all his jewels and rings, And the clothes he had bought for the trip. He had +forty-two + boxes, all carefully packed, With his name painted clearly on each: But, since he omitted to mention the fact, They were all left behind on the beach. + + + + + + + + + + + + + + + + + + + + 840434 + + + 2075902 + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + + + + + + + +The crew was complete: it included a +Boots +— A maker of Bonnets and Hoods— A +Barrister +, brought to arrange their disputes— And a +Broker +, to value their goods. + + + +A +Billiard-marker +, whose skill was immense, Might perhaps have won more than his share— But a +Banker +, engaged at enormous expense, Had the whole of their +cash +in his care. + + + +There was also a +Beaver +, that paced on the deck, Or would sit making lace in the bow: And had often (the +Bellman +said) saved them from wreck, Though none of the sailors knew how. + + + + + + + + + + + + + + + + + + + + 3428932 + + + 1309973 + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + + + + + + + +"Just the place for a +Snark +!" the +Bellman +cried, + + + + As he landed his crew with care; + + + +Supporting each man on the top of the tide + + + + By a finger entwined in his hair. + + + +"Just the place for a +Snark +! I have said it twice: + + + + That alone should encourage the crew. + + + +Just the place for a +Snark +! I have said it thrice: + + + + What I tell you +three +times is true." + + + + + + + + + + + + + + + + + + + + 4254598 + + + -113601 + + + + + + + + + + + + + + + + + + + + + + + + a young man of +Madras +, + + + +e balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + + + + + + + + a young man of +Madras +, + + + +e balls were +constructed +of brass, + + + +When jangled together, + + + +They played “ +Stormy Weather +”, + + + +And +lightning + +shot out of his ass. + + + + + + + + + + + + + + + + + + + + 1670564 + + + -465543 + + + + + + + + + + + + + + + + + + + + + + + +A Python, I sho + + + +For it needs a doctorAnd has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + + + + + + + + + + + + + + + + + +A Python, I sho + + + +For it needs a doctorAnd has the Measles yearly. + + + +However, if +you feel + inclined + + + +To get one (to improve your mind, + + + +And not from fashion merely), + + + +Allow no +music + near its cage; + + + +And when it +flies + into a rage + + + +Chastise it, most severely. + + + +I had an Aunt in Yucatan + + + +Who bought a Python from a man + + + +And kept it for a pet. + + + +She +died +, because she never knew + + + +These simple little rules and few; — + + + +The snake is living yet. + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/fontTable.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/settings.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/styles.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/theme/theme1.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/webSettings.xml b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/Python2clipped.pdf.mutool.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf b/extract/test/text_graphic_image.pdf new file mode 100644 index 00000000..e551870c --- /dev/null +++ b/extract/test/text_graphic_image.pdf @@ -0,0 +1,627 @@ +%PDF-1.7 % +1 0 obj <>/Metadata 22 0 R/Pages 2 0 R/Type/Catalog>> endobj 22 0 obj <>stream + + + + + uuid:3061f54b-da79-4e4f-8d50-bb8ea880972b + adobe:docid:indd:9ea070bd-7cd6-11e0-b511-cc88c39318f9 + proof:pdf + + + 2011-06-22T10:16:27-07:00 + 2011-06-22T10:16:27-07:00 + 2011-06-22T10:16:27-07:00 + Adobe InDesign CS3 (5.0.4) + + + + JPEG + 256 + 256 + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4AE0Fkb2JlAGQAAAAAAQUAAimY/9sAhAAKBwcHBwcKBwcKDgkJCQ4RDAsLDBEU EBAQEBAUEQ8RERERDxERFxoaGhcRHyEhISEfKy0tLSsyMjIyMjIyMjIyAQsJCQ4MDh8XFx8rIh0i KzIrKysrMjIyMjIyMjIyMjIyMjIyMjI+Pj4+PjJAQEBAQEBAQEBAQEBAQEBAQEBAQED/wAARCAEA AMYDAREAAhEBAxEB/8QBogAAAAcBAQEBAQAAAAAAAAAABAUDAgYBAAcICQoLAQACAgMBAQEBAQAA AAAAAAABAAIDBAUGBwgJCgsQAAIBAwMCBAIGBwMEAgYCcwECAxEEAAUhEjFBUQYTYSJxgRQykaEH FbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeTo7M2F1RkdMPS4ggmgwkKGBmElEVGpLRW01Uo GvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2xtbm9jdHV2d3h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJ WWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+hEAAgIBAgMFBQQFBgQIAwNtAQACEQMEIRIxQQVRE2Ei BnGBkTKhsfAUwdHhI0IVUmJy8TMkNEOCFpJTJaJjssIHc9I14kSDF1STCAkKGBkmNkUaJ2R0VTfy o7PDKCnT4/OElKS0xNTk9GV1hZWltcXV5fVGVmZ2hpamtsbW5vZHV2d3h5ent8fX5/c4SFhoeIiY qLjI2Oj4OUlZaXmJmam5ydnp+So6SlpqeoqaqrrK2ur6/9oADAMBAAIRAxEAPwCbeU/KflW58q6L cXGi6fNNNp9rJJJJaws7u0MbMzM0ZJJJ3OKpt/gzyf8A9WHTf+kOD/qnirv8GeT/APqw6b/0hwf9 U8Vd/gzyf/1YdN/6Q4P+qeKu/wAGeT/+rDpv/SHB/wBU8Vd/gzyf/wBWHTf+kOD/AKp4q7/Bnk// AKsOm/8ASHB/1TxV3+DPJ/8A1YdN/wCkOD/qnirv8GeT/wDqw6b/ANIcH/VPFXf4M8n/APVh03/p Dg/6p4q7/Bnk/wD6sOm/9IcH/VPFXf4M8n/9WHTf+kOD/qnirv8ABnk//qw6b/0hwf8AVPFXf4M8 n/8AVh03/pDg/wCqeKu/wZ5P/wCrDpv/AEhwf9U8Vd/gzyf/ANWHTf8ApDg/6p4q7/Bnk/8A6sOm /wDSHB/1TxV3+DPJ/wD1YdN/6Q4P+qeKu/wZ5P8A+rDpv/SHB/1TxV3+DPJ//Vh03/pDg/6p4q7/ AAZ5P/6sOm/9IcH/AFTxV3+DPJ//AFYdN/6Q4P8Aqnirv8GeT/8Aqw6b/wBIcH/VPFXf4M8n/wDV h03/AKQ4P+qeKpTrPlPyrFqOgJFounok+oSRyqtrCA6Cwv5OLgR7jkimh7gYqm3kz/lD9B/7Ztn/ AMmI8VTrFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUl13/jqeXP8A tpSf907UsVd5M/5Q/Qf+2bZ/8mI8VTrFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7 FXYq7FXYq7FUl13/AI6nlz/tpSf907UsVd5M/wCUP0H/ALZtn/yYjxVOsVSbzRrV5oGmjUbW0jvQ JoYZEknaCnrypAjKVgnr8cgr02+7FUPH5j1KDU/0PqmmLHeTW013ZizuROk4g4c4uU8VoUerinIc f8rFUw0DV117RrPWEiMC3sQlWNjyKg9ATQYqmOKpVpGtHVLzVLN7V7V9KuRbNzZWMnKNJlkHplgA yuCN6+NDiqn5o1q70DTBqNraR3oE0MMiSTGCnryJAjKVgnr8cgr02+7FVPTPMNzPrF3oOr2iWN7a 26XgaGc3EDwOzJy9R4bdlIZSCCuKtWWv6lqqi/0rTkn0l6mK4luDFPMoLDnDB6DKVNPhLyJXFVC5 8xa4mrWWlWmlW7tqFq95G1zdyQFPS9ESxyItlNRg0wA/hiqP0HXDrMd1HPbmzvNPnNrd25cSKsgV ZAUkUDkpVwQaA+IGKptirsVdirsVdirsVdirsVdirsVdirsVSXXf+Op5c/7aUn/dO1LFXeTP+UP0 H/tm2f8AyYjxVOsVYv8AmGGm8tvZRwXNxJcXFpRLOGaVwsVzBNI1bZGZKIhNdvbfFUotYlt/Ndtq uhW+pvZRWs66tNqcN7IwiA5xJafX0a4aQuu6x1BHUVpiqVW2mTah5Y0DR77SbisOn3ELST2csjQ3 IEYWMQTp6SMwqVmdSBSinc4qjtNtYrqKzTzhpl7eetptgtrMba5kaCeJONyv7lDJbzeqeXqfDUft fDiqHuEmk8x6rd3+l3eoaJJqEPr2EthO/qf6Nb263aVhYSiF4nBUVBB5Cvw1VZJ5+/0jyqbW3t7q c3M9mUitIJ2kVI7iCdyRAnOPjGh603264qgbO0TSbu8057a9ns/McXK11X0Lme5hEi8Pq167q8yc DJyRpOlSGpxxVT064urDyqPKmr2OpW1/Yw/VIJtPjuWSb0/hgmiu7EUQNxHIOy0/a2xVAC0aK98t xa3FrLtZaVKNRuIBqUsgu7gWkhQ3VnydviV9g5UUpttiqfeRLO8sv0tH6M0OkPdCTTPrqMl24dQZ 2m9UCUj1PsmT4qe1MVZbirsVdirsVdirsVdirsVdirsVdirsVSXXf+Op5c/7aUn/AHTtSxV3kz/l D9B/7Ztn/wAmI8VTrFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUtutXjjYx2yiZhszk0RT8/2 j8vvzE1Guhi2G5ZCNoF7++k+1MVB6qihR9Gxb8cwJ9o5pctmXAFou7tTVZ3B+fL8HDDIDXZh1XhC Ih1e5jIEyidO5Hwv/wA0n8MycXaZ/iCDBNbe5huo/UhbkOhHQg+DA9M2UMkZiwwpVySuxV2KpLrv /HU8uf8AbSk/7p2pYq7yZ/yh+g/9s2z/AOTEeKp1irsVdirsVdirsVdirsVdirsVdirsVdirsVSv VrtlpZxHiWHKVh1CnYKP9an+dcwtfqTjjQ5llEWlYAAAAoBsAM0zY7FXYq7FV8M8lrMLiLcjZ07O v8p/h/t5kaXUnDLyRIWyON0lRZYzyRwGU+IIqM3wNhqXYq7FUl13/jqeXP8AtpSf907UsVd5M/5Q /Qf+2bZ/8mI8VTrFUu1y+lsbNTbkLNcSpbxuRUKZDTlT2GKqNytrpQgaW7u1eSRRyJmnEh5A8Cqh 1Ut2pTFVWPWkmSWWG0uZEhcxMQig8wQOPFnVu/Uig74qpr5htnhWdIJmQz/VXK+kRHJVQOberxoe XUE4qj4bgXEk8QjdBAwQyNx4uSKnhxYnavcDFWLvLMpuLWznujqIvWjtOcszRcE4EqxlYxsAta9W xVOJpZb7WG0z1HhgtoVml9JijyM5oq81owUAdjiqGvZbdINStoLq69a3t2kWNjOpiaNZCHExpUMf FjWmKqMF0EvdMS0mulacf6Qt003puvCp4/WurcunDFWTYq7FXYq7FWOXbF7udz1Lkf8AA/APwXNF rpE5i2R5KWYzJ2KuxV2KuxVOtIYmyCnqjMv0E8h+DZvtFLiwhqlzR2ZCHYqkuu/8dTy5/wBtKT/u nalirvJn/KH6D/2zbP8A5MR4qnWKoa/sYNRtXtLioR6EMpoysDVWU+IOKoRtMvpxbx3l4ssdtKkw Kw8ZHMbcl5v6rL86KMVUxolybS4tpbpGM9x9aqISF5cg7I6GVuSGnSoxVa+nLa2d7azFrhdQdnVI YWBVyirSql1UVQcSaU8cVTKyt2tbSOBm5yKtXc/tO3xOx+bEnFUvTQ5TBcxXFyrvPMbqKWOIo0Mx p8S1leoFOmKqjaTctNFfC6CX8Sek0yxUjkjrXjJEZD38GGKrJdHuplvWkuk9e+iFu7CEhFjAcfCn qk1+PqWxVttHubj6pHe3SSQWTpIkcUJjLNGKIWZpZPwpiqbYq7FXYq7FWPX0ZivZk7MRIvyfr/ww OaXtDHw5b72yB2UMw2TsVdirsVd0xVPdLjMdlHyFGesh8fiNVr/saZ0Glx8GIBqJsovLkOxVJdd/ 46nlz/tpSf8AdO1LFXeTP+UP0H/tm2f/ACYjxVOsVdirsVdirsVdirsVdirsVdirsVdirsVdiqD1 Gy+txhoyFmjqUJ6EHqp9jTKNTpxmhXVINJHuGKOCjpsyNsQffNHkxyxyotgNuyCXYq7FUTYWLXrC Rx/ow3JP+7P8lf8AJ8T9Hy2Gi0ZJ4pcmEpJ/m2YOxV2KpLrv/HU8uf8AbSk/7p2pYq7yZ/yh+g/9 s2z/AOTEeKp1irsVdirsVdirsVdirsVdirsVdirsVdirsVdiqhcWdvdAeunIr9lhUMPkwochkxRy CpBQaQL6Ia/urggf5aBj/wAKyfqzDn2ZA8jTLjK0aLN+1Oo+SE1Hj9sZAdlDrJPGiIdHtUPKas58 H+x/wA6/TXMnFosWPer97EyJR2ZKG8VdirsVSXXf+Op5c/7aUn/dO1LFXeTP+UP0H/tm2f8AyYjx VOsVQuoQxT2zLKobpQkAkVIG3hiqDehKWF6okkjkT0ncA+pGWA79+xxVXGouz8Ybdnjqyq9HAqtR Un0+IFR44q5dRkdYGWIf6RGzrV+hQVofg/HFVtvf3Trbo0KtJPGZA/OikClf2CR18MVXrflroWjx gcy6hlfkQVBPxUWgrTxriq7SgBZgDoHkG+/7bYqjMVdirsVdirsVYrLqeq+XtSf9KsbrT7pyUmA+ x7KO1P5fuyuzE7uzjp8Wpx+jaQ6MmhmiuIlngcSRyDkrLuCDljrZRMTRVMUOxV2KuxV2KuxV2Kux VJdd/wCOp5c/7aUn/dO1LFXeTP8AlD9B/wC2bZ/8mI8VTrFVKeH14/T5tGKgkpSpp2+JWxVqS2jm 9IyVZoWDK+1aj5Dviq2OzSJjwd/TYlvSqOFSa7bV6++KqaaZCnpfvJGEAYRqWAADdvhAxV0WnJC8 TrLIfQUqoJUih7fY9hirl06NGRkkkHpszoKqQpevIbr798VVrW2W1jMSuzipb46VFTU/ZVe+Kq2K uxV2KuxV2KqVzbQXkD21ygkikFGU4kWyhOUJWObE2TUPJ1yZI+V1pMrfEvdCf1H8Dle8Pc7QHHro 0dphlVneW1/brc2riSJ+hHY+BHY5MG3WZMUscqkN1fCwdirsVdirsVdirsVSXXf+Op5c/wC2lJ/3 TtSxV3kz/lD9B/7Ztn/yYjxVOsVULu5FrCZSORJCoo7sdgMVWVv1ClvSbkQCFVvgr3+18X4Yqhvr t6LSS5rFWOX0+PBv5/Tr/ee+KoljeIH/AHsLFULU4MCD2qPVOxocVX2Uks1tHNMVLSKHAQEAAgGm 7NiqlcXrQ3UUIUGNiFlf+UvUJ+IxVu4mulu4oImjCzK5qyFiOFPB161xVuyuZJzNHKF5wPwLJXi2 1dq4qisVdirsVdirsVWSRxzRtFKodHFGVhUEHsQcUxkYmwxO7sb/AMq3DajpdZtPc1nt2JPEf59G +/KyDHcO0x5cesjwT2l0LJNN1O01W2FzaNyXoyn7SnwYZMEF1+fBPDKpIvC1OxV2KuxV2KuxVJdd /wCOp5c/7aUn/dO1LFXeTP8AlD9B/wC2bZ/8mI8VTrFUNf2zXUHGMgSIyyRk9OSnviraTXLgcrcx kbtVlINOy0bv70xVAGC6axltjbNykl5gFo6cS/P+fwGKq/BoxILaxMQkSj0Ma1pUKAFkp+11xVdb Pdw2sMH1V+aKqMS0fGg2JFJK4qovZ3FxbTtJ6kcsrFvSHpEVFOFG36UH7QxVuWO4uJbaS5sy4iRx IpMbDk3Hpyf/ACcVVdPt5YXnYp6ELsDFDUHj/MfhJAr4YqjsVdirsVdirsVdirRAIIIqDsQcVYrq OjXmh3J1jQK+n1ntRuOPU0H8vt27ZWYmO4dng1MNRHw8vwKdaPrVprNv6sB4yrT1YSfiQ/xHgcnG QLh6nSzwSo8u9McLQ7FXYq7FXYqkuu/8dTy5/wBtKT/unalirvJn/KH6D/2zbP8A5MR4qnWKuxV2 KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KsZ1jQJ7a4/TOgn0rlPikhX7LjvxHv3Hf55CUa3Ds dNrIzj4eXl3o/Q9ft9XjMbD0buMUlhO3Tqy17fqwxlbRq9HLAb5x703yTiuxV2KuxVJdd/46nlz/ ALaUn/dO1LFXeTP+UP0H/tm2f/JiPFU6xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K sf13y81zINU0pvq+oRHl8OwkI/U36++QlDqHO0mt4BwT3iv0LzEuoMbG+X6vqEVVZDtz49SPfxGM Z2jV6LwvVHeKe5NwnYq7FUl13/jqeXP+2lJ/3TtSxV3kz/lD9B/7Ztn/AMmI8VTrFXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUl17y9Fqqi5tz6F9HvHKNuVOgam/yPbIyhbl6TWnDs d49yO0tdQWxiGplWugPjK/hWm1fGmGN1u06g4zkPByRmFqdiqS67/wAdTy5/20pP+6dqWKu8mf8A KH6D/wBs2z/5MR4qnWKuxV5/+Z3njWfJ8unJpUcEgvFmMnrozUMZj48eLp/OcVYSn50ebmO8Nj/y Kk/6rYLRb0Tyv5p1PUNLTVNaaCHnGKW8SESM5kajrWRvh9Pjt1O/tlwwkgOTHSzlW3NE3Hmi8s7r 0riL4ZF5xKY+Dcf5zWZ9q+wOSGKJDbDSRndFM7TWHubUTOoiYRhmZq8STvRR16DInHRYZNMIyod6 Al81fVLhkugPRC/bVTUMOxWpND75H92SBe7b+SjKIo7oC883arETJBFE0Dtxjchu4qoPTc5DUSGA gnkwlp8cOdoKz87eYbq5e2+rxeohqY1jZiE6fFxk2oaZXgnLJOjyYxwQJ8kXZ+cr6S69G8MEcaKz SlVYspFdqc8zpYIAN8tDGtrU9b88XenaTdXtt6crxKnoMUISQsVBPEuGpvlc8cQC15dLGELYOfzk 82dorLf/AIqk/wCq2UW4Fu/5XJ5urQwWW3X91J/1WwWvEmmh/mzrepavYadPFbhbu6ggcqjAhZZF Q0rId98FlAkbevZNm7FXYq7FXYq7FXYq7FUl13/jqeXP+2lJ/wB07UsVd5M/5Q/Qf+2bZ/8AJiPF U6xV2KvIvzyUtPo3hwuf1wYCxk8xsIXF7AhWNi0igLKf3ZqR9s1Hw+O+MTumJ3e5WVjNB6Ka3cW6 SIQF4MPSLBfjAVgvcZm+ITHZ2wyylD0jfrSF8z38KmJ7eZJ5Io29KVyRVgC/FmJ9xvtmNlynFW3N iJSxRJIrySvXNeFze2tharJcRRdHg4iN6cak8eo+Lx+WTOQjkmEzDp9Spd31mbiErAaR0Wb1WqZG rUsK8hhsDet24wMY2Smlzr8Js30yG3/cMv7tyVBqxqQQFOE4ozPqaRpgTxE7scjujbmT0XpJMOMi gsKjanKnXJQxwiPS3jCOak0iVKhByry5U/Xk7vkyB70Hrr3Fx5fKKiIEl4MwJDsGPNQR0NPTOUZp EQtw9eQIbdWHrbtRgoQDsHO+3gcxOIOqUTFKDwB5GvT/AG8PEF5px5ShY+ZNILDdb61anenqpvgE t16vpHLWx2KuxV2KuxV2KuxV2KpLrv8Ax1PLn/bSk/7p2pYq7yZ/yh+g/wDbNs/+TEeKp1irsVeW /nJarczaTzPBUWer9aVMXYZVlnwsJmnmn1CWNi0T8wlSH6VI6Hi2VxzIEmYWWp3N0ipdtzuLelIg 26o29E5V236DM/T5xkDudJqhkj3SRyIl1FLeT2s94kChvRjUEKagAy0X7PAN0wamEZ0e5lqxdWUR cCzdJJbbisFUljjhIRE5pVg0a/tn0/D5ZDjF0C14+GAY9f263lwQz8hAgoAPiAr1NPc5i5854tnC 1ubjybK49S3RZGmaRgCWjYGjAABeJqfH8Mrhq5iV2xw55xN265ne3g+tzKDCSoJSppzHw1zZ48pE fU7TjPDclS0uZVZvTZA0qFSjBWqhG+zVofDbIT1cQNmPiRIvmiAvoxSzXKirQkRQE1C8/h5sAftb nr92UyIyQJPRx9RxZIknor23kqwudG+vRXf+mhS7WoTcOK1UNU7UHhkI4JSx8ThRwSMbrZjN95bn tZCkyyqOvIoVPiKqa+OUGZB5NR2KI8s2IbzHp8kCh447y3Jk2BNJVY/D7EdcYzPEF5F75mY2OxV2 KuxV2KuxV2KuxVJdd/46nlz/ALaUn/dO1LFXeTP+UP0H/tm2f/JiPFU6xV2KvN/zXEguNKkjf0yi zHfvvF2zF1cqIa8jDPRubtBe8KvUjmlR8K7Co+nMOUqYU6O1t7QKXPqXLMQJo2KgKvUVbqSPbDHN MG4lnCcomwn2kazqEFqbW0jiICuHdwP3gJJo5oDX4szMevqFEbuVDVbVLdRltzFEgsomjiSJBdqK 0Epr17dB4ZstLjAgPPdzsUQI78y3LHPaREXCNHI8QYhDuVYch49RletgJY/ixzxiRsdkPJcSI6Is JkWnEhaCn0VHzwjEMQAjFuw4YQGyWapc3thdoXnZrSFXkdDCyhZOJUAhwtd22oad8x84lIUWGcSJ voEDo1le6k09968tImCFndhvQV+EGp6jIwkBMR6uPhI46N2yvQrJRcqt5IHMilUEgDISdgCp26+O Zvg8UdyS5WSETYZYn1/RvRVw3pbIvMFokZioX7BPyHQZj6eEonhlycfFDGY8P9qnqsv6VP76QEwh iAFIQlRz4Oa+HTJarSxnHbowy6aPDt0Y/ppR9bsZbcKGN1AGC0IVfUWoFflmoxn1j3uAZX0esZtG bsVdirsVdirsVdirsVSXXf8AjqeXP+2lJ/3TtSxV3kz/AJQ/Qf8Atm2f/JiPFU6xV2KvPPzRkZJt NVW4h1lDeFKx9cwtd0asrDrfULqC29KCVBCxYNGwqQD1p9K5iVfNgEXbw2jeg0gcuwZnDGiE0+Dv tiGaowRQJEBEcAAcgVBbACSNk8QRWlyxTxXM4uBDcpV4IlavIozMPhNOVVBB2ze6HOckN+jttNml khVe9A319davLDFdSM5tjUtQKQPiNOS0r/bjmnATED3ss2TEJ0AvWNJXdoplKr2che9Nq5kk25Ag QOSnexqdPm5UdiTVWPIUK8egoe/XNZqdYYmo0XC1WvldCkF5dt57GBi09Y5yH47gPx7MO68l6e2S 0+oiZVyXS54mwUyCM9LkAoVIG/8AEZmxyATAc6GSMZcPNPn1e1NpGivznkq7yqWXgzH4l9M0G36s tPeGMuIT/H3rp9ctLaxuLJQkzeiYxNU8md67/tA8dqZRqZiMDv0cbUwHDZNeSTaFX9M6cCiuxuIj yX9n41JqBmjxG5j3upGxevZtWx2KuxV2KuxV2KuxV2KpLrv/AB1PLn/bSk/7p2pYq7yZ/wAofoP/ AGzbP/kxHiqdYq7FXmv5stxuNLBNAUnBNKncxdMxtULphkYJbzxW85MkZmUjanbfMWrDDkjg0T9X MhY1C9ApG3c9Mr4tl4kxhuPqEZd4F+NiarRjGwFAd+QpWhpkI5Fq1S1hNxp/12eeMzBuUnLitTJ8 QoPp7DNxpBwQ4v5xr9DstGTijf8AOUSJVVxbsJJZFYKADQqtG5Hbpt45dlMhXe5OeZ2rmrWel31x FLdI0ZitgJJB8PJRXpxbqMxMo1PA42TLnA36ofUr76pBJPcjd/3aIAByJB8Nhmtx45GThEKGmXS+ m1IecaAM8bEBVYmnJD+yTTtTJ3KJv5IBMd2S6KJbOKa+vLVpLSfaEOPjDUPxB6bU5bbfqzP0nFks z+ZczTxOUeo7pXMUnjIVKLC5HiAxNRVu9RmblMskSIHdzcsiQeA7oZRGQwoWc1UDagbamaTJllkN l1GXNKZsovRp5jrGnq0fpj63CpYCm5kU0xxXxj3tI5vXs2rc7FXYq7FXYq7FXYq7FUl13/jqeXP+ 2lJ/3TtSxV3kz/lD9B/7Ztn/AMmI8VTrFXYq8t/OSZo7jR1qeDCckCnUGGnX55TnjbCYYD9eiENY 4uMitRnZwQR7JmL4dlrRNs9yOE0kbGKTcSEELSu9G6ZTOAivJP4IYXUSQRsBPRqOSfhG56EfjkOE BYy3tdFDKI0gLVL0R4YzU0Ue3fNvoNRIg8X0h2ej1HEDZ2iiY/qtlbxXCSPFcwEbFaKa0/aDH7Pg R3zMjG5XezkgnLI9ygJRN8CXHpTN6lZJPsOGBIU8etaUwzPpO7ZMnhNBB3Oi6leelNfPFO6Bz6UT cxxOxP2ga1zQk8PJ0PGHWUP1Vp4bhCs3FAjEVjfhVSGAp1+H6chM3Fnacpq+oS20djG5SCEcQgAp xah6d+nfNlpdXAxAkPJz9PqYH6huhV53ZLonGOAH4auQR1BNWIqT4YdbqPDPpO5Z6vJ4ZuJ5oPka l/tcjyYDp881MiSXWS3Ka6PIs2s6ezR0YzxESdahZAOnbJ4NpAeaL3esZtmx2KuxV2KuxV2KuxV2 KpLrv/HU8uf9tKT/ALp2pYq7yZ/yh+g/9s2z/wCTEeKp1irsVeW/nLGrvpla1CT0NNtzF3yrL0Yy edR28cihWNPTHFem5O/vlBtAibTnSjqGnTLbxzNFGaPJGvQ9AAytsa18Mqlunwt2VJrlnKfq92r2 N1cfBHMg+BiRsAabHfpTKfCFEtU4GJSW90C4sZv0jYTsswo5laQcSa78i25qN8shkIFHki9kC+vG 6Ej29uzRPLShFaE13J6bkZmR1c4bbObj1+SFDZESWk04iWC8kjkAZ1VgBwkBbvvsKbjMUaiY/Sw8 WRvfmo6frzRyvFqNtEoVlCSBVBjdu4rvxJWu2SlEEWGkUEzmmhbl6IKEEjpQbeFOmYUocO4WQrcK tlKWT1udJakANvUVPSvzy3ibY7qsTvIHjPxq2+3Yj+bwxluN1kLCxuNxB6SM0brQRxiOo5EHpw+X c4Iw3auCVquhi5ttbtFkHAtcwrUUoQZVB+/J4wRkAPey3t63m1ZOxV2KuxV2KuxV2KuxVJdd/wCO p5c/7aUn/dO1LFXeTP8AlD9B/wC2bZ/8mI8VTrFXYqxvzP5a0zzDdWh1KUolukhVFPHlyMdSW9ts fD4mcIWOVqOiaToMqy21nY2r2lsQoLRhmdv5i7qWO3jkpQxgV1b80I4gB/ElXmTStFsYm1CP/RIR xP7o/Yep2WlRRqdMxdVp+EWGjNjnEWktpBb3E0F7PaCOOM/BJPQ8lPE7LSlduv3HMGQNOJZPNfrL NYGRrKETw3vNRIoLejzUlQAgOxr2wQ3BTKFC2JSxxadG+m2zmWW5Zf3XIFWcNQU222bb55YQZUT0 ZdAybTfrJsGup7OG0VV9ISTHc95WaiswauAxA5Ngyx4SCN0hv0s7z1kEchdDWOSKGTbanxc1WgOT x7CwQ1nJY5LNEuIZ4Gt3mS2aFTUyFVLCu+7Uqf6YckDdhJOyb/VeM6xyrI6BlU8QONG25d8q5thA rZXt7A28gDTtxMgShBLfdv8AjkJEC6TCQMbVmv25N9Yb0oKE/AECEKAm4NPtH6cnjlM73s2HJQW6 TfW8+q6ekKCMm+hZS7EtxMiCleJBr2yeIesOOQQeT1zNkzdirsVdirsVdirsVdiqS67/AMdTy5/2 0pP+6dqWKu8mf8ofoP8A2zbP/kxHiqdYq7FULc2UN1JHJNGsnpggBugr7U9snGZiNm3HmljBANJf caTdxsU0r07WE/EQrshZunxBY22+Rw48lE2LbY6kHee5UJNCvpZCJBbTQBQqpJyO4X7R+Dry3yU5 wnCiGU9RjnCiDaEn8r6ncKwdreoBCfGxO/ixhNM1h0sz3Ot8IrJPKF66iksQIiWPhyb0yUJIqDGf HIZNJmO0SGwR9NFi8H5U60Lj67dTWclz9YSU8ZJAhQEs44i3FDWmWnTzqgdkCCd2vlHzLa2Mtiv6 PeJ+SohklVVUg9eNvvufbEaUjqg499ltl5N8zRabDp1xNZLxJWWaJ5CxjO/RoFq3apOP5SjsxOIr YPy1EN5dXRFu/qsjwAk/AVX3iIFWx/L5K5p8MqjeS9dBMsU1qssm0lXcgiv83oj9WA6WZQMcgrTe TNTmn9d3gYuiiRBI6guo2b+6PfI/k5nq2RFRpC3X5eXt9ye4eCNmQLwjduHbb+4HhkoaWURzbIEB qy8gaxaatZXiz2sdtazRSvGhckhGUsAvpKvRcMdNISBZSmC9BzLa3Yq7FXYq7FXYq7FXYqkuu/8A HU8uf9tKT/unalirvJn/ACh+g/8AbNs/+TEeKp1irsVdirsVdirsVdirsVdirsVdirsVdirsVdir sVdirsVdirsVdirsVdiqS67/AMdTy5/20pP+6dqWKu8mf8ofoP8A2zbP/kxHiqdYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqkuu/8dTy5/20pP8AunalirvJn/KH6D/2 zbP/AJMR4qnWKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KpLrv/HU8 uf8AbSk/7p2pYqlPlPzZ5VtvKui29xrWnwzQ6faxyRyXUKujrDGrKytICCCNxiqbf4z8n/8AV+03 /pMg/wCqmKu/xn5P/wCr9pv/AEmQf9VMVd/jPyf/ANX7Tf8ApMg/6qYq7/Gfk/8A6v2m/wDSZB/1 UxV3+M/J/wD1ftN/6TIP+qmKu/xn5P8A+r9pv/SZB/1UxV3+M/J//V+03/pMg/6qYq7/ABn5P/6v 2m/9JkH/AFUxV3+M/J//AFftN/6TIP8Aqpirv8Z+T/8Aq/ab/wBJkH/VTFXf4z8n/wDV+03/AKTI P+qmKu/xn5P/AOr9pv8A0mQf9VMVd/jPyf8A9X7Tf+kyD/qpirv8Z+T/APq/ab/0mQf9VMVd/jPy f/1ftN/6TIP+qmKu/wAZ+T/+r9pv/SZB/wBVMVd/jPyf/wBX7Tf+kyD/AKqYq7/Gfk//AKv2m/8A SZB/1UxV3+M/J/8A1ftN/wCkyD/qpirv8Z+T/wDq/ab/ANJkH/VTFXf4z8n/APV+03/pMg/6qYq7 /Gfk/wD6v2m/9JkH/VTFXf4z8n/9X7Tf+kyD/qpiqU6z5s8qy6joDxa1p7pBqEkkrLdQkIhsL+Pk 5Emw5Ooqe5GKv//Z + + + + + + application/pdf + + + Adobe PDF Library 8.0 + False + + + + +endstream endobj 2 0 obj <> endobj 7 0 obj <>/ColorSpace<>/Font<>/ProcSet[/PDF/Text/ImageC]/ExtGState<>>>/Type/Page>> endobj 18 0 obj <>stream +q +0 0 612 792 re +W n +BT +0 0 0 rg +/GS0 gs +/TT0 1 Tf +48 0 0 48 62.6667 672.0521 Tm +(Black RGB )Tj +0.502 0.502 0.502 rg +0.028 -1.861 Td +(Gray RGB )Tj +/CS0 cs 74 0 0 sc +0 -2.028 TD +(Neutral )Tj +0 -1.2 TD +(CIELAB)Tj +ET +0.855 0.863 0.439 rg +q 1 0 0 1 451.2545 532.1 cm +0 0 m +41.507 0 75.155 29.252 75.155 65.336 c +75.155 101.421 41.507 130.673 0 130.673 c +-41.507 130.673 -75.155 101.421 -75.155 65.336 c +-75.155 29.252 -41.507 0 0 0 c +f +Q +0 0 0 1 K +4 M +/GS1 gs +q 1 0 0 1 451.2545 532.1 cm +0 0 m +41.507 0 75.155 29.252 75.155 65.336 c +75.155 101.421 41.507 130.673 0 130.673 c +-41.507 130.673 -75.155 101.421 -75.155 65.336 c +-75.155 29.252 -41.507 0 0 0 c +h +S +Q +Q +0.855 0.365 0.439 RG +10 w 4 M +/GS0 gs +q 1 0 0 1 350.1097 513.3745 cm +0 0 m +174.545 -157.091 l +S +Q +q +307.1826477 0 0 230.3869934 85.1999969 108 cm +/Im0 Do +Q + +endstream endobj 10 0 obj <> endobj 17 0 obj <> endobj 14 0 obj <> endobj 15 0 obj <> endobj 21 0 obj <>stream +H\j0EY6Gb14n +^A~#SC- Y; )T ҽDUT~=ـx ጗ީ$ۛZfhH,ӌCQD9aG;q`1_Uzb(KؑK_!Ze~?/[\ 3S]_f}>2f\|r{f=T8r5gm!Pkk|9~@*Wm +endstream endobj 20 0 obj <>stream +HytWǿo7M,!&kAhsZj !$rBQ*%ʖBp""%1j7{3̝{3?X1ДZ<L^iy7gSHbA突ޏԸ=ǧcfqg<I2ƞ1a0:-*5L><+`:F~@הIilhnʣrӦEK+(>abZnƛ@wޤN b3z\kz&1\CQlmHO91/deBQȔ h| ({ z0Duz BM%>,0_3Ę6bH3H4HO mh@"m06';eOL6m+'f`'O!m(0 gD$spCۻcQ|zlA[ҴL=˵bd9 culH^Jm~Tfl=4GbF`"WK +o¶yeEy~I%P"ߜ2$+&׵u~V~Ox>2)|$ǤXF +3(%# i:=(Ƙ+$P&dLE9MNGCr89WG\,W!Aޓ5hll`2ooڣT=5BXbDօ?HEz?E +~1|L+Dn1l@98*zk +X +lrJw/ui_漧}| ?j_о٩}S}>]T*?i_־٣}Wr.u*TFj_Ӿe~˝(9@rX'ڗ9/w>!7Dj /4ZC1_2_2 p!G>+<"yD$wȀGD +="H!߁^Q!"PBeGD="RyDdGD{DdKDFzDd= \"GD6o둑;Fy|dijRa? ,QG*TGJcF*Rtq + ܸF8tBGwZaFW/a:t?YsH.#]v$u`9nUh5>3et貟?~F3gt螟Q~F[teX3Lts OZh9c/J i?VbX/7n0\=bzCW|VPîfgG:Y#Un& 2sNLCT>"v餯N괯꬯꼯.h%hi'󙭦|f?lbvowaŴFkz6!RDr"Dl;m4+ }]+ҽR۵m69vV-%&`+JwPз`+VUhB}` G雪-DZo8EVC|P\^Qu ݢVGב__VC-ܙ9bϵ0+(ߴ㹻-J[Oxo;n*_b&^fo|7A~WSįQ_w]^kD+$}D?1@ 3bx^ ???"SLd K)fb/^ "kQ(߈bX-~+֊u-Q"b%}8$8#.+↸#Ex ٰiGvk7O-v[hw='>v?{3;ΰ'7*lUjbUZV*I%.j~FT5JVcUr.{hʛ-x[ޖ֠oGkݑw]yW|& l>!|.P>G/ "aV//jkZDu|/謪+ yOo3 "D00Hb! a SHB 3"R +E(TVZPk-"E@ TEғW/wɽ~7<97MuD"un]KCݥ$R>y@i4zX}}_ԣzT1=&zROJ~HST?39izYZ"^zMIn&miTJ{#]:'zCDtDd!Ka IBFbtF + Q,(EtDha*Jw\R03`b.JccHbsxNzaI&c,>X˰L˥V`de,9XUjX52kVa#6`7d2۰M;evc 3w;xGF]+xh)GH +q Ǥq\yS|*cqgqV.H).㲔*x ۸--I@LvTp.S]ȅdjtWՑG\]WW]@u.RsQ.JfX+3]3Lw-\ ZV2Ź8]<ڹv:S(s]Ky,]K]K.ե3.ݥBYW9WJ'ܕˢvy>#C VYb0OUVjϬՑeaEZ,([ +kn%ki-ekcmkoe%X:Y'yպZWYe= ː_Zo-k,re Ά0YollB+6ʯu`dMI>Q^􆾠/+J_ IwݯxHֳzh8}!|1fIx oڋ8!8$>)9\\W߹jdq$!*pŮgBn!eu5&Cuf@j#lq6ſk9&4[N iJ]}N_UWW!zRMzT^C/O/եKR}zԐ^Hi(A mM6MSڦmӜiA۴mZ6i8ڦ mO۴C@Gz H:.@2=ЕFtR@*=F@Oz=I},z=M\z`!4$zYLߡ7#2;̎"dv4- d̎!t,9-!i)9-#r:N"r:N##d2]c5N;h%\Wj] ݩ{zP/zB fټl@ L#x + ;m;ǿ y\¿q s>WSDzy[vA@Ng\;>Ky$'$_@oq~EEDw7ˏ=?'#nvϳlvxb+XͫWUOWU gUճ*^U`EJЯ>5ڇN'Z3h@|3#+ڡ=Nt g7|V;j~HlZwG{S뫽6j[jFSwIzIw }^0;Qhxۑ(u2%9ÜXLpvt905s`0%|F܈7d14YFg,0V2c8d5W]\]\]]\\%I6Qg'g+nuk5[ b:[2,dT}`jhJ5ǚ*f'/Sm jhSK}ƭmh]zJT-CqՋ[/=&[St'pKkP(n/sP*n%Y~/*n]{OO鵙AnuLWg/%s7Q+ P8hV8׭8UFYUH_/gI}Pf;A'~| ëԽ*TPէ2r䅏+2*>,X9WPQZ.N. S$ooGo%O'ɓqzy"-F(Ȅ1p`+c2 A8j:sqb\ ЂRɟ\Kp)`).W*\kp-II7f܂_b(6ĭX160 nH0c` Ŧ;q6hC;=E@'}A<a<£X8@2\M(&J4S͠O4O4R͡4S1-ZJ% *eVJZEi u6F`Di }I[m5m }KNEi}A:DrSTc5ՙZ9ةf2s070[̒q:A'3tΑOygIԠ]փf`6D`&hJ 0kAӴP3܌0 Ff3lgfgv7{A@\~I_ѯXihn6 fx@0aҨbx>gUM K+kGRqJӢ\g9q^"..'-V24C۩oi۴aqDP;ͤ骁f.)kE<}8JsigGlc3*=]F&k{tfYb_mB['Eb}>AQ(P֖A2XڥC:K:Ғn*dl/;T.)d'cd')d̑̕eLl,&#b-bIArL9II )%H9Mer\%ur$mrGq\q 9KAԥa">:A>ʁTiPG'Jc`,S>HECi uD̘X2FH"Ei=Cci}ڀ)+9P߇P럊`6TQ_{z+“㭕3W\W+B ЖŰXëR>4c 9mH3Z 8yir6`^ a*>~UVQV` +cCFDFE׋ a|M6KhآeRmڶKi!cZzF̬y]vޣg~}8hÆ(9jO{S~GӦϘ9kΛ`K>Y+>VZŗ__fn7}-[m߱w޳wO.:rcO,.)=.?sy¯tf&kU^pd QFqt2CSI[{(܅ +u"Zj7|V5doj>nPj`ad a1@:A5\I *+MX`?:0›Q8\q80NB;xo;. > >!oG0>O`| +[a#*``. +&BgbPH(\1vTnm\Kp).\+p%ո:\p#܁Spn-?G'6mcb1Q8ĝ ¯X 0[෸%cp(C1pxa8T.r\!WUr\#ur 7MrQS-UJP.V*I%Z֪1՘CY%^+c_s~_/KG+*܏3T[ک:NP]TWՍ'qOlSyOù^tE'Yt]E7]<&z~> Oħb.Ft1R1q3>ćc\ǹOI>ŧ s\yq /p_K|U.W5*\|oMomw3k9h\fiF`0cXfi%-,n)ˡURke9fVs+tflZaVaEZQVh.3 3 3YH$, "%";c.Bd jk)@Y-;&*p_<39s3^Un#u$K}i )I4I i,%ML#*TIJsi!-)%mMIvr{+Ig"]YwNI>WC碌)PzK)R,DK A ,CK*d'#d/(yPFeq<,ȣ<.Ox t=CL=Ks+z;_5G=Oׯ7d.K>v BȽu{O3_)"O2ͯp9 ,wx1/᥼W7po䝼A>>}Q_җMsi떸'w]s]I_u1+lLibځU1۝LgG Ng0c|6jdLf<neۖ XN3W]lW-=m/[h{>Ŷ-m`A83-s8dHDftst[T7jFQ(+jZGQ^-*zGQi48FEnoU{>_P!C +UCЄ6L + ЇaͰVxcx:KJSpmsWr_nv{w^piiv%F m)\ *rPfϹs)b&]PǜrZv>x>ruImEۣTNSZ@T*SD5SR$Z&;u|]_'O }#| |c|f>E/|oK|Ov`'n[>t'n[6zRo[VMo;tJ>>ǠugJ8sNG~(cfT0-fh 7 YͱpG* ?w܊IuxA8]G|͌1~Q*2Ԉ~PM͡nHK:=6S@ 3-TLRm$r$!Gn3!6.]qx +)~uT2n(^F8jR:RLe| 6?,Tqj@襠e0-KGI[Vf[1$Pgx9M9ϼI)S! ٧hy.ǝr|,Gu`?a7v!Q_-,FUf7z+ +1"6v65+ç;TXyItoo1et{Ϋ\8‘4T>a/e:X9xQ|TdjCE4TEG]>*z{PަQ'W_]ZNQʚ \Fj*EFރ@?y3;Ә-~yR)mk*zQmlhQӝQoX\3KHH\QT 0x΀cƨ'at^չ7;r?Syۂǃ?MwyqÉʸ ~{ȢtjB-54= B^ߤX:PN j<Fc T9olJ2;c&#|~]^uu:m^sKNA-~wȷ2n ä =栝i>`2u6v`)z$i2s$qN75a _|^*d3[$W=i)\]=La: +_{Mt,fS? +87nuD{D) ˠS䀐-2h1y\`ar!mHjt˖(>âKc @ϙCq 'L`;I!m{ϋr:)9DVrMdY4c\);6"*qk(l38~Ѿn8jyx~ X^hs6s;pϨ'L< >Hu{Qxi>\ V{ԵGD,Ҋ@C4mDV8hc/QCe }ۓnakyGs*"c ky^8hڠK39uYiLq&>U3dAzK^ߺNim䤞y9\^bF"y:" +^Gf GRJr ӂ[ m4J tAfwagъÎӅlK2LKvgyjel`NFCt.~yE:C٭99g9ԫȢO0i`239hHqCªBFڳ*Y׭MH6N MdVQM-Zl1x.~pB-95-#9G2qZFQe- )7V( ak0vs9zMnE#PrQOEP@vMPxIf{i.ԅao_$]MUy $G^4CPM+2O-! $H!Zv}~;f~ ILpʫzSSJK.,ox[_##>?|挈%uA5B +P*`0TQrsN[fEy\o}G'.+ +zq!%ֆĮ2M.l7хaq{HSiB +LHsI ſ Wūmx+ZZ"JBw<3y˂= ʢ +eA/wOUT*T: w\S\|.W+#V lC{To]+)GYynx爼CV|ceƩ]5M\w޻9g_wM0Vr(4JBa,nj7bC!eSK +***LeTVZ5@chM+(DѴXFU6{ۤ޽}UBΡ7~HW-y٥MOo|"עuTn +~>i"ìh hICOP5 *_?SJ-ő.Z5ݲ;%c`wC0tppn,w<4_ 9'$ECGOt&3r!8DXf@Aomm^>0y=]E*9QpK!]&H1gTQ&:b:F3{^qD3`1ssXɮ4>\fȦPZ`K?v|[qq +(LS$l4A)pPbtS58l(؂/B"QͫYUTwZ(.^wh'sW|3T1 V¬YG6Um2P'xHaYa$vaLvtY:uŸ"3:\qy5mϢ(AT"JEBh +qi:$eH8H)+ni|ťc7>5ң>3ʦ/Zy34ѹN6>~%*OD)-=;OnNzBubG^-h, dRVh'\(^KylqrbVM!3T( gNYGHaSWDs;*<.qK 8 ?4}'kTϜw M3߆4r'd.#DΖioe6azaf:F1*BTDAB!RchXL+H L '@BհU'N "a| +WLEdEKK+k-,]b0`8fCgv$1U'ѭOT_o739!3gʘ3e̙8qAEnË90n6(*BepZ(TPboYhpQ +m +XHP0# $G3F s20hʠm{$M+JcU.1Zgw_j>r#.=}_kѡPֽ! $;GkeCdYT^# iM4(}uF|QFv ;ޑA;;xrGx=gp-j:K5{/fe_;A(xPTפ.0 +cqјt4F6FVL^A';W9!{89SnƗ97F}]7 a1 ep1a?|`NX$B +ytU0d޷t@e8VFE"$݀l.99.NB(pƅ5BA'Vcc2EXp1S6ˌBIeM""dc^BB4A:^<|gl b]ڼmzmo-ߵI ~woRa%i凵wk_1~+#u#H"KcdjS2p$#JYVE)URbܼ,N·zavf{,^v%7ُYe.v7hR3ZM[ KcҴDjR4 %8)B!Dv=&vHy]8/9kT/h}aV'4 .i_(J{`(+|{gc{vw;3c^w?B ndMZ҂ !DpyaM6)$J*j#$~?mmT7p1ޞ{fΝwf=~w#ڡ(!>^z7va4rh`Ct}Ni?.iks𺝭vVb h { w4,1- UTQI.:G@+R?)h\n.In>Isӷ} +1hY<0D/mc%\oZ4;hUVv iط~NxE\6۵}whM  D/(}R MS +(gp %Ba M}|oҏi>PɹuCú!0okF(5ZQ [v՚+vkKQW3- \i׋=WZ5\%+h OЄ=¯n`\" &nvQӰYn@%q)k$ 'W X`DDϰRjT~ T>9 x{^DcHK߭S +@E%oA lbÙg!lcGvb)ޡs3 `%fEmEVۘgs|% #sB=BjnNã`<_:,7Hgyߒ(T6fNTٺ߭^ W7\!;9 $G=m09OzMP4<\2 dvCp)8 ?H~v~?7S2J +* ثt4wdITU W1ŮRaUٴɌ +آB +ըؘx[ wvlGEaZ R9]!Q)v贝Κ< <ѯ_S +6Bk4~T?s巿5̔L,b{dEzHp2.,XSNV6`PZ0{'wZ2!j.5StZl4eI,f`0 +7A9djj@VsHMUBX6(&QK[m2x!BmgB||V[|t̯/ChtjROucy'(d}.6*\z\׆%\?'wY ۻ=T*hQkp5rξFN{N%!& e.ϱ^[ou؅SRԈ ܽ! qqOՖF +tԙ%D*w D"R˒<޽#/K%jiT4KeRWIZcFBCB:tW؅g.'5>y^e)H$[!I&~ w5{ v8"fԜ42|bIL-2o"?25j`]N[-]iiIQEx"fĞ|KD/bfu6b㢼0^XxZlM2`$Tm WlܐTc徶vp9N ͠҈7S⫊V`:-;ssEU4R WFO<1#CS'0>A=3+L oo""gdf+6 ߝUyB +2z,7ne[nn.UfK6!23kڶBb?X2Z` W$AStÏ#ch`tv7:U%מYS}e݁1hh^K N'_MXj캟Bisz/ :kYܧ.._GrqMFz=l᫦[qYK w>kcۘʑXOE5X1TNUߖq8<;OIF@'` #Ш?4N)ӡw] =^ߝϴE9FeH9=MƞD扆G7D#OFam7%kxѧD]әןX*0]bTW}lS=}>=~6ql[;$~4 ڬ@JzilJvS'VL&m0 ib @4:"EZA%cU;eG ιN&{}߽ʋ[ 8pH_梭A]ˌ2F4ikD >J\#qX(:%WJ} QߺPkk o uvZ9j=IȥdQR/! : 3ASyhBJ"Pz14\`Zq)w\zGtfkܐ2}}7&wo[E;;*]D[s\v>+}N$Dנ8MB$)[% +E x]r8x%(zDD + 1r+Wh2A"2U$ʴrMFC&1@H f qѠD4R}_hIM #0-Rņ .V BBBBTHFvH*A.\36_9mQ0? $QHkH#P0XtҼPPPJ=ޑ\dޣ{N̆al Ԃ-/  R5Ѫ]IWuRְtG:Wvf;lGΞ?` q--oR#Nzҟ2liP ;v;R̟LA (B]2Qw}K>(I5)uxuFhcq,\TZ0#psZ^'d \N槂Y̎bթ|~&)-:˷S=Hev(Mg +!J`j f?'EO cuaQ5]ӛޖuꌸP'-lLJ4]jKށ/MHř/pqۭzֻA5 (q_1<2h] O + e n/ܥQNweyѨ#7hPCM(څCt! +~G@l9>LVe YFub+|w&,I<uu|م!;Om͛Wufc.cKaHkLʼPRH҆Kޗ)Z6KAs+KC(fMyJ|Ȗ>H~@0}47%*ScAA38VT@/k>2 @!UdsE,-ϳ P[|09 +a)ʓ&M-d[ōE,nE_o(&NYMk-.݇ ]:ٶg5`Xc֔uܿNIPmc0[%l3{CהNt:SQ}Q'#'ߌCr´ ю6@EcڲTLjz|d6)|= 5H^шk\d[f{4=l=l+`P&z!W؜7` ӢAh~^.ʤ:ή#X}9.ώUAJSvӃn=~ω};?r?.$s $ | d@Z5~ 1VJI6ְ-]U5 6YH/ĤHa:=kV{=K#8p5X(`]3ŷ]m|wZ ɔVA-a3L&r»]$_?嶋$L5E-] A|Ov*#:]EE Y@Sdsf_ +<7۶pf3 A?|(Ѐ&ol.0ana2A!sCin͂EnUy8kf溵mwT^\+NjuIY쑪E#CgHgI𙮈b`3|`i'Qзb +{bk.2F,vA" _j.j0w)i14duQ,K Ѥ8`RQqURyܒKr4VM(} 4^1lR$\TIghK_z}v@?`m M^@xr8F;& N^wX?eK:o + S\6+QQ5TLj"ycJZ4Bޞ4SIbڐń( ښmBi*ïItGvJ/=u瀮bԺ18m\? +]wyJ?@Jj5}U_:dqY@K`%PU!WS{AI:!l?{h=[,~c-MŗxEN/Ɂdʌyz/Ӣ8]-w#/~O7MKavҨgg`p~/Wd" q_$er2{׸E(J\ӏ{T@dArf:\uz) (u0>z|9D~ 7Oh x7ȱ73 "@B֐{A;--Ltȩ%mžc{o n@Vu/Uqs@ !> +/1LcB + D<*DKi3(mE `eԶ!3F`ʄ +<t(mB[ -J[ǀo={$PO39w{Z +|'4wRP?;>w#^ZA hbLȎ4%5!YDZo`&el5Zڃe8ԧ&Ya&%li`p6\|iUJjX#Q6xܕk&X"S(vsDEQ?s*8a5J1ֻъsZz!(lsmIKcHF;UUE*IcgH^ves i>1.9laǖDsO15I9me||'7ts0EysXfOb]yFm[ߗX4ӀxߟE9ʍ^I9}[֗!w-jxE +GD.0bnslSƐ@rJ'JqV/ٻ(d;94~2yE++K)Ҧ\OT|A|``/\s_6 WRq6P!֏*龄"riWxE%ݎ4mr/+8bdcꢎKt5chg^CD|H_Mr@"șF[?"ո5=?P=Yyu5t:WԓuD?GJJ>QO&٫hXkFՈ}2X#o {/Lu sأ`ϐצ-Y}jXgU#/R!+%"w FSF@ s)SНNW>]Vr|Q]+8%`4!:AV[9'@ׇBp9|ݕ4+=RFD.'|@m{:Oa:r: 6ݱNl΄i<wW/]ކX #A`_ y_EnǜK|_lӑ϶P>Ð_62xg63>՜O|_ײ +QSCԖ +q7 q#|?ru+ jbW#^!'Z0Gl7~qcaocpNa H}5YX-9]6vڏy^: հ\#CyۥT%rh9fqXlUr!y8_SL@߳b>?[C{`?dfJuQM?g`7.0VJFXyaP2ƯO z ~T'ztկ+= +GWfA}U +>gA}Uz?wizu߶.Bˇ~+.?(So^u +-&]&1\{[[篩]wʷzzmֿ2}vrA[ +힛%Vg?6vϾΞ~Ww)TKwz8`â~p1܍ro#xT =RKD{\n>Mw3V%.+rV"Tl#~mA\;NYn+{S8/*Q~bc(? i݀B{X1}Hq]40LEM̃~}r;BEW[JU(C+DFaU*){J}/4M }|?@OhThCRK41g_N\|xY9îdr_LO%SʜR#Ώ~H1TOjijBgX+GgL3M[Gy1~yޝ= +{]m L5\S5s >8n+Xw:$*{Q4"yl|s,x:PtpDGsOs c_(9IxKZ!~}^z sUso#F½m׼٤TMo\Zע{vi|Avc$1#W95>g9po=ӑ~Jj Pu;kA @Q> Z6T8}]ƹML3 +pn-򠋜XS. +rY"ip.΀"x@Ov;@5H3"-N+ŰM9 lmz# +]n6yc` bJ=wHxY iqQ{w;zq~LP*u2s`߭i,z'@ ڻբg[)2g AGVvgs?8|G_n G ^Pg޿>e\ +ˉ~{mNQ`L`#Ig{?#A=5gܯ3zr3U߹D=}͐^KbqE]xqL꽻J[pޟg%^E`Z jKbPu#Vr욏8ͯkrJ,1=y֭>5Ǡ%Al{k|5n`짇p?;b'qcn&i"oĢ]Ӆwt<϶`ė :F=2ς:VL*7: eZA {$A= R ԃz-Κ:ރ]i%&9uخ4aޙLgGNpc ߬koĚ}pc+vcĔ;kS γ12s tsw*, <}o8g8g [i y;xy5ejp+G'ʿÍM݅^&zM]"7}kSMgPisשxOЀ(ni'g"xG)X( )O4\f+qzU ? `0 `0 `0 `0 `0 `0 1Q,Myt-"܏C~ߝ˾EEbߦZAFxTHjߧV\1:bUh?N5hI Zg~^#^-hߦU;4ʻCnGCE1Z=8zOPK9flʎg(/O|_!d-?PjPjFʨ9TC9TC9TC"&cXH~w/czϏ+R7,~A$ԽN~Rf"e# )?K +_% +#}eGwyJh8fLijVI%wHjJ62-wK6CK\~݅Nz].I_},A ~Kh0Z_BwiB2$Ҿji45y292d4K˭J^ RK7E'6P"EPtN@&FDQ]l@@*E6 HFwne6wNki^ѵ #Gm#2 *2QcJ &|{kY@ڰ8rTѶ*Yg67}_M!@$’&Ri3YOL$Yƣo 1SSALc[Q'E)]2i땐̞G4JxLbobYz: k SEy]A.$c9…gWAh,UZ^Q:=RϞd{Oy.API+ֈ7Ĕ^iIڅ]~j0Ayŝhܣ9Vƍ2mum]z1 MX=~im/ώe8vf[=P=4[" +^\}Z-tužwF_Սv^]3Nuĭ{rQǷ#V/?䫧P4,W%vQsxZ ;ѡV,'l[ h]q<'FX}nC^ĎV͚sVnJmyf* ŭ:~CfɨS*"湑Dv%lۉs5]+c9@KP+Gª,()8u-;73:+Z]jJF=q$ X"WkAGvnhԈqC%jҡd +v1n%|+bN;"m\sC9F9aکߛ^$+ʑM8eM:[2e^ ?Sޫ1<%'wIyT +R/Im%sj}ͲE6H>C8K>KݲG;b|)_|+i ?O"o(8[9(-9A9sqʣ*|TBeT q.F5\P5q).C-\ڨhHC#4F4E34G \+qZZj5hvh ס3 ]聛胛00Cp BDPd0 Grn8|$|܆܎#q'(܍{0c0p/x! c'v >|53~ 888pq +A2< ɳXey6XX+ +/`U^("^jikR^ZYue>!؈لMٌقWJ^Ŗlּmx ۲۳eGvuyod+;{&d/f7fe? 3f68t8Ù\F2[1N 1sHɻ8w8x?|| > I2Oi:S s|83grgE\y\E\̗K +_ +*:[\ M|]7s CnG۹S~ϹwsrW[~OW~Aa_<ʿy?փЗFc۶ضm6vƶmƼ5_!B #P0pH(hX8x I ɑ) +i Y ّ9 yQQQEQ Q%Q +7ʠ,ʡ<*"*2*:j&j6.>!1)9ZFKBkA[C{t@GtBgtAWtCw@OBoA_C @ ` P pHhXxLDLdLTLt`ga6`.a>`!a1`)a9V`%Va5`-a}6b6c b;+{ppGpp'ppgppppWpp7ppwppO/o_? IC140,1<#0"#120*1:c0&c160.1~H0!110)19S0%S150-1=30cZ23 23s2s3?&? 0(xnJK ˲˳++ +kk [[ ۲۳;; {{srsrsGrGs rs'r's +rsgl\|.B.b.R.rJjZznFnfnVnv]={yyyGyy'yygyyyyWyy7yywyO/o_?GA +( +(B+*+"*"+*+b*b+*/%PB%Rb%QR%SrPJRjQZSzePFeRfeQVeSvPNRnQ^S~PARaQQSqPIRi2*r* +J*jZ:zjFj&jfjjVj6jvjN.n^>~A!aQ1q I)i4K5Gs5O@ HDKL˵B+JFkNAIE[M۵Cjvi?>!1 )9]%]]5] -==#==3= +;}'}}7}/9Ce;P0pH(hX8xᅵ ȉIɝ)ʩiəYٝ9˹y]]ȅ]E]]%]ʥ˸˹++kk븮빾[[۸۹;;{{xyxyGxGyxy'x'yxygx,</"//2/ +*:o&oo6o|Ї|G||'|ҧ|g|||ї|W||7|ӷ|w||ЏO/үoџ_?ӿAP@ 6`w۶m۶m۶m۶m۶m+`aQ1q Iɐ)iYِ9yPPEPP%PPePPPPUPP5PPuPP M-m]=}00C00#00c0000S00300s00 K˰+k[۰;{ppGpp'ppgppppWpp7ppwppO/o_?A! )fe8gFd$FfFe4Fg d,fegd!fe1g d)fe9gVd%VfVe5Vg d-fe=g6d#6f6e36g d+fe;gvd'vfve7vgd/fe? 0(8N$NN4N ,<."..2. +*:n&nn6n.>!1 )9^%^^5^ -=>#>>3> +;~'~~7~/?QPSpPHDIV@FaNAIEQMC1KGqO@ HDILɕB)JFiNAIEYMٕC9KGyOU@UHUDEULUB%UJUFeUNUAUIUEUUMUC5UKUGuUO@ HDMLB-JFmNAIE]MC=KG}O5@5H5DC5L5B#5J5Fc5N5A5I5ES5M5C35K5Gs5O@ HDKL˵B+JFkNAIE[M۵C;KG{Ou@uHuDGuLuB'uJuFguNuAuIuEWuMuC7uKuGwuO@HDOLB/JFoNAIE_MC?KGA!ҡ ӲphqXsxGpDGrdGqTGstpLrlq\s|'pB'rb'qR'srpJrjqZszgpFgrfgqVgsvpNrnq^s~pAraqQsqpIriqYsyWpEWreWqUWsupMrmq]s}7pC7rc7qS7sspKrkq[s{wpGwrgwqWwswpOroq_s@`PpHhXxODOdOTOtLl\|/B/b/R/rJjZzoFofoVovNn^~AaQqIiYy_E_e_U_uMm]}?C?c?S?sKk[{GgWwOo_     + op- @ %)Tll0=cZ g,> dCz{{]gy7PA_l~ ` 6&ac6#1 +6c0aˆ #vN)H&4c300s03c K˰+cvvd脍<(`(C]j{b/}/8 Cp(8G(cp,8'$Sp*N8g,sp."\Kp).W*\kp-7&܌[p+nw.܍{p/x!_+|o-?'_+~/g/ְboֱ )þ܀؟r#@nM89C)70n-%GrGs+nm-p,8a1g &99sȝ8Sb9Ml4Ng gp&gq6p.qg.d+waq1p)qW. +FL3C2G+Iy:tY*Y2\ݹ^ܛp_yAS|Y>_K|U[|]?GS~W[~OW_z%$NB#}e'eCH@X6A2XPT6a2\F沅l)#edkF12VqD%&%. I(d{AvdL4HL&ii2]Zd̔Y2[\';|Y Uv6Y$e,e,c H4Qe4m*݊hF µjƪD"O5d0^4̠QE(f] i:L:G8ԤLդLYFA[aqZsgGarzÚ|TTb + d +"Ռ @krreTI<ȓll L3y#0gzFͼ0BdL3Bfd~5Q),);XJE3nיӶ%YŢm^j UlS3nv鰌Y\6 fڳ\檲eئ69\2ſgZiv\-WlEaͨfbDGkNߣz>cڏix\3z)͵:S54Z?Z?Z?Z?Z?Z?~vӝ!n* (P,zJ9#cc(Ye]eqW+d+ZF\P,j?(ULftE^s/#m?Tvf!P*iș/d/c1ܫeF/k%[șTF3/U+1ǛǞǖ\LGJth즜HNi6:S1ؤڛڛj` $Ț֨nшn+X[gNo79x1V]jQUYN-E}cIvf؆zRw,#㚉&'[c}o.եU=(%I,QJFV6U6ڪ6ZVm:{^V[Fzm=w׬~͖S]m~\kRMY%lή3*6-#7;n6UT[2f*uU*dUSٕjKǚj {ܶ0 $6iw,LrHJ'Kp +qF`כ'Yggp<Ra}?M=Yմ|_N^-5^O-nW5ݞ~<@Lt=޿9~syr8-WVn,Lnv/EOOg‹nzW]΋‰bF\}vz߼}g|x0ſol?~pe}\.rW/ΓUboqwt0iSxqoޯWG{??;Mqz4F4mݠڣ>)\up\Lqp\up\WP>Gp +Gx{{{~~ϡ+~+~ |//_ |/#7p#\FnF^ײvy]MuG*hDum-.=n[}Rg^yUWa^y ++̯0?Hߑ#}GOfx3~o-~tvht@E.>4F4 +? pO_oR B./ȚRuAtĹ8OfL '{ H=O>%| +фfA[t2T^~uR:DyɌF*%AAm,p)5kԠ%h5ڼ[y;N5Yg- +v݇r]5pBMir-Y%iW1 {LhG[>_<_S r AMXנ޸P;9Ρv$7Ҥ/Oݥ6]޽~Yv(x8uRMsu>3qkN/5T/~n\fhk\;9ιvnjҦ.mKvnjjѦZmEGX8Ka8l0~@2ؤ$MDou$=}c{4Gc{`\cc{lldg;[r쭛)my!YlyŖs@z{@z{@sѬ?WM:&y +} +OAf +q +q +#-[.''D[myS>S>Sg*d[mym>m>m-D`_000P!q|+Ó|Io+·ۊmEbYSЭk4FIQQ[HAAAAAAAA Q(C!e2D QFTFTFTFTFTFTFTFTFTFTFRFRFRFRFRFRFRFRFRFRFVFVFVFVFVFVFVFVFVFVFF2e4h(QFF2Zeh*UFV2pFN#QH4%FFppppppppppP;S;S;S;Żakvkvk7ϻWo;So;}>]=|9%\ zآX<$K%/C6u_}QwctuwuwuOl&uO}esUUWu/lu/^Խy+<6;Vzn ō:S#R uMGu A;.=[7lz]zѳҳ-.trtrۥ.8v9Fk6mͦٴ5ٴ5flylښM[qM[ik6m5]uvkvmخ ۙNډ];k'v:k'vĮĮصvbvbNډ=={Vwʩ_ʩC B rZN]˩k9uʩk9u-)ԵSSrZNrZN]˩k9 +gh -3C'!:5Z_CkP_Ckh} A} 55PbJ Ca@ {U| T2SePI1-ơ8Ueu1bЯIM5^K^^\\Օ Y7Yt˘ғ#M7;N=QQMsj{Nmϩ927p{x;M5U8|poGet[ȕn趼MVv&aX;;be|܃.8t?1~pCcsC;9Τ55uxD派+oշ׿秧翟ػ.ӗo}_~{^KU}e{0cx![6#G=J(ѣF5|jHK ˏ&_jΚXWZX+kcunVZ ^k5x ^N[.u:x^u:x5 xo7 xMu?O' ?O qَ><=~3*F¨\ raT.ʅQ0*F¨\N>e'8?????????n&֕5z묃un;R~ϏOOϿ,dB& ,dbdbd`d`d`d`d`q 6 Tyyyy8y8'||N+仒J+yJ^+y䵒W7fp3 n7sN ~? ~_/ ~_/,b0,b0,b0,b|`k4Lc04Lc04Lc04<c0<c0<c0 `y 1`y 1`y 1Ɖy 1`y 1`a 1&8 ǿo01o0PC e0PC e0PC e0P_v v v;_]]~[y^]շ5Įwk5>k!v [;C{v v V%VB═ g-n!v ۝5y&%i```K9%5[ߍX`ޯ!Ր>k!v [ϼk.>c+߱sKk5[Bry v V;"==oo!r;cp_]]}n!Vc```kl}l5Į!v_Y|*TSɧO%J<*yTQ9 +nɳ~N^sɯ_'AAAA8o$I~s$$$$$I|'N's?7;'hΕ        N`YrY$lYV10t 3nm7J֟Nq:ʹЅҍ6gA_v܎qj'ԎqjgԎq;nǵsSjvPTjU;AvP=pkމ7}~y>|o>_y}_֙ЕVFwAOzѠ/3?3?3?3?_ ~/_ ~// / / / ++++W_+~ůW_+~ůoooo7~o 7~o ۭ[onzvۭ=O|U^4'|BK_[wAOzѠțM3-t+t}Qo0PC! 0PC! AOzѠ/z! 0PC! 0oQG!pQGo!,RK!,RK!,RK!,RK!,RK!,RK!,RK!,RK!,RK!,oSO!<SOo!L0TS!L0TSBU8po!d[[!lV[!lV[!lwؚ{_u.Es7ov{?L[KxߛLuro?/l0BJ7N\yywKu\Q} +\u? +V5Y5޺RkҺ&]e&-vnp/Zgl~ ` ,tVܪn,̪kB[T(7իҍz<6{ձcSǦM7ZݗV?#:F7c*'Ue|1Z]13^}Li}ը*lVGT?OOm̔1Z~3}T?VՏ1~gǩ6gxf4F=:Fuo&xamp,6jXF˨lXaUX}կUF먾>Տ9wpO1ק1|jߟƫaoaovӰ4a7 iMnvӰXvo ;S;;;;~w;~w''''_%JT.rtu]8͟g"!e/O,}:F1e42[ec2Z[c422Mc4Qe1cQ}c$e$w双lJ_~x /+tJuTJuTJuTJugZ֤rzAOzQIs4WP5:qqq)UFwAOzYYY͏2(ִִ0}V6 s #1\@p + _ +M#4UAIeZe%Kd +* .IflAӴS-1mheԍ=BZ)&<8=\;z.z.z.z.h|'^kmk)zZy:H]Ճzhˮ],eϑ})#=LFٟ]Fo_/ڗY^{];={>P:].qy]5.:9ͺq'$Fx +~&<Ƌ,Xn乑 ^6跢$"fDsEoKb4RaTd-(`h-xj++ e|It1WD<_IJ:VIG* +Gz(///%}Ɋ中OUZV_kE-}ZUWT۸}ۆ[fZnj%[ZZXn]ʬ H- jsGv(3$x 0@l +N;MZ$VLGeLD\L§H3^I``X{ +)H^V+L9xe C:p: I"8+96ցv@wJb~]]IA!$o(k -ɯH>#9,\mV7?kVݬn@ K.]JDm=BJlL"q~=TTTT}T=V~Tۈ*]͒7.ZՈJ/ST' K$ ^qG$:D5C<)t E 1C!6C!2C 1?iY~Gѿ&?D&KC >f_)sI7J5kM7^2_GՋ/l{| >fh H"r{O;i*~ +L~1+* +iB6]ޠi帩ɋ,&\b#䦋Oj.uͫLNa=uqm^ɜ保2-hti'7i^h\^3C|Zq QV~I`9+ޏp¿&._"PL۵mpקiSjזVj57ir+_{G:-z)ظn]0b\zlS)}/$>G_P?}!XM#eJ?HHHK2FhJ4ȩ)r'rކ!njN- t/x8-^myFhWq[w!Ң'}G]zWL&RC:Zq! ECqV\Ԛ'dokuDM)΢DC<;J _/0uW.NG@R6qAE:u:tqk ҥK7W77'/{%W~[k2ItP B؝ڄ 7/C-&¿6X7lZ8=:ƩJU6/„rإfeW5T#5Q%kb! +/b(Fb"V(p?6H| +ǢDa¢QXM@<]q2{~ -)y"RDGu{yN7InU໰ՠ7g3>7(9gy&i CJK%.8MR2 ++{Ƶe +, e^MYBU +endstream endobj 16 0 obj [/Lab<>] endobj 13 0 obj <>stream +Adobed + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + 4  +  + o!1AQ"aq2 #BR3$bC4% +rS&cD5Ts6'E7F򃓣dU()8GHVe*9:IJWXYZftugvwhijxyzi!1AQa"q2#BR 3br$’Csc%4S5&DTdEU' +()*6789:FGHIJVWXYZefghijtuvwxyz ? +[|x8k]>=]+&bjd.EKLZgDV:hk[O54ąMJ#XN :꣭93Fd zi+ot^ڞ 1;p|4+_eyuͧ~PQ)۩BN&oOXu~=` ەqjz|Ljⴵ4iUKUHtYeE*,@ o X~g,Z_2$l [yVD%*$#`N=m\W1;ԇ\O4ϖ tiH!`TBѕZ(N mAYfX%C$GA~4^}(=emX4bS:H*4%d 5<&0!XSa:vfl2^[<2Dw9{υL m.%N]uA/̶-! :ZYy|&28Gݼ8@q}DRF#LbHم6gfӚ*%KQQY,0ÆVēy"ުѬN>绿q)GKA>آ̓3?1m*Q7UT8گ5Ndp*`I$\""b.u6`$>з.ɬٲ1&g$BS@U/ժL?lf</lQ8~$Aet#.-n|)+V ;`j:ͯRJO z8Uꮮt 9eCSL. ıZrKVUCf4} Rwבe0Zcn>Jw#{/[+G$|h*P9 <^)[XUpJIٛd|{jT\Fً(kj1US +.\ۿ*t x׿D1yV"r IU*aq#)LrSCKvJQQṉt#`0g<@wc}b4<)֥&4s6|k^%rvy 1!eCQTJ䝂+(ZJ(g + эa~l^#V4 OWH,`-}FӯW;7DBD46^5(amlR9G'd*Lqz<@MDsv+[jm  [1yiE*♨UITlc+Hc'sʲ_$bz`>pi~vWn~\][^:$N8:_SϹ'4~̱h3x4UM6#_/>[J> wy/63L':q+TJAُM]9νb\/*XĞeuu%ED0ң3eMArmŹpLJxPTjm*Y +]_q\3FRyږi28M; yD'a%W[M֢JJiywh뀥fѷ^nƺծ䌃T:l\v2(֦ eX'XAjXeDkʭ, 'iUsPG#˲̏(jmQ +v''nȣ1(&d"ysbN($x%MѺ IA#wnOrQQ!# 0æ;?)bxUM'J~3u":Y"F2c`; ٭IwVuJ7]KJTx~:5ʲi*T} V8`v Lt'׬ޜ2mc-&6Pr,S27<v;Y3AԒvqEɹۜH:H!RvSk+jo9zX1ϑ T1`AfDESxw̉هxCLшE%{VG +4["pVE8e#+X8:{StZɮ1THT9Hoؼ\q"CNM‚Go[kUө$.p,+ * wU71zz+$8V)ZOSLG!˥$` 1eHXY) +&J{hR6Dl/bUpQς"GYRI6ܬTr w$D \whP'I~4ՙz]re~XZZU5=3 ).5..ԍ5/x1l/4}ԦO>2Q3|s0AN2ՓRYVʷk ms}m,pcfy}WniI wޑG vPue:/PqH-Cjkm U9b4K,g143=3D6fkv*"0Aj5׊W7OQe_fm%CQ/GVn7ҿ}mK3oTK]ukw?W~_YH¥A"|I8ۀʸ%1:|qIR +x)iY*Gfff  8$NQlF\OAOkIZ7IN8dF5XibmW&nD +~z:A w+Ɯf`(Di;Oj:̭A+T3AWM2EiQRVB,^r q ̏`(+s;tA`u~01j1 ߏ=IJx/NwM\f>+zxѩrp0N=XD< 'F) +*ޮ9qb$Ik̨,*ǿ{<7xك'g}ܼט mE V0<:%?EqCi㙣4U!(顊yHő}cmxgZgg.YIN>%`Jaґ8h5۹l$&x + +v?\RB +0$P + /e 1C:2x?'P*PYB*BauV8# &>f&Z3(2!1h6<JL,Y$؆K1(M42Hn(I `g[t)1c5!d]Xܵ8Ӏ*x +g3KsvS=qYzd>O,eZ7TAoMĨ-S@8ۅȜ9p%v(@'È8O$8fq +\i%˝FKTU5 Ok%\fX7*F"/0~,!,B[4OF.8'Luq2OM"sNf̙B\?\=E%}9ŧz9U5 iI!H ;M$HLO%F$k'f!K:`~tz[\*V4®ҭĪV( K`dK[ I$D[ezd ҏAe6s6 V^|9cT4rɸ LYMeSp h f;qf^WJma[@Ң JAׯB4Yɰ羣HgԓQ>+ [-Ĕn !GU=I"+v22oQWuF*HG]mkdztƺԬOӎ{^A˵4Tئī~DS֒t (DH|`UefSI}ˎŘHƅ9>Qfv) 'HՆ=a'Ax&I Q&&Z:LX9'r=%'w:Ϳ5knԒ +:q !Nm)jQusåƟ65)CeFik >XAƼTwQéhXMcn6i.,VK<#s}wwe#|ɏ3#LlûqZɞyvHORaK0cvom9W@ tS|Jm!RjE-;AZ1&݅4/O?Q:/1lE.%D|ߤoqvfOL8}f7[<[!HG]Q9Ώ#˓8tn#l:Jj٤ m,ָ9ihu i) 8"n;TF[%+@L) q=QFv@º鳦aL )\@UK*!xRJTD =Hp+' Ēvuпy3[q$=(vѐ:׏Ѭ3Ͻ;ég̊Z: +â3,bM*Gl ?] |'h Dž{Iެ4aҦJA$+:6*9UcG]OjZ:gjů+[B82nJ (JI ن'ʫv gJRL@JA 12v=p=F}4UGOrt.!) +㦘J%R+w1UǘŇ +, DDmKbn0mE;LٲG0UJdj'=s2m/ۋ6v J:=x +BĀ #F]?Zr}u^v!xkWDYI( ҂7n nQzTE{a`jUc"6êƽYuC]IϸMFl2\3>)SM>S;RH`Θ6Xƻ+-3ox6 6#iƗnNkKݶ%85< I $IGͣ0 N(5u3,$e* mŋ,X2J' %XfR$=2 I?]3v9t`ٹ1H!zs+pI"G,؀m=4qQp'bǿve,(@ 0?uP安PQSӠ^FiTQHIiKFMʋ.܌&q8@^Ŏd-s +GlE#$g=ejy0jlSަ4-%x/܋v +`v "v4-έ_-9 'G(z~sv@/ǣ]ؓQ.\7c|-0Ίho@?o)UrtKO FQ2ׅideDjP|m}/n ̷5ۻ *&&{g7Ka >5?:uSٗ%ouX.',S2~`E}hc@"+[vܖҩQL(ݕme0A$uz8lY-Twx,X8}=E_D6( ϰܛ?е6Plj*G:q{nK I1L\Z<dMD {Pekli80uQ\RթBpҫ& +q.;aFH⢯F FW: ;/f-Tb#X'!*'iS(Su]L\2lB@L4#_9swG&6s,JpxV1隞 r`3_˵Kb؆+S UR7\B,`K _&lJ&$I$zǕ +?̍KmiI +j1JNy*zfMtux-T $TUM3؋{f6uwl5b$j[h}ڧjYkz6ZtT$ 1+auKzmWZRC%3ĨBñ#x[o,@@HHV=u)%w N!A#Q3>TNE\237V*,$9Z#R6-oq{,nevT'T8${'ϳ7TDGmVc!ꃭ5WEzyY-Fs3*G|C:#Y)X̗BH'ݕ\m\Z$p O:]rjnV( Ɣ$pxhӜ>`ɔ r7Vri=%6"F +kk!L'mK/O1B6Sy{uq\T[CJ)2&e#@KZ6$ iP ϖ6тXwo+t4b&cq5%.7qZ&5ByFӱXS>n&b,j)!:$&Oϭo߼LL$c|@ a;8mνx6_=FY1cPb1>]ZJ_!Z`f`>fH]us9Ki*A3(˶nєnH)8:ADQPF +O@+/ (#"F}Os{mB[R a{{Km'p8lvULHQ|WU}MH#*@ʆa! WUVu%(JI2coI=g2KwlM  F1H,Y8b֮6y(2;"-`l<84.j1Ru[wiX@A<鶣 +2S]رu{;˖f7o!Z[mn/J#oۢ]W]0hO*jJRY]VF;$mrxu7{0S3rA)$d]RZ' t"gR3t3*VKjcYckHyI$~_%hJ$Τml,V3>eBcqSU`.,j@AW],IO jPN4˵GEd*>ɍT6&PS$ ›Zq +35 _M0J4]IIԽ2P:lO)Hаf,t])J2nV 쑴Rw̔ZJ|$1`H}]9Pԭ[VH^K{U5_p_2*D4Vw#P /(Yp,m.nN59U2O&<Ӵ vd;bRoN[ILkyN\ێ6c':mK Z5 CH!/;II#5@}F݅%6c3..֤RO8a񮳖)Vb5tU3ewJp4:sYSnҖ#J[[;5\)q:H<5tʧ5x8_YyneyZHXPbmhG;iTV$ƒ۹]miI:FlcC;I}|ijKIY5lrcj 6 #.ңHXhl8My L>F@'oDݫ,! P) 'Ϋ51,.Hi ԅAqѐ*M5׮#-*{*><|I)w3$06oo9)N5K%`ǺK2)S@dS֊Can9s( +iFIel%<llxirۗ+Pq,V K-4P΋k8n;Ȧ\;-晲ɴE#5Z +N4uc¤Pnq +i$i\6W'. $LF4$e7\Q)q*Iݰ :8[7{zE#4Y$R6oƊb)~Y)+)q*YVjL [P*Js6k)V\Bg^2-Fэ4ff).D}c%kSxyK>}[Ν겇QR +w!봉m$0 n F +>v  lo^Y.҇G>`SxP0 /)q +Dى}.r6[dJf(Tm uF5'3t_E%ȕQTU/兙 +* ~E>0&pfLs >Pۆ +)-XiN2H=3{1<_*0C`P(3JiV0=d39)[E6)[W%ChZP P7wws\$@f~Cf6,SiV8vTN'J:/>W=6LZLA$t(<9M8[1Jc4oŶ]hp2>hI}YsUq'$LZz<ƊR'F/as8j (Cn-n'N: Kg(*zz:.\b0n#I<2hUܽ$pysF0<_&^ӭ̕˂ +GZ75 Q`񝸄/,k~#u#@nwˁ5fRW)i)Y$ǡ,CՌ74E}-j8YBH,FX{*Lҕ%@c8{sHˮJTJQy&>&QgLUTTKRE/*xÖ,@\z+JY&xQ-iĶ +RFMuMP&hU見kvܕ/ZJA҄v9i}Aү +k?,>Z ۸EA_)e/: +QO+ה>i 2=u~1[uG6=>|IF$.o{i)QY$ad +i +¨KXmAst׉P8vO: cΕjsF'bTٔbD%bEP wW☛${K\|.L#™ -S#I K.t:us+|ɕ4$M5sJSDEu8webN.p'EWV< ȓA<'u|ngܡ)j2=RGVulbSb,kkpCZMX^ޠbnMWcSjIq),Iq*T]wOkpWB4*8i;z5߬ :o飦(. R +s"=Q3X|{GmP&e]]}}KM7h,XON8aEǣ|мn,:'iD,J9%jb`oog듨l4A[vU!ͦ*e>؎׿NJ\emmf'6صJ6x+YƓpn%XC{$x㔮_2g0)ԓ*R*0ZY7m_]a LOp+l mnFh1RI˔֭qRHL4N# [[R pՈm/ARo[z;E?Kǿ==jElUXMT.%{6,m 0 "AE:ch"ꊣߧ=֗#OBQq,ىaQqE$[Fe;#wv6:_N7B7U.iI]_ZJO>1.:ЎoXG j|u/Ѽ56WS%]3+1 :1crO}}niD- 2L06q<*'2M xqŒN 9sfuHُYX+q(Fn +$q + ̋0BM#L:6YnkݨDC=Ԍw/gQA1XN oy+*dffx_a`aon}$4~ 'dž>mU R 0ӢyӿO3Zl(=Q~3=V5QOK–Ñ` +ab #@+Ɇ%&'Scayk[3ejwZ; ,XB襬dEw@+ +oot^(ži&2>4됳fWV\jLWؽO^LdWуk\-Zed$ $' d|jʖZ3'B5s`1x,>޶8hi#,}Ϙv[wHRk >*#+XR&A \z/:gzZf +ʸ J@Wb2s,;\۲NtR +4xbo3%ᆓcXqbt4Q m%Yu[ JKb8ZV,P)+cNX{nn&)l#i4\*]Li0\2IEJB@C+M$%@ȁY\@XA?e!($B7_pvF,:ޘ3MSz8hJ(*wZ:v|>X. =25;BxlY>gHW826q•UêqS]Hhq\VJ +H¤hG;)j*K,5˗BRos+ 5ݦ ' &<ɎAUɀuIs-+ѽz- f$(ۯ|U /LOOGIowֲt8xzOABw?OK$f/5ur\&JZ֠IHPmQSw*ܪ[^v$kxQdP7)թ˕3ӷ32~)9"c=H2l؆#0u4O!dDPa[I k+R JN &6M{KmrÆͦ="( ^ ~t,cypY?ғ 6/$k +lyv$ֈւE>fOK}ϙB +쑘0,4cSQO ;Ɇ7H6A8b< +y޹Iդ'ϙK 8l6HK#k>=i46jQA]MՕ̒C:2׻n5J+ +F횖@nm|3[Kkkߍ=s%4~#e5`=ON ^TG]f;Y:wq*,BpDјRnƽA)J$R Uspn_rtq檼IY\gFd괯k*ܷWSG֟7ߣ3:5dw0t ؇6ɉM, .bOoo?!u}w!+PKͤlCNY/_2aUE0ç)N$l  9դi(@ښ]YSj;i"|y0`@X㽴acoMiГ7Lգڌœ㦭\'x/-{>JhH5'Aۖwx N=6x^H[=X\E]Ҭ)[@e| ,+Q%C7# VS;}EWã5gۛns+%!edb'N1ïԣuK,T8Y| + +SR`5UQ i#1277z?5iB48; 8H#2H. @qEF%b~:>: +]eH 9-ҭ]5_mr7%&5;| ,qY&exkwp<^mjeՂ8*L͍aH' + +zԌlcphk THU yI2 /w^t+kYRyJ8OE3宷asmfbWL:ȞbKF,jܑTįGP6 cݾNFzw3{(vU rK,O2[NU̕31,m@ =3.9m*A%Cd 7wvn/Fh<͓0lY3Zfc2-X$k卅×}GߢݑEcX{|[f.㴔Iֆ$#xP+mWiB% %> b Ikv7km’`E塀s*bUdTX*7GJa[.Чp8DfZ03EƱvF9!n#85IjD,fʺ\`=(8nnѧYl^c/RʇꋫyYr'öS Qbҫ]iMJԙ[@6m@},.<檂5R$ZB-kԅ50)ͱAP=X|;xp7g 1 ,tZCbpEGgO v&MuSzB:j*L`n[oۊ޾ Tv0p\>KlS Ky6%Gm{8zTR +fkv\L ro#b}9OtˮM8'aV֤oOSQ|bYZSAu x{DueDXa7 +4NsHn5a>Z;nĂUp<՟h9N|5D[wtkAB8*3apB27T(l"Az?Zh νAy )Ә+Uo Dwpw3JD=5>vIv;| f*re\?%2څHJyj8P|Ock|o(_Xmލ{1^?g|R1ܛkS3SPU=U49brt +4]l$AA禊ﲥ7lN z}CЏUsKVv8N[&',DH o~-EP@88LED5噷mm!$AV>I_Q^z /Q&?[ jN],[jxح݈@ Kڼ P'1+踷ۈ`N$qduC_RFuG#<=rح|nd]H>`$}l7f{TVIl3w6>I<aUޓY/Eή:qytx؀/ tbYH:$.2`p*8Ze-Id ن<(?ˑO>p:7(ZK*[x=dz(%̗ 'III8;h]W A3ȑ?󿧬ŏc`TB#dusp[i}a{{O +Aд ('xOCBGID)nRT4[Ȱ s:;\.68HRH o޲qĐTڈR8#υX|y[(aY^p!ty%OD̊ o +ï18ƃOiOiܘ_Xr4xW^&\;+Ldh0*XԐ{-:[WwJe!R&Ni +?QK%F`\;2MB؋OFAa_\Ⱦs\1U muj"xAg΄9?d׷x$M#0sM6y楑U*i#Y\3ݶ +A=kWuNMx-Q(p0neʳ4n a|hjxNWy +&¡}%!Wސ3l qy mCRljOA⃙نd ^aC0YiñJ-PCN7Řlg-U]<梭S`Fw.'%O+vV4Jy3sQxK!j꿗F\؊²Ii!  vyZw)gX3pd4([ns\a.uߢWP1nE%h)&,QebͶ;׷-v襒04OZkq;x;Pن +d7\2Ԭ?xc-1MS RmS_V[]fBݥ#8'lhzoIq ڝ=d!4C٣ _ A)j*WMڝ$F1P9GVLտs߹A* +=(XFyyeIP@<)STfS^?Q0zU̦8B U@X@P)N[ \1E{a564p'ș(t9xH#\U$^_ZYZ"@M 7lm8lc_>u"n朥S =U0a顒O$x͒pAr =*]$5`7])j'n>9ޓ}3^ Gu.LpUc5T0Q"RNv+ijH$'@KS&veY.XnA"''C>7,U( l)@FL P3F1^ao ULۼbfi{ k~ jy-@py…?j6kfu(pz” '!3u'eViA%VNTӕ;}:߁rLST'O/j ~+Q2x}i/}2uGl-27A6jV#9Yky}| ЮχBE ?Xd/Fgckp@<o6(%8\W 0 TUsEb..Q5*,đ'Mkm@$5:"yAv2d]R(RfZ7`xabnXJR"=ԭh:+:3):q&- +{Sy7N\!RI"w,u6[hK?~C|ۼwwhsH?<=TM}A݄PJX{upZrg'7S&Z!géRc m8bqN~X)]_L + /xmF!J p9[)LY;3u 9~>l4eP[Ca`/5z~ϵG%NQ*6$u5݌G$h #  ]edY2Y;A#:gQR?AYESM2a 1Q(鿱n1x$( I 8z]s>%u+*`Ztظs>}ʩ4Ӵ73j$v֖a)if\ bBqNʹjrϫ>UdW|mWDQ_ir,{Yfl:#q<m؞g%[ |>1V1Ëu8b4 +]}MŊ+R#O@æ~ [! $Id}Q}hJgG(ÖiGZ&j6;o+Jc+`ʧq='lۆ%p'd@0z# 2ZI(: +\<ÓsNӥ~CVYrXQCh %6=Გު + e*b USUs&MӞSTwosfoPbmuVs0 [RE `ߔf.(ujPƒOo|P~m6cN1h/[xٞ\{U`]%ypPCudq†.˖N)% +lN"ʔI +N7+og m3)xR斴GM5c x\QN96١E,c@~΀:V`dD[~N`&W.Kվ-KZJkFm x9m$YgIl 6<*s&6é b,N‚T5eIİ\?cX%&-' 2y Fi,:;)t?P:]$Sd|u "/Xj/7-\ˌeJ>M~|&^L3dyH6uX8Sv%;d6PmA`r%DvIuCj'!CdQ WxDzA-QRT,5uTyP1:}x,[ yPvF'6y*,[`|^R3O*1ao)]"AcJ|8gFspmBxlZ彪f V5'F>]D*`L)KyOa_`^w0A $pbwoNjmTz0".l6?!rU bqFd  ܓrG&ƷvᬿuT#mI5}Yt8Cʁ,fMwPKrYOLJYFTJ3eNԼGN}ʽ99635,AIFTYuЂ{EIϭ÷*XXjf^tUe +($(FUHt9a+l͊Rಾ +>P4+m`kqc[D4ƕ'0~f%6.cV&owq\sxw#{h͛#΂jg%:9U10Ms"i`H!͐ңh2%?J0^3\MzOC69SES2lif.̎(ɘLhm$o{Nognfyzb4Uux\` +JZv;FTў~4Msf``Fv +$eeLOu) ~ZSϐԛwm88CwM(5*R.f6Z{VÆi5F%UqK2偬icv6BKu0 -"͑`]W(zzpU3L?D4]$ʶ`\2gqhh U +ݙ 6l&PrWN:1#u=13vZ|YJrL_yݘl"Rw;*K{ +n0^<6CJ{es8+Ӭ?&!BU\ob)$lE$2)6q{ٞnB-X"@:Q_i/\1-H4oz#Q-%WJ:#%&[TD1fX^6R}$Hmq$*1dEyw[,.Pdq4aH]61fj~B^t~\IUNmWZ\>bclnE_ǏeyU(uI$c> Z=e䬷cW\tG;=# ;*9Θ-+遢(Mg.4>; ̓=+Gz>6U=)Jqz%=zWsJ2EO*zj"]d{.@ nnNǷ?3˝*`Efe\ktL 'D ]ºMj: CPs SSCWGQ(䧐ӽ=@0#pTkF8(=5;[QQlPA"im׫~g< =t(ipq%*D]DU1TH%&d2I)#k}o&zʺZd<6]kY3P, 2< ,&}$cJ?tuOx m]v͛( ЄA&825DhG3Nҫ)=/$ F& $$pnޝ1f+X9m-6c˹ :dr'MHx՗ڻ]ݩ*3u' $ni=dTR$p숛RG7G# {g)R"2ؼF*ٶWZVO×2G%J,>86$1Q# + +b [o&[flh>-6&ob9/wjhQxq'Np_}IzuV'P«iJ4ZbvZ tu-[O9-PR\)>%ZO&W؞d9ZKE!@[1V8{E>"7'Y~a+=BWR+2WAPTmA*W9ͲT5;8Hzjv&ݧpTIA:OѬKaúd/3a1yt )*h}ױ#K$D@'hc_^!Q@ p1W^/9c +yjQk#o.2O&G@@7Ur\$ 0)6agcu|)5 #`3׍9GӯOgN:_RaYf +Z&\3$faIzWSb|d )Uw >тN$uq<}[D :~[I%Ğ-~%ovg&ФL`D*EڱaAP10( ȵ2ᨭ ^J +k#Eͮyxh.6SF"ePzcyz\Q3Q_3Tj*@d-.WB-?9Úҝ)%*PGE;λ- J5) LA/ }Msww`b݇|HF"[({x.YeD@(w=2bvZ!8mJ~(:NXqHru5}0,"Fه?[VذJlOISP)v.7$ǡN0LS>LO>{_bbU-+Tl+&`q#=k,sjm3>#ޭmYtJ;ŒGNr.++MEd󎡝 :f$$7֦R? OXfz:)vAnH+؅hq`lkyi+8{ L_7\Ҍ;u53"R%iM$RWTbQ}WB@x*hxOA6SqS$tC#r/N2NKPiq|R:O$+Ec߿ PpTIQNf]_EJ)6H 灾ku*7*iץ:4Fv.j.'h# A j5rVQz"b?1#0V`t[Og[۴ sJ#@(49zbtg͓GTP;Fa۔ݦč٭-84Gn2d @읛DHFKm%oPy5 xJ􉔳G2YMJlO#3cE}o}nf FN$Ltz(a礞ڟ/Ǫ\Սhꊚz*bR.e;yvJej N>wjחRƦ@I8;{g|ќprNO +^8[ճ/QVkZX`8[5zJ/.~+S^2 cѢ3 fLovf 8GY$%FBjM}l#qu tD|*$~ѵ6Q +Bd8qᲆl} gZ(dUZ'5T%, 4!US, H@*~9epL%Cǀƃv{Õ4j+jI|"<Jx2>Exd0fZIRa;x$Yۨ|nAЗa32P3=˃ABRN"J}H2S豜F|? ո ^Cq#I(.=xM(rAɸD:zUdӿnEG(k=moɎ^˟W_ ߎ,jc(m:; tG_*EDE6U}l:'wșf5J` jd3(ooڴqڕu7Ʃ)aT#7K/mƲJ@[_Vs*",ؽCXv ڛ[]G r\`#u'>Z1iUVb~{qIuTLf 0RD3MOB ++D [s¤ ~}UQ&H8 +gbm2(9}3̐#Yc&}6,f,[kH;ݮ/pѧ[bmďPc:AU%s Ĉ{}I;Yl$qُʭr G΃r=)3Ur^ihisZP*)̯S@Y5PiM;kSr;2фSdf`tԢ0GZ8ǝV'*p֒Zi2씢U\7EMϭp_ƍbaNTI#D@. +5K2XHF1ƀvc$wd =~ʏӫtQ4+UOk7/\x{)ǬkwDKًJxҙ"S$ߞel;̘v-'c$23KZJHkؔ& +0|.1)9Ti+ tQI'+.O@W*<E=V""%*VnCy,-rvd靜#9sniV)IҮ6sTu & fM"%Gͥb}~1M\ =!VH.o[΄O=ʯԵZtxR"I2Jn/pͽP82#=TYgl?! Tȏ7zZ x@Zc=hrәP-L 2cc46K3pX`I"zTh8lhzͅ=@H:h!N)GUV!W JcwjE(b.ˋ&2ݪ +2>…jd181÷;k|rCjyU}T|FIfDB\[G!X:$€0DJ3[(?l@^"`0$ICtf/[My$ZFvIѣxIY PM#wE(lL{if\wyRd03=8N\՟9W]Sbm>K. +|.h!cjjH%.Mɿ;%Z6@$Ǖ5Yxu`:II8c$(`KԮoa1th.Fj{l2ܳ6&_0T?*{sSz2^s~W񼽙q VLj+,,]~7nUiᢐ +Q"z= zD}LK +,:}%m )?hjm{/{iԥ@W;jymk.6`pK=*T#0G2ѷ^܂n\LO% vR041 k&bA U"ark[N8m#BR+s7LմhfK;KK dLdNOCjHn;-cQ&/;EQAb&f3+meZ*ÃbK-߷YRaA1E)opJNb2T S<ԻXC۠Ņ;o mDufCYhel]Gu*l*ƚvkQ aB_L0S\3 +O3 au%MTiiXOuMIEf + + rnil FKmiNY#~^mSCQnNeܲ82_K@6DuW<*wP:3M7֡ O3!@_yvB~sۺP.6uPD];Tu7ӥ,INį![ݻǂ0~&^\@2>4ޫzg6GYw)`Td8zw5~hrBpܧQڜ/.4O4u) +- jG{Af%)m+ a4 ˷G0r + 0?JEu*5y?9:Ta'C @v:MD@I,6j5ٙgQef ${N{+ScRQ6ȴ0A gSY_e(ݾH!!@eZɃf2.&-wF{oAyYQ1*k𬙂7NzfA=oNp򐈋Vyr$X؍P66(s‰mrL; +'FȕM9?y'ÞR0GeR* raqu )O8FViq=tc/u9 Pa^p\>D|m$5%Vvd69=ne*HI$&jW]UN~䉜q>`T9MRL2?pDM6't[) +#7fJ\$Dp*Ot8R4u\4,nP f$iȏnЬK;3bQ:HوG葉n6&ܩI$A}ULƱhSRMbPs4]$pV$bIɃ"ܿ4pF& =-}nn[|-Rx =b8>d-%xfiij +"i7\7oԑA׋\ϪIvPx70G\3=v-b2 +1J^ +3]3AI Y5AI;2 ??dyV,ӃSu%c8X1jzÎ[\uj'pq~2'lQMz̹{(v dZVYy&HªsP pWdMd# OžqּJ|7çΊ_ȨWbRkOm Ht2(ڋv"Yz6KI;AeY݄KHp1ej#\GSI_KO;7,Yl no-nRd8$yVH3Y%/B W/f6Wb@#@7߼H%' AjE=--^`**`I(Jy(UHV.s[##i>@L=๴mj HQz}+aO5f%TP_QP4mj\,=5Pzi`:fx'ƣ.}E8F*A%n,s 9{&|6s9C} )).4aS0 .}i 3ѳzQK4481_I , jlHGCL[-O,I8vs,?QV2XeK}P i&gRW(R CGGj,I勒nO' kUn/ę1pJx +w<[=ԵZ{z*3LmpM Y#ՖF:qCV4Xv9]VLP>dmeca`,9 ^f +@<Po]j{rJ@S?^zsYrNURܬL +.y)8U`ʘ+R4BݕVR-n'NJĴR">Ǖ:$}QLަR_SD]GRZ~ĮMwVĒ(Dt]ܭ-`SrBt;:;O^DW"aއX4#u3458k2U4b[Vݬ%&Q€pFb5+̓{ d/'V%v$&5;x_~6^>2I3T~ |*: uPAos8ܛn)(J`:0^,uO$ 8u/:'(źc[UaUQ2S'2Uy_knCnY9tҜ$niFO'6F\&1 +Y!PvCww] {"okvyyjuia0c 7V [AzГQ%zvYqlt<"S&P]l}o{ZWԢJN 二rHZ:cMV{kFD{%30:Yf6I;iC +[~3 +$iΊܐA +.X^;cuw1bφct h GdH)>t΢RZ=H+0w>\`ELJn^!cemO֚&UkVfQ粰?_:N4C'f^9F Չ؜<  xNfu*H*"I&n:UbtX6Ml33b&q*Til$FםֶS& e ic7pHjY\ilc͔-OD󏗞0Pȃp7&Ǥywu)a$AhOzm5RYޮ[t&HωnP5d-b,rt{2in JTV$+L؟ҥ6Y. ++6A=L]V_ ZL+_vZ%RHJgsIu!)J8m'pF o[vͦB@u fF8;!x(_2:zwd[ܵfkbxV;4-=6ob 2䕯BÇ} ^`9Pq\6o%R(XhS4Wt`~Np5FZZI D 1=oNUdy(Pq pROXCL/1JIg9'Y;#p}tnsCbKRH# I'm [͑~In!Ԭ` &6Eޛ:y]3Vr0 8-bTAD,fy`O*<.69m QóP-7I+Ksrphduu"8"5;5R0RcK+f9fDC8 8p6}kfRd*U zH_\.bwubU3E +!qJ3h"ah7odR c5\3(Ɣu6#Y¯<]eNbby[e"E'ggiLa,nX[^&V@ӻLJUc9uY[j23h Ui瑁EΗ$=0ȷQI#]Ɖ͙79a ٖ?ǗB5)R{T P}j2T; >*sc~҂zjt" LSFΈ$7T\更:p4rAZ|ﳻwG^FTYrD3~Ntti4nkw6 g +mY4іq1YE4_5UTC!Oxە,ۈa4RY%mC l ;ik,}qtxm H]#ٯfK N"Y sr&EM4TQ=q ZqM'uxg&c 4Fja+iTI1+:iҧ1Ը%Lr=@05K_*LS-QPdǢpvl{jQ}&,=|^ O*XRZ|Z**| 2O#[)"|8Ets)jyS3|ԬGW͆hu"3j-Nje/H,`Ŷy6ge0~UܿconԷJ@;1Oh"m1RǖF_Ds%%4o +.'if4u+'{#dT]%`SSa#Si{됃 cg5@r5LuV%%*QWSC{ +@u^Evg+PuH N;cw݇\\&A $E.ur {5 < # +L¥wE;^($0>a0*lqt0O$sFm8nfy̩S(P #oX(XC̹dE%_U +e#,ݦpᑅϹA7&1,Q+Ԯ)0gb@p({7k,f +dH; Ԏg3RJ+LB "jzP! +c{{p-,nI~(A(3`y[yvdRENGYG3>k`ab"!7fd]Tp弪l 7momo @UW_C}YtO1*;̑a_/1hJhܖ-`@:lH7<VҌLlW87.RB"Nƫ!eEco<6Xv -G:H* $ A5dln[2ZT8D{DKL%BV I'z+ضG,IZ:g5! FAQF-K0y䠅ĝtAnu]qIr/ӜFC6B,e$۵{(:(E6n9"x <*<Ԓ\m|x]̋v8=Xn"E\> 8)59({nT)j* }dO(gN8fv< bs?σT"+Mmo\xT6SGQ^𼦯1"iK8$؅&IĨl5+G4$ B7nKeҝ"eG3eWq48:fʜV9ХZ=%Ȭvl=0R6nYtæ, +NqiæxmhsJ b[)a~5k14ڔ v~>CMW^ v|p_apWIbM)Cm`Lڳ hsRc;m[XIێ/Z=|$g gV'ͷo}F4ruLr>9MRN#&2.̢Aa.,jJ֛@4bE-$"LM=ױ=qOXХ+ԚRSNk\|5|(*jKl韪\=,䒞"w;PwA1[NM&: !+GOi[夰&$mjZ+#Ȫ : {qi.Hid\^;jnHͳ-)G[AOLcuw^^j%83#[EWUR( qK[JZYN s7YZ MDk[k+e2V@h6L>M(qjzDI"Qw#j0chQ:rVUpjǡ"IcW(jD{F Mׂ3堐*"gU{ĜRG#ʝnXq|7 +# Nb i෰{<2v@%.(NE#CK[|ً $L"MHPf%[XMSCQҩM9n:.|mmy9k.W|y!K͝<*D{O +k'υ(zIrLVCG(9$QԆ_,nvKR,#of=c cI4U̹A&ι,>ʔS: +YGgMv&]eoJS`uy̩Xa6DhF돮Mʹ:T]#[=fim@Eozݸ}~`ڗjܸbA>΅=n6Qh%@2DDaLxf#O6Ś14>fj<":W"XK&H, { lBTD1No(#? + #&7e:تVڊ"Hиа;@#xKx[;ކh#iU{^ 5e<^2TG%3,iYIlX|4kٻڶʓIvBbk{df4ݓ:ggI\:l[y35.[-LXn#^F{x#h# ]qARDQIL۩tX}q0Zֺ11=˰8/3fHڭi*1Bbʯ.?+ҡU=Ejym`bءejd}NF P9V|эK܅EQ'#6cNEsɵlF߉7S<@)P>T8,SNdέSaM]R +ڄ#S}"xW-kU6%[7)&{֓}p+iS/I#,''#'OVC$OT Em9 {&ows8eX. d\)54L"=6Q=E)ӦuX-Zhp +F@VbI$~f&]{R AGJdfhz+YPS^ssN#ōO,Q8 +!A`ěh;.CHeOv49uA߲B@Vd?0PӚu EٛV:X(+K\ ! `@5nEw)Џy~&=#a.)u'rg6z9jqH 55Z +h9$YM;n]ZC2FuyV<^dL1E +5el{|rgi ( w.ryzYVxp4y:Q 8(#4 Y +ɹo +11Y5Yr˵8&zM/arB4Na7g,HᒑMNkƃjkRH]ޠ6S7k>O??>O$ƪjYpde)Ğ$?mST 9KBIH)ֻlJVM%TIƕ~-UUp؁?hیxw+/cKu'630 f |#Onym%F|˲RHP'sZ-o4#L 16dž'%QFx4L)gۊ;Dmcp6ubBxk +KE8unPi~PUvu(VQI/lŧ,Bt BP* ru&+DQp4H.ez骩0 em4,s<-#lԨ+;EJ0' Exj*mLz֐yg0UES遾&V6i5A7$.FFۭ]p;V+x1x_裫]7_/:Z3&xZav&KAEbN'gUB}`kq:'N>}5^2vf9.9Rg|8DHLon[Qkqout<:hі2'g8Ӟc>Z³iflA'xI׸`^S4;q5G +zSW^򗍘|9g39Xe8$L`R컍 \#TcO1 +NJ,H!obp.qTxIϯ+0poP +ϥxdpq>]'S-EGʓVU, |~9P5FR&kս^޺&8bUHŴ=Zt41d!`zPWȟ=Ef6kyw^56aJ,^ +Ĉ#ƪ738;G~H [Z +ŖW..1$u$Y]ֱ毗pTQ'V˔ E4J wpEOAҲQpJJQNCg72z* n3GDTR$:$0{m~#kICzB°"p&,7RKs "5u6XƳl'ZNl[KQK5-V-R bVh)ܠ!]+^W:.R0 g<6c?>ZŎw0|!#06>>>b!6UCb㚖\>ɒ9 + +O{ uk} H_wE; - w <m̅Sۮίubx}we{H>̫,c8nfzˇ +Nb(}'b2hr-a(,g|:Zl!)T:Dzj $I=;  `vn,^;D斝xlW^)ӈ,l2``:7A3q/Z8d(7W*(:MO_IQ(\5i >KQ1MV]yLJ!챣{5n;t/HCfW|bߣٷ}UigN*v= xI2icSbb3aLI>KʼZ8a&PJ@k7;jٕ xL tBJvG aƩYD;i#=Z d8N:1 +ZS`OSSw&QĎcha;}/{^y[y tRn{z/Z^2)w%iRJy2Xܸ"綜Y!լ84JL߅1Of:ĨFI$2n +*>wi=h)$(zmꗥ 2Rﭝ6(M~1UI !]鳹~w3!zOGWa@̮oJGJEEn|k2O1E}N `H7`ŒĶSCoE5X[OT*^d,_&J8#8w'~_ +4)'J`VL. h&6S,M X le!N})}g0@OgkvM!d=arP icR"*)hȷo쌆!zi oSx5bEV &_)p\a~i+k #;w #[i; +SI)le"`EO3K$2ͺ;]ܐws4] fdQG8BNkM.`%8-$p͛% +pPYًYvNo(ʇS[L/"CKXy u:w6mZB69 OjKWoeCjoƚZԑ)>lƱ|Aj c mu169PJtK?CK^@Tzz/j\Յ4u_/([*"pm|xN)-p Ae}Vd&.)gGQlomp3ݧy&$l6 v:?ь,mC9ܸF$ܰkٯ+n +JO5u us(Qlc{;e[ ښO8JU8PYVay/Z=\X׿k —e!ƻƪ-T،ĴOPs5+UR@Jy#J.bTTm%-Usp{G{^bTcIQi{T~S+[~~7G:gQ;*2 G%6[zv"$ל.%AlpnOQNS>,[o4iN4(:i xeV/T n kڵS._JHke84Ӻ̭S%Q8g Xi+ChYN㹕@mi +Tf2M?!qOK2 _d,!IP8az5_-kżaXL "^>Erք9݀H|b%g)(۷~bډ0iD&$~T]@gـ;=*# #m 7G ]ɐ5 'M g[#N8Vkƨ[͒Y=<1kx"8ݒ&h^ xQE_p[$as`:()XH.S( +\ýps%I[|CMu@P]K@X}M^ub2eði#0OJ6%b8`0}jD HHHӮ, :W|1ՋV!x+QYV=,j/,(.}5O鵹BD8qJ/4&қ*MY{mf @?Bֲkګ0RӇfy5rG[NڅFFhB.9|M%ip) tVXֵghNo%mp|46# orR3 =+wbqVFcу3PG.[vE]Z,gDŋUd,'5ii//x1AKz'<q̷ɋeSr/M7X_w\dA"UnL<[~sϛ11UKLT+=$q ̠"#v䇺{/в5c|&{Hkc%T3' ycJ_tvO9g>t#%e9%W-`{1vaQي{ފ*V]p(ĞX>e|<:5aY:[M="f{9i*tP)nUȵf+GIjqIjѰYiWB8x~1>+T. T>q _nKSa)YBZy'h\9X%[Znh)uQHVN2;Mo~}i;c/OnaO|7y t5{t15N9sC.IuZZ| !Аt#7.$m<+i\e4 -?VV=ɥF LV/'9aՄtr UIZnNTG?Qu=9($(%X޺)[xrBAJ򬤶܁39__Z.vũ; Ie% : ׷~]һZK<"||ÏQeM$MwKfuÁf;Y}h.a=ze1ưl#&ɉQWIOF8A +Ԯ8UZCuMigKU" +Ē=7sn5+J"=NzGy*]G8UUB4VAJcY:KҐTѴPK}lPμWz<kWA/N1Nq,.U&cmYUmۼ]J +fmRNjr[pKtb8c&[QK 1x "QUTH¸gf^z6lI(qF8G| "jCǃnϭ݈gŲ08Ѓ%)n 鯤ϬOzm6s, dľ#(|v؝t7>EbxN] >˟ƏF~: qIuK 0Yr<-O,`扶&7+[M5eK$Θ5Z92M}/*L:ĝ6sku7Ǟo1tf &D4F:<ӺeŢ"9 +EV` iQ;7 :|iHpVzERK +:䬿MA*0RGm)WS)Q'CgnZ (g֌aL;i :4PVPx7 +lҎ=GʟS&|ɏ>l Ea^Tmt[W:'\j +qqOTf ++F)0j %(; qC:)0T|%5?/)EmtR_kY6e3N'.9H7@} ? by7RF ^.GpTGi@D4%C׬")B;G +IhŤ)¹U笗u0XX]R偵rʹR)+dcINgJ<,el6:P鹛yKPaC<SK1* +"QS#d(sqx%"5L&kd0,C%I=Q ױ&MXT(˙B8|GpfꞄѡ K9* +{^.]ViSCw=t7cV )Eo6QIM3*:*mn^Z m ;"kġQ%DȞJ.y~"2K| j1VE,`0i!7jӃm1qve5 {)~v=kpD$lNΝ슝:B3\/H05j/oXTlC)1.+Hta9w.Y&e$(R-gG\Te'_!W;[^7:ҷ޿tD$el6̯#]urXK 8l8Sf:1X')X>`zv~L1G_'묞W רJSi%Ms=&V +QRV +#aW#~3 T&*h:p, e5XKӰxe$7Vnun#E>IW{tMR+ Zhc5C"ڝ@{rͭVl~wP{ɧ_HN0b0$`75 P1 RXZou$ o<.:OY=` o>ChEWeYZ0[%J0Ҩ62X (:Ĝ} h+@;1!x?-el^ 1 +Y[%u) %t$nebV'y>je43^Y.PO`fXF it$m>VYR[m8wXF]sYu86*ȊĤN~犵ZaȌF8me(W+E<O1LZ) +KYM =3%`tבXojT6]wPZê&0*~P=0Ǫ>rw>M,1yRYؓ{IƲof6$޺%nn$ +gs sT)K±8FI7Qm |ySb0-^b)gN  bJOZ(iF-ڔl1I OSK_"5.i$=o7yàqKqٍgr969i#d + '{NxܯAV5䲔e4aE̕8P$k_u<[ ׉NPX^yU4"e2ݹRI xq}N[Z:դ(b7]MIQBT+ʇ!fD Kv+#VmN*In>174ލ:]djjp%F5qMP^N$Trx%ɕ۴ztIQFeeJq08'RlW(og 1JtCpavwmmtBJ' ,*lpz?GEAa4c+Q1ڞ Wƪ%UJ0Zxԑd4yfɜ5)JzFI7{rGŶLl pny .ZYRY +P: x3`|uR>񼳅řV6dU_vzX/EA[kTgK/S?'goo;U9y6zQ<0 n?ziMO8w 1FD"S"1[wr7"Z }f'IhócFiA"1, #MBKp3;gOI&w풂?U=Dt/M3ETU玜SUawzE ~Aa܎ֱWv}+LI{O9 (Tv`=ݢYٺ +&PqLRV1_(Bu6I\Uo]#Q(k6eyZO u&F(PR|G"E԰VP+-rO ^óT="%E8C,lK2y @댡  ت+I 1R?ъ\# \>jUb|H akq{S/Z#d%q_"|ne+ηt\%0 L&N)=UbMsLӅŏ`jO>j8d$hd+FRH:JL8b*8 "0;zFg| dD+4;ao9Qq^#3H&D~Rk%oZ,Uj䥌H#y)YXJۉ\ɜmѥ2}օyO,p$LI`F-YA`4cyz1$m7H8l +GFio! +Q'vQ6]A+ct؝# + OD~>nWB㄃Z HnJEz]szϊf< +8 kCI5MDYJ,xvrT. q=5f2*j JM.F>%@&@Ž2lᩎ +=Td2M@᩟3LVZ9 *GΒ<n`-;n:t5l)C> *6\X*U {ZO eKpSFn+AXq,{k0[F +j\oc7yBP a:A"jn+t.-YOIj7 yh6jt81I떈`*ʄO^EwBV ũ 5n! + +MiCyg-J cAl= i4㞘*qaèDfRv,-޴: 7B76(q^{)`)&4J͑@PnOcWU)1yy`*Is…|Jc?Rf̽Ê4P]-K/UIR|x.sF!&xMO$Fi#[!-rmn*TP hG8QsgD6ݻ3o/S>1eW^{i<3C_]AKT|ŏ]#R$ j>'(6Z@$cΚy27DjRpc6C&5`uX GT3oK'n%ocN~h^Bh>q@쓲-8Q VȘ?_uԾf`R +S ҥbJtbwNdF^ X*sƷi +3bóaqjWpČ "_ g:mEzK%(M+ENлu;5|`V$KMw2AVĈѓ m[BbT f.\֖Y}Xdĥ+4m,B,5Macuu`_`6RNIc̥$ #g7c 3oT3`x3 fGaiZx ۬#+P#>Dq֙ܳʊ"T.'A}h7 ve0‘4F]9 9Yfn1 %'Ԏ:*8G(Q +tm +ҟΩo;Jڿ6T'/ i*^"&ۙo¬(9#d‚Z">z 7CR3,Ez\ƿ落(^B W#as#t:e6.Rk&9\DٶP.TI3] -YOhpJH^^:1w% {ɘ%,U2QӴ[&pj#e6IK+5$C.kk @{ Oeԇ[h"b+((W¿5}P̴2xT1X ~Z +2{+(q!OR/Z"K'Kh'3Hds!q]IpG…q &p&H̙36a-Լ_*SAbXV"|R֏+cȱN)t6 '正JI)#cЎ_DؼX5MnszGFPMK*؁mDZY|7+Я=kwyjB׫go&Vu]mPqh1Zh +%b +l1@c@UaAdSb(=m#O;WFx,,J'(4koUP}xyC`,ee2 c/EK +wYYPa!Nb#17`/*nҌVD%\KWxģn} Fwwq][i4]nLLm_Oɧ2˶kg:1Aɍ=3e._U՝YƙLK~*'HeٲG>@ꑆXKP)"cHMf/cATRC6v5}\]oSWwEn;Fߍ9a)=O΄\l胤GJKOtAS]!ItВno[3잺;jˆt114~f CNVh%br1`6dciP>Tt;ɘD\@rL +Hp>*9#B|f])bdD +FZ%CrB8FÚe9>Ymb%E@Nl&zDK⹧&g,C[VQ2J)Ls)L&"wyRVZq:Rv"6b Z)SlVu1)PLcejne5IB0W r`$Ivb>+{1RTH(l_D&J/'#b91P ЬpM~0sWx~l!L=IId73H|6I_Cn#M6?^;;tVWE:ESC-jLJU/ 1mզ*TpўJkXl'a)(u*{Eg ]r461E'eTH ,qkqf_PT[\" K}Gê.%[r2zr# !ܛ~ u[$ Hzi ޔPԘFof_tNOwv+(HA`3Bz{.Qt Aj'[ڠer +z]KP +z|-^_xF1R1` 42 Hֿ8ڸoJAM<ʂAOž8]\|!Xy>_}1+hMQ8V .W@ˤ+ĭx̮M7W8J3L͋ Qb 5>%AWFY%Q}p9u(t3\Vҡҕ8^_/Yap:O KQ#7õ߄-`Ձg^wp3ˆO]:Yi}@d|p +:I6<j19gnQJ dY2.DR0#+ nAzHRHP2fΧ˳`5Y{-"M]>O[UKT<'1]t*i**cP P+a=/BRO΅c(*6!naZi]F({0{es0J ( 0Iŷw +!% i@8‹VJg FG%}#gQTQP"=(oFz7AA1Yz*6ICLX2V[%f~0?S"sN26Om. MS,X~X:uEdb AW{omgj*M^ r'O@./3n&0[(+!Þ;ʸ)%2Y5bF̡/ vg ”13˭4}:KV`U-Dx^$K(+bC2$;՞]!Yh 2T O[zo^YQ):d o3U,ňsOeZjjZX&icx<+.u'ؖUgempN%ARHDLdDnRY諾(3sVUF.aBfz+`yoѨ~طqhVHd`D0G$zbÞ̆ Vel;Z7&\c<[p0!BN + +sS!xk"J4Ro)/r ‚Bk2C ҥ =)і%w&9srZ,4h2Rnh)$۽\[dRBT!@ F1 C1+[ڴF{Wz{ҚLFvXc-%.%66\)~[ GYဇ56A}ꃫ]vG0Ν͂gOM&.Gwi*k*cXYRʬ\ߗ˛E$R8q thƧ#NjTdOy#wdy7# `y/ip9yk|d)Zp(Kz.e˹{/b;?Q@<\:}6tg2t-o<](4"hRG= +ǰG.6%5,r6I u;SmT[1F*;o.:1wܥ:S$ԏT2UfS3q*>ZTZihI5VI"!oAtcr`X|R5$O;,냣 ;5d{)!'FJ1'oHF#ICDŚ5eVRbmn;SIcteޡ7)*ǣ +KNJ#5+˭G_MÎf2'AQ^(xvi(ijyC]bwmͪI> endobj xref +0 23 +0000000003 65535 f +0000000016 00000 n +0000016265 00000 n +0000000004 00001 f +0000000005 00000 f +0000000006 00001 f +0000000008 00001 f +0000016316 00000 n +0000000009 00001 f +0000000011 00001 f +0000017534 00000 n +0000000012 00001 f +0000000000 00001 f +0000064834 00000 n +0000017758 00000 n +0000018156 00000 n +0000064716 00000 n +0000017647 00000 n +0000016666 00000 n +0000133054 00000 n +0000018810 00000 n +0000018423 00000 n +0000000113 00000 n +trailer +<<2F906DFFBCE6D040877907067CF14093>]>> +startxref +133230 +%%EOF diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..57a86260 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/document.xml @@ -0,0 +1,14 @@ + + + + +Black RGB + + + +Gray RGB + + + +Neutral CIELAB + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.gs.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..40bb6d6d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml @@ -0,0 +1,26 @@ + + + + + + + + +Black RGB + + + + + + + +Gray RGB + + + + + + + +Neutral CIELAB + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..40bb6d6d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml @@ -0,0 +1,26 @@ + + + + + + + + +Black RGB + + + + + + + +Gray RGB + + + + + + + +Neutral CIELAB + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..57a86260 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml @@ -0,0 +1,14 @@ + + + + +Black RGB + + + +Gray RGB + + + +Neutral CIELAB + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..40bb6d6d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml @@ -0,0 +1,26 @@ + + + + + + + + +Black RGB + + + + + + + +Gray RGB + + + + + + + +Neutral CIELAB + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..8f5e8099 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..2d778e67 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..90ae4318 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml @@ -0,0 +1,82 @@ + + + + + + + + +Black RGB + + + + + + + +Gray RGB + + + + + + + +Neutral CIELAB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/media/image11.jpeg b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/media/image11.jpeg new file mode 100644 index 00000000..70105d1e Binary files /dev/null and b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/media/image11.jpeg differ diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..8f5e8099 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..2d778e67 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..efcf1da8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml @@ -0,0 +1,82 @@ + + + + + + + + +Black RGB + + + + + + + +Gray RGB + + + + + + + +NeutralCIELAB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/media/image11.jpeg b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/media/image11.jpeg new file mode 100644 index 00000000..70105d1e Binary files /dev/null and b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/media/image11.jpeg differ diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..8f5e8099 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..2d778e67 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..841daec9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml @@ -0,0 +1,70 @@ + + + + +Black RGB + + + +Gray RGB + + + +NeutralCIELAB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/media/image11.jpeg b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/media/image11.jpeg new file mode 100644 index 00000000..70105d1e Binary files /dev/null and b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/media/image11.jpeg differ diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..8f5e8099 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..2d778e67 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..efcf1da8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml @@ -0,0 +1,82 @@ + + + + + + + + +Black RGB + + + + + + + +Gray RGB + + + + + + + +NeutralCIELAB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/media/image11.jpeg b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/media/image11.jpeg new file mode 100644 index 00000000..70105d1e Binary files /dev/null and b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/media/image11.jpeg differ diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..8f5e8099 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..2d778e67 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..841daec9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/document.xml @@ -0,0 +1,70 @@ + + + + +Black RGB + + + +Gray RGB + + + +NeutralCIELAB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/media/image11.jpeg b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/media/image11.jpeg new file mode 100644 index 00000000..70105d1e Binary files /dev/null and b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/media/image11.jpeg differ diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/[Content_Types].xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..8f5e8099 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/_rels/.rels b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/app.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/core.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..2d778e67 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/document.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..841daec9 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/document.xml @@ -0,0 +1,70 @@ + + + + +Black RGB + + + +Gray RGB + + + +NeutralCIELAB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/fontTable.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/media/image11.jpeg b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/media/image11.jpeg new file mode 100644 index 00000000..70105d1e Binary files /dev/null and b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/media/image11.jpeg differ diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/settings.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/styles.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/theme/theme1.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/webSettings.xml b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/text_graphic_image.pdf.mutool.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf b/extract/test/zlib.3.pdf new file mode 100644 index 00000000..6fa519c5 Binary files /dev/null and b/extract/test/zlib.3.pdf differ diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.gs.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..609b9792 --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/document.xml @@ -0,0 +1,185 @@ + + + + +ZLIB(3) ZLIB(3) + + + +NAME +zlib − compression/decompression library + + + +SYNOPSIS +[see +zlib.h +for full description] + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + +SEE ALSO +The +zlib +web site can be found at: + + + +http://zlib.net/ + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + +http://zlib.net/zlib_faq.html + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + +15 Jan 2017 1 + + + +ZLIB(3) ZLIB(3) + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + +3. This notice may not be removed or altered from any source distribution. + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.gs.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6f6f7cd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +NAME +zlib − compression/decompression library + + + + + + + +SYNOPSIS +[see +zlib.h +for full description] + + + + + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + + + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + + + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + + + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + + + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + + + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + + + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + + + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + + + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + + + + + +SEE ALSO +The +zlib +web site can be found at: + + + + + + + +http://zlib.net/ + + + + + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + + + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + + + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + + + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + + + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + + + + + +http://zlib.net/zlib_faq.html + + + + + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + + + + + +15 Jan 2017 1 + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + + + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + + + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + + + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + + + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + + + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + + + + + +3. This notice may not be removed or altered from any source distribution. + + + + + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + + + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + + + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + + + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6f6f7cd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +NAME +zlib − compression/decompression library + + + + + + + +SYNOPSIS +[see +zlib.h +for full description] + + + + + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + + + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + + + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + + + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + + + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + + + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + + + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + + + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + + + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + + + + + +SEE ALSO +The +zlib +web site can be found at: + + + + + + + +http://zlib.net/ + + + + + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + + + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + + + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + + + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + + + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + + + + + +http://zlib.net/zlib_faq.html + + + + + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + + + + + +15 Jan 2017 1 + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + + + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + + + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + + + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + + + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + + + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + + + + + +3. This notice may not be removed or altered from any source distribution. + + + + + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + + + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + + + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + + + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6089db2 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/document.xml @@ -0,0 +1,185 @@ + + + + +ZLIB(3) ZLIB(3) + + + +NAME +zlib − compression/decompression library + + + +SYNOPSIS +[see +zlib.h +for full description] + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + +SEE ALSO +The +zlib +web site can be found at: + + + +http://zlib.net/ + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + +http://zlib.net/zlib_faq.html + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + +15 Jan 2017 1 + + + +ZLIB(3) ZLIB(3) + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + +3. This notice may not be removed or altered from any source distribution. + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract-rotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6f6f7cd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +NAME +zlib − compression/decompression library + + + + + + + +SYNOPSIS +[see +zlib.h +for full description] + + + + + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + + + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + + + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + + + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + + + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + + + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + + + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + + + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + + + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + + + + + +SEE ALSO +The +zlib +web site can be found at: + + + + + + + +http://zlib.net/ + + + + + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + + + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + + + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + + + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + + + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + + + + + +http://zlib.net/zlib_faq.html + + + + + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + + + + + +15 Jan 2017 1 + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + + + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + + + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + + + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + + + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + + + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + + + + + +3. This notice may not be removed or altered from any source distribution. + + + + + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + + + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + + + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + + + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-gs.xml.extract.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6f6f7cd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +NAME +zlib − compression/decompression library + + + + + + + +SYNOPSIS +[see +zlib.h +for full description] + + + + + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + + + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + + + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + + + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + + + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + + + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + + + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + + + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + + + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + + + + + +SEE ALSO +The +zlib +web site can be found at: + + + + + + + +http://zlib.net/ + + + + + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + + + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + + + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + + + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + + + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + + + + + +http://zlib.net/zlib_faq.html + + + + + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + + + + + +15 Jan 2017 1 + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + + + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + + + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + + + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + + + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + + + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + + + + + +3. This notice may not be removed or altered from any source distribution. + + + + + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + + + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + + + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + + + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-autosplit.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6f6f7cd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +NAME +zlib − compression/decompression library + + + + + + + +SYNOPSIS +[see +zlib.h +for full description] + + + + + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + + + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + + + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + + + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + + + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + + + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + + + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + + + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + + + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + + + + + +SEE ALSO +The +zlib +web site can be found at: + + + + + + + +http://zlib.net/ + + + + + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + + + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + + + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + + + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + + + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + + + + + +http://zlib.net/zlib_faq.html + + + + + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + + + + + +15 Jan 2017 1 + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + + + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + + + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + + + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + + + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + + + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + + + + + +3. This notice may not be removed or altered from any source distribution. + + + + + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + + + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + + + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + + + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate-spacing.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6089db2 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/document.xml @@ -0,0 +1,185 @@ + + + + +ZLIB(3) ZLIB(3) + + + +NAME +zlib − compression/decompression library + + + +SYNOPSIS +[see +zlib.h +for full description] + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + +SEE ALSO +The +zlib +web site can be found at: + + + +http://zlib.net/ + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + +http://zlib.net/zlib_faq.html + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + +15 Jan 2017 1 + + + +ZLIB(3) ZLIB(3) + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + +3. This notice may not be removed or altered from any source distribution. + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract-rotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6f6f7cd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/document.xml @@ -0,0 +1,321 @@ + + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +NAME +zlib − compression/decompression library + + + + + + + +SYNOPSIS +[see +zlib.h +for full description] + + + + + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + + + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + + + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + + + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + + + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + + + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + + + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + + + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + + + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + + + + + +SEE ALSO +The +zlib +web site can be found at: + + + + + + + +http://zlib.net/ + + + + + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + + + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + + + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + + + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + + + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + + + + + +http://zlib.net/zlib_faq.html + + + + + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + + + + + +15 Jan 2017 1 + + + + + + + +ZLIB(3) ZLIB(3) + + + + + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + + + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + + + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + + + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + + + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + + + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + + + + + +3. This notice may not be removed or altered from any source distribution. + + + + + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + + + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + + + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + + + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.intermediate-mu.xml.extract.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6089db2 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/document.xml @@ -0,0 +1,185 @@ + + + + +ZLIB(3) ZLIB(3) + + + +NAME +zlib − compression/decompression library + + + +SYNOPSIS +[see +zlib.h +for full description] + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + +SEE ALSO +The +zlib +web site can be found at: + + + +http://zlib.net/ + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + +http://zlib.net/zlib_faq.html + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + +15 Jan 2017 1 + + + +ZLIB(3) ZLIB(3) + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + +3. This notice may not be removed or altered from any source distribution. + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool-norotate.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/[Content_Types].xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/[Content_Types].xml new file mode 100644 index 00000000..07d88cca --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/_rels/.rels b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/_rels/.rels new file mode 100644 index 00000000..32548d42 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/app.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/app.xml new file mode 100644 index 00000000..eb8dd2e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/app.xml @@ -0,0 +1,2 @@ + +31218Microsoft Office Word011falsefalse19falsefalse16.0000 \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/core.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/core.xml new file mode 100644 index 00000000..195d77a9 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/docProps/core.xml @@ -0,0 +1,2 @@ + +12020-09-25T17:04:00Z2020-09-25T17:07:00Z \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels new file mode 100644 index 00000000..3b2b7f8c --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/document.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/document.xml new file mode 100644 index 00000000..a6089db2 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/document.xml @@ -0,0 +1,185 @@ + + + + +ZLIB(3) ZLIB(3) + + + +NAME +zlib − compression/decompression library + + + +SYNOPSIS +[see +zlib.h +for full description] + + + +DESCRIPTION +The +zlib +library is a general purpose data compression library. The code is thread safe, assuming that the standard library functions used are thread safe, such as memory allocation routines. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later with the same stream interface. + + + +Compression can be done in a single step if the buffers are large enough or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + + +The library also supports reading and writing files in +gzip +(1) (.gz) format with an interface similar to that of stdio. + + + +The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in the case of corrupted input. + + + +All functions of the compression library are documented in the file +zlib.h +. The distribution source includes examples of use of the library in the files +test/example.c +and +test/minigzip.c, +as well as other examples in the +examples/ +directory. + + + +Changes to this version are documented in the file +ChangeLog +that accompanies the source. + + + +zlib +is built in to many languages and operating systems, including but not limited to Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. + + + +An experimental package to read and write files in the .zip format, written on top of +zlib +by Gilles Vollant (info@winimage.com), is available at: + + + +http://www.winimage.com/zLibDll/minizip.html and also in the +contrib/minizip +directory of the main +zlib +source distribution. + + + +SEE ALSO +The +zlib +web site can be found at: + + + +http://zlib.net/ + + + +The data format used by the +zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: + + + +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) + + + +Mark Nelson wrote an article about +zlib +for the Jan. 1997 issue of Dr. Dobb’s Journal; a copy of the article is available at: + + + +http://marknelson.us/1997/01/01/zlib-engine/ + + + +REPORTING PROBLEMS +Before reporting a problem, please check the +zlib +web site to verify that you have the latest version of +zlib +; otherwise, obtain the latest version and see if the problem still exists. Please read the +zlib +FAQ at: + + + +http://zlib.net/zlib_faq.html + + + +before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). + + + +15 Jan 2017 1 + + + +ZLIB(3) ZLIB(3) + + + +AUTHORS AND LICENSE +Version 1.2.11 + + + +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + + +This software is provided ’as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + + + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + + +3. This notice may not be removed or altered from any source distribution. + + + +Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu + + + +The deflate format used by +zlib +was defined by Phil Katz. The deflate and +zlib +specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in +zlib +; who are too numerous to cite here. + + + +UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). + + + +15 Jan 2017 2 + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/fontTable.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/fontTable.xml new file mode 100644 index 00000000..a39546e5 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/settings.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/settings.xml new file mode 100644 index 00000000..c403540d --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/styles.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/styles.xml new file mode 100644 index 00000000..38e5e2bd --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/theme/theme1.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/theme/theme1.xml new file mode 100644 index 00000000..d1a502f8 --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/webSettings.xml b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/webSettings.xml new file mode 100644 index 00000000..629ae06a --- /dev/null +++ b/extract/test/zlib.3.pdf.mutool.docx.dir.ref/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/freetype/.clang-format b/freetype/.clang-format new file mode 100644 index 00000000..fbd04c11 --- /dev/null +++ b/freetype/.clang-format @@ -0,0 +1,16 @@ +BasedOnStyle: Chromium +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignConsecutiveMacros: true +AlignEscapedNewlines: true +# AlignOperands: Align +AlignTrailingComments: true +AlwaysBreakAfterReturnType: AllDefinitions +BreakBeforeBraces: Allman +ColumnLimit: 80 +DerivePointerAlignment: false +IndentCaseLabels: false +PointerAlignment: Left +SpaceBeforeParens: ControlStatements +SpacesInParentheses: true diff --git a/freetype/CMakeLists.txt b/freetype/CMakeLists.txt index e3ffb83b..3ed55aad 100644 --- a/freetype/CMakeLists.txt +++ b/freetype/CMakeLists.txt @@ -1,6 +1,6 @@ # CMakeLists.txt # -# Copyright (C) 2013-2019 by +# Copyright (C) 2013-2020 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # Written originally by John Cary @@ -14,14 +14,14 @@ # # The following will 1. create a build directory and 2. change into it and # call cmake to configure the build with default parameters as a static -# library. +# library. See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html +# for information about Debug, Release, etc. builds. # -# cmake -E make_directory build -# cmake -E chdir build cmake .. +# cmake -B build -D CMAKE_BUILD_TYPE=Release # # For a dynamic library, use # -# cmake -E chdir build cmake -D BUILD_SHARED_LIBS:BOOL=true .. +# cmake -B build -D BUILD_SHARED_LIBS=true -D CMAKE_BUILD_TYPE=Release # # For a framework on OS X, use # @@ -68,14 +68,26 @@ # . `CMakeLists.txt' is provided as-is since it is normally not used by the # developer team. # -# . Set the `FT_WITH_ZLIB', `FT_WITH_BZIP2', `FT_WITH_PNG', and -# `FT_WITH_HARFBUZZ' CMake variables to `ON' to force using a dependency. -# Leave a variable undefined (which is the default) to use the dependency -# only if it is available. Set `CMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE' to -# disable a dependency completely (CMake package name, so `BZip2' instead of -# `BZIP2'). Example: +# . Set the `FT_WITH_ZLIB', `FT_WITH_BZIP2', `FT_WITH_PNG', +# `FT_WITH_HARFBUZZ', and `FT_WITH_BROTLI' CMake variables to `ON' to +# force using a dependency. Leave a variable undefined (which is the +# default) to use the dependency only if it is available. Example: # -# cmake -DFT_WITH_ZLIB=ON -DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE [...] +# cmake -B build -D FT_WITH_ZLIB=ON \ +# -D FT_WITH_BZIP2=ON \ +# -D FT_WITH_PNG=ON \ +# -D FT_WITH_HARFBUZZ=ON \ +# -D FT_WITH_BROTLI=ON [...] +# +# Set `CMAKE_DISABLE_FIND_PACKAGE_XXX=TRUE' to disable a dependency completely +# (where `XXX' is a CMake package name like `BZip2'). Example for disabling all +# dependencies: +# +# cmake -B build -D CMAKE_DISABLE_FIND_PACKAGE_ZLIB=TRUE \ +# -D CMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE \ +# -D CMAKE_DISABLE_FIND_PACKAGE_PNG=TRUE \ +# -D CMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE \ +# -D CMAKE_DISABLE_FIND_PACKAGE_BrotliDec=TRUE [...] # # . Installation of FreeType can be controlled with the CMake variables # `SKIP_INSTALL_HEADERS', `SKIP_INSTALL_LIBRARIES', and `SKIP_INSTALL_ALL' @@ -89,7 +101,7 @@ cmake_minimum_required(VERSION 2.8.12) if (NOT CMAKE_VERSION VERSION_LESS 3.3) # Allow symbol visibility settings also on static libraries. CMake < 3.3 - # only sets the propery on a shared library build. + # only sets the property on a shared library build. cmake_policy(SET CMP0063 NEW) endif () @@ -135,26 +147,34 @@ project(freetype C) set(VERSION_MAJOR "2") set(VERSION_MINOR "10") -set(VERSION_PATCH "1") - -# SOVERSION scheme: CURRENT.AGE.REVISION -# If there was an incompatible interface change: -# Increment CURRENT. Set AGE and REVISION to 0 -# If there was a compatible interface change: -# Increment AGE. Set REVISION to 0 -# If the source code was changed, but there were no interface changes: -# Increment REVISION. -set(LIBRARY_VERSION "6.16.0") -set(LIBRARY_SOVERSION "6") - -# These options mean "require x and complain if not found". They'll get -# optionally found anyway. Use `-DCMAKE_DISABLE_FIND_PACKAGE_x=TRUE` to disable -# searching for a packge entirely (x is the CMake package name, so "BZip2" -# instead of "BZIP2"). +set(VERSION_PATCH "4") + +# Generate LIBRARY_VERSION and LIBRARY_SOVERSION. +set(LIBTOOL_REGEX "version_info='([0-9]+):([0-9]+):([0-9]+)'") +file(STRINGS "${PROJECT_SOURCE_DIR}/builds/unix/configure.raw" + VERSION_INFO + REGEX ${LIBTOOL_REGEX}) +string(REGEX REPLACE + ${LIBTOOL_REGEX} "\\1" + LIBTOOL_CURRENT "${VERSION_INFO}") +string(REGEX REPLACE + ${LIBTOOL_REGEX} "\\2" + LIBTOOL_REVISION "${VERSION_INFO}") +string(REGEX REPLACE + ${LIBTOOL_REGEX} "\\3" + LIBTOOL_AGE "${VERSION_INFO}") + +# This is what libtool does internally on Unix platforms. +math(EXPR LIBRARY_SOVERSION "${LIBTOOL_CURRENT} - ${LIBTOOL_AGE}") +set(LIBRARY_VERSION "${LIBRARY_SOVERSION}.${LIBTOOL_AGE}.${LIBTOOL_REVISION}") + +# External dependency library detection is automatic. See the notes at the top +# of this file, for how to force or disable dependencies completely. option(FT_WITH_ZLIB "Use system zlib instead of internal library." OFF) option(FT_WITH_BZIP2 "Support bzip2 compressed fonts." OFF) option(FT_WITH_PNG "Support PNG compressed OpenType embedded bitmaps." OFF) option(FT_WITH_HARFBUZZ "Improve auto-hinting of OpenType fonts." OFF) +option(FT_WITH_BROTLI "Support compressed WOFF2 fonts." OFF) # Disallow in-source builds @@ -185,10 +205,11 @@ endif () # Find dependencies +set(HARFBUZZ_MIN_VERSION "1.8.0") if (FT_WITH_HARFBUZZ) - find_package(HarfBuzz 1.3.0 REQUIRED) + find_package(HarfBuzz ${HARFBUZZ_MIN_VERSION} REQUIRED) else () - find_package(HarfBuzz 1.3.0) + find_package(HarfBuzz ${HARFBUZZ_MIN_VERSION}) endif () if (FT_WITH_PNG) @@ -209,13 +230,18 @@ else () find_package(BZip2) endif () +if (FT_WITH_BROTLI) + find_package(BrotliDec REQUIRED) +else () + find_package(BrotliDec) +endif () + # Create the configuration file if (UNIX) check_include_file("unistd.h" HAVE_UNISTD_H) check_include_file("fcntl.h" HAVE_FCNTL_H) - check_include_file("stdint.h" HAVE_STDINT_H) - file(READ "${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.in" + file(READ "${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.h.in" FTCONFIG_H) if (HAVE_UNISTD_H) string(REGEX REPLACE @@ -227,13 +253,6 @@ if (UNIX) "#undef +(HAVE_FCNTL_H)" "#define \\1 1" FTCONFIG_H "${FTCONFIG_H}") endif () - if (HAVE_STDINT_H) - string(REGEX REPLACE - "#undef +(HAVE_STDINT_H)" "#define \\1 1" - FTCONFIG_H "${FTCONFIG_H}") - endif () - string(REPLACE "/undef " "#undef " - FTCONFIG_H "${FTCONFIG_H}") else () file(READ "${PROJECT_SOURCE_DIR}/include/freetype/config/ftconfig.h" FTCONFIG_H) @@ -273,6 +292,11 @@ if (HARFBUZZ_FOUND) "/\\* +(#define +FT_CONFIG_OPTION_USE_HARFBUZZ) +\\*/" "\\1" FTOPTION_H "${FTOPTION_H}") endif () +if (BROTLIDEC_FOUND) + string(REGEX REPLACE + "/\\* +(#define +FT_CONFIG_OPTION_USE_BROTLI) +\\*/" "\\1" + FTOPTION_H "${FTOPTION_H}") +endif () set(FTOPTION_H_NAME "${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h") if (EXISTS "${FTOPTION_H_NAME}") @@ -308,7 +332,6 @@ set(BASE_SRCS src/base/ftpfr.c src/base/ftstroke.c src/base/ftsynth.c - src/base/ftsystem.c src/base/fttype1.c src/base/ftwinfnt.c src/bdf/bdf.c @@ -332,6 +355,12 @@ set(BASE_SRCS src/winfonts/winfnt.c ) +if (UNIX) + list(APPEND BASE_SRCS "builds/unix/ftsystem.c") +else () + list(APPEND BASE_SRCS "src/base/ftsystem.c") +endif () + if (WIN32) enable_language(RC) list(APPEND BASE_SRCS builds/windows/ftdebug.c @@ -390,7 +419,11 @@ target_include_directories( $ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/include) + ${CMAKE_CURRENT_SOURCE_DIR}/include + + # Make available for builds/unix/ftsystem.c. + ${CMAKE_CURRENT_BINARY_DIR}/include/freetype/config +) if (BUILD_FRAMEWORK) @@ -411,23 +444,29 @@ set(PKG_CONFIG_REQUIRED_PRIVATE "") if (ZLIB_FOUND) target_link_libraries(freetype PRIVATE ${ZLIB_LIBRARIES}) target_include_directories(freetype PRIVATE ${ZLIB_INCLUDE_DIRS}) - list(APPEND PKG_CONFIG_REQUIRED_PRIVATE zlib) + list(APPEND PKG_CONFIG_REQUIRED_PRIVATE "zlib") endif () if (BZIP2_FOUND) target_link_libraries(freetype PRIVATE ${BZIP2_LIBRARIES}) target_include_directories(freetype PRIVATE ${BZIP2_INCLUDE_DIR}) # not BZIP2_INCLUDE_DIRS - list(APPEND PKG_CONFIG_REQUIRED_PRIVATE bzip2) + list(APPEND PKG_CONFIG_REQUIRED_PRIVATE "bzip2") endif () if (PNG_FOUND) target_link_libraries(freetype PRIVATE ${PNG_LIBRARIES}) target_compile_definitions(freetype PRIVATE ${PNG_DEFINITIONS}) target_include_directories(freetype PRIVATE ${PNG_INCLUDE_DIRS}) - list(APPEND PKG_CONFIG_REQUIRED_PRIVATE libpng) + list(APPEND PKG_CONFIG_REQUIRED_PRIVATE "libpng") endif () if (HARFBUZZ_FOUND) target_link_libraries(freetype PRIVATE ${HARFBUZZ_LIBRARIES}) target_include_directories(freetype PRIVATE ${HARFBUZZ_INCLUDE_DIRS}) - list(APPEND PKG_CONFIG_REQUIRED_PRIVATE harfbuzz) + list(APPEND PKG_CONFIG_REQUIRED_PRIVATE "harfbuzz >= ${HARFBUZZ_MIN_VERSION}") +endif () +if (BROTLIDEC_FOUND) + target_link_libraries(freetype PRIVATE ${BROTLIDEC_LIBRARIES}) + target_compile_definitions(freetype PRIVATE ${BROTLIDEC_DEFINITIONS}) + target_include_directories(freetype PRIVATE ${BROTLIDEC_INCLUDE_DIRS}) + list(APPEND PKG_CONFIG_REQUIRED_PRIVATE "libbrotlidec") endif () @@ -453,7 +492,7 @@ endif () if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) # Generate the pkg-config file if (UNIX) - file(READ ${PROJECT_SOURCE_DIR}/builds/unix/freetype2.in FREETYPE2_PC_IN) + file(READ "${PROJECT_SOURCE_DIR}/builds/unix/freetype2.in" FREETYPE2_PC_IN) string(REPLACE ";" ", " PKG_CONFIG_REQUIRED_PRIVATE "${PKG_CONFIG_REQUIRED_PRIVATE}") @@ -465,7 +504,7 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) FREETYPE2_PC_IN ${FREETYPE2_PC_IN}) string(REPLACE "%includedir%" "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}" FREETYPE2_PC_IN ${FREETYPE2_PC_IN}) - string(REPLACE "%ft_version%" "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" + string(REPLACE "%ft_version%" "${LIBTOOL_CURRENT}.${LIBTOOL_REVISION}.${LIBTOOL_AGE}" FREETYPE2_PC_IN ${FREETYPE2_PC_IN}) string(REPLACE "%REQUIRES_PRIVATE%" "${PKG_CONFIG_REQUIRED_PRIVATE}" FREETYPE2_PC_IN ${FREETYPE2_PC_IN}) @@ -488,6 +527,12 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) COMPONENT pkgconfig) endif () + include(CMakePackageConfigHelpers) + write_basic_package_version_file( + ${PROJECT_BINARY_DIR}/freetype-config-version.cmake + VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + COMPATIBILITY SameMajorVersion) + install( TARGETS freetype EXPORT freetype-targets @@ -501,6 +546,10 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/freetype FILE freetype-config.cmake COMPONENT headers) + install( + FILES ${PROJECT_BINARY_DIR}/freetype-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/freetype + COMPONENT headers) endif () diff --git a/freetype/ChangeLog b/freetype/ChangeLog index 6450a60b..42f7c34b 100644 --- a/freetype/ChangeLog +++ b/freetype/ChangeLog @@ -1,3 +1,1949 @@ +2020-10-20 Werner Lemberg + + * Version 2.10.4 released. + ========================== + + + Tag sources with `VER-2-10-4'. + + * docs/VERSION.TXT: Add entry for version 2.10.4. + * docs/CHANGES: Updated. + + * README, src/base/ftver.rc, builds/windows/vc2010/index.html, + builds/windows/visualc/index.html, + builds/windows/visualce/index.html, + builds/wince/vc2005-ce/index.html, + builds/wince/vc2008-ce/index.html, docs/freetype-config.1: + s/2.10.3/2.10.4/, s/2103/2104/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 4. + + * builds/unix/configure.raw (version_info): Set to 23:4:17. + * CMakeLists.txt (VERSION_PATCH): Set to 4. + +2020-10-19 Werner Lemberg + + [sfnt] Fix heap buffer overflow (#59308). + + This is CVE-2020-15999. + + * src/sfnt/pngshim.c (Load_SBit_Png): Test bitmap size earlier. + +2020-10-17 Alexei Podtelezhnikov + + * src/sfnt/tt{colr,cpal}.c: Fix signedness warnings from VC++. + +2020-10-17 Alexei Podtelezhnikov + + * src/sfnt/sfwoff2.c (Read255UShort): Tweak types to please VC++. + +2020-10-10 Werner Lemberg + + * Version 2.10.3 released. + ========================== + + + Tag sources with `VER-2-10-3'. + + * docs/VERSION.TXT: Add entry for version 2.10.3. + + * README, src/base/ftver.rc, builds/windows/vc2010/index.html, + builds/windows/visualc/index.html, + builds/windows/visualce/index.html, + builds/wince/vc2005-ce/index.html, + builds/wince/vc2008-ce/index.html, docs/freetype-config.1: + s/2.10.2/2.10.3/, s/2102/2103/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 3. + + * builds/unix/configure.raw (version_info): Set to 23:3:17. + * CMakeLists.txt (VERSION_PATCH): Set to 3. + +2020-09-25 Werner Lemberg + + [autofit] Synchronize with ttfautohint. + + This corresponds to the following commits in the ttfautohint git + repository: + + bb6842bd3bd437b7b4a7921b0376c860f5e73d18 Typo, formatting. + d5c91ddb1cb310257a3dfe9a8e20e1fc51335faa Add Medefaidrin script. + + * src/autofit/afblue.dat: Add blue zone data for Medefaidrin. + * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + + * src/autofit/afscript.h: Add Medefaidrin standard characters. + + * src/autofit/afranges.c, src/autofit/afstyles.h: Add Medefaidrin + data. + +2020-09-25 Werner Lemberg + + Move `scripts/make_distribution_archives.py` to `src/tools`. + + * scr/tools/scripts/make_distribution_archives.py: (_TOP_DIR, + _SCRIPT_DIR): Updated to new location. + (main): s/shutils.copyfile/shutils.copy/ to preserve file + permissions. + (main): Prefix source file paths with `git_dir` while copying files + to allow calls of the script from other places than the top-level + directory. + +2020-09-24 Werner Lemberg + + * src/cff/cffgload.c (cff_slot_load): Scale `vertBearingY`. + + Towards the end of the the function there is a call to + `FT_Outline_Get_CBox` that retrieves the glyph bbox in scaled units. + That sets `horiBearing{X,Y}` and `vertBearingX` but `vertBearingY` + is left alone, and is not scaled. + + Patch from Eric Muller . + +2020-09-24 Werner Lemberg + + * src/base/ftobjs.c (FT_Load_Glyph): Trace glyph metrics. + +2020-09-22 Werner Lemberg + + [meson] Move auxiliary scripts to `builds/meson`. + + Suggested by Alexei. + + * scripts/*.py: Move meson scripts to... + * builds/meson/*.py: ... this new location. + + * meson.build: Updated. + +2020-09-21 David Turner + + Add python script for building tarballs. + + * scripts/make_distribution_archives.py: New file. + + This standalone Python script should be equivalent to running `make + dist` with the Make-based build system, with the following minor + differences: + + - Since `make distclean` doesn't always clean up `objs/` properly, + `make dist` archives may contain some stale binaries like + `objs/.libs/libfreetype.so.6` or others. + + - `config.guess` and `config.sub` are not updated unless option + `--gnu-config-dir=DIR` is used to specify the location of these + files. + + - Some bits of the auto-generated reference documentation may + appear in slightly different order, probably due to issues related + to mkdocs and docwriter. + + As an example, the call + + scripts/make_distribution_archives.py /tmp/freetype2-dist + + creates the following files under `/tmp/freetype2-dist`: + + freetype-.tar.gz + freetype-.tar.xz + ft.zip + +2020-09-21 Werner Lemberg + + * scripts/extract_freetype_version.py: Fix regex typos. + +2020-09-21 David Turner + + Add Meson build project file. + + Example usage: + + # Configure Meson build in directory `build-meson` to generate + # release binaries comparable to to the ones from the + # autotools/make build system. + meson setup build-meson \ + --prefix=/usr/local \ + --buildtype=debugoptimized \ + --strip \ + -Db_ndebug=true + + # After configuring the Meson build with the above command, + # compile and install to `/usr/local/`; this includes a pkg-config + # file. + ninja -C build-meson install + + # Alternatively, compile and install to `/tmp/aa/usr/local/...` + # for packaging. + DESTDIR=/tmp/aa ninja -C build-meson install + + # Generate documentation under `build-meson/docs`. + ninja -C build-meson docs + + Library size comparison for stripped `libfreetype.so` generated by + all three build systems: + + - Default build (autotools + libtool): 712 KiB + - CMake build (RelWithDebInfo): 712 KiB + - Meson build: 712 KiB + + + * meson.build: New top-level Meson build file for the library. + + * meson_options.txt: New file. It holds user-selectable options for + the build, which can be printed with `meson configure`, and selected + at `meson setup` or `meson --reconfigure` time with + `-D