diff -Nru pdfminer-20110515+dfsg/debian/changelog pdfminer-20140328+dfsg/debian/changelog --- pdfminer-20110515+dfsg/debian/changelog 2011-08-24 10:56:37.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/changelog 2015-11-05 11:12:28.000000000 +0000 @@ -1,3 +1,50 @@ +pdfminer (20140328+dfsg-1) unstable; urgency=medium + + [ Jakub Wilk ] + * Use canonical URIs for Vcs-* fields. + + [ Daniele Tricoli ] + * New upstream release. (Closes: #741046, #794682) + * debian/compat + - Bump debhelper compatibility level to 9. + * debian/control + - Bump debhelper B-D to (>= 9). + - Bump Standards-Version to 3.9.6 (no changes needed). + - Add dh-python to B-D. + - Bump X-Python-Version to >= 2.6. + - Drop elinks-lite from B-D since it is a transitional package. + - Update Vcs fields for git migration. + * debian/copyright + - Update Format URI. + - Update copyright years. + - Use Files-Excluded to remove non redistributable files and prebuilt + Python objects. + - Rename cmapsrc into cmaprsrc. + * debian/get-orig-source.sh + - Remove because superseded by Files-Excluded in debian/copyright. + * debian/manpages/latin2ascii.1.xml + - Add manpage for latin2ascii. + * debian/patches/pickle-protocol2.diff + - Refresh. + * debian/patches/avoid-timestamped-gzip.patch + - Avoid timestamps in gzip-compressed file and use compressionlevel=9 to + reduce data size. + * debian/python-pdfminer.docs + - Remove README.txt since not shipped anymore. + * debian/python-pdfminer.install + - Add /usr/bin/latin2ascii. + * debian/{python-pdfminer.install,rules} + - Don't recreate cmap/__init__.py since pdfminer.cmap is not a + Python package anymore. + * debian/rules + - Use uscan inside get-orig-source target. + - Disable tests inside samples directory since they are failing also + upstream. + * debian/watch + - Use pypi.debian.net redirector. + + -- Daniele Tricoli Thu, 05 Nov 2015 01:18:35 +0100 + pdfminer (20110515+dfsg-1) unstable; urgency=low * New upstream release diff -Nru pdfminer-20110515+dfsg/debian/compat pdfminer-20140328+dfsg/debian/compat --- pdfminer-20110515+dfsg/debian/compat 2010-06-05 11:40:26.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/compat 2015-11-05 10:21:08.000000000 +0000 @@ -1 +1 @@ -7 +9 diff -Nru pdfminer-20110515+dfsg/debian/control pdfminer-20140328+dfsg/debian/control --- pdfminer-20110515+dfsg/debian/control 2011-07-26 22:35:52.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/control 2015-11-05 10:21:08.000000000 +0000 @@ -3,19 +3,21 @@ Priority: optional Maintainer: Debian Python Modules Team Uploaders: Daniele Tricoli -Build-Depends: debhelper (>= 7.0.50~), - docbook-xml, - docbook-xsl, - elinks-lite | elinks, - libxml2-utils, - python-all (>= 2.6.6-3~), - python-nose, - xsltproc, -X-Python-Version: >= 2.4 -Standards-Version: 3.9.2 +Build-Depends: + debhelper (>= 9), + dh-python, + docbook-xml, + docbook-xsl, + elinks, + libxml2-utils, + python-all (>= 2.6.6-3~), + python-nose, + xsltproc, +X-Python-Version: >= 2.6 +Standards-Version: 3.9.6 Homepage: http://www.unixuser.org/~euske/python/pdfminer/ -Vcs-Svn: svn://svn.debian.org/python-modules/packages/pdfminer/trunk/ -Vcs-Browser: http://svn.debian.org/viewsvn/python-modules/packages/pdfminer/trunk/ +Vcs-Git: git://anonscm.debian.org/python-modules/packages/pdfminer.git +Vcs-Browser: https://anonscm.debian.org/cgit/python-modules/packages/pdfminer.git Package: python-pdfminer Architecture: all diff -Nru pdfminer-20110515+dfsg/debian/copyright pdfminer-20140328+dfsg/debian/copyright --- pdfminer-20110515+dfsg/debian/copyright 2011-08-24 03:58:54.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/copyright 2015-11-05 10:21:08.000000000 +0000 @@ -1,7 +1,8 @@ -Format: http://anonscm.debian.org/viewvc/dep/web/deps/dep5.mdwn?revision=174 +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: PDFminer Upstream-Contact: Yusuke Shinyama Source: http://pypi.python.org/pypi/pdfminer/ +Files-Excluded: samples/nonfree/* pdfminer/*.pyc Comment: All but trivial test PDF documents were removed from the sources/ directory because of lack of source code for them. @@ -26,10 +27,10 @@ SOFTWARE. Files: * -Copyright: 2004-2011, Yusuke Shinyama +Copyright: 2004-2013, Yusuke Shinyama License: Expat -Files: cmapsrc/*.txt +Files: cmaprsrc/*.txt Copyright: 1990-2010, Adobe Systems Incorporated License: BSD-Adobe Redistribution and use in source and binary forms, with or without @@ -121,5 +122,5 @@ Files: debian/* Copyright: 2010, Jakub Wilk - 2011, Daniele Tricoli + 2011-2014 Daniele Tricoli License: Expat diff -Nru pdfminer-20110515+dfsg/debian/get-orig-source.sh pdfminer-20140328+dfsg/debian/get-orig-source.sh --- pdfminer-20110515+dfsg/debian/get-orig-source.sh 2011-03-05 17:30:51.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/get-orig-source.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -set -e -export TAR_OPTIONS="--owner root --group root --mode a+rX" -export GZIP="-9n" -pwd=$(pwd) -version="$1" -if [ -z "$version" ] -then - printf 'Usage: %s \n' "$0" - exit 1 -fi -cd "$(dirname "$0")/../" -tmpdir=$(mktemp -d get-orig-source.XXXXXX) -uscan --noconf --force-download --rename --download-version="$version" --destdir="$tmpdir" -cd "$tmpdir" -tar -xzf pdfminer_*.orig.tar.gz -rm *.tar.gz -# Remove test documents without source: -rm -Rf pdfminer-*/samples/nonfree/ -# Remove byte-compiled files -find pdfminer-* -name '*.py[co]' -delete -mv pdfminer-*/ "pdfminer-$version.orig" -tar -czf "$pwd/pdfminer_$version+dfsg.orig.tar.gz" pdfminer-*.orig/ -cd .. -rm -Rf "$tmpdir" - -# vim:ts=4 sw=4 et diff -Nru pdfminer-20110515+dfsg/debian/.git-dpm pdfminer-20140328+dfsg/debian/.git-dpm --- pdfminer-20110515+dfsg/debian/.git-dpm 1970-01-01 00:00:00.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/.git-dpm 2015-11-05 10:21:08.000000000 +0000 @@ -0,0 +1,11 @@ +# see git-dpm(1) from git-dpm package +d380a9fb3ab43c254f18c15849c4419392494ea3 +d380a9fb3ab43c254f18c15849c4419392494ea3 +bdc59684f56bcf06cd3c23aa214cbf3125b8fc48 +bdc59684f56bcf06cd3c23aa214cbf3125b8fc48 +pdfminer_20140328+dfsg.orig.tar.gz +921bdb7dfadf067676855af4492a469b462940ca +2031505 +debianTag="debian/%e%v" +patchedTag="patched/%e%v" +upstreamTag="upstream/%e%u" diff -Nru pdfminer-20110515+dfsg/debian/manpages/latin2ascii.1.xml pdfminer-20140328+dfsg/debian/manpages/latin2ascii.1.xml --- pdfminer-20110515+dfsg/debian/manpages/latin2ascii.1.xml 1970-01-01 00:00:00.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/manpages/latin2ascii.1.xml 2015-11-05 10:21:08.000000000 +0000 @@ -0,0 +1,63 @@ + + + + + PDFMiner Manual + latin2ascii + + + Daniele + Tricoli + Wrote this manual page for the Debian system. +
eriol@mornie.org
+
+ + Yusuke + Shinyama + Author of PDFMiner and its original HTML documentation. +
yusuke@cs.nyu.edu
+
+
+
+ + latin2ascii + 1 + + + latin2ascii + converts Latin-1 characters into ASCII + + + + latin2ascii + option + file + + + + Description + + latin2ascii converts Latin-1 characters into ASCII + using an in-house mapping table. + + + + Options + + + + + + Specifies input file codec. + + + + + + + See also + + pdf2txt1 + + +
diff -Nru pdfminer-20110515+dfsg/debian/patches/avoid-timestamped-gzip.patch pdfminer-20140328+dfsg/debian/patches/avoid-timestamped-gzip.patch --- pdfminer-20110515+dfsg/debian/patches/avoid-timestamped-gzip.patch 1970-01-01 00:00:00.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/patches/avoid-timestamped-gzip.patch 2015-11-05 10:21:08.000000000 +0000 @@ -0,0 +1,47 @@ +From d380a9fb3ab43c254f18c15849c4419392494ea3 Mon Sep 17 00:00:00 2001 +From: Daniele Tricoli +Date: Sun, 11 Oct 2015 20:35:02 +0200 +Subject: Avoid timestamps in gzip-compressed file and use + + compressionlevel=9 to reduce data size. +Forwarded: https://github.com/euske/pdfminer/pull/119 +Last-Update: 2015-08-17 + +Patch-Name: avoid-timestamped-gzip.patch +--- + tools/conv_cmap.py | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/tools/conv_cmap.py b/tools/conv_cmap.py +index f5b62cc..09557bf 100755 +--- a/tools/conv_cmap.py ++++ b/tools/conv_cmap.py +@@ -180,16 +180,22 @@ def main(argv): + fname = '%s.pickle.gz' % enc + path = os.path.join(outdir, fname) + print >>sys.stderr, 'writing: %r...' % path +- fp = gzip.open(path, 'wb') +- converter.dump_cmap(fp, enc) +- fp.close() ++ with open(path, 'wb') as fp: ++ # with statement support for GzipFile is available only from Python ++ # 2.7 ++ fgz = gzip.GzipFile('', 'wb', 9, fp, 0.) ++ converter.dump_cmap(fgz, enc) ++ fgz.close() + + fname = 'to-unicode-%s.pickle.gz' % regname + path = os.path.join(outdir, fname) + print >>sys.stderr, 'writing: %r...' % path +- fp = gzip.open(path, 'wb') +- converter.dump_unicodemap(fp) +- fp.close() ++ with open(path, 'wb') as fp: ++ # with statement support for GzipFile is available only from Python ++ # 2.7 ++ fgz = gzip.GzipFile('', 'wb', 9, fp, 0.) ++ converter.dump_unicodemap(fgz) ++ fgz.close() + return + + if __name__ == '__main__': sys.exit(main(sys.argv)) diff -Nru pdfminer-20110515+dfsg/debian/patches/pickle-protocol-2.diff pdfminer-20140328+dfsg/debian/patches/pickle-protocol-2.diff --- pdfminer-20110515+dfsg/debian/patches/pickle-protocol-2.diff 2010-08-29 09:43:44.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/patches/pickle-protocol-2.diff 2015-11-05 10:21:08.000000000 +0000 @@ -1,14 +1,32 @@ -Description: Use pickle protocol 2 for serializing data. -Author: Jakub Wilk +From 453e0d7c130f3dfbd88f301c3961319dca18116f Mon Sep 17 00:00:00 2001 +From: Jakub Wilk +Date: Sun, 11 Oct 2015 20:35:01 +0200 +Subject: Use pickle protocol 2 for serializing data. +Patch-Name: pickle-protocol-2.diff +--- + tools/conv_cmap.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/conv_cmap.py b/tools/conv_cmap.py +index 4e908bd..f5b62cc 100755 --- a/tools/conv_cmap.py +++ b/tools/conv_cmap.py -@@ -148,7 +148,7 @@ - CID2UNICHR_H=cid2unichr_h, - CID2UNICHR_V=cid2unichr_v, - ) -- fp.write(pickle.dumps(data)) -+ fp.write(pickle.dumps(data, protocol=2)) - fp.close() +@@ -135,7 +135,7 @@ class CMapConverter(object): + IS_VERTICAL=self.is_vertical.get(enc, False), + CODE2CID=self.code2cid.get(enc), + ) +- fp.write(pickle.dumps(data)) ++ fp.write(pickle.dumps(data, protocol=2)) + return + + def dump_unicodemap(self, fp): +@@ -143,7 +143,7 @@ class CMapConverter(object): + CID2UNICHR_H=self.cid2unichr_h, + CID2UNICHR_V=self.cid2unichr_v, + ) +- fp.write(pickle.dumps(data)) ++ fp.write(pickle.dumps(data, protocol=2)) + return - return 0 + # main diff -Nru pdfminer-20110515+dfsg/debian/patches/python2.diff pdfminer-20140328+dfsg/debian/patches/python2.diff --- pdfminer-20110515+dfsg/debian/patches/python2.diff 2010-12-27 22:19:36.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/patches/python2.diff 2015-11-05 10:21:08.000000000 +0000 @@ -1,7 +1,22 @@ -Description: Use ‘python’ rather than ‘python2’ binary. +From 405404af458d4e7ff59a39b49a7ec9b8d939f9b4 Mon Sep 17 00:00:00 2001 +From: Stefano Rivera +Date: Sun, 11 Oct 2015 20:35:00 +0200 +Subject: =?UTF-8?q?Use=20=E2=80=98python=E2=80=99=20rather=20than=20?= + =?UTF-8?q?=E2=80=98python2=E2=80=99=20binary.?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + Forwarded: no Last-Update: 2010-12-27 +Patch-Name: python2.diff +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index bf69a84..94d4827 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ diff -Nru pdfminer-20110515+dfsg/debian/patches/series pdfminer-20140328+dfsg/debian/patches/series --- pdfminer-20110515+dfsg/debian/patches/series 2010-12-27 22:19:36.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/patches/series 2015-11-05 10:21:08.000000000 +0000 @@ -1,2 +1,3 @@ python2.diff pickle-protocol-2.diff +avoid-timestamped-gzip.patch diff -Nru pdfminer-20110515+dfsg/debian/python-pdfminer.docs pdfminer-20140328+dfsg/debian/python-pdfminer.docs --- pdfminer-20110515+dfsg/debian/python-pdfminer.docs 2010-06-05 11:40:26.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/python-pdfminer.docs 2015-11-05 10:21:08.000000000 +0000 @@ -1,2 +1 @@ docs/*.html -README.txt diff -Nru pdfminer-20110515+dfsg/debian/python-pdfminer.install pdfminer-20140328+dfsg/debian/python-pdfminer.install --- pdfminer-20110515+dfsg/debian/python-pdfminer.install 2010-06-12 17:45:29.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/python-pdfminer.install 2015-11-05 10:21:08.000000000 +0000 @@ -1,5 +1,5 @@ /usr/bin/pdf2txt /usr/bin/dumppdf +/usr/bin/latin2ascii /usr/lib/python*/*-packages/pdfminer-*.egg-info /usr/lib/python*/*-packages/pdfminer/*.py -/usr/lib/python*/*-packages/pdfminer/cmap/*.py diff -Nru pdfminer-20110515+dfsg/debian/rules pdfminer-20140328+dfsg/debian/rules --- pdfminer-20110515+dfsg/debian/rules 2011-07-28 02:42:55.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/rules 2015-11-05 10:21:08.000000000 +0000 @@ -7,7 +7,6 @@ override_dh_auto_build: $(MAKE) cmap dh_auto_build - echo '#' > pdfminer/cmap/__init__.py .PHONY: override_dh_install override_dh_install: @@ -19,17 +18,22 @@ $(MAKE) -C debian/manpages/ dh_installman +# Disable tests inside samples directory since they are failing also +# upstream: +# https://github.com/euske/pdfminer/issues/115 .PHONY: override_dh_auto_test override_dh_auto_test: ifeq ($(filter nocheck,$(DEB_BUILD_OPTIONS)),) set -e -x; \ for python in $(shell pyversions -r); do \ $$python /usr/bin/nosetests --with-doctest --verbose pdfminer/*.py; \ - $(MAKE) -C samples clean; \ - $(MAKE) -C samples PYTHON=$$python CMP="diff -u" HTMLS_NONFREE= TEXTS_NONFREE= XMLS_NONFREE= test; \ done endif +.PHONY: get-orig-source +get-orig-source: + uscan --verbose --force-download --repack + .PHONY: override_dh_installchangelogs override_dh_installchangelogs: elinks -config-file /dev/null -dump -no-numbering -no-references docs/index.html \ @@ -37,10 +41,6 @@ > docs/changelog dh_installchangelogs docs/changelog -.PHONY: -get-orig-source: - sh -x $(here)/debian/get-orig-source.sh $(upstream_version) - .PHONY: build build-arch build-indep binary binary-arch binary-indep clean build build-arch build-indep binary binary-indep clean: dh $(@) --with python2 -Spython_distutils diff -Nru pdfminer-20110515+dfsg/debian/watch pdfminer-20140328+dfsg/debian/watch --- pdfminer-20110515+dfsg/debian/watch 2010-08-25 23:21:14.000000000 +0000 +++ pdfminer-20140328+dfsg/debian/watch 2015-11-05 10:21:08.000000000 +0000 @@ -1,4 +1,3 @@ version=3 - -opts=dversionmangle=s/\+dfsg// \ -http://pypi.python.org/packages/source/p/pdfminer/pdfminer-([0-9.]+(?:p[0-9.]+)?)[.]tar[.]gz +opts=uversionmangle=s/(rc|a|b|c)/~$1/,dversionmangle=s/\+dfsg\d*$//,repacksuffix=+dfsg \ +http://pypi.debian.net/pdfminer/pdfminer-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) diff -Nru pdfminer-20110515+dfsg/docs/index.html pdfminer-20140328+dfsg/docs/index.html --- pdfminer-20110515+dfsg/docs/index.html 2011-05-14 16:33:16.000000000 +0000 +++ pdfminer-20140328+dfsg/docs/index.html 2015-10-11 18:33:29.000000000 +0000 @@ -9,7 +9,7 @@
-Last Modified: Sat May 14 16:33:16 UTC 2011 +Last Modified: Fri Mar 28 09:17:06 UTC 2014
@@ -139,7 +139,7 @@ during installation:
 # make cmap
-python tools/conv_cmap.py pdfminer/cmap Adobe-CNS1 cmaprsrc/cid2code_Adobe_CNS1.txt cp950 big5
+python tools/conv_cmap.py pdfminer/cmap Adobe-CNS1 cmaprsrc/cid2code_Adobe_CNS1.txt
 reading 'cmaprsrc/cid2code_Adobe_CNS1.txt'...
 writing 'CNS1_H.py'...
 ...
@@ -152,10 +152,11 @@
 On Windows machines which don't have make command, 
 paste the following commands on a command line prompt:
 
-python tools\conv_cmap.py pdfminer\cmap Adobe-CNS1 cmaprsrc\cid2code_Adobe_CNS1.txt cp950 big5
-python tools\conv_cmap.py pdfminer\cmap Adobe-GB1 cmaprsrc\cid2code_Adobe_GB1.txt cp936 gb2312
-python tools\conv_cmap.py pdfminer\cmap Adobe-Japan1 cmaprsrc\cid2code_Adobe_Japan1.txt cp932 euc-jp
-python tools\conv_cmap.py pdfminer\cmap Adobe-Korea1 cmaprsrc\cid2code_Adobe_Korea1.txt cp949 euc-kr
+mkdir pdfminer\cmap
+python tools\conv_cmap.py -c B5=cp950 -c UniCNS-UTF8=utf-8 pdfminer\cmap Adobe-CNS1 cmaprsrc\cid2code_Adobe_CNS1.txt
+python tools\conv_cmap.py -c GBK-EUC=cp936 -c UniGB-UTF8=utf-8 pdfminer\cmap Adobe-GB1 cmaprsrc\cid2code_Adobe_GB1.txt
+python tools\conv_cmap.py -c RKSJ=cp932 -c EUC=euc-jp -c UniJIS-UTF8=utf-8 pdfminer\cmap Adobe-Japan1 cmaprsrc\cid2code_Adobe_Japan1.txt
+python tools\conv_cmap.py -c KSC-EUC=euc-kr -c KSC-Johab=johab -c KSCms-UHC=cp949 -c UniKS-UTF8=utf-8 pdfminer\cmap Adobe-Korea1 cmaprsrc\cid2code_Adobe_Korea1.txt
 python setup.py install
 
@@ -263,6 +264,12 @@ ↑

+

-F boxes_flow +
Specifies how much a horizontal and vertical position of a text matters +when determining a text order. The value should be within the range of +-1.0 (only horizontal position matters) to +1.0 (only vertical position matters). +The default value is 0.5. +

-C
Suppress object caching. This will reduce the memory consumption but also slows down the process. @@ -285,6 +292,9 @@
  • loose : preserve the overall location of each text block.

    +

    -E extractdir +
    Specifies the extraction directory of embedded files. +

    -s scale
    Specifies the output scale. Can be used in HTML format only.

    @@ -352,6 +362,9 @@

    -T
    Shows the table of contents.

    +

    -E directory +
    Extracts embedded files from the pdf into the given directory. +

    -P password
    Provides the user password to access PDF contents.

    @@ -361,12 +374,32 @@

    Changes

      -
    • 2010/05/15: Speed improvements for layout analysis. -
    • 2010/05/15: API changes. LTText.get_text() is added. -
    • 2010/04/20: API changes. LTPolygon class was renamed as LTCurve. -
    • 2010/04/20: LTLine now represents horizontal/vertical lines only. Thanks to Koji Nakagawa. -
    • 2010/03/07: Documentation improvements by Jakub Wilk. Memory usage patch by Jonathan Hunt. -
    • 2010/02/27: Bugfixes and layout analysis improvements. Thanks to fujimoto.report. +
    • 2014/03/28: Further bugfixes. +
    • 2014/03/24: Bugfixes and improvements for fauly PDFs.
      +API changes: +
        +
      • PDFDocument.initialize() method is removed and no longer needed. + A password is given as an argument of a PDFDocument constructor. +
      +
    • 2013/11/13: Bugfixes and minor improvements.
      +As of November 2013, there were a few changes made to the PDFMiner API +prior to October 2013. This is the result of code restructuring. Here +is a list of the changes: +
        +
      • PDFDocument class is moved to pdfdocument.py. +
      • PDFDocument class now takes a PDFParser object as an argument. +
      • PDFDocument.set_parser() and PDFParser.set_document() is removed. +
      • PDFPage class is moved to pdfpage.py. +
      • process_pdf function is implemented as PDFPage.get_pages. +
      +
    • 2013/10/22: Sudden resurge of interests. API changes. +Incorporated a lot of patches and robust handling of broken PDFs. +
    • 2011/05/15: Speed improvements for layout analysis. +
    • 2011/05/15: API changes. LTText.get_text() is added. +
    • 2011/04/20: API changes. LTPolygon class was renamed as LTCurve. +
    • 2011/04/20: LTLine now represents horizontal/vertical lines only. Thanks to Koji Nakagawa. +
    • 2011/03/07: Documentation improvements by Jakub Wilk. Memory usage patch by Jonathan Hunt. +
    • 2011/02/27: Bugfixes and layout analysis improvements. Thanks to fujimoto.report.
    • 2010/12/26: A couple of bugfixes and minor improvements. Thanks to Kevin Brubeck Unhammer and Daniel Gerber.
    • 2010/10/17: A couple of bugfixes and minor improvements. Thanks to standardabweichung and Alastair Irving.
    • 2010/09/07: A minor bugfix. Thanks to Alexander Garden. @@ -423,9 +456,7 @@ PEP-257 conformance.
    • Better documentation.
    • Better text extraction / layout analysis. (writing mode detection, Type1 font file analysis, etc.) -
    • Robust error handling.
    • Crypt stream filter support. (More sample documents are needed!) -
    • CCITTFax stream filter support.

    Related Projects

    @@ -441,7 +472,7 @@ (This is so-called MIT/X License)

    -Copyright (c) 2004-2010 Yusuke Shinyama <yusuke at cs dot nyu dot edu> +Copyright (c) 2004-2013 Yusuke Shinyama <yusuke at cs dot nyu dot edu>

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff -Nru pdfminer-20110515+dfsg/docs/programming.html pdfminer-20140328+dfsg/docs/programming.html --- pdfminer-20110515+dfsg/docs/programming.html 2011-05-14 16:36:12.000000000 +0000 +++ pdfminer-20140328+dfsg/docs/programming.html 2015-10-11 18:33:29.000000000 +0000 @@ -9,7 +9,7 @@

    -Last Modified: Sat May 14 16:36:12 UTC 2011 +Last Modified: Mon Mar 24 11:49:28 UTC 2014
    @@ -23,9 +23,9 @@

    Overview

    @@ -75,8 +75,12 @@

    A typical way to parse a PDF file is the following:

    -from pdfminer.pdfparser import PDFParser, PDFDocument
    -from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
    +from pdfminer.pdfparser import PDFParser
    +from pdfminer.pdfdocument import PDFDocument
    +from pdfminer.pdfpage import PDFPage
    +from pdfminer.pdfpage import PDFTextExtractionNotAllowed
    +from pdfminer.pdfinterp import PDFResourceManager
    +from pdfminer.pdfinterp import PDFPageInterpreter
     from pdfminer.pdfdevice import PDFDevice
     
     # Open a PDF file.
    @@ -84,15 +88,10 @@
     # Create a PDF parser object associated with the file object.
     parser = PDFParser(fp)
     # Create a PDF document object that stores the document structure.
    -doc = PDFDocument()
    -# Connect the parser and document objects.
    -parser.set_document(doc)
    -doc.set_parser(parser)
     # Supply the password for initialization.
    -# (If no password is set, give an empty string.)
    -doc.initialize(password)
    +document = PDFDocument(parser, password)
     # Check if the document allows text extraction. If not, abort.
    -if not doc.is_extractable:
    +if not document.is_extractable:
         raise PDFTextExtractionNotAllowed
     # Create a PDF resource manager object that stores shared resources.
     rsrcmgr = PDFResourceManager()
    @@ -101,11 +100,11 @@
     # Create a PDF interpreter object.
     interpreter = PDFPageInterpreter(rsrcmgr, device)
     # Process each page contained in the document.
    -for page in doc.get_pages():
    +for page in PDFPage.create_pages(document):
         interpreter.process_page(page)
     
    -

    Accessing Layout Objects

    +

    Performing Layout Analysis

    Here is a typical way to use the layout analysis function:

    @@ -117,15 +116,15 @@
     # Create a PDF page aggregator object.
     device = PDFPageAggregator(rsrcmgr, laparams=laparams)
     interpreter = PDFPageInterpreter(rsrcmgr, device)
    -for page in doc.get_pages():
    +for page in PDFPage.create_pages(document):
         interpreter.process_page(page)
         # receive the LTPage object for the page.
         layout = device.get_result()
     
    -The layout analyzer gives a "LTPage" object for each page -in the PDF document. The object contains child objects within the page, -forming a tree-like structure. Figure 2 shows the relationship between +A layout analyzer returns a LTPage object for each page +in the PDF document. This object contains child objects within the page, +forming a tree structure. Figure 2 shows the relationship between these objects.
    @@ -153,10 +152,10 @@ get_text() method returns the text content.
    LTChar -
    LTAnon +
    LTAnno
    Represent an actual letter in the text as a Unicode string. Note that, while a LTChar object has actual boundaries, -LTAnon objects does not, as these are "virtual" characters, +LTAnno objects does not, as these are "virtual" characters, inserted by a layout analyzer according to the relationship between two characters (e.g. a space). @@ -179,29 +178,28 @@ Could be used for framing another pictures or figures.
    LTCurve -
    Represents a generic bezier curve. +
    Represents a generic Bezier curve.

    Also, check out a more complete example by Denis Papathanasiou. -

    TOC Extraction

    +

    Obtaining Table of Contents

    PDFMiner provides functions to access the document's table of contents ("Outlines").

    -from pdfminer.pdfparser import PDFParser, PDFDocument
    +from pdfminer.pdfparser import PDFParser
    +from pdfminer.pdfdocument import PDFDocument
     
    +# Open a PDF document.
     fp = open('mypdf.pdf', 'rb')
     parser = PDFParser(fp)
    -doc = PDFDocument()
    -parser.set_document(doc)
    -doc.set_parser(parser)
    -doc.initialize(password)
    +document = PDFDocument(parser, password)
     
     # Get the outlines of the document.
    -outlines = doc.get_outlines()
    +outlines = document.get_outlines()
     for (level,title,dest,a,se) in outlines:
         print (level, title)
     
    @@ -209,12 +207,12 @@

    Some PDF documents use page numbers as destinations, while others use page numbers and the physical location within the page. Since -PDF does not have a logical strucutre, and it does not provide a +PDF does not have a logical structure, and it does not provide a way to refer to any in-page object from the outside, there's no way to tell exactly which part of text these destinations are -refering to. +referring to. -

    Parser Extension

    +

    Extending Functionality

    You can extend PDFPageInterpreter and PDFDevice class diff -Nru pdfminer-20110515+dfsg/docs/style.css pdfminer-20140328+dfsg/docs/style.css --- pdfminer-20110515+dfsg/docs/style.css 2010-10-17 09:14:31.000000000 +0000 +++ pdfminer-20140328+dfsg/docs/style.css 2015-10-11 18:33:29.000000000 +0000 @@ -1,3 +1,4 @@ blockquote { background: #eeeeee; } h1 { border-bottom: solid black 2px; } h2 { border-bottom: solid black 1px; } +.comment { color: darkgreen; } diff -Nru pdfminer-20110515+dfsg/Makefile pdfminer-20140328+dfsg/Makefile --- pdfminer-20110515+dfsg/Makefile 2011-02-27 10:41:09.000000000 +0000 +++ pdfminer-20140328+dfsg/Makefile 2015-10-11 18:33:29.000000000 +0000 @@ -7,6 +7,7 @@ GIT=git RM=rm -f CP=cp -f +MKDIR=mkdir all: @@ -26,7 +27,7 @@ register: distclean MANIFEST.in $(PYTHON) setup.py sdist upload register -WEBDIR=$$HOME/Site/unixuser.org/python/$(PACKAGE) +WEBDIR=../euske.github.io/$(PACKAGE) publish: $(CP) docs/*.html docs/*.png docs/*.css $(WEBDIR) @@ -36,15 +37,21 @@ cmap: $(CMAPDST)/to-unicode-Adobe-CNS1.pickle.gz $(CMAPDST)/to-unicode-Adobe-GB1.pickle.gz \ $(CMAPDST)/to-unicode-Adobe-Japan1.pickle.gz $(CMAPDST)/to-unicode-Adobe-Korea1.pickle.gz cmap_clean: - cd $(CMAPDST) && make cmap_clean -$(CMAPDST)/to-unicode-Adobe-CNS1.pickle.gz: - $(CONV_CMAP) $(CMAPDST) Adobe-CNS1 $(CMAPSRC)/cid2code_Adobe_CNS1.txt cp950 big5 -$(CMAPDST)/to-unicode-Adobe-GB1.pickle.gz: - $(CONV_CMAP) $(CMAPDST) Adobe-GB1 $(CMAPSRC)/cid2code_Adobe_GB1.txt cp936 gb2312 -$(CMAPDST)/to-unicode-Adobe-Japan1.pickle.gz: - $(CONV_CMAP) $(CMAPDST) Adobe-Japan1 $(CMAPSRC)/cid2code_Adobe_Japan1.txt cp932 euc-jp -$(CMAPDST)/to-unicode-Adobe-Korea1.pickle.gz: - $(CONV_CMAP) $(CMAPDST) Adobe-Korea1 $(CMAPSRC)/cid2code_Adobe_Korea1.txt cp949 euc-kr + -$(RM) -r $(CMAPDST) +$(CMAPDST): + $(MKDIR) $(CMAPDST) +$(CMAPDST)/to-unicode-Adobe-CNS1.pickle.gz: $(CMAPDST) + $(CONV_CMAP) -c B5=cp950 -c UniCNS-UTF8=utf-8 \ + $(CMAPDST) Adobe-CNS1 $(CMAPSRC)/cid2code_Adobe_CNS1.txt +$(CMAPDST)/to-unicode-Adobe-GB1.pickle.gz: $(CMAPDST) + $(CONV_CMAP) -c GBK-EUC=cp936 -c UniGB-UTF8=utf-8 \ + $(CMAPDST) Adobe-GB1 $(CMAPSRC)/cid2code_Adobe_GB1.txt +$(CMAPDST)/to-unicode-Adobe-Japan1.pickle.gz: $(CMAPDST) + $(CONV_CMAP) -c RKSJ=cp932 -c EUC=euc-jp -c UniJIS-UTF8=utf-8 \ + $(CMAPDST) Adobe-Japan1 $(CMAPSRC)/cid2code_Adobe_Japan1.txt +$(CMAPDST)/to-unicode-Adobe-Korea1.pickle.gz: $(CMAPDST) + $(CONV_CMAP) -c KSC-EUC=euc-kr -c KSC-Johab=johab -c KSCms-UHC=cp949 -c UniKS-UTF8=utf-8 \ + $(CMAPDST) Adobe-Korea1 $(CMAPSRC)/cid2code_Adobe_Korea1.txt test: cmap cd samples && $(MAKE) test diff -Nru pdfminer-20110515+dfsg/pdfminer/arcfour.py pdfminer-20140328+dfsg/pdfminer/arcfour.py --- pdfminer-20110515+dfsg/pdfminer/arcfour.py 2010-10-19 09:55:22.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/arcfour.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Python implementation of Arcfour encryption algorithm. @@ -6,6 +6,7 @@ """ + ## Arcfour ## class Arcfour(object): diff -Nru pdfminer-20110515+dfsg/pdfminer/ascii85.py pdfminer-20140328+dfsg/pdfminer/ascii85.py --- pdfminer-20110515+dfsg/pdfminer/ascii85.py 2010-10-19 09:55:23.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/ascii85.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Python implementation of ASCII85/ASCIIHex decoder (Adobe version). @@ -9,6 +9,7 @@ import re import struct + # ascii85decode(data) def ascii85decode(data): """ @@ -16,13 +17,13 @@ letters, using 85 different types of characters (as 256**4 < 85**5). When the length of the original bytes is not a multiple of 4, a special rule is used for round up. - + The Adobe's ASCII85 implementation is slightly different from its original in handling the last characters. - + The sample string is taken from: http://en.wikipedia.org/w/index.php?title=Ascii85 - + >>> ascii85decode('9jqo^BlbD-BleB1DJ+*+F(f,q') 'Man is distinguished' >>> ascii85decode('E,9)oF*2M7/c~>') @@ -35,7 +36,7 @@ n += 1 b = b*85+(ord(c)-33) if n == 5: - out += struct.pack('>L',b) + out += struct.pack('>L', b) n = b = 0 elif c == 'z': assert n == 0 @@ -44,13 +45,15 @@ if n: for _ in range(5-n): b = b*85+84 - out += struct.pack('>L',b)[:n-1] + out += struct.pack('>L', b)[:n-1] break return out # asciihexdecode(data) hex_re = re.compile(r'([a-f\d]{2})', re.IGNORECASE) trail_re = re.compile(r'^(?:[a-f\d]{2}|\s)*([a-f\d])[\s>]*$', re.IGNORECASE) + + def asciihexdecode(data): """ ASCIIHexDecode filter: PDFReference v1.4 section 3.3.1 @@ -60,7 +63,7 @@ EOD. Any other characters will cause an error. If the filter encounters the EOD marker after reading an odd number of hexadecimal digits, it will behave as if a 0 followed the last digit. - + >>> asciihexdecode('61 62 2e6364 65') 'ab.cde' >>> asciihexdecode('61 62 2e6364 657>') diff -Nru pdfminer-20110515+dfsg/pdfminer/ccitt.py pdfminer-20140328+dfsg/pdfminer/ccitt.py --- pdfminer-20110515+dfsg/pdfminer/ccitt.py 1970-01-01 00:00:00.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/ccitt.py 2015-10-11 18:33:29.000000000 +0000 @@ -0,0 +1,757 @@ +#!/usr/bin/env python +# CCITT Fax decoder +# +# Bugs: uncompressed mode untested. +# +# cf. +# ITU-T Recommendation T.4 +# "Standardization of Group 3 facsimile terminals for document transmission" +# ITU-T Recommendation T.6 +# "FACSIMILE CODING SCHEMES AND CODING CONTROL FUNCTIONS FOR GROUP 4 FACSIMILE APPARATUS" + + +import sys +import array + + +## BitParser +## +class BitParser(object): + + def __init__(self): + self._pos = 0 + return + + @classmethod + def add(klass, root, v, bits): + p = root + b = None + for i in xrange(len(bits)): + if 0 < i: + if p[b] is None: + p[b] = [None, None] + p = p[b] + if bits[i] == '1': + b = 1 + else: + b = 0 + p[b] = v + return + + def feedbytes(self, data): + for c in data: + b = ord(c) + for m in (128, 64, 32, 16, 8, 4, 2, 1): + self._parse_bit(b & m) + return + + def _parse_bit(self, x): + if x: + v = self._state[1] + else: + v = self._state[0] + self._pos += 1 + if isinstance(v, list): + self._state = v + else: + self._state = self._accept(v) + return + + +## CCITTG4Parser +## +class CCITTG4Parser(BitParser): + + MODE = [None, None] + BitParser.add(MODE, 0, '1') + BitParser.add(MODE, +1, '011') + BitParser.add(MODE, -1, '010') + BitParser.add(MODE, 'h', '001') + BitParser.add(MODE, 'p', '0001') + BitParser.add(MODE, +2, '000011') + BitParser.add(MODE, -2, '000010') + BitParser.add(MODE, +3, '0000011') + BitParser.add(MODE, -3, '0000010') + BitParser.add(MODE, 'u', '0000001111') + BitParser.add(MODE, 'x1', '0000001000') + BitParser.add(MODE, 'x2', '0000001001') + BitParser.add(MODE, 'x3', '0000001010') + BitParser.add(MODE, 'x4', '0000001011') + BitParser.add(MODE, 'x5', '0000001100') + BitParser.add(MODE, 'x6', '0000001101') + BitParser.add(MODE, 'x7', '0000001110') + BitParser.add(MODE, 'e', '000000000001000000000001') + + WHITE = [None, None] + BitParser.add(WHITE, 0 , '00110101') + BitParser.add(WHITE, 1 , '000111') + BitParser.add(WHITE, 2 , '0111') + BitParser.add(WHITE, 3 , '1000') + BitParser.add(WHITE, 4 , '1011') + BitParser.add(WHITE, 5 , '1100') + BitParser.add(WHITE, 6 , '1110') + BitParser.add(WHITE, 7 , '1111') + BitParser.add(WHITE, 8 , '10011') + BitParser.add(WHITE, 9 , '10100') + BitParser.add(WHITE, 10 , '00111') + BitParser.add(WHITE, 11 , '01000') + BitParser.add(WHITE, 12 , '001000') + BitParser.add(WHITE, 13 , '000011') + BitParser.add(WHITE, 14 , '110100') + BitParser.add(WHITE, 15 , '110101') + BitParser.add(WHITE, 16 , '101010') + BitParser.add(WHITE, 17 , '101011') + BitParser.add(WHITE, 18 , '0100111') + BitParser.add(WHITE, 19 , '0001100') + BitParser.add(WHITE, 20 , '0001000') + BitParser.add(WHITE, 21 , '0010111') + BitParser.add(WHITE, 22 , '0000011') + BitParser.add(WHITE, 23 , '0000100') + BitParser.add(WHITE, 24 , '0101000') + BitParser.add(WHITE, 25 , '0101011') + BitParser.add(WHITE, 26 , '0010011') + BitParser.add(WHITE, 27 , '0100100') + BitParser.add(WHITE, 28 , '0011000') + BitParser.add(WHITE, 29 , '00000010') + BitParser.add(WHITE, 30 , '00000011') + BitParser.add(WHITE, 31 , '00011010') + BitParser.add(WHITE, 32 , '00011011') + BitParser.add(WHITE, 33 , '00010010') + BitParser.add(WHITE, 34 , '00010011') + BitParser.add(WHITE, 35 , '00010100') + BitParser.add(WHITE, 36 , '00010101') + BitParser.add(WHITE, 37 , '00010110') + BitParser.add(WHITE, 38 , '00010111') + BitParser.add(WHITE, 39 , '00101000') + BitParser.add(WHITE, 40 , '00101001') + BitParser.add(WHITE, 41 , '00101010') + BitParser.add(WHITE, 42 , '00101011') + BitParser.add(WHITE, 43 , '00101100') + BitParser.add(WHITE, 44 , '00101101') + BitParser.add(WHITE, 45 , '00000100') + BitParser.add(WHITE, 46 , '00000101') + BitParser.add(WHITE, 47 , '00001010') + BitParser.add(WHITE, 48 , '00001011') + BitParser.add(WHITE, 49 , '01010010') + BitParser.add(WHITE, 50 , '01010011') + BitParser.add(WHITE, 51 , '01010100') + BitParser.add(WHITE, 52 , '01010101') + BitParser.add(WHITE, 53 , '00100100') + BitParser.add(WHITE, 54 , '00100101') + BitParser.add(WHITE, 55 , '01011000') + BitParser.add(WHITE, 56 , '01011001') + BitParser.add(WHITE, 57 , '01011010') + BitParser.add(WHITE, 58 , '01011011') + BitParser.add(WHITE, 59 , '01001010') + BitParser.add(WHITE, 60 , '01001011') + BitParser.add(WHITE, 61 , '00110010') + BitParser.add(WHITE, 62 , '00110011') + BitParser.add(WHITE, 63 , '00110100') + BitParser.add(WHITE, 64 , '11011') + BitParser.add(WHITE, 128 , '10010') + BitParser.add(WHITE, 192 , '010111') + BitParser.add(WHITE, 256 , '0110111') + BitParser.add(WHITE, 320 , '00110110') + BitParser.add(WHITE, 384 , '00110111') + BitParser.add(WHITE, 448 , '01100100') + BitParser.add(WHITE, 512 , '01100101') + BitParser.add(WHITE, 576 , '01101000') + BitParser.add(WHITE, 640 , '01100111') + BitParser.add(WHITE, 704 , '011001100') + BitParser.add(WHITE, 768 , '011001101') + BitParser.add(WHITE, 832 , '011010010') + BitParser.add(WHITE, 896 , '011010011') + BitParser.add(WHITE, 960 , '011010100') + BitParser.add(WHITE, 1024, '011010101') + BitParser.add(WHITE, 1088, '011010110') + BitParser.add(WHITE, 1152, '011010111') + BitParser.add(WHITE, 1216, '011011000') + BitParser.add(WHITE, 1280, '011011001') + BitParser.add(WHITE, 1344, '011011010') + BitParser.add(WHITE, 1408, '011011011') + BitParser.add(WHITE, 1472, '010011000') + BitParser.add(WHITE, 1536, '010011001') + BitParser.add(WHITE, 1600, '010011010') + BitParser.add(WHITE, 1664, '011000') + BitParser.add(WHITE, 1728, '010011011') + BitParser.add(WHITE, 1792, '00000001000') + BitParser.add(WHITE, 1856, '00000001100') + BitParser.add(WHITE, 1920, '00000001101') + BitParser.add(WHITE, 1984, '000000010010') + BitParser.add(WHITE, 2048, '000000010011') + BitParser.add(WHITE, 2112, '000000010100') + BitParser.add(WHITE, 2176, '000000010101') + BitParser.add(WHITE, 2240, '000000010110') + BitParser.add(WHITE, 2304, '000000010111') + BitParser.add(WHITE, 2368, '000000011100') + BitParser.add(WHITE, 2432, '000000011101') + BitParser.add(WHITE, 2496, '000000011110') + BitParser.add(WHITE, 2560, '000000011111') + + BLACK = [None, None] + BitParser.add(BLACK, 0 , '0000110111') + BitParser.add(BLACK, 1 , '010') + BitParser.add(BLACK, 2 , '11') + BitParser.add(BLACK, 3 , '10') + BitParser.add(BLACK, 4 , '011') + BitParser.add(BLACK, 5 , '0011') + BitParser.add(BLACK, 6 , '0010') + BitParser.add(BLACK, 7 , '00011') + BitParser.add(BLACK, 8 , '000101') + BitParser.add(BLACK, 9 , '000100') + BitParser.add(BLACK, 10 , '0000100') + BitParser.add(BLACK, 11 , '0000101') + BitParser.add(BLACK, 12 , '0000111') + BitParser.add(BLACK, 13 , '00000100') + BitParser.add(BLACK, 14 , '00000111') + BitParser.add(BLACK, 15 , '000011000') + BitParser.add(BLACK, 16 , '0000010111') + BitParser.add(BLACK, 17 , '0000011000') + BitParser.add(BLACK, 18 , '0000001000') + BitParser.add(BLACK, 19 , '00001100111') + BitParser.add(BLACK, 20 , '00001101000') + BitParser.add(BLACK, 21 , '00001101100') + BitParser.add(BLACK, 22 , '00000110111') + BitParser.add(BLACK, 23 , '00000101000') + BitParser.add(BLACK, 24 , '00000010111') + BitParser.add(BLACK, 25 , '00000011000') + BitParser.add(BLACK, 26 , '000011001010') + BitParser.add(BLACK, 27 , '000011001011') + BitParser.add(BLACK, 28 , '000011001100') + BitParser.add(BLACK, 29 , '000011001101') + BitParser.add(BLACK, 30 , '000001101000') + BitParser.add(BLACK, 31 , '000001101001') + BitParser.add(BLACK, 32 , '000001101010') + BitParser.add(BLACK, 33 , '000001101011') + BitParser.add(BLACK, 34 , '000011010010') + BitParser.add(BLACK, 35 , '000011010011') + BitParser.add(BLACK, 36 , '000011010100') + BitParser.add(BLACK, 37 , '000011010101') + BitParser.add(BLACK, 38 , '000011010110') + BitParser.add(BLACK, 39 , '000011010111') + BitParser.add(BLACK, 40 , '000001101100') + BitParser.add(BLACK, 41 , '000001101101') + BitParser.add(BLACK, 42 , '000011011010') + BitParser.add(BLACK, 43 , '000011011011') + BitParser.add(BLACK, 44 , '000001010100') + BitParser.add(BLACK, 45 , '000001010101') + BitParser.add(BLACK, 46 , '000001010110') + BitParser.add(BLACK, 47 , '000001010111') + BitParser.add(BLACK, 48 , '000001100100') + BitParser.add(BLACK, 49 , '000001100101') + BitParser.add(BLACK, 50 , '000001010010') + BitParser.add(BLACK, 51 , '000001010011') + BitParser.add(BLACK, 52 , '000000100100') + BitParser.add(BLACK, 53 , '000000110111') + BitParser.add(BLACK, 54 , '000000111000') + BitParser.add(BLACK, 55 , '000000100111') + BitParser.add(BLACK, 56 , '000000101000') + BitParser.add(BLACK, 57 , '000001011000') + BitParser.add(BLACK, 58 , '000001011001') + BitParser.add(BLACK, 59 , '000000101011') + BitParser.add(BLACK, 60 , '000000101100') + BitParser.add(BLACK, 61 , '000001011010') + BitParser.add(BLACK, 62 , '000001100110') + BitParser.add(BLACK, 63 , '000001100111') + BitParser.add(BLACK, 64 , '0000001111') + BitParser.add(BLACK, 128 , '000011001000') + BitParser.add(BLACK, 192 , '000011001001') + BitParser.add(BLACK, 256 , '000001011011') + BitParser.add(BLACK, 320 , '000000110011') + BitParser.add(BLACK, 384 , '000000110100') + BitParser.add(BLACK, 448 , '000000110101') + BitParser.add(BLACK, 512 , '0000001101100') + BitParser.add(BLACK, 576 , '0000001101101') + BitParser.add(BLACK, 640 , '0000001001010') + BitParser.add(BLACK, 704 , '0000001001011') + BitParser.add(BLACK, 768 , '0000001001100') + BitParser.add(BLACK, 832 , '0000001001101') + BitParser.add(BLACK, 896 , '0000001110010') + BitParser.add(BLACK, 960 , '0000001110011') + BitParser.add(BLACK, 1024, '0000001110100') + BitParser.add(BLACK, 1088, '0000001110101') + BitParser.add(BLACK, 1152, '0000001110110') + BitParser.add(BLACK, 1216, '0000001110111') + BitParser.add(BLACK, 1280, '0000001010010') + BitParser.add(BLACK, 1344, '0000001010011') + BitParser.add(BLACK, 1408, '0000001010100') + BitParser.add(BLACK, 1472, '0000001010101') + BitParser.add(BLACK, 1536, '0000001011010') + BitParser.add(BLACK, 1600, '0000001011011') + BitParser.add(BLACK, 1664, '0000001100100') + BitParser.add(BLACK, 1728, '0000001100101') + BitParser.add(BLACK, 1792, '00000001000') + BitParser.add(BLACK, 1856, '00000001100') + BitParser.add(BLACK, 1920, '00000001101') + BitParser.add(BLACK, 1984, '000000010010') + BitParser.add(BLACK, 2048, '000000010011') + BitParser.add(BLACK, 2112, '000000010100') + BitParser.add(BLACK, 2176, '000000010101') + BitParser.add(BLACK, 2240, '000000010110') + BitParser.add(BLACK, 2304, '000000010111') + BitParser.add(BLACK, 2368, '000000011100') + BitParser.add(BLACK, 2432, '000000011101') + BitParser.add(BLACK, 2496, '000000011110') + BitParser.add(BLACK, 2560, '000000011111') + + UNCOMPRESSED = [None, None] + BitParser.add(UNCOMPRESSED, '1', '1') + BitParser.add(UNCOMPRESSED, '01', '01') + BitParser.add(UNCOMPRESSED, '001', '001') + BitParser.add(UNCOMPRESSED, '0001', '0001') + BitParser.add(UNCOMPRESSED, '00001', '00001') + BitParser.add(UNCOMPRESSED, '00000', '000001') + BitParser.add(UNCOMPRESSED, 'T00', '00000011') + BitParser.add(UNCOMPRESSED, 'T10', '00000010') + BitParser.add(UNCOMPRESSED, 'T000', '000000011') + BitParser.add(UNCOMPRESSED, 'T100', '000000010') + BitParser.add(UNCOMPRESSED, 'T0000', '0000000011') + BitParser.add(UNCOMPRESSED, 'T1000', '0000000010') + BitParser.add(UNCOMPRESSED, 'T00000', '00000000011') + BitParser.add(UNCOMPRESSED, 'T10000', '00000000010') + + class EOFB(Exception): + pass + + class InvalidData(Exception): + pass + + class ByteSkip(Exception): + pass + + def __init__(self, width, bytealign=False): + BitParser.__init__(self) + self.width = width + self.bytealign = bytealign + self.reset() + return + + def feedbytes(self, data): + for c in data: + b = ord(c) + try: + for m in (128, 64, 32, 16, 8, 4, 2, 1): + self._parse_bit(b & m) + except self.ByteSkip: + self._accept = self._parse_mode + self._state = self.MODE + except self.EOFB: + break + return + + def _parse_mode(self, mode): + if mode == 'p': + self._do_pass() + self._flush_line() + return self.MODE + elif mode == 'h': + self._n1 = 0 + self._accept = self._parse_horiz1 + if self._color: + return self.WHITE + else: + return self.BLACK + elif mode == 'u': + self._accept = self._parse_uncompressed + return self.UNCOMPRESSED + elif mode == 'e': + raise self.EOFB + elif isinstance(mode, int): + self._do_vertical(mode) + self._flush_line() + return self.MODE + else: + raise self.InvalidData(mode) + + def _parse_horiz1(self, n): + if n is None: + raise self.InvalidData + self._n1 += n + if n < 64: + self._n2 = 0 + self._color = 1-self._color + self._accept = self._parse_horiz2 + if self._color: + return self.WHITE + else: + return self.BLACK + + def _parse_horiz2(self, n): + if n is None: + raise self.InvalidData + self._n2 += n + if n < 64: + self._color = 1-self._color + self._accept = self._parse_mode + self._do_horizontal(self._n1, self._n2) + self._flush_line() + return self.MODE + elif self._color: + return self.WHITE + else: + return self.BLACK + + def _parse_uncompressed(self, bits): + if not bits: + raise self.InvalidData + if bits.startswith('T'): + self._accept = self._parse_mode + self._color = int(bits[1]) + self._do_uncompressed(bits[2:]) + return self.MODE + else: + self._do_uncompressed(bits) + return self.UNCOMPRESSED + + def _get_bits(self): + return ''.join(str(b) for b in self._curline[:self._curpos]) + + def _get_refline(self, i): + if i < 0: + return '[]'+''.join(str(b) for b in self._refline) + elif len(self._refline) <= i: + return ''.join(str(b) for b in self._refline)+'[]' + else: + return (''.join(str(b) for b in self._refline[:i]) + + '['+str(self._refline[i])+']' + + ''.join(str(b) for b in self._refline[i+1:])) + + def reset(self): + self._y = 0 + self._curline = array.array('b', [1]*self.width) + self._reset_line() + self._accept = self._parse_mode + self._state = self.MODE + return + + def output_line(self, y, bits): + print y, ''.join(str(b) for b in bits) + return + + def _reset_line(self): + self._refline = self._curline + self._curline = array.array('b', [1]*self.width) + self._curpos = -1 + self._color = 1 + return + + def _flush_line(self): + if self.width <= self._curpos: + self.output_line(self._y, self._curline) + self._y += 1 + self._reset_line() + if self.bytealign: + raise self.ByteSkip + return + + def _do_vertical(self, dx): + #print '* vertical(%d): curpos=%r, color=%r' % (dx, self._curpos, self._color) + #print ' refline:', self._get_refline(self._curpos+1) + x1 = self._curpos+1 + while 1: + if x1 == 0: + if (self._color == 1 and self._refline[x1] != self._color): + break + elif x1 == len(self._refline): + break + elif (self._refline[x1-1] == self._color and + self._refline[x1] != self._color): + break + x1 += 1 + x1 += dx + x0 = max(0, self._curpos) + x1 = max(0, min(self.width, x1)) + if x1 < x0: + for x in xrange(x1, x0): + self._curline[x] = self._color + elif x0 < x1: + for x in xrange(x0, x1): + self._curline[x] = self._color + self._curpos = x1 + self._color = 1-self._color + return + + def _do_pass(self): + #print '* pass: curpos=%r, color=%r' % (self._curpos, self._color) + #print ' refline:', self._get_refline(self._curpos+1) + x1 = self._curpos+1 + while 1: + if x1 == 0: + if (self._color == 1 and self._refline[x1] != self._color): + break + elif x1 == len(self._refline): + break + elif (self._refline[x1-1] == self._color and + self._refline[x1] != self._color): + break + x1 += 1 + while 1: + if x1 == 0: + if (self._color == 0 and self._refline[x1] == self._color): + break + elif x1 == len(self._refline): + break + elif (self._refline[x1-1] != self._color and + self._refline[x1] == self._color): + break + x1 += 1 + for x in xrange(self._curpos, x1): + self._curline[x] = self._color + self._curpos = x1 + return + + def _do_horizontal(self, n1, n2): + #print '* horizontal(%d,%d): curpos=%r, color=%r' % (n1, n2, self._curpos, self._color) + if self._curpos < 0: + self._curpos = 0 + x = self._curpos + for _ in xrange(n1): + if len(self._curline) <= x: + break + self._curline[x] = self._color + x += 1 + for _ in xrange(n2): + if len(self._curline) <= x: + break + self._curline[x] = 1-self._color + x += 1 + self._curpos = x + return + + def _do_uncompressed(self, bits): + #print '* uncompressed(%r): curpos=%r' % (bits, self._curpos) + for c in bits: + self._curline[self._curpos] = int(c) + self._curpos += 1 + self._flush_line() + return + +import unittest + + +## Test cases +## +class TestCCITTG4Parser(unittest.TestCase): + + def get_parser(self, bits): + parser = CCITTG4Parser(len(bits)) + parser._curline = [int(c) for c in bits] + parser._reset_line() + return parser + + def test_b1(self): + parser = self.get_parser('00000') + parser._do_vertical(0) + self.assertEqual(parser._curpos, 0) + return + + def test_b2(self): + parser = self.get_parser('10000') + parser._do_vertical(-1) + self.assertEqual(parser._curpos, 0) + return + + def test_b3(self): + parser = self.get_parser('000111') + parser._do_pass() + self.assertEqual(parser._curpos, 3) + self.assertEqual(parser._get_bits(), '111') + return + + def test_b4(self): + parser = self.get_parser('00000') + parser._do_vertical(+2) + self.assertEqual(parser._curpos, 2) + self.assertEqual(parser._get_bits(), '11') + return + + def test_b5(self): + parser = self.get_parser('11111111100') + parser._do_horizontal(0, 3) + self.assertEqual(parser._curpos, 3) + parser._do_vertical(1) + self.assertEqual(parser._curpos, 10) + self.assertEqual(parser._get_bits(), '0001111111') + return + + def test_e1(self): + parser = self.get_parser('10000') + parser._do_vertical(0) + self.assertEqual(parser._curpos, 1) + parser._do_vertical(0) + self.assertEqual(parser._curpos, 5) + self.assertEqual(parser._get_bits(), '10000') + return + + def test_e2(self): + parser = self.get_parser('10011') + parser._do_vertical(0) + self.assertEqual(parser._curpos, 1) + parser._do_vertical(2) + self.assertEqual(parser._curpos, 5) + self.assertEqual(parser._get_bits(), '10000') + return + + def test_e3(self): + parser = self.get_parser('011111') + parser._color = 0 + parser._do_vertical(0) + self.assertEqual(parser._color, 1) + self.assertEqual(parser._curpos, 1) + parser._do_vertical(-2) + self.assertEqual(parser._color, 0) + self.assertEqual(parser._curpos, 4) + parser._do_vertical(0) + self.assertEqual(parser._curpos, 6) + self.assertEqual(parser._get_bits(), '011100') + return + + def test_e4(self): + parser = self.get_parser('10000') + parser._do_vertical(0) + self.assertEqual(parser._curpos, 1) + parser._do_vertical(-2) + self.assertEqual(parser._curpos, 3) + parser._do_vertical(0) + self.assertEqual(parser._curpos, 5) + self.assertEqual(parser._get_bits(), '10011') + return + + def test_e5(self): + parser = self.get_parser('011000') + parser._color = 0 + parser._do_vertical(0) + self.assertEqual(parser._curpos, 1) + parser._do_vertical(3) + self.assertEqual(parser._curpos, 6) + self.assertEqual(parser._get_bits(), '011111') + return + + def test_e6(self): + parser = self.get_parser('11001') + parser._do_pass() + self.assertEqual(parser._curpos, 4) + parser._do_vertical(0) + self.assertEqual(parser._curpos, 5) + self.assertEqual(parser._get_bits(), '11111') + return + + def test_e7(self): + parser = self.get_parser('0000000000') + parser._curpos = 2 + parser._color = 1 + parser._do_horizontal(2, 6) + self.assertEqual(parser._curpos, 10) + self.assertEqual(parser._get_bits(), '1111000000') + return + + def test_e8(self): + parser = self.get_parser('001100000') + parser._curpos = 1 + parser._color = 0 + parser._do_vertical(0) + self.assertEqual(parser._curpos, 2) + parser._do_horizontal(7, 0) + self.assertEqual(parser._curpos, 9) + self.assertEqual(parser._get_bits(), '101111111') + return + + def test_m1(self): + parser = self.get_parser('10101') + parser._do_pass() + self.assertEqual(parser._curpos, 2) + parser._do_pass() + self.assertEqual(parser._curpos, 4) + self.assertEqual(parser._get_bits(), '1111') + return + + def test_m2(self): + parser = self.get_parser('101011') + parser._do_vertical(-1) + parser._do_vertical(-1) + parser._do_vertical(1) + parser._do_horizontal(1, 1) + self.assertEqual(parser._get_bits(), '011101') + return + + def test_m3(self): + parser = self.get_parser('10111011') + parser._do_vertical(-1) + parser._do_pass() + parser._do_vertical(1) + parser._do_vertical(1) + self.assertEqual(parser._get_bits(), '00000001') + return + + +## CCITTFaxDecoder +## +class CCITTFaxDecoder(CCITTG4Parser): + + def __init__(self, width, bytealign=False, reversed=False): + CCITTG4Parser.__init__(self, width, bytealign=bytealign) + self.reversed = reversed + self._buf = '' + return + + def close(self): + return self._buf + + def output_line(self, y, bits): + bytes = array.array('B', [0]*((len(bits)+7)//8)) + if self.reversed: + bits = [1-b for b in bits] + for (i, b) in enumerate(bits): + if b: + bytes[i//8] += (128, 64, 32, 16, 8, 4, 2, 1)[i % 8] + self._buf += bytes.tostring() + return + + +def ccittfaxdecode(data, params): + K = params.get('K') + cols = params.get('Columns') + bytealign = params.get('EncodedByteAlign') + reversed = params.get('BlackIs1') + if K == -1: + parser = CCITTFaxDecoder(cols, bytealign=bytealign, reversed=reversed) + else: + raise ValueError(K) + parser.feedbytes(data) + return parser.close() + + +# test +def main(argv): + import pygame + if not argv[1:]: + return unittest.main() + + class Parser(CCITTG4Parser): + def __init__(self, width, bytealign=False): + CCITTG4Parser.__init__(self, width, bytealign=bytealign) + self.img = pygame.Surface((self.width, 1000)) + return + + def output_line(self, y, bits): + for (x, b) in enumerate(bits): + if b: + self.img.set_at((x, y), (255, 255, 255)) + else: + self.img.set_at((x, y), (0, 0, 0)) + return + + def close(self): + pygame.image.save(self.img, 'out.bmp') + return + for path in argv[1:]: + fp = file(path, 'rb') + (_, _, k, w, h, _) = path.split('.') + parser = Parser(int(w)) + parser.feedbytes(fp.read()) + parser.close() + fp.close() + return + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff -Nru pdfminer-20110515+dfsg/pdfminer/cmap/Makefile pdfminer-20140328+dfsg/pdfminer/cmap/Makefile --- pdfminer-20110515+dfsg/pdfminer/cmap/Makefile 2010-06-13 13:46:57.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/cmap/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# Makefile for pdfminer.cmap - -all: - -clean: - -rm *.pyc *.pyo - -cmap_clean: - rm -f *.pickle.gz diff -Nru pdfminer-20110515+dfsg/pdfminer/cmapdb.py pdfminer-20140328+dfsg/pdfminer/cmapdb.py --- pdfminer-20110515+dfsg/pdfminer/cmapdb.py 2011-03-02 14:38:31.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/cmapdb.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Adobe character mapping (CMap) support. @@ -12,22 +12,21 @@ """ import sys -import re import os import os.path import gzip import cPickle as pickle -import cmap import struct from psparser import PSStackParser -from psparser import PSException, PSSyntaxError, PSTypeError, PSEOF -from psparser import PSLiteral, PSKeyword -from psparser import literal_name, keyword_name +from psparser import PSSyntaxError, PSEOF +from psparser import PSLiteral +from psparser import literal_name from encodingdb import name2unicode from utils import choplist, nunpack -class CMapError(Exception): pass +class CMapError(Exception): + pass ## CMap @@ -45,8 +44,9 @@ def use_cmap(self, cmap): assert isinstance(cmap, CMap) + def copy(dst, src): - for (k,v) in src.iteritems(): + for (k, v) in src.iteritems(): if isinstance(v, dict): d = {} dst[k] = d @@ -75,14 +75,14 @@ if code2cid is None: code2cid = self.code2cid code = () - for (k,v) in sorted(code2cid.iteritems()): + for (k, v) in sorted(code2cid.iteritems()): c = code+(k,) if isinstance(v, int): - out.write('code %r = cid %d\n' % (c,v)) + out.write('code %r = cid %d\n' % (c, v)) else: self.dump(out=out, code2cid=v, code=c) return - + ## IdentityCMap ## @@ -96,13 +96,12 @@ return self.vertical def decode(self, code): - n = len(code)/2 + n = len(code)//2 if n: return struct.unpack('>%dH' % n, code) else: return () - - + ## UnicodeMap ## @@ -120,8 +119,8 @@ return self.cid2unichr[cid] def dump(self, out=sys.stdout): - for (k,v) in sorted(self.cid2unichr.iteritems()): - out.write('cid %d = unicode %r\n' % (k,v)) + for (k, v) in sorted(self.cid2unichr.iteritems()): + out.write('cid %d = unicode %r\n' % (k, v)) return @@ -154,7 +153,7 @@ else: t = {} d[c] = t - d =t + d = t c = ord(code[-1]) d[c] = cid return @@ -163,7 +162,7 @@ ## FileUnicodeMap ## class FileUnicodeMap(UnicodeMap): - + def __init__(self): UnicodeMap.__init__(self) self.attrs = {} @@ -206,12 +205,12 @@ def is_vertical(self): return self._is_vertical - + ## PyUnicodeMap ## class PyUnicodeMap(UnicodeMap): - + def __init__(self, name, module, vertical): if vertical: cid2unichr = module.CID2UNICHR_V @@ -232,16 +231,18 @@ debug = 0 _cmap_cache = {} _umap_cache = {} - - class CMapNotFound(CMapError): pass + + class CMapNotFound(CMapError): + pass @classmethod def _load_data(klass, name): filename = '%s.pickle.gz' % name if klass.debug: print >>sys.stderr, 'loading:', name - default_path = os.environ.get('CMAP_PATH', '/usr/share/pdfminer/') - for directory in (os.path.dirname(cmap.__file__), default_path): + cmap_paths = (os.environ.get('CMAP_PATH', '/usr/share/pdfminer/'), + os.path.join(os.path.dirname(__file__), 'cmap'),) + for directory in cmap_paths: path = os.path.join(directory, filename) if os.path.exists(path): gzfile = gzip.open(path) @@ -284,7 +285,8 @@ def __init__(self, cmap, fp): PSStackParser.__init__(self, fp) self.cmap = cmap - self._in_cmap = False + # some ToUnicode maps don't have "begincmap" keyword. + self._in_cmap = True return def run(self): @@ -303,11 +305,12 @@ elif name == 'endcmap': self._in_cmap = False return - if not self._in_cmap: return + if not self._in_cmap: + return # if name == 'def': try: - ((_,k),(_,v)) = self.pop(2) + ((_, k), (_, v)) = self.pop(2) self.cmap.set_attr(literal_name(k), v) except PSSyntaxError: pass @@ -315,7 +318,7 @@ if name == 'usecmap': try: - ((_,cmapname),) = self.pop(1) + ((_, cmapname),) = self.pop(1) self.cmap.use_cmap(CMapDB.get_cmap(literal_name(cmapname))) except PSSyntaxError: pass @@ -334,13 +337,15 @@ self.popall() return if name == 'endcidrange': - objs = [ obj for (_,obj) in self.popall() ] - for (s,e,cid) in choplist(3, objs): + objs = [obj for (__, obj) in self.popall()] + for (s, e, cid) in choplist(3, objs): if (not isinstance(s, str) or not isinstance(e, str) or - not isinstance(cid, int) or len(s) != len(e)): continue + not isinstance(cid, int) or len(s) != len(e)): + continue sprefix = s[:-4] eprefix = e[:-4] - if sprefix != eprefix: continue + if sprefix != eprefix: + continue svar = s[-4:] evar = e[-4:] s1 = nunpack(svar) @@ -348,7 +353,7 @@ vlen = len(svar) #assert s1 <= e1 for i in xrange(e1-s1+1): - x = sprefix+struct.pack('>L',s1+i)[-vlen:] + x = sprefix+struct.pack('>L', s1+i)[-vlen:] self.cmap.add_code2cid(x, cid+i) return @@ -356,8 +361,8 @@ self.popall() return if name == 'endcidchar': - objs = [ obj for (_,obj) in self.popall() ] - for (cid,code) in choplist(2, objs): + objs = [obj for (__, obj) in self.popall()] + for (cid, code) in choplist(2, objs): if isinstance(code, str) and isinstance(cid, str): self.cmap.add_code2cid(code, nunpack(cid)) return @@ -366,10 +371,11 @@ self.popall() return if name == 'endbfrange': - objs = [ obj for (_,obj) in self.popall() ] - for (s,e,code) in choplist(3, objs): + objs = [obj for (__, obj) in self.popall()] + for (s, e, code) in choplist(3, objs): if (not isinstance(s, str) or not isinstance(e, str) or - len(s) != len(e)): continue + len(s) != len(e)): + continue s1 = nunpack(s) e1 = nunpack(e) #assert s1 <= e1 @@ -382,7 +388,7 @@ prefix = code[:-4] vlen = len(var) for i in xrange(e1-s1+1): - x = prefix+struct.pack('>L',base+i)[-vlen:] + x = prefix+struct.pack('>L', base+i)[-vlen:] self.cmap.add_cid2unichr(s1+i, x) return @@ -390,8 +396,8 @@ self.popall() return if name == 'endbfchar': - objs = [ obj for (_,obj) in self.popall() ] - for (cid,code) in choplist(2, objs): + objs = [obj for (__, obj) in self.popall()] + for (cid, code) in choplist(2, objs): if isinstance(cid, str) and isinstance(code, str): self.cmap.add_cid2unichr(nunpack(cid), code) return @@ -406,6 +412,7 @@ self.push((pos, token)) return + # test def main(argv): args = argv[1:] @@ -418,4 +425,5 @@ cmap.dump() return -if __name__ == '__main__': sys.exit(main(sys.argv)) +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff -Nru pdfminer-20110515+dfsg/pdfminer/converter.py pdfminer-20140328+dfsg/pdfminer/converter.py --- pdfminer-20110515+dfsg/pdfminer/converter.py 2011-05-14 06:51:08.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/converter.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,14 +1,12 @@ -#!/usr/bin/env python2 -import sys, os.path -from pdfdevice import PDFDevice, PDFTextDevice +#!/usr/bin/env python +import sys +from pdfdevice import PDFTextDevice from pdffont import PDFUnicodeNotDefined -from pdftypes import LITERALS_DCT_DECODE -from pdfcolor import LITERAL_DEVICE_GRAY, LITERAL_DEVICE_RGB from layout import LTContainer, LTPage, LTText, LTLine, LTRect, LTCurve from layout import LTFigure, LTImage, LTChar, LTTextLine from layout import LTTextBox, LTTextBoxVertical, LTTextGroup from utils import apply_matrix_pt, mult_matrix -from utils import enc, bbox2str, create_bmp +from utils import enc, bbox2str ## PDFLayoutAnalyzer @@ -23,9 +21,9 @@ return def begin_page(self, page, ctm): - (x0,y0,x1,y1) = page.mediabox - (x0,y0) = apply_matrix_pt(ctm, (x0,y0)) - (x1,y1) = apply_matrix_pt(ctm, (x1,y1)) + (x0, y0, x1, y1) = page.mediabox + (x0, y0) = apply_matrix_pt(ctm, (x0, y0)) + (x1, y1) = apply_matrix_pt(ctm, (x1, y1)) mediabox = (0, 0, abs(x0-x1), abs(y0-y1)) self.cur_item = LTPage(self.pageno, mediabox) return @@ -63,26 +61,26 @@ shape = ''.join(x[0] for x in path) if shape == 'ml': # horizontal/vertical line - (_,x0,y0) = path[0] - (_,x1,y1) = path[1] - (x0,y0) = apply_matrix_pt(self.ctm, (x0,y0)) - (x1,y1) = apply_matrix_pt(self.ctm, (x1,y1)) + (_, x0, y0) = path[0] + (_, x1, y1) = path[1] + (x0, y0) = apply_matrix_pt(self.ctm, (x0, y0)) + (x1, y1) = apply_matrix_pt(self.ctm, (x1, y1)) if x0 == x1 or y0 == y1: - self.cur_item.add(LTLine(gstate.linewidth, (x0,y0), (x1,y1))) + self.cur_item.add(LTLine(gstate.linewidth, (x0, y0), (x1, y1))) return if shape == 'mlllh': # rectangle - (_,x0,y0) = path[0] - (_,x1,y1) = path[1] - (_,x2,y2) = path[2] - (_,x3,y3) = path[3] - (x0,y0) = apply_matrix_pt(self.ctm, (x0,y0)) - (x1,y1) = apply_matrix_pt(self.ctm, (x1,y1)) - (x2,y2) = apply_matrix_pt(self.ctm, (x2,y2)) - (x3,y3) = apply_matrix_pt(self.ctm, (x3,y3)) + (_, x0, y0) = path[0] + (_, x1, y1) = path[1] + (_, x2, y2) = path[2] + (_, x3, y3) = path[3] + (x0, y0) = apply_matrix_pt(self.ctm, (x0, y0)) + (x1, y1) = apply_matrix_pt(self.ctm, (x1, y1)) + (x2, y2) = apply_matrix_pt(self.ctm, (x2, y2)) + (x3, y3) = apply_matrix_pt(self.ctm, (x3, y3)) if ((x0 == x1 and y1 == y2 and x2 == x3 and y3 == y0) or (y0 == y1 and x1 == x2 and y2 == y3 and x3 == x0)): - self.cur_item.add(LTRect(gstate.linewidth, (x0,y0,x2,y2))) + self.cur_item.add(LTRect(gstate.linewidth, (x0, y0, x2, y2))) return # other shapes pts = [] @@ -121,7 +119,7 @@ PDFLayoutAnalyzer.__init__(self, rsrcmgr, pageno=pageno, laparams=laparams) self.result = None return - + def receive_layout(self, ltpage): self.result = ltpage return @@ -140,37 +138,16 @@ self.codec = codec return - def write_image(self, image): - stream = image.stream - filters = stream.get_filters() - if len(filters) == 1 and filters[0] in LITERALS_DCT_DECODE: - ext = '.jpg' - data = stream.get_rawdata() - elif stream.colorspace is LITERAL_DEVICE_RGB: - ext = '.bmp' - data = create_bmp(stream.get_data(), stream.bits*3, image.width, image.height) - elif stream.colorspace is LITERAL_DEVICE_GRAY: - ext = '.bmp' - data = create_bmp(stream.get_data(), stream.bits, image.width, image.height) - else: - ext = '.img' - data = stream.get_data() - name = image.name+ext - path = os.path.join(self.outdir, name) - fp = file(path, 'wb') - fp.write(data) - fp.close() - return name - ## TextConverter ## class TextConverter(PDFConverter): def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, laparams=None, - showpageno=False): + showpageno=False, imagewriter=None): PDFConverter.__init__(self, rsrcmgr, outfp, codec=codec, pageno=pageno, laparams=laparams) self.showpageno = showpageno + self.imagewriter = imagewriter return def write_text(self, text): @@ -186,19 +163,26 @@ self.write_text(item.get_text()) if isinstance(item, LTTextBox): self.write_text('\n') + elif isinstance(item, LTImage): + if self.imagewriter is not None: + self.imagewriter.export_image(item) if self.showpageno: self.write_text('Page %s\n' % ltpage.pageid) render(ltpage) self.write_text('\f') return - # Some dummy functions to save memory/CPU when all that is wanted is text. - # This stops all the image and drawing ouput from being recorded and taking - # up RAM. + # Some dummy functions to save memory/CPU when all that is wanted + # is text. This stops all the image and drawing ouput from being + # recorded and taking up RAM. def render_image(self, name, stream): - pass + if self.imagewriter is None: + return + PDFConverter.render_image(self, name, stream) + return + def paint_path(self, gstate, stroke, fill, evenodd, path): - pass + return ## HTMLConverter @@ -213,25 +197,25 @@ 'textgroup': 'red', 'curve': 'black', 'page': 'gray', - } - + } + TEXT_COLORS = { 'textbox': 'blue', 'char': 'black', - } + } - def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, laparams=None, - scale=1, fontscale=0.7, layoutmode='normal', showpageno=True, - pagemargin=50, outdir=None, - rect_colors={'curve':'black', 'page':'gray'}, - text_colors={'char':'black'}): + def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, laparams=None, + scale=1, fontscale=1.0, layoutmode='normal', showpageno=True, + pagemargin=50, imagewriter=None, + rect_colors={'curve': 'black', 'page': 'gray'}, + text_colors={'char': 'black'}): PDFConverter.__init__(self, rsrcmgr, outfp, codec=codec, pageno=pageno, laparams=laparams) self.scale = scale self.fontscale = fontscale self.layoutmode = layoutmode self.showpageno = showpageno self.pagemargin = pagemargin - self.outdir = outdir + self.imagewriter = imagewriter self.rect_colors = rect_colors self.text_colors = text_colors if self.debug: @@ -255,7 +239,7 @@ def write_footer(self): self.write('

    Page: %s
    \n' % - ', '.join('%s' % (i,i) for i in xrange(1,self.pageno))) + ', '.join('%s' % (i, i) for i in xrange(1, self.pageno))) self.write('\n') return @@ -278,8 +262,8 @@ return def place_image(self, item, borderwidth, x, y, w, h): - if self.outdir is not None: - name = self.write_image(item) + if self.imagewriter is not None: + name = self.imagewriter.export_image(item) self.write('\n' % (enc(name), borderwidth, @@ -296,7 +280,7 @@ self.write('\n') return - def begin_textbox(self, color, borderwidth, x, y, w, h, writing_mode): + def begin_div(self, color, borderwidth, x, y, w, h, writing_mode=False): self._fontstack.append(self._font) self._font = None self.write('
    \n' % @@ -479,8 +467,8 @@ elif isinstance(item, LTText): self.outfp.write('%s\n' % item.get_text()) elif isinstance(item, LTImage): - if self.outdir: - name = self.write_image(item) + if self.imagewriter is not None: + name = self.imagewriter.export_image(item) self.outfp.write('\n' % (enc(name), item.width, item.height)) else: diff -Nru pdfminer-20110515+dfsg/pdfminer/encodingdb.py pdfminer-20140328+dfsg/pdfminer/encodingdb.py --- pdfminer-20110515+dfsg/pdfminer/encodingdb.py 2011-03-01 11:32:18.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/encodingdb.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import re from psparser import PSLiteral @@ -6,15 +6,18 @@ from latin_enc import ENCODING +STRIP_NAME = re.compile(r'[0-9]+') + + ## name2unicode ## -STRIP_NAME = re.compile(r'[0-9]+') def name2unicode(name): """Converts Adobe glyph names to Unicode numbers.""" if name in glyphname2unicode: return glyphname2unicode[name] m = STRIP_NAME.search(name) - if not m: raise KeyError(name) + if not m: + raise KeyError(name) return unichr(int(m.group(0))) @@ -26,19 +29,23 @@ mac2unicode = {} win2unicode = {} pdf2unicode = {} - for (name,std,mac,win,pdf) in ENCODING: + for (name, std, mac, win, pdf) in ENCODING: c = name2unicode(name) - if std: std2unicode[std] = c - if mac: mac2unicode[mac] = c - if win: win2unicode[win] = c - if pdf: pdf2unicode[pdf] = c + if std: + std2unicode[std] = c + if mac: + mac2unicode[mac] = c + if win: + win2unicode[win] = c + if pdf: + pdf2unicode[pdf] = c encodings = { - 'StandardEncoding': std2unicode, - 'MacRomanEncoding': mac2unicode, - 'WinAnsiEncoding': win2unicode, - 'PDFDocEncoding': pdf2unicode, - } + 'StandardEncoding': std2unicode, + 'MacRomanEncoding': mac2unicode, + 'WinAnsiEncoding': win2unicode, + 'PDFDocEncoding': pdf2unicode, + } @classmethod def get_encoding(klass, name, diff=None): diff -Nru pdfminer-20110515+dfsg/pdfminer/fontmetrics.py pdfminer-20140328+dfsg/pdfminer/fontmetrics.py --- pdfminer-20110515+dfsg/pdfminer/fontmetrics.py 2010-10-19 09:55:33.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/fontmetrics.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Font metrics for the Adobe core 14 fonts. @@ -8,13 +8,13 @@ The following data were extracted from the AFM files: http://www.ctan.org/tex-archive/fonts/adobe/afm/ - + """ ### BEGIN Verbatim copy of the license part # -# Adobe Core 35 AFM Files with 229 Glyph Entries - ReadMe +# Adobe Core 35 AFM Files with 314 Glyph Entries - ReadMe # # This file and the 35 PostScript(R) AFM files it accompanies may be # used, copied, and distributed for any purpose and without charge, @@ -29,18 +29,18 @@ ### END Verbatim copy of the license part FONT_METRICS = { - 'Courier-Oblique': ({'FontName': 'Courier-Oblique', 'Descent': -194.0, 'FontBBox': (-49.0, -249.0, 749.0, 803.0), 'FontWeight': 'Medium', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': -11.0, 'Ascent': 627.0}, {32: 600, 33: 600, 34: 600, 35: 600, 36: 600, 37: 600, 38: 600, 39: 600, 40: 600, 41: 600, 42: 600, 43: 600, 44: 600, 45: 600, 46: 600, 47: 600, 48: 600, 49: 600, 50: 600, 51: 600, 52: 600, 53: 600, 54: 600, 55: 600, 56: 600, 57: 600, 58: 600, 59: 600, 60: 600, 61: 600, 62: 600, 63: 600, 64: 600, 65: 600, 66: 600, 67: 600, 68: 600, 69: 600, 70: 600, 71: 600, 72: 600, 73: 600, 74: 600, 75: 600, 76: 600, 77: 600, 78: 600, 79: 600, 80: 600, 81: 600, 82: 600, 83: 600, 84: 600, 85: 600, 86: 600, 87: 600, 88: 600, 89: 600, 90: 600, 91: 600, 92: 600, 93: 600, 94: 600, 95: 600, 96: 600, 97: 600, 98: 600, 99: 600, 100: 600, 101: 600, 102: 600, 103: 600, 104: 600, 105: 600, 106: 600, 107: 600, 108: 600, 109: 600, 110: 600, 111: 600, 112: 600, 113: 600, 114: 600, 115: 600, 116: 600, 117: 600, 118: 600, 119: 600, 120: 600, 121: 600, 122: 600, 123: 600, 124: 600, 125: 600, 126: 600, 161: 600, 162: 600, 163: 600, 164: 600, 165: 600, 166: 600, 167: 600, 168: 600, 169: 600, 170: 600, 171: 600, 172: 600, 173: 600, 174: 600, 175: 600, 177: 600, 178: 600, 179: 600, 180: 600, 182: 600, 183: 600, 184: 600, 185: 600, 186: 600, 187: 600, 188: 600, 189: 600, 191: 600, 193: 600, 194: 600, 195: 600, 196: 600, 197: 600, 198: 600, 199: 600, 200: 600, 202: 600, 203: 600, 205: 600, 206: 600, 207: 600, 208: 600, 225: 600, 227: 600, 232: 600, 233: 600, 234: 600, 235: 600, 241: 600, 245: 600, 248: 600, 249: 600, 250: 600, 251: 600}), - 'Times-BoldItalic': ({'FontName': 'Times-BoldItalic', 'Descent': -217.0, 'FontBBox': (-200.0, -218.0, 996.0, 921.0), 'FontWeight': 'Bold', 'CapHeight': 669.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 462.0, 'ItalicAngle': -15.0, 'Ascent': 683.0}, {32: 250, 33: 389, 34: 555, 35: 500, 36: 500, 37: 833, 38: 778, 39: 333, 40: 333, 41: 333, 42: 500, 43: 570, 44: 250, 45: 333, 46: 250, 47: 278, 48: 500, 49: 500, 50: 500, 51: 500, 52: 500, 53: 500, 54: 500, 55: 500, 56: 500, 57: 500, 58: 333, 59: 333, 60: 570, 61: 570, 62: 570, 63: 500, 64: 832, 65: 667, 66: 667, 67: 667, 68: 722, 69: 667, 70: 667, 71: 722, 72: 778, 73: 389, 74: 500, 75: 667, 76: 611, 77: 889, 78: 722, 79: 722, 80: 611, 81: 722, 82: 667, 83: 556, 84: 611, 85: 722, 86: 667, 87: 889, 88: 667, 89: 611, 90: 611, 91: 333, 92: 278, 93: 333, 94: 570, 95: 500, 96: 333, 97: 500, 98: 500, 99: 444, 100: 500, 101: 444, 102: 333, 103: 500, 104: 556, 105: 278, 106: 278, 107: 500, 108: 278, 109: 778, 110: 556, 111: 500, 112: 500, 113: 500, 114: 389, 115: 389, 116: 278, 117: 556, 118: 444, 119: 667, 120: 500, 121: 444, 122: 389, 123: 348, 124: 220, 125: 348, 126: 570, 161: 389, 162: 500, 163: 500, 164: 167, 165: 500, 166: 500, 167: 500, 168: 500, 169: 278, 170: 500, 171: 500, 172: 333, 173: 333, 174: 556, 175: 556, 177: 500, 178: 500, 179: 500, 180: 250, 182: 500, 183: 350, 184: 333, 185: 500, 186: 500, 187: 500, 188: 1000, 189: 1000, 191: 500, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 1000, 225: 944, 227: 266, 232: 611, 233: 722, 234: 944, 235: 300, 241: 722, 245: 278, 248: 278, 249: 500, 250: 722, 251: 500}), - 'Helvetica-Bold': ({'FontName': 'Helvetica-Bold', 'Descent': -207.0, 'FontBBox': (-170.0, -228.0, 1003.0, 962.0), 'FontWeight': 'Bold', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 532.0, 'ItalicAngle': 0.0, 'Ascent': 718.0}, {32: 278, 33: 333, 34: 474, 35: 556, 36: 556, 37: 889, 38: 722, 39: 278, 40: 333, 41: 333, 42: 389, 43: 584, 44: 278, 45: 333, 46: 278, 47: 278, 48: 556, 49: 556, 50: 556, 51: 556, 52: 556, 53: 556, 54: 556, 55: 556, 56: 556, 57: 556, 58: 333, 59: 333, 60: 584, 61: 584, 62: 584, 63: 611, 64: 975, 65: 722, 66: 722, 67: 722, 68: 722, 69: 667, 70: 611, 71: 778, 72: 722, 73: 278, 74: 556, 75: 722, 76: 611, 77: 833, 78: 722, 79: 778, 80: 667, 81: 778, 82: 722, 83: 667, 84: 611, 85: 722, 86: 667, 87: 944, 88: 667, 89: 667, 90: 611, 91: 333, 92: 278, 93: 333, 94: 584, 95: 556, 96: 278, 97: 556, 98: 611, 99: 556, 100: 611, 101: 556, 102: 333, 103: 611, 104: 611, 105: 278, 106: 278, 107: 556, 108: 278, 109: 889, 110: 611, 111: 611, 112: 611, 113: 611, 114: 389, 115: 556, 116: 333, 117: 611, 118: 556, 119: 778, 120: 556, 121: 556, 122: 500, 123: 389, 124: 280, 125: 389, 126: 584, 161: 333, 162: 556, 163: 556, 164: 167, 165: 556, 166: 556, 167: 556, 168: 556, 169: 238, 170: 500, 171: 556, 172: 333, 173: 333, 174: 611, 175: 611, 177: 556, 178: 556, 179: 556, 180: 278, 182: 556, 183: 350, 184: 278, 185: 500, 186: 500, 187: 556, 188: 1000, 189: 1000, 191: 611, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 1000, 225: 1000, 227: 370, 232: 611, 233: 778, 234: 1000, 235: 365, 241: 889, 245: 278, 248: 278, 249: 611, 250: 944, 251: 611}), - 'Courier': ({'FontName': 'Courier', 'Descent': -194.0, 'FontBBox': (-6.0, -249.0, 639.0, 803.0), 'FontWeight': 'Medium', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': 0.0, 'Ascent': 627.0}, {32: 600, 33: 600, 34: 600, 35: 600, 36: 600, 37: 600, 38: 600, 39: 600, 40: 600, 41: 600, 42: 600, 43: 600, 44: 600, 45: 600, 46: 600, 47: 600, 48: 600, 49: 600, 50: 600, 51: 600, 52: 600, 53: 600, 54: 600, 55: 600, 56: 600, 57: 600, 58: 600, 59: 600, 60: 600, 61: 600, 62: 600, 63: 600, 64: 600, 65: 600, 66: 600, 67: 600, 68: 600, 69: 600, 70: 600, 71: 600, 72: 600, 73: 600, 74: 600, 75: 600, 76: 600, 77: 600, 78: 600, 79: 600, 80: 600, 81: 600, 82: 600, 83: 600, 84: 600, 85: 600, 86: 600, 87: 600, 88: 600, 89: 600, 90: 600, 91: 600, 92: 600, 93: 600, 94: 600, 95: 600, 96: 600, 97: 600, 98: 600, 99: 600, 100: 600, 101: 600, 102: 600, 103: 600, 104: 600, 105: 600, 106: 600, 107: 600, 108: 600, 109: 600, 110: 600, 111: 600, 112: 600, 113: 600, 114: 600, 115: 600, 116: 600, 117: 600, 118: 600, 119: 600, 120: 600, 121: 600, 122: 600, 123: 600, 124: 600, 125: 600, 126: 600, 161: 600, 162: 600, 163: 600, 164: 600, 165: 600, 166: 600, 167: 600, 168: 600, 169: 600, 170: 600, 171: 600, 172: 600, 173: 600, 174: 600, 175: 600, 177: 600, 178: 600, 179: 600, 180: 600, 182: 600, 183: 600, 184: 600, 185: 600, 186: 600, 187: 600, 188: 600, 189: 600, 191: 600, 193: 600, 194: 600, 195: 600, 196: 600, 197: 600, 198: 600, 199: 600, 200: 600, 202: 600, 203: 600, 205: 600, 206: 600, 207: 600, 208: 600, 225: 600, 227: 600, 232: 600, 233: 600, 234: 600, 235: 600, 241: 600, 245: 600, 248: 600, 249: 600, 250: 600, 251: 600}), - 'Courier-BoldOblique': ({'FontName': 'Courier-BoldOblique', 'Descent': -194.0, 'FontBBox': (-49.0, -249.0, 758.0, 811.0), 'FontWeight': 'Bold', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': -11.0, 'Ascent': 627.0}, {32: 600, 33: 600, 34: 600, 35: 600, 36: 600, 37: 600, 38: 600, 39: 600, 40: 600, 41: 600, 42: 600, 43: 600, 44: 600, 45: 600, 46: 600, 47: 600, 48: 600, 49: 600, 50: 600, 51: 600, 52: 600, 53: 600, 54: 600, 55: 600, 56: 600, 57: 600, 58: 600, 59: 600, 60: 600, 61: 600, 62: 600, 63: 600, 64: 600, 65: 600, 66: 600, 67: 600, 68: 600, 69: 600, 70: 600, 71: 600, 72: 600, 73: 600, 74: 600, 75: 600, 76: 600, 77: 600, 78: 600, 79: 600, 80: 600, 81: 600, 82: 600, 83: 600, 84: 600, 85: 600, 86: 600, 87: 600, 88: 600, 89: 600, 90: 600, 91: 600, 92: 600, 93: 600, 94: 600, 95: 600, 96: 600, 97: 600, 98: 600, 99: 600, 100: 600, 101: 600, 102: 600, 103: 600, 104: 600, 105: 600, 106: 600, 107: 600, 108: 600, 109: 600, 110: 600, 111: 600, 112: 600, 113: 600, 114: 600, 115: 600, 116: 600, 117: 600, 118: 600, 119: 600, 120: 600, 121: 600, 122: 600, 123: 600, 124: 600, 125: 600, 126: 600, 161: 600, 162: 600, 163: 600, 164: 600, 165: 600, 166: 600, 167: 600, 168: 600, 169: 600, 170: 600, 171: 600, 172: 600, 173: 600, 174: 600, 175: 600, 177: 600, 178: 600, 179: 600, 180: 600, 182: 600, 183: 600, 184: 600, 185: 600, 186: 600, 187: 600, 188: 600, 189: 600, 191: 600, 193: 600, 194: 600, 195: 600, 196: 600, 197: 600, 198: 600, 199: 600, 200: 600, 202: 600, 203: 600, 205: 600, 206: 600, 207: 600, 208: 600, 225: 600, 227: 600, 232: 600, 233: 600, 234: 600, 235: 600, 241: 600, 245: 600, 248: 600, 249: 600, 250: 600, 251: 600}), - 'Times-Bold': ({'FontName': 'Times-Bold', 'Descent': -217.0, 'FontBBox': (-168.0, -218.0, 1000.0, 935.0), 'FontWeight': 'Bold', 'CapHeight': 676.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 461.0, 'ItalicAngle': 0.0, 'Ascent': 683.0}, {32: 250, 33: 333, 34: 555, 35: 500, 36: 500, 37: 1000, 38: 833, 39: 333, 40: 333, 41: 333, 42: 500, 43: 570, 44: 250, 45: 333, 46: 250, 47: 278, 48: 500, 49: 500, 50: 500, 51: 500, 52: 500, 53: 500, 54: 500, 55: 500, 56: 500, 57: 500, 58: 333, 59: 333, 60: 570, 61: 570, 62: 570, 63: 500, 64: 930, 65: 722, 66: 667, 67: 722, 68: 722, 69: 667, 70: 611, 71: 778, 72: 778, 73: 389, 74: 500, 75: 778, 76: 667, 77: 944, 78: 722, 79: 778, 80: 611, 81: 778, 82: 722, 83: 556, 84: 667, 85: 722, 86: 722, 87: 1000, 88: 722, 89: 722, 90: 667, 91: 333, 92: 278, 93: 333, 94: 581, 95: 500, 96: 333, 97: 500, 98: 556, 99: 444, 100: 556, 101: 444, 102: 333, 103: 500, 104: 556, 105: 278, 106: 333, 107: 556, 108: 278, 109: 833, 110: 556, 111: 500, 112: 556, 113: 556, 114: 444, 115: 389, 116: 333, 117: 556, 118: 500, 119: 722, 120: 500, 121: 500, 122: 444, 123: 394, 124: 220, 125: 394, 126: 520, 161: 333, 162: 500, 163: 500, 164: 167, 165: 500, 166: 500, 167: 500, 168: 500, 169: 278, 170: 500, 171: 500, 172: 333, 173: 333, 174: 556, 175: 556, 177: 500, 178: 500, 179: 500, 180: 250, 182: 540, 183: 350, 184: 333, 185: 500, 186: 500, 187: 500, 188: 1000, 189: 1000, 191: 500, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 1000, 225: 1000, 227: 300, 232: 667, 233: 778, 234: 1000, 235: 330, 241: 722, 245: 278, 248: 278, 249: 500, 250: 722, 251: 556}), - 'Symbol': ({'FontName': 'Symbol', 'FontBBox': (-180.0, -293.0, 1090.0, 1010.0), 'FontWeight': 'Medium', 'FontFamily': 'Symbol', 'Flags': 0, 'ItalicAngle': 0.0}, {32: 250, 33: 333, 34: 713, 35: 500, 36: 549, 37: 833, 38: 778, 39: 439, 40: 333, 41: 333, 42: 500, 43: 549, 44: 250, 45: 549, 46: 250, 47: 278, 48: 500, 49: 500, 50: 500, 51: 500, 52: 500, 53: 500, 54: 500, 55: 500, 56: 500, 57: 500, 58: 278, 59: 278, 60: 549, 61: 549, 62: 549, 63: 444, 64: 549, 65: 722, 66: 667, 67: 722, 68: 612, 69: 611, 70: 763, 71: 603, 72: 722, 73: 333, 74: 631, 75: 722, 76: 686, 77: 889, 78: 722, 79: 722, 80: 768, 81: 741, 82: 556, 83: 592, 84: 611, 85: 690, 86: 439, 87: 768, 88: 645, 89: 795, 90: 611, 91: 333, 92: 863, 93: 333, 94: 658, 95: 500, 96: 500, 97: 631, 98: 549, 99: 549, 100: 494, 101: 439, 102: 521, 103: 411, 104: 603, 105: 329, 106: 603, 107: 549, 108: 549, 109: 576, 110: 521, 111: 549, 112: 549, 113: 521, 114: 549, 115: 603, 116: 439, 117: 576, 118: 713, 119: 686, 120: 493, 121: 686, 122: 494, 123: 480, 124: 200, 125: 480, 126: 549, 160: 750, 161: 620, 162: 247, 163: 549, 164: 167, 165: 713, 166: 500, 167: 753, 168: 753, 169: 753, 170: 753, 171: 1042, 172: 987, 173: 603, 174: 987, 175: 603, 176: 400, 177: 549, 178: 411, 179: 549, 180: 549, 181: 713, 182: 494, 183: 460, 184: 549, 185: 549, 186: 549, 187: 549, 188: 1000, 189: 603, 190: 1000, 191: 658, 192: 823, 193: 686, 194: 795, 195: 987, 196: 768, 197: 768, 198: 823, 199: 768, 200: 768, 201: 713, 202: 713, 203: 713, 204: 713, 205: 713, 206: 713, 207: 713, 208: 768, 209: 713, 210: 790, 211: 790, 212: 890, 213: 823, 214: 549, 215: 250, 216: 713, 217: 603, 218: 603, 219: 1042, 220: 987, 221: 603, 222: 987, 223: 603, 224: 494, 225: 329, 226: 790, 227: 790, 228: 786, 229: 713, 230: 384, 231: 384, 232: 384, 233: 384, 234: 384, 235: 384, 236: 494, 237: 494, 238: 494, 239: 494, 241: 329, 242: 274, 243: 686, 244: 686, 245: 686, 246: 384, 247: 384, 248: 384, 249: 384, 250: 384, 251: 384, 252: 494, 253: 494, 254: 494}), - 'Helvetica': ({'FontName': 'Helvetica', 'Descent': -207.0, 'FontBBox': (-166.0, -225.0, 1000.0, 931.0), 'FontWeight': 'Medium', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 523.0, 'ItalicAngle': 0.0, 'Ascent': 718.0}, {32: 278, 33: 278, 34: 355, 35: 556, 36: 556, 37: 889, 38: 667, 39: 222, 40: 333, 41: 333, 42: 389, 43: 584, 44: 278, 45: 333, 46: 278, 47: 278, 48: 556, 49: 556, 50: 556, 51: 556, 52: 556, 53: 556, 54: 556, 55: 556, 56: 556, 57: 556, 58: 278, 59: 278, 60: 584, 61: 584, 62: 584, 63: 556, 64: 1015, 65: 667, 66: 667, 67: 722, 68: 722, 69: 667, 70: 611, 71: 778, 72: 722, 73: 278, 74: 500, 75: 667, 76: 556, 77: 833, 78: 722, 79: 778, 80: 667, 81: 778, 82: 722, 83: 667, 84: 611, 85: 722, 86: 667, 87: 944, 88: 667, 89: 667, 90: 611, 91: 278, 92: 278, 93: 278, 94: 469, 95: 556, 96: 222, 97: 556, 98: 556, 99: 500, 100: 556, 101: 556, 102: 278, 103: 556, 104: 556, 105: 222, 106: 222, 107: 500, 108: 222, 109: 833, 110: 556, 111: 556, 112: 556, 113: 556, 114: 333, 115: 500, 116: 278, 117: 556, 118: 500, 119: 722, 120: 500, 121: 500, 122: 500, 123: 334, 124: 260, 125: 334, 126: 584, 161: 333, 162: 556, 163: 556, 164: 167, 165: 556, 166: 556, 167: 556, 168: 556, 169: 191, 170: 333, 171: 556, 172: 333, 173: 333, 174: 500, 175: 500, 177: 556, 178: 556, 179: 556, 180: 278, 182: 537, 183: 350, 184: 222, 185: 333, 186: 333, 187: 556, 188: 1000, 189: 1000, 191: 611, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 1000, 225: 1000, 227: 370, 232: 556, 233: 778, 234: 1000, 235: 365, 241: 889, 245: 278, 248: 222, 249: 611, 250: 944, 251: 611}), - 'Helvetica-BoldOblique': ({'FontName': 'Helvetica-BoldOblique', 'Descent': -207.0, 'FontBBox': (-175.0, -228.0, 1114.0, 962.0), 'FontWeight': 'Bold', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 532.0, 'ItalicAngle': -12.0, 'Ascent': 718.0}, {32: 278, 33: 333, 34: 474, 35: 556, 36: 556, 37: 889, 38: 722, 39: 278, 40: 333, 41: 333, 42: 389, 43: 584, 44: 278, 45: 333, 46: 278, 47: 278, 48: 556, 49: 556, 50: 556, 51: 556, 52: 556, 53: 556, 54: 556, 55: 556, 56: 556, 57: 556, 58: 333, 59: 333, 60: 584, 61: 584, 62: 584, 63: 611, 64: 975, 65: 722, 66: 722, 67: 722, 68: 722, 69: 667, 70: 611, 71: 778, 72: 722, 73: 278, 74: 556, 75: 722, 76: 611, 77: 833, 78: 722, 79: 778, 80: 667, 81: 778, 82: 722, 83: 667, 84: 611, 85: 722, 86: 667, 87: 944, 88: 667, 89: 667, 90: 611, 91: 333, 92: 278, 93: 333, 94: 584, 95: 556, 96: 278, 97: 556, 98: 611, 99: 556, 100: 611, 101: 556, 102: 333, 103: 611, 104: 611, 105: 278, 106: 278, 107: 556, 108: 278, 109: 889, 110: 611, 111: 611, 112: 611, 113: 611, 114: 389, 115: 556, 116: 333, 117: 611, 118: 556, 119: 778, 120: 556, 121: 556, 122: 500, 123: 389, 124: 280, 125: 389, 126: 584, 161: 333, 162: 556, 163: 556, 164: 167, 165: 556, 166: 556, 167: 556, 168: 556, 169: 238, 170: 500, 171: 556, 172: 333, 173: 333, 174: 611, 175: 611, 177: 556, 178: 556, 179: 556, 180: 278, 182: 556, 183: 350, 184: 278, 185: 500, 186: 500, 187: 556, 188: 1000, 189: 1000, 191: 611, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 1000, 225: 1000, 227: 370, 232: 611, 233: 778, 234: 1000, 235: 365, 241: 889, 245: 278, 248: 278, 249: 611, 250: 944, 251: 611}), - 'ZapfDingbats': ({'FontName': 'ZapfDingbats', 'FontBBox': (-1.0, -143.0, 981.0, 820.0), 'FontWeight': 'Medium', 'FontFamily': 'ITC', 'Flags': 0, 'ItalicAngle': 0.0}, {32: 278, 33: 974, 34: 961, 35: 974, 36: 980, 37: 719, 38: 789, 39: 790, 40: 791, 41: 690, 42: 960, 43: 939, 44: 549, 45: 855, 46: 911, 47: 933, 48: 911, 49: 945, 50: 974, 51: 755, 52: 846, 53: 762, 54: 761, 55: 571, 56: 677, 57: 763, 58: 760, 59: 759, 60: 754, 61: 494, 62: 552, 63: 537, 64: 577, 65: 692, 66: 786, 67: 788, 68: 788, 69: 790, 70: 793, 71: 794, 72: 816, 73: 823, 74: 789, 75: 841, 76: 823, 77: 833, 78: 816, 79: 831, 80: 923, 81: 744, 82: 723, 83: 749, 84: 790, 85: 792, 86: 695, 87: 776, 88: 768, 89: 792, 90: 759, 91: 707, 92: 708, 93: 682, 94: 701, 95: 826, 96: 815, 97: 789, 98: 789, 99: 707, 100: 687, 101: 696, 102: 689, 103: 786, 104: 787, 105: 713, 106: 791, 107: 785, 108: 791, 109: 873, 110: 761, 111: 762, 112: 762, 113: 759, 114: 759, 115: 892, 116: 892, 117: 788, 118: 784, 119: 438, 120: 138, 121: 277, 122: 415, 123: 392, 124: 392, 125: 668, 126: 668, 128: 390, 129: 390, 130: 317, 131: 317, 132: 276, 133: 276, 134: 509, 135: 509, 136: 410, 137: 410, 138: 234, 139: 234, 140: 334, 141: 334, 161: 732, 162: 544, 163: 544, 164: 910, 165: 667, 166: 760, 167: 760, 168: 776, 169: 595, 170: 694, 171: 626, 172: 788, 173: 788, 174: 788, 175: 788, 176: 788, 177: 788, 178: 788, 179: 788, 180: 788, 181: 788, 182: 788, 183: 788, 184: 788, 185: 788, 186: 788, 187: 788, 188: 788, 189: 788, 190: 788, 191: 788, 192: 788, 193: 788, 194: 788, 195: 788, 196: 788, 197: 788, 198: 788, 199: 788, 200: 788, 201: 788, 202: 788, 203: 788, 204: 788, 205: 788, 206: 788, 207: 788, 208: 788, 209: 788, 210: 788, 211: 788, 212: 894, 213: 838, 214: 1016, 215: 458, 216: 748, 217: 924, 218: 748, 219: 918, 220: 927, 221: 928, 222: 928, 223: 834, 224: 873, 225: 828, 226: 924, 227: 924, 228: 917, 229: 930, 230: 931, 231: 463, 232: 883, 233: 836, 234: 836, 235: 867, 236: 867, 237: 696, 238: 696, 239: 874, 241: 874, 242: 760, 243: 946, 244: 771, 245: 865, 246: 771, 247: 888, 248: 967, 249: 888, 250: 831, 251: 873, 252: 927, 253: 970, 254: 918}), - 'Courier-Bold': ({'FontName': 'Courier-Bold', 'Descent': -194.0, 'FontBBox': (-88.0, -249.0, 697.0, 811.0), 'FontWeight': 'Bold', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': 0.0, 'Ascent': 627.0}, {32: 600, 33: 600, 34: 600, 35: 600, 36: 600, 37: 600, 38: 600, 39: 600, 40: 600, 41: 600, 42: 600, 43: 600, 44: 600, 45: 600, 46: 600, 47: 600, 48: 600, 49: 600, 50: 600, 51: 600, 52: 600, 53: 600, 54: 600, 55: 600, 56: 600, 57: 600, 58: 600, 59: 600, 60: 600, 61: 600, 62: 600, 63: 600, 64: 600, 65: 600, 66: 600, 67: 600, 68: 600, 69: 600, 70: 600, 71: 600, 72: 600, 73: 600, 74: 600, 75: 600, 76: 600, 77: 600, 78: 600, 79: 600, 80: 600, 81: 600, 82: 600, 83: 600, 84: 600, 85: 600, 86: 600, 87: 600, 88: 600, 89: 600, 90: 600, 91: 600, 92: 600, 93: 600, 94: 600, 95: 600, 96: 600, 97: 600, 98: 600, 99: 600, 100: 600, 101: 600, 102: 600, 103: 600, 104: 600, 105: 600, 106: 600, 107: 600, 108: 600, 109: 600, 110: 600, 111: 600, 112: 600, 113: 600, 114: 600, 115: 600, 116: 600, 117: 600, 118: 600, 119: 600, 120: 600, 121: 600, 122: 600, 123: 600, 124: 600, 125: 600, 126: 600, 161: 600, 162: 600, 163: 600, 164: 600, 165: 600, 166: 600, 167: 600, 168: 600, 169: 600, 170: 600, 171: 600, 172: 600, 173: 600, 174: 600, 175: 600, 177: 600, 178: 600, 179: 600, 180: 600, 182: 600, 183: 600, 184: 600, 185: 600, 186: 600, 187: 600, 188: 600, 189: 600, 191: 600, 193: 600, 194: 600, 195: 600, 196: 600, 197: 600, 198: 600, 199: 600, 200: 600, 202: 600, 203: 600, 205: 600, 206: 600, 207: 600, 208: 600, 225: 600, 227: 600, 232: 600, 233: 600, 234: 600, 235: 600, 241: 600, 245: 600, 248: 600, 249: 600, 250: 600, 251: 600}), - 'Times-Italic': ({'FontName': 'Times-Italic', 'Descent': -217.0, 'FontBBox': (-169.0, -217.0, 1010.0, 883.0), 'FontWeight': 'Medium', 'CapHeight': 653.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 441.0, 'ItalicAngle': -15.5, 'Ascent': 683.0}, {32: 250, 33: 333, 34: 420, 35: 500, 36: 500, 37: 833, 38: 778, 39: 333, 40: 333, 41: 333, 42: 500, 43: 675, 44: 250, 45: 333, 46: 250, 47: 278, 48: 500, 49: 500, 50: 500, 51: 500, 52: 500, 53: 500, 54: 500, 55: 500, 56: 500, 57: 500, 58: 333, 59: 333, 60: 675, 61: 675, 62: 675, 63: 500, 64: 920, 65: 611, 66: 611, 67: 667, 68: 722, 69: 611, 70: 611, 71: 722, 72: 722, 73: 333, 74: 444, 75: 667, 76: 556, 77: 833, 78: 667, 79: 722, 80: 611, 81: 722, 82: 611, 83: 500, 84: 556, 85: 722, 86: 611, 87: 833, 88: 611, 89: 556, 90: 556, 91: 389, 92: 278, 93: 389, 94: 422, 95: 500, 96: 333, 97: 500, 98: 500, 99: 444, 100: 500, 101: 444, 102: 278, 103: 500, 104: 500, 105: 278, 106: 278, 107: 444, 108: 278, 109: 722, 110: 500, 111: 500, 112: 500, 113: 500, 114: 389, 115: 389, 116: 278, 117: 500, 118: 444, 119: 667, 120: 444, 121: 444, 122: 389, 123: 400, 124: 275, 125: 400, 126: 541, 161: 389, 162: 500, 163: 500, 164: 167, 165: 500, 166: 500, 167: 500, 168: 500, 169: 214, 170: 556, 171: 500, 172: 333, 173: 333, 174: 500, 175: 500, 177: 500, 178: 500, 179: 500, 180: 250, 182: 523, 183: 350, 184: 333, 185: 556, 186: 556, 187: 500, 188: 889, 189: 1000, 191: 500, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 889, 225: 889, 227: 276, 232: 556, 233: 722, 234: 944, 235: 310, 241: 667, 245: 278, 248: 278, 249: 500, 250: 667, 251: 500}), - 'Times-Roman': ({'FontName': 'Times-Roman', 'Descent': -217.0, 'FontBBox': (-168.0, -218.0, 1000.0, 898.0), 'FontWeight': 'Roman', 'CapHeight': 662.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 450.0, 'ItalicAngle': 0.0, 'Ascent': 683.0}, {32: 250, 33: 333, 34: 408, 35: 500, 36: 500, 37: 833, 38: 778, 39: 333, 40: 333, 41: 333, 42: 500, 43: 564, 44: 250, 45: 333, 46: 250, 47: 278, 48: 500, 49: 500, 50: 500, 51: 500, 52: 500, 53: 500, 54: 500, 55: 500, 56: 500, 57: 500, 58: 278, 59: 278, 60: 564, 61: 564, 62: 564, 63: 444, 64: 921, 65: 722, 66: 667, 67: 667, 68: 722, 69: 611, 70: 556, 71: 722, 72: 722, 73: 333, 74: 389, 75: 722, 76: 611, 77: 889, 78: 722, 79: 722, 80: 556, 81: 722, 82: 667, 83: 556, 84: 611, 85: 722, 86: 722, 87: 944, 88: 722, 89: 722, 90: 611, 91: 333, 92: 278, 93: 333, 94: 469, 95: 500, 96: 333, 97: 444, 98: 500, 99: 444, 100: 500, 101: 444, 102: 333, 103: 500, 104: 500, 105: 278, 106: 278, 107: 500, 108: 278, 109: 778, 110: 500, 111: 500, 112: 500, 113: 500, 114: 333, 115: 389, 116: 278, 117: 500, 118: 500, 119: 722, 120: 500, 121: 500, 122: 444, 123: 480, 124: 200, 125: 480, 126: 541, 161: 333, 162: 500, 163: 500, 164: 167, 165: 500, 166: 500, 167: 500, 168: 500, 169: 180, 170: 444, 171: 500, 172: 333, 173: 333, 174: 556, 175: 556, 177: 500, 178: 500, 179: 500, 180: 250, 182: 453, 183: 350, 184: 333, 185: 444, 186: 444, 187: 500, 188: 1000, 189: 1000, 191: 444, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 1000, 225: 889, 227: 276, 232: 611, 233: 722, 234: 889, 235: 310, 241: 667, 245: 278, 248: 278, 249: 500, 250: 722, 251: 500}), - 'Helvetica-Oblique': ({'FontName': 'Helvetica-Oblique', 'Descent': -207.0, 'FontBBox': (-171.0, -225.0, 1116.0, 931.0), 'FontWeight': 'Medium', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 523.0, 'ItalicAngle': -12.0, 'Ascent': 718.0}, {32: 278, 33: 278, 34: 355, 35: 556, 36: 556, 37: 889, 38: 667, 39: 222, 40: 333, 41: 333, 42: 389, 43: 584, 44: 278, 45: 333, 46: 278, 47: 278, 48: 556, 49: 556, 50: 556, 51: 556, 52: 556, 53: 556, 54: 556, 55: 556, 56: 556, 57: 556, 58: 278, 59: 278, 60: 584, 61: 584, 62: 584, 63: 556, 64: 1015, 65: 667, 66: 667, 67: 722, 68: 722, 69: 667, 70: 611, 71: 778, 72: 722, 73: 278, 74: 500, 75: 667, 76: 556, 77: 833, 78: 722, 79: 778, 80: 667, 81: 778, 82: 722, 83: 667, 84: 611, 85: 722, 86: 667, 87: 944, 88: 667, 89: 667, 90: 611, 91: 278, 92: 278, 93: 278, 94: 469, 95: 556, 96: 222, 97: 556, 98: 556, 99: 500, 100: 556, 101: 556, 102: 278, 103: 556, 104: 556, 105: 222, 106: 222, 107: 500, 108: 222, 109: 833, 110: 556, 111: 556, 112: 556, 113: 556, 114: 333, 115: 500, 116: 278, 117: 556, 118: 500, 119: 722, 120: 500, 121: 500, 122: 500, 123: 334, 124: 260, 125: 334, 126: 584, 161: 333, 162: 556, 163: 556, 164: 167, 165: 556, 166: 556, 167: 556, 168: 556, 169: 191, 170: 333, 171: 556, 172: 333, 173: 333, 174: 500, 175: 500, 177: 556, 178: 556, 179: 556, 180: 278, 182: 537, 183: 350, 184: 222, 185: 333, 186: 333, 187: 556, 188: 1000, 189: 1000, 191: 611, 193: 333, 194: 333, 195: 333, 196: 333, 197: 333, 198: 333, 199: 333, 200: 333, 202: 333, 203: 333, 205: 333, 206: 333, 207: 333, 208: 1000, 225: 1000, 227: 370, 232: 556, 233: 778, 234: 1000, 235: 365, 241: 889, 245: 278, 248: 222, 249: 611, 250: 944, 251: 611}), + 'Courier': ({'FontName': 'Courier', 'Descent': -194.0, 'FontBBox': (-6.0, -249.0, 639.0, 803.0), 'FontWeight': 'Medium', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': 0.0, 'Ascent': 627.0}, {u' ': 600, u'!': 600, u'"': 600, u'#': 600, u'$': 600, u'%': 600, u'&': 600, u"'": 600, u'(': 600, u')': 600, u'*': 600, u'+': 600, u',': 600, u'-': 600, u'.': 600, u'/': 600, u'0': 600, u'1': 600, u'2': 600, u'3': 600, u'4': 600, u'5': 600, u'6': 600, u'7': 600, u'8': 600, u'9': 600, u':': 600, u';': 600, u'<': 600, u'=': 600, u'>': 600, u'?': 600, u'@': 600, u'A': 600, u'B': 600, u'C': 600, u'D': 600, u'E': 600, u'F': 600, u'G': 600, u'H': 600, u'I': 600, u'J': 600, u'K': 600, u'L': 600, u'M': 600, u'N': 600, u'O': 600, u'P': 600, u'Q': 600, u'R': 600, u'S': 600, u'T': 600, u'U': 600, u'V': 600, u'W': 600, u'X': 600, u'Y': 600, u'Z': 600, u'[': 600, u'\\': 600, u']': 600, u'^': 600, u'_': 600, u'`': 600, u'a': 600, u'b': 600, u'c': 600, u'd': 600, u'e': 600, u'f': 600, u'g': 600, u'h': 600, u'i': 600, u'j': 600, u'k': 600, u'l': 600, u'm': 600, u'n': 600, u'o': 600, u'p': 600, u'q': 600, u'r': 600, u's': 600, u't': 600, u'u': 600, u'v': 600, u'w': 600, u'x': 600, u'y': 600, u'z': 600, u'{': 600, u'|': 600, u'}': 600, u'~': 600, u'\xa1': 600, u'\xa2': 600, u'\xa3': 600, u'\xa4': 600, u'\xa5': 600, u'\xa6': 600, u'\xa7': 600, u'\xa8': 600, u'\xa9': 600, u'\xaa': 600, u'\xab': 600, u'\xac': 600, u'\xae': 600, u'\xaf': 600, u'\xb0': 600, u'\xb1': 600, u'\xb2': 600, u'\xb3': 600, u'\xb4': 600, u'\xb5': 600, u'\xb6': 600, u'\xb7': 600, u'\xb8': 600, u'\xb9': 600, u'\xba': 600, u'\xbb': 600, u'\xbc': 600, u'\xbd': 600, u'\xbe': 600, u'\xbf': 600, u'\xc0': 600, u'\xc1': 600, u'\xc2': 600, u'\xc3': 600, u'\xc4': 600, u'\xc5': 600, u'\xc6': 600, u'\xc7': 600, u'\xc8': 600, u'\xc9': 600, u'\xca': 600, u'\xcb': 600, u'\xcc': 600, u'\xcd': 600, u'\xce': 600, u'\xcf': 600, u'\xd0': 600, u'\xd1': 600, u'\xd2': 600, u'\xd3': 600, u'\xd4': 600, u'\xd5': 600, u'\xd6': 600, u'\xd7': 600, u'\xd8': 600, u'\xd9': 600, u'\xda': 600, u'\xdb': 600, u'\xdc': 600, u'\xdd': 600, u'\xde': 600, u'\xdf': 600, u'\xe0': 600, u'\xe1': 600, u'\xe2': 600, u'\xe3': 600, u'\xe4': 600, u'\xe5': 600, u'\xe6': 600, u'\xe7': 600, u'\xe8': 600, u'\xe9': 600, u'\xea': 600, u'\xeb': 600, u'\xec': 600, u'\xed': 600, u'\xee': 600, u'\xef': 600, u'\xf0': 600, u'\xf1': 600, u'\xf2': 600, u'\xf3': 600, u'\xf4': 600, u'\xf5': 600, u'\xf6': 600, u'\xf7': 600, u'\xf8': 600, u'\xf9': 600, u'\xfa': 600, u'\xfb': 600, u'\xfc': 600, u'\xfd': 600, u'\xfe': 600, u'\xff': 600, u'\u0100': 600, u'\u0101': 600, u'\u0102': 600, u'\u0103': 600, u'\u0104': 600, u'\u0105': 600, u'\u0106': 600, u'\u0107': 600, u'\u010c': 600, u'\u010d': 600, u'\u010e': 600, u'\u010f': 600, u'\u0110': 600, u'\u0111': 600, u'\u0112': 600, u'\u0113': 600, u'\u0116': 600, u'\u0117': 600, u'\u0118': 600, u'\u0119': 600, u'\u011a': 600, u'\u011b': 600, u'\u011e': 600, u'\u011f': 600, u'\u0122': 600, u'\u0123': 600, u'\u012a': 600, u'\u012b': 600, u'\u012e': 600, u'\u012f': 600, u'\u0130': 600, u'\u0131': 600, u'\u0136': 600, u'\u0137': 600, u'\u0139': 600, u'\u013a': 600, u'\u013b': 600, u'\u013c': 600, u'\u013d': 600, u'\u013e': 600, u'\u0141': 600, u'\u0142': 600, u'\u0143': 600, u'\u0144': 600, u'\u0145': 600, u'\u0146': 600, u'\u0147': 600, u'\u0148': 600, u'\u014c': 600, u'\u014d': 600, u'\u0150': 600, u'\u0151': 600, u'\u0152': 600, u'\u0153': 600, u'\u0154': 600, u'\u0155': 600, u'\u0156': 600, u'\u0157': 600, u'\u0158': 600, u'\u0159': 600, u'\u015a': 600, u'\u015b': 600, u'\u015e': 600, u'\u015f': 600, u'\u0160': 600, u'\u0161': 600, u'\u0162': 600, u'\u0163': 600, u'\u0164': 600, u'\u0165': 600, u'\u016a': 600, u'\u016b': 600, u'\u016e': 600, u'\u016f': 600, u'\u0170': 600, u'\u0171': 600, u'\u0172': 600, u'\u0173': 600, u'\u0178': 600, u'\u0179': 600, u'\u017a': 600, u'\u017b': 600, u'\u017c': 600, u'\u017d': 600, u'\u017e': 600, u'\u0192': 600, u'\u0218': 600, u'\u0219': 600, u'\u02c6': 600, u'\u02c7': 600, u'\u02d8': 600, u'\u02d9': 600, u'\u02da': 600, u'\u02db': 600, u'\u02dc': 600, u'\u02dd': 600, u'\u2013': 600, u'\u2014': 600, u'\u2018': 600, u'\u2019': 600, u'\u201a': 600, u'\u201c': 600, u'\u201d': 600, u'\u201e': 600, u'\u2020': 600, u'\u2021': 600, u'\u2022': 600, u'\u2026': 600, u'\u2030': 600, u'\u2039': 600, u'\u203a': 600, u'\u2044': 600, u'\u2122': 600, u'\u2202': 600, u'\u2206': 600, u'\u2211': 600, u'\u2212': 600, u'\u221a': 600, u'\u2260': 600, u'\u2264': 600, u'\u2265': 600, u'\u25ca': 600, u'\uf6c3': 600, u'\ufb01': 600, u'\ufb02': 600}), + 'Courier-Bold': ({'FontName': 'Courier-Bold', 'Descent': -194.0, 'FontBBox': (-88.0, -249.0, 697.0, 811.0), 'FontWeight': 'Bold', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': 0.0, 'Ascent': 627.0}, {u' ': 600, u'!': 600, u'"': 600, u'#': 600, u'$': 600, u'%': 600, u'&': 600, u"'": 600, u'(': 600, u')': 600, u'*': 600, u'+': 600, u',': 600, u'-': 600, u'.': 600, u'/': 600, u'0': 600, u'1': 600, u'2': 600, u'3': 600, u'4': 600, u'5': 600, u'6': 600, u'7': 600, u'8': 600, u'9': 600, u':': 600, u';': 600, u'<': 600, u'=': 600, u'>': 600, u'?': 600, u'@': 600, u'A': 600, u'B': 600, u'C': 600, u'D': 600, u'E': 600, u'F': 600, u'G': 600, u'H': 600, u'I': 600, u'J': 600, u'K': 600, u'L': 600, u'M': 600, u'N': 600, u'O': 600, u'P': 600, u'Q': 600, u'R': 600, u'S': 600, u'T': 600, u'U': 600, u'V': 600, u'W': 600, u'X': 600, u'Y': 600, u'Z': 600, u'[': 600, u'\\': 600, u']': 600, u'^': 600, u'_': 600, u'`': 600, u'a': 600, u'b': 600, u'c': 600, u'd': 600, u'e': 600, u'f': 600, u'g': 600, u'h': 600, u'i': 600, u'j': 600, u'k': 600, u'l': 600, u'm': 600, u'n': 600, u'o': 600, u'p': 600, u'q': 600, u'r': 600, u's': 600, u't': 600, u'u': 600, u'v': 600, u'w': 600, u'x': 600, u'y': 600, u'z': 600, u'{': 600, u'|': 600, u'}': 600, u'~': 600, u'\xa1': 600, u'\xa2': 600, u'\xa3': 600, u'\xa4': 600, u'\xa5': 600, u'\xa6': 600, u'\xa7': 600, u'\xa8': 600, u'\xa9': 600, u'\xaa': 600, u'\xab': 600, u'\xac': 600, u'\xae': 600, u'\xaf': 600, u'\xb0': 600, u'\xb1': 600, u'\xb2': 600, u'\xb3': 600, u'\xb4': 600, u'\xb5': 600, u'\xb6': 600, u'\xb7': 600, u'\xb8': 600, u'\xb9': 600, u'\xba': 600, u'\xbb': 600, u'\xbc': 600, u'\xbd': 600, u'\xbe': 600, u'\xbf': 600, u'\xc0': 600, u'\xc1': 600, u'\xc2': 600, u'\xc3': 600, u'\xc4': 600, u'\xc5': 600, u'\xc6': 600, u'\xc7': 600, u'\xc8': 600, u'\xc9': 600, u'\xca': 600, u'\xcb': 600, u'\xcc': 600, u'\xcd': 600, u'\xce': 600, u'\xcf': 600, u'\xd0': 600, u'\xd1': 600, u'\xd2': 600, u'\xd3': 600, u'\xd4': 600, u'\xd5': 600, u'\xd6': 600, u'\xd7': 600, u'\xd8': 600, u'\xd9': 600, u'\xda': 600, u'\xdb': 600, u'\xdc': 600, u'\xdd': 600, u'\xde': 600, u'\xdf': 600, u'\xe0': 600, u'\xe1': 600, u'\xe2': 600, u'\xe3': 600, u'\xe4': 600, u'\xe5': 600, u'\xe6': 600, u'\xe7': 600, u'\xe8': 600, u'\xe9': 600, u'\xea': 600, u'\xeb': 600, u'\xec': 600, u'\xed': 600, u'\xee': 600, u'\xef': 600, u'\xf0': 600, u'\xf1': 600, u'\xf2': 600, u'\xf3': 600, u'\xf4': 600, u'\xf5': 600, u'\xf6': 600, u'\xf7': 600, u'\xf8': 600, u'\xf9': 600, u'\xfa': 600, u'\xfb': 600, u'\xfc': 600, u'\xfd': 600, u'\xfe': 600, u'\xff': 600, u'\u0100': 600, u'\u0101': 600, u'\u0102': 600, u'\u0103': 600, u'\u0104': 600, u'\u0105': 600, u'\u0106': 600, u'\u0107': 600, u'\u010c': 600, u'\u010d': 600, u'\u010e': 600, u'\u010f': 600, u'\u0110': 600, u'\u0111': 600, u'\u0112': 600, u'\u0113': 600, u'\u0116': 600, u'\u0117': 600, u'\u0118': 600, u'\u0119': 600, u'\u011a': 600, u'\u011b': 600, u'\u011e': 600, u'\u011f': 600, u'\u0122': 600, u'\u0123': 600, u'\u012a': 600, u'\u012b': 600, u'\u012e': 600, u'\u012f': 600, u'\u0130': 600, u'\u0131': 600, u'\u0136': 600, u'\u0137': 600, u'\u0139': 600, u'\u013a': 600, u'\u013b': 600, u'\u013c': 600, u'\u013d': 600, u'\u013e': 600, u'\u0141': 600, u'\u0142': 600, u'\u0143': 600, u'\u0144': 600, u'\u0145': 600, u'\u0146': 600, u'\u0147': 600, u'\u0148': 600, u'\u014c': 600, u'\u014d': 600, u'\u0150': 600, u'\u0151': 600, u'\u0152': 600, u'\u0153': 600, u'\u0154': 600, u'\u0155': 600, u'\u0156': 600, u'\u0157': 600, u'\u0158': 600, u'\u0159': 600, u'\u015a': 600, u'\u015b': 600, u'\u015e': 600, u'\u015f': 600, u'\u0160': 600, u'\u0161': 600, u'\u0162': 600, u'\u0163': 600, u'\u0164': 600, u'\u0165': 600, u'\u016a': 600, u'\u016b': 600, u'\u016e': 600, u'\u016f': 600, u'\u0170': 600, u'\u0171': 600, u'\u0172': 600, u'\u0173': 600, u'\u0178': 600, u'\u0179': 600, u'\u017a': 600, u'\u017b': 600, u'\u017c': 600, u'\u017d': 600, u'\u017e': 600, u'\u0192': 600, u'\u0218': 600, u'\u0219': 600, u'\u02c6': 600, u'\u02c7': 600, u'\u02d8': 600, u'\u02d9': 600, u'\u02da': 600, u'\u02db': 600, u'\u02dc': 600, u'\u02dd': 600, u'\u2013': 600, u'\u2014': 600, u'\u2018': 600, u'\u2019': 600, u'\u201a': 600, u'\u201c': 600, u'\u201d': 600, u'\u201e': 600, u'\u2020': 600, u'\u2021': 600, u'\u2022': 600, u'\u2026': 600, u'\u2030': 600, u'\u2039': 600, u'\u203a': 600, u'\u2044': 600, u'\u2122': 600, u'\u2202': 600, u'\u2206': 600, u'\u2211': 600, u'\u2212': 600, u'\u221a': 600, u'\u2260': 600, u'\u2264': 600, u'\u2265': 600, u'\u25ca': 600, u'\uf6c3': 600, u'\ufb01': 600, u'\ufb02': 600}), + 'Courier-BoldOblique': ({'FontName': 'Courier-BoldOblique', 'Descent': -194.0, 'FontBBox': (-49.0, -249.0, 758.0, 811.0), 'FontWeight': 'Bold', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': -11.0, 'Ascent': 627.0}, {u' ': 600, u'!': 600, u'"': 600, u'#': 600, u'$': 600, u'%': 600, u'&': 600, u"'": 600, u'(': 600, u')': 600, u'*': 600, u'+': 600, u',': 600, u'-': 600, u'.': 600, u'/': 600, u'0': 600, u'1': 600, u'2': 600, u'3': 600, u'4': 600, u'5': 600, u'6': 600, u'7': 600, u'8': 600, u'9': 600, u':': 600, u';': 600, u'<': 600, u'=': 600, u'>': 600, u'?': 600, u'@': 600, u'A': 600, u'B': 600, u'C': 600, u'D': 600, u'E': 600, u'F': 600, u'G': 600, u'H': 600, u'I': 600, u'J': 600, u'K': 600, u'L': 600, u'M': 600, u'N': 600, u'O': 600, u'P': 600, u'Q': 600, u'R': 600, u'S': 600, u'T': 600, u'U': 600, u'V': 600, u'W': 600, u'X': 600, u'Y': 600, u'Z': 600, u'[': 600, u'\\': 600, u']': 600, u'^': 600, u'_': 600, u'`': 600, u'a': 600, u'b': 600, u'c': 600, u'd': 600, u'e': 600, u'f': 600, u'g': 600, u'h': 600, u'i': 600, u'j': 600, u'k': 600, u'l': 600, u'm': 600, u'n': 600, u'o': 600, u'p': 600, u'q': 600, u'r': 600, u's': 600, u't': 600, u'u': 600, u'v': 600, u'w': 600, u'x': 600, u'y': 600, u'z': 600, u'{': 600, u'|': 600, u'}': 600, u'~': 600, u'\xa1': 600, u'\xa2': 600, u'\xa3': 600, u'\xa4': 600, u'\xa5': 600, u'\xa6': 600, u'\xa7': 600, u'\xa8': 600, u'\xa9': 600, u'\xaa': 600, u'\xab': 600, u'\xac': 600, u'\xae': 600, u'\xaf': 600, u'\xb0': 600, u'\xb1': 600, u'\xb2': 600, u'\xb3': 600, u'\xb4': 600, u'\xb5': 600, u'\xb6': 600, u'\xb7': 600, u'\xb8': 600, u'\xb9': 600, u'\xba': 600, u'\xbb': 600, u'\xbc': 600, u'\xbd': 600, u'\xbe': 600, u'\xbf': 600, u'\xc0': 600, u'\xc1': 600, u'\xc2': 600, u'\xc3': 600, u'\xc4': 600, u'\xc5': 600, u'\xc6': 600, u'\xc7': 600, u'\xc8': 600, u'\xc9': 600, u'\xca': 600, u'\xcb': 600, u'\xcc': 600, u'\xcd': 600, u'\xce': 600, u'\xcf': 600, u'\xd0': 600, u'\xd1': 600, u'\xd2': 600, u'\xd3': 600, u'\xd4': 600, u'\xd5': 600, u'\xd6': 600, u'\xd7': 600, u'\xd8': 600, u'\xd9': 600, u'\xda': 600, u'\xdb': 600, u'\xdc': 600, u'\xdd': 600, u'\xde': 600, u'\xdf': 600, u'\xe0': 600, u'\xe1': 600, u'\xe2': 600, u'\xe3': 600, u'\xe4': 600, u'\xe5': 600, u'\xe6': 600, u'\xe7': 600, u'\xe8': 600, u'\xe9': 600, u'\xea': 600, u'\xeb': 600, u'\xec': 600, u'\xed': 600, u'\xee': 600, u'\xef': 600, u'\xf0': 600, u'\xf1': 600, u'\xf2': 600, u'\xf3': 600, u'\xf4': 600, u'\xf5': 600, u'\xf6': 600, u'\xf7': 600, u'\xf8': 600, u'\xf9': 600, u'\xfa': 600, u'\xfb': 600, u'\xfc': 600, u'\xfd': 600, u'\xfe': 600, u'\xff': 600, u'\u0100': 600, u'\u0101': 600, u'\u0102': 600, u'\u0103': 600, u'\u0104': 600, u'\u0105': 600, u'\u0106': 600, u'\u0107': 600, u'\u010c': 600, u'\u010d': 600, u'\u010e': 600, u'\u010f': 600, u'\u0110': 600, u'\u0111': 600, u'\u0112': 600, u'\u0113': 600, u'\u0116': 600, u'\u0117': 600, u'\u0118': 600, u'\u0119': 600, u'\u011a': 600, u'\u011b': 600, u'\u011e': 600, u'\u011f': 600, u'\u0122': 600, u'\u0123': 600, u'\u012a': 600, u'\u012b': 600, u'\u012e': 600, u'\u012f': 600, u'\u0130': 600, u'\u0131': 600, u'\u0136': 600, u'\u0137': 600, u'\u0139': 600, u'\u013a': 600, u'\u013b': 600, u'\u013c': 600, u'\u013d': 600, u'\u013e': 600, u'\u0141': 600, u'\u0142': 600, u'\u0143': 600, u'\u0144': 600, u'\u0145': 600, u'\u0146': 600, u'\u0147': 600, u'\u0148': 600, u'\u014c': 600, u'\u014d': 600, u'\u0150': 600, u'\u0151': 600, u'\u0152': 600, u'\u0153': 600, u'\u0154': 600, u'\u0155': 600, u'\u0156': 600, u'\u0157': 600, u'\u0158': 600, u'\u0159': 600, u'\u015a': 600, u'\u015b': 600, u'\u015e': 600, u'\u015f': 600, u'\u0160': 600, u'\u0161': 600, u'\u0162': 600, u'\u0163': 600, u'\u0164': 600, u'\u0165': 600, u'\u016a': 600, u'\u016b': 600, u'\u016e': 600, u'\u016f': 600, u'\u0170': 600, u'\u0171': 600, u'\u0172': 600, u'\u0173': 600, u'\u0178': 600, u'\u0179': 600, u'\u017a': 600, u'\u017b': 600, u'\u017c': 600, u'\u017d': 600, u'\u017e': 600, u'\u0192': 600, u'\u0218': 600, u'\u0219': 600, u'\u02c6': 600, u'\u02c7': 600, u'\u02d8': 600, u'\u02d9': 600, u'\u02da': 600, u'\u02db': 600, u'\u02dc': 600, u'\u02dd': 600, u'\u2013': 600, u'\u2014': 600, u'\u2018': 600, u'\u2019': 600, u'\u201a': 600, u'\u201c': 600, u'\u201d': 600, u'\u201e': 600, u'\u2020': 600, u'\u2021': 600, u'\u2022': 600, u'\u2026': 600, u'\u2030': 600, u'\u2039': 600, u'\u203a': 600, u'\u2044': 600, u'\u2122': 600, u'\u2202': 600, u'\u2206': 600, u'\u2211': 600, u'\u2212': 600, u'\u221a': 600, u'\u2260': 600, u'\u2264': 600, u'\u2265': 600, u'\u25ca': 600, u'\uf6c3': 600, u'\ufb01': 600, u'\ufb02': 600}), + 'Courier-Oblique': ({'FontName': 'Courier-Oblique', 'Descent': -194.0, 'FontBBox': (-49.0, -249.0, 749.0, 803.0), 'FontWeight': 'Medium', 'CapHeight': 572.0, 'FontFamily': 'Courier', 'Flags': 64, 'XHeight': 434.0, 'ItalicAngle': -11.0, 'Ascent': 627.0}, {u' ': 600, u'!': 600, u'"': 600, u'#': 600, u'$': 600, u'%': 600, u'&': 600, u"'": 600, u'(': 600, u')': 600, u'*': 600, u'+': 600, u',': 600, u'-': 600, u'.': 600, u'/': 600, u'0': 600, u'1': 600, u'2': 600, u'3': 600, u'4': 600, u'5': 600, u'6': 600, u'7': 600, u'8': 600, u'9': 600, u':': 600, u';': 600, u'<': 600, u'=': 600, u'>': 600, u'?': 600, u'@': 600, u'A': 600, u'B': 600, u'C': 600, u'D': 600, u'E': 600, u'F': 600, u'G': 600, u'H': 600, u'I': 600, u'J': 600, u'K': 600, u'L': 600, u'M': 600, u'N': 600, u'O': 600, u'P': 600, u'Q': 600, u'R': 600, u'S': 600, u'T': 600, u'U': 600, u'V': 600, u'W': 600, u'X': 600, u'Y': 600, u'Z': 600, u'[': 600, u'\\': 600, u']': 600, u'^': 600, u'_': 600, u'`': 600, u'a': 600, u'b': 600, u'c': 600, u'd': 600, u'e': 600, u'f': 600, u'g': 600, u'h': 600, u'i': 600, u'j': 600, u'k': 600, u'l': 600, u'm': 600, u'n': 600, u'o': 600, u'p': 600, u'q': 600, u'r': 600, u's': 600, u't': 600, u'u': 600, u'v': 600, u'w': 600, u'x': 600, u'y': 600, u'z': 600, u'{': 600, u'|': 600, u'}': 600, u'~': 600, u'\xa1': 600, u'\xa2': 600, u'\xa3': 600, u'\xa4': 600, u'\xa5': 600, u'\xa6': 600, u'\xa7': 600, u'\xa8': 600, u'\xa9': 600, u'\xaa': 600, u'\xab': 600, u'\xac': 600, u'\xae': 600, u'\xaf': 600, u'\xb0': 600, u'\xb1': 600, u'\xb2': 600, u'\xb3': 600, u'\xb4': 600, u'\xb5': 600, u'\xb6': 600, u'\xb7': 600, u'\xb8': 600, u'\xb9': 600, u'\xba': 600, u'\xbb': 600, u'\xbc': 600, u'\xbd': 600, u'\xbe': 600, u'\xbf': 600, u'\xc0': 600, u'\xc1': 600, u'\xc2': 600, u'\xc3': 600, u'\xc4': 600, u'\xc5': 600, u'\xc6': 600, u'\xc7': 600, u'\xc8': 600, u'\xc9': 600, u'\xca': 600, u'\xcb': 600, u'\xcc': 600, u'\xcd': 600, u'\xce': 600, u'\xcf': 600, u'\xd0': 600, u'\xd1': 600, u'\xd2': 600, u'\xd3': 600, u'\xd4': 600, u'\xd5': 600, u'\xd6': 600, u'\xd7': 600, u'\xd8': 600, u'\xd9': 600, u'\xda': 600, u'\xdb': 600, u'\xdc': 600, u'\xdd': 600, u'\xde': 600, u'\xdf': 600, u'\xe0': 600, u'\xe1': 600, u'\xe2': 600, u'\xe3': 600, u'\xe4': 600, u'\xe5': 600, u'\xe6': 600, u'\xe7': 600, u'\xe8': 600, u'\xe9': 600, u'\xea': 600, u'\xeb': 600, u'\xec': 600, u'\xed': 600, u'\xee': 600, u'\xef': 600, u'\xf0': 600, u'\xf1': 600, u'\xf2': 600, u'\xf3': 600, u'\xf4': 600, u'\xf5': 600, u'\xf6': 600, u'\xf7': 600, u'\xf8': 600, u'\xf9': 600, u'\xfa': 600, u'\xfb': 600, u'\xfc': 600, u'\xfd': 600, u'\xfe': 600, u'\xff': 600, u'\u0100': 600, u'\u0101': 600, u'\u0102': 600, u'\u0103': 600, u'\u0104': 600, u'\u0105': 600, u'\u0106': 600, u'\u0107': 600, u'\u010c': 600, u'\u010d': 600, u'\u010e': 600, u'\u010f': 600, u'\u0110': 600, u'\u0111': 600, u'\u0112': 600, u'\u0113': 600, u'\u0116': 600, u'\u0117': 600, u'\u0118': 600, u'\u0119': 600, u'\u011a': 600, u'\u011b': 600, u'\u011e': 600, u'\u011f': 600, u'\u0122': 600, u'\u0123': 600, u'\u012a': 600, u'\u012b': 600, u'\u012e': 600, u'\u012f': 600, u'\u0130': 600, u'\u0131': 600, u'\u0136': 600, u'\u0137': 600, u'\u0139': 600, u'\u013a': 600, u'\u013b': 600, u'\u013c': 600, u'\u013d': 600, u'\u013e': 600, u'\u0141': 600, u'\u0142': 600, u'\u0143': 600, u'\u0144': 600, u'\u0145': 600, u'\u0146': 600, u'\u0147': 600, u'\u0148': 600, u'\u014c': 600, u'\u014d': 600, u'\u0150': 600, u'\u0151': 600, u'\u0152': 600, u'\u0153': 600, u'\u0154': 600, u'\u0155': 600, u'\u0156': 600, u'\u0157': 600, u'\u0158': 600, u'\u0159': 600, u'\u015a': 600, u'\u015b': 600, u'\u015e': 600, u'\u015f': 600, u'\u0160': 600, u'\u0161': 600, u'\u0162': 600, u'\u0163': 600, u'\u0164': 600, u'\u0165': 600, u'\u016a': 600, u'\u016b': 600, u'\u016e': 600, u'\u016f': 600, u'\u0170': 600, u'\u0171': 600, u'\u0172': 600, u'\u0173': 600, u'\u0178': 600, u'\u0179': 600, u'\u017a': 600, u'\u017b': 600, u'\u017c': 600, u'\u017d': 600, u'\u017e': 600, u'\u0192': 600, u'\u0218': 600, u'\u0219': 600, u'\u02c6': 600, u'\u02c7': 600, u'\u02d8': 600, u'\u02d9': 600, u'\u02da': 600, u'\u02db': 600, u'\u02dc': 600, u'\u02dd': 600, u'\u2013': 600, u'\u2014': 600, u'\u2018': 600, u'\u2019': 600, u'\u201a': 600, u'\u201c': 600, u'\u201d': 600, u'\u201e': 600, u'\u2020': 600, u'\u2021': 600, u'\u2022': 600, u'\u2026': 600, u'\u2030': 600, u'\u2039': 600, u'\u203a': 600, u'\u2044': 600, u'\u2122': 600, u'\u2202': 600, u'\u2206': 600, u'\u2211': 600, u'\u2212': 600, u'\u221a': 600, u'\u2260': 600, u'\u2264': 600, u'\u2265': 600, u'\u25ca': 600, u'\uf6c3': 600, u'\ufb01': 600, u'\ufb02': 600}), + 'Helvetica': ({'FontName': 'Helvetica', 'Descent': -207.0, 'FontBBox': (-166.0, -225.0, 1000.0, 931.0), 'FontWeight': 'Medium', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 523.0, 'ItalicAngle': 0.0, 'Ascent': 718.0}, {u' ': 278, u'!': 278, u'"': 355, u'#': 556, u'$': 556, u'%': 889, u'&': 667, u"'": 191, u'(': 333, u')': 333, u'*': 389, u'+': 584, u',': 278, u'-': 333, u'.': 278, u'/': 278, u'0': 556, u'1': 556, u'2': 556, u'3': 556, u'4': 556, u'5': 556, u'6': 556, u'7': 556, u'8': 556, u'9': 556, u':': 278, u';': 278, u'<': 584, u'=': 584, u'>': 584, u'?': 556, u'@': 1015, u'A': 667, u'B': 667, u'C': 722, u'D': 722, u'E': 667, u'F': 611, u'G': 778, u'H': 722, u'I': 278, u'J': 500, u'K': 667, u'L': 556, u'M': 833, u'N': 722, u'O': 778, u'P': 667, u'Q': 778, u'R': 722, u'S': 667, u'T': 611, u'U': 722, u'V': 667, u'W': 944, u'X': 667, u'Y': 667, u'Z': 611, u'[': 278, u'\\': 278, u']': 278, u'^': 469, u'_': 556, u'`': 333, u'a': 556, u'b': 556, u'c': 500, u'd': 556, u'e': 556, u'f': 278, u'g': 556, u'h': 556, u'i': 222, u'j': 222, u'k': 500, u'l': 222, u'm': 833, u'n': 556, u'o': 556, u'p': 556, u'q': 556, u'r': 333, u's': 500, u't': 278, u'u': 556, u'v': 500, u'w': 722, u'x': 500, u'y': 500, u'z': 500, u'{': 334, u'|': 260, u'}': 334, u'~': 584, u'\xa1': 333, u'\xa2': 556, u'\xa3': 556, u'\xa4': 556, u'\xa5': 556, u'\xa6': 260, u'\xa7': 556, u'\xa8': 333, u'\xa9': 737, u'\xaa': 370, u'\xab': 556, u'\xac': 584, u'\xae': 737, u'\xaf': 333, u'\xb0': 400, u'\xb1': 584, u'\xb2': 333, u'\xb3': 333, u'\xb4': 333, u'\xb5': 556, u'\xb6': 537, u'\xb7': 278, u'\xb8': 333, u'\xb9': 333, u'\xba': 365, u'\xbb': 556, u'\xbc': 834, u'\xbd': 834, u'\xbe': 834, u'\xbf': 611, u'\xc0': 667, u'\xc1': 667, u'\xc2': 667, u'\xc3': 667, u'\xc4': 667, u'\xc5': 667, u'\xc6': 1000, u'\xc7': 722, u'\xc8': 667, u'\xc9': 667, u'\xca': 667, u'\xcb': 667, u'\xcc': 278, u'\xcd': 278, u'\xce': 278, u'\xcf': 278, u'\xd0': 722, u'\xd1': 722, u'\xd2': 778, u'\xd3': 778, u'\xd4': 778, u'\xd5': 778, u'\xd6': 778, u'\xd7': 584, u'\xd8': 778, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 667, u'\xde': 667, u'\xdf': 611, u'\xe0': 556, u'\xe1': 556, u'\xe2': 556, u'\xe3': 556, u'\xe4': 556, u'\xe5': 556, u'\xe6': 889, u'\xe7': 500, u'\xe8': 556, u'\xe9': 556, u'\xea': 556, u'\xeb': 556, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 556, u'\xf1': 556, u'\xf2': 556, u'\xf3': 556, u'\xf4': 556, u'\xf5': 556, u'\xf6': 556, u'\xf7': 584, u'\xf8': 611, u'\xf9': 556, u'\xfa': 556, u'\xfb': 556, u'\xfc': 556, u'\xfd': 500, u'\xfe': 556, u'\xff': 500, u'\u0100': 667, u'\u0101': 556, u'\u0102': 667, u'\u0103': 556, u'\u0104': 667, u'\u0105': 556, u'\u0106': 722, u'\u0107': 500, u'\u010c': 722, u'\u010d': 500, u'\u010e': 722, u'\u010f': 643, u'\u0110': 722, u'\u0111': 556, u'\u0112': 667, u'\u0113': 556, u'\u0116': 667, u'\u0117': 556, u'\u0118': 667, u'\u0119': 556, u'\u011a': 667, u'\u011b': 556, u'\u011e': 778, u'\u011f': 556, u'\u0122': 778, u'\u0123': 556, u'\u012a': 278, u'\u012b': 278, u'\u012e': 278, u'\u012f': 222, u'\u0130': 278, u'\u0131': 278, u'\u0136': 667, u'\u0137': 500, u'\u0139': 556, u'\u013a': 222, u'\u013b': 556, u'\u013c': 222, u'\u013d': 556, u'\u013e': 299, u'\u0141': 556, u'\u0142': 222, u'\u0143': 722, u'\u0144': 556, u'\u0145': 722, u'\u0146': 556, u'\u0147': 722, u'\u0148': 556, u'\u014c': 778, u'\u014d': 556, u'\u0150': 778, u'\u0151': 556, u'\u0152': 1000, u'\u0153': 944, u'\u0154': 722, u'\u0155': 333, u'\u0156': 722, u'\u0157': 333, u'\u0158': 722, u'\u0159': 333, u'\u015a': 667, u'\u015b': 500, u'\u015e': 667, u'\u015f': 500, u'\u0160': 667, u'\u0161': 500, u'\u0162': 611, u'\u0163': 278, u'\u0164': 611, u'\u0165': 317, u'\u016a': 722, u'\u016b': 556, u'\u016e': 722, u'\u016f': 556, u'\u0170': 722, u'\u0171': 556, u'\u0172': 722, u'\u0173': 556, u'\u0178': 667, u'\u0179': 611, u'\u017a': 500, u'\u017b': 611, u'\u017c': 500, u'\u017d': 611, u'\u017e': 500, u'\u0192': 556, u'\u0218': 667, u'\u0219': 500, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 556, u'\u2014': 1000, u'\u2018': 222, u'\u2019': 222, u'\u201a': 222, u'\u201c': 333, u'\u201d': 333, u'\u201e': 333, u'\u2020': 556, u'\u2021': 556, u'\u2022': 350, u'\u2026': 1000, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 1000, u'\u2202': 476, u'\u2206': 612, u'\u2211': 600, u'\u2212': 584, u'\u221a': 453, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 471, u'\uf6c3': 250, u'\ufb01': 500, u'\ufb02': 500}), + 'Helvetica-Bold': ({'FontName': 'Helvetica-Bold', 'Descent': -207.0, 'FontBBox': (-170.0, -228.0, 1003.0, 962.0), 'FontWeight': 'Bold', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 532.0, 'ItalicAngle': 0.0, 'Ascent': 718.0}, {u' ': 278, u'!': 333, u'"': 474, u'#': 556, u'$': 556, u'%': 889, u'&': 722, u"'": 238, u'(': 333, u')': 333, u'*': 389, u'+': 584, u',': 278, u'-': 333, u'.': 278, u'/': 278, u'0': 556, u'1': 556, u'2': 556, u'3': 556, u'4': 556, u'5': 556, u'6': 556, u'7': 556, u'8': 556, u'9': 556, u':': 333, u';': 333, u'<': 584, u'=': 584, u'>': 584, u'?': 611, u'@': 975, u'A': 722, u'B': 722, u'C': 722, u'D': 722, u'E': 667, u'F': 611, u'G': 778, u'H': 722, u'I': 278, u'J': 556, u'K': 722, u'L': 611, u'M': 833, u'N': 722, u'O': 778, u'P': 667, u'Q': 778, u'R': 722, u'S': 667, u'T': 611, u'U': 722, u'V': 667, u'W': 944, u'X': 667, u'Y': 667, u'Z': 611, u'[': 333, u'\\': 278, u']': 333, u'^': 584, u'_': 556, u'`': 333, u'a': 556, u'b': 611, u'c': 556, u'd': 611, u'e': 556, u'f': 333, u'g': 611, u'h': 611, u'i': 278, u'j': 278, u'k': 556, u'l': 278, u'm': 889, u'n': 611, u'o': 611, u'p': 611, u'q': 611, u'r': 389, u's': 556, u't': 333, u'u': 611, u'v': 556, u'w': 778, u'x': 556, u'y': 556, u'z': 500, u'{': 389, u'|': 280, u'}': 389, u'~': 584, u'\xa1': 333, u'\xa2': 556, u'\xa3': 556, u'\xa4': 556, u'\xa5': 556, u'\xa6': 280, u'\xa7': 556, u'\xa8': 333, u'\xa9': 737, u'\xaa': 370, u'\xab': 556, u'\xac': 584, u'\xae': 737, u'\xaf': 333, u'\xb0': 400, u'\xb1': 584, u'\xb2': 333, u'\xb3': 333, u'\xb4': 333, u'\xb5': 611, u'\xb6': 556, u'\xb7': 278, u'\xb8': 333, u'\xb9': 333, u'\xba': 365, u'\xbb': 556, u'\xbc': 834, u'\xbd': 834, u'\xbe': 834, u'\xbf': 611, u'\xc0': 722, u'\xc1': 722, u'\xc2': 722, u'\xc3': 722, u'\xc4': 722, u'\xc5': 722, u'\xc6': 1000, u'\xc7': 722, u'\xc8': 667, u'\xc9': 667, u'\xca': 667, u'\xcb': 667, u'\xcc': 278, u'\xcd': 278, u'\xce': 278, u'\xcf': 278, u'\xd0': 722, u'\xd1': 722, u'\xd2': 778, u'\xd3': 778, u'\xd4': 778, u'\xd5': 778, u'\xd6': 778, u'\xd7': 584, u'\xd8': 778, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 667, u'\xde': 667, u'\xdf': 611, u'\xe0': 556, u'\xe1': 556, u'\xe2': 556, u'\xe3': 556, u'\xe4': 556, u'\xe5': 556, u'\xe6': 889, u'\xe7': 556, u'\xe8': 556, u'\xe9': 556, u'\xea': 556, u'\xeb': 556, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 611, u'\xf1': 611, u'\xf2': 611, u'\xf3': 611, u'\xf4': 611, u'\xf5': 611, u'\xf6': 611, u'\xf7': 584, u'\xf8': 611, u'\xf9': 611, u'\xfa': 611, u'\xfb': 611, u'\xfc': 611, u'\xfd': 556, u'\xfe': 611, u'\xff': 556, u'\u0100': 722, u'\u0101': 556, u'\u0102': 722, u'\u0103': 556, u'\u0104': 722, u'\u0105': 556, u'\u0106': 722, u'\u0107': 556, u'\u010c': 722, u'\u010d': 556, u'\u010e': 722, u'\u010f': 743, u'\u0110': 722, u'\u0111': 611, u'\u0112': 667, u'\u0113': 556, u'\u0116': 667, u'\u0117': 556, u'\u0118': 667, u'\u0119': 556, u'\u011a': 667, u'\u011b': 556, u'\u011e': 778, u'\u011f': 611, u'\u0122': 778, u'\u0123': 611, u'\u012a': 278, u'\u012b': 278, u'\u012e': 278, u'\u012f': 278, u'\u0130': 278, u'\u0131': 278, u'\u0136': 722, u'\u0137': 556, u'\u0139': 611, u'\u013a': 278, u'\u013b': 611, u'\u013c': 278, u'\u013d': 611, u'\u013e': 400, u'\u0141': 611, u'\u0142': 278, u'\u0143': 722, u'\u0144': 611, u'\u0145': 722, u'\u0146': 611, u'\u0147': 722, u'\u0148': 611, u'\u014c': 778, u'\u014d': 611, u'\u0150': 778, u'\u0151': 611, u'\u0152': 1000, u'\u0153': 944, u'\u0154': 722, u'\u0155': 389, u'\u0156': 722, u'\u0157': 389, u'\u0158': 722, u'\u0159': 389, u'\u015a': 667, u'\u015b': 556, u'\u015e': 667, u'\u015f': 556, u'\u0160': 667, u'\u0161': 556, u'\u0162': 611, u'\u0163': 333, u'\u0164': 611, u'\u0165': 389, u'\u016a': 722, u'\u016b': 611, u'\u016e': 722, u'\u016f': 611, u'\u0170': 722, u'\u0171': 611, u'\u0172': 722, u'\u0173': 611, u'\u0178': 667, u'\u0179': 611, u'\u017a': 500, u'\u017b': 611, u'\u017c': 500, u'\u017d': 611, u'\u017e': 500, u'\u0192': 556, u'\u0218': 667, u'\u0219': 556, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 556, u'\u2014': 1000, u'\u2018': 278, u'\u2019': 278, u'\u201a': 278, u'\u201c': 500, u'\u201d': 500, u'\u201e': 500, u'\u2020': 556, u'\u2021': 556, u'\u2022': 350, u'\u2026': 1000, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 1000, u'\u2202': 494, u'\u2206': 612, u'\u2211': 600, u'\u2212': 584, u'\u221a': 549, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 494, u'\uf6c3': 250, u'\ufb01': 611, u'\ufb02': 611}), + 'Helvetica-BoldOblique': ({'FontName': 'Helvetica-BoldOblique', 'Descent': -207.0, 'FontBBox': (-175.0, -228.0, 1114.0, 962.0), 'FontWeight': 'Bold', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 532.0, 'ItalicAngle': -12.0, 'Ascent': 718.0}, {u' ': 278, u'!': 333, u'"': 474, u'#': 556, u'$': 556, u'%': 889, u'&': 722, u"'": 238, u'(': 333, u')': 333, u'*': 389, u'+': 584, u',': 278, u'-': 333, u'.': 278, u'/': 278, u'0': 556, u'1': 556, u'2': 556, u'3': 556, u'4': 556, u'5': 556, u'6': 556, u'7': 556, u'8': 556, u'9': 556, u':': 333, u';': 333, u'<': 584, u'=': 584, u'>': 584, u'?': 611, u'@': 975, u'A': 722, u'B': 722, u'C': 722, u'D': 722, u'E': 667, u'F': 611, u'G': 778, u'H': 722, u'I': 278, u'J': 556, u'K': 722, u'L': 611, u'M': 833, u'N': 722, u'O': 778, u'P': 667, u'Q': 778, u'R': 722, u'S': 667, u'T': 611, u'U': 722, u'V': 667, u'W': 944, u'X': 667, u'Y': 667, u'Z': 611, u'[': 333, u'\\': 278, u']': 333, u'^': 584, u'_': 556, u'`': 333, u'a': 556, u'b': 611, u'c': 556, u'd': 611, u'e': 556, u'f': 333, u'g': 611, u'h': 611, u'i': 278, u'j': 278, u'k': 556, u'l': 278, u'm': 889, u'n': 611, u'o': 611, u'p': 611, u'q': 611, u'r': 389, u's': 556, u't': 333, u'u': 611, u'v': 556, u'w': 778, u'x': 556, u'y': 556, u'z': 500, u'{': 389, u'|': 280, u'}': 389, u'~': 584, u'\xa1': 333, u'\xa2': 556, u'\xa3': 556, u'\xa4': 556, u'\xa5': 556, u'\xa6': 280, u'\xa7': 556, u'\xa8': 333, u'\xa9': 737, u'\xaa': 370, u'\xab': 556, u'\xac': 584, u'\xae': 737, u'\xaf': 333, u'\xb0': 400, u'\xb1': 584, u'\xb2': 333, u'\xb3': 333, u'\xb4': 333, u'\xb5': 611, u'\xb6': 556, u'\xb7': 278, u'\xb8': 333, u'\xb9': 333, u'\xba': 365, u'\xbb': 556, u'\xbc': 834, u'\xbd': 834, u'\xbe': 834, u'\xbf': 611, u'\xc0': 722, u'\xc1': 722, u'\xc2': 722, u'\xc3': 722, u'\xc4': 722, u'\xc5': 722, u'\xc6': 1000, u'\xc7': 722, u'\xc8': 667, u'\xc9': 667, u'\xca': 667, u'\xcb': 667, u'\xcc': 278, u'\xcd': 278, u'\xce': 278, u'\xcf': 278, u'\xd0': 722, u'\xd1': 722, u'\xd2': 778, u'\xd3': 778, u'\xd4': 778, u'\xd5': 778, u'\xd6': 778, u'\xd7': 584, u'\xd8': 778, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 667, u'\xde': 667, u'\xdf': 611, u'\xe0': 556, u'\xe1': 556, u'\xe2': 556, u'\xe3': 556, u'\xe4': 556, u'\xe5': 556, u'\xe6': 889, u'\xe7': 556, u'\xe8': 556, u'\xe9': 556, u'\xea': 556, u'\xeb': 556, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 611, u'\xf1': 611, u'\xf2': 611, u'\xf3': 611, u'\xf4': 611, u'\xf5': 611, u'\xf6': 611, u'\xf7': 584, u'\xf8': 611, u'\xf9': 611, u'\xfa': 611, u'\xfb': 611, u'\xfc': 611, u'\xfd': 556, u'\xfe': 611, u'\xff': 556, u'\u0100': 722, u'\u0101': 556, u'\u0102': 722, u'\u0103': 556, u'\u0104': 722, u'\u0105': 556, u'\u0106': 722, u'\u0107': 556, u'\u010c': 722, u'\u010d': 556, u'\u010e': 722, u'\u010f': 743, u'\u0110': 722, u'\u0111': 611, u'\u0112': 667, u'\u0113': 556, u'\u0116': 667, u'\u0117': 556, u'\u0118': 667, u'\u0119': 556, u'\u011a': 667, u'\u011b': 556, u'\u011e': 778, u'\u011f': 611, u'\u0122': 778, u'\u0123': 611, u'\u012a': 278, u'\u012b': 278, u'\u012e': 278, u'\u012f': 278, u'\u0130': 278, u'\u0131': 278, u'\u0136': 722, u'\u0137': 556, u'\u0139': 611, u'\u013a': 278, u'\u013b': 611, u'\u013c': 278, u'\u013d': 611, u'\u013e': 400, u'\u0141': 611, u'\u0142': 278, u'\u0143': 722, u'\u0144': 611, u'\u0145': 722, u'\u0146': 611, u'\u0147': 722, u'\u0148': 611, u'\u014c': 778, u'\u014d': 611, u'\u0150': 778, u'\u0151': 611, u'\u0152': 1000, u'\u0153': 944, u'\u0154': 722, u'\u0155': 389, u'\u0156': 722, u'\u0157': 389, u'\u0158': 722, u'\u0159': 389, u'\u015a': 667, u'\u015b': 556, u'\u015e': 667, u'\u015f': 556, u'\u0160': 667, u'\u0161': 556, u'\u0162': 611, u'\u0163': 333, u'\u0164': 611, u'\u0165': 389, u'\u016a': 722, u'\u016b': 611, u'\u016e': 722, u'\u016f': 611, u'\u0170': 722, u'\u0171': 611, u'\u0172': 722, u'\u0173': 611, u'\u0178': 667, u'\u0179': 611, u'\u017a': 500, u'\u017b': 611, u'\u017c': 500, u'\u017d': 611, u'\u017e': 500, u'\u0192': 556, u'\u0218': 667, u'\u0219': 556, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 556, u'\u2014': 1000, u'\u2018': 278, u'\u2019': 278, u'\u201a': 278, u'\u201c': 500, u'\u201d': 500, u'\u201e': 500, u'\u2020': 556, u'\u2021': 556, u'\u2022': 350, u'\u2026': 1000, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 1000, u'\u2202': 494, u'\u2206': 612, u'\u2211': 600, u'\u2212': 584, u'\u221a': 549, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 494, u'\uf6c3': 250, u'\ufb01': 611, u'\ufb02': 611}), + 'Helvetica-Oblique': ({'FontName': 'Helvetica-Oblique', 'Descent': -207.0, 'FontBBox': (-171.0, -225.0, 1116.0, 931.0), 'FontWeight': 'Medium', 'CapHeight': 718.0, 'FontFamily': 'Helvetica', 'Flags': 0, 'XHeight': 523.0, 'ItalicAngle': -12.0, 'Ascent': 718.0}, {u' ': 278, u'!': 278, u'"': 355, u'#': 556, u'$': 556, u'%': 889, u'&': 667, u"'": 191, u'(': 333, u')': 333, u'*': 389, u'+': 584, u',': 278, u'-': 333, u'.': 278, u'/': 278, u'0': 556, u'1': 556, u'2': 556, u'3': 556, u'4': 556, u'5': 556, u'6': 556, u'7': 556, u'8': 556, u'9': 556, u':': 278, u';': 278, u'<': 584, u'=': 584, u'>': 584, u'?': 556, u'@': 1015, u'A': 667, u'B': 667, u'C': 722, u'D': 722, u'E': 667, u'F': 611, u'G': 778, u'H': 722, u'I': 278, u'J': 500, u'K': 667, u'L': 556, u'M': 833, u'N': 722, u'O': 778, u'P': 667, u'Q': 778, u'R': 722, u'S': 667, u'T': 611, u'U': 722, u'V': 667, u'W': 944, u'X': 667, u'Y': 667, u'Z': 611, u'[': 278, u'\\': 278, u']': 278, u'^': 469, u'_': 556, u'`': 333, u'a': 556, u'b': 556, u'c': 500, u'd': 556, u'e': 556, u'f': 278, u'g': 556, u'h': 556, u'i': 222, u'j': 222, u'k': 500, u'l': 222, u'm': 833, u'n': 556, u'o': 556, u'p': 556, u'q': 556, u'r': 333, u's': 500, u't': 278, u'u': 556, u'v': 500, u'w': 722, u'x': 500, u'y': 500, u'z': 500, u'{': 334, u'|': 260, u'}': 334, u'~': 584, u'\xa1': 333, u'\xa2': 556, u'\xa3': 556, u'\xa4': 556, u'\xa5': 556, u'\xa6': 260, u'\xa7': 556, u'\xa8': 333, u'\xa9': 737, u'\xaa': 370, u'\xab': 556, u'\xac': 584, u'\xae': 737, u'\xaf': 333, u'\xb0': 400, u'\xb1': 584, u'\xb2': 333, u'\xb3': 333, u'\xb4': 333, u'\xb5': 556, u'\xb6': 537, u'\xb7': 278, u'\xb8': 333, u'\xb9': 333, u'\xba': 365, u'\xbb': 556, u'\xbc': 834, u'\xbd': 834, u'\xbe': 834, u'\xbf': 611, u'\xc0': 667, u'\xc1': 667, u'\xc2': 667, u'\xc3': 667, u'\xc4': 667, u'\xc5': 667, u'\xc6': 1000, u'\xc7': 722, u'\xc8': 667, u'\xc9': 667, u'\xca': 667, u'\xcb': 667, u'\xcc': 278, u'\xcd': 278, u'\xce': 278, u'\xcf': 278, u'\xd0': 722, u'\xd1': 722, u'\xd2': 778, u'\xd3': 778, u'\xd4': 778, u'\xd5': 778, u'\xd6': 778, u'\xd7': 584, u'\xd8': 778, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 667, u'\xde': 667, u'\xdf': 611, u'\xe0': 556, u'\xe1': 556, u'\xe2': 556, u'\xe3': 556, u'\xe4': 556, u'\xe5': 556, u'\xe6': 889, u'\xe7': 500, u'\xe8': 556, u'\xe9': 556, u'\xea': 556, u'\xeb': 556, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 556, u'\xf1': 556, u'\xf2': 556, u'\xf3': 556, u'\xf4': 556, u'\xf5': 556, u'\xf6': 556, u'\xf7': 584, u'\xf8': 611, u'\xf9': 556, u'\xfa': 556, u'\xfb': 556, u'\xfc': 556, u'\xfd': 500, u'\xfe': 556, u'\xff': 500, u'\u0100': 667, u'\u0101': 556, u'\u0102': 667, u'\u0103': 556, u'\u0104': 667, u'\u0105': 556, u'\u0106': 722, u'\u0107': 500, u'\u010c': 722, u'\u010d': 500, u'\u010e': 722, u'\u010f': 643, u'\u0110': 722, u'\u0111': 556, u'\u0112': 667, u'\u0113': 556, u'\u0116': 667, u'\u0117': 556, u'\u0118': 667, u'\u0119': 556, u'\u011a': 667, u'\u011b': 556, u'\u011e': 778, u'\u011f': 556, u'\u0122': 778, u'\u0123': 556, u'\u012a': 278, u'\u012b': 278, u'\u012e': 278, u'\u012f': 222, u'\u0130': 278, u'\u0131': 278, u'\u0136': 667, u'\u0137': 500, u'\u0139': 556, u'\u013a': 222, u'\u013b': 556, u'\u013c': 222, u'\u013d': 556, u'\u013e': 299, u'\u0141': 556, u'\u0142': 222, u'\u0143': 722, u'\u0144': 556, u'\u0145': 722, u'\u0146': 556, u'\u0147': 722, u'\u0148': 556, u'\u014c': 778, u'\u014d': 556, u'\u0150': 778, u'\u0151': 556, u'\u0152': 1000, u'\u0153': 944, u'\u0154': 722, u'\u0155': 333, u'\u0156': 722, u'\u0157': 333, u'\u0158': 722, u'\u0159': 333, u'\u015a': 667, u'\u015b': 500, u'\u015e': 667, u'\u015f': 500, u'\u0160': 667, u'\u0161': 500, u'\u0162': 611, u'\u0163': 278, u'\u0164': 611, u'\u0165': 317, u'\u016a': 722, u'\u016b': 556, u'\u016e': 722, u'\u016f': 556, u'\u0170': 722, u'\u0171': 556, u'\u0172': 722, u'\u0173': 556, u'\u0178': 667, u'\u0179': 611, u'\u017a': 500, u'\u017b': 611, u'\u017c': 500, u'\u017d': 611, u'\u017e': 500, u'\u0192': 556, u'\u0218': 667, u'\u0219': 500, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 556, u'\u2014': 1000, u'\u2018': 222, u'\u2019': 222, u'\u201a': 222, u'\u201c': 333, u'\u201d': 333, u'\u201e': 333, u'\u2020': 556, u'\u2021': 556, u'\u2022': 350, u'\u2026': 1000, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 1000, u'\u2202': 476, u'\u2206': 612, u'\u2211': 600, u'\u2212': 584, u'\u221a': 453, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 471, u'\uf6c3': 250, u'\ufb01': 500, u'\ufb02': 500}), + 'Symbol': ({'FontName': 'Symbol', 'FontBBox': (-180.0, -293.0, 1090.0, 1010.0), 'FontWeight': 'Medium', 'FontFamily': 'Symbol', 'Flags': 0, 'ItalicAngle': 0.0}, {u' ': 250, u'!': 333, u'#': 500, u'%': 833, u'&': 778, u'(': 333, u')': 333, u'+': 549, u',': 250, u'.': 250, u'/': 278, u'0': 500, u'1': 500, u'2': 500, u'3': 500, u'4': 500, u'5': 500, u'6': 500, u'7': 500, u'8': 500, u'9': 500, u':': 278, u';': 278, u'<': 549, u'=': 549, u'>': 549, u'?': 444, u'[': 333, u']': 333, u'_': 500, u'{': 480, u'|': 200, u'}': 480, u'\xac': 713, u'\xb0': 400, u'\xb1': 549, u'\xb5': 576, u'\xd7': 549, u'\xf7': 549, u'\u0192': 500, u'\u0391': 722, u'\u0392': 667, u'\u0393': 603, u'\u0395': 611, u'\u0396': 611, u'\u0397': 722, u'\u0398': 741, u'\u0399': 333, u'\u039a': 722, u'\u039b': 686, u'\u039c': 889, u'\u039d': 722, u'\u039e': 645, u'\u039f': 722, u'\u03a0': 768, u'\u03a1': 556, u'\u03a3': 592, u'\u03a4': 611, u'\u03a5': 690, u'\u03a6': 763, u'\u03a7': 722, u'\u03a8': 795, u'\u03b1': 631, u'\u03b2': 549, u'\u03b3': 411, u'\u03b4': 494, u'\u03b5': 439, u'\u03b6': 494, u'\u03b7': 603, u'\u03b8': 521, u'\u03b9': 329, u'\u03ba': 549, u'\u03bb': 549, u'\u03bd': 521, u'\u03be': 493, u'\u03bf': 549, u'\u03c0': 549, u'\u03c1': 549, u'\u03c2': 439, u'\u03c3': 603, u'\u03c4': 439, u'\u03c5': 576, u'\u03c6': 521, u'\u03c7': 549, u'\u03c8': 686, u'\u03c9': 686, u'\u03d1': 631, u'\u03d2': 620, u'\u03d5': 603, u'\u03d6': 713, u'\u2022': 460, u'\u2026': 1000, u'\u2032': 247, u'\u2033': 411, u'\u2044': 167, u'\u20ac': 750, u'\u2111': 686, u'\u2118': 987, u'\u211c': 795, u'\u2126': 768, u'\u2135': 823, u'\u2190': 987, u'\u2191': 603, u'\u2192': 987, u'\u2193': 603, u'\u2194': 1042, u'\u21b5': 658, u'\u21d0': 987, u'\u21d1': 603, u'\u21d2': 987, u'\u21d3': 603, u'\u21d4': 1042, u'\u2200': 713, u'\u2202': 494, u'\u2203': 549, u'\u2205': 823, u'\u2206': 612, u'\u2207': 713, u'\u2208': 713, u'\u2209': 713, u'\u220b': 439, u'\u220f': 823, u'\u2211': 713, u'\u2212': 549, u'\u2217': 500, u'\u221a': 549, u'\u221d': 713, u'\u221e': 713, u'\u2220': 768, u'\u2227': 603, u'\u2228': 603, u'\u2229': 768, u'\u222a': 768, u'\u222b': 274, u'\u2234': 863, u'\u223c': 549, u'\u2245': 549, u'\u2248': 549, u'\u2260': 549, u'\u2261': 549, u'\u2264': 549, u'\u2265': 549, u'\u2282': 713, u'\u2283': 713, u'\u2284': 713, u'\u2286': 713, u'\u2287': 713, u'\u2295': 768, u'\u2297': 768, u'\u22a5': 658, u'\u22c5': 250, u'\u2320': 686, u'\u2321': 686, u'\u2329': 329, u'\u232a': 329, u'\u25ca': 494, u'\u2660': 753, u'\u2663': 753, u'\u2665': 753, u'\u2666': 753, u'\uf6d9': 790, u'\uf6da': 790, u'\uf6db': 890, u'\uf8e5': 500, u'\uf8e6': 603, u'\uf8e7': 1000, u'\uf8e8': 790, u'\uf8e9': 790, u'\uf8ea': 786, u'\uf8eb': 384, u'\uf8ec': 384, u'\uf8ed': 384, u'\uf8ee': 384, u'\uf8ef': 384, u'\uf8f0': 384, u'\uf8f1': 494, u'\uf8f2': 494, u'\uf8f3': 494, u'\uf8f4': 494, u'\uf8f5': 686, u'\uf8f6': 384, u'\uf8f7': 384, u'\uf8f8': 384, u'\uf8f9': 384, u'\uf8fa': 384, u'\uf8fb': 384, u'\uf8fc': 494, u'\uf8fd': 494, u'\uf8fe': 494, u'\uf8ff': 790}), + 'Times-Bold': ({'FontName': 'Times-Bold', 'Descent': -217.0, 'FontBBox': (-168.0, -218.0, 1000.0, 935.0), 'FontWeight': 'Bold', 'CapHeight': 676.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 461.0, 'ItalicAngle': 0.0, 'Ascent': 683.0}, {u' ': 250, u'!': 333, u'"': 555, u'#': 500, u'$': 500, u'%': 1000, u'&': 833, u"'": 278, u'(': 333, u')': 333, u'*': 500, u'+': 570, u',': 250, u'-': 333, u'.': 250, u'/': 278, u'0': 500, u'1': 500, u'2': 500, u'3': 500, u'4': 500, u'5': 500, u'6': 500, u'7': 500, u'8': 500, u'9': 500, u':': 333, u';': 333, u'<': 570, u'=': 570, u'>': 570, u'?': 500, u'@': 930, u'A': 722, u'B': 667, u'C': 722, u'D': 722, u'E': 667, u'F': 611, u'G': 778, u'H': 778, u'I': 389, u'J': 500, u'K': 778, u'L': 667, u'M': 944, u'N': 722, u'O': 778, u'P': 611, u'Q': 778, u'R': 722, u'S': 556, u'T': 667, u'U': 722, u'V': 722, u'W': 1000, u'X': 722, u'Y': 722, u'Z': 667, u'[': 333, u'\\': 278, u']': 333, u'^': 581, u'_': 500, u'`': 333, u'a': 500, u'b': 556, u'c': 444, u'd': 556, u'e': 444, u'f': 333, u'g': 500, u'h': 556, u'i': 278, u'j': 333, u'k': 556, u'l': 278, u'm': 833, u'n': 556, u'o': 500, u'p': 556, u'q': 556, u'r': 444, u's': 389, u't': 333, u'u': 556, u'v': 500, u'w': 722, u'x': 500, u'y': 500, u'z': 444, u'{': 394, u'|': 220, u'}': 394, u'~': 520, u'\xa1': 333, u'\xa2': 500, u'\xa3': 500, u'\xa4': 500, u'\xa5': 500, u'\xa6': 220, u'\xa7': 500, u'\xa8': 333, u'\xa9': 747, u'\xaa': 300, u'\xab': 500, u'\xac': 570, u'\xae': 747, u'\xaf': 333, u'\xb0': 400, u'\xb1': 570, u'\xb2': 300, u'\xb3': 300, u'\xb4': 333, u'\xb5': 556, u'\xb6': 540, u'\xb7': 250, u'\xb8': 333, u'\xb9': 300, u'\xba': 330, u'\xbb': 500, u'\xbc': 750, u'\xbd': 750, u'\xbe': 750, u'\xbf': 500, u'\xc0': 722, u'\xc1': 722, u'\xc2': 722, u'\xc3': 722, u'\xc4': 722, u'\xc5': 722, u'\xc6': 1000, u'\xc7': 722, u'\xc8': 667, u'\xc9': 667, u'\xca': 667, u'\xcb': 667, u'\xcc': 389, u'\xcd': 389, u'\xce': 389, u'\xcf': 389, u'\xd0': 722, u'\xd1': 722, u'\xd2': 778, u'\xd3': 778, u'\xd4': 778, u'\xd5': 778, u'\xd6': 778, u'\xd7': 570, u'\xd8': 778, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 722, u'\xde': 611, u'\xdf': 556, u'\xe0': 500, u'\xe1': 500, u'\xe2': 500, u'\xe3': 500, u'\xe4': 500, u'\xe5': 500, u'\xe6': 722, u'\xe7': 444, u'\xe8': 444, u'\xe9': 444, u'\xea': 444, u'\xeb': 444, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 500, u'\xf1': 556, u'\xf2': 500, u'\xf3': 500, u'\xf4': 500, u'\xf5': 500, u'\xf6': 500, u'\xf7': 570, u'\xf8': 500, u'\xf9': 556, u'\xfa': 556, u'\xfb': 556, u'\xfc': 556, u'\xfd': 500, u'\xfe': 556, u'\xff': 500, u'\u0100': 722, u'\u0101': 500, u'\u0102': 722, u'\u0103': 500, u'\u0104': 722, u'\u0105': 500, u'\u0106': 722, u'\u0107': 444, u'\u010c': 722, u'\u010d': 444, u'\u010e': 722, u'\u010f': 672, u'\u0110': 722, u'\u0111': 556, u'\u0112': 667, u'\u0113': 444, u'\u0116': 667, u'\u0117': 444, u'\u0118': 667, u'\u0119': 444, u'\u011a': 667, u'\u011b': 444, u'\u011e': 778, u'\u011f': 500, u'\u0122': 778, u'\u0123': 500, u'\u012a': 389, u'\u012b': 278, u'\u012e': 389, u'\u012f': 278, u'\u0130': 389, u'\u0131': 278, u'\u0136': 778, u'\u0137': 556, u'\u0139': 667, u'\u013a': 278, u'\u013b': 667, u'\u013c': 278, u'\u013d': 667, u'\u013e': 394, u'\u0141': 667, u'\u0142': 278, u'\u0143': 722, u'\u0144': 556, u'\u0145': 722, u'\u0146': 556, u'\u0147': 722, u'\u0148': 556, u'\u014c': 778, u'\u014d': 500, u'\u0150': 778, u'\u0151': 500, u'\u0152': 1000, u'\u0153': 722, u'\u0154': 722, u'\u0155': 444, u'\u0156': 722, u'\u0157': 444, u'\u0158': 722, u'\u0159': 444, u'\u015a': 556, u'\u015b': 389, u'\u015e': 556, u'\u015f': 389, u'\u0160': 556, u'\u0161': 389, u'\u0162': 667, u'\u0163': 333, u'\u0164': 667, u'\u0165': 416, u'\u016a': 722, u'\u016b': 556, u'\u016e': 722, u'\u016f': 556, u'\u0170': 722, u'\u0171': 556, u'\u0172': 722, u'\u0173': 556, u'\u0178': 722, u'\u0179': 667, u'\u017a': 444, u'\u017b': 667, u'\u017c': 444, u'\u017d': 667, u'\u017e': 444, u'\u0192': 500, u'\u0218': 556, u'\u0219': 389, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 500, u'\u2014': 1000, u'\u2018': 333, u'\u2019': 333, u'\u201a': 333, u'\u201c': 500, u'\u201d': 500, u'\u201e': 500, u'\u2020': 500, u'\u2021': 500, u'\u2022': 350, u'\u2026': 1000, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 1000, u'\u2202': 494, u'\u2206': 612, u'\u2211': 600, u'\u2212': 570, u'\u221a': 549, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 494, u'\uf6c3': 250, u'\ufb01': 556, u'\ufb02': 556}), + 'Times-BoldItalic': ({'FontName': 'Times-BoldItalic', 'Descent': -217.0, 'FontBBox': (-200.0, -218.0, 996.0, 921.0), 'FontWeight': 'Bold', 'CapHeight': 669.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 462.0, 'ItalicAngle': -15.0, 'Ascent': 683.0}, {u' ': 250, u'!': 389, u'"': 555, u'#': 500, u'$': 500, u'%': 833, u'&': 778, u"'": 278, u'(': 333, u')': 333, u'*': 500, u'+': 570, u',': 250, u'-': 333, u'.': 250, u'/': 278, u'0': 500, u'1': 500, u'2': 500, u'3': 500, u'4': 500, u'5': 500, u'6': 500, u'7': 500, u'8': 500, u'9': 500, u':': 333, u';': 333, u'<': 570, u'=': 570, u'>': 570, u'?': 500, u'@': 832, u'A': 667, u'B': 667, u'C': 667, u'D': 722, u'E': 667, u'F': 667, u'G': 722, u'H': 778, u'I': 389, u'J': 500, u'K': 667, u'L': 611, u'M': 889, u'N': 722, u'O': 722, u'P': 611, u'Q': 722, u'R': 667, u'S': 556, u'T': 611, u'U': 722, u'V': 667, u'W': 889, u'X': 667, u'Y': 611, u'Z': 611, u'[': 333, u'\\': 278, u']': 333, u'^': 570, u'_': 500, u'`': 333, u'a': 500, u'b': 500, u'c': 444, u'd': 500, u'e': 444, u'f': 333, u'g': 500, u'h': 556, u'i': 278, u'j': 278, u'k': 500, u'l': 278, u'm': 778, u'n': 556, u'o': 500, u'p': 500, u'q': 500, u'r': 389, u's': 389, u't': 278, u'u': 556, u'v': 444, u'w': 667, u'x': 500, u'y': 444, u'z': 389, u'{': 348, u'|': 220, u'}': 348, u'~': 570, u'\xa1': 389, u'\xa2': 500, u'\xa3': 500, u'\xa4': 500, u'\xa5': 500, u'\xa6': 220, u'\xa7': 500, u'\xa8': 333, u'\xa9': 747, u'\xaa': 266, u'\xab': 500, u'\xac': 606, u'\xae': 747, u'\xaf': 333, u'\xb0': 400, u'\xb1': 570, u'\xb2': 300, u'\xb3': 300, u'\xb4': 333, u'\xb5': 576, u'\xb6': 500, u'\xb7': 250, u'\xb8': 333, u'\xb9': 300, u'\xba': 300, u'\xbb': 500, u'\xbc': 750, u'\xbd': 750, u'\xbe': 750, u'\xbf': 500, u'\xc0': 667, u'\xc1': 667, u'\xc2': 667, u'\xc3': 667, u'\xc4': 667, u'\xc5': 667, u'\xc6': 944, u'\xc7': 667, u'\xc8': 667, u'\xc9': 667, u'\xca': 667, u'\xcb': 667, u'\xcc': 389, u'\xcd': 389, u'\xce': 389, u'\xcf': 389, u'\xd0': 722, u'\xd1': 722, u'\xd2': 722, u'\xd3': 722, u'\xd4': 722, u'\xd5': 722, u'\xd6': 722, u'\xd7': 570, u'\xd8': 722, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 611, u'\xde': 611, u'\xdf': 500, u'\xe0': 500, u'\xe1': 500, u'\xe2': 500, u'\xe3': 500, u'\xe4': 500, u'\xe5': 500, u'\xe6': 722, u'\xe7': 444, u'\xe8': 444, u'\xe9': 444, u'\xea': 444, u'\xeb': 444, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 500, u'\xf1': 556, u'\xf2': 500, u'\xf3': 500, u'\xf4': 500, u'\xf5': 500, u'\xf6': 500, u'\xf7': 570, u'\xf8': 500, u'\xf9': 556, u'\xfa': 556, u'\xfb': 556, u'\xfc': 556, u'\xfd': 444, u'\xfe': 500, u'\xff': 444, u'\u0100': 667, u'\u0101': 500, u'\u0102': 667, u'\u0103': 500, u'\u0104': 667, u'\u0105': 500, u'\u0106': 667, u'\u0107': 444, u'\u010c': 667, u'\u010d': 444, u'\u010e': 722, u'\u010f': 608, u'\u0110': 722, u'\u0111': 500, u'\u0112': 667, u'\u0113': 444, u'\u0116': 667, u'\u0117': 444, u'\u0118': 667, u'\u0119': 444, u'\u011a': 667, u'\u011b': 444, u'\u011e': 722, u'\u011f': 500, u'\u0122': 722, u'\u0123': 500, u'\u012a': 389, u'\u012b': 278, u'\u012e': 389, u'\u012f': 278, u'\u0130': 389, u'\u0131': 278, u'\u0136': 667, u'\u0137': 500, u'\u0139': 611, u'\u013a': 278, u'\u013b': 611, u'\u013c': 278, u'\u013d': 611, u'\u013e': 382, u'\u0141': 611, u'\u0142': 278, u'\u0143': 722, u'\u0144': 556, u'\u0145': 722, u'\u0146': 556, u'\u0147': 722, u'\u0148': 556, u'\u014c': 722, u'\u014d': 500, u'\u0150': 722, u'\u0151': 500, u'\u0152': 944, u'\u0153': 722, u'\u0154': 667, u'\u0155': 389, u'\u0156': 667, u'\u0157': 389, u'\u0158': 667, u'\u0159': 389, u'\u015a': 556, u'\u015b': 389, u'\u015e': 556, u'\u015f': 389, u'\u0160': 556, u'\u0161': 389, u'\u0162': 611, u'\u0163': 278, u'\u0164': 611, u'\u0165': 366, u'\u016a': 722, u'\u016b': 556, u'\u016e': 722, u'\u016f': 556, u'\u0170': 722, u'\u0171': 556, u'\u0172': 722, u'\u0173': 556, u'\u0178': 611, u'\u0179': 611, u'\u017a': 389, u'\u017b': 611, u'\u017c': 389, u'\u017d': 611, u'\u017e': 389, u'\u0192': 500, u'\u0218': 556, u'\u0219': 389, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 500, u'\u2014': 1000, u'\u2018': 333, u'\u2019': 333, u'\u201a': 333, u'\u201c': 500, u'\u201d': 500, u'\u201e': 500, u'\u2020': 500, u'\u2021': 500, u'\u2022': 350, u'\u2026': 1000, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 1000, u'\u2202': 494, u'\u2206': 612, u'\u2211': 600, u'\u2212': 606, u'\u221a': 549, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 494, u'\uf6c3': 250, u'\ufb01': 556, u'\ufb02': 556}), + 'Times-Italic': ({'FontName': 'Times-Italic', 'Descent': -217.0, 'FontBBox': (-169.0, -217.0, 1010.0, 883.0), 'FontWeight': 'Medium', 'CapHeight': 653.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 441.0, 'ItalicAngle': -15.5, 'Ascent': 683.0}, {u' ': 250, u'!': 333, u'"': 420, u'#': 500, u'$': 500, u'%': 833, u'&': 778, u"'": 214, u'(': 333, u')': 333, u'*': 500, u'+': 675, u',': 250, u'-': 333, u'.': 250, u'/': 278, u'0': 500, u'1': 500, u'2': 500, u'3': 500, u'4': 500, u'5': 500, u'6': 500, u'7': 500, u'8': 500, u'9': 500, u':': 333, u';': 333, u'<': 675, u'=': 675, u'>': 675, u'?': 500, u'@': 920, u'A': 611, u'B': 611, u'C': 667, u'D': 722, u'E': 611, u'F': 611, u'G': 722, u'H': 722, u'I': 333, u'J': 444, u'K': 667, u'L': 556, u'M': 833, u'N': 667, u'O': 722, u'P': 611, u'Q': 722, u'R': 611, u'S': 500, u'T': 556, u'U': 722, u'V': 611, u'W': 833, u'X': 611, u'Y': 556, u'Z': 556, u'[': 389, u'\\': 278, u']': 389, u'^': 422, u'_': 500, u'`': 333, u'a': 500, u'b': 500, u'c': 444, u'd': 500, u'e': 444, u'f': 278, u'g': 500, u'h': 500, u'i': 278, u'j': 278, u'k': 444, u'l': 278, u'm': 722, u'n': 500, u'o': 500, u'p': 500, u'q': 500, u'r': 389, u's': 389, u't': 278, u'u': 500, u'v': 444, u'w': 667, u'x': 444, u'y': 444, u'z': 389, u'{': 400, u'|': 275, u'}': 400, u'~': 541, u'\xa1': 389, u'\xa2': 500, u'\xa3': 500, u'\xa4': 500, u'\xa5': 500, u'\xa6': 275, u'\xa7': 500, u'\xa8': 333, u'\xa9': 760, u'\xaa': 276, u'\xab': 500, u'\xac': 675, u'\xae': 760, u'\xaf': 333, u'\xb0': 400, u'\xb1': 675, u'\xb2': 300, u'\xb3': 300, u'\xb4': 333, u'\xb5': 500, u'\xb6': 523, u'\xb7': 250, u'\xb8': 333, u'\xb9': 300, u'\xba': 310, u'\xbb': 500, u'\xbc': 750, u'\xbd': 750, u'\xbe': 750, u'\xbf': 500, u'\xc0': 611, u'\xc1': 611, u'\xc2': 611, u'\xc3': 611, u'\xc4': 611, u'\xc5': 611, u'\xc6': 889, u'\xc7': 667, u'\xc8': 611, u'\xc9': 611, u'\xca': 611, u'\xcb': 611, u'\xcc': 333, u'\xcd': 333, u'\xce': 333, u'\xcf': 333, u'\xd0': 722, u'\xd1': 667, u'\xd2': 722, u'\xd3': 722, u'\xd4': 722, u'\xd5': 722, u'\xd6': 722, u'\xd7': 675, u'\xd8': 722, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 556, u'\xde': 611, u'\xdf': 500, u'\xe0': 500, u'\xe1': 500, u'\xe2': 500, u'\xe3': 500, u'\xe4': 500, u'\xe5': 500, u'\xe6': 667, u'\xe7': 444, u'\xe8': 444, u'\xe9': 444, u'\xea': 444, u'\xeb': 444, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 500, u'\xf1': 500, u'\xf2': 500, u'\xf3': 500, u'\xf4': 500, u'\xf5': 500, u'\xf6': 500, u'\xf7': 675, u'\xf8': 500, u'\xf9': 500, u'\xfa': 500, u'\xfb': 500, u'\xfc': 500, u'\xfd': 444, u'\xfe': 500, u'\xff': 444, u'\u0100': 611, u'\u0101': 500, u'\u0102': 611, u'\u0103': 500, u'\u0104': 611, u'\u0105': 500, u'\u0106': 667, u'\u0107': 444, u'\u010c': 667, u'\u010d': 444, u'\u010e': 722, u'\u010f': 544, u'\u0110': 722, u'\u0111': 500, u'\u0112': 611, u'\u0113': 444, u'\u0116': 611, u'\u0117': 444, u'\u0118': 611, u'\u0119': 444, u'\u011a': 611, u'\u011b': 444, u'\u011e': 722, u'\u011f': 500, u'\u0122': 722, u'\u0123': 500, u'\u012a': 333, u'\u012b': 278, u'\u012e': 333, u'\u012f': 278, u'\u0130': 333, u'\u0131': 278, u'\u0136': 667, u'\u0137': 444, u'\u0139': 556, u'\u013a': 278, u'\u013b': 556, u'\u013c': 278, u'\u013d': 611, u'\u013e': 300, u'\u0141': 556, u'\u0142': 278, u'\u0143': 667, u'\u0144': 500, u'\u0145': 667, u'\u0146': 500, u'\u0147': 667, u'\u0148': 500, u'\u014c': 722, u'\u014d': 500, u'\u0150': 722, u'\u0151': 500, u'\u0152': 944, u'\u0153': 667, u'\u0154': 611, u'\u0155': 389, u'\u0156': 611, u'\u0157': 389, u'\u0158': 611, u'\u0159': 389, u'\u015a': 500, u'\u015b': 389, u'\u015e': 500, u'\u015f': 389, u'\u0160': 500, u'\u0161': 389, u'\u0162': 556, u'\u0163': 278, u'\u0164': 556, u'\u0165': 300, u'\u016a': 722, u'\u016b': 500, u'\u016e': 722, u'\u016f': 500, u'\u0170': 722, u'\u0171': 500, u'\u0172': 722, u'\u0173': 500, u'\u0178': 556, u'\u0179': 556, u'\u017a': 389, u'\u017b': 556, u'\u017c': 389, u'\u017d': 556, u'\u017e': 389, u'\u0192': 500, u'\u0218': 500, u'\u0219': 389, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 500, u'\u2014': 889, u'\u2018': 333, u'\u2019': 333, u'\u201a': 333, u'\u201c': 556, u'\u201d': 556, u'\u201e': 556, u'\u2020': 500, u'\u2021': 500, u'\u2022': 350, u'\u2026': 889, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 980, u'\u2202': 476, u'\u2206': 612, u'\u2211': 600, u'\u2212': 675, u'\u221a': 453, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 471, u'\uf6c3': 250, u'\ufb01': 500, u'\ufb02': 500}), + 'Times-Roman': ({'FontName': 'Times-Roman', 'Descent': -217.0, 'FontBBox': (-168.0, -218.0, 1000.0, 898.0), 'FontWeight': 'Roman', 'CapHeight': 662.0, 'FontFamily': 'Times', 'Flags': 0, 'XHeight': 450.0, 'ItalicAngle': 0.0, 'Ascent': 683.0}, {u' ': 250, u'!': 333, u'"': 408, u'#': 500, u'$': 500, u'%': 833, u'&': 778, u"'": 180, u'(': 333, u')': 333, u'*': 500, u'+': 564, u',': 250, u'-': 333, u'.': 250, u'/': 278, u'0': 500, u'1': 500, u'2': 500, u'3': 500, u'4': 500, u'5': 500, u'6': 500, u'7': 500, u'8': 500, u'9': 500, u':': 278, u';': 278, u'<': 564, u'=': 564, u'>': 564, u'?': 444, u'@': 921, u'A': 722, u'B': 667, u'C': 667, u'D': 722, u'E': 611, u'F': 556, u'G': 722, u'H': 722, u'I': 333, u'J': 389, u'K': 722, u'L': 611, u'M': 889, u'N': 722, u'O': 722, u'P': 556, u'Q': 722, u'R': 667, u'S': 556, u'T': 611, u'U': 722, u'V': 722, u'W': 944, u'X': 722, u'Y': 722, u'Z': 611, u'[': 333, u'\\': 278, u']': 333, u'^': 469, u'_': 500, u'`': 333, u'a': 444, u'b': 500, u'c': 444, u'd': 500, u'e': 444, u'f': 333, u'g': 500, u'h': 500, u'i': 278, u'j': 278, u'k': 500, u'l': 278, u'm': 778, u'n': 500, u'o': 500, u'p': 500, u'q': 500, u'r': 333, u's': 389, u't': 278, u'u': 500, u'v': 500, u'w': 722, u'x': 500, u'y': 500, u'z': 444, u'{': 480, u'|': 200, u'}': 480, u'~': 541, u'\xa1': 333, u'\xa2': 500, u'\xa3': 500, u'\xa4': 500, u'\xa5': 500, u'\xa6': 200, u'\xa7': 500, u'\xa8': 333, u'\xa9': 760, u'\xaa': 276, u'\xab': 500, u'\xac': 564, u'\xae': 760, u'\xaf': 333, u'\xb0': 400, u'\xb1': 564, u'\xb2': 300, u'\xb3': 300, u'\xb4': 333, u'\xb5': 500, u'\xb6': 453, u'\xb7': 250, u'\xb8': 333, u'\xb9': 300, u'\xba': 310, u'\xbb': 500, u'\xbc': 750, u'\xbd': 750, u'\xbe': 750, u'\xbf': 444, u'\xc0': 722, u'\xc1': 722, u'\xc2': 722, u'\xc3': 722, u'\xc4': 722, u'\xc5': 722, u'\xc6': 889, u'\xc7': 667, u'\xc8': 611, u'\xc9': 611, u'\xca': 611, u'\xcb': 611, u'\xcc': 333, u'\xcd': 333, u'\xce': 333, u'\xcf': 333, u'\xd0': 722, u'\xd1': 722, u'\xd2': 722, u'\xd3': 722, u'\xd4': 722, u'\xd5': 722, u'\xd6': 722, u'\xd7': 564, u'\xd8': 722, u'\xd9': 722, u'\xda': 722, u'\xdb': 722, u'\xdc': 722, u'\xdd': 722, u'\xde': 556, u'\xdf': 500, u'\xe0': 444, u'\xe1': 444, u'\xe2': 444, u'\xe3': 444, u'\xe4': 444, u'\xe5': 444, u'\xe6': 667, u'\xe7': 444, u'\xe8': 444, u'\xe9': 444, u'\xea': 444, u'\xeb': 444, u'\xec': 278, u'\xed': 278, u'\xee': 278, u'\xef': 278, u'\xf0': 500, u'\xf1': 500, u'\xf2': 500, u'\xf3': 500, u'\xf4': 500, u'\xf5': 500, u'\xf6': 500, u'\xf7': 564, u'\xf8': 500, u'\xf9': 500, u'\xfa': 500, u'\xfb': 500, u'\xfc': 500, u'\xfd': 500, u'\xfe': 500, u'\xff': 500, u'\u0100': 722, u'\u0101': 444, u'\u0102': 722, u'\u0103': 444, u'\u0104': 722, u'\u0105': 444, u'\u0106': 667, u'\u0107': 444, u'\u010c': 667, u'\u010d': 444, u'\u010e': 722, u'\u010f': 588, u'\u0110': 722, u'\u0111': 500, u'\u0112': 611, u'\u0113': 444, u'\u0116': 611, u'\u0117': 444, u'\u0118': 611, u'\u0119': 444, u'\u011a': 611, u'\u011b': 444, u'\u011e': 722, u'\u011f': 500, u'\u0122': 722, u'\u0123': 500, u'\u012a': 333, u'\u012b': 278, u'\u012e': 333, u'\u012f': 278, u'\u0130': 333, u'\u0131': 278, u'\u0136': 722, u'\u0137': 500, u'\u0139': 611, u'\u013a': 278, u'\u013b': 611, u'\u013c': 278, u'\u013d': 611, u'\u013e': 344, u'\u0141': 611, u'\u0142': 278, u'\u0143': 722, u'\u0144': 500, u'\u0145': 722, u'\u0146': 500, u'\u0147': 722, u'\u0148': 500, u'\u014c': 722, u'\u014d': 500, u'\u0150': 722, u'\u0151': 500, u'\u0152': 889, u'\u0153': 722, u'\u0154': 667, u'\u0155': 333, u'\u0156': 667, u'\u0157': 333, u'\u0158': 667, u'\u0159': 333, u'\u015a': 556, u'\u015b': 389, u'\u015e': 556, u'\u015f': 389, u'\u0160': 556, u'\u0161': 389, u'\u0162': 611, u'\u0163': 278, u'\u0164': 611, u'\u0165': 326, u'\u016a': 722, u'\u016b': 500, u'\u016e': 722, u'\u016f': 500, u'\u0170': 722, u'\u0171': 500, u'\u0172': 722, u'\u0173': 500, u'\u0178': 722, u'\u0179': 611, u'\u017a': 444, u'\u017b': 611, u'\u017c': 444, u'\u017d': 611, u'\u017e': 444, u'\u0192': 500, u'\u0218': 556, u'\u0219': 389, u'\u02c6': 333, u'\u02c7': 333, u'\u02d8': 333, u'\u02d9': 333, u'\u02da': 333, u'\u02db': 333, u'\u02dc': 333, u'\u02dd': 333, u'\u2013': 500, u'\u2014': 1000, u'\u2018': 333, u'\u2019': 333, u'\u201a': 333, u'\u201c': 444, u'\u201d': 444, u'\u201e': 444, u'\u2020': 500, u'\u2021': 500, u'\u2022': 350, u'\u2026': 1000, u'\u2030': 1000, u'\u2039': 333, u'\u203a': 333, u'\u2044': 167, u'\u2122': 980, u'\u2202': 476, u'\u2206': 612, u'\u2211': 600, u'\u2212': 564, u'\u221a': 453, u'\u2260': 549, u'\u2264': 549, u'\u2265': 549, u'\u25ca': 471, u'\uf6c3': 250, u'\ufb01': 556, u'\ufb02': 556}), + 'ZapfDingbats': ({'FontName': 'ZapfDingbats', 'FontBBox': (-1.0, -143.0, 981.0, 820.0), 'FontWeight': 'Medium', 'FontFamily': 'ITC', 'Flags': 0, 'ItalicAngle': 0.0}, {u'\x01': 974, u'\x02': 961, u'\x03': 980, u'\x04': 719, u'\x05': 789, u'\x06': 494, u'\x07': 552, u'\x08': 537, u'\t': 577, u'\n': 692, u'\x0b': 960, u'\x0c': 939, u'\r': 549, u'\x0e': 855, u'\x0f': 911, u'\x10': 933, u'\x11': 945, u'\x12': 974, u'\x13': 755, u'\x14': 846, u'\x15': 762, u'\x16': 761, u'\x17': 571, u'\x18': 677, u'\x19': 763, u'\x1a': 760, u'\x1b': 759, u'\x1c': 754, u'\x1d': 786, u'\x1e': 788, u'\x1f': 788, u' ': 790, u'!': 793, u'"': 794, u'#': 816, u'$': 823, u'%': 789, u'&': 841, u"'": 823, u'(': 833, u')': 816, u'*': 831, u'+': 923, u',': 744, u'-': 723, u'.': 749, u'/': 790, u'0': 792, u'1': 695, u'2': 776, u'3': 768, u'4': 792, u'5': 759, u'6': 707, u'7': 708, u'8': 682, u'9': 701, u':': 826, u';': 815, u'<': 789, u'=': 789, u'>': 707, u'?': 687, u'@': 696, u'A': 689, u'B': 786, u'C': 787, u'D': 713, u'E': 791, u'F': 785, u'G': 791, u'H': 873, u'I': 761, u'J': 762, u'K': 759, u'L': 892, u'M': 892, u'N': 788, u'O': 784, u'Q': 438, u'R': 138, u'S': 277, u'T': 415, u'U': 509, u'V': 410, u'W': 234, u'X': 234, u'Y': 390, u'Z': 390, u'[': 276, u'\\': 276, u']': 317, u'^': 317, u'_': 334, u'`': 334, u'a': 392, u'b': 392, u'c': 668, u'd': 668, u'e': 732, u'f': 544, u'g': 544, u'h': 910, u'i': 911, u'j': 667, u'k': 760, u'l': 760, u'm': 626, u'n': 694, u'o': 595, u'p': 776, u'u': 690, u'v': 791, u'w': 790, u'x': 788, u'y': 788, u'z': 788, u'{': 788, u'|': 788, u'}': 788, u'~': 788, u'\x7f': 788, u'\x80': 788, u'\x81': 788, u'\x82': 788, u'\x83': 788, u'\x84': 788, u'\x85': 788, u'\x86': 788, u'\x87': 788, u'\x88': 788, u'\x89': 788, u'\x8a': 788, u'\x8b': 788, u'\x8c': 788, u'\x8d': 788, u'\x8e': 788, u'\x8f': 788, u'\x90': 788, u'\x91': 788, u'\x92': 788, u'\x93': 788, u'\x94': 788, u'\x95': 788, u'\x96': 788, u'\x97': 788, u'\x98': 788, u'\x99': 788, u'\x9a': 788, u'\x9b': 788, u'\x9c': 788, u'\x9d': 788, u'\x9e': 788, u'\x9f': 788, u'\xa0': 894, u'\xa1': 838, u'\xa2': 924, u'\xa3': 1016, u'\xa4': 458, u'\xa5': 924, u'\xa6': 918, u'\xa7': 927, u'\xa8': 928, u'\xa9': 928, u'\xaa': 834, u'\xab': 873, u'\xac': 828, u'\xad': 924, u'\xae': 917, u'\xaf': 930, u'\xb0': 931, u'\xb1': 463, u'\xb2': 883, u'\xb3': 836, u'\xb4': 867, u'\xb5': 696, u'\xb6': 874, u'\xb7': 760, u'\xb8': 946, u'\xb9': 865, u'\xba': 967, u'\xbb': 831, u'\xbc': 873, u'\xbd': 927, u'\xbe': 970, u'\xbf': 918, u'\xc0': 748, u'\xc1': 836, u'\xc2': 771, u'\xc3': 888, u'\xc4': 748, u'\xc5': 771, u'\xc6': 888, u'\xc7': 867, u'\xc8': 696, u'\xc9': 874, u'\xca': 974, u'\xcb': 762, u'\xcc': 759, u'\xcd': 509, u'\xce': 410}), } diff -Nru pdfminer-20110515+dfsg/pdfminer/glyphlist.py pdfminer-20140328+dfsg/pdfminer/glyphlist.py --- pdfminer-20110515+dfsg/pdfminer/glyphlist.py 2010-10-19 09:55:35.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/glyphlist.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Mappings from Adobe glyph names to Unicode characters. diff -Nru pdfminer-20110515+dfsg/pdfminer/image.py pdfminer-20140328+dfsg/pdfminer/image.py --- pdfminer-20110515+dfsg/pdfminer/image.py 1970-01-01 00:00:00.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/image.py 2015-10-11 18:33:29.000000000 +0000 @@ -0,0 +1,119 @@ +#!/usr/bin/env python +import cStringIO +import struct +import os, os.path +from pdftypes import LITERALS_DCT_DECODE +from pdfcolor import LITERAL_DEVICE_GRAY, LITERAL_DEVICE_RGB, LITERAL_DEVICE_CMYK + + +def align32(x): + return ((x+3)//4)*4 + + +## BMPWriter +## +class BMPWriter(object): + + def __init__(self, fp, bits, width, height): + self.fp = fp + self.bits = bits + self.width = width + self.height = height + if bits == 1: + ncols = 2 + elif bits == 8: + ncols = 256 + elif bits == 24: + ncols = 0 + else: + raise ValueError(bits) + self.linesize = align32((self.width*self.bits+7)//8) + self.datasize = self.linesize * self.height + headersize = 14+40+ncols*4 + info = struct.pack('' % (self.__class__.__name__, bbox2str(self.bbox))) - def set_bbox(self, (x0,y0,x1,y1)): + def set_bbox(self, (x0, y0, x1, y1)): self.x0 = x0 self.y0 = y0 self.x1 = x1 @@ -94,7 +93,7 @@ def is_empty(self): return self.width <= 0 or self.height <= 0 - + def is_hoverlap(self, obj): assert isinstance(obj, LTComponent) return obj.x0 <= self.x1 and self.x0 <= obj.x1 @@ -143,7 +142,7 @@ return def get_pts(self): - return ','.join( '%.3f,%.3f' % p for p in self.pts ) + return ','.join('%.3f,%.3f' % p for p in self.pts) ## LTLine @@ -159,8 +158,8 @@ ## class LTRect(LTCurve): - def __init__(self, linewidth, (x0,y0,x1,y1)): - LTCurve.__init__(self, linewidth, [(x0,y0), (x1,y0), (x1,y1), (x0,y1)]) + def __init__(self, linewidth, (x0, y0, x1, y1)): + LTCurve.__init__(self, linewidth, [(x0, y0), (x1, y0), (x1, y1), (x0, y1)]) return @@ -187,9 +186,9 @@ bbox2str(self.bbox), self.srcsize)) -## LTAnon +## LTAnno ## -class LTAnon(LTItem, LTText): +class LTAnno(LTItem, LTText): def __init__(self, text): self._text = text @@ -203,7 +202,8 @@ ## class LTChar(LTComponent, LTText): - def __init__(self, matrix, font, fontsize, scaling, rise, text, textwidth, textdisp): + def __init__(self, matrix, font, fontsize, scaling, rise, + text, textwidth, textdisp): LTText.__init__(self) self._text = text self.matrix = matrix @@ -213,9 +213,9 @@ if font.is_vertical(): # vertical width = font.get_width() * fontsize - (vx,vy) = textdisp + (vx, vy) = textdisp if vx is None: - vx = width/2 + vx = width//2 else: vx = vx * fontsize * .001 vy = (1000 - vy) * fontsize * .001 @@ -230,15 +230,15 @@ ty = descent + rise bll = (0, ty) bur = (self.adv, ty+height) - (a,b,c,d,e,f) = self.matrix + (a, b, c, d, e, f) = self.matrix self.upright = (0 < a*d*scaling and b*c <= 0) - (x0,y0) = apply_matrix_pt(self.matrix, bll) - (x1,y1) = apply_matrix_pt(self.matrix, bur) + (x0, y0) = apply_matrix_pt(self.matrix, bll) + (x1, y1) = apply_matrix_pt(self.matrix, bur) if x1 < x0: - (x0,x1) = (x1,x0) + (x0, x1) = (x1, x0) if y1 < y0: - (y0,y1) = (y1,y0) - LTComponent.__init__(self, (x0,y0,x1,y1)) + (y0, y1) = (y1, y0) + LTComponent.__init__(self, (x0, y0, x1, y1)) if font.is_vertical(): self.size = self.width else: @@ -247,7 +247,7 @@ def __repr__(self): return ('<%s %s matrix=%s font=%r adv=%s text=%r>' % - (self.__class__.__name__, bbox2str(self.bbox), + (self.__class__.__name__, bbox2str(self.bbox), matrix2str(self.matrix), self.fontname, self.adv, self.get_text())) @@ -258,7 +258,7 @@ """Returns True if two characters can coexist in the same line.""" return True - + ## LTContainer ## class LTContainer(LTComponent): @@ -287,14 +287,14 @@ for obj in self._objs: obj.analyze(laparams) return - + ## LTExpandableContainer ## class LTExpandableContainer(LTContainer): def __init__(self): - LTContainer.__init__(self, (+INF,+INF,-INF,-INF)) + LTContainer.__init__(self, (+INF, +INF, -INF, -INF)) return def add(self, obj): @@ -314,8 +314,8 @@ return def get_text(self): - return ''.join( obj.get_text() for obj in self if isinstance(obj, LTText) ) - + return ''.join(obj.get_text() for obj in self if isinstance(obj, LTText)) + ## LTTextLine ## @@ -333,12 +333,13 @@ def analyze(self, laparams): LTTextContainer.analyze(self, laparams) - LTContainer.add(self, LTAnon('\n')) + LTContainer.add(self, LTAnno('\n')) return def find_neighbors(self, plane, ratio): raise NotImplementedError + class LTTextLineHorizontal(LTTextLine): def __init__(self, word_margin): @@ -348,18 +349,23 @@ def add(self, obj): if isinstance(obj, LTChar) and self.word_margin: - margin = self.word_margin * obj.width + margin = self.word_margin * max(obj.width, obj.height) if self._x1 < obj.x0-margin: - LTContainer.add(self, LTAnon(' ')) + LTContainer.add(self, LTAnno(' ')) self._x1 = obj.x1 LTTextLine.add(self, obj) return def find_neighbors(self, plane, ratio): - h = ratio*self.height - objs = plane.find((self.x0, self.y0-h, self.x1, self.y1+h)) - return [ obj for obj in objs if isinstance(obj, LTTextLineHorizontal) ] - + d = ratio*self.height + objs = plane.find((self.x0, self.y0-d, self.x1, self.y1+d)) + return [obj for obj in objs + if (isinstance(obj, LTTextLineHorizontal) and + abs(obj.height-self.height) < d and + (abs(obj.x0-self.x0) < d or + abs(obj.x1-self.x1) < d))] + + class LTTextLineVertical(LTTextLine): def __init__(self, word_margin): @@ -369,18 +375,22 @@ def add(self, obj): if isinstance(obj, LTChar) and self.word_margin: - margin = self.word_margin * obj.height + margin = self.word_margin * max(obj.width, obj.height) if obj.y1+margin < self._y0: - LTContainer.add(self, LTAnon(' ')) + LTContainer.add(self, LTAnno(' ')) self._y0 = obj.y0 LTTextLine.add(self, obj) return - + def find_neighbors(self, plane, ratio): - w = ratio*self.width - objs = plane.find((self.x0-w, self.y0, self.x1+w, self.y1)) - return [ obj for obj in objs if isinstance(obj, LTTextLineVertical) ] - + d = ratio*self.width + objs = plane.find((self.x0-d, self.y0, self.x1+d, self.y1)) + return [obj for obj in objs + if (isinstance(obj, LTTextLineVertical) and + abs(obj.width-self.width) < d and + (abs(obj.y0-self.y0) < d or + abs(obj.y1-self.y1) < d))] + ## LTTextBox ## @@ -391,7 +401,7 @@ def __init__(self): LTTextContainer.__init__(self) - self.index = None + self.index = -1 return def __repr__(self): @@ -399,8 +409,9 @@ (self.__class__.__name__, self.index, bbox2str(self.bbox), self.get_text())) + class LTTextBoxHorizontal(LTTextBox): - + def analyze(self, laparams): LTTextBox.analyze(self, laparams) self._objs = csort(self._objs, key=lambda obj: -obj.y1) @@ -409,6 +420,7 @@ def get_writing_mode(self): return 'lr-tb' + class LTTextBoxVertical(LTTextBox): def analyze(self, laparams): @@ -429,8 +441,9 @@ self.extend(objs) return + class LTTextGroupLRTB(LTTextGroup): - + def analyze(self, laparams): LTTextGroup.analyze(self, laparams) # reorder the objects from top-left to bottom-right. @@ -439,14 +452,15 @@ (1+laparams.boxes_flow)*(obj.y0+obj.y1)) return + class LTTextGroupTBRL(LTTextGroup): - + def analyze(self, laparams): LTTextGroup.analyze(self, laparams) # reorder the objects from top-right to bottom-left. self._objs = csort(self._objs, key=lambda obj: -(1+laparams.boxes_flow)*(obj.x0+obj.x1) - -(1-laparams.boxes_flow)*(obj.y1)) + - (1-laparams.boxes_flow)*(obj.y1)) return @@ -458,58 +472,64 @@ LTContainer.__init__(self, bbox) self.groups = None return - - def get_textlines(self, laparams, objs): + + # group_objects: group text object to textlines. + def group_objects(self, laparams, objs): obj0 = None line = None for obj1 in objs: if obj0 is not None: - k = 0 - if (obj0.is_compatible(obj1) and obj0.is_voverlap(obj1) and - min(obj0.height, obj1.height) * laparams.line_overlap < obj0.voverlap(obj1) and - obj0.hdistance(obj1) < max(obj0.width, obj1.width) * laparams.char_margin): - # obj0 and obj1 is horizontally aligned: - # - # +------+ - - - - # | obj0 | - - +------+ - - # | | | obj1 | | (line_overlap) - # +------+ - - | | - - # - - - +------+ - # - # |<--->| - # (char_margin) - k |= 1 - if (laparams.detect_vertical and - obj0.is_compatible(obj1) and obj0.is_hoverlap(obj1) and - min(obj0.width, obj1.width) * laparams.line_overlap < obj0.hoverlap(obj1) and - obj0.vdistance(obj1) < max(obj0.height, obj1.height) * laparams.char_margin): - # obj0 and obj1 is vertically aligned: - # - # +------+ - # | obj0 | - # | | - # +------+ - - - - # | | | (char_margin) - # +------+ - - - # | obj1 | - # | | - # +------+ - # - # |<-->| - # (line_overlap) - k |= 2 - if ( (k & 1 and isinstance(line, LTTextLineHorizontal)) or - (k & 2 and isinstance(line, LTTextLineVertical)) ): + # halign: obj0 and obj1 is horizontally aligned. + # + # +------+ - - - + # | obj0 | - - +------+ - + # | | | obj1 | | (line_overlap) + # +------+ - - | | - + # - - - +------+ + # + # |<--->| + # (char_margin) + halign = (obj0.is_compatible(obj1) and + obj0.is_voverlap(obj1) and + (min(obj0.height, obj1.height) * laparams.line_overlap < + obj0.voverlap(obj1)) and + (obj0.hdistance(obj1) < + max(obj0.width, obj1.width) * laparams.char_margin)) + + # valign: obj0 and obj1 is vertically aligned. + # + # +------+ + # | obj0 | + # | | + # +------+ - - - + # | | | (char_margin) + # +------+ - - + # | obj1 | + # | | + # +------+ + # + # |<-->| + # (line_overlap) + valign = (laparams.detect_vertical and + obj0.is_compatible(obj1) and + obj0.is_hoverlap(obj1) and + (min(obj0.width, obj1.width) * laparams.line_overlap < + obj0.hoverlap(obj1)) and + (obj0.vdistance(obj1) < + max(obj0.height, obj1.height) * laparams.char_margin)) + + if ((halign and isinstance(line, LTTextLineHorizontal)) or + (valign and isinstance(line, LTTextLineVertical))): line.add(obj1) elif line is not None: yield line line = None else: - if k == 2: + if valign and not halign: line = LTTextLineVertical(laparams.word_margin) line.add(obj0) line.add(obj1) - elif k == 1: + elif halign and not valign: line = LTTextLineHorizontal(laparams.word_margin) line.add(obj0) line.add(obj1) @@ -525,12 +545,14 @@ yield line return - def get_textboxes(self, laparams, lines): - plane = Plane(lines) + # group_textlines: group neighboring lines to textboxes. + def group_textlines(self, laparams, lines): + plane = Plane(self.bbox) + plane.extend(lines) boxes = {} for line in lines: neighbors = line.find_neighbors(plane, laparams.line_margin) - assert line in neighbors, line + if line not in neighbors: continue members = [] for obj1 in neighbors: members.append(obj1) @@ -545,39 +567,46 @@ boxes[obj] = box done = set() for line in lines: + if line not in boxes: continue box = boxes[line] - if box in done: continue + if box in done: + continue done.add(box) - yield box + if not box.is_empty(): + yield box return + # group_textboxes: group textboxes hierarchically. def group_textboxes(self, laparams, boxes): + assert boxes + def dist(obj1, obj2): """A distance function between two TextBoxes. - + Consider the bounding rectangle for obj1 and obj2. - Return its area less the areas of obj1 and obj2, + Return its area less the areas of obj1 and obj2, shown as 'www' below. This value may be negative. - +------+..........+ (x1,y1) + +------+..........+ (x1, y1) | obj1 |wwwwwwwwww: +------+www+------+ :wwwwwwwwww| obj2 | - (x0,y0) +..........+------+ + (x0, y0) +..........+------+ """ - x0 = min(obj1.x0,obj2.x0) - y0 = min(obj1.y0,obj2.y0) - x1 = max(obj1.x1,obj2.x1) - y1 = max(obj1.y1,obj2.y1) + x0 = min(obj1.x0, obj2.x0) + y0 = min(obj1.y0, obj2.y0) + x1 = max(obj1.x1, obj2.x1) + y1 = max(obj1.y1, obj2.y1) return ((x1-x0)*(y1-y0) - obj1.width*obj1.height - obj2.width*obj2.height) + def isany(obj1, obj2): """Check if there's any other object between obj1 and obj2. """ - x0 = min(obj1.x0,obj2.x0) - y0 = min(obj1.y0,obj2.y0) - x1 = max(obj1.x1,obj2.x1) - y1 = max(obj1.y1,obj2.y1) - objs = set(plane.find((x0,y0,x1,y1))) - return objs.difference((obj1,obj2)) + x0 = min(obj1.x0, obj2.x0) + y0 = min(obj1.y0, obj2.y0) + x1 = max(obj1.x1, obj2.x1) + y1 = max(obj1.y1, obj2.y1) + objs = set(plane.find((x0, y0, x1, y1))) + return objs.difference((obj1, obj2)) # XXX this still takes O(n^2) :( dists = [] for i in xrange(len(boxes)): @@ -586,52 +615,50 @@ obj2 = boxes[j] dists.append((0, dist(obj1, obj2), obj1, obj2)) dists.sort() - plane = Plane(boxes) + plane = Plane(self.bbox) + plane.extend(boxes) while dists: - (c,d,obj1,obj2) = dists.pop(0) + (c, d, obj1, obj2) = dists.pop(0) if c == 0 and isany(obj1, obj2): - dists.append((1,d,obj1,obj2)) + dists.append((1, d, obj1, obj2)) continue - if (isinstance(obj1, LTTextBoxVertical) or - isinstance(obj1, LTTextGroupTBRL) or - isinstance(obj2, LTTextBoxVertical) or - isinstance(obj2, LTTextGroupTBRL)): - group = LTTextGroupTBRL([obj1,obj2]) + if (isinstance(obj1, (LTTextBoxVertical, LTTextGroupTBRL)) or + isinstance(obj2, (LTTextBoxVertical, LTTextGroupTBRL))): + group = LTTextGroupTBRL([obj1, obj2]) else: - group = LTTextGroupLRTB([obj1,obj2]) + group = LTTextGroupLRTB([obj1, obj2]) plane.remove(obj1) plane.remove(obj2) - dists = [ (c,d,o1,o2) for (c,d,o1,o2) in dists - if o1 in plane and o2 in plane ] + # this line is optimized -- don't change without profiling + dists = [n for n in dists if n[2] in plane._objs and n[3] in plane._objs] for other in plane: - dists.append((0, dist(group,other), group, other)) + dists.append((0, dist(group, other), group, other)) dists.sort() plane.add(group) assert len(plane) == 1 return list(plane) - + def analyze(self, laparams): # textobjs is a list of LTChar objects, i.e. # it has all the individual characters in the page. - (textobjs, otherobjs) = fsplit(lambda obj: isinstance(obj, LTChar), self._objs) + (textobjs, otherobjs) = fsplit(lambda obj: isinstance(obj, LTChar), self) for obj in otherobjs: obj.analyze(laparams) - if not textobjs: return - textlines = list(self.get_textlines(laparams, textobjs)) - assert len(textobjs) <= sum( len(line._objs) for line in textlines ) + if not textobjs: + return + textlines = list(self.group_objects(laparams, textobjs)) (empties, textlines) = fsplit(lambda obj: obj.is_empty(), textlines) for obj in empties: obj.analyze(laparams) - textboxes = list(self.get_textboxes(laparams, textlines)) - assert len(textlines) == sum( len(box._objs) for box in textboxes ) - groups = self.group_textboxes(laparams, textboxes) - assigner = IndexAssigner() - for group in groups: - group.analyze(laparams) - assigner.run(group) - textboxes.sort(key=lambda box:box.index) + textboxes = list(self.group_textlines(laparams, textlines)) + if textboxes: + self.groups = self.group_textboxes(laparams, textboxes) + assigner = IndexAssigner() + for group in self.groups: + group.analyze(laparams) + assigner.run(group) + textboxes.sort(key=lambda box: box.index) self._objs = textboxes + otherobjs + empties - self.groups = groups return @@ -642,9 +669,9 @@ def __init__(self, name, bbox, matrix): self.name = name self.matrix = matrix - (x,y,w,h) = bbox - bbox = get_bound( apply_matrix_pt(matrix, (p,q)) - for (p,q) in ((x,y), (x+w,y), (x,y+h), (x+w,y+h)) ) + (x, y, w, h) = bbox + bbox = get_bound(apply_matrix_pt(matrix, (p, q)) + for (p, q) in ((x, y), (x+w, y), (x, y+h), (x+w, y+h))) LTLayoutContainer.__init__(self, bbox) return @@ -654,9 +681,10 @@ bbox2str(self.bbox), matrix2str(self.matrix))) def analyze(self, laparams): - if not laparams.all_texts: return + if not laparams.all_texts: + return LTLayoutContainer.analyze(self, laparams) - return + return ## LTPage diff -Nru pdfminer-20110515+dfsg/pdfminer/lzw.py pdfminer-20140328+dfsg/pdfminer/lzw.py --- pdfminer-20110515+dfsg/pdfminer/lzw.py 2011-03-02 14:35:31.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/lzw.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys try: from cStringIO import StringIO @@ -6,6 +6,10 @@ from StringIO import StringIO +class CorruptDataError(Exception): + pass + + ## LZWDecoder ## class LZWDecoder(object): @@ -30,17 +34,18 @@ # |-----8-bits-----| # |-bpos-|-bits-| | # | |----r----| - v = (v<>(r-bits)) & ((1<> (r-bits)) & ((1 << bits)-1)) self.bpos += bits break else: # |-----8-bits-----| # |-bpos-|---bits----... # | |----r----| - v = (v<>sys.stderr, ('nbits=%d, code=%d, output=%r, table=%r' % (self.nbits, code, x, self.table[258:])) return + # lzwdecode def lzwdecode(data): """ diff -Nru pdfminer-20110515+dfsg/pdfminer/pdfcolor.py pdfminer-20140328+dfsg/pdfminer/pdfcolor.py --- pdfminer-20110515+dfsg/pdfminer/pdfcolor.py 2010-10-19 09:55:45.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdfcolor.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python from psparser import LIT @@ -8,6 +8,7 @@ LITERAL_DEVICE_RGB = LIT('DeviceRGB') LITERAL_DEVICE_CMYK = LIT('DeviceCMYK') + class PDFColorSpace(object): def __init__(self, name, ncomponents): @@ -20,14 +21,14 @@ PREDEFINED_COLORSPACE = dict( - (name, PDFColorSpace(name,n)) for (name,n) in { - 'CalRGB': 3, - 'CalGray': 1, - 'Lab': 3, - 'DeviceRGB': 3, - 'DeviceCMYK': 4, - 'DeviceGray': 1, - 'Separation': 1, - 'Indexed': 1, - 'Pattern': 1, - }.iteritems()) + (name, PDFColorSpace(name, n)) for (name, n) in { + 'CalRGB': 3, + 'CalGray': 1, + 'Lab': 3, + 'DeviceRGB': 3, + 'DeviceCMYK': 4, + 'DeviceGray': 1, + 'Separation': 1, + 'Indexed': 1, + 'Pattern': 1, + }.iteritems()) diff -Nru pdfminer-20110515+dfsg/pdfminer/pdfdevice.py pdfminer-20140328+dfsg/pdfminer/pdfdevice.py --- pdfminer-20110515+dfsg/pdfminer/pdfdevice.py 2011-02-14 13:41:25.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdfdevice.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,7 +1,6 @@ -#!/usr/bin/env python2 -import sys +#!/usr/bin/env python from utils import mult_matrix, translate_matrix -from utils import enc, bbox2str +from utils import enc, bbox2str, isnumber from pdffont import PDFUnicodeNotDefined @@ -28,24 +27,31 @@ def begin_tag(self, tag, props=None): return + def end_tag(self): return + def do_tag(self, tag, props=None): return def begin_page(self, page, ctm): return + def end_page(self, page): return + def begin_figure(self, name, bbox, matrix): return + def end_figure(self, name): return def paint_path(self, graphicstate, stroke, fill, evenodd, path): return + def render_image(self, name, stream): return + def render_string(self, textstate, seq): return @@ -74,37 +80,37 @@ seq, matrix, textstate.linematrix, font, fontsize, scaling, charspace, wordspace, rise, dxscale) return - - def render_string_horizontal(self, seq, matrix, (x,y), + + def render_string_horizontal(self, seq, matrix, (x, y), font, fontsize, scaling, charspace, wordspace, rise, dxscale): needcharspace = False for obj in seq: - if isinstance(obj, int) or isinstance(obj, float): + if isnumber(obj): x -= obj*dxscale needcharspace = True else: for cid in font.decode(obj): if needcharspace: x += charspace - x += self.render_char(translate_matrix(matrix, (x,y)), + x += self.render_char(translate_matrix(matrix, (x, y)), font, fontsize, scaling, rise, cid) if cid == 32 and wordspace: x += wordspace needcharspace = True return (x, y) - def render_string_vertical(self, seq, matrix, (x,y), + def render_string_vertical(self, seq, matrix, (x, y), font, fontsize, scaling, charspace, wordspace, rise, dxscale): needcharspace = False for obj in seq: - if isinstance(obj, int) or isinstance(obj, float): + if isnumber(obj): y -= obj*dxscale needcharspace = True else: for cid in font.decode(obj): if needcharspace: y += charspace - y += self.render_char(translate_matrix(matrix, (x,y)), + y += self.render_char(translate_matrix(matrix, (x, y)), font, fontsize, scaling, rise, cid) if cid == 32 and wordspace: y += wordspace @@ -132,7 +138,8 @@ font = textstate.font text = '' for obj in seq: - if not isinstance(obj, str): continue + if not isinstance(obj, str): + continue chars = font.decode(obj) for cid in chars: try: @@ -156,8 +163,8 @@ def begin_tag(self, tag, props=None): s = '' if isinstance(props, dict): - s = ''.join( ' %s="%s"' % (enc(k), enc(str(v))) for (k,v) - in sorted(props.iteritems()) ) + s = ''.join(' %s="%s"' % (enc(k), enc(str(v))) for (k, v) + in sorted(props.iteritems())) self.outfp.write('<%s%s>' % (enc(tag.name), s)) self._stack.append(tag) return diff -Nru pdfminer-20110515+dfsg/pdfminer/pdfdocument.py pdfminer-20140328+dfsg/pdfminer/pdfdocument.py --- pdfminer-20110515+dfsg/pdfminer/pdfdocument.py 1970-01-01 00:00:00.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdfdocument.py 2015-10-11 18:33:29.000000000 +0000 @@ -0,0 +1,599 @@ +#!/usr/bin/env python +import sys +import re +import struct +try: + import hashlib as md5 +except ImportError: + import md5 +from psparser import PSEOF +from psparser import literal_name +from psparser import LIT, KWD, STRICT +from pdftypes import PDFException, PDFTypeError, PDFNotImplementedError +from pdftypes import PDFObjectNotFound, PDFStream +from pdftypes import decipher_all +from pdftypes import int_value +from pdftypes import str_value, list_value, dict_value, stream_value +from pdfparser import PDFSyntaxError +from pdfparser import PDFStreamParser +from arcfour import Arcfour +from utils import choplist, nunpack +from utils import decode_text + + +## Exceptions +## +class PDFNoValidXRef(PDFSyntaxError): + pass + +class PDFNoOutlines(PDFException): + pass + +class PDFDestinationNotFound(PDFException): + pass + +class PDFEncryptionError(PDFException): + pass + +class PDFPasswordIncorrect(PDFEncryptionError): + pass + +class PDFTextExtractionNotAllowed(PDFEncryptionError): + pass + +# some predefined literals and keywords. +LITERAL_OBJSTM = LIT('ObjStm') +LITERAL_XREF = LIT('XRef') +LITERAL_CATALOG = LIT('Catalog') + + +## XRefs +## +class PDFBaseXRef(object): + + def get_trailer(self): + raise NotImplementedError + + def get_objids(self): + return [] + + # Must return + # (strmid, index, genno) + # or (None, pos, genno) + def get_pos(self, objid): + raise KeyError(objid) + + +## PDFXRef +## +class PDFXRef(PDFBaseXRef): + + def __init__(self): + self.offsets = {} + self.trailer = {} + return + + def __repr__(self): + return '' % (self.offsets.keys()) + + def load(self, parser, debug=0): + while 1: + try: + (pos, line) = parser.nextline() + if not line.strip(): + continue + except PSEOF: + raise PDFNoValidXRef('Unexpected EOF - file corrupted?') + if not line: + raise PDFNoValidXRef('Premature eof: %r' % parser) + if line.startswith('trailer'): + parser.seek(pos) + break + f = line.strip().split(' ') + if len(f) != 2: + raise PDFNoValidXRef('Trailer not found: %r: line=%r' % (parser, line)) + try: + (start, nobjs) = map(long, f) + except ValueError: + raise PDFNoValidXRef('Invalid line: %r: line=%r' % (parser, line)) + for objid in xrange(start, start+nobjs): + try: + (_, line) = parser.nextline() + except PSEOF: + raise PDFNoValidXRef('Unexpected EOF - file corrupted?') + f = line.strip().split(' ') + if len(f) != 3: + raise PDFNoValidXRef('Invalid XRef format: %r, line=%r' % (parser, line)) + (pos, genno, use) = f + if use != 'n': + continue + self.offsets[objid] = (None, long(pos), int(genno)) + if 1 <= debug: + print >>sys.stderr, 'xref objects:', self.offsets + self.load_trailer(parser) + return + + KEYWORD_TRAILER = KWD('trailer') + + def load_trailer(self, parser): + try: + (_, kwd) = parser.nexttoken() + assert kwd is self.KEYWORD_TRAILER + (_, dic) = parser.nextobject() + except PSEOF: + x = parser.pop(1) + if not x: + raise PDFNoValidXRef('Unexpected EOF - file corrupted') + (_, dic) = x[0] + self.trailer.update(dict_value(dic)) + return + + def get_trailer(self): + return self.trailer + + def get_objids(self): + return self.offsets.iterkeys() + + def get_pos(self, objid): + try: + return self.offsets[objid] + except KeyError: + raise + + +## PDFXRefFallback +## +class PDFXRefFallback(PDFXRef): + + def __repr__(self): + return '' % (self.offsets.keys()) + + PDFOBJ_CUE = re.compile(r'^(\d+)\s+(\d+)\s+obj\b') + + def load(self, parser, debug=0): + parser.seek(0) + while 1: + try: + (pos, line) = parser.nextline() + except PSEOF: + break + if line.startswith('trailer'): + parser.seek(pos) + self.load_trailer(parser) + if 1 <= debug: + print >>sys.stderr, 'trailer: %r' % self.get_trailer() + break + m = self.PDFOBJ_CUE.match(line) + if not m: + continue + (objid, genno) = m.groups() + objid = int(objid) + genno = int(genno) + self.offsets[objid] = (None, pos, genno) + # expand ObjStm. + parser.seek(pos) + (_, obj) = parser.nextobject() + if isinstance(obj, PDFStream) and obj.get('Type') is LITERAL_OBJSTM: + stream = stream_value(obj) + try: + n = stream['N'] + except KeyError: + if STRICT: + raise PDFSyntaxError('N is not defined: %r' % stream) + n = 0 + parser1 = PDFStreamParser(stream.get_data()) + objs = [] + try: + while 1: + (_, obj) = parser1.nextobject() + objs.append(obj) + except PSEOF: + pass + n = min(n, len(objs)//2) + for index in xrange(n): + objid1 = objs[index*2] + self.offsets[objid1] = (objid, index, 0) + return + + +## PDFXRefStream +## +class PDFXRefStream(PDFBaseXRef): + + def __init__(self): + self.data = None + self.entlen = None + self.fl1 = self.fl2 = self.fl3 = None + self.ranges = [] + return + + def __repr__(self): + return '' % (self.ranges) + + def load(self, parser, debug=0): + (_, objid) = parser.nexttoken() # ignored + (_, genno) = parser.nexttoken() # ignored + (_, kwd) = parser.nexttoken() + (_, stream) = parser.nextobject() + if not isinstance(stream, PDFStream) or stream['Type'] is not LITERAL_XREF: + raise PDFNoValidXRef('Invalid PDF stream spec.') + size = stream['Size'] + index_array = stream.get('Index', (0, size)) + if len(index_array) % 2 != 0: + raise PDFSyntaxError('Invalid index number') + self.ranges.extend(choplist(2, index_array)) + (self.fl1, self.fl2, self.fl3) = stream['W'] + self.data = stream.get_data() + self.entlen = self.fl1+self.fl2+self.fl3 + self.trailer = stream.attrs + if 1 <= debug: + print >>sys.stderr, ('xref stream: objid=%s, fields=%d,%d,%d' % + (', '.join(map(repr, self.ranges)), + self.fl1, self.fl2, self.fl3)) + return + + def get_trailer(self): + return self.trailer + + def get_objids(self): + for (start, nobjs) in self.ranges: + for i in xrange(nobjs): + offset = self.entlen * i + ent = self.data[offset:offset+self.entlen] + f1 = nunpack(ent[:self.fl1], 1) + if f1 == 1 or f1 == 2: + yield start+i + return + + def get_pos(self, objid): + index = 0 + for (start, nobjs) in self.ranges: + if start <= objid and objid < start+nobjs: + index += objid - start + break + else: + index += nobjs + else: + raise KeyError(objid) + offset = self.entlen * index + ent = self.data[offset:offset+self.entlen] + f1 = nunpack(ent[:self.fl1], 1) + f2 = nunpack(ent[self.fl1:self.fl1+self.fl2]) + f3 = nunpack(ent[self.fl1+self.fl2:]) + if f1 == 1: + return (None, f2, f3) + elif f1 == 2: + return (f2, f3, 0) + else: + # this is a free object + raise KeyError(objid) + + +## PDFDocument +## +class PDFDocument(object): + + """PDFDocument object represents a PDF document. + + Since a PDF file can be very big, normally it is not loaded at + once. So PDF document has to cooperate with a PDF parser in order to + dynamically import the data as processing goes. + + Typical usage: + doc = PDFDocument(parser, password) + obj = doc.getobj(objid) + + """ + + debug = 0 + PASSWORD_PADDING = '(\xbfN^Nu\x8aAd\x00NV\xff\xfa\x01\x08..\x00\xb6\xd0h>\x80/\x0c\xa9\xfedSiz' + + def __init__(self, parser, password='', caching=True, fallback=True): + "Set the document to use a given PDFParser object." + self.caching = caching + self.xrefs = [] + self.info = [] + self.catalog = None + self.encryption = None + self.decipher = None + self._parser = None + self._cached_objs = {} + self._parsed_objs = {} + self._parser = parser + self._parser.set_document(self) + self.is_printable = self.is_modifiable = self.is_extractable = True + # Retrieve the information of each header that was appended + # (maybe multiple times) at the end of the document. + try: + pos = self.find_xref(parser) + self.read_xref_from(parser, pos, self.xrefs) + except PDFNoValidXRef: + fallback = True + if fallback: + parser.fallback = True + xref = PDFXRefFallback() + xref.load(parser) + self.xrefs.append(xref) + for xref in self.xrefs: + trailer = xref.get_trailer() + if not trailer: + continue + # If there's an encryption info, remember it. + if 'Encrypt' in trailer: + #assert not self.encryption + self.encryption = (list_value(trailer['ID']), + dict_value(trailer['Encrypt'])) + self._initialize_password(password) + if 'Info' in trailer: + self.info.append(dict_value(trailer['Info'])) + if 'Root' in trailer: + # Every PDF file must have exactly one /Root dictionary. + self.catalog = dict_value(trailer['Root']) + break + else: + raise PDFSyntaxError('No /Root object! - Is this really a PDF?') + if self.catalog.get('Type') is not LITERAL_CATALOG: + if STRICT: + raise PDFSyntaxError('Catalog not found!') + return + + # _initialize_password(password='') + # Perform the initialization with a given password. + def _initialize_password(self, password=''): + (docid, param) = self.encryption + if literal_name(param.get('Filter')) != 'Standard': + raise PDFEncryptionError('Unknown filter: param=%r' % param) + V = int_value(param.get('V', 0)) + if not (V == 1 or V == 2): + raise PDFEncryptionError('Unknown algorithm: param=%r' % param) + length = int_value(param.get('Length', 40)) # Key length (bits) + O = str_value(param['O']) + R = int_value(param['R']) # Revision + if 5 <= R: + raise PDFEncryptionError('Unknown revision: %r' % R) + U = str_value(param['U']) + P = int_value(param['P']) + self.is_printable = bool(P & 4) + self.is_modifiable = bool(P & 8) + self.is_extractable = bool(P & 16) + # Algorithm 3.2 + password = (password+self.PASSWORD_PADDING)[:32] # 1 + hash = md5.md5(password) # 2 + hash.update(O) # 3 + hash.update(struct.pack('>sys.stderr, 'getobj: objid=%r' % (objid) + if objid in self._cached_objs: + (obj, genno) = self._cached_objs[objid] + else: + for xref in self.xrefs: + try: + (strmid, index, genno) = xref.get_pos(objid) + except KeyError: + continue + try: + if strmid is not None: + stream = stream_value(self.getobj(strmid)) + obj = self._getobj_objstm(stream, index, objid) + else: + obj = self._getobj_parse(index, objid) + if isinstance(obj, PDFStream): + obj.set_objid(objid, genno) + break + except (PSEOF, PDFSyntaxError): + continue + else: + raise PDFObjectNotFound(objid) + if 2 <= self.debug: + print >>sys.stderr, 'register: objid=%r: %r' % (objid, obj) + if self.caching: + self._cached_objs[objid] = (obj, genno) + if self.decipher: + obj = decipher_all(self.decipher, objid, genno, obj) + return obj + + def get_outlines(self): + if 'Outlines' not in self.catalog: + raise PDFNoOutlines + + def search(entry, level): + entry = dict_value(entry) + if 'Title' in entry: + if 'A' in entry or 'Dest' in entry: + title = decode_text(str_value(entry['Title'])) + dest = entry.get('Dest') + action = entry.get('A') + se = entry.get('SE') + yield (level, title, dest, action, se) + if 'First' in entry and 'Last' in entry: + for x in search(entry['First'], level+1): + yield x + if 'Next' in entry: + for x in search(entry['Next'], level): + yield x + return + return search(self.catalog['Outlines'], 0) + + def lookup_name(self, cat, key): + try: + names = dict_value(self.catalog['Names']) + except (PDFTypeError, KeyError): + raise KeyError((cat, key)) + # may raise KeyError + d0 = dict_value(names[cat]) + + def lookup(d): + if 'Limits' in d: + (k1, k2) = list_value(d['Limits']) + if key < k1 or k2 < key: + return None + if 'Names' in d: + objs = list_value(d['Names']) + names = dict(choplist(2, objs)) + return names[key] + if 'Kids' in d: + for c in list_value(d['Kids']): + v = lookup(dict_value(c)) + if v: + return v + raise KeyError((cat, key)) + return lookup(d0) + + def get_dest(self, name): + try: + # PDF-1.2 or later + obj = self.lookup_name('Dests', name) + except KeyError: + # PDF-1.1 or prior + if 'Dests' not in self.catalog: + raise PDFDestinationNotFound(name) + d0 = dict_value(self.catalog['Dests']) + if name not in d0: + raise PDFDestinationNotFound(name) + obj = d0[name] + return obj + + # find_xref + def find_xref(self, parser): + """Internal function used to locate the first XRef.""" + # search the last xref table by scanning the file backwards. + prev = None + for line in parser.revreadlines(): + line = line.strip() + if 2 <= self.debug: + print >>sys.stderr, 'find_xref: %r' % line + if line == 'startxref': + break + if line: + prev = line + else: + raise PDFNoValidXRef('Unexpected EOF') + if 1 <= self.debug: + print >>sys.stderr, 'xref found: pos=%r' % prev + return long(prev) + + # read xref table + def read_xref_from(self, parser, start, xrefs): + """Reads XRefs from the given location.""" + parser.seek(start) + parser.reset() + try: + (pos, token) = parser.nexttoken() + except PSEOF: + raise PDFNoValidXRef('Unexpected EOF') + if 2 <= self.debug: + print >>sys.stderr, 'read_xref_from: start=%d, token=%r' % (start, token) + if isinstance(token, int): + # XRefStream: PDF-1.5 + parser.seek(pos) + parser.reset() + xref = PDFXRefStream() + xref.load(parser, debug=self.debug) + else: + if token is parser.KEYWORD_XREF: + parser.nextline() + xref = PDFXRef() + xref.load(parser, debug=self.debug) + xrefs.append(xref) + trailer = xref.get_trailer() + if 1 <= self.debug: + print >>sys.stderr, 'trailer: %r' % trailer + if 'XRefStm' in trailer: + pos = int_value(trailer['XRefStm']) + self.read_xref_from(parser, pos, xrefs) + if 'Prev' in trailer: + # find previous xref + pos = int_value(trailer['Prev']) + self.read_xref_from(parser, pos, xrefs) + return diff -Nru pdfminer-20110515+dfsg/pdfminer/pdffont.py pdfminer-20140328+dfsg/pdfminer/pdffont.py --- pdfminer-20110515+dfsg/pdfminer/pdffont.py 2011-03-02 14:39:10.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdffont.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys import struct try: @@ -8,14 +8,14 @@ from cmapdb import CMapDB, CMapParser, FileUnicodeMap, CMap from encodingdb import EncodingDB, name2unicode from psparser import PSStackParser -from psparser import PSSyntaxError, PSEOF +from psparser import PSEOF from psparser import LIT, KWD, STRICT from psparser import PSLiteral, literal_name from pdftypes import PDFException, resolve1 -from pdftypes import int_value, float_value, num_value -from pdftypes import str_value, list_value, dict_value, stream_value +from pdftypes import int_value, num_value +from pdftypes import list_value, dict_value, stream_value from fontmetrics import FONT_METRICS -from utils import apply_matrix_norm, nunpack, choplist +from utils import apply_matrix_norm, nunpack, choplist, isnumber def get_widths(seq): @@ -25,13 +25,13 @@ if isinstance(v, list): if r: char1 = r[-1] - for (i,w) in enumerate(v): + for (i, w) in enumerate(v): widths[char1+i] = w r = [] - elif isinstance(v, int): + elif isnumber(v): r.append(v) if len(r) == 3: - (char1,char2,w) = r + (char1, char2, w) = r for i in xrange(char1, char2+1): widths[i] = w r = [] @@ -40,6 +40,7 @@ #assert get_widths([1,2,3]) == {1:3, 2:3} #assert get_widths([1,[2,3],6,[7,8]]) == {1:2,2:3, 6:7,7:8} + def get_widths2(seq): widths = {} r = [] @@ -47,20 +48,20 @@ if isinstance(v, list): if r: char1 = r[-1] - for (i,(w,vx,vy)) in enumerate(choplist(3,v)): - widths[char1+i] = (w,(vx,vy)) + for (i, (w, vx, vy)) in enumerate(choplist(3, v)): + widths[char1+i] = (w, (vx, vy)) r = [] - elif isinstance(v, int): + elif isnumber(v): r.append(v) if len(r) == 5: - (char1,char2,w,vx,vy) = r + (char1, char2, w, vx, vy) = r for i in xrange(char1, char2+1): - widths[i] = (w,(vx,vy)) + widths[i] = (w, (vx, vy)) r = [] return widths #assert get_widths2([1]) == {} -#assert get_widths2([1,2,3,4,5]) == {1:(3,(4,5)), 2:(3,(4,5))} -#assert get_widths2([1,[2,3,4,5],6,[7,8,9]]) == {1:(2,(3,4)), 6:(7,(8,9))} +#assert get_widths2([1,2,3,4,5]) == {1:(3, (4,5)), 2:(3, (4,5))} +#assert get_widths2([1,[2,3,4,5],6,[7,8,9]]) == {1:(2, (3,4)), 6:(7, (8,9))} ## FontMetricsDB @@ -94,7 +95,7 @@ def get_encoding(self): while 1: try: - (cid,name) = self.nextobject() + (cid, name) = self.nextobject() except PSEOF: break try: @@ -102,28 +103,31 @@ except KeyError: pass return self._cid2unicode - + def do_keyword(self, pos, token): if token is self.KEYWORD_PUT: - ((_,key),(_,value)) = self.pop(2) + ((_, key), (_, value)) = self.pop(2) if (isinstance(key, int) and isinstance(value, PSLiteral)): self.add_results((key, literal_name(value))) return - + +NIBBLES = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'e-', None, '-') + + ## CFFFont ## (Format specified in Adobe Technical Note: #5176 ## "The Compact Font Format Specification") ## -NIBBLES = ('0','1','2','3','4','5','6','7','8','9','.','e','e-',None,'-') def getdict(data): d = {} fp = StringIO(data) stack = [] while 1: c = fp.read(1) - if not c: break + if not c: + break b0 = ord(c) if b0 <= 21: d[b0] = stack @@ -145,19 +149,21 @@ else: b1 = ord(fp.read(1)) if 247 <= b0 and b0 <= 250: - value = ((b0-247)<<8)+b1+108 + value = ((b0-247) << 8)+b1+108 elif 251 <= b0 and b0 <= 254: - value = -((b0-251)<<8)-b1-108 + value = -((b0-251) << 8)-b1-108 else: b2 = ord(fp.read(1)) - if 128 <= b1: b1 -= 256 + if 128 <= b1: + b1 -= 256 if b0 == 28: - value = b1<<8 | b2 + value = b1 << 8 | b2 else: - value = b1<<24 | b2<<16 | struct.unpack('>H', fp.read(2))[0] + value = b1 << 24 | b2 << 16 | struct.unpack('>H', fp.read(2))[0] stack.append(value) return d + class CFFFont(object): STANDARD_STRINGS = ( @@ -239,7 +245,7 @@ 'Yacutesmall', 'Thornsmall', 'Ydieresissmall', '001.000', '001.001', '001.002', '001.003', 'Black', 'Bold', 'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold', - ) + ) class INDEX(object): @@ -264,13 +270,13 @@ return self.fp.read(self.offsets[i+1]-self.offsets[i]) def __iter__(self): - return iter( self[i] for i in xrange(len(self)) ) + return iter(self[i] for i in xrange(len(self))) def __init__(self, name, fp): self.name = name self.fp = fp # Header - (_major,_minor,hdrsize,offsize) = struct.unpack('BBBB', self.fp.read(4)) + (_major, _minor, hdrsize, offsize) = struct.unpack('BBBB', self.fp.read(4)) self.fp.read(hdrsize-4) # Name INDEX self.name_index = self.INDEX(self.fp) @@ -297,7 +303,7 @@ if format == '\x00': # Format 0 (n,) = struct.unpack('B', self.fp.read(1)) - for (code,gid) in enumerate(struct.unpack('B'*n, self.fp.read(n))): + for (code, gid) in enumerate(struct.unpack('B'*n, self.fp.read(n))): self.code2gid[code] = gid self.gid2code[gid] = code elif format == '\x01': @@ -305,8 +311,8 @@ (n,) = struct.unpack('B', self.fp.read(1)) code = 0 for i in xrange(n): - (first,nleft) = struct.unpack('BB', self.fp.read(2)) - for gid in xrange(first,first+nleft+1): + (first, nleft) = struct.unpack('BB', self.fp.read(2)) + for gid in xrange(first, first+nleft+1): self.code2gid[code] = gid self.gid2code[gid] = code code += 1 @@ -320,7 +326,7 @@ if format == '\x00': # Format 0 n = self.nglyphs-1 - for (gid,sid) in enumerate(struct.unpack('>'+'H'*n, self.fp.read(2*n))): + for (gid, sid) in enumerate(struct.unpack('>'+'H'*n, self.fp.read(2*n))): gid += 1 name = self.getstr(sid) self.name2gid[name] = gid @@ -330,8 +336,8 @@ (n,) = struct.unpack('B', self.fp.read(1)) sid = 0 for i in xrange(n): - (first,nleft) = struct.unpack('BB', self.fp.read(2)) - for gid in xrange(first,first+nleft+1): + (first, nleft) = struct.unpack('BB', self.fp.read(2)) + for gid in xrange(first, first+nleft+1): name = self.getstr(sid) self.name2gid[name] = gid self.gid2name[gid] = name @@ -356,7 +362,8 @@ ## class TrueTypeFont(object): - class CMapNotFound(Exception): pass + class CMapNotFound(Exception): + pass def __init__(self, name, fp): self.name = name @@ -389,15 +396,16 @@ elif fmttype == 2: subheaderkeys = struct.unpack('>256H', fp.read(512)) firstbytes = [0]*8192 - for (i,k) in enumerate(subheaderkeys): - firstbytes[k/8] = i - nhdrs = max(subheaderkeys)/8 + 1 + for (i, k) in enumerate(subheaderkeys): + firstbytes[k//8] = i + nhdrs = max(subheaderkeys)//8 + 1 hdrs = [] for i in xrange(nhdrs): - (firstcode,entcount,delta,offset) = struct.unpack('>HHhH', fp.read(8)) - hdrs.append((i,firstcode,entcount,delta,fp.tell()-2+offset)) - for (i,firstcode,entcount,delta,pos) in hdrs: - if not entcount: continue + (firstcode, entcount, delta, offset) = struct.unpack('>HHhH', fp.read(8)) + hdrs.append((i, firstcode, entcount, delta, fp.tell()-2+offset)) + for (i, firstcode, entcount, delta, pos) in hdrs: + if not entcount: + continue first = firstcode + (firstbytes[i] << 8) fp.seek(pos) for c in xrange(entcount): @@ -407,14 +415,14 @@ char2gid[first+c] = gid elif fmttype == 4: (segcount, _1, _2, _3) = struct.unpack('>HHHH', fp.read(8)) - segcount /= 2 + segcount //= 2 ecs = struct.unpack('>%dH' % segcount, fp.read(2*segcount)) fp.read(2) scs = struct.unpack('>%dH' % segcount, fp.read(2*segcount)) idds = struct.unpack('>%dh' % segcount, fp.read(2*segcount)) pos = fp.tell() idrs = struct.unpack('>%dH' % segcount, fp.read(2*segcount)) - for (ec,sc,idd,idr) in zip(ecs, scs, idds, idrs): + for (ec, sc, idd, idr) in zip(ecs, scs, idds, idrs): if idr: fp.seek(pos+idr) for c in xrange(sc, ec+1): @@ -426,16 +434,19 @@ assert 0 # create unicode map unicode_map = FileUnicodeMap() - for (char,gid) in char2gid.iteritems(): + for (char, gid) in char2gid.iteritems(): unicode_map.add_cid2unichr(gid, char) return unicode_map ## Fonts ## +class PDFFontError(PDFException): + pass -class PDFFontError(PDFException): pass -class PDFUnicodeNotDefined(PDFFontError): pass + +class PDFUnicodeNotDefined(PDFFontError): + pass LITERAL_STANDARD_ENCODING = LIT('StandardEncoding') LITERAL_TYPE1C = LIT('Type1C') @@ -456,7 +467,7 @@ self.italic_angle = num_value(descriptor.get('ItalicAngle', 0)) self.default_width = default_width or num_value(descriptor.get('MissingWidth', 0)) self.leading = num_value(descriptor.get('Leading', 0)) - self.bbox = list_value(descriptor.get('FontBBox', (0,0,0,0))) + self.bbox = list_value(descriptor.get('FontBBox', (0, 0, 0, 0))) self.hscale = self.vscale = .001 return @@ -474,6 +485,7 @@ def get_ascent(self): return self.ascent * self.vscale + def get_descent(self): return self.descent * self.vscale @@ -482,6 +494,7 @@ if w == 0: w = -self.default_width return w * self.hscale + def get_height(self): h = self.bbox[3]-self.bbox[1] if h == 0: @@ -489,13 +502,19 @@ return h * self.vscale def char_width(self, cid): - return self.widths.get(cid, self.default_width) * self.hscale + try: + return self.widths[cid] * self.hscale + except KeyError: + try: + return self.widths[self.to_unichr(cid)] * self.hscale + except (KeyError, PDFUnicodeNotDefined): + return self.default_width * self.hscale def char_disp(self, cid): return 0 def string_width(self, s): - return sum( self.char_width(cid) for cid in self.decode(s) ) + return sum(self.char_width(cid) for cid in self.decode(s)) # PDFSimpleFont @@ -534,6 +553,7 @@ except KeyError: raise PDFUnicodeNotDefined(None, cid) + # PDFType1Font class PDFType1Font(PDFSimpleFont): @@ -551,7 +571,7 @@ firstchar = int_value(spec.get('FirstChar', 0)) lastchar = int_value(spec.get('LastChar', 255)) widths = list_value(spec.get('Widths', [0]*256)) - widths = dict( (i+firstchar,w) for (i,w) in enumerate(widths) ) + widths = dict((i+firstchar, w) for (i, w) in enumerate(widths)) PDFSimpleFont.__init__(self, descriptor, widths, spec) if 'Encoding' not in spec and 'FontFile' in descriptor: # try to recover the missing encoding info from the font file. @@ -565,12 +585,14 @@ def __repr__(self): return '' % self.basefont + # PDFTrueTypeFont class PDFTrueTypeFont(PDFType1Font): def __repr__(self): return '' % self.basefont + # PDFType3Font class PDFType3Font(PDFSimpleFont): @@ -578,16 +600,16 @@ firstchar = int_value(spec.get('FirstChar', 0)) lastchar = int_value(spec.get('LastChar', 0)) widths = list_value(spec.get('Widths', [0]*256)) - widths = dict( (i+firstchar,w) for (i,w) in enumerate(widths)) + widths = dict((i+firstchar, w) for (i, w) in enumerate(widths)) if 'FontDescriptor' in spec: descriptor = dict_value(spec['FontDescriptor']) else: - descriptor = {'Ascent':0, 'Descent':0, - 'FontBBox':spec['FontBBox']} + descriptor = {'Ascent': 0, 'Descent': 0, + 'FontBBox': spec['FontBBox']} PDFSimpleFont.__init__(self, descriptor, widths, spec) self.matrix = tuple(list_value(spec.get('FontMatrix'))) - (_,self.descent,_,self.ascent) = self.bbox - (self.hscale,self.vscale) = apply_matrix_norm(self.matrix, (1,1)) + (_, self.descent, _, self.ascent) = self.bbox + (self.hscale, self.vscale) = apply_matrix_norm(self.matrix, (1, 1)) return def __repr__(self): @@ -635,7 +657,7 @@ strm = stream_value(spec['ToUnicode']) self.unicode_map = FileUnicodeMap() CMapParser(self.unicode_map, StringIO(strm.get_data())).run() - elif self.cidcoding == 'Adobe-Identity': + elif self.cidcoding in ('Adobe-Identity', 'Adobe-UCS'): if ttf: try: self.unicode_map = ttf.create_unicode_map() @@ -651,10 +673,10 @@ if self.vertical: # writing mode: vertical widths = get_widths2(list_value(spec.get('W2', []))) - self.disps = dict( (cid,(vx,vy)) for (cid,(_,(vx,vy))) in widths.iteritems() ) - (vy,w) = spec.get('DW2', [880, -1000]) - self.default_disp = (None,vy) - widths = dict( (cid,w) for (cid,(w,_)) in widths.iteritems() ) + self.disps = dict((cid, (vx, vy)) for (cid, (_, (vx, vy))) in widths.iteritems()) + (vy, w) = spec.get('DW2', [880, -1000]) + self.default_disp = (None, vy) + widths = dict((cid, w) for (cid, (w, _)) in widths.iteritems()) default_width = w else: # writing mode: horizontal @@ -683,7 +705,8 @@ def to_unichr(self, cid): try: - if not self.unicode_map: raise KeyError(cid) + if not self.unicode_map: + raise KeyError(cid) return self.unicode_map.get_unichr(cid) except KeyError: raise PDFUnicodeNotDefined(self.cidcoding, cid) @@ -699,4 +722,5 @@ fp.close() return -if __name__ == '__main__': sys.exit(main(sys.argv)) +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff -Nru pdfminer-20110515+dfsg/pdfminer/pdfinterp.py pdfminer-20140328+dfsg/pdfminer/pdfinterp.py --- pdfminer-20110515+dfsg/pdfminer/pdfinterp.py 2011-03-02 15:00:41.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdfinterp.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys import re try: @@ -6,19 +6,16 @@ except ImportError: from StringIO import StringIO from cmapdb import CMapDB, CMap -from psparser import PSException, PSTypeError, PSEOF +from psparser import PSTypeError, PSEOF from psparser import PSKeyword, literal_name, keyword_name from psparser import PSStackParser from psparser import LIT, KWD, STRICT from pdftypes import PDFException, PDFStream, PDFObjRef from pdftypes import resolve1 -from pdftypes import int_value, float_value, num_value -from pdftypes import str_value, list_value, dict_value, stream_value +from pdftypes import list_value, dict_value, stream_value from pdffont import PDFFontError from pdffont import PDFType1Font, PDFTrueTypeFont, PDFType3Font from pdffont import PDFCIDFont -from pdfparser import PDFDocument, PDFParser -from pdfparser import PDFPasswordIncorrect from pdfcolor import PDFColorSpace from pdfcolor import PREDEFINED_COLORSPACE from pdfcolor import LITERAL_DEVICE_GRAY, LITERAL_DEVICE_RGB @@ -29,8 +26,11 @@ ## Exceptions ## -class PDFResourceError(PDFException): pass -class PDFInterpreterError(PDFException): pass +class PDFResourceError(PDFException): + pass + +class PDFInterpreterError(PDFException): + pass ## Constants @@ -119,12 +119,13 @@ (self.linewidth, self.linecap, self.linejoin, self.miterlimit, self.dash, self.intent, self.flatness)) + ## Resource Manager ## class PDFResourceManager(object): """Repository of shared resources. - + ResourceManager facilitates reuse of shared resources such as fonts and images so that large objects are not allocated multiple times. @@ -151,7 +152,8 @@ try: return CMapDB.get_cmap(cmapname) except CMapDB.CMapNotFound: - if strict: raise + if strict: + raise return CMap() def get_font(self, objid, spec): @@ -194,7 +196,7 @@ else: if STRICT: raise PDFFontError('Invalid Font spec: %r' % spec) - font = PDFType1Font(self, spec) # this is so wrong! + font = PDFType1Font(self, spec) # this is so wrong! if objid and self.caching: self._cached_fonts[objid] = font return font @@ -226,12 +228,14 @@ return def fillbuf(self): - if self.charpos < len(self.buf): return + if self.charpos < len(self.buf): + return while 1: self.fillfp() self.bufpos = self.fp.tell() self.buf = self.fp.read(self.BUFSIZ) - if self.buf: break + if self.buf: + break self.fp = None self.charpos = 0 return @@ -262,7 +266,7 @@ except ValueError: data += self.buf[self.charpos:] self.charpos = len(self.buf) - data = data[:-(len(target)+1)] # strip the last part + data = data[:-(len(target)+1)] # strip the last part data = re.sub(r'(\x0d\x0a|[\x0d\x0a])$', '', data) return (pos, data) @@ -273,6 +277,7 @@ KEYWORD_BI = KWD('BI') KEYWORD_ID = KWD('ID') KEYWORD_EI = KWD('EI') + def do_keyword(self, pos, token): if token is self.KEYWORD_BI: # inline image within a content stream @@ -282,13 +287,14 @@ (_, objs) = self.end_type('inline') if len(objs) % 2 != 0: raise PSTypeError('Invalid dictionary construct: %r' % objs) - d = dict( (literal_name(k), v) for (k,v) in choplist(2, objs) ) + d = dict((literal_name(k), v) for (k, v) in choplist(2, objs)) (pos, data) = self.get_inline_data(pos+len('ID ')) obj = PDFStream(d, data) self.push((pos, obj)) self.push((pos, self.KEYWORD_EI)) except PSTypeError: - if STRICT: raise + if STRICT: + raise else: self.push((pos, token)) return @@ -306,7 +312,7 @@ return def dup(self): - return PDFPageInterpreter(self.rsrcmgr, self.device) + return self.__class__(self.rsrcmgr, self.device) # init_resources(resources): # Prepare the fonts and XObjects listed in the Resource attribute. @@ -315,7 +321,9 @@ self.fontmap = {} self.xobjmap = {} self.csmap = PREDEFINED_COLORSPACE.copy() - if not resources: return + if not resources: + return + def get_colorspace(spec): if isinstance(spec, list): name = literal_name(spec[0]) @@ -326,24 +334,24 @@ elif name == 'DeviceN' and isinstance(spec, list) and 2 <= len(spec): return PDFColorSpace(name, len(list_value(spec[1]))) else: - return PREDEFINED_COLORSPACE[name] - for (k,v) in dict_value(resources).iteritems(): + return PREDEFINED_COLORSPACE.get(name) + for (k, v) in dict_value(resources).iteritems(): if 2 <= self.debug: - print >>sys.stderr, 'Resource: %r: %r' % (k,v) + print >>sys.stderr, 'Resource: %r: %r' % (k, v) if k == 'Font': - for (fontid,spec) in dict_value(v).iteritems(): + for (fontid, spec) in dict_value(v).iteritems(): objid = None if isinstance(spec, PDFObjRef): objid = spec.objid spec = dict_value(spec) self.fontmap[fontid] = self.rsrcmgr.get_font(objid, spec) elif k == 'ColorSpace': - for (csid,spec) in dict_value(v).iteritems(): + for (csid, spec) in dict_value(v).iteritems(): self.csmap[csid] = get_colorspace(resolve1(spec)) elif k == 'ProcSet': self.rsrcmgr.get_procset(list_value(v)) elif k == 'XObject': - for (xobjid,xobjstrm) in dict_value(v).iteritems(): + for (xobjid, xobjstrm) in dict_value(v).iteritems(): self.xobjmap[xobjid] = xobjstrm return @@ -370,7 +378,8 @@ return def pop(self, n): - if n == 0: return [] + if n == 0: + return [] x = self.argstack[-n:] self.argstack = self.argstack[:-n] return x @@ -387,6 +396,7 @@ def do_q(self): self.gstack.append(self.get_current_state()) return + # grestore def do_Q(self): if self.gstack: @@ -395,7 +405,7 @@ # concat-matrix def do_cm(self, a1, b1, c1, d1, e1, f1): - self.ctm = mult_matrix((a1,b1,c1,d1,e1,f1), self.ctm) + self.ctm = mult_matrix((a1, b1, c1, d1, e1, f1), self.ctm) self.device.set_ctm(self.ctm) return @@ -403,30 +413,37 @@ def do_w(self, linewidth): self.graphicstate.linewidth = linewidth return + # setlinecap def do_J(self, linecap): self.graphicstate.linecap = linecap return + # setlinejoin def do_j(self, linejoin): self.graphicstate.linejoin = linejoin return + # setmiterlimit def do_M(self, miterlimit): self.graphicstate.miterlimit = miterlimit return + # setdash def do_d(self, dash, phase): self.graphicstate.dash = (dash, phase) return + # setintent def do_ri(self, intent): self.graphicstate.intent = intent return + # setflatness def do_i(self, flatness): self.graphicstate.flatness = flatness return + # load-gstate def do_gs(self, name): #XXX @@ -434,34 +451,40 @@ # moveto def do_m(self, x, y): - self.curpath.append(('m',x,y)) + self.curpath.append(('m', x, y)) return + # lineto def do_l(self, x, y): - self.curpath.append(('l',x,y)) + self.curpath.append(('l', x, y)) return + # curveto def do_c(self, x1, y1, x2, y2, x3, y3): - self.curpath.append(('c',x1,y1,x2,y2,x3,y3)) + self.curpath.append(('c', x1, y1, x2, y2, x3, y3)) return + # urveto def do_v(self, x2, y2, x3, y3): - self.curpath.append(('v',x2,y2,x3,y3)) + self.curpath.append(('v', x2, y2, x3, y3)) return + # rveto def do_y(self, x1, y1, x3, y3): - self.curpath.append(('y',x1,y1,x3,y3)) + self.curpath.append(('y', x1, y1, x3, y3)) return + # closepath def do_h(self): self.curpath.append(('h',)) return + # rectangle def do_re(self, x, y, w, h): - self.curpath.append(('m',x,y)) - self.curpath.append(('l',x+w,y)) - self.curpath.append(('l',x+w,y+h)) - self.curpath.append(('l',x,y+h)) + self.curpath.append(('m', x, y)) + self.curpath.append(('l', x+w, y)) + self.curpath.append(('l', x+w, y+h)) + self.curpath.append(('l', x, y+h)) self.curpath.append(('h',)) return @@ -470,11 +493,13 @@ self.device.paint_path(self.graphicstate, True, False, False, self.curpath) self.curpath = [] return + # close-and-stroke def do_s(self): self.do_h() self.do_S() return + # fill def do_f(self): self.device.paint_path(self.graphicstate, False, True, False, self.curpath) @@ -482,68 +507,93 @@ return # fill (obsolete) do_F = do_f + # fill-even-odd def do_f_a(self): self.device.paint_path(self.graphicstate, False, True, True, self.curpath) self.curpath = [] return + # fill-and-stroke def do_B(self): self.device.paint_path(self.graphicstate, True, True, False, self.curpath) self.curpath = [] return + # fill-and-stroke-even-odd def do_B_a(self): self.device.paint_path(self.graphicstate, True, True, True, self.curpath) self.curpath = [] return + # close-fill-and-stroke def do_b(self): self.do_h() self.do_B() return + # close-fill-and-stroke-even-odd def do_b_a(self): self.do_h() self.do_B_a() return + # close-only def do_n(self): self.curpath = [] return + # clip - def do_W(self): return + def do_W(self): + return + # clip-even-odd - def do_W_a(self): return + def do_W_a(self): + return # setcolorspace-stroking def do_CS(self, name): - self.scs = self.csmap[literal_name(name)] + try: + self.scs = self.csmap[literal_name(name)] + except KeyError: + if STRICT: + raise PDFInterpreterError('Undefined ColorSpace: %r' % name) return + # setcolorspace-non-strokine def do_cs(self, name): - self.ncs = self.csmap[literal_name(name)] + try: + self.ncs = self.csmap[literal_name(name)] + except KeyError: + if STRICT: + raise PDFInterpreterError('Undefined ColorSpace: %r' % name) return + # setgray-stroking def do_G(self, gray): #self.do_CS(LITERAL_DEVICE_GRAY) return + # setgray-non-stroking def do_g(self, gray): #self.do_cs(LITERAL_DEVICE_GRAY) return + # setrgb-stroking def do_RG(self, r, g, b): #self.do_CS(LITERAL_DEVICE_RGB) return + # setrgb-non-stroking def do_rg(self, r, g, b): #self.do_cs(LITERAL_DEVICE_RGB) return + # setcmyk-stroking def do_K(self, c, m, y, k): #self.do_CS(LITERAL_DEVICE_CMYK) return + # setcmyk-non-stroking def do_k(self, c, m, y, k): #self.do_cs(LITERAL_DEVICE_CMYK) @@ -559,6 +609,7 @@ n = 1 self.pop(n) return + def do_scn(self): if self.ncs: n = self.ncs.ncomponents @@ -568,42 +619,53 @@ n = 1 self.pop(n) return + def do_SC(self): self.do_SCN() return + def do_sc(self): self.do_scn() return # sharing-name - def do_sh(self, name): return + def do_sh(self, name): + return # begin-text def do_BT(self): self.textstate.reset() return + # end-text def do_ET(self): return # begin-compat - def do_BX(self): return + def do_BX(self): + return + # end-compat - def do_EX(self): return + def do_EX(self): + return # marked content operators def do_MP(self, tag): self.device.do_tag(tag) return + def do_DP(self, tag, props): self.device.do_tag(tag, props) return + def do_BMC(self, tag): self.device.begin_tag(tag) return + def do_BDC(self, tag, props): self.device.begin_tag(tag, props) return + def do_EMC(self): self.device.end_tag() return @@ -612,33 +674,38 @@ def do_Tc(self, space): self.textstate.charspace = space return + # setwordspace def do_Tw(self, space): self.textstate.wordspace = space return + # textscale def do_Tz(self, scale): self.textstate.scaling = scale return + # setleading def do_TL(self, leading): self.textstate.leading = -leading return + # selectfont def do_Tf(self, fontid, fontsize): try: self.textstate.font = self.fontmap[literal_name(fontid)] except KeyError: - raise if STRICT: raise PDFInterpreterError('Undefined Font id: %r' % fontid) - return + self.textstate.font = self.rsrcmgr.get_font(None, {}) self.textstate.fontsize = fontsize return + # setrendering def do_Tr(self, render): self.textstate.render = render return + # settextrise def do_Ts(self, rise): self.textstate.rise = rise @@ -646,49 +713,55 @@ # text-move def do_Td(self, tx, ty): - (a,b,c,d,e,f) = self.textstate.matrix - self.textstate.matrix = (a,b,c,d,tx*a+ty*c+e,tx*b+ty*d+f) + (a, b, c, d, e, f) = self.textstate.matrix + self.textstate.matrix = (a, b, c, d, tx*a+ty*c+e, tx*b+ty*d+f) self.textstate.linematrix = (0, 0) - #print >>sys.stderr, 'Td(%r,%r): %r' % (tx,ty,self.textstate) + #print >>sys.stderr, 'Td(%r,%r): %r' % (tx, ty, self.textstate) return + # text-move def do_TD(self, tx, ty): - (a,b,c,d,e,f) = self.textstate.matrix - self.textstate.matrix = (a,b,c,d,tx*a+ty*c+e,tx*b+ty*d+f) + (a, b, c, d, e, f) = self.textstate.matrix + self.textstate.matrix = (a, b, c, d, tx*a+ty*c+e, tx*b+ty*d+f) self.textstate.leading = ty self.textstate.linematrix = (0, 0) - #print >>sys.stderr, 'TD(%r,%r): %r' % (tx,ty,self.textstate) + #print >>sys.stderr, 'TD(%r,%r): %r' % (tx, ty, self.textstate) return + # textmatrix - def do_Tm(self, a,b,c,d,e,f): - self.textstate.matrix = (a,b,c,d,e,f) + def do_Tm(self, a, b, c, d, e, f): + self.textstate.matrix = (a, b, c, d, e, f) self.textstate.linematrix = (0, 0) return + # nextline def do_T_a(self): - (a,b,c,d,e,f) = self.textstate.matrix - self.textstate.matrix = (a,b,c,d,self.textstate.leading*c+e,self.textstate.leading*d+f) + (a, b, c, d, e, f) = self.textstate.matrix + self.textstate.matrix = (a, b, c, d, self.textstate.leading*c+e, self.textstate.leading*d+f) self.textstate.linematrix = (0, 0) return # show-pos def do_TJ(self, seq): - #print >>sys.stderr, 'TJ(%r): %r' % (seq,self.textstate) + #print >>sys.stderr, 'TJ(%r): %r' % (seq, self.textstate) if self.textstate.font is None: if STRICT: raise PDFInterpreterError('No font specified!') return self.device.render_string(self.textstate, seq) return + # show def do_Tj(self, s): self.do_TJ([s]) return + # quote def do__q(self, s): self.do_T_a() self.do_TJ([s]) return + # doublequote def do__w(self, aw, ac, s): self.do_Tw(aw) @@ -697,14 +770,16 @@ return # inline image - def do_BI(self): # never called + def do_BI(self): # never called return - def do_ID(self): # never called + + def do_ID(self): # never called return + def do_EI(self, obj): if 'W' in obj and 'H' in obj: iobjid = str(id(obj)) - self.device.begin_figure(iobjid, (0,0,1,1), MATRIX_IDENTITY) + self.device.begin_figure(iobjid, (0, 0, 1, 1), MATRIX_IDENTITY) self.device.render_image(iobjid, obj) self.device.end_figure(iobjid) return @@ -725,7 +800,7 @@ interpreter = self.dup() bbox = list_value(xobj['BBox']) matrix = list_value(xobj.get('Matrix', MATRIX_IDENTITY)) - # According to PDF reference 1.7 section 4.9.1, XObjects in + # According to PDF reference 1.7 section 4.9.1, XObjects in # earlier PDFs (prior to v1.2) use the page's Resources entry # instead of having their own Resources entry. resources = dict_value(xobj.get('Resources')) or self.resources.copy() @@ -733,7 +808,7 @@ interpreter.render_contents(resources, [xobj], ctm=mult_matrix(matrix, self.ctm)) self.device.end_figure(xobjid) elif subtype is LITERAL_IMAGE and 'Width' in xobj and 'Height' in xobj: - self.device.begin_figure(xobjid, (0,0,1,1), MATRIX_IDENTITY) + self.device.begin_figure(xobjid, (0, 0, 1, 1), MATRIX_IDENTITY) self.device.render_image(xobjid, xobj) self.device.end_figure(xobjid) else: @@ -744,15 +819,15 @@ def process_page(self, page): if 1 <= self.debug: print >>sys.stderr, 'Processing page: %r' % page - (x0,y0,x1,y1) = page.mediabox + (x0, y0, x1, y1) = page.mediabox if page.rotate == 90: - ctm = (0,-1,1,0, -y0,x1) + ctm = (0, -1, 1, 0, -y0, x1) elif page.rotate == 180: - ctm = (-1,0,0,-1, x1,y1) + ctm = (-1, 0, 0, -1, x1, y1) elif page.rotate == 270: - ctm = (0,1,-1,0, y1,-x0) + ctm = (0, 1, -1, 0, y1, -x0) else: - ctm = (1,0,0,1, -x0,-y0) + ctm = (1, 0, 0, 1, -x0, -y0) self.device.begin_page(page, ctm) self.render_contents(page.resources, page.contents, ctm=ctm) self.device.end_page(page) @@ -764,7 +839,7 @@ def render_contents(self, resources, streams, ctm=MATRIX_IDENTITY): if 1 <= self.debug: print >>sys.stderr, ('render_contents: resources=%r, streams=%r, ctm=%r' % - (resources, streams, ctm)) + (resources, streams, ctm)) self.init_resources(resources) self.init_state(ctm) self.execute(list_value(streams)) @@ -778,12 +853,12 @@ return while 1: try: - (_,obj) = parser.nextobject() + (_, obj) = parser.nextobject() except PSEOF: break if isinstance(obj, PSKeyword): name = keyword_name(obj) - method = 'do_%s' % name.replace('*','_a').replace('"','_w').replace("'",'_q') + method = 'do_%s' % name.replace('*', '_a').replace('"', '_w').replace("'", '_q') if hasattr(self, method): func = getattr(self, method) nargs = func.func_code.co_argcount-1 @@ -803,32 +878,3 @@ else: self.push(obj) return - - -## process_pdf -## -class PDFTextExtractionNotAllowed(PDFInterpreterError): pass - -def process_pdf(rsrcmgr, device, fp, pagenos=None, maxpages=0, password='', - caching=True, check_extractable=True): - # Create a PDF parser object associated with the file object. - parser = PDFParser(fp) - # Create a PDF document object that stores the document structure. - doc = PDFDocument(caching=caching) - # Connect the parser and document objects. - parser.set_document(doc) - doc.set_parser(parser) - # Supply the document password for initialization. - # (If no password is set, give an empty string.) - doc.initialize(password) - # Check if the document allows text extraction. If not, abort. - if check_extractable and not doc.is_extractable: - raise PDFTextExtractionNotAllowed('Text extraction is not allowed: %r' % fp) - # Create a PDF interpreter object. - interpreter = PDFPageInterpreter(rsrcmgr, device) - # Process each page contained in the document. - for (pageno,page) in enumerate(doc.get_pages()): - if pagenos and (pageno not in pagenos): continue - interpreter.process_page(page) - if maxpages and maxpages <= pageno+1: break - return diff -Nru pdfminer-20110515+dfsg/pdfminer/pdfpage.py pdfminer-20140328+dfsg/pdfminer/pdfpage.py --- pdfminer-20110515+dfsg/pdfminer/pdfpage.py 1970-01-01 00:00:00.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdfpage.py 2015-10-11 18:33:29.000000000 +0000 @@ -0,0 +1,132 @@ +#!/usr/bin/env python +import sys +from psparser import LIT +from pdftypes import PDFObjectNotFound +from pdftypes import resolve1 +from pdftypes import int_value, list_value, dict_value +from pdfparser import PDFParser +from pdfdocument import PDFDocument +from pdfdocument import PDFEncryptionError +from pdfdocument import PDFTextExtractionNotAllowed + +# some predefined literals and keywords. +LITERAL_PAGE = LIT('Page') +LITERAL_PAGES = LIT('Pages') + + +## PDFPage +## +class PDFPage(object): + + """An object that holds the information about a page. + + A PDFPage object is merely a convenience class that has a set + of keys and values, which describe the properties of a page + and point to its contents. + + Attributes: + doc: a PDFDocument object. + pageid: any Python object that can uniquely identify the page. + attrs: a dictionary of page attributes. + contents: a list of PDFStream objects that represents the page content. + lastmod: the last modified time of the page. + resources: a list of resources used by the page. + mediabox: the physical size of the page. + cropbox: the crop rectangle of the page. + rotate: the page rotation (in degree). + annots: the page annotations. + beads: a chain that represents natural reading order. + """ + + def __init__(self, doc, pageid, attrs): + """Initialize a page object. + + doc: a PDFDocument object. + pageid: any Python object that can uniquely identify the page. + attrs: a dictionary of page attributes. + """ + self.doc = doc + self.pageid = pageid + self.attrs = dict_value(attrs) + self.lastmod = resolve1(self.attrs.get('LastModified')) + self.resources = resolve1(self.attrs['Resources']) + self.mediabox = resolve1(self.attrs['MediaBox']) + if 'CropBox' in self.attrs: + self.cropbox = resolve1(self.attrs['CropBox']) + else: + self.cropbox = self.mediabox + self.rotate = (int_value(self.attrs.get('Rotate', 0))+360) % 360 + self.annots = self.attrs.get('Annots') + self.beads = self.attrs.get('B') + if 'Contents' in self.attrs: + contents = resolve1(self.attrs['Contents']) + else: + contents = [] + if not isinstance(contents, list): + contents = [contents] + self.contents = contents + return + + def __repr__(self): + return '' % (self.resources, self.mediabox) + + INHERITABLE_ATTRS = set(['Resources', 'MediaBox', 'CropBox', 'Rotate']) + + @classmethod + def create_pages(klass, document, debug=0): + def search(obj, parent): + if isinstance(obj, int): + objid = obj + tree = dict_value(document.getobj(objid)).copy() + else: + objid = obj.objid + tree = dict_value(obj).copy() + for (k, v) in parent.iteritems(): + if k in klass.INHERITABLE_ATTRS and k not in tree: + tree[k] = v + if tree.get('Type') is LITERAL_PAGES and 'Kids' in tree: + if 1 <= debug: + print >>sys.stderr, 'Pages: Kids=%r' % tree['Kids'] + for c in list_value(tree['Kids']): + for x in search(c, tree): + yield x + elif tree.get('Type') is LITERAL_PAGE: + if 1 <= debug: + print >>sys.stderr, 'Page: %r' % tree + yield (objid, tree) + pages = False + if 'Pages' in document.catalog: + for (objid, tree) in search(document.catalog['Pages'], document.catalog): + yield klass(document, objid, tree) + pages = True + if not pages: + # fallback when /Pages is missing. + for xref in document.xrefs: + for objid in xref.get_objids(): + try: + obj = document.getobj(objid) + if isinstance(obj, dict) and obj.get('Type') is LITERAL_PAGE: + yield klass(document, objid, obj) + except PDFObjectNotFound: + pass + return + + @classmethod + def get_pages(klass, fp, + pagenos=None, maxpages=0, password='', + caching=True, check_extractable=True): + # Create a PDF parser object associated with the file object. + parser = PDFParser(fp) + # Create a PDF document object that stores the document structure. + doc = PDFDocument(parser, password=password, caching=caching) + # Check if the document allows text extraction. If not, abort. + if check_extractable and not doc.is_extractable: + raise PDFTextExtractionNotAllowed('Text extraction is not allowed: %r' % fp) + # Process each page contained in the document. + for (pageno, page) in enumerate(klass.create_pages(doc)): + if pagenos and (pageno not in pagenos): + continue + yield page + if maxpages and maxpages <= pageno+1: + break + return diff -Nru pdfminer-20110515+dfsg/pdfminer/pdfparser.py pdfminer-20140328+dfsg/pdfminer/pdfparser.py --- pdfminer-20110515+dfsg/pdfminer/pdfparser.py 2011-04-21 13:05:31.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdfparser.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,579 +1,22 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys -import re -import struct -try: - import hashlib as md5 -except ImportError: - import md5 try: from cStringIO import StringIO except ImportError: from StringIO import StringIO from psparser import PSStackParser from psparser import PSSyntaxError, PSEOF -from psparser import literal_name -from psparser import LIT, KWD, STRICT -from pdftypes import PDFException, PDFTypeError, PDFNotImplementedError +from psparser import KWD, STRICT +from pdftypes import PDFException from pdftypes import PDFStream, PDFObjRef -from pdftypes import resolve1, decipher_all -from pdftypes import int_value, float_value, num_value -from pdftypes import str_value, list_value, dict_value, stream_value -from arcfour import Arcfour -from utils import choplist, nunpack -from utils import decode_text, ObjIdRange +from pdftypes import int_value +from pdftypes import dict_value ## Exceptions ## -class PDFSyntaxError(PDFException): pass -class PDFNoValidXRef(PDFSyntaxError): pass -class PDFNoOutlines(PDFException): pass -class PDFDestinationNotFound(PDFException): pass -class PDFEncryptionError(PDFException): pass -class PDFPasswordIncorrect(PDFEncryptionError): pass - -# some predefined literals and keywords. -LITERAL_OBJSTM = LIT('ObjStm') -LITERAL_XREF = LIT('XRef') -LITERAL_PAGE = LIT('Page') -LITERAL_PAGES = LIT('Pages') -LITERAL_CATALOG = LIT('Catalog') - - -## XRefs -## -class PDFBaseXRef(object): - - def get_trailer(self): - raise NotImplementedError - - def get_objids(self): - return [] - - def get_pos(self, objid): - raise KeyError(objid) - - -## PDFXRef -## -class PDFXRef(PDFBaseXRef): - - def __init__(self): - self.offsets = {} - self.trailer = {} - return - - def load(self, parser, debug=0): - while 1: - try: - (pos, line) = parser.nextline() - if not line.strip(): continue - except PSEOF: - raise PDFNoValidXRef('Unexpected EOF - file corrupted?') - if not line: - raise PDFNoValidXRef('Premature eof: %r' % parser) - if line.startswith('trailer'): - parser.seek(pos) - break - f = line.strip().split(' ') - if len(f) != 2: - raise PDFNoValidXRef('Trailer not found: %r: line=%r' % (parser, line)) - try: - (start, nobjs) = map(long, f) - except ValueError: - raise PDFNoValidXRef('Invalid line: %r: line=%r' % (parser, line)) - for objid in xrange(start, start+nobjs): - try: - (_, line) = parser.nextline() - except PSEOF: - raise PDFNoValidXRef('Unexpected EOF - file corrupted?') - f = line.strip().split(' ') - if len(f) != 3: - raise PDFNoValidXRef('Invalid XRef format: %r, line=%r' % (parser, line)) - (pos, genno, use) = f - if use != 'n': continue - self.offsets[objid] = (int(genno), long(pos)) - if 1 <= debug: - print >>sys.stderr, 'xref objects:', self.offsets - self.load_trailer(parser) - return - - KEYWORD_TRAILER = KWD('trailer') - def load_trailer(self, parser): - try: - (_,kwd) = parser.nexttoken() - assert kwd is self.KEYWORD_TRAILER - (_,dic) = parser.nextobject() - except PSEOF: - x = parser.pop(1) - if not x: - raise PDFNoValidXRef('Unexpected EOF - file corrupted') - (_,dic) = x[0] - self.trailer.update(dict_value(dic)) - return - - PDFOBJ_CUE = re.compile(r'^(\d+)\s+(\d+)\s+obj\b') - def load_fallback(self, parser, debug=0): - parser.seek(0) - while 1: - try: - (pos, line) = parser.nextline() - except PSEOF: - break - if line.startswith('trailer'): - parser.seek(pos) - self.load_trailer(parser) - if 1 <= debug: - print >>sys.stderr, 'trailer: %r' % self.get_trailer() - break - m = self.PDFOBJ_CUE.match(line) - if not m: continue - (objid, genno) = m.groups() - self.offsets[int(objid)] = (0, pos) - return - - def get_trailer(self): - return self.trailer - - def get_objids(self): - return self.offsets.iterkeys() - - def get_pos(self, objid): - try: - (genno, pos) = self.offsets[objid] - except KeyError: - raise - return (None, pos) - - -## PDFXRefStream -## -class PDFXRefStream(PDFBaseXRef): - - def __init__(self): - self.data = None - self.entlen = None - self.fl1 = self.fl2 = self.fl3 = None - self.objid_ranges = [] - return - - def __repr__(self): - return '' % (self.fl1, self.fl2, self.fl3) - - def load(self, parser, debug=0): - (_,objid) = parser.nexttoken() # ignored - (_,genno) = parser.nexttoken() # ignored - (_,kwd) = parser.nexttoken() - (_,stream) = parser.nextobject() - if not isinstance(stream, PDFStream) or stream['Type'] is not LITERAL_XREF: - raise PDFNoValidXRef('Invalid PDF stream spec.') - size = stream['Size'] - index_array = stream.get('Index', (0,size)) - if len(index_array) % 2 != 0: - raise PDFSyntaxError('Invalid index number') - self.objid_ranges.extend( ObjIdRange(start, nobjs) - for (start,nobjs) in choplist(2, index_array) ) - (self.fl1, self.fl2, self.fl3) = stream['W'] - self.data = stream.get_data() - self.entlen = self.fl1+self.fl2+self.fl3 - self.trailer = stream.attrs - if 1 <= debug: - print >>sys.stderr, ('xref stream: objid=%s, fields=%d,%d,%d' % - (', '.join(map(repr, self.objid_ranges)), - self.fl1, self.fl2, self.fl3)) - return - - def get_trailer(self): - return self.trailer - - def get_objids(self): - for objid_range in self.objid_ranges: - for x in xrange(objid_range.get_start_id(), objid_range.get_end_id()+1): - yield x - return - - def get_pos(self, objid): - offset = 0 - found = False - for objid_range in self.objid_ranges: - if objid >= objid_range.get_start_id() and objid <= objid_range.get_end_id(): - offset += objid - objid_range.get_start_id() - found = True - break - else: - offset += objid_range.get_nobjs() - if not found: raise KeyError(objid) - i = self.entlen * offset - ent = self.data[i:i+self.entlen] - f1 = nunpack(ent[:self.fl1], 1) - if f1 == 1: - pos = nunpack(ent[self.fl1:self.fl1+self.fl2]) - genno = nunpack(ent[self.fl1+self.fl2:]) - return (None, pos) - elif f1 == 2: - objid = nunpack(ent[self.fl1:self.fl1+self.fl2]) - index = nunpack(ent[self.fl1+self.fl2:]) - return (objid, index) - # this is a free object - raise KeyError(objid) - - -## PDFPage -## -class PDFPage(object): - - """An object that holds the information about a page. - - A PDFPage object is merely a convenience class that has a set - of keys and values, which describe the properties of a page - and point to its contents. - - Attributes: - doc: a PDFDocument object. - pageid: any Python object that can uniquely identify the page. - attrs: a dictionary of page attributes. - contents: a list of PDFStream objects that represents the page content. - lastmod: the last modified time of the page. - resources: a list of resources used by the page. - mediabox: the physical size of the page. - cropbox: the crop rectangle of the page. - rotate: the page rotation (in degree). - annots: the page annotations. - beads: a chain that represents natural reading order. - """ - - def __init__(self, doc, pageid, attrs): - """Initialize a page object. - - doc: a PDFDocument object. - pageid: any Python object that can uniquely identify the page. - attrs: a dictionary of page attributes. - """ - self.doc = doc - self.pageid = pageid - self.attrs = dict_value(attrs) - self.lastmod = resolve1(self.attrs.get('LastModified')) - self.resources = resolve1(self.attrs['Resources']) - self.mediabox = resolve1(self.attrs['MediaBox']) - if 'CropBox' in self.attrs: - self.cropbox = resolve1(self.attrs['CropBox']) - else: - self.cropbox = self.mediabox - self.rotate = (self.attrs.get('Rotate', 0)+360) % 360 - self.annots = self.attrs.get('Annots') - self.beads = self.attrs.get('B') - if 'Contents' in self.attrs: - contents = resolve1(self.attrs['Contents']) - else: - contents = [] - if not isinstance(contents, list): - contents = [ contents ] - self.contents = contents - return - - def __repr__(self): - return '' % (self.resources, self.mediabox) - - -## PDFDocument -## -class PDFDocument(object): - - """PDFDocument object represents a PDF document. - - Since a PDF file can be very big, normally it is not loaded at - once. So PDF document has to cooperate with a PDF parser in order to - dynamically import the data as processing goes. - - Typical usage: - doc = PDFDocument() - doc.set_parser(parser) - doc.initialize(password) - obj = doc.getobj(objid) - - """ - - debug = 0 - - def __init__(self, caching=True): - self.caching = caching - self.xrefs = [] - self.info = [] - self.catalog = None - self.encryption = None - self.decipher = None - self._parser = None - self._cached_objs = {} - self._parsed_objs = {} - return - - def set_parser(self, parser): - "Set the document to use a given PDFParser object." - if self._parser: return - self._parser = parser - # Retrieve the information of each header that was appended - # (maybe multiple times) at the end of the document. - self.xrefs = parser.read_xref() - for xref in self.xrefs: - trailer = xref.get_trailer() - if not trailer: continue - # If there's an encryption info, remember it. - if 'Encrypt' in trailer: - #assert not self.encryption - self.encryption = (list_value(trailer['ID']), - dict_value(trailer['Encrypt'])) - if 'Info' in trailer: - self.info.append(dict_value(trailer['Info'])) - if 'Root' in trailer: - # Every PDF file must have exactly one /Root dictionary. - self.catalog = dict_value(trailer['Root']) - break - else: - raise PDFSyntaxError('No /Root object! - Is this really a PDF?') - if self.catalog.get('Type') is not LITERAL_CATALOG: - if STRICT: - raise PDFSyntaxError('Catalog not found!') - return - - # initialize(password='') - # Perform the initialization with a given password. - # This step is mandatory even if there's no password associated - # with the document. - PASSWORD_PADDING = '(\xbfN^Nu\x8aAd\x00NV\xff\xfa\x01\x08..\x00\xb6\xd0h>\x80/\x0c\xa9\xfedSiz' - def initialize(self, password=''): - if not self.encryption: - self.is_printable = self.is_modifiable = self.is_extractable = True - return - (docid, param) = self.encryption - if literal_name(param.get('Filter')) != 'Standard': - raise PDFEncryptionError('Unknown filter: param=%r' % param) - V = int_value(param.get('V', 0)) - if not (V == 1 or V == 2): - raise PDFEncryptionError('Unknown algorithm: param=%r' % param) - length = int_value(param.get('Length', 40)) # Key length (bits) - O = str_value(param['O']) - R = int_value(param['R']) # Revision - if 5 <= R: - raise PDFEncryptionError('Unknown revision: %r' % R) - U = str_value(param['U']) - P = int_value(param['P']) - self.is_printable = bool(P & 4) - self.is_modifiable = bool(P & 8) - self.is_extractable = bool(P & 16) - # Algorithm 3.2 - password = (password+self.PASSWORD_PADDING)[:32] # 1 - hash = md5.md5(password) # 2 - hash.update(O) # 3 - hash.update(struct.pack('>sys.stderr, 'getobj: objid=%r' % (objid) - if objid in self._cached_objs: - genno = 0 - obj = self._cached_objs[objid] - else: - for xref in self.xrefs: - try: - (strmid, index) = xref.get_pos(objid) - break - except KeyError: - pass - else: - if STRICT: - raise PDFSyntaxError('Cannot locate objid=%r' % objid) - # return null for a nonexistent reference. - return None - if strmid: - stream = stream_value(self.getobj(strmid)) - if stream.get('Type') is not LITERAL_OBJSTM: - if STRICT: - raise PDFSyntaxError('Not a stream object: %r' % stream) - try: - n = stream['N'] - except KeyError: - if STRICT: - raise PDFSyntaxError('N is not defined: %r' % stream) - n = 0 - if strmid in self._parsed_objs: - objs = self._parsed_objs[strmid] - else: - parser = PDFStreamParser(stream.get_data()) - parser.set_document(self) - objs = [] - try: - while 1: - (_,obj) = parser.nextobject() - objs.append(obj) - except PSEOF: - pass - if self.caching: - self._parsed_objs[strmid] = objs - genno = 0 - i = n*2+index - try: - obj = objs[i] - except IndexError: - raise PDFSyntaxError('Invalid object number: objid=%r' % (objid)) - if isinstance(obj, PDFStream): - obj.set_objid(objid, 0) - else: - self._parser.seek(index) - (_,objid1) = self._parser.nexttoken() # objid - (_,genno) = self._parser.nexttoken() # genno - (_,kwd) = self._parser.nexttoken() - # #### hack around malformed pdf files - #assert objid1 == objid, (objid, objid1) - if objid1 != objid: - x = [] - while kwd is not self.KEYWORD_OBJ: - (_,kwd) = self._parser.nexttoken() - x.append(kwd) - if x: - objid1 = x[-2] - genno = x[-1] - # #### end hack around malformed pdf files - if kwd is not self.KEYWORD_OBJ: - raise PDFSyntaxError('Invalid object spec: offset=%r' % index) - try: - (_,obj) = self._parser.nextobject() - if isinstance(obj, PDFStream): - obj.set_objid(objid, genno) - except PSEOF: - return None - if 2 <= self.debug: - print >>sys.stderr, 'register: objid=%r: %r' % (objid, obj) - if self.caching: - self._cached_objs[objid] = obj - if self.decipher: - obj = decipher_all(self.decipher, objid, genno, obj) - return obj - - INHERITABLE_ATTRS = set(['Resources', 'MediaBox', 'CropBox', 'Rotate']) - def get_pages(self): - if not self.xrefs: - raise PDFException('PDFDocument is not initialized') - def search(obj, parent): - if isinstance(obj, int): - objid = obj - tree = dict_value(self.getobj(objid)).copy() - else: - objid = obj.objid - tree = dict_value(obj).copy() - for (k,v) in parent.iteritems(): - if k in self.INHERITABLE_ATTRS and k not in tree: - tree[k] = v - if tree.get('Type') is LITERAL_PAGES and 'Kids' in tree: - if 1 <= self.debug: - print >>sys.stderr, 'Pages: Kids=%r' % tree['Kids'] - for c in list_value(tree['Kids']): - for x in search(c, tree): - yield x - elif tree.get('Type') is LITERAL_PAGE: - if 1 <= self.debug: - print >>sys.stderr, 'Page: %r' % tree - yield (objid, tree) - if 'Pages' not in self.catalog: return - for (pageid,tree) in search(self.catalog['Pages'], self.catalog): - yield PDFPage(self, pageid, tree) - return - - def get_outlines(self): - if 'Outlines' not in self.catalog: - raise PDFNoOutlines - def search(entry, level): - entry = dict_value(entry) - if 'Title' in entry: - if 'A' in entry or 'Dest' in entry: - title = decode_text(str_value(entry['Title'])) - dest = entry.get('Dest') - action = entry.get('A') - se = entry.get('SE') - yield (level, title, dest, action, se) - if 'First' in entry and 'Last' in entry: - for x in search(entry['First'], level+1): - yield x - if 'Next' in entry: - for x in search(entry['Next'], level): - yield x - return - return search(self.catalog['Outlines'], 0) - - def lookup_name(self, cat, key): - try: - names = dict_value(self.catalog['Names']) - except (PDFTypeError, KeyError): - raise KeyError((cat,key)) - # may raise KeyError - d0 = dict_value(names[cat]) - def lookup(d): - if 'Limits' in d: - (k1,k2) = list_value(d['Limits']) - if key < k1 or k2 < key: return None - if 'Names' in d: - objs = list_value(d['Names']) - names = dict(choplist(2, objs)) - return names[key] - if 'Kids' in d: - for c in list_value(d['Kids']): - v = lookup(dict_value(c)) - if v: return v - raise KeyError((cat,key)) - return lookup(d0) - - def get_dest(self, name): - try: - # PDF-1.2 or later - obj = self.lookup_name('Dests', name) - except KeyError: - # PDF-1.1 or prior - if 'Dests' not in self.catalog: - raise PDFDestinationNotFound(name) - d0 = dict_value(self.catalog['Dests']) - if name not in d0: - raise PDFDestinationNotFound(name) - obj = d0[name] - return obj +class PDFSyntaxError(PDFException): + pass ## PDFParser @@ -589,10 +32,11 @@ Typical usage: parser = PDFParser(fp) parser.read_xref() + parser.read_xref(fallback=True) # optional parser.set_document(doc) parser.seek(offset) parser.nextobject() - + """ def __init__(self, fp): @@ -612,12 +56,13 @@ KEYWORD_STREAM = KWD('stream') KEYWORD_XREF = KWD('xref') KEYWORD_STARTXREF = KWD('startxref') + def do_keyword(self, pos, token): """Handles PDF-related keywords.""" - + if token in (self.KEYWORD_XREF, self.KEYWORD_STARTXREF): self.add_results(*self.pop(1)) - + elif token is self.KEYWORD_ENDOBJ: self.add_results(*self.pop(4)) @@ -628,7 +73,7 @@ elif token is self.KEYWORD_R: # reference to indirect object try: - ((_,objid), (_,genno)) = self.pop(2) + ((_, objid), (_, genno)) = self.pop(2) (objid, genno) = (int(objid), int(genno)) obj = PDFObjRef(self.doc, objid, genno) self.push((pos, obj)) @@ -637,7 +82,7 @@ elif token is self.KEYWORD_STREAM: # stream object - ((_,dic),) = self.pop(1) + ((_, dic),) = self.pop(1) dic = dict_value(dic) objlen = 0 if not self.fallback: @@ -675,85 +120,16 @@ # XXX limit objlen not to exceed object boundary if 2 <= self.debug: print >>sys.stderr, 'Stream: pos=%d, objlen=%d, dic=%r, data=%r...' % \ - (pos, objlen, dic, data[:10]) + (pos, objlen, dic, data[:10]) obj = PDFStream(dic, data, self.doc.decipher) self.push((pos, obj)) else: # others self.push((pos, token)) - - return - def find_xref(self): - """Internal function used to locate the first XRef.""" - # search the last xref table by scanning the file backwards. - prev = None - for line in self.revreadlines(): - line = line.strip() - if 2 <= self.debug: - print >>sys.stderr, 'find_xref: %r' % line - if line == 'startxref': break - if line: - prev = line - else: - raise PDFNoValidXRef('Unexpected EOF') - if 1 <= self.debug: - print >>sys.stderr, 'xref found: pos=%r' % prev - return long(prev) - - # read xref table - def read_xref_from(self, start, xrefs): - """Reads XRefs from the given location.""" - self.seek(start) - self.reset() - try: - (pos, token) = self.nexttoken() - except PSEOF: - raise PDFNoValidXRef('Unexpected EOF') - if 2 <= self.debug: - print >>sys.stderr, 'read_xref_from: start=%d, token=%r' % (start, token) - if isinstance(token, int): - # XRefStream: PDF-1.5 - self.seek(pos) - self.reset() - xref = PDFXRefStream() - xref.load(self, debug=self.debug) - else: - if token is self.KEYWORD_XREF: - self.nextline() - xref = PDFXRef() - xref.load(self, debug=self.debug) - xrefs.append(xref) - trailer = xref.get_trailer() - if 1 <= self.debug: - print >>sys.stderr, 'trailer: %r' % trailer - if 'XRefStm' in trailer: - pos = int_value(trailer['XRefStm']) - self.read_xref_from(pos, xrefs) - if 'Prev' in trailer: - # find previous xref - pos = int_value(trailer['Prev']) - self.read_xref_from(pos, xrefs) return - # read xref tables and trailers - def read_xref(self): - """Reads all the XRefs in the PDF file and returns them.""" - xrefs = [] - try: - pos = self.find_xref() - self.read_xref_from(pos, xrefs) - except PDFNoValidXRef: - # fallback - if 1 <= self.debug: - print >>sys.stderr, 'no xref, fallback' - self.fallback = True - xref = PDFXRef() - xref.load_fallback(self) - xrefs.append(xref) - return xrefs - ## PDFStreamParser ## @@ -779,7 +155,7 @@ if token is self.KEYWORD_R: # reference to indirect object try: - ((_,objid), (_,genno)) = self.pop(2) + ((_, objid), (_, genno)) = self.pop(2) (objid, genno) = (int(objid), int(genno)) obj = PDFObjRef(self.doc, objid, genno) self.push((pos, obj)) diff -Nru pdfminer-20110515+dfsg/pdfminer/pdftypes.py pdfminer-20140328+dfsg/pdfminer/pdftypes.py --- pdfminer-20110515+dfsg/pdfminer/pdftypes.py 2011-04-21 13:05:56.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/pdftypes.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,11 +1,12 @@ -#!/usr/bin/env python2 -import sys +#!/usr/bin/env python import zlib from lzw import lzwdecode from ascii85 import ascii85decode, asciihexdecode from runlength import rldecode +from ccitt import ccittfaxdecode from psparser import PSException, PSObject -from psparser import LIT, KWD, STRICT +from psparser import LIT, STRICT +from utils import apply_png_predictor, isnumber LITERAL_CRYPT = LIT('Crypt') @@ -21,12 +22,23 @@ ## PDF Objects ## -class PDFObject(PSObject): pass +class PDFObject(PSObject): + pass -class PDFException(PSException): pass -class PDFTypeError(PDFException): pass -class PDFValueError(PDFException): pass -class PDFNotImplementedError(PSException): pass +class PDFException(PSException): + pass + +class PDFTypeError(PDFException): + pass + +class PDFValueError(PDFException): + pass + +class PDFObjectNotFound(PDFException): + pass + +class PDFNotImplementedError(PDFException): + pass ## PDFObjRef @@ -45,48 +57,54 @@ def __repr__(self): return '' % (self.objid) - def resolve(self): - return self.doc.getobj(self.objid) + def resolve(self, default=None): + try: + return self.doc.getobj(self.objid) + except PDFObjectNotFound: + return default # resolve -def resolve1(x): +def resolve1(x, default=None): """Resolves an object. If this is an array or dictionary, it may still contains some indirect objects inside. """ while isinstance(x, PDFObjRef): - x = x.resolve() + x = x.resolve(default=default) return x -def resolve_all(x): + +def resolve_all(x, default=None): """Recursively resolves the given object and all the internals. - + Make sure there is no indirect reference within the nested object. This procedure might be slow. """ while isinstance(x, PDFObjRef): - x = x.resolve() + x = x.resolve(default=default) if isinstance(x, list): - x = [ resolve_all(v) for v in x ] + x = [resolve_all(v, default=default) for v in x] elif isinstance(x, dict): - for (k,v) in x.iteritems(): - x[k] = resolve_all(v) + for (k, v) in x.iteritems(): + x[k] = resolve_all(v, default=default) return x + def decipher_all(decipher, objid, genno, x): """Recursively deciphers the given object. """ if isinstance(x, str): return decipher(objid, genno, x) if isinstance(x, list): - x = [ decipher_all(decipher, objid, genno, v) for v in x ] + x = [decipher_all(decipher, objid, genno, v) for v in x] elif isinstance(x, dict): - for (k,v) in x.iteritems(): + for (k, v) in x.iteritems(): x[k] = decipher_all(decipher, objid, genno, v) return x + # Type cheking def int_value(x): x = resolve1(x) @@ -96,6 +114,7 @@ return 0 return x + def float_value(x): x = resolve1(x) if not isinstance(x, float): @@ -104,14 +123,16 @@ return 0.0 return x + def num_value(x): x = resolve1(x) - if not (isinstance(x, int) or isinstance(x, float)): + if not isnumber(x): if STRICT: raise PDFTypeError('Int or Float required: %r' % x) return 0 return x + def str_value(x): x = resolve1(x) if not isinstance(x, str): @@ -120,14 +141,16 @@ return '' return x + def list_value(x): x = resolve1(x) - if not (isinstance(x, list) or isinstance(x, tuple)): + if not isinstance(x, (list, tuple)): if STRICT: raise PDFTypeError('List required: %r' % x) return [] return x + def dict_value(x): x = resolve1(x) if not isinstance(x, dict): @@ -136,6 +159,7 @@ return {} return x + def stream_value(x): x = resolve1(x) if not isinstance(x, PDFStream): @@ -174,13 +198,13 @@ def __contains__(self, name): return name in self.attrs - + def __getitem__(self, name): return self.attrs[name] - + def get(self, name, default=None): return self.attrs.get(name, default) - + def get_any(self, names, default=None): for name in names: if name in self.attrs: @@ -189,12 +213,14 @@ def get_filters(self): filters = self.get_any(('F', 'Filter')) - if not filters: return [] - if isinstance(filters, list): return filters - return [ filters ] + if not filters: + return [] + if isinstance(filters, list): + return filters + return [filters] def decode(self): - assert self.data is None and self.rawdata != None + assert self.data is None and self.rawdata is not None data = self.rawdata if self.decipher: # Handle encryption @@ -205,6 +231,7 @@ self.rawdata = None return for f in filters: + params = self.get_any(('DP', 'DecodeParms', 'FDecodeParms'), {}) if f in LITERALS_FLATE_DECODE: # will get errors if the document is encrypted. try: @@ -222,31 +249,26 @@ elif f in LITERALS_RUNLENGTH_DECODE: data = rldecode(data) elif f in LITERALS_CCITTFAX_DECODE: - #data = ccittfaxdecode(data) - raise PDFNotImplementedError('Unsupported filter: %r' % f) + data = ccittfaxdecode(data, params) elif f == LITERAL_CRYPT: # not yet.. raise PDFNotImplementedError('/Crypt filter is unsupported') else: raise PDFNotImplementedError('Unsupported filter: %r' % f) # apply predictors - params = self.get_any(('DP', 'DecodeParms', 'FDecodeParms'), {}) - if 'Predictor' in params and 'Columns' in params: + if 'Predictor' in params: pred = int_value(params['Predictor']) - columns = int_value(params['Columns']) - if pred: - if pred != 12: - raise PDFNotImplementedError('Unsupported predictor: %r' % pred) - buf = '' - ent0 = '\x00' * columns - for i in xrange(0, len(data), columns+1): - pred = data[i] - ent1 = data[i+1:i+1+columns] - if pred == '\x02': - ent1 = ''.join( chr((ord(a)+ord(b)) & 255) for (a,b) in zip(ent0,ent1) ) - buf += ent1 - ent0 = ent1 - data = buf + if pred == 1: + # no predictor + pass + elif 10 <= pred: + # PNG predictor + colors = int_value(params.get('Colors', 1)) + columns = int_value(params.get('Columns', 1)) + bitspercomponent = int_value(params.get('BitsPerComponent', 8)) + data = apply_png_predictor(pred, colors, columns, bitspercomponent, data) + else: + raise PDFNotImplementedError('Unsupported predictor: %r' % pred) self.data = data self.rawdata = None return diff -Nru pdfminer-20110515+dfsg/pdfminer/psparser.py pdfminer-20140328+dfsg/pdfminer/psparser.py --- pdfminer-20110515+dfsg/pdfminer/psparser.py 2011-04-21 13:05:12.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/psparser.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys import re from utils import choplist @@ -8,11 +8,24 @@ ## PS Exceptions ## -class PSException(Exception): pass -class PSEOF(PSException): pass -class PSSyntaxError(PSException): pass -class PSTypeError(PSException): pass -class PSValueError(PSException): pass +class PSException(Exception): + pass + + +class PSEOF(PSException): + pass + + +class PSSyntaxError(PSException): + pass + + +class PSTypeError(PSException): + pass + + +class PSValueError(PSException): + pass ## Basic PostScript Types @@ -32,7 +45,7 @@ class PSLiteral(PSObject): """A class that represents a PostScript literal. - + Postscript literals are used as identifiers, such as variable names, property names and dictionary keys. Literals are case sensitive and denoted by a preceding @@ -55,11 +68,11 @@ class PSKeyword(PSObject): """A class that represents a PostScript keyword. - + PostScript keywords are a dozen of predefined words. Commands and directives in PostScript are expressed by keywords. They are also used to denote the content boundaries. - + Note: Do not create an instance of PSKeyword directly. Always use PSKeywordTable.intern(). """ @@ -80,7 +93,7 @@ Interned objects can be checked its identity with "is" operator. """ - + def __init__(self, klass): self.dict = {} self.klass = klass @@ -114,6 +127,7 @@ return str(x) return x.name + def keyword_name(x): if not isinstance(x, PSKeyword): if STRICT: @@ -136,7 +150,9 @@ END_KEYWORD = re.compile(r'[#/%\[\]()<>{}\s]') END_STRING = re.compile(r'[()\134]') OCT_STRING = re.compile(r'[0-7]') -ESC_STRING = { 'b':8, 't':9, 'n':10, 'f':12, 'r':13, '(':40, ')':41, '\\':92 } +ESC_STRING = {'b': 8, 't': 9, 'n': 10, 'f': 12, 'r': 13, '(': 40, ')': 41, '\\': 92} + + class PSBaseParser(object): """Most basic PostScript parser that performs only tokenization. @@ -190,7 +206,8 @@ return def fillbuf(self): - if self.charpos < len(self.buf): return + if self.charpos < len(self.buf): + return # fetch next chunk. self.bufpos = self.fp.tell() self.buf = self.fp.read(self.BUFSIZ) @@ -242,7 +259,8 @@ pos = max(0, pos-self.BUFSIZ) self.fp.seek(pos) s = self.fp.read(prevpos-pos) - if not s: break + if not s: + break while 1: n = max(s.rfind('\r'), s.rfind('\n')) if n == -1: @@ -357,7 +375,7 @@ pass self._parse1 = self._parse_main return j - + def _parse_float(self, s, i): m = END_NUMBER.search(s, i) if not m: @@ -407,7 +425,7 @@ return j+1 if c == ')': self.paren -= 1 - if self.paren: # WTF, they said balanced parens need no special treatment. + if self.paren: # WTF, they said balanced parens need no special treatment. self._curtoken += c return j+1 self._add_token(self._curtoken) @@ -493,17 +511,17 @@ def push(self, *objs): self.curstack.extend(objs) return - + def pop(self, n): objs = self.curstack[-n:] self.curstack[-n:] = [] return objs - + def popall(self): objs = self.curstack self.curstack = [] return objs - + def add_results(self, *objs): if 2 <= self.debug: print >>sys.stderr, 'add_results: %r' % (objs,) @@ -516,11 +534,11 @@ if 2 <= self.debug: print >>sys.stderr, 'start_type: pos=%r, type=%r' % (pos, type) return - + def end_type(self, type): if self.curtype != type: raise PSTypeError('Type mismatch: %r != %r' % (self.curtype, type)) - objs = [ obj for (_,obj) in self.curstack ] + objs = [obj for (_, obj) in self.curstack] (pos, self.curtype, self.curstack) = self.context.pop() if 2 <= self.debug: print >>sys.stderr, 'end_type: pos=%r, type=%r, objs=%r' % (pos, type, objs) @@ -538,11 +556,7 @@ while not self.results: (pos, token) = self.nexttoken() #print (pos,token), (self.curtype, self.curstack) - if (isinstance(token, int) or - isinstance(token, float) or - isinstance(token, bool) or - isinstance(token, str) or - isinstance(token, PSLiteral)): + if isinstance(token, (int, long, float, bool, str, PSLiteral)): # normal token self.push((pos, token)) elif token == KEYWORD_ARRAY_BEGIN: @@ -553,7 +567,8 @@ try: self.push(self.end_type('a')) except PSTypeError: - if STRICT: raise + if STRICT: + raise elif token == KEYWORD_DICT_BEGIN: # begin dictionary self.start_type(pos, 'd') @@ -564,10 +579,11 @@ if len(objs) % 2 != 0: raise PSSyntaxError('Invalid dictionary construct: %r' % objs) # construct a Python dictionary. - d = dict( (literal_name(k), v) for (k,v) in choplist(2, objs) if v is not None ) + d = dict((literal_name(k), v) for (k, v) in choplist(2, objs) if v is not None) self.push((pos, d)) except PSTypeError: - if STRICT: raise + if STRICT: + raise elif token == KEYWORD_PROC_BEGIN: # begin proc self.start_type(pos, 'p') @@ -576,7 +592,8 @@ try: self.push(self.end_type('p')) except PSTypeError: - if STRICT: raise + if STRICT: + raise else: if 2 <= self.debug: print >>sys.stderr, 'do_keyword: pos=%r, token=%r, stack=%r' % \ @@ -592,9 +609,11 @@ return obj +import unittest + + ## Simplistic Test cases ## -import unittest class TestPSBaseParser(unittest.TestCase): TESTDATA = r'''%!PS @@ -630,7 +649,7 @@ (242, KWD('def')), (246, KWD('[')), (248, 1), (250, 'z'), (254, KWD('!')), (256, KWD(']')), (258, KWD('<<')), (261, LIT('foo')), (266, 'bar'), (272, KWD('>>')) - ] + ] OBJS = [ (23, LIT('a')), (25, LIT('BCD')), (30, LIT('Some_Name')), @@ -641,10 +660,11 @@ (191, ''), (194, ' '), (199, '@@ '), (211, '\xab\xcd\x00\x124\x05'), (230, LIT('a')), (232, LIT('b')), (234, ['c']), (246, [1, 'z']), (258, {'foo': 'bar'}), - ] + ] def get_tokens(self, s): import StringIO + class MyParser(PSBaseParser): def flush(self): self.add_results(*self.popall()) @@ -659,6 +679,7 @@ def get_objects(self, s): import StringIO + class MyParser(PSStackParser): def flush(self): self.add_results(*self.popall()) @@ -683,4 +704,5 @@ self.assertEqual(objs, self.OBJS) return -if __name__ == '__main__': unittest.main() +if __name__ == '__main__': + unittest.main() diff -Nru pdfminer-20110515+dfsg/pdfminer/rijndael.py pdfminer-20140328+dfsg/pdfminer/rijndael.py --- pdfminer-20110515+dfsg/pdfminer/rijndael.py 2011-03-02 14:37:56.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/rijndael.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Python implementation of Rijndael encryption algorithm. @@ -10,689 +10,696 @@ """ -import sys import struct -def KEYLENGTH(keybits): return (keybits)/8 -def RKLENGTH(keybits): return (keybits)/8+28 -def NROUNDS(keybits): return (keybits)/32+6 + +def KEYLENGTH(keybits): + return (keybits)//8 + + +def RKLENGTH(keybits): + return (keybits)//8+28 + + +def NROUNDS(keybits): + return (keybits)//32+6 Te0 = [ - 0xc66363a5L, 0xf87c7c84L, 0xee777799L, 0xf67b7b8dL, - 0xfff2f20dL, 0xd66b6bbdL, 0xde6f6fb1L, 0x91c5c554L, - 0x60303050L, 0x02010103L, 0xce6767a9L, 0x562b2b7dL, - 0xe7fefe19L, 0xb5d7d762L, 0x4dababe6L, 0xec76769aL, - 0x8fcaca45L, 0x1f82829dL, 0x89c9c940L, 0xfa7d7d87L, - 0xeffafa15L, 0xb25959ebL, 0x8e4747c9L, 0xfbf0f00bL, - 0x41adadecL, 0xb3d4d467L, 0x5fa2a2fdL, 0x45afafeaL, - 0x239c9cbfL, 0x53a4a4f7L, 0xe4727296L, 0x9bc0c05bL, - 0x75b7b7c2L, 0xe1fdfd1cL, 0x3d9393aeL, 0x4c26266aL, - 0x6c36365aL, 0x7e3f3f41L, 0xf5f7f702L, 0x83cccc4fL, - 0x6834345cL, 0x51a5a5f4L, 0xd1e5e534L, 0xf9f1f108L, - 0xe2717193L, 0xabd8d873L, 0x62313153L, 0x2a15153fL, - 0x0804040cL, 0x95c7c752L, 0x46232365L, 0x9dc3c35eL, - 0x30181828L, 0x379696a1L, 0x0a05050fL, 0x2f9a9ab5L, - 0x0e070709L, 0x24121236L, 0x1b80809bL, 0xdfe2e23dL, - 0xcdebeb26L, 0x4e272769L, 0x7fb2b2cdL, 0xea75759fL, - 0x1209091bL, 0x1d83839eL, 0x582c2c74L, 0x341a1a2eL, - 0x361b1b2dL, 0xdc6e6eb2L, 0xb45a5aeeL, 0x5ba0a0fbL, - 0xa45252f6L, 0x763b3b4dL, 0xb7d6d661L, 0x7db3b3ceL, - 0x5229297bL, 0xdde3e33eL, 0x5e2f2f71L, 0x13848497L, - 0xa65353f5L, 0xb9d1d168L, 0x00000000L, 0xc1eded2cL, - 0x40202060L, 0xe3fcfc1fL, 0x79b1b1c8L, 0xb65b5bedL, - 0xd46a6abeL, 0x8dcbcb46L, 0x67bebed9L, 0x7239394bL, - 0x944a4adeL, 0x984c4cd4L, 0xb05858e8L, 0x85cfcf4aL, - 0xbbd0d06bL, 0xc5efef2aL, 0x4faaaae5L, 0xedfbfb16L, - 0x864343c5L, 0x9a4d4dd7L, 0x66333355L, 0x11858594L, - 0x8a4545cfL, 0xe9f9f910L, 0x04020206L, 0xfe7f7f81L, - 0xa05050f0L, 0x783c3c44L, 0x259f9fbaL, 0x4ba8a8e3L, - 0xa25151f3L, 0x5da3a3feL, 0x804040c0L, 0x058f8f8aL, - 0x3f9292adL, 0x219d9dbcL, 0x70383848L, 0xf1f5f504L, - 0x63bcbcdfL, 0x77b6b6c1L, 0xafdada75L, 0x42212163L, - 0x20101030L, 0xe5ffff1aL, 0xfdf3f30eL, 0xbfd2d26dL, - 0x81cdcd4cL, 0x180c0c14L, 0x26131335L, 0xc3ecec2fL, - 0xbe5f5fe1L, 0x359797a2L, 0x884444ccL, 0x2e171739L, - 0x93c4c457L, 0x55a7a7f2L, 0xfc7e7e82L, 0x7a3d3d47L, - 0xc86464acL, 0xba5d5de7L, 0x3219192bL, 0xe6737395L, - 0xc06060a0L, 0x19818198L, 0x9e4f4fd1L, 0xa3dcdc7fL, - 0x44222266L, 0x542a2a7eL, 0x3b9090abL, 0x0b888883L, - 0x8c4646caL, 0xc7eeee29L, 0x6bb8b8d3L, 0x2814143cL, - 0xa7dede79L, 0xbc5e5ee2L, 0x160b0b1dL, 0xaddbdb76L, - 0xdbe0e03bL, 0x64323256L, 0x743a3a4eL, 0x140a0a1eL, - 0x924949dbL, 0x0c06060aL, 0x4824246cL, 0xb85c5ce4L, - 0x9fc2c25dL, 0xbdd3d36eL, 0x43acacefL, 0xc46262a6L, - 0x399191a8L, 0x319595a4L, 0xd3e4e437L, 0xf279798bL, - 0xd5e7e732L, 0x8bc8c843L, 0x6e373759L, 0xda6d6db7L, - 0x018d8d8cL, 0xb1d5d564L, 0x9c4e4ed2L, 0x49a9a9e0L, - 0xd86c6cb4L, 0xac5656faL, 0xf3f4f407L, 0xcfeaea25L, - 0xca6565afL, 0xf47a7a8eL, 0x47aeaee9L, 0x10080818L, - 0x6fbabad5L, 0xf0787888L, 0x4a25256fL, 0x5c2e2e72L, - 0x381c1c24L, 0x57a6a6f1L, 0x73b4b4c7L, 0x97c6c651L, - 0xcbe8e823L, 0xa1dddd7cL, 0xe874749cL, 0x3e1f1f21L, - 0x964b4bddL, 0x61bdbddcL, 0x0d8b8b86L, 0x0f8a8a85L, - 0xe0707090L, 0x7c3e3e42L, 0x71b5b5c4L, 0xcc6666aaL, - 0x904848d8L, 0x06030305L, 0xf7f6f601L, 0x1c0e0e12L, - 0xc26161a3L, 0x6a35355fL, 0xae5757f9L, 0x69b9b9d0L, - 0x17868691L, 0x99c1c158L, 0x3a1d1d27L, 0x279e9eb9L, - 0xd9e1e138L, 0xebf8f813L, 0x2b9898b3L, 0x22111133L, - 0xd26969bbL, 0xa9d9d970L, 0x078e8e89L, 0x339494a7L, - 0x2d9b9bb6L, 0x3c1e1e22L, 0x15878792L, 0xc9e9e920L, - 0x87cece49L, 0xaa5555ffL, 0x50282878L, 0xa5dfdf7aL, - 0x038c8c8fL, 0x59a1a1f8L, 0x09898980L, 0x1a0d0d17L, - 0x65bfbfdaL, 0xd7e6e631L, 0x844242c6L, 0xd06868b8L, - 0x824141c3L, 0x299999b0L, 0x5a2d2d77L, 0x1e0f0f11L, - 0x7bb0b0cbL, 0xa85454fcL, 0x6dbbbbd6L, 0x2c16163aL, - ] + 0xc66363a5L, 0xf87c7c84L, 0xee777799L, 0xf67b7b8dL, + 0xfff2f20dL, 0xd66b6bbdL, 0xde6f6fb1L, 0x91c5c554L, + 0x60303050L, 0x02010103L, 0xce6767a9L, 0x562b2b7dL, + 0xe7fefe19L, 0xb5d7d762L, 0x4dababe6L, 0xec76769aL, + 0x8fcaca45L, 0x1f82829dL, 0x89c9c940L, 0xfa7d7d87L, + 0xeffafa15L, 0xb25959ebL, 0x8e4747c9L, 0xfbf0f00bL, + 0x41adadecL, 0xb3d4d467L, 0x5fa2a2fdL, 0x45afafeaL, + 0x239c9cbfL, 0x53a4a4f7L, 0xe4727296L, 0x9bc0c05bL, + 0x75b7b7c2L, 0xe1fdfd1cL, 0x3d9393aeL, 0x4c26266aL, + 0x6c36365aL, 0x7e3f3f41L, 0xf5f7f702L, 0x83cccc4fL, + 0x6834345cL, 0x51a5a5f4L, 0xd1e5e534L, 0xf9f1f108L, + 0xe2717193L, 0xabd8d873L, 0x62313153L, 0x2a15153fL, + 0x0804040cL, 0x95c7c752L, 0x46232365L, 0x9dc3c35eL, + 0x30181828L, 0x379696a1L, 0x0a05050fL, 0x2f9a9ab5L, + 0x0e070709L, 0x24121236L, 0x1b80809bL, 0xdfe2e23dL, + 0xcdebeb26L, 0x4e272769L, 0x7fb2b2cdL, 0xea75759fL, + 0x1209091bL, 0x1d83839eL, 0x582c2c74L, 0x341a1a2eL, + 0x361b1b2dL, 0xdc6e6eb2L, 0xb45a5aeeL, 0x5ba0a0fbL, + 0xa45252f6L, 0x763b3b4dL, 0xb7d6d661L, 0x7db3b3ceL, + 0x5229297bL, 0xdde3e33eL, 0x5e2f2f71L, 0x13848497L, + 0xa65353f5L, 0xb9d1d168L, 0x00000000L, 0xc1eded2cL, + 0x40202060L, 0xe3fcfc1fL, 0x79b1b1c8L, 0xb65b5bedL, + 0xd46a6abeL, 0x8dcbcb46L, 0x67bebed9L, 0x7239394bL, + 0x944a4adeL, 0x984c4cd4L, 0xb05858e8L, 0x85cfcf4aL, + 0xbbd0d06bL, 0xc5efef2aL, 0x4faaaae5L, 0xedfbfb16L, + 0x864343c5L, 0x9a4d4dd7L, 0x66333355L, 0x11858594L, + 0x8a4545cfL, 0xe9f9f910L, 0x04020206L, 0xfe7f7f81L, + 0xa05050f0L, 0x783c3c44L, 0x259f9fbaL, 0x4ba8a8e3L, + 0xa25151f3L, 0x5da3a3feL, 0x804040c0L, 0x058f8f8aL, + 0x3f9292adL, 0x219d9dbcL, 0x70383848L, 0xf1f5f504L, + 0x63bcbcdfL, 0x77b6b6c1L, 0xafdada75L, 0x42212163L, + 0x20101030L, 0xe5ffff1aL, 0xfdf3f30eL, 0xbfd2d26dL, + 0x81cdcd4cL, 0x180c0c14L, 0x26131335L, 0xc3ecec2fL, + 0xbe5f5fe1L, 0x359797a2L, 0x884444ccL, 0x2e171739L, + 0x93c4c457L, 0x55a7a7f2L, 0xfc7e7e82L, 0x7a3d3d47L, + 0xc86464acL, 0xba5d5de7L, 0x3219192bL, 0xe6737395L, + 0xc06060a0L, 0x19818198L, 0x9e4f4fd1L, 0xa3dcdc7fL, + 0x44222266L, 0x542a2a7eL, 0x3b9090abL, 0x0b888883L, + 0x8c4646caL, 0xc7eeee29L, 0x6bb8b8d3L, 0x2814143cL, + 0xa7dede79L, 0xbc5e5ee2L, 0x160b0b1dL, 0xaddbdb76L, + 0xdbe0e03bL, 0x64323256L, 0x743a3a4eL, 0x140a0a1eL, + 0x924949dbL, 0x0c06060aL, 0x4824246cL, 0xb85c5ce4L, + 0x9fc2c25dL, 0xbdd3d36eL, 0x43acacefL, 0xc46262a6L, + 0x399191a8L, 0x319595a4L, 0xd3e4e437L, 0xf279798bL, + 0xd5e7e732L, 0x8bc8c843L, 0x6e373759L, 0xda6d6db7L, + 0x018d8d8cL, 0xb1d5d564L, 0x9c4e4ed2L, 0x49a9a9e0L, + 0xd86c6cb4L, 0xac5656faL, 0xf3f4f407L, 0xcfeaea25L, + 0xca6565afL, 0xf47a7a8eL, 0x47aeaee9L, 0x10080818L, + 0x6fbabad5L, 0xf0787888L, 0x4a25256fL, 0x5c2e2e72L, + 0x381c1c24L, 0x57a6a6f1L, 0x73b4b4c7L, 0x97c6c651L, + 0xcbe8e823L, 0xa1dddd7cL, 0xe874749cL, 0x3e1f1f21L, + 0x964b4bddL, 0x61bdbddcL, 0x0d8b8b86L, 0x0f8a8a85L, + 0xe0707090L, 0x7c3e3e42L, 0x71b5b5c4L, 0xcc6666aaL, + 0x904848d8L, 0x06030305L, 0xf7f6f601L, 0x1c0e0e12L, + 0xc26161a3L, 0x6a35355fL, 0xae5757f9L, 0x69b9b9d0L, + 0x17868691L, 0x99c1c158L, 0x3a1d1d27L, 0x279e9eb9L, + 0xd9e1e138L, 0xebf8f813L, 0x2b9898b3L, 0x22111133L, + 0xd26969bbL, 0xa9d9d970L, 0x078e8e89L, 0x339494a7L, + 0x2d9b9bb6L, 0x3c1e1e22L, 0x15878792L, 0xc9e9e920L, + 0x87cece49L, 0xaa5555ffL, 0x50282878L, 0xa5dfdf7aL, + 0x038c8c8fL, 0x59a1a1f8L, 0x09898980L, 0x1a0d0d17L, + 0x65bfbfdaL, 0xd7e6e631L, 0x844242c6L, 0xd06868b8L, + 0x824141c3L, 0x299999b0L, 0x5a2d2d77L, 0x1e0f0f11L, + 0x7bb0b0cbL, 0xa85454fcL, 0x6dbbbbd6L, 0x2c16163aL, +] Te1 = [ - 0xa5c66363L, 0x84f87c7cL, 0x99ee7777L, 0x8df67b7bL, - 0x0dfff2f2L, 0xbdd66b6bL, 0xb1de6f6fL, 0x5491c5c5L, - 0x50603030L, 0x03020101L, 0xa9ce6767L, 0x7d562b2bL, - 0x19e7fefeL, 0x62b5d7d7L, 0xe64dababL, 0x9aec7676L, - 0x458fcacaL, 0x9d1f8282L, 0x4089c9c9L, 0x87fa7d7dL, - 0x15effafaL, 0xebb25959L, 0xc98e4747L, 0x0bfbf0f0L, - 0xec41adadL, 0x67b3d4d4L, 0xfd5fa2a2L, 0xea45afafL, - 0xbf239c9cL, 0xf753a4a4L, 0x96e47272L, 0x5b9bc0c0L, - 0xc275b7b7L, 0x1ce1fdfdL, 0xae3d9393L, 0x6a4c2626L, - 0x5a6c3636L, 0x417e3f3fL, 0x02f5f7f7L, 0x4f83ccccL, - 0x5c683434L, 0xf451a5a5L, 0x34d1e5e5L, 0x08f9f1f1L, - 0x93e27171L, 0x73abd8d8L, 0x53623131L, 0x3f2a1515L, - 0x0c080404L, 0x5295c7c7L, 0x65462323L, 0x5e9dc3c3L, - 0x28301818L, 0xa1379696L, 0x0f0a0505L, 0xb52f9a9aL, - 0x090e0707L, 0x36241212L, 0x9b1b8080L, 0x3ddfe2e2L, - 0x26cdebebL, 0x694e2727L, 0xcd7fb2b2L, 0x9fea7575L, - 0x1b120909L, 0x9e1d8383L, 0x74582c2cL, 0x2e341a1aL, - 0x2d361b1bL, 0xb2dc6e6eL, 0xeeb45a5aL, 0xfb5ba0a0L, - 0xf6a45252L, 0x4d763b3bL, 0x61b7d6d6L, 0xce7db3b3L, - 0x7b522929L, 0x3edde3e3L, 0x715e2f2fL, 0x97138484L, - 0xf5a65353L, 0x68b9d1d1L, 0x00000000L, 0x2cc1ededL, - 0x60402020L, 0x1fe3fcfcL, 0xc879b1b1L, 0xedb65b5bL, - 0xbed46a6aL, 0x468dcbcbL, 0xd967bebeL, 0x4b723939L, - 0xde944a4aL, 0xd4984c4cL, 0xe8b05858L, 0x4a85cfcfL, - 0x6bbbd0d0L, 0x2ac5efefL, 0xe54faaaaL, 0x16edfbfbL, - 0xc5864343L, 0xd79a4d4dL, 0x55663333L, 0x94118585L, - 0xcf8a4545L, 0x10e9f9f9L, 0x06040202L, 0x81fe7f7fL, - 0xf0a05050L, 0x44783c3cL, 0xba259f9fL, 0xe34ba8a8L, - 0xf3a25151L, 0xfe5da3a3L, 0xc0804040L, 0x8a058f8fL, - 0xad3f9292L, 0xbc219d9dL, 0x48703838L, 0x04f1f5f5L, - 0xdf63bcbcL, 0xc177b6b6L, 0x75afdadaL, 0x63422121L, - 0x30201010L, 0x1ae5ffffL, 0x0efdf3f3L, 0x6dbfd2d2L, - 0x4c81cdcdL, 0x14180c0cL, 0x35261313L, 0x2fc3ececL, - 0xe1be5f5fL, 0xa2359797L, 0xcc884444L, 0x392e1717L, - 0x5793c4c4L, 0xf255a7a7L, 0x82fc7e7eL, 0x477a3d3dL, - 0xacc86464L, 0xe7ba5d5dL, 0x2b321919L, 0x95e67373L, - 0xa0c06060L, 0x98198181L, 0xd19e4f4fL, 0x7fa3dcdcL, - 0x66442222L, 0x7e542a2aL, 0xab3b9090L, 0x830b8888L, - 0xca8c4646L, 0x29c7eeeeL, 0xd36bb8b8L, 0x3c281414L, - 0x79a7dedeL, 0xe2bc5e5eL, 0x1d160b0bL, 0x76addbdbL, - 0x3bdbe0e0L, 0x56643232L, 0x4e743a3aL, 0x1e140a0aL, - 0xdb924949L, 0x0a0c0606L, 0x6c482424L, 0xe4b85c5cL, - 0x5d9fc2c2L, 0x6ebdd3d3L, 0xef43acacL, 0xa6c46262L, - 0xa8399191L, 0xa4319595L, 0x37d3e4e4L, 0x8bf27979L, - 0x32d5e7e7L, 0x438bc8c8L, 0x596e3737L, 0xb7da6d6dL, - 0x8c018d8dL, 0x64b1d5d5L, 0xd29c4e4eL, 0xe049a9a9L, - 0xb4d86c6cL, 0xfaac5656L, 0x07f3f4f4L, 0x25cfeaeaL, - 0xafca6565L, 0x8ef47a7aL, 0xe947aeaeL, 0x18100808L, - 0xd56fbabaL, 0x88f07878L, 0x6f4a2525L, 0x725c2e2eL, - 0x24381c1cL, 0xf157a6a6L, 0xc773b4b4L, 0x5197c6c6L, - 0x23cbe8e8L, 0x7ca1ddddL, 0x9ce87474L, 0x213e1f1fL, - 0xdd964b4bL, 0xdc61bdbdL, 0x860d8b8bL, 0x850f8a8aL, - 0x90e07070L, 0x427c3e3eL, 0xc471b5b5L, 0xaacc6666L, - 0xd8904848L, 0x05060303L, 0x01f7f6f6L, 0x121c0e0eL, - 0xa3c26161L, 0x5f6a3535L, 0xf9ae5757L, 0xd069b9b9L, - 0x91178686L, 0x5899c1c1L, 0x273a1d1dL, 0xb9279e9eL, - 0x38d9e1e1L, 0x13ebf8f8L, 0xb32b9898L, 0x33221111L, - 0xbbd26969L, 0x70a9d9d9L, 0x89078e8eL, 0xa7339494L, - 0xb62d9b9bL, 0x223c1e1eL, 0x92158787L, 0x20c9e9e9L, - 0x4987ceceL, 0xffaa5555L, 0x78502828L, 0x7aa5dfdfL, - 0x8f038c8cL, 0xf859a1a1L, 0x80098989L, 0x171a0d0dL, - 0xda65bfbfL, 0x31d7e6e6L, 0xc6844242L, 0xb8d06868L, - 0xc3824141L, 0xb0299999L, 0x775a2d2dL, 0x111e0f0fL, - 0xcb7bb0b0L, 0xfca85454L, 0xd66dbbbbL, 0x3a2c1616L, - ] + 0xa5c66363L, 0x84f87c7cL, 0x99ee7777L, 0x8df67b7bL, + 0x0dfff2f2L, 0xbdd66b6bL, 0xb1de6f6fL, 0x5491c5c5L, + 0x50603030L, 0x03020101L, 0xa9ce6767L, 0x7d562b2bL, + 0x19e7fefeL, 0x62b5d7d7L, 0xe64dababL, 0x9aec7676L, + 0x458fcacaL, 0x9d1f8282L, 0x4089c9c9L, 0x87fa7d7dL, + 0x15effafaL, 0xebb25959L, 0xc98e4747L, 0x0bfbf0f0L, + 0xec41adadL, 0x67b3d4d4L, 0xfd5fa2a2L, 0xea45afafL, + 0xbf239c9cL, 0xf753a4a4L, 0x96e47272L, 0x5b9bc0c0L, + 0xc275b7b7L, 0x1ce1fdfdL, 0xae3d9393L, 0x6a4c2626L, + 0x5a6c3636L, 0x417e3f3fL, 0x02f5f7f7L, 0x4f83ccccL, + 0x5c683434L, 0xf451a5a5L, 0x34d1e5e5L, 0x08f9f1f1L, + 0x93e27171L, 0x73abd8d8L, 0x53623131L, 0x3f2a1515L, + 0x0c080404L, 0x5295c7c7L, 0x65462323L, 0x5e9dc3c3L, + 0x28301818L, 0xa1379696L, 0x0f0a0505L, 0xb52f9a9aL, + 0x090e0707L, 0x36241212L, 0x9b1b8080L, 0x3ddfe2e2L, + 0x26cdebebL, 0x694e2727L, 0xcd7fb2b2L, 0x9fea7575L, + 0x1b120909L, 0x9e1d8383L, 0x74582c2cL, 0x2e341a1aL, + 0x2d361b1bL, 0xb2dc6e6eL, 0xeeb45a5aL, 0xfb5ba0a0L, + 0xf6a45252L, 0x4d763b3bL, 0x61b7d6d6L, 0xce7db3b3L, + 0x7b522929L, 0x3edde3e3L, 0x715e2f2fL, 0x97138484L, + 0xf5a65353L, 0x68b9d1d1L, 0x00000000L, 0x2cc1ededL, + 0x60402020L, 0x1fe3fcfcL, 0xc879b1b1L, 0xedb65b5bL, + 0xbed46a6aL, 0x468dcbcbL, 0xd967bebeL, 0x4b723939L, + 0xde944a4aL, 0xd4984c4cL, 0xe8b05858L, 0x4a85cfcfL, + 0x6bbbd0d0L, 0x2ac5efefL, 0xe54faaaaL, 0x16edfbfbL, + 0xc5864343L, 0xd79a4d4dL, 0x55663333L, 0x94118585L, + 0xcf8a4545L, 0x10e9f9f9L, 0x06040202L, 0x81fe7f7fL, + 0xf0a05050L, 0x44783c3cL, 0xba259f9fL, 0xe34ba8a8L, + 0xf3a25151L, 0xfe5da3a3L, 0xc0804040L, 0x8a058f8fL, + 0xad3f9292L, 0xbc219d9dL, 0x48703838L, 0x04f1f5f5L, + 0xdf63bcbcL, 0xc177b6b6L, 0x75afdadaL, 0x63422121L, + 0x30201010L, 0x1ae5ffffL, 0x0efdf3f3L, 0x6dbfd2d2L, + 0x4c81cdcdL, 0x14180c0cL, 0x35261313L, 0x2fc3ececL, + 0xe1be5f5fL, 0xa2359797L, 0xcc884444L, 0x392e1717L, + 0x5793c4c4L, 0xf255a7a7L, 0x82fc7e7eL, 0x477a3d3dL, + 0xacc86464L, 0xe7ba5d5dL, 0x2b321919L, 0x95e67373L, + 0xa0c06060L, 0x98198181L, 0xd19e4f4fL, 0x7fa3dcdcL, + 0x66442222L, 0x7e542a2aL, 0xab3b9090L, 0x830b8888L, + 0xca8c4646L, 0x29c7eeeeL, 0xd36bb8b8L, 0x3c281414L, + 0x79a7dedeL, 0xe2bc5e5eL, 0x1d160b0bL, 0x76addbdbL, + 0x3bdbe0e0L, 0x56643232L, 0x4e743a3aL, 0x1e140a0aL, + 0xdb924949L, 0x0a0c0606L, 0x6c482424L, 0xe4b85c5cL, + 0x5d9fc2c2L, 0x6ebdd3d3L, 0xef43acacL, 0xa6c46262L, + 0xa8399191L, 0xa4319595L, 0x37d3e4e4L, 0x8bf27979L, + 0x32d5e7e7L, 0x438bc8c8L, 0x596e3737L, 0xb7da6d6dL, + 0x8c018d8dL, 0x64b1d5d5L, 0xd29c4e4eL, 0xe049a9a9L, + 0xb4d86c6cL, 0xfaac5656L, 0x07f3f4f4L, 0x25cfeaeaL, + 0xafca6565L, 0x8ef47a7aL, 0xe947aeaeL, 0x18100808L, + 0xd56fbabaL, 0x88f07878L, 0x6f4a2525L, 0x725c2e2eL, + 0x24381c1cL, 0xf157a6a6L, 0xc773b4b4L, 0x5197c6c6L, + 0x23cbe8e8L, 0x7ca1ddddL, 0x9ce87474L, 0x213e1f1fL, + 0xdd964b4bL, 0xdc61bdbdL, 0x860d8b8bL, 0x850f8a8aL, + 0x90e07070L, 0x427c3e3eL, 0xc471b5b5L, 0xaacc6666L, + 0xd8904848L, 0x05060303L, 0x01f7f6f6L, 0x121c0e0eL, + 0xa3c26161L, 0x5f6a3535L, 0xf9ae5757L, 0xd069b9b9L, + 0x91178686L, 0x5899c1c1L, 0x273a1d1dL, 0xb9279e9eL, + 0x38d9e1e1L, 0x13ebf8f8L, 0xb32b9898L, 0x33221111L, + 0xbbd26969L, 0x70a9d9d9L, 0x89078e8eL, 0xa7339494L, + 0xb62d9b9bL, 0x223c1e1eL, 0x92158787L, 0x20c9e9e9L, + 0x4987ceceL, 0xffaa5555L, 0x78502828L, 0x7aa5dfdfL, + 0x8f038c8cL, 0xf859a1a1L, 0x80098989L, 0x171a0d0dL, + 0xda65bfbfL, 0x31d7e6e6L, 0xc6844242L, 0xb8d06868L, + 0xc3824141L, 0xb0299999L, 0x775a2d2dL, 0x111e0f0fL, + 0xcb7bb0b0L, 0xfca85454L, 0xd66dbbbbL, 0x3a2c1616L, +] Te2 = [ - 0x63a5c663L, 0x7c84f87cL, 0x7799ee77L, 0x7b8df67bL, - 0xf20dfff2L, 0x6bbdd66bL, 0x6fb1de6fL, 0xc55491c5L, - 0x30506030L, 0x01030201L, 0x67a9ce67L, 0x2b7d562bL, - 0xfe19e7feL, 0xd762b5d7L, 0xabe64dabL, 0x769aec76L, - 0xca458fcaL, 0x829d1f82L, 0xc94089c9L, 0x7d87fa7dL, - 0xfa15effaL, 0x59ebb259L, 0x47c98e47L, 0xf00bfbf0L, - 0xadec41adL, 0xd467b3d4L, 0xa2fd5fa2L, 0xafea45afL, - 0x9cbf239cL, 0xa4f753a4L, 0x7296e472L, 0xc05b9bc0L, - 0xb7c275b7L, 0xfd1ce1fdL, 0x93ae3d93L, 0x266a4c26L, - 0x365a6c36L, 0x3f417e3fL, 0xf702f5f7L, 0xcc4f83ccL, - 0x345c6834L, 0xa5f451a5L, 0xe534d1e5L, 0xf108f9f1L, - 0x7193e271L, 0xd873abd8L, 0x31536231L, 0x153f2a15L, - 0x040c0804L, 0xc75295c7L, 0x23654623L, 0xc35e9dc3L, - 0x18283018L, 0x96a13796L, 0x050f0a05L, 0x9ab52f9aL, - 0x07090e07L, 0x12362412L, 0x809b1b80L, 0xe23ddfe2L, - 0xeb26cdebL, 0x27694e27L, 0xb2cd7fb2L, 0x759fea75L, - 0x091b1209L, 0x839e1d83L, 0x2c74582cL, 0x1a2e341aL, - 0x1b2d361bL, 0x6eb2dc6eL, 0x5aeeb45aL, 0xa0fb5ba0L, - 0x52f6a452L, 0x3b4d763bL, 0xd661b7d6L, 0xb3ce7db3L, - 0x297b5229L, 0xe33edde3L, 0x2f715e2fL, 0x84971384L, - 0x53f5a653L, 0xd168b9d1L, 0x00000000L, 0xed2cc1edL, - 0x20604020L, 0xfc1fe3fcL, 0xb1c879b1L, 0x5bedb65bL, - 0x6abed46aL, 0xcb468dcbL, 0xbed967beL, 0x394b7239L, - 0x4ade944aL, 0x4cd4984cL, 0x58e8b058L, 0xcf4a85cfL, - 0xd06bbbd0L, 0xef2ac5efL, 0xaae54faaL, 0xfb16edfbL, - 0x43c58643L, 0x4dd79a4dL, 0x33556633L, 0x85941185L, - 0x45cf8a45L, 0xf910e9f9L, 0x02060402L, 0x7f81fe7fL, - 0x50f0a050L, 0x3c44783cL, 0x9fba259fL, 0xa8e34ba8L, - 0x51f3a251L, 0xa3fe5da3L, 0x40c08040L, 0x8f8a058fL, - 0x92ad3f92L, 0x9dbc219dL, 0x38487038L, 0xf504f1f5L, - 0xbcdf63bcL, 0xb6c177b6L, 0xda75afdaL, 0x21634221L, - 0x10302010L, 0xff1ae5ffL, 0xf30efdf3L, 0xd26dbfd2L, - 0xcd4c81cdL, 0x0c14180cL, 0x13352613L, 0xec2fc3ecL, - 0x5fe1be5fL, 0x97a23597L, 0x44cc8844L, 0x17392e17L, - 0xc45793c4L, 0xa7f255a7L, 0x7e82fc7eL, 0x3d477a3dL, - 0x64acc864L, 0x5de7ba5dL, 0x192b3219L, 0x7395e673L, - 0x60a0c060L, 0x81981981L, 0x4fd19e4fL, 0xdc7fa3dcL, - 0x22664422L, 0x2a7e542aL, 0x90ab3b90L, 0x88830b88L, - 0x46ca8c46L, 0xee29c7eeL, 0xb8d36bb8L, 0x143c2814L, - 0xde79a7deL, 0x5ee2bc5eL, 0x0b1d160bL, 0xdb76addbL, - 0xe03bdbe0L, 0x32566432L, 0x3a4e743aL, 0x0a1e140aL, - 0x49db9249L, 0x060a0c06L, 0x246c4824L, 0x5ce4b85cL, - 0xc25d9fc2L, 0xd36ebdd3L, 0xacef43acL, 0x62a6c462L, - 0x91a83991L, 0x95a43195L, 0xe437d3e4L, 0x798bf279L, - 0xe732d5e7L, 0xc8438bc8L, 0x37596e37L, 0x6db7da6dL, - 0x8d8c018dL, 0xd564b1d5L, 0x4ed29c4eL, 0xa9e049a9L, - 0x6cb4d86cL, 0x56faac56L, 0xf407f3f4L, 0xea25cfeaL, - 0x65afca65L, 0x7a8ef47aL, 0xaee947aeL, 0x08181008L, - 0xbad56fbaL, 0x7888f078L, 0x256f4a25L, 0x2e725c2eL, - 0x1c24381cL, 0xa6f157a6L, 0xb4c773b4L, 0xc65197c6L, - 0xe823cbe8L, 0xdd7ca1ddL, 0x749ce874L, 0x1f213e1fL, - 0x4bdd964bL, 0xbddc61bdL, 0x8b860d8bL, 0x8a850f8aL, - 0x7090e070L, 0x3e427c3eL, 0xb5c471b5L, 0x66aacc66L, - 0x48d89048L, 0x03050603L, 0xf601f7f6L, 0x0e121c0eL, - 0x61a3c261L, 0x355f6a35L, 0x57f9ae57L, 0xb9d069b9L, - 0x86911786L, 0xc15899c1L, 0x1d273a1dL, 0x9eb9279eL, - 0xe138d9e1L, 0xf813ebf8L, 0x98b32b98L, 0x11332211L, - 0x69bbd269L, 0xd970a9d9L, 0x8e89078eL, 0x94a73394L, - 0x9bb62d9bL, 0x1e223c1eL, 0x87921587L, 0xe920c9e9L, - 0xce4987ceL, 0x55ffaa55L, 0x28785028L, 0xdf7aa5dfL, - 0x8c8f038cL, 0xa1f859a1L, 0x89800989L, 0x0d171a0dL, - 0xbfda65bfL, 0xe631d7e6L, 0x42c68442L, 0x68b8d068L, - 0x41c38241L, 0x99b02999L, 0x2d775a2dL, 0x0f111e0fL, - 0xb0cb7bb0L, 0x54fca854L, 0xbbd66dbbL, 0x163a2c16L, - ] + 0x63a5c663L, 0x7c84f87cL, 0x7799ee77L, 0x7b8df67bL, + 0xf20dfff2L, 0x6bbdd66bL, 0x6fb1de6fL, 0xc55491c5L, + 0x30506030L, 0x01030201L, 0x67a9ce67L, 0x2b7d562bL, + 0xfe19e7feL, 0xd762b5d7L, 0xabe64dabL, 0x769aec76L, + 0xca458fcaL, 0x829d1f82L, 0xc94089c9L, 0x7d87fa7dL, + 0xfa15effaL, 0x59ebb259L, 0x47c98e47L, 0xf00bfbf0L, + 0xadec41adL, 0xd467b3d4L, 0xa2fd5fa2L, 0xafea45afL, + 0x9cbf239cL, 0xa4f753a4L, 0x7296e472L, 0xc05b9bc0L, + 0xb7c275b7L, 0xfd1ce1fdL, 0x93ae3d93L, 0x266a4c26L, + 0x365a6c36L, 0x3f417e3fL, 0xf702f5f7L, 0xcc4f83ccL, + 0x345c6834L, 0xa5f451a5L, 0xe534d1e5L, 0xf108f9f1L, + 0x7193e271L, 0xd873abd8L, 0x31536231L, 0x153f2a15L, + 0x040c0804L, 0xc75295c7L, 0x23654623L, 0xc35e9dc3L, + 0x18283018L, 0x96a13796L, 0x050f0a05L, 0x9ab52f9aL, + 0x07090e07L, 0x12362412L, 0x809b1b80L, 0xe23ddfe2L, + 0xeb26cdebL, 0x27694e27L, 0xb2cd7fb2L, 0x759fea75L, + 0x091b1209L, 0x839e1d83L, 0x2c74582cL, 0x1a2e341aL, + 0x1b2d361bL, 0x6eb2dc6eL, 0x5aeeb45aL, 0xa0fb5ba0L, + 0x52f6a452L, 0x3b4d763bL, 0xd661b7d6L, 0xb3ce7db3L, + 0x297b5229L, 0xe33edde3L, 0x2f715e2fL, 0x84971384L, + 0x53f5a653L, 0xd168b9d1L, 0x00000000L, 0xed2cc1edL, + 0x20604020L, 0xfc1fe3fcL, 0xb1c879b1L, 0x5bedb65bL, + 0x6abed46aL, 0xcb468dcbL, 0xbed967beL, 0x394b7239L, + 0x4ade944aL, 0x4cd4984cL, 0x58e8b058L, 0xcf4a85cfL, + 0xd06bbbd0L, 0xef2ac5efL, 0xaae54faaL, 0xfb16edfbL, + 0x43c58643L, 0x4dd79a4dL, 0x33556633L, 0x85941185L, + 0x45cf8a45L, 0xf910e9f9L, 0x02060402L, 0x7f81fe7fL, + 0x50f0a050L, 0x3c44783cL, 0x9fba259fL, 0xa8e34ba8L, + 0x51f3a251L, 0xa3fe5da3L, 0x40c08040L, 0x8f8a058fL, + 0x92ad3f92L, 0x9dbc219dL, 0x38487038L, 0xf504f1f5L, + 0xbcdf63bcL, 0xb6c177b6L, 0xda75afdaL, 0x21634221L, + 0x10302010L, 0xff1ae5ffL, 0xf30efdf3L, 0xd26dbfd2L, + 0xcd4c81cdL, 0x0c14180cL, 0x13352613L, 0xec2fc3ecL, + 0x5fe1be5fL, 0x97a23597L, 0x44cc8844L, 0x17392e17L, + 0xc45793c4L, 0xa7f255a7L, 0x7e82fc7eL, 0x3d477a3dL, + 0x64acc864L, 0x5de7ba5dL, 0x192b3219L, 0x7395e673L, + 0x60a0c060L, 0x81981981L, 0x4fd19e4fL, 0xdc7fa3dcL, + 0x22664422L, 0x2a7e542aL, 0x90ab3b90L, 0x88830b88L, + 0x46ca8c46L, 0xee29c7eeL, 0xb8d36bb8L, 0x143c2814L, + 0xde79a7deL, 0x5ee2bc5eL, 0x0b1d160bL, 0xdb76addbL, + 0xe03bdbe0L, 0x32566432L, 0x3a4e743aL, 0x0a1e140aL, + 0x49db9249L, 0x060a0c06L, 0x246c4824L, 0x5ce4b85cL, + 0xc25d9fc2L, 0xd36ebdd3L, 0xacef43acL, 0x62a6c462L, + 0x91a83991L, 0x95a43195L, 0xe437d3e4L, 0x798bf279L, + 0xe732d5e7L, 0xc8438bc8L, 0x37596e37L, 0x6db7da6dL, + 0x8d8c018dL, 0xd564b1d5L, 0x4ed29c4eL, 0xa9e049a9L, + 0x6cb4d86cL, 0x56faac56L, 0xf407f3f4L, 0xea25cfeaL, + 0x65afca65L, 0x7a8ef47aL, 0xaee947aeL, 0x08181008L, + 0xbad56fbaL, 0x7888f078L, 0x256f4a25L, 0x2e725c2eL, + 0x1c24381cL, 0xa6f157a6L, 0xb4c773b4L, 0xc65197c6L, + 0xe823cbe8L, 0xdd7ca1ddL, 0x749ce874L, 0x1f213e1fL, + 0x4bdd964bL, 0xbddc61bdL, 0x8b860d8bL, 0x8a850f8aL, + 0x7090e070L, 0x3e427c3eL, 0xb5c471b5L, 0x66aacc66L, + 0x48d89048L, 0x03050603L, 0xf601f7f6L, 0x0e121c0eL, + 0x61a3c261L, 0x355f6a35L, 0x57f9ae57L, 0xb9d069b9L, + 0x86911786L, 0xc15899c1L, 0x1d273a1dL, 0x9eb9279eL, + 0xe138d9e1L, 0xf813ebf8L, 0x98b32b98L, 0x11332211L, + 0x69bbd269L, 0xd970a9d9L, 0x8e89078eL, 0x94a73394L, + 0x9bb62d9bL, 0x1e223c1eL, 0x87921587L, 0xe920c9e9L, + 0xce4987ceL, 0x55ffaa55L, 0x28785028L, 0xdf7aa5dfL, + 0x8c8f038cL, 0xa1f859a1L, 0x89800989L, 0x0d171a0dL, + 0xbfda65bfL, 0xe631d7e6L, 0x42c68442L, 0x68b8d068L, + 0x41c38241L, 0x99b02999L, 0x2d775a2dL, 0x0f111e0fL, + 0xb0cb7bb0L, 0x54fca854L, 0xbbd66dbbL, 0x163a2c16L, +] Te3 = [ - 0x6363a5c6L, 0x7c7c84f8L, 0x777799eeL, 0x7b7b8df6L, - 0xf2f20dffL, 0x6b6bbdd6L, 0x6f6fb1deL, 0xc5c55491L, - 0x30305060L, 0x01010302L, 0x6767a9ceL, 0x2b2b7d56L, - 0xfefe19e7L, 0xd7d762b5L, 0xababe64dL, 0x76769aecL, - 0xcaca458fL, 0x82829d1fL, 0xc9c94089L, 0x7d7d87faL, - 0xfafa15efL, 0x5959ebb2L, 0x4747c98eL, 0xf0f00bfbL, - 0xadadec41L, 0xd4d467b3L, 0xa2a2fd5fL, 0xafafea45L, - 0x9c9cbf23L, 0xa4a4f753L, 0x727296e4L, 0xc0c05b9bL, - 0xb7b7c275L, 0xfdfd1ce1L, 0x9393ae3dL, 0x26266a4cL, - 0x36365a6cL, 0x3f3f417eL, 0xf7f702f5L, 0xcccc4f83L, - 0x34345c68L, 0xa5a5f451L, 0xe5e534d1L, 0xf1f108f9L, - 0x717193e2L, 0xd8d873abL, 0x31315362L, 0x15153f2aL, - 0x04040c08L, 0xc7c75295L, 0x23236546L, 0xc3c35e9dL, - 0x18182830L, 0x9696a137L, 0x05050f0aL, 0x9a9ab52fL, - 0x0707090eL, 0x12123624L, 0x80809b1bL, 0xe2e23ddfL, - 0xebeb26cdL, 0x2727694eL, 0xb2b2cd7fL, 0x75759feaL, - 0x09091b12L, 0x83839e1dL, 0x2c2c7458L, 0x1a1a2e34L, - 0x1b1b2d36L, 0x6e6eb2dcL, 0x5a5aeeb4L, 0xa0a0fb5bL, - 0x5252f6a4L, 0x3b3b4d76L, 0xd6d661b7L, 0xb3b3ce7dL, - 0x29297b52L, 0xe3e33eddL, 0x2f2f715eL, 0x84849713L, - 0x5353f5a6L, 0xd1d168b9L, 0x00000000L, 0xeded2cc1L, - 0x20206040L, 0xfcfc1fe3L, 0xb1b1c879L, 0x5b5bedb6L, - 0x6a6abed4L, 0xcbcb468dL, 0xbebed967L, 0x39394b72L, - 0x4a4ade94L, 0x4c4cd498L, 0x5858e8b0L, 0xcfcf4a85L, - 0xd0d06bbbL, 0xefef2ac5L, 0xaaaae54fL, 0xfbfb16edL, - 0x4343c586L, 0x4d4dd79aL, 0x33335566L, 0x85859411L, - 0x4545cf8aL, 0xf9f910e9L, 0x02020604L, 0x7f7f81feL, - 0x5050f0a0L, 0x3c3c4478L, 0x9f9fba25L, 0xa8a8e34bL, - 0x5151f3a2L, 0xa3a3fe5dL, 0x4040c080L, 0x8f8f8a05L, - 0x9292ad3fL, 0x9d9dbc21L, 0x38384870L, 0xf5f504f1L, - 0xbcbcdf63L, 0xb6b6c177L, 0xdada75afL, 0x21216342L, - 0x10103020L, 0xffff1ae5L, 0xf3f30efdL, 0xd2d26dbfL, - 0xcdcd4c81L, 0x0c0c1418L, 0x13133526L, 0xecec2fc3L, - 0x5f5fe1beL, 0x9797a235L, 0x4444cc88L, 0x1717392eL, - 0xc4c45793L, 0xa7a7f255L, 0x7e7e82fcL, 0x3d3d477aL, - 0x6464acc8L, 0x5d5de7baL, 0x19192b32L, 0x737395e6L, - 0x6060a0c0L, 0x81819819L, 0x4f4fd19eL, 0xdcdc7fa3L, - 0x22226644L, 0x2a2a7e54L, 0x9090ab3bL, 0x8888830bL, - 0x4646ca8cL, 0xeeee29c7L, 0xb8b8d36bL, 0x14143c28L, - 0xdede79a7L, 0x5e5ee2bcL, 0x0b0b1d16L, 0xdbdb76adL, - 0xe0e03bdbL, 0x32325664L, 0x3a3a4e74L, 0x0a0a1e14L, - 0x4949db92L, 0x06060a0cL, 0x24246c48L, 0x5c5ce4b8L, - 0xc2c25d9fL, 0xd3d36ebdL, 0xacacef43L, 0x6262a6c4L, - 0x9191a839L, 0x9595a431L, 0xe4e437d3L, 0x79798bf2L, - 0xe7e732d5L, 0xc8c8438bL, 0x3737596eL, 0x6d6db7daL, - 0x8d8d8c01L, 0xd5d564b1L, 0x4e4ed29cL, 0xa9a9e049L, - 0x6c6cb4d8L, 0x5656faacL, 0xf4f407f3L, 0xeaea25cfL, - 0x6565afcaL, 0x7a7a8ef4L, 0xaeaee947L, 0x08081810L, - 0xbabad56fL, 0x787888f0L, 0x25256f4aL, 0x2e2e725cL, - 0x1c1c2438L, 0xa6a6f157L, 0xb4b4c773L, 0xc6c65197L, - 0xe8e823cbL, 0xdddd7ca1L, 0x74749ce8L, 0x1f1f213eL, - 0x4b4bdd96L, 0xbdbddc61L, 0x8b8b860dL, 0x8a8a850fL, - 0x707090e0L, 0x3e3e427cL, 0xb5b5c471L, 0x6666aaccL, - 0x4848d890L, 0x03030506L, 0xf6f601f7L, 0x0e0e121cL, - 0x6161a3c2L, 0x35355f6aL, 0x5757f9aeL, 0xb9b9d069L, - 0x86869117L, 0xc1c15899L, 0x1d1d273aL, 0x9e9eb927L, - 0xe1e138d9L, 0xf8f813ebL, 0x9898b32bL, 0x11113322L, - 0x6969bbd2L, 0xd9d970a9L, 0x8e8e8907L, 0x9494a733L, - 0x9b9bb62dL, 0x1e1e223cL, 0x87879215L, 0xe9e920c9L, - 0xcece4987L, 0x5555ffaaL, 0x28287850L, 0xdfdf7aa5L, - 0x8c8c8f03L, 0xa1a1f859L, 0x89898009L, 0x0d0d171aL, - 0xbfbfda65L, 0xe6e631d7L, 0x4242c684L, 0x6868b8d0L, - 0x4141c382L, 0x9999b029L, 0x2d2d775aL, 0x0f0f111eL, - 0xb0b0cb7bL, 0x5454fca8L, 0xbbbbd66dL, 0x16163a2cL, - ] + 0x6363a5c6L, 0x7c7c84f8L, 0x777799eeL, 0x7b7b8df6L, + 0xf2f20dffL, 0x6b6bbdd6L, 0x6f6fb1deL, 0xc5c55491L, + 0x30305060L, 0x01010302L, 0x6767a9ceL, 0x2b2b7d56L, + 0xfefe19e7L, 0xd7d762b5L, 0xababe64dL, 0x76769aecL, + 0xcaca458fL, 0x82829d1fL, 0xc9c94089L, 0x7d7d87faL, + 0xfafa15efL, 0x5959ebb2L, 0x4747c98eL, 0xf0f00bfbL, + 0xadadec41L, 0xd4d467b3L, 0xa2a2fd5fL, 0xafafea45L, + 0x9c9cbf23L, 0xa4a4f753L, 0x727296e4L, 0xc0c05b9bL, + 0xb7b7c275L, 0xfdfd1ce1L, 0x9393ae3dL, 0x26266a4cL, + 0x36365a6cL, 0x3f3f417eL, 0xf7f702f5L, 0xcccc4f83L, + 0x34345c68L, 0xa5a5f451L, 0xe5e534d1L, 0xf1f108f9L, + 0x717193e2L, 0xd8d873abL, 0x31315362L, 0x15153f2aL, + 0x04040c08L, 0xc7c75295L, 0x23236546L, 0xc3c35e9dL, + 0x18182830L, 0x9696a137L, 0x05050f0aL, 0x9a9ab52fL, + 0x0707090eL, 0x12123624L, 0x80809b1bL, 0xe2e23ddfL, + 0xebeb26cdL, 0x2727694eL, 0xb2b2cd7fL, 0x75759feaL, + 0x09091b12L, 0x83839e1dL, 0x2c2c7458L, 0x1a1a2e34L, + 0x1b1b2d36L, 0x6e6eb2dcL, 0x5a5aeeb4L, 0xa0a0fb5bL, + 0x5252f6a4L, 0x3b3b4d76L, 0xd6d661b7L, 0xb3b3ce7dL, + 0x29297b52L, 0xe3e33eddL, 0x2f2f715eL, 0x84849713L, + 0x5353f5a6L, 0xd1d168b9L, 0x00000000L, 0xeded2cc1L, + 0x20206040L, 0xfcfc1fe3L, 0xb1b1c879L, 0x5b5bedb6L, + 0x6a6abed4L, 0xcbcb468dL, 0xbebed967L, 0x39394b72L, + 0x4a4ade94L, 0x4c4cd498L, 0x5858e8b0L, 0xcfcf4a85L, + 0xd0d06bbbL, 0xefef2ac5L, 0xaaaae54fL, 0xfbfb16edL, + 0x4343c586L, 0x4d4dd79aL, 0x33335566L, 0x85859411L, + 0x4545cf8aL, 0xf9f910e9L, 0x02020604L, 0x7f7f81feL, + 0x5050f0a0L, 0x3c3c4478L, 0x9f9fba25L, 0xa8a8e34bL, + 0x5151f3a2L, 0xa3a3fe5dL, 0x4040c080L, 0x8f8f8a05L, + 0x9292ad3fL, 0x9d9dbc21L, 0x38384870L, 0xf5f504f1L, + 0xbcbcdf63L, 0xb6b6c177L, 0xdada75afL, 0x21216342L, + 0x10103020L, 0xffff1ae5L, 0xf3f30efdL, 0xd2d26dbfL, + 0xcdcd4c81L, 0x0c0c1418L, 0x13133526L, 0xecec2fc3L, + 0x5f5fe1beL, 0x9797a235L, 0x4444cc88L, 0x1717392eL, + 0xc4c45793L, 0xa7a7f255L, 0x7e7e82fcL, 0x3d3d477aL, + 0x6464acc8L, 0x5d5de7baL, 0x19192b32L, 0x737395e6L, + 0x6060a0c0L, 0x81819819L, 0x4f4fd19eL, 0xdcdc7fa3L, + 0x22226644L, 0x2a2a7e54L, 0x9090ab3bL, 0x8888830bL, + 0x4646ca8cL, 0xeeee29c7L, 0xb8b8d36bL, 0x14143c28L, + 0xdede79a7L, 0x5e5ee2bcL, 0x0b0b1d16L, 0xdbdb76adL, + 0xe0e03bdbL, 0x32325664L, 0x3a3a4e74L, 0x0a0a1e14L, + 0x4949db92L, 0x06060a0cL, 0x24246c48L, 0x5c5ce4b8L, + 0xc2c25d9fL, 0xd3d36ebdL, 0xacacef43L, 0x6262a6c4L, + 0x9191a839L, 0x9595a431L, 0xe4e437d3L, 0x79798bf2L, + 0xe7e732d5L, 0xc8c8438bL, 0x3737596eL, 0x6d6db7daL, + 0x8d8d8c01L, 0xd5d564b1L, 0x4e4ed29cL, 0xa9a9e049L, + 0x6c6cb4d8L, 0x5656faacL, 0xf4f407f3L, 0xeaea25cfL, + 0x6565afcaL, 0x7a7a8ef4L, 0xaeaee947L, 0x08081810L, + 0xbabad56fL, 0x787888f0L, 0x25256f4aL, 0x2e2e725cL, + 0x1c1c2438L, 0xa6a6f157L, 0xb4b4c773L, 0xc6c65197L, + 0xe8e823cbL, 0xdddd7ca1L, 0x74749ce8L, 0x1f1f213eL, + 0x4b4bdd96L, 0xbdbddc61L, 0x8b8b860dL, 0x8a8a850fL, + 0x707090e0L, 0x3e3e427cL, 0xb5b5c471L, 0x6666aaccL, + 0x4848d890L, 0x03030506L, 0xf6f601f7L, 0x0e0e121cL, + 0x6161a3c2L, 0x35355f6aL, 0x5757f9aeL, 0xb9b9d069L, + 0x86869117L, 0xc1c15899L, 0x1d1d273aL, 0x9e9eb927L, + 0xe1e138d9L, 0xf8f813ebL, 0x9898b32bL, 0x11113322L, + 0x6969bbd2L, 0xd9d970a9L, 0x8e8e8907L, 0x9494a733L, + 0x9b9bb62dL, 0x1e1e223cL, 0x87879215L, 0xe9e920c9L, + 0xcece4987L, 0x5555ffaaL, 0x28287850L, 0xdfdf7aa5L, + 0x8c8c8f03L, 0xa1a1f859L, 0x89898009L, 0x0d0d171aL, + 0xbfbfda65L, 0xe6e631d7L, 0x4242c684L, 0x6868b8d0L, + 0x4141c382L, 0x9999b029L, 0x2d2d775aL, 0x0f0f111eL, + 0xb0b0cb7bL, 0x5454fca8L, 0xbbbbd66dL, 0x16163a2cL, +] Te4 = [ - 0x63636363L, 0x7c7c7c7cL, 0x77777777L, 0x7b7b7b7bL, - 0xf2f2f2f2L, 0x6b6b6b6bL, 0x6f6f6f6fL, 0xc5c5c5c5L, - 0x30303030L, 0x01010101L, 0x67676767L, 0x2b2b2b2bL, - 0xfefefefeL, 0xd7d7d7d7L, 0xababababL, 0x76767676L, - 0xcacacacaL, 0x82828282L, 0xc9c9c9c9L, 0x7d7d7d7dL, - 0xfafafafaL, 0x59595959L, 0x47474747L, 0xf0f0f0f0L, - 0xadadadadL, 0xd4d4d4d4L, 0xa2a2a2a2L, 0xafafafafL, - 0x9c9c9c9cL, 0xa4a4a4a4L, 0x72727272L, 0xc0c0c0c0L, - 0xb7b7b7b7L, 0xfdfdfdfdL, 0x93939393L, 0x26262626L, - 0x36363636L, 0x3f3f3f3fL, 0xf7f7f7f7L, 0xccccccccL, - 0x34343434L, 0xa5a5a5a5L, 0xe5e5e5e5L, 0xf1f1f1f1L, - 0x71717171L, 0xd8d8d8d8L, 0x31313131L, 0x15151515L, - 0x04040404L, 0xc7c7c7c7L, 0x23232323L, 0xc3c3c3c3L, - 0x18181818L, 0x96969696L, 0x05050505L, 0x9a9a9a9aL, - 0x07070707L, 0x12121212L, 0x80808080L, 0xe2e2e2e2L, - 0xebebebebL, 0x27272727L, 0xb2b2b2b2L, 0x75757575L, - 0x09090909L, 0x83838383L, 0x2c2c2c2cL, 0x1a1a1a1aL, - 0x1b1b1b1bL, 0x6e6e6e6eL, 0x5a5a5a5aL, 0xa0a0a0a0L, - 0x52525252L, 0x3b3b3b3bL, 0xd6d6d6d6L, 0xb3b3b3b3L, - 0x29292929L, 0xe3e3e3e3L, 0x2f2f2f2fL, 0x84848484L, - 0x53535353L, 0xd1d1d1d1L, 0x00000000L, 0xededededL, - 0x20202020L, 0xfcfcfcfcL, 0xb1b1b1b1L, 0x5b5b5b5bL, - 0x6a6a6a6aL, 0xcbcbcbcbL, 0xbebebebeL, 0x39393939L, - 0x4a4a4a4aL, 0x4c4c4c4cL, 0x58585858L, 0xcfcfcfcfL, - 0xd0d0d0d0L, 0xefefefefL, 0xaaaaaaaaL, 0xfbfbfbfbL, - 0x43434343L, 0x4d4d4d4dL, 0x33333333L, 0x85858585L, - 0x45454545L, 0xf9f9f9f9L, 0x02020202L, 0x7f7f7f7fL, - 0x50505050L, 0x3c3c3c3cL, 0x9f9f9f9fL, 0xa8a8a8a8L, - 0x51515151L, 0xa3a3a3a3L, 0x40404040L, 0x8f8f8f8fL, - 0x92929292L, 0x9d9d9d9dL, 0x38383838L, 0xf5f5f5f5L, - 0xbcbcbcbcL, 0xb6b6b6b6L, 0xdadadadaL, 0x21212121L, - 0x10101010L, 0xffffffffL, 0xf3f3f3f3L, 0xd2d2d2d2L, - 0xcdcdcdcdL, 0x0c0c0c0cL, 0x13131313L, 0xececececL, - 0x5f5f5f5fL, 0x97979797L, 0x44444444L, 0x17171717L, - 0xc4c4c4c4L, 0xa7a7a7a7L, 0x7e7e7e7eL, 0x3d3d3d3dL, - 0x64646464L, 0x5d5d5d5dL, 0x19191919L, 0x73737373L, - 0x60606060L, 0x81818181L, 0x4f4f4f4fL, 0xdcdcdcdcL, - 0x22222222L, 0x2a2a2a2aL, 0x90909090L, 0x88888888L, - 0x46464646L, 0xeeeeeeeeL, 0xb8b8b8b8L, 0x14141414L, - 0xdedededeL, 0x5e5e5e5eL, 0x0b0b0b0bL, 0xdbdbdbdbL, - 0xe0e0e0e0L, 0x32323232L, 0x3a3a3a3aL, 0x0a0a0a0aL, - 0x49494949L, 0x06060606L, 0x24242424L, 0x5c5c5c5cL, - 0xc2c2c2c2L, 0xd3d3d3d3L, 0xacacacacL, 0x62626262L, - 0x91919191L, 0x95959595L, 0xe4e4e4e4L, 0x79797979L, - 0xe7e7e7e7L, 0xc8c8c8c8L, 0x37373737L, 0x6d6d6d6dL, - 0x8d8d8d8dL, 0xd5d5d5d5L, 0x4e4e4e4eL, 0xa9a9a9a9L, - 0x6c6c6c6cL, 0x56565656L, 0xf4f4f4f4L, 0xeaeaeaeaL, - 0x65656565L, 0x7a7a7a7aL, 0xaeaeaeaeL, 0x08080808L, - 0xbabababaL, 0x78787878L, 0x25252525L, 0x2e2e2e2eL, - 0x1c1c1c1cL, 0xa6a6a6a6L, 0xb4b4b4b4L, 0xc6c6c6c6L, - 0xe8e8e8e8L, 0xddddddddL, 0x74747474L, 0x1f1f1f1fL, - 0x4b4b4b4bL, 0xbdbdbdbdL, 0x8b8b8b8bL, 0x8a8a8a8aL, - 0x70707070L, 0x3e3e3e3eL, 0xb5b5b5b5L, 0x66666666L, - 0x48484848L, 0x03030303L, 0xf6f6f6f6L, 0x0e0e0e0eL, - 0x61616161L, 0x35353535L, 0x57575757L, 0xb9b9b9b9L, - 0x86868686L, 0xc1c1c1c1L, 0x1d1d1d1dL, 0x9e9e9e9eL, - 0xe1e1e1e1L, 0xf8f8f8f8L, 0x98989898L, 0x11111111L, - 0x69696969L, 0xd9d9d9d9L, 0x8e8e8e8eL, 0x94949494L, - 0x9b9b9b9bL, 0x1e1e1e1eL, 0x87878787L, 0xe9e9e9e9L, - 0xcecececeL, 0x55555555L, 0x28282828L, 0xdfdfdfdfL, - 0x8c8c8c8cL, 0xa1a1a1a1L, 0x89898989L, 0x0d0d0d0dL, - 0xbfbfbfbfL, 0xe6e6e6e6L, 0x42424242L, 0x68686868L, - 0x41414141L, 0x99999999L, 0x2d2d2d2dL, 0x0f0f0f0fL, - 0xb0b0b0b0L, 0x54545454L, 0xbbbbbbbbL, 0x16161616L, - ] + 0x63636363L, 0x7c7c7c7cL, 0x77777777L, 0x7b7b7b7bL, + 0xf2f2f2f2L, 0x6b6b6b6bL, 0x6f6f6f6fL, 0xc5c5c5c5L, + 0x30303030L, 0x01010101L, 0x67676767L, 0x2b2b2b2bL, + 0xfefefefeL, 0xd7d7d7d7L, 0xababababL, 0x76767676L, + 0xcacacacaL, 0x82828282L, 0xc9c9c9c9L, 0x7d7d7d7dL, + 0xfafafafaL, 0x59595959L, 0x47474747L, 0xf0f0f0f0L, + 0xadadadadL, 0xd4d4d4d4L, 0xa2a2a2a2L, 0xafafafafL, + 0x9c9c9c9cL, 0xa4a4a4a4L, 0x72727272L, 0xc0c0c0c0L, + 0xb7b7b7b7L, 0xfdfdfdfdL, 0x93939393L, 0x26262626L, + 0x36363636L, 0x3f3f3f3fL, 0xf7f7f7f7L, 0xccccccccL, + 0x34343434L, 0xa5a5a5a5L, 0xe5e5e5e5L, 0xf1f1f1f1L, + 0x71717171L, 0xd8d8d8d8L, 0x31313131L, 0x15151515L, + 0x04040404L, 0xc7c7c7c7L, 0x23232323L, 0xc3c3c3c3L, + 0x18181818L, 0x96969696L, 0x05050505L, 0x9a9a9a9aL, + 0x07070707L, 0x12121212L, 0x80808080L, 0xe2e2e2e2L, + 0xebebebebL, 0x27272727L, 0xb2b2b2b2L, 0x75757575L, + 0x09090909L, 0x83838383L, 0x2c2c2c2cL, 0x1a1a1a1aL, + 0x1b1b1b1bL, 0x6e6e6e6eL, 0x5a5a5a5aL, 0xa0a0a0a0L, + 0x52525252L, 0x3b3b3b3bL, 0xd6d6d6d6L, 0xb3b3b3b3L, + 0x29292929L, 0xe3e3e3e3L, 0x2f2f2f2fL, 0x84848484L, + 0x53535353L, 0xd1d1d1d1L, 0x00000000L, 0xededededL, + 0x20202020L, 0xfcfcfcfcL, 0xb1b1b1b1L, 0x5b5b5b5bL, + 0x6a6a6a6aL, 0xcbcbcbcbL, 0xbebebebeL, 0x39393939L, + 0x4a4a4a4aL, 0x4c4c4c4cL, 0x58585858L, 0xcfcfcfcfL, + 0xd0d0d0d0L, 0xefefefefL, 0xaaaaaaaaL, 0xfbfbfbfbL, + 0x43434343L, 0x4d4d4d4dL, 0x33333333L, 0x85858585L, + 0x45454545L, 0xf9f9f9f9L, 0x02020202L, 0x7f7f7f7fL, + 0x50505050L, 0x3c3c3c3cL, 0x9f9f9f9fL, 0xa8a8a8a8L, + 0x51515151L, 0xa3a3a3a3L, 0x40404040L, 0x8f8f8f8fL, + 0x92929292L, 0x9d9d9d9dL, 0x38383838L, 0xf5f5f5f5L, + 0xbcbcbcbcL, 0xb6b6b6b6L, 0xdadadadaL, 0x21212121L, + 0x10101010L, 0xffffffffL, 0xf3f3f3f3L, 0xd2d2d2d2L, + 0xcdcdcdcdL, 0x0c0c0c0cL, 0x13131313L, 0xececececL, + 0x5f5f5f5fL, 0x97979797L, 0x44444444L, 0x17171717L, + 0xc4c4c4c4L, 0xa7a7a7a7L, 0x7e7e7e7eL, 0x3d3d3d3dL, + 0x64646464L, 0x5d5d5d5dL, 0x19191919L, 0x73737373L, + 0x60606060L, 0x81818181L, 0x4f4f4f4fL, 0xdcdcdcdcL, + 0x22222222L, 0x2a2a2a2aL, 0x90909090L, 0x88888888L, + 0x46464646L, 0xeeeeeeeeL, 0xb8b8b8b8L, 0x14141414L, + 0xdedededeL, 0x5e5e5e5eL, 0x0b0b0b0bL, 0xdbdbdbdbL, + 0xe0e0e0e0L, 0x32323232L, 0x3a3a3a3aL, 0x0a0a0a0aL, + 0x49494949L, 0x06060606L, 0x24242424L, 0x5c5c5c5cL, + 0xc2c2c2c2L, 0xd3d3d3d3L, 0xacacacacL, 0x62626262L, + 0x91919191L, 0x95959595L, 0xe4e4e4e4L, 0x79797979L, + 0xe7e7e7e7L, 0xc8c8c8c8L, 0x37373737L, 0x6d6d6d6dL, + 0x8d8d8d8dL, 0xd5d5d5d5L, 0x4e4e4e4eL, 0xa9a9a9a9L, + 0x6c6c6c6cL, 0x56565656L, 0xf4f4f4f4L, 0xeaeaeaeaL, + 0x65656565L, 0x7a7a7a7aL, 0xaeaeaeaeL, 0x08080808L, + 0xbabababaL, 0x78787878L, 0x25252525L, 0x2e2e2e2eL, + 0x1c1c1c1cL, 0xa6a6a6a6L, 0xb4b4b4b4L, 0xc6c6c6c6L, + 0xe8e8e8e8L, 0xddddddddL, 0x74747474L, 0x1f1f1f1fL, + 0x4b4b4b4bL, 0xbdbdbdbdL, 0x8b8b8b8bL, 0x8a8a8a8aL, + 0x70707070L, 0x3e3e3e3eL, 0xb5b5b5b5L, 0x66666666L, + 0x48484848L, 0x03030303L, 0xf6f6f6f6L, 0x0e0e0e0eL, + 0x61616161L, 0x35353535L, 0x57575757L, 0xb9b9b9b9L, + 0x86868686L, 0xc1c1c1c1L, 0x1d1d1d1dL, 0x9e9e9e9eL, + 0xe1e1e1e1L, 0xf8f8f8f8L, 0x98989898L, 0x11111111L, + 0x69696969L, 0xd9d9d9d9L, 0x8e8e8e8eL, 0x94949494L, + 0x9b9b9b9bL, 0x1e1e1e1eL, 0x87878787L, 0xe9e9e9e9L, + 0xcecececeL, 0x55555555L, 0x28282828L, 0xdfdfdfdfL, + 0x8c8c8c8cL, 0xa1a1a1a1L, 0x89898989L, 0x0d0d0d0dL, + 0xbfbfbfbfL, 0xe6e6e6e6L, 0x42424242L, 0x68686868L, + 0x41414141L, 0x99999999L, 0x2d2d2d2dL, 0x0f0f0f0fL, + 0xb0b0b0b0L, 0x54545454L, 0xbbbbbbbbL, 0x16161616L, +] Td0 = [ - 0x51f4a750L, 0x7e416553L, 0x1a17a4c3L, 0x3a275e96L, - 0x3bab6bcbL, 0x1f9d45f1L, 0xacfa58abL, 0x4be30393L, - 0x2030fa55L, 0xad766df6L, 0x88cc7691L, 0xf5024c25L, - 0x4fe5d7fcL, 0xc52acbd7L, 0x26354480L, 0xb562a38fL, - 0xdeb15a49L, 0x25ba1b67L, 0x45ea0e98L, 0x5dfec0e1L, - 0xc32f7502L, 0x814cf012L, 0x8d4697a3L, 0x6bd3f9c6L, - 0x038f5fe7L, 0x15929c95L, 0xbf6d7aebL, 0x955259daL, - 0xd4be832dL, 0x587421d3L, 0x49e06929L, 0x8ec9c844L, - 0x75c2896aL, 0xf48e7978L, 0x99583e6bL, 0x27b971ddL, - 0xbee14fb6L, 0xf088ad17L, 0xc920ac66L, 0x7dce3ab4L, - 0x63df4a18L, 0xe51a3182L, 0x97513360L, 0x62537f45L, - 0xb16477e0L, 0xbb6bae84L, 0xfe81a01cL, 0xf9082b94L, - 0x70486858L, 0x8f45fd19L, 0x94de6c87L, 0x527bf8b7L, - 0xab73d323L, 0x724b02e2L, 0xe31f8f57L, 0x6655ab2aL, - 0xb2eb2807L, 0x2fb5c203L, 0x86c57b9aL, 0xd33708a5L, - 0x302887f2L, 0x23bfa5b2L, 0x02036abaL, 0xed16825cL, - 0x8acf1c2bL, 0xa779b492L, 0xf307f2f0L, 0x4e69e2a1L, - 0x65daf4cdL, 0x0605bed5L, 0xd134621fL, 0xc4a6fe8aL, - 0x342e539dL, 0xa2f355a0L, 0x058ae132L, 0xa4f6eb75L, - 0x0b83ec39L, 0x4060efaaL, 0x5e719f06L, 0xbd6e1051L, - 0x3e218af9L, 0x96dd063dL, 0xdd3e05aeL, 0x4de6bd46L, - 0x91548db5L, 0x71c45d05L, 0x0406d46fL, 0x605015ffL, - 0x1998fb24L, 0xd6bde997L, 0x894043ccL, 0x67d99e77L, - 0xb0e842bdL, 0x07898b88L, 0xe7195b38L, 0x79c8eedbL, - 0xa17c0a47L, 0x7c420fe9L, 0xf8841ec9L, 0x00000000L, - 0x09808683L, 0x322bed48L, 0x1e1170acL, 0x6c5a724eL, - 0xfd0efffbL, 0x0f853856L, 0x3daed51eL, 0x362d3927L, - 0x0a0fd964L, 0x685ca621L, 0x9b5b54d1L, 0x24362e3aL, - 0x0c0a67b1L, 0x9357e70fL, 0xb4ee96d2L, 0x1b9b919eL, - 0x80c0c54fL, 0x61dc20a2L, 0x5a774b69L, 0x1c121a16L, - 0xe293ba0aL, 0xc0a02ae5L, 0x3c22e043L, 0x121b171dL, - 0x0e090d0bL, 0xf28bc7adL, 0x2db6a8b9L, 0x141ea9c8L, - 0x57f11985L, 0xaf75074cL, 0xee99ddbbL, 0xa37f60fdL, - 0xf701269fL, 0x5c72f5bcL, 0x44663bc5L, 0x5bfb7e34L, - 0x8b432976L, 0xcb23c6dcL, 0xb6edfc68L, 0xb8e4f163L, - 0xd731dccaL, 0x42638510L, 0x13972240L, 0x84c61120L, - 0x854a247dL, 0xd2bb3df8L, 0xaef93211L, 0xc729a16dL, - 0x1d9e2f4bL, 0xdcb230f3L, 0x0d8652ecL, 0x77c1e3d0L, - 0x2bb3166cL, 0xa970b999L, 0x119448faL, 0x47e96422L, - 0xa8fc8cc4L, 0xa0f03f1aL, 0x567d2cd8L, 0x223390efL, - 0x87494ec7L, 0xd938d1c1L, 0x8ccaa2feL, 0x98d40b36L, - 0xa6f581cfL, 0xa57ade28L, 0xdab78e26L, 0x3fadbfa4L, - 0x2c3a9de4L, 0x5078920dL, 0x6a5fcc9bL, 0x547e4662L, - 0xf68d13c2L, 0x90d8b8e8L, 0x2e39f75eL, 0x82c3aff5L, - 0x9f5d80beL, 0x69d0937cL, 0x6fd52da9L, 0xcf2512b3L, - 0xc8ac993bL, 0x10187da7L, 0xe89c636eL, 0xdb3bbb7bL, - 0xcd267809L, 0x6e5918f4L, 0xec9ab701L, 0x834f9aa8L, - 0xe6956e65L, 0xaaffe67eL, 0x21bccf08L, 0xef15e8e6L, - 0xbae79bd9L, 0x4a6f36ceL, 0xea9f09d4L, 0x29b07cd6L, - 0x31a4b2afL, 0x2a3f2331L, 0xc6a59430L, 0x35a266c0L, - 0x744ebc37L, 0xfc82caa6L, 0xe090d0b0L, 0x33a7d815L, - 0xf104984aL, 0x41ecdaf7L, 0x7fcd500eL, 0x1791f62fL, - 0x764dd68dL, 0x43efb04dL, 0xccaa4d54L, 0xe49604dfL, - 0x9ed1b5e3L, 0x4c6a881bL, 0xc12c1fb8L, 0x4665517fL, - 0x9d5eea04L, 0x018c355dL, 0xfa877473L, 0xfb0b412eL, - 0xb3671d5aL, 0x92dbd252L, 0xe9105633L, 0x6dd64713L, - 0x9ad7618cL, 0x37a10c7aL, 0x59f8148eL, 0xeb133c89L, - 0xcea927eeL, 0xb761c935L, 0xe11ce5edL, 0x7a47b13cL, - 0x9cd2df59L, 0x55f2733fL, 0x1814ce79L, 0x73c737bfL, - 0x53f7cdeaL, 0x5ffdaa5bL, 0xdf3d6f14L, 0x7844db86L, - 0xcaaff381L, 0xb968c43eL, 0x3824342cL, 0xc2a3405fL, - 0x161dc372L, 0xbce2250cL, 0x283c498bL, 0xff0d9541L, - 0x39a80171L, 0x080cb3deL, 0xd8b4e49cL, 0x6456c190L, - 0x7bcb8461L, 0xd532b670L, 0x486c5c74L, 0xd0b85742L, - ] + 0x51f4a750L, 0x7e416553L, 0x1a17a4c3L, 0x3a275e96L, + 0x3bab6bcbL, 0x1f9d45f1L, 0xacfa58abL, 0x4be30393L, + 0x2030fa55L, 0xad766df6L, 0x88cc7691L, 0xf5024c25L, + 0x4fe5d7fcL, 0xc52acbd7L, 0x26354480L, 0xb562a38fL, + 0xdeb15a49L, 0x25ba1b67L, 0x45ea0e98L, 0x5dfec0e1L, + 0xc32f7502L, 0x814cf012L, 0x8d4697a3L, 0x6bd3f9c6L, + 0x038f5fe7L, 0x15929c95L, 0xbf6d7aebL, 0x955259daL, + 0xd4be832dL, 0x587421d3L, 0x49e06929L, 0x8ec9c844L, + 0x75c2896aL, 0xf48e7978L, 0x99583e6bL, 0x27b971ddL, + 0xbee14fb6L, 0xf088ad17L, 0xc920ac66L, 0x7dce3ab4L, + 0x63df4a18L, 0xe51a3182L, 0x97513360L, 0x62537f45L, + 0xb16477e0L, 0xbb6bae84L, 0xfe81a01cL, 0xf9082b94L, + 0x70486858L, 0x8f45fd19L, 0x94de6c87L, 0x527bf8b7L, + 0xab73d323L, 0x724b02e2L, 0xe31f8f57L, 0x6655ab2aL, + 0xb2eb2807L, 0x2fb5c203L, 0x86c57b9aL, 0xd33708a5L, + 0x302887f2L, 0x23bfa5b2L, 0x02036abaL, 0xed16825cL, + 0x8acf1c2bL, 0xa779b492L, 0xf307f2f0L, 0x4e69e2a1L, + 0x65daf4cdL, 0x0605bed5L, 0xd134621fL, 0xc4a6fe8aL, + 0x342e539dL, 0xa2f355a0L, 0x058ae132L, 0xa4f6eb75L, + 0x0b83ec39L, 0x4060efaaL, 0x5e719f06L, 0xbd6e1051L, + 0x3e218af9L, 0x96dd063dL, 0xdd3e05aeL, 0x4de6bd46L, + 0x91548db5L, 0x71c45d05L, 0x0406d46fL, 0x605015ffL, + 0x1998fb24L, 0xd6bde997L, 0x894043ccL, 0x67d99e77L, + 0xb0e842bdL, 0x07898b88L, 0xe7195b38L, 0x79c8eedbL, + 0xa17c0a47L, 0x7c420fe9L, 0xf8841ec9L, 0x00000000L, + 0x09808683L, 0x322bed48L, 0x1e1170acL, 0x6c5a724eL, + 0xfd0efffbL, 0x0f853856L, 0x3daed51eL, 0x362d3927L, + 0x0a0fd964L, 0x685ca621L, 0x9b5b54d1L, 0x24362e3aL, + 0x0c0a67b1L, 0x9357e70fL, 0xb4ee96d2L, 0x1b9b919eL, + 0x80c0c54fL, 0x61dc20a2L, 0x5a774b69L, 0x1c121a16L, + 0xe293ba0aL, 0xc0a02ae5L, 0x3c22e043L, 0x121b171dL, + 0x0e090d0bL, 0xf28bc7adL, 0x2db6a8b9L, 0x141ea9c8L, + 0x57f11985L, 0xaf75074cL, 0xee99ddbbL, 0xa37f60fdL, + 0xf701269fL, 0x5c72f5bcL, 0x44663bc5L, 0x5bfb7e34L, + 0x8b432976L, 0xcb23c6dcL, 0xb6edfc68L, 0xb8e4f163L, + 0xd731dccaL, 0x42638510L, 0x13972240L, 0x84c61120L, + 0x854a247dL, 0xd2bb3df8L, 0xaef93211L, 0xc729a16dL, + 0x1d9e2f4bL, 0xdcb230f3L, 0x0d8652ecL, 0x77c1e3d0L, + 0x2bb3166cL, 0xa970b999L, 0x119448faL, 0x47e96422L, + 0xa8fc8cc4L, 0xa0f03f1aL, 0x567d2cd8L, 0x223390efL, + 0x87494ec7L, 0xd938d1c1L, 0x8ccaa2feL, 0x98d40b36L, + 0xa6f581cfL, 0xa57ade28L, 0xdab78e26L, 0x3fadbfa4L, + 0x2c3a9de4L, 0x5078920dL, 0x6a5fcc9bL, 0x547e4662L, + 0xf68d13c2L, 0x90d8b8e8L, 0x2e39f75eL, 0x82c3aff5L, + 0x9f5d80beL, 0x69d0937cL, 0x6fd52da9L, 0xcf2512b3L, + 0xc8ac993bL, 0x10187da7L, 0xe89c636eL, 0xdb3bbb7bL, + 0xcd267809L, 0x6e5918f4L, 0xec9ab701L, 0x834f9aa8L, + 0xe6956e65L, 0xaaffe67eL, 0x21bccf08L, 0xef15e8e6L, + 0xbae79bd9L, 0x4a6f36ceL, 0xea9f09d4L, 0x29b07cd6L, + 0x31a4b2afL, 0x2a3f2331L, 0xc6a59430L, 0x35a266c0L, + 0x744ebc37L, 0xfc82caa6L, 0xe090d0b0L, 0x33a7d815L, + 0xf104984aL, 0x41ecdaf7L, 0x7fcd500eL, 0x1791f62fL, + 0x764dd68dL, 0x43efb04dL, 0xccaa4d54L, 0xe49604dfL, + 0x9ed1b5e3L, 0x4c6a881bL, 0xc12c1fb8L, 0x4665517fL, + 0x9d5eea04L, 0x018c355dL, 0xfa877473L, 0xfb0b412eL, + 0xb3671d5aL, 0x92dbd252L, 0xe9105633L, 0x6dd64713L, + 0x9ad7618cL, 0x37a10c7aL, 0x59f8148eL, 0xeb133c89L, + 0xcea927eeL, 0xb761c935L, 0xe11ce5edL, 0x7a47b13cL, + 0x9cd2df59L, 0x55f2733fL, 0x1814ce79L, 0x73c737bfL, + 0x53f7cdeaL, 0x5ffdaa5bL, 0xdf3d6f14L, 0x7844db86L, + 0xcaaff381L, 0xb968c43eL, 0x3824342cL, 0xc2a3405fL, + 0x161dc372L, 0xbce2250cL, 0x283c498bL, 0xff0d9541L, + 0x39a80171L, 0x080cb3deL, 0xd8b4e49cL, 0x6456c190L, + 0x7bcb8461L, 0xd532b670L, 0x486c5c74L, 0xd0b85742L, +] Td1 = [ - 0x5051f4a7L, 0x537e4165L, 0xc31a17a4L, 0x963a275eL, - 0xcb3bab6bL, 0xf11f9d45L, 0xabacfa58L, 0x934be303L, - 0x552030faL, 0xf6ad766dL, 0x9188cc76L, 0x25f5024cL, - 0xfc4fe5d7L, 0xd7c52acbL, 0x80263544L, 0x8fb562a3L, - 0x49deb15aL, 0x6725ba1bL, 0x9845ea0eL, 0xe15dfec0L, - 0x02c32f75L, 0x12814cf0L, 0xa38d4697L, 0xc66bd3f9L, - 0xe7038f5fL, 0x9515929cL, 0xebbf6d7aL, 0xda955259L, - 0x2dd4be83L, 0xd3587421L, 0x2949e069L, 0x448ec9c8L, - 0x6a75c289L, 0x78f48e79L, 0x6b99583eL, 0xdd27b971L, - 0xb6bee14fL, 0x17f088adL, 0x66c920acL, 0xb47dce3aL, - 0x1863df4aL, 0x82e51a31L, 0x60975133L, 0x4562537fL, - 0xe0b16477L, 0x84bb6baeL, 0x1cfe81a0L, 0x94f9082bL, - 0x58704868L, 0x198f45fdL, 0x8794de6cL, 0xb7527bf8L, - 0x23ab73d3L, 0xe2724b02L, 0x57e31f8fL, 0x2a6655abL, - 0x07b2eb28L, 0x032fb5c2L, 0x9a86c57bL, 0xa5d33708L, - 0xf2302887L, 0xb223bfa5L, 0xba02036aL, 0x5ced1682L, - 0x2b8acf1cL, 0x92a779b4L, 0xf0f307f2L, 0xa14e69e2L, - 0xcd65daf4L, 0xd50605beL, 0x1fd13462L, 0x8ac4a6feL, - 0x9d342e53L, 0xa0a2f355L, 0x32058ae1L, 0x75a4f6ebL, - 0x390b83ecL, 0xaa4060efL, 0x065e719fL, 0x51bd6e10L, - 0xf93e218aL, 0x3d96dd06L, 0xaedd3e05L, 0x464de6bdL, - 0xb591548dL, 0x0571c45dL, 0x6f0406d4L, 0xff605015L, - 0x241998fbL, 0x97d6bde9L, 0xcc894043L, 0x7767d99eL, - 0xbdb0e842L, 0x8807898bL, 0x38e7195bL, 0xdb79c8eeL, - 0x47a17c0aL, 0xe97c420fL, 0xc9f8841eL, 0x00000000L, - 0x83098086L, 0x48322bedL, 0xac1e1170L, 0x4e6c5a72L, - 0xfbfd0effL, 0x560f8538L, 0x1e3daed5L, 0x27362d39L, - 0x640a0fd9L, 0x21685ca6L, 0xd19b5b54L, 0x3a24362eL, - 0xb10c0a67L, 0x0f9357e7L, 0xd2b4ee96L, 0x9e1b9b91L, - 0x4f80c0c5L, 0xa261dc20L, 0x695a774bL, 0x161c121aL, - 0x0ae293baL, 0xe5c0a02aL, 0x433c22e0L, 0x1d121b17L, - 0x0b0e090dL, 0xadf28bc7L, 0xb92db6a8L, 0xc8141ea9L, - 0x8557f119L, 0x4caf7507L, 0xbbee99ddL, 0xfda37f60L, - 0x9ff70126L, 0xbc5c72f5L, 0xc544663bL, 0x345bfb7eL, - 0x768b4329L, 0xdccb23c6L, 0x68b6edfcL, 0x63b8e4f1L, - 0xcad731dcL, 0x10426385L, 0x40139722L, 0x2084c611L, - 0x7d854a24L, 0xf8d2bb3dL, 0x11aef932L, 0x6dc729a1L, - 0x4b1d9e2fL, 0xf3dcb230L, 0xec0d8652L, 0xd077c1e3L, - 0x6c2bb316L, 0x99a970b9L, 0xfa119448L, 0x2247e964L, - 0xc4a8fc8cL, 0x1aa0f03fL, 0xd8567d2cL, 0xef223390L, - 0xc787494eL, 0xc1d938d1L, 0xfe8ccaa2L, 0x3698d40bL, - 0xcfa6f581L, 0x28a57adeL, 0x26dab78eL, 0xa43fadbfL, - 0xe42c3a9dL, 0x0d507892L, 0x9b6a5fccL, 0x62547e46L, - 0xc2f68d13L, 0xe890d8b8L, 0x5e2e39f7L, 0xf582c3afL, - 0xbe9f5d80L, 0x7c69d093L, 0xa96fd52dL, 0xb3cf2512L, - 0x3bc8ac99L, 0xa710187dL, 0x6ee89c63L, 0x7bdb3bbbL, - 0x09cd2678L, 0xf46e5918L, 0x01ec9ab7L, 0xa8834f9aL, - 0x65e6956eL, 0x7eaaffe6L, 0x0821bccfL, 0xe6ef15e8L, - 0xd9bae79bL, 0xce4a6f36L, 0xd4ea9f09L, 0xd629b07cL, - 0xaf31a4b2L, 0x312a3f23L, 0x30c6a594L, 0xc035a266L, - 0x37744ebcL, 0xa6fc82caL, 0xb0e090d0L, 0x1533a7d8L, - 0x4af10498L, 0xf741ecdaL, 0x0e7fcd50L, 0x2f1791f6L, - 0x8d764dd6L, 0x4d43efb0L, 0x54ccaa4dL, 0xdfe49604L, - 0xe39ed1b5L, 0x1b4c6a88L, 0xb8c12c1fL, 0x7f466551L, - 0x049d5eeaL, 0x5d018c35L, 0x73fa8774L, 0x2efb0b41L, - 0x5ab3671dL, 0x5292dbd2L, 0x33e91056L, 0x136dd647L, - 0x8c9ad761L, 0x7a37a10cL, 0x8e59f814L, 0x89eb133cL, - 0xeecea927L, 0x35b761c9L, 0xede11ce5L, 0x3c7a47b1L, - 0x599cd2dfL, 0x3f55f273L, 0x791814ceL, 0xbf73c737L, - 0xea53f7cdL, 0x5b5ffdaaL, 0x14df3d6fL, 0x867844dbL, - 0x81caaff3L, 0x3eb968c4L, 0x2c382434L, 0x5fc2a340L, - 0x72161dc3L, 0x0cbce225L, 0x8b283c49L, 0x41ff0d95L, - 0x7139a801L, 0xde080cb3L, 0x9cd8b4e4L, 0x906456c1L, - 0x617bcb84L, 0x70d532b6L, 0x74486c5cL, 0x42d0b857L, - ] + 0x5051f4a7L, 0x537e4165L, 0xc31a17a4L, 0x963a275eL, + 0xcb3bab6bL, 0xf11f9d45L, 0xabacfa58L, 0x934be303L, + 0x552030faL, 0xf6ad766dL, 0x9188cc76L, 0x25f5024cL, + 0xfc4fe5d7L, 0xd7c52acbL, 0x80263544L, 0x8fb562a3L, + 0x49deb15aL, 0x6725ba1bL, 0x9845ea0eL, 0xe15dfec0L, + 0x02c32f75L, 0x12814cf0L, 0xa38d4697L, 0xc66bd3f9L, + 0xe7038f5fL, 0x9515929cL, 0xebbf6d7aL, 0xda955259L, + 0x2dd4be83L, 0xd3587421L, 0x2949e069L, 0x448ec9c8L, + 0x6a75c289L, 0x78f48e79L, 0x6b99583eL, 0xdd27b971L, + 0xb6bee14fL, 0x17f088adL, 0x66c920acL, 0xb47dce3aL, + 0x1863df4aL, 0x82e51a31L, 0x60975133L, 0x4562537fL, + 0xe0b16477L, 0x84bb6baeL, 0x1cfe81a0L, 0x94f9082bL, + 0x58704868L, 0x198f45fdL, 0x8794de6cL, 0xb7527bf8L, + 0x23ab73d3L, 0xe2724b02L, 0x57e31f8fL, 0x2a6655abL, + 0x07b2eb28L, 0x032fb5c2L, 0x9a86c57bL, 0xa5d33708L, + 0xf2302887L, 0xb223bfa5L, 0xba02036aL, 0x5ced1682L, + 0x2b8acf1cL, 0x92a779b4L, 0xf0f307f2L, 0xa14e69e2L, + 0xcd65daf4L, 0xd50605beL, 0x1fd13462L, 0x8ac4a6feL, + 0x9d342e53L, 0xa0a2f355L, 0x32058ae1L, 0x75a4f6ebL, + 0x390b83ecL, 0xaa4060efL, 0x065e719fL, 0x51bd6e10L, + 0xf93e218aL, 0x3d96dd06L, 0xaedd3e05L, 0x464de6bdL, + 0xb591548dL, 0x0571c45dL, 0x6f0406d4L, 0xff605015L, + 0x241998fbL, 0x97d6bde9L, 0xcc894043L, 0x7767d99eL, + 0xbdb0e842L, 0x8807898bL, 0x38e7195bL, 0xdb79c8eeL, + 0x47a17c0aL, 0xe97c420fL, 0xc9f8841eL, 0x00000000L, + 0x83098086L, 0x48322bedL, 0xac1e1170L, 0x4e6c5a72L, + 0xfbfd0effL, 0x560f8538L, 0x1e3daed5L, 0x27362d39L, + 0x640a0fd9L, 0x21685ca6L, 0xd19b5b54L, 0x3a24362eL, + 0xb10c0a67L, 0x0f9357e7L, 0xd2b4ee96L, 0x9e1b9b91L, + 0x4f80c0c5L, 0xa261dc20L, 0x695a774bL, 0x161c121aL, + 0x0ae293baL, 0xe5c0a02aL, 0x433c22e0L, 0x1d121b17L, + 0x0b0e090dL, 0xadf28bc7L, 0xb92db6a8L, 0xc8141ea9L, + 0x8557f119L, 0x4caf7507L, 0xbbee99ddL, 0xfda37f60L, + 0x9ff70126L, 0xbc5c72f5L, 0xc544663bL, 0x345bfb7eL, + 0x768b4329L, 0xdccb23c6L, 0x68b6edfcL, 0x63b8e4f1L, + 0xcad731dcL, 0x10426385L, 0x40139722L, 0x2084c611L, + 0x7d854a24L, 0xf8d2bb3dL, 0x11aef932L, 0x6dc729a1L, + 0x4b1d9e2fL, 0xf3dcb230L, 0xec0d8652L, 0xd077c1e3L, + 0x6c2bb316L, 0x99a970b9L, 0xfa119448L, 0x2247e964L, + 0xc4a8fc8cL, 0x1aa0f03fL, 0xd8567d2cL, 0xef223390L, + 0xc787494eL, 0xc1d938d1L, 0xfe8ccaa2L, 0x3698d40bL, + 0xcfa6f581L, 0x28a57adeL, 0x26dab78eL, 0xa43fadbfL, + 0xe42c3a9dL, 0x0d507892L, 0x9b6a5fccL, 0x62547e46L, + 0xc2f68d13L, 0xe890d8b8L, 0x5e2e39f7L, 0xf582c3afL, + 0xbe9f5d80L, 0x7c69d093L, 0xa96fd52dL, 0xb3cf2512L, + 0x3bc8ac99L, 0xa710187dL, 0x6ee89c63L, 0x7bdb3bbbL, + 0x09cd2678L, 0xf46e5918L, 0x01ec9ab7L, 0xa8834f9aL, + 0x65e6956eL, 0x7eaaffe6L, 0x0821bccfL, 0xe6ef15e8L, + 0xd9bae79bL, 0xce4a6f36L, 0xd4ea9f09L, 0xd629b07cL, + 0xaf31a4b2L, 0x312a3f23L, 0x30c6a594L, 0xc035a266L, + 0x37744ebcL, 0xa6fc82caL, 0xb0e090d0L, 0x1533a7d8L, + 0x4af10498L, 0xf741ecdaL, 0x0e7fcd50L, 0x2f1791f6L, + 0x8d764dd6L, 0x4d43efb0L, 0x54ccaa4dL, 0xdfe49604L, + 0xe39ed1b5L, 0x1b4c6a88L, 0xb8c12c1fL, 0x7f466551L, + 0x049d5eeaL, 0x5d018c35L, 0x73fa8774L, 0x2efb0b41L, + 0x5ab3671dL, 0x5292dbd2L, 0x33e91056L, 0x136dd647L, + 0x8c9ad761L, 0x7a37a10cL, 0x8e59f814L, 0x89eb133cL, + 0xeecea927L, 0x35b761c9L, 0xede11ce5L, 0x3c7a47b1L, + 0x599cd2dfL, 0x3f55f273L, 0x791814ceL, 0xbf73c737L, + 0xea53f7cdL, 0x5b5ffdaaL, 0x14df3d6fL, 0x867844dbL, + 0x81caaff3L, 0x3eb968c4L, 0x2c382434L, 0x5fc2a340L, + 0x72161dc3L, 0x0cbce225L, 0x8b283c49L, 0x41ff0d95L, + 0x7139a801L, 0xde080cb3L, 0x9cd8b4e4L, 0x906456c1L, + 0x617bcb84L, 0x70d532b6L, 0x74486c5cL, 0x42d0b857L, +] Td2 = [ - 0xa75051f4L, 0x65537e41L, 0xa4c31a17L, 0x5e963a27L, - 0x6bcb3babL, 0x45f11f9dL, 0x58abacfaL, 0x03934be3L, - 0xfa552030L, 0x6df6ad76L, 0x769188ccL, 0x4c25f502L, - 0xd7fc4fe5L, 0xcbd7c52aL, 0x44802635L, 0xa38fb562L, - 0x5a49deb1L, 0x1b6725baL, 0x0e9845eaL, 0xc0e15dfeL, - 0x7502c32fL, 0xf012814cL, 0x97a38d46L, 0xf9c66bd3L, - 0x5fe7038fL, 0x9c951592L, 0x7aebbf6dL, 0x59da9552L, - 0x832dd4beL, 0x21d35874L, 0x692949e0L, 0xc8448ec9L, - 0x896a75c2L, 0x7978f48eL, 0x3e6b9958L, 0x71dd27b9L, - 0x4fb6bee1L, 0xad17f088L, 0xac66c920L, 0x3ab47dceL, - 0x4a1863dfL, 0x3182e51aL, 0x33609751L, 0x7f456253L, - 0x77e0b164L, 0xae84bb6bL, 0xa01cfe81L, 0x2b94f908L, - 0x68587048L, 0xfd198f45L, 0x6c8794deL, 0xf8b7527bL, - 0xd323ab73L, 0x02e2724bL, 0x8f57e31fL, 0xab2a6655L, - 0x2807b2ebL, 0xc2032fb5L, 0x7b9a86c5L, 0x08a5d337L, - 0x87f23028L, 0xa5b223bfL, 0x6aba0203L, 0x825ced16L, - 0x1c2b8acfL, 0xb492a779L, 0xf2f0f307L, 0xe2a14e69L, - 0xf4cd65daL, 0xbed50605L, 0x621fd134L, 0xfe8ac4a6L, - 0x539d342eL, 0x55a0a2f3L, 0xe132058aL, 0xeb75a4f6L, - 0xec390b83L, 0xefaa4060L, 0x9f065e71L, 0x1051bd6eL, - 0x8af93e21L, 0x063d96ddL, 0x05aedd3eL, 0xbd464de6L, - 0x8db59154L, 0x5d0571c4L, 0xd46f0406L, 0x15ff6050L, - 0xfb241998L, 0xe997d6bdL, 0x43cc8940L, 0x9e7767d9L, - 0x42bdb0e8L, 0x8b880789L, 0x5b38e719L, 0xeedb79c8L, - 0x0a47a17cL, 0x0fe97c42L, 0x1ec9f884L, 0x00000000L, - 0x86830980L, 0xed48322bL, 0x70ac1e11L, 0x724e6c5aL, - 0xfffbfd0eL, 0x38560f85L, 0xd51e3daeL, 0x3927362dL, - 0xd9640a0fL, 0xa621685cL, 0x54d19b5bL, 0x2e3a2436L, - 0x67b10c0aL, 0xe70f9357L, 0x96d2b4eeL, 0x919e1b9bL, - 0xc54f80c0L, 0x20a261dcL, 0x4b695a77L, 0x1a161c12L, - 0xba0ae293L, 0x2ae5c0a0L, 0xe0433c22L, 0x171d121bL, - 0x0d0b0e09L, 0xc7adf28bL, 0xa8b92db6L, 0xa9c8141eL, - 0x198557f1L, 0x074caf75L, 0xddbbee99L, 0x60fda37fL, - 0x269ff701L, 0xf5bc5c72L, 0x3bc54466L, 0x7e345bfbL, - 0x29768b43L, 0xc6dccb23L, 0xfc68b6edL, 0xf163b8e4L, - 0xdccad731L, 0x85104263L, 0x22401397L, 0x112084c6L, - 0x247d854aL, 0x3df8d2bbL, 0x3211aef9L, 0xa16dc729L, - 0x2f4b1d9eL, 0x30f3dcb2L, 0x52ec0d86L, 0xe3d077c1L, - 0x166c2bb3L, 0xb999a970L, 0x48fa1194L, 0x642247e9L, - 0x8cc4a8fcL, 0x3f1aa0f0L, 0x2cd8567dL, 0x90ef2233L, - 0x4ec78749L, 0xd1c1d938L, 0xa2fe8ccaL, 0x0b3698d4L, - 0x81cfa6f5L, 0xde28a57aL, 0x8e26dab7L, 0xbfa43fadL, - 0x9de42c3aL, 0x920d5078L, 0xcc9b6a5fL, 0x4662547eL, - 0x13c2f68dL, 0xb8e890d8L, 0xf75e2e39L, 0xaff582c3L, - 0x80be9f5dL, 0x937c69d0L, 0x2da96fd5L, 0x12b3cf25L, - 0x993bc8acL, 0x7da71018L, 0x636ee89cL, 0xbb7bdb3bL, - 0x7809cd26L, 0x18f46e59L, 0xb701ec9aL, 0x9aa8834fL, - 0x6e65e695L, 0xe67eaaffL, 0xcf0821bcL, 0xe8e6ef15L, - 0x9bd9bae7L, 0x36ce4a6fL, 0x09d4ea9fL, 0x7cd629b0L, - 0xb2af31a4L, 0x23312a3fL, 0x9430c6a5L, 0x66c035a2L, - 0xbc37744eL, 0xcaa6fc82L, 0xd0b0e090L, 0xd81533a7L, - 0x984af104L, 0xdaf741ecL, 0x500e7fcdL, 0xf62f1791L, - 0xd68d764dL, 0xb04d43efL, 0x4d54ccaaL, 0x04dfe496L, - 0xb5e39ed1L, 0x881b4c6aL, 0x1fb8c12cL, 0x517f4665L, - 0xea049d5eL, 0x355d018cL, 0x7473fa87L, 0x412efb0bL, - 0x1d5ab367L, 0xd25292dbL, 0x5633e910L, 0x47136dd6L, - 0x618c9ad7L, 0x0c7a37a1L, 0x148e59f8L, 0x3c89eb13L, - 0x27eecea9L, 0xc935b761L, 0xe5ede11cL, 0xb13c7a47L, - 0xdf599cd2L, 0x733f55f2L, 0xce791814L, 0x37bf73c7L, - 0xcdea53f7L, 0xaa5b5ffdL, 0x6f14df3dL, 0xdb867844L, - 0xf381caafL, 0xc43eb968L, 0x342c3824L, 0x405fc2a3L, - 0xc372161dL, 0x250cbce2L, 0x498b283cL, 0x9541ff0dL, - 0x017139a8L, 0xb3de080cL, 0xe49cd8b4L, 0xc1906456L, - 0x84617bcbL, 0xb670d532L, 0x5c74486cL, 0x5742d0b8L, - ] + 0xa75051f4L, 0x65537e41L, 0xa4c31a17L, 0x5e963a27L, + 0x6bcb3babL, 0x45f11f9dL, 0x58abacfaL, 0x03934be3L, + 0xfa552030L, 0x6df6ad76L, 0x769188ccL, 0x4c25f502L, + 0xd7fc4fe5L, 0xcbd7c52aL, 0x44802635L, 0xa38fb562L, + 0x5a49deb1L, 0x1b6725baL, 0x0e9845eaL, 0xc0e15dfeL, + 0x7502c32fL, 0xf012814cL, 0x97a38d46L, 0xf9c66bd3L, + 0x5fe7038fL, 0x9c951592L, 0x7aebbf6dL, 0x59da9552L, + 0x832dd4beL, 0x21d35874L, 0x692949e0L, 0xc8448ec9L, + 0x896a75c2L, 0x7978f48eL, 0x3e6b9958L, 0x71dd27b9L, + 0x4fb6bee1L, 0xad17f088L, 0xac66c920L, 0x3ab47dceL, + 0x4a1863dfL, 0x3182e51aL, 0x33609751L, 0x7f456253L, + 0x77e0b164L, 0xae84bb6bL, 0xa01cfe81L, 0x2b94f908L, + 0x68587048L, 0xfd198f45L, 0x6c8794deL, 0xf8b7527bL, + 0xd323ab73L, 0x02e2724bL, 0x8f57e31fL, 0xab2a6655L, + 0x2807b2ebL, 0xc2032fb5L, 0x7b9a86c5L, 0x08a5d337L, + 0x87f23028L, 0xa5b223bfL, 0x6aba0203L, 0x825ced16L, + 0x1c2b8acfL, 0xb492a779L, 0xf2f0f307L, 0xe2a14e69L, + 0xf4cd65daL, 0xbed50605L, 0x621fd134L, 0xfe8ac4a6L, + 0x539d342eL, 0x55a0a2f3L, 0xe132058aL, 0xeb75a4f6L, + 0xec390b83L, 0xefaa4060L, 0x9f065e71L, 0x1051bd6eL, + 0x8af93e21L, 0x063d96ddL, 0x05aedd3eL, 0xbd464de6L, + 0x8db59154L, 0x5d0571c4L, 0xd46f0406L, 0x15ff6050L, + 0xfb241998L, 0xe997d6bdL, 0x43cc8940L, 0x9e7767d9L, + 0x42bdb0e8L, 0x8b880789L, 0x5b38e719L, 0xeedb79c8L, + 0x0a47a17cL, 0x0fe97c42L, 0x1ec9f884L, 0x00000000L, + 0x86830980L, 0xed48322bL, 0x70ac1e11L, 0x724e6c5aL, + 0xfffbfd0eL, 0x38560f85L, 0xd51e3daeL, 0x3927362dL, + 0xd9640a0fL, 0xa621685cL, 0x54d19b5bL, 0x2e3a2436L, + 0x67b10c0aL, 0xe70f9357L, 0x96d2b4eeL, 0x919e1b9bL, + 0xc54f80c0L, 0x20a261dcL, 0x4b695a77L, 0x1a161c12L, + 0xba0ae293L, 0x2ae5c0a0L, 0xe0433c22L, 0x171d121bL, + 0x0d0b0e09L, 0xc7adf28bL, 0xa8b92db6L, 0xa9c8141eL, + 0x198557f1L, 0x074caf75L, 0xddbbee99L, 0x60fda37fL, + 0x269ff701L, 0xf5bc5c72L, 0x3bc54466L, 0x7e345bfbL, + 0x29768b43L, 0xc6dccb23L, 0xfc68b6edL, 0xf163b8e4L, + 0xdccad731L, 0x85104263L, 0x22401397L, 0x112084c6L, + 0x247d854aL, 0x3df8d2bbL, 0x3211aef9L, 0xa16dc729L, + 0x2f4b1d9eL, 0x30f3dcb2L, 0x52ec0d86L, 0xe3d077c1L, + 0x166c2bb3L, 0xb999a970L, 0x48fa1194L, 0x642247e9L, + 0x8cc4a8fcL, 0x3f1aa0f0L, 0x2cd8567dL, 0x90ef2233L, + 0x4ec78749L, 0xd1c1d938L, 0xa2fe8ccaL, 0x0b3698d4L, + 0x81cfa6f5L, 0xde28a57aL, 0x8e26dab7L, 0xbfa43fadL, + 0x9de42c3aL, 0x920d5078L, 0xcc9b6a5fL, 0x4662547eL, + 0x13c2f68dL, 0xb8e890d8L, 0xf75e2e39L, 0xaff582c3L, + 0x80be9f5dL, 0x937c69d0L, 0x2da96fd5L, 0x12b3cf25L, + 0x993bc8acL, 0x7da71018L, 0x636ee89cL, 0xbb7bdb3bL, + 0x7809cd26L, 0x18f46e59L, 0xb701ec9aL, 0x9aa8834fL, + 0x6e65e695L, 0xe67eaaffL, 0xcf0821bcL, 0xe8e6ef15L, + 0x9bd9bae7L, 0x36ce4a6fL, 0x09d4ea9fL, 0x7cd629b0L, + 0xb2af31a4L, 0x23312a3fL, 0x9430c6a5L, 0x66c035a2L, + 0xbc37744eL, 0xcaa6fc82L, 0xd0b0e090L, 0xd81533a7L, + 0x984af104L, 0xdaf741ecL, 0x500e7fcdL, 0xf62f1791L, + 0xd68d764dL, 0xb04d43efL, 0x4d54ccaaL, 0x04dfe496L, + 0xb5e39ed1L, 0x881b4c6aL, 0x1fb8c12cL, 0x517f4665L, + 0xea049d5eL, 0x355d018cL, 0x7473fa87L, 0x412efb0bL, + 0x1d5ab367L, 0xd25292dbL, 0x5633e910L, 0x47136dd6L, + 0x618c9ad7L, 0x0c7a37a1L, 0x148e59f8L, 0x3c89eb13L, + 0x27eecea9L, 0xc935b761L, 0xe5ede11cL, 0xb13c7a47L, + 0xdf599cd2L, 0x733f55f2L, 0xce791814L, 0x37bf73c7L, + 0xcdea53f7L, 0xaa5b5ffdL, 0x6f14df3dL, 0xdb867844L, + 0xf381caafL, 0xc43eb968L, 0x342c3824L, 0x405fc2a3L, + 0xc372161dL, 0x250cbce2L, 0x498b283cL, 0x9541ff0dL, + 0x017139a8L, 0xb3de080cL, 0xe49cd8b4L, 0xc1906456L, + 0x84617bcbL, 0xb670d532L, 0x5c74486cL, 0x5742d0b8L, +] Td3 = [ - 0xf4a75051L, 0x4165537eL, 0x17a4c31aL, 0x275e963aL, - 0xab6bcb3bL, 0x9d45f11fL, 0xfa58abacL, 0xe303934bL, - 0x30fa5520L, 0x766df6adL, 0xcc769188L, 0x024c25f5L, - 0xe5d7fc4fL, 0x2acbd7c5L, 0x35448026L, 0x62a38fb5L, - 0xb15a49deL, 0xba1b6725L, 0xea0e9845L, 0xfec0e15dL, - 0x2f7502c3L, 0x4cf01281L, 0x4697a38dL, 0xd3f9c66bL, - 0x8f5fe703L, 0x929c9515L, 0x6d7aebbfL, 0x5259da95L, - 0xbe832dd4L, 0x7421d358L, 0xe0692949L, 0xc9c8448eL, - 0xc2896a75L, 0x8e7978f4L, 0x583e6b99L, 0xb971dd27L, - 0xe14fb6beL, 0x88ad17f0L, 0x20ac66c9L, 0xce3ab47dL, - 0xdf4a1863L, 0x1a3182e5L, 0x51336097L, 0x537f4562L, - 0x6477e0b1L, 0x6bae84bbL, 0x81a01cfeL, 0x082b94f9L, - 0x48685870L, 0x45fd198fL, 0xde6c8794L, 0x7bf8b752L, - 0x73d323abL, 0x4b02e272L, 0x1f8f57e3L, 0x55ab2a66L, - 0xeb2807b2L, 0xb5c2032fL, 0xc57b9a86L, 0x3708a5d3L, - 0x2887f230L, 0xbfa5b223L, 0x036aba02L, 0x16825cedL, - 0xcf1c2b8aL, 0x79b492a7L, 0x07f2f0f3L, 0x69e2a14eL, - 0xdaf4cd65L, 0x05bed506L, 0x34621fd1L, 0xa6fe8ac4L, - 0x2e539d34L, 0xf355a0a2L, 0x8ae13205L, 0xf6eb75a4L, - 0x83ec390bL, 0x60efaa40L, 0x719f065eL, 0x6e1051bdL, - 0x218af93eL, 0xdd063d96L, 0x3e05aeddL, 0xe6bd464dL, - 0x548db591L, 0xc45d0571L, 0x06d46f04L, 0x5015ff60L, - 0x98fb2419L, 0xbde997d6L, 0x4043cc89L, 0xd99e7767L, - 0xe842bdb0L, 0x898b8807L, 0x195b38e7L, 0xc8eedb79L, - 0x7c0a47a1L, 0x420fe97cL, 0x841ec9f8L, 0x00000000L, - 0x80868309L, 0x2bed4832L, 0x1170ac1eL, 0x5a724e6cL, - 0x0efffbfdL, 0x8538560fL, 0xaed51e3dL, 0x2d392736L, - 0x0fd9640aL, 0x5ca62168L, 0x5b54d19bL, 0x362e3a24L, - 0x0a67b10cL, 0x57e70f93L, 0xee96d2b4L, 0x9b919e1bL, - 0xc0c54f80L, 0xdc20a261L, 0x774b695aL, 0x121a161cL, - 0x93ba0ae2L, 0xa02ae5c0L, 0x22e0433cL, 0x1b171d12L, - 0x090d0b0eL, 0x8bc7adf2L, 0xb6a8b92dL, 0x1ea9c814L, - 0xf1198557L, 0x75074cafL, 0x99ddbbeeL, 0x7f60fda3L, - 0x01269ff7L, 0x72f5bc5cL, 0x663bc544L, 0xfb7e345bL, - 0x4329768bL, 0x23c6dccbL, 0xedfc68b6L, 0xe4f163b8L, - 0x31dccad7L, 0x63851042L, 0x97224013L, 0xc6112084L, - 0x4a247d85L, 0xbb3df8d2L, 0xf93211aeL, 0x29a16dc7L, - 0x9e2f4b1dL, 0xb230f3dcL, 0x8652ec0dL, 0xc1e3d077L, - 0xb3166c2bL, 0x70b999a9L, 0x9448fa11L, 0xe9642247L, - 0xfc8cc4a8L, 0xf03f1aa0L, 0x7d2cd856L, 0x3390ef22L, - 0x494ec787L, 0x38d1c1d9L, 0xcaa2fe8cL, 0xd40b3698L, - 0xf581cfa6L, 0x7ade28a5L, 0xb78e26daL, 0xadbfa43fL, - 0x3a9de42cL, 0x78920d50L, 0x5fcc9b6aL, 0x7e466254L, - 0x8d13c2f6L, 0xd8b8e890L, 0x39f75e2eL, 0xc3aff582L, - 0x5d80be9fL, 0xd0937c69L, 0xd52da96fL, 0x2512b3cfL, - 0xac993bc8L, 0x187da710L, 0x9c636ee8L, 0x3bbb7bdbL, - 0x267809cdL, 0x5918f46eL, 0x9ab701ecL, 0x4f9aa883L, - 0x956e65e6L, 0xffe67eaaL, 0xbccf0821L, 0x15e8e6efL, - 0xe79bd9baL, 0x6f36ce4aL, 0x9f09d4eaL, 0xb07cd629L, - 0xa4b2af31L, 0x3f23312aL, 0xa59430c6L, 0xa266c035L, - 0x4ebc3774L, 0x82caa6fcL, 0x90d0b0e0L, 0xa7d81533L, - 0x04984af1L, 0xecdaf741L, 0xcd500e7fL, 0x91f62f17L, - 0x4dd68d76L, 0xefb04d43L, 0xaa4d54ccL, 0x9604dfe4L, - 0xd1b5e39eL, 0x6a881b4cL, 0x2c1fb8c1L, 0x65517f46L, - 0x5eea049dL, 0x8c355d01L, 0x877473faL, 0x0b412efbL, - 0x671d5ab3L, 0xdbd25292L, 0x105633e9L, 0xd647136dL, - 0xd7618c9aL, 0xa10c7a37L, 0xf8148e59L, 0x133c89ebL, - 0xa927eeceL, 0x61c935b7L, 0x1ce5ede1L, 0x47b13c7aL, - 0xd2df599cL, 0xf2733f55L, 0x14ce7918L, 0xc737bf73L, - 0xf7cdea53L, 0xfdaa5b5fL, 0x3d6f14dfL, 0x44db8678L, - 0xaff381caL, 0x68c43eb9L, 0x24342c38L, 0xa3405fc2L, - 0x1dc37216L, 0xe2250cbcL, 0x3c498b28L, 0x0d9541ffL, - 0xa8017139L, 0x0cb3de08L, 0xb4e49cd8L, 0x56c19064L, - 0xcb84617bL, 0x32b670d5L, 0x6c5c7448L, 0xb85742d0L, - ] + 0xf4a75051L, 0x4165537eL, 0x17a4c31aL, 0x275e963aL, + 0xab6bcb3bL, 0x9d45f11fL, 0xfa58abacL, 0xe303934bL, + 0x30fa5520L, 0x766df6adL, 0xcc769188L, 0x024c25f5L, + 0xe5d7fc4fL, 0x2acbd7c5L, 0x35448026L, 0x62a38fb5L, + 0xb15a49deL, 0xba1b6725L, 0xea0e9845L, 0xfec0e15dL, + 0x2f7502c3L, 0x4cf01281L, 0x4697a38dL, 0xd3f9c66bL, + 0x8f5fe703L, 0x929c9515L, 0x6d7aebbfL, 0x5259da95L, + 0xbe832dd4L, 0x7421d358L, 0xe0692949L, 0xc9c8448eL, + 0xc2896a75L, 0x8e7978f4L, 0x583e6b99L, 0xb971dd27L, + 0xe14fb6beL, 0x88ad17f0L, 0x20ac66c9L, 0xce3ab47dL, + 0xdf4a1863L, 0x1a3182e5L, 0x51336097L, 0x537f4562L, + 0x6477e0b1L, 0x6bae84bbL, 0x81a01cfeL, 0x082b94f9L, + 0x48685870L, 0x45fd198fL, 0xde6c8794L, 0x7bf8b752L, + 0x73d323abL, 0x4b02e272L, 0x1f8f57e3L, 0x55ab2a66L, + 0xeb2807b2L, 0xb5c2032fL, 0xc57b9a86L, 0x3708a5d3L, + 0x2887f230L, 0xbfa5b223L, 0x036aba02L, 0x16825cedL, + 0xcf1c2b8aL, 0x79b492a7L, 0x07f2f0f3L, 0x69e2a14eL, + 0xdaf4cd65L, 0x05bed506L, 0x34621fd1L, 0xa6fe8ac4L, + 0x2e539d34L, 0xf355a0a2L, 0x8ae13205L, 0xf6eb75a4L, + 0x83ec390bL, 0x60efaa40L, 0x719f065eL, 0x6e1051bdL, + 0x218af93eL, 0xdd063d96L, 0x3e05aeddL, 0xe6bd464dL, + 0x548db591L, 0xc45d0571L, 0x06d46f04L, 0x5015ff60L, + 0x98fb2419L, 0xbde997d6L, 0x4043cc89L, 0xd99e7767L, + 0xe842bdb0L, 0x898b8807L, 0x195b38e7L, 0xc8eedb79L, + 0x7c0a47a1L, 0x420fe97cL, 0x841ec9f8L, 0x00000000L, + 0x80868309L, 0x2bed4832L, 0x1170ac1eL, 0x5a724e6cL, + 0x0efffbfdL, 0x8538560fL, 0xaed51e3dL, 0x2d392736L, + 0x0fd9640aL, 0x5ca62168L, 0x5b54d19bL, 0x362e3a24L, + 0x0a67b10cL, 0x57e70f93L, 0xee96d2b4L, 0x9b919e1bL, + 0xc0c54f80L, 0xdc20a261L, 0x774b695aL, 0x121a161cL, + 0x93ba0ae2L, 0xa02ae5c0L, 0x22e0433cL, 0x1b171d12L, + 0x090d0b0eL, 0x8bc7adf2L, 0xb6a8b92dL, 0x1ea9c814L, + 0xf1198557L, 0x75074cafL, 0x99ddbbeeL, 0x7f60fda3L, + 0x01269ff7L, 0x72f5bc5cL, 0x663bc544L, 0xfb7e345bL, + 0x4329768bL, 0x23c6dccbL, 0xedfc68b6L, 0xe4f163b8L, + 0x31dccad7L, 0x63851042L, 0x97224013L, 0xc6112084L, + 0x4a247d85L, 0xbb3df8d2L, 0xf93211aeL, 0x29a16dc7L, + 0x9e2f4b1dL, 0xb230f3dcL, 0x8652ec0dL, 0xc1e3d077L, + 0xb3166c2bL, 0x70b999a9L, 0x9448fa11L, 0xe9642247L, + 0xfc8cc4a8L, 0xf03f1aa0L, 0x7d2cd856L, 0x3390ef22L, + 0x494ec787L, 0x38d1c1d9L, 0xcaa2fe8cL, 0xd40b3698L, + 0xf581cfa6L, 0x7ade28a5L, 0xb78e26daL, 0xadbfa43fL, + 0x3a9de42cL, 0x78920d50L, 0x5fcc9b6aL, 0x7e466254L, + 0x8d13c2f6L, 0xd8b8e890L, 0x39f75e2eL, 0xc3aff582L, + 0x5d80be9fL, 0xd0937c69L, 0xd52da96fL, 0x2512b3cfL, + 0xac993bc8L, 0x187da710L, 0x9c636ee8L, 0x3bbb7bdbL, + 0x267809cdL, 0x5918f46eL, 0x9ab701ecL, 0x4f9aa883L, + 0x956e65e6L, 0xffe67eaaL, 0xbccf0821L, 0x15e8e6efL, + 0xe79bd9baL, 0x6f36ce4aL, 0x9f09d4eaL, 0xb07cd629L, + 0xa4b2af31L, 0x3f23312aL, 0xa59430c6L, 0xa266c035L, + 0x4ebc3774L, 0x82caa6fcL, 0x90d0b0e0L, 0xa7d81533L, + 0x04984af1L, 0xecdaf741L, 0xcd500e7fL, 0x91f62f17L, + 0x4dd68d76L, 0xefb04d43L, 0xaa4d54ccL, 0x9604dfe4L, + 0xd1b5e39eL, 0x6a881b4cL, 0x2c1fb8c1L, 0x65517f46L, + 0x5eea049dL, 0x8c355d01L, 0x877473faL, 0x0b412efbL, + 0x671d5ab3L, 0xdbd25292L, 0x105633e9L, 0xd647136dL, + 0xd7618c9aL, 0xa10c7a37L, 0xf8148e59L, 0x133c89ebL, + 0xa927eeceL, 0x61c935b7L, 0x1ce5ede1L, 0x47b13c7aL, + 0xd2df599cL, 0xf2733f55L, 0x14ce7918L, 0xc737bf73L, + 0xf7cdea53L, 0xfdaa5b5fL, 0x3d6f14dfL, 0x44db8678L, + 0xaff381caL, 0x68c43eb9L, 0x24342c38L, 0xa3405fc2L, + 0x1dc37216L, 0xe2250cbcL, 0x3c498b28L, 0x0d9541ffL, + 0xa8017139L, 0x0cb3de08L, 0xb4e49cd8L, 0x56c19064L, + 0xcb84617bL, 0x32b670d5L, 0x6c5c7448L, 0xb85742d0L, +] Td4 = [ - 0x52525252L, 0x09090909L, 0x6a6a6a6aL, 0xd5d5d5d5L, - 0x30303030L, 0x36363636L, 0xa5a5a5a5L, 0x38383838L, - 0xbfbfbfbfL, 0x40404040L, 0xa3a3a3a3L, 0x9e9e9e9eL, - 0x81818181L, 0xf3f3f3f3L, 0xd7d7d7d7L, 0xfbfbfbfbL, - 0x7c7c7c7cL, 0xe3e3e3e3L, 0x39393939L, 0x82828282L, - 0x9b9b9b9bL, 0x2f2f2f2fL, 0xffffffffL, 0x87878787L, - 0x34343434L, 0x8e8e8e8eL, 0x43434343L, 0x44444444L, - 0xc4c4c4c4L, 0xdedededeL, 0xe9e9e9e9L, 0xcbcbcbcbL, - 0x54545454L, 0x7b7b7b7bL, 0x94949494L, 0x32323232L, - 0xa6a6a6a6L, 0xc2c2c2c2L, 0x23232323L, 0x3d3d3d3dL, - 0xeeeeeeeeL, 0x4c4c4c4cL, 0x95959595L, 0x0b0b0b0bL, - 0x42424242L, 0xfafafafaL, 0xc3c3c3c3L, 0x4e4e4e4eL, - 0x08080808L, 0x2e2e2e2eL, 0xa1a1a1a1L, 0x66666666L, - 0x28282828L, 0xd9d9d9d9L, 0x24242424L, 0xb2b2b2b2L, - 0x76767676L, 0x5b5b5b5bL, 0xa2a2a2a2L, 0x49494949L, - 0x6d6d6d6dL, 0x8b8b8b8bL, 0xd1d1d1d1L, 0x25252525L, - 0x72727272L, 0xf8f8f8f8L, 0xf6f6f6f6L, 0x64646464L, - 0x86868686L, 0x68686868L, 0x98989898L, 0x16161616L, - 0xd4d4d4d4L, 0xa4a4a4a4L, 0x5c5c5c5cL, 0xccccccccL, - 0x5d5d5d5dL, 0x65656565L, 0xb6b6b6b6L, 0x92929292L, - 0x6c6c6c6cL, 0x70707070L, 0x48484848L, 0x50505050L, - 0xfdfdfdfdL, 0xededededL, 0xb9b9b9b9L, 0xdadadadaL, - 0x5e5e5e5eL, 0x15151515L, 0x46464646L, 0x57575757L, - 0xa7a7a7a7L, 0x8d8d8d8dL, 0x9d9d9d9dL, 0x84848484L, - 0x90909090L, 0xd8d8d8d8L, 0xababababL, 0x00000000L, - 0x8c8c8c8cL, 0xbcbcbcbcL, 0xd3d3d3d3L, 0x0a0a0a0aL, - 0xf7f7f7f7L, 0xe4e4e4e4L, 0x58585858L, 0x05050505L, - 0xb8b8b8b8L, 0xb3b3b3b3L, 0x45454545L, 0x06060606L, - 0xd0d0d0d0L, 0x2c2c2c2cL, 0x1e1e1e1eL, 0x8f8f8f8fL, - 0xcacacacaL, 0x3f3f3f3fL, 0x0f0f0f0fL, 0x02020202L, - 0xc1c1c1c1L, 0xafafafafL, 0xbdbdbdbdL, 0x03030303L, - 0x01010101L, 0x13131313L, 0x8a8a8a8aL, 0x6b6b6b6bL, - 0x3a3a3a3aL, 0x91919191L, 0x11111111L, 0x41414141L, - 0x4f4f4f4fL, 0x67676767L, 0xdcdcdcdcL, 0xeaeaeaeaL, - 0x97979797L, 0xf2f2f2f2L, 0xcfcfcfcfL, 0xcecececeL, - 0xf0f0f0f0L, 0xb4b4b4b4L, 0xe6e6e6e6L, 0x73737373L, - 0x96969696L, 0xacacacacL, 0x74747474L, 0x22222222L, - 0xe7e7e7e7L, 0xadadadadL, 0x35353535L, 0x85858585L, - 0xe2e2e2e2L, 0xf9f9f9f9L, 0x37373737L, 0xe8e8e8e8L, - 0x1c1c1c1cL, 0x75757575L, 0xdfdfdfdfL, 0x6e6e6e6eL, - 0x47474747L, 0xf1f1f1f1L, 0x1a1a1a1aL, 0x71717171L, - 0x1d1d1d1dL, 0x29292929L, 0xc5c5c5c5L, 0x89898989L, - 0x6f6f6f6fL, 0xb7b7b7b7L, 0x62626262L, 0x0e0e0e0eL, - 0xaaaaaaaaL, 0x18181818L, 0xbebebebeL, 0x1b1b1b1bL, - 0xfcfcfcfcL, 0x56565656L, 0x3e3e3e3eL, 0x4b4b4b4bL, - 0xc6c6c6c6L, 0xd2d2d2d2L, 0x79797979L, 0x20202020L, - 0x9a9a9a9aL, 0xdbdbdbdbL, 0xc0c0c0c0L, 0xfefefefeL, - 0x78787878L, 0xcdcdcdcdL, 0x5a5a5a5aL, 0xf4f4f4f4L, - 0x1f1f1f1fL, 0xddddddddL, 0xa8a8a8a8L, 0x33333333L, - 0x88888888L, 0x07070707L, 0xc7c7c7c7L, 0x31313131L, - 0xb1b1b1b1L, 0x12121212L, 0x10101010L, 0x59595959L, - 0x27272727L, 0x80808080L, 0xececececL, 0x5f5f5f5fL, - 0x60606060L, 0x51515151L, 0x7f7f7f7fL, 0xa9a9a9a9L, - 0x19191919L, 0xb5b5b5b5L, 0x4a4a4a4aL, 0x0d0d0d0dL, - 0x2d2d2d2dL, 0xe5e5e5e5L, 0x7a7a7a7aL, 0x9f9f9f9fL, - 0x93939393L, 0xc9c9c9c9L, 0x9c9c9c9cL, 0xefefefefL, - 0xa0a0a0a0L, 0xe0e0e0e0L, 0x3b3b3b3bL, 0x4d4d4d4dL, - 0xaeaeaeaeL, 0x2a2a2a2aL, 0xf5f5f5f5L, 0xb0b0b0b0L, - 0xc8c8c8c8L, 0xebebebebL, 0xbbbbbbbbL, 0x3c3c3c3cL, - 0x83838383L, 0x53535353L, 0x99999999L, 0x61616161L, - 0x17171717L, 0x2b2b2b2bL, 0x04040404L, 0x7e7e7e7eL, - 0xbabababaL, 0x77777777L, 0xd6d6d6d6L, 0x26262626L, - 0xe1e1e1e1L, 0x69696969L, 0x14141414L, 0x63636363L, - 0x55555555L, 0x21212121L, 0x0c0c0c0cL, 0x7d7d7d7dL, - ] + 0x52525252L, 0x09090909L, 0x6a6a6a6aL, 0xd5d5d5d5L, + 0x30303030L, 0x36363636L, 0xa5a5a5a5L, 0x38383838L, + 0xbfbfbfbfL, 0x40404040L, 0xa3a3a3a3L, 0x9e9e9e9eL, + 0x81818181L, 0xf3f3f3f3L, 0xd7d7d7d7L, 0xfbfbfbfbL, + 0x7c7c7c7cL, 0xe3e3e3e3L, 0x39393939L, 0x82828282L, + 0x9b9b9b9bL, 0x2f2f2f2fL, 0xffffffffL, 0x87878787L, + 0x34343434L, 0x8e8e8e8eL, 0x43434343L, 0x44444444L, + 0xc4c4c4c4L, 0xdedededeL, 0xe9e9e9e9L, 0xcbcbcbcbL, + 0x54545454L, 0x7b7b7b7bL, 0x94949494L, 0x32323232L, + 0xa6a6a6a6L, 0xc2c2c2c2L, 0x23232323L, 0x3d3d3d3dL, + 0xeeeeeeeeL, 0x4c4c4c4cL, 0x95959595L, 0x0b0b0b0bL, + 0x42424242L, 0xfafafafaL, 0xc3c3c3c3L, 0x4e4e4e4eL, + 0x08080808L, 0x2e2e2e2eL, 0xa1a1a1a1L, 0x66666666L, + 0x28282828L, 0xd9d9d9d9L, 0x24242424L, 0xb2b2b2b2L, + 0x76767676L, 0x5b5b5b5bL, 0xa2a2a2a2L, 0x49494949L, + 0x6d6d6d6dL, 0x8b8b8b8bL, 0xd1d1d1d1L, 0x25252525L, + 0x72727272L, 0xf8f8f8f8L, 0xf6f6f6f6L, 0x64646464L, + 0x86868686L, 0x68686868L, 0x98989898L, 0x16161616L, + 0xd4d4d4d4L, 0xa4a4a4a4L, 0x5c5c5c5cL, 0xccccccccL, + 0x5d5d5d5dL, 0x65656565L, 0xb6b6b6b6L, 0x92929292L, + 0x6c6c6c6cL, 0x70707070L, 0x48484848L, 0x50505050L, + 0xfdfdfdfdL, 0xededededL, 0xb9b9b9b9L, 0xdadadadaL, + 0x5e5e5e5eL, 0x15151515L, 0x46464646L, 0x57575757L, + 0xa7a7a7a7L, 0x8d8d8d8dL, 0x9d9d9d9dL, 0x84848484L, + 0x90909090L, 0xd8d8d8d8L, 0xababababL, 0x00000000L, + 0x8c8c8c8cL, 0xbcbcbcbcL, 0xd3d3d3d3L, 0x0a0a0a0aL, + 0xf7f7f7f7L, 0xe4e4e4e4L, 0x58585858L, 0x05050505L, + 0xb8b8b8b8L, 0xb3b3b3b3L, 0x45454545L, 0x06060606L, + 0xd0d0d0d0L, 0x2c2c2c2cL, 0x1e1e1e1eL, 0x8f8f8f8fL, + 0xcacacacaL, 0x3f3f3f3fL, 0x0f0f0f0fL, 0x02020202L, + 0xc1c1c1c1L, 0xafafafafL, 0xbdbdbdbdL, 0x03030303L, + 0x01010101L, 0x13131313L, 0x8a8a8a8aL, 0x6b6b6b6bL, + 0x3a3a3a3aL, 0x91919191L, 0x11111111L, 0x41414141L, + 0x4f4f4f4fL, 0x67676767L, 0xdcdcdcdcL, 0xeaeaeaeaL, + 0x97979797L, 0xf2f2f2f2L, 0xcfcfcfcfL, 0xcecececeL, + 0xf0f0f0f0L, 0xb4b4b4b4L, 0xe6e6e6e6L, 0x73737373L, + 0x96969696L, 0xacacacacL, 0x74747474L, 0x22222222L, + 0xe7e7e7e7L, 0xadadadadL, 0x35353535L, 0x85858585L, + 0xe2e2e2e2L, 0xf9f9f9f9L, 0x37373737L, 0xe8e8e8e8L, + 0x1c1c1c1cL, 0x75757575L, 0xdfdfdfdfL, 0x6e6e6e6eL, + 0x47474747L, 0xf1f1f1f1L, 0x1a1a1a1aL, 0x71717171L, + 0x1d1d1d1dL, 0x29292929L, 0xc5c5c5c5L, 0x89898989L, + 0x6f6f6f6fL, 0xb7b7b7b7L, 0x62626262L, 0x0e0e0e0eL, + 0xaaaaaaaaL, 0x18181818L, 0xbebebebeL, 0x1b1b1b1bL, + 0xfcfcfcfcL, 0x56565656L, 0x3e3e3e3eL, 0x4b4b4b4bL, + 0xc6c6c6c6L, 0xd2d2d2d2L, 0x79797979L, 0x20202020L, + 0x9a9a9a9aL, 0xdbdbdbdbL, 0xc0c0c0c0L, 0xfefefefeL, + 0x78787878L, 0xcdcdcdcdL, 0x5a5a5a5aL, 0xf4f4f4f4L, + 0x1f1f1f1fL, 0xddddddddL, 0xa8a8a8a8L, 0x33333333L, + 0x88888888L, 0x07070707L, 0xc7c7c7c7L, 0x31313131L, + 0xb1b1b1b1L, 0x12121212L, 0x10101010L, 0x59595959L, + 0x27272727L, 0x80808080L, 0xececececL, 0x5f5f5f5fL, + 0x60606060L, 0x51515151L, 0x7f7f7f7fL, 0xa9a9a9a9L, + 0x19191919L, 0xb5b5b5b5L, 0x4a4a4a4aL, 0x0d0d0d0dL, + 0x2d2d2d2dL, 0xe5e5e5e5L, 0x7a7a7a7aL, 0x9f9f9f9fL, + 0x93939393L, 0xc9c9c9c9L, 0x9c9c9c9cL, 0xefefefefL, + 0xa0a0a0a0L, 0xe0e0e0e0L, 0x3b3b3b3bL, 0x4d4d4d4dL, + 0xaeaeaeaeL, 0x2a2a2a2aL, 0xf5f5f5f5L, 0xb0b0b0b0L, + 0xc8c8c8c8L, 0xebebebebL, 0xbbbbbbbbL, 0x3c3c3c3cL, + 0x83838383L, 0x53535353L, 0x99999999L, 0x61616161L, + 0x17171717L, 0x2b2b2b2bL, 0x04040404L, 0x7e7e7e7eL, + 0xbabababaL, 0x77777777L, 0xd6d6d6d6L, 0x26262626L, + 0xe1e1e1e1L, 0x69696969L, 0x14141414L, 0x63636363L, + 0x55555555L, 0x21212121L, 0x0c0c0c0cL, 0x7d7d7d7dL, +] rcon = [ - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, - # 128-bit blocks, Rijndael never uses more than 10 rcon values - ] + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, + # 128-bit blocks, Rijndael never uses more than 10 rcon values +] if len(struct.pack('L',0)) == 4: # 32bit @@ -703,6 +710,7 @@ def GETU32(x): return struct.unpack('>I', x)[0] def PUTU32(x): return struct.pack('>I', x) + # Expand the cipher key into the encryption key schedule. # # @return the number of rounds for the given cipher key size. @@ -1051,6 +1059,7 @@ assert len(ciphertext) == 16 return rijndaelDecrypt(self.rk, self.nrounds, ciphertext) + # encrypt(key, fin, fout, keybits=256) class RijndaelEncryptor(object): @@ -1060,7 +1069,7 @@ >>> RijndaelEncryptor(key, 128).encrypt(plaintext).encode('hex') 'd8f532538289ef7d06b506a4fd5be9c9' """ - + def __init__(self, key, keybits=256): assert len(key) == KEYLENGTH(keybits) (self.rk, self.nrounds) = rijndaelSetupEncrypt(key, keybits) diff -Nru pdfminer-20110515+dfsg/pdfminer/runlength.py pdfminer-20140328+dfsg/pdfminer/runlength.py --- pdfminer-20110515+dfsg/pdfminer/runlength.py 2010-10-19 09:55:59.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/runlength.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # # RunLength decoder (Adobe version) implementation based on PDF Reference # version 1.4 section 3.3.4. @@ -6,8 +6,6 @@ # * public domain * # -import sys - def rldecode(data): """ RunLength decoder (Adobe version) implementation based on PDF Reference @@ -26,7 +24,7 @@ '1234567777777abcde' """ decoded = [] - i=0 + i = 0 while i < len(data): #print "data[%d]=:%d:" % (i,ord(data[i])) length = ord(data[i]) diff -Nru pdfminer-20110515+dfsg/pdfminer/utils.py pdfminer-20140328+dfsg/pdfminer/utils.py --- pdfminer-20110515+dfsg/pdfminer/utils.py 2011-05-14 16:18:58.000000000 +0000 +++ pdfminer-20140328+dfsg/pdfminer/utils.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Miscellaneous Routines. """ @@ -6,25 +6,72 @@ from sys import maxint as INF +## PNG Predictor +## +def apply_png_predictor(pred, colors, columns, bitspercomponent, data): + if bitspercomponent != 8: + # unsupported + raise ValueError(bitspercomponent) + nbytes = colors*columns*bitspercomponent//8 + i = 0 + buf = '' + line0 = '\x00' * columns + for i in xrange(0, len(data), nbytes+1): + ft = data[i] + i += 1 + line1 = data[i:i+nbytes] + line2 = '' + if ft == '\x00': + # PNG none + line2 += line1 + elif ft == '\x01': + # PNG sub (UNTESTED) + c = 0 + for b in line1: + c = (c+ord(b)) & 255 + line2 += chr(c) + elif ft == '\x02': + # PNG up + for (a, b) in zip(line0, line1): + c = (ord(a)+ord(b)) & 255 + line2 += chr(c) + elif ft == '\x03': + # PNG average (UNTESTED) + c = 0 + for (a, b) in zip(line0, line1): + c = ((c+ord(a)+ord(b))//2) & 255 + line2 += chr(c) + else: + # unsupported + raise ValueError(ft) + buf += line2 + line0 = line2 + return buf + + ## Matrix operations ## MATRIX_IDENTITY = (1, 0, 0, 1, 0, 0) -def mult_matrix((a1,b1,c1,d1,e1,f1), (a0,b0,c0,d0,e0,f0)): + +def mult_matrix((a1, b1, c1, d1, e1, f1), (a0, b0, c0, d0, e0, f0)): """Returns the multiplication of two matrices.""" return (a0*a1+c0*b1, b0*a1+d0*b1, a0*c1+c0*d1, b0*c1+d0*d1, a0*e1+c0*f1+e0, b0*e1+d0*f1+f0) -def translate_matrix((a,b,c,d,e,f), (x,y)): - """Translates a matrix by (x,y).""" - return (a,b,c,d,x*a+y*c+e,x*b+y*d+f) -def apply_matrix_pt((a,b,c,d,e,f), (x,y)): +def translate_matrix((a, b, c, d, e, f), (x, y)): + """Translates a matrix by (x, y).""" + return (a, b, c, d, x*a+y*c+e, x*b+y*d+f) + + +def apply_matrix_pt((a, b, c, d, e, f), (x, y)): """Applies a matrix to a point.""" return (a*x+c*y+e, b*x+d*y+f) -def apply_matrix_norm((a,b,c,d,e,f), (p,q)): + +def apply_matrix_norm((a, b, c, d, e, f), (p, q)): """Equivalent to apply_matrix_pt(M, (p,q)) - apply_matrix_pt(M, (0,0))""" return (a*p+c*q, b*p+d*q) @@ -32,22 +79,29 @@ ## Utility functions ## +# isnumber +def isnumber(x): + return isinstance(x, (int, long, float)) + # uniq def uniq(objs): """Eliminates duplicated elements.""" done = set() for obj in objs: - if obj in done: continue + if obj in done: + continue done.add(obj) yield obj return + # csort -def csort(objs, key=lambda x:x): +def csort(objs, key=lambda x: x): """Order-preserving sorting function.""" - idxs = dict( (obj,i) for (i,obj) in enumerate(objs) ) + idxs = dict((obj, i) for (i, obj) in enumerate(objs)) return sorted(objs, key=lambda obj: (key(obj), idxs[obj])) + # fsplit def fsplit(pred, objs): """Split a list into two classes according to the predicate.""" @@ -58,24 +112,27 @@ t.append(obj) else: f.append(obj) - return (t,f) + return (t, f) + # drange def drange(v0, v1, d): """Returns a discrete range.""" assert v0 < v1 - return xrange(int(v0)/d, int(v1+d-1)/d) + return xrange(int(v0)//d, int(v1+d)//d) + # get_bound def get_bound(pts): """Compute a minimal rectangle that covers all the points.""" (x0, y0, x1, y1) = (INF, INF, -INF, -INF) - for (x,y) in pts: + for (x, y) in pts: x0 = min(x0, x) y0 = min(y0, y) x1 = max(x1, x) y1 = max(y1, y) - return (x0,y0,x1,y1) + return (x0, y0, x1, y1) + # pick def pick(seq, func, maxobj=None): @@ -84,9 +141,10 @@ for obj in seq: score = func(obj) if maxscore is None or maxscore < score: - (maxscore,maxobj) = (score,obj) + (maxscore, maxobj) = (score, obj) return maxobj + # choplist def choplist(n, seq): """Groups every n elements of the list.""" @@ -98,6 +156,7 @@ r = [] return + # nunpack def nunpack(s, default=0): """Unpacks 1 to 4 byte integers (big endian).""" @@ -115,83 +174,65 @@ else: raise TypeError('invalid length: %d' % l) + # decode_text -PDFDocEncoding = ''.join( unichr(x) for x in ( - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0017, 0x0017, - 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, - 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, - 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, - 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, - 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, - 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, - 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, - 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, - 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, - 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, - 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, - 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, - 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, - 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, - 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, - 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, +PDFDocEncoding = ''.join(unichr(x) for x in ( + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0017, 0x0017, + 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, + 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, + 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, + 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, + 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, + 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, )) + + def decode_text(s): """Decodes a PDFDocEncoding string to Unicode.""" if s.startswith('\xfe\xff'): return unicode(s[2:], 'utf-16be', 'ignore') else: - return ''.join( PDFDocEncoding[ord(c)] for c in s ) + return ''.join(PDFDocEncoding[ord(c)] for c in s) + # enc def enc(x, codec='ascii'): """Encodes a string for SGML/XML/HTML""" - x = x.replace('&','&').replace('>','>').replace('<','<').replace('"','"') + x = x.replace('&', '&').replace('>', '>').replace('<', '<').replace('"', '"') return x.encode(codec, 'xmlcharrefreplace') -def bbox2str((x0,y0,x1,y1)): - return '%.3f,%.3f,%.3f,%.3f' % (x0, y0, x1, y1) - -def matrix2str((a,b,c,d,e,f)): - return '[%.2f,%.2f,%.2f,%.2f, (%.2f,%.2f)]' % (a,b,c,d,e,f) - - -## ObjIdRange -## -class ObjIdRange(object): - - "A utility class to represent a range of object IDs." - - def __init__(self, start, nobjs): - self.start = start - self.nobjs = nobjs - return - - def __repr__(self): - return '' % (self.get_start_id(), self.get_end_id()) - def get_start_id(self): - return self.start +def bbox2str((x0, y0, x1, y1)): + return '%.3f,%.3f,%.3f,%.3f' % (x0, y0, x1, y1) - def get_end_id(self): - return self.start + self.nobjs - 1 - def get_nobjs(self): - return self.nobjs +def matrix2str((a, b, c, d, e, f)): + return '[%.2f,%.2f,%.2f,%.2f, (%.2f,%.2f)]' % (a, b, c, d, e, f) ## Plane @@ -203,13 +244,11 @@ ## class Plane(object): - def __init__(self, objs=None, gridsize=50): - self._objs = [] + def __init__(self, bbox, gridsize=50): + self._objs = set() self._grid = {} self.gridsize = gridsize - if objs is not None: - for obj in objs: - self.add(obj) + (self.x0, self.y0, self.x1, self.y1) = bbox return def __repr__(self): @@ -224,12 +263,24 @@ def __contains__(self, obj): return obj in self._objs - def _getrange(self, (x0,y0,x1,y1)): + def _getrange(self, (x0, y0, x1, y1)): + if (x1 <= self.x0 or self.x1 <= x0 or + y1 <= self.y0 or self.y1 <= y0): return + x0 = max(self.x0, x0) + y0 = max(self.y0, y0) + x1 = min(self.x1, x1) + y1 = min(self.y1, y1) for y in drange(y0, y1, self.gridsize): for x in drange(x0, x1, self.gridsize): - yield (x,y) + yield (x, y) + return + + # extend(objs) + def extend(self, objs): + for obj in objs: + self.add(obj) return - + # add(obj): place an object. def add(self, obj): for k in self._getrange((obj.x0, obj.y0, obj.x1, obj.y1)): @@ -239,7 +290,7 @@ else: r = self._grid[k] r.append(obj) - self._objs.append(obj) + self._objs.add(obj) return # remove(obj): displace an object. @@ -253,24 +304,17 @@ return # find(): finds objects that are in a certain area. - def find(self, (x0,y0,x1,y1)): + def find(self, (x0, y0, x1, y1)): done = set() - for k in self._getrange((x0,y0,x1,y1)): - if k not in self._grid: continue + for k in self._getrange((x0, y0, x1, y1)): + if k not in self._grid: + continue for obj in self._grid[k]: - if obj in done: continue + if obj in done: + continue done.add(obj) if (obj.x1 <= x0 or x1 <= obj.x0 or - obj.y1 <= y0 or y1 <= obj.y0): continue + obj.y1 <= y0 or y1 <= obj.y0): + continue yield obj return - - -# create_bmp -def create_bmp(data, bits, width, height): - info = struct.pack(' -
      序 -
      -
    わたくしといふ現象は +
      序 +
      +
    わたくしといふ現象は
    假定された有機交流電燈の
    ひとつの青い照明です
    (あらゆる透明な幽霊の複合体) @@ -30,12 +30,12 @@
    それぞれ新鮮な本体論もかんがへませうが
    それらも畢竟こゝろのひとつの風物です
    たゞたしかに記録されたこれらのけしきは -
    記録されたそのとほりのこのけしきで -
    それが虚無ならば虚無自身がこのとほりで +
    記録されたそのとほりのこのけしきで +
    それが虚無ならば虚無自身がこのとほりで
    ある程度まではみんなに共通いたします -
    (すべてがわたくしの中のみんなであるやうに -
     みんなのおのおののなかのすべてですから) -
    けれどもこれら新世代沖積世の +
    (すべてがわたくしの中のみんなであるやうに +
     みんなのおのおののなかのすべてですから) +
    けれどもこれら新世代沖積世の
    巨大に明るい時間の集積のなかで
    正しくうつされた筈のこれらのことばが
    わづかその一點にも均しい明暗のうちに @@ -58,15 +58,15 @@
    青ぞらいっぱいの無色な孔雀が居たとおもひ
    新進の大學士たちは気圏のいちばんの上層
    きらびやかな氷窒素のあたりから -
    すてきな化石を發堀したり -
    あるひは白堊紀砂岩の層面に +
    すてきな化石を發堀したり +
    あるひは白堊紀砂岩の層面に
    透明な人類の巨大な足跡を -
    発見するかもしれません -
       -
    すべてこれらの命題は -
    心象や時間それ自身の性質として -
    第四次延長のなかで主張されます -
       -
    大正十三年一月廿日  宮澤賢治 +
    発見するかもしれません +
       +
    すべてこれらの命題は +
    心象や時間それ自身の性質として +
    第四次延長のなかで主張されます +
       +
    大正十三年一月廿日  宮澤賢治
    Page: 1
    diff -Nru pdfminer-20110515+dfsg/samples/simple1.html.ref pdfminer-20140328+dfsg/samples/simple1.html.ref --- pdfminer-20110515+dfsg/samples/simple1.html.ref 2011-05-14 16:19:53.000000000 +0000 +++ pdfminer-20140328+dfsg/samples/simple1.html.ref 2015-10-11 18:33:29.000000000 +0000 @@ -3,13 +3,13 @@ -
    Hello -
    World -
    Hello -
    World -
    H e l l o -
    W o r l d -
    H e l l o -
    W o r l d +
    Hello +
    World +
    Hello +
    World +
    H e l l o +
    W o r l d +
    H e l l o +
    W o r l d
    Page: 1
    diff -Nru pdfminer-20110515+dfsg/samples/simple3.html.ref pdfminer-20140328+dfsg/samples/simple3.html.ref --- pdfminer-20110515+dfsg/samples/simple3.html.ref 2011-05-14 16:19:53.000000000 +0000 +++ pdfminer-20140328+dfsg/samples/simple3.html.ref 2015-10-11 18:33:29.000000000 +0000 @@ -3,9 +3,9 @@ -
    World -
    orld -
    あいうえおあいうえお W -
    HelloHello +
    World +
    orld +
    あいうえおあいうえお W +
    HelloHello
    Page: 1
    diff -Nru pdfminer-20110515+dfsg/setup.py pdfminer-20140328+dfsg/setup.py --- pdfminer-20110515+dfsg/setup.py 2010-10-19 09:54:29.000000000 +0000 +++ pdfminer-20140328+dfsg/setup.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python from distutils.core import setup from pdfminer import __version__ @@ -7,9 +7,9 @@ version=__version__, description='PDF parser and analyzer', long_description='''PDFMiner is a tool for extracting information from PDF documents. -Unlike other PDF-related tools, it focuses entirely on getting +Unlike other PDF-related tools, it focuses entirely on getting and analyzing text data. PDFMiner allows to obtain -the exact location of texts in a page, as well as +the exact location of texts in a page, as well as other information such as fonts or lines. It includes a PDF converter that can transform PDF files into other text formats (such as HTML). It has an extensible @@ -17,13 +17,12 @@ license='MIT/X', author='Yusuke Shinyama', author_email='yusuke at cs dot nyu dot edu', - url='http://www.unixuser.org/~euske/python/pdfminer/index.html', + url='http://euske.github.io/pdfminer/index.html', packages=[ 'pdfminer', - 'pdfminer.cmap', ], package_data={ - 'pdfminer.cmap': ['*.pickle.gz'], + 'pdfminer': ['cmap/*.pickle.gz'] }, scripts=[ 'tools/pdf2txt.py', diff -Nru pdfminer-20110515+dfsg/tools/conv_afm.py pdfminer-20140328+dfsg/tools/conv_afm.py --- pdfminer-20110515+dfsg/tools/conv_afm.py 2010-10-19 09:53:35.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/conv_afm.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys import fileinput diff -Nru pdfminer-20110515+dfsg/tools/conv_cmap.py pdfminer-20140328+dfsg/tools/conv_cmap.py --- pdfminer-20110515+dfsg/tools/conv_cmap.py 2010-10-19 09:53:37.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/conv_cmap.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,156 +1,195 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys -import os.path -import gzip import cPickle as pickle -def process_cid2code(fp, check_codecs=[]): - def get_canonicals(name): - if name.endswith('-H'): - return (name, None) - elif name == 'H': - return ('H', 'V') +## CMapConverter +## +class CMapConverter(object): + + def __init__(self, enc2codec={}): + self.enc2codec = enc2codec + self.code2cid = {} # {'cmapname': ...} + self.is_vertical = {} + self.cid2unichr_h = {} # {cid: unichr} + self.cid2unichr_v = {} # {cid: unichr} + return + + def get_encs(self): + return self.code2cid.keys() + + def get_maps(self, enc): + if enc.endswith('-H'): + (hmapenc, vmapenc) = (enc, None) + elif enc == 'H': + (hmapenc, vmapenc) = ('H', 'V') + else: + (hmapenc, vmapenc) = (enc+'-H', enc+'-V') + if hmapenc in self.code2cid: + hmap = self.code2cid[hmapenc] else: - return (name+'-H', name+'-V') + hmap = {} + self.code2cid[hmapenc] = hmap + vmap = None + if vmapenc: + self.is_vertical[vmapenc] = True + if vmapenc in self.code2cid: + vmap = self.code2cid[vmapenc] + else: + vmap = {} + self.code2cid[vmapenc] = vmap + return (hmap, vmap) + + def load(self, fp): + encs = None + for line in fp: + (line,_,_) = line.strip().partition('#') + if not line: continue + values = line.split('\t') + if encs is None: + assert values[0] == 'CID' + encs = values + continue + + def put(dmap, code, cid, force=False): + for b in code[:-1]: + b = ord(b) + if b in dmap: + dmap = dmap[b] + else: + d = {} + dmap[b] = d + dmap = d + b = ord(code[-1]) + if force or ((b not in dmap) or dmap[b] == cid): + dmap[b] = cid + return - def get_unichr(codes): - # determine the "most popular" candidate. - d = {} - for code in codes: - char = unicode(code, 'utf-8') - if char not in d: - d[char] = 0 - for codec in check_codecs: + def add(unimap, enc, code): try: - char.encode(codec, 'strict') - d[char] += 1 + codec = self.enc2codec[enc] + c = code.decode(codec, 'strict') + if len(c) == 1: + if c not in unimap: + unimap[c] = 0 + unimap[c] += 1 + except KeyError: + pass except UnicodeError: pass - chars = sorted(d.keys(), key=lambda char:d[char], reverse=True) - return chars[0] + return + + def pick(unimap): + chars = unimap.items() + chars.sort(key=(lambda (c,n):(n,-ord(c))), reverse=True) + (c,_) = chars[0] + return c + + cid = int(values[0]) + unimap_h = {} + unimap_v = {} + for (enc,value) in zip(encs, values): + if enc == 'CID': continue + if value == '*': continue + + # hcodes, vcodes: encoded bytes for each writing mode. + hcodes = [] + vcodes = [] + for code in value.split(','): + vertical = code.endswith('v') + if vertical: + code = code[:-1] + try: + code = code.decode('hex') + except: + code = chr(int(code, 16)) + if vertical: + vcodes.append(code) + add(unimap_v, enc, code) + else: + hcodes.append(code) + add(unimap_h, enc, code) + # add cid to each map. + (hmap, vmap) = self.get_maps(enc) + if vcodes: + assert vmap is not None + for code in vcodes: + put(vmap, code, cid, True) + for code in hcodes: + put(hmap, code, cid, True) + else: + for code in hcodes: + put(hmap, code, cid) + put(vmap, code, cid) + + # Determine the "most popular" candidate. + if unimap_h: + self.cid2unichr_h[cid] = pick(unimap_h) + if unimap_v or unimap_h: + self.cid2unichr_v[cid] = pick(unimap_v or unimap_h) - def put(dmap, code, cid, force=False): - for b in code[:-1]: - b = ord(b) - if b in dmap: - dmap = dmap[b] - else: - d = {} - dmap[b] = d - dmap = d - b = ord(code[-1]) - if force or ((b not in dmap) or dmap[b] == cid): - dmap[b] = cid return - names = [] - code2cid = {} # {'cmapname': ...} - is_vertical = {} - cid2unichr_h = {} # {cid: unichr} - cid2unichr_v = {} # {cid: unichr} - - for line in fp: - line = line.strip() - if line.startswith('#'): continue - if line.startswith('CID'): - names = line.split('\t')[1:] - continue - f = line.split('\t') - if not f: continue - cid = int(f[0]) - for (x,name) in zip(f[1:], names): - if x == '*': continue - (hmapname, vmapname) = get_canonicals(name) - if hmapname in code2cid: - hmap = code2cid[hmapname] - else: - hmap = {} - code2cid[hmapname] = hmap - vmap = None - if vmapname: - is_vertical[vmapname] = True - if vmapname in code2cid: - vmap = code2cid[vmapname] - else: - vmap = {} - code2cid[vmapname] = vmap - hcodes = [] - vcodes = [] - for code in x.split(','): - vertical = code.endswith('v') - if vertical: - code = code[:-1] - try: - code = code.decode('hex') - except: - code = chr(int(code, 16)) - if vertical: - vcodes.append(code) - else: - hcodes.append(code) - if vcodes: - assert vmap is not None - for code in vcodes: - put(vmap, code, cid, True) - for code in hcodes: - put(hmap, code, cid, True) - if name.endswith('-UTF8'): - if hcodes: - cid2unichr_h[cid] = get_unichr(hcodes) - if vcodes: - cid2unichr_v[cid] = get_unichr(vcodes) - else: - for code in hcodes: - put(hmap, code, cid) - put(vmap, code, cid) - if name.endswith('-UTF8') and hcodes: - code = get_unichr(hcodes) - if cid not in cid2unichr_h: - cid2unichr_h[cid] = code - if cid not in cid2unichr_v: - cid2unichr_v[cid] = code + def dump_cmap(self, fp, enc): + data = dict( + IS_VERTICAL=self.is_vertical.get(enc, False), + CODE2CID=self.code2cid.get(enc), + ) + fp.write(pickle.dumps(data)) + return - return (code2cid, is_vertical, cid2unichr_h, cid2unichr_v) + def dump_unicodemap(self, fp): + data = dict( + CID2UNICHR_H=self.cid2unichr_h, + CID2UNICHR_V=self.cid2unichr_v, + ) + fp.write(pickle.dumps(data)) + return # main def main(argv): + import getopt + import gzip + import os.path def usage(): - print 'usage: %s output_dir regname cid2code.txt codecs ...' % argv[0] + print 'usage: %s [-c enc=codec] output_dir regname [cid2code.txt ...]' % argv[0] return 100 - - args = argv[1:] - if len(args) < 3: return usage() - (outdir, regname, src) = args[:3] - check_codecs = args[3:] - - print >>sys.stderr, 'reading %r...' % src - fp = file(src) - (code2cid, is_vertical, cid2unichr_h, cid2unichr_v) = process_cid2code(fp, check_codecs) - fp.close() + try: + (opts, args) = getopt.getopt(argv[1:], 'c:') + except getopt.GetoptError: + return usage() + enc2codec = {} + for (k, v) in opts: + if k == '-c': + (enc,_,codec) = v.partition('=') + enc2codec[enc] = codec + if not args: return usage() + outdir = args.pop(0) + if not args: return usage() + regname = args.pop(0) + + converter = CMapConverter(enc2codec) + for path in args: + print >>sys.stderr, 'reading: %r...' % path + fp = file(path) + converter.load(fp) + fp.close() - for (name, cmap) in code2cid.iteritems(): - fname = '%s.pickle.gz' % name - print >>sys.stderr, 'writing %r...' % fname - fp = gzip.open(os.path.join(outdir, fname), 'wb') - data = dict( - IS_VERTICAL=is_vertical.get(name, False), - CODE2CID=cmap, - ) - fp.write(pickle.dumps(data)) + for enc in converter.get_encs(): + fname = '%s.pickle.gz' % enc + path = os.path.join(outdir, fname) + print >>sys.stderr, 'writing: %r...' % path + fp = gzip.open(path, 'wb') + converter.dump_cmap(fp, enc) fp.close() fname = 'to-unicode-%s.pickle.gz' % regname - print >>sys.stderr, 'writing %r...' % fname - fp = gzip.open(os.path.join(outdir, fname), 'wb') - data = dict( - CID2UNICHR_H=cid2unichr_h, - CID2UNICHR_V=cid2unichr_v, - ) - fp.write(pickle.dumps(data)) + path = os.path.join(outdir, fname) + print >>sys.stderr, 'writing: %r...' % path + fp = gzip.open(path, 'wb') + converter.dump_unicodemap(fp) fp.close() - - return 0 + return if __name__ == '__main__': sys.exit(main(sys.argv)) diff -Nru pdfminer-20110515+dfsg/tools/conv_glyphlist.py pdfminer-20140328+dfsg/tools/conv_glyphlist.py --- pdfminer-20110515+dfsg/tools/conv_glyphlist.py 2010-10-19 09:53:39.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/conv_glyphlist.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys import fileinput diff -Nru pdfminer-20110515+dfsg/tools/dumppdf.py pdfminer-20140328+dfsg/tools/dumppdf.py --- pdfminer-20110515+dfsg/tools/dumppdf.py 2010-10-19 09:53:40.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/dumppdf.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # # dumppdf.py - dump pdf contents in XML format. # @@ -6,10 +6,14 @@ # options: # -i objid : object id # -import sys, re -from pdfminer.psparser import PSKeyword, PSLiteral -from pdfminer.pdfparser import PDFDocument, PDFParser, PDFNoOutlines +import sys, os.path, re +from pdfminer.psparser import PSKeyword, PSLiteral, LIT +from pdfminer.pdfparser import PDFParser +from pdfminer.pdfdocument import PDFDocument, PDFNoOutlines +from pdfminer.pdftypes import PDFObjectNotFound, PDFValueError from pdfminer.pdftypes import PDFStream, PDFObjRef, resolve1, stream_value +from pdfminer.pdfpage import PDFPage +from pdfminer.utils import isnumber ESC_PAT = re.compile(r'[\000-\037&<>()"\042\047\134\177-\377]') @@ -22,7 +26,7 @@ if obj is None: out.write('') return - + if isinstance(obj, dict): out.write('\n' % len(obj)) for (k,v) in obj.iteritems(): @@ -72,7 +76,7 @@ out.write('%s' % obj.name) return - if isinstance(obj, int) or isinstance(obj, float): + if isnumber(obj): out.write('%s' % obj) return @@ -88,31 +92,32 @@ # dumpallobjs def dumpallobjs(out, doc, codec=None): + visited = set() out.write('') for xref in doc.xrefs: for objid in xref.get_objids(): + if objid in visited: continue + visited.add(objid) try: obj = doc.getobj(objid) if obj is None: continue out.write('\n' % objid) dumpxml(out, obj, codec=codec) out.write('\n\n\n') - except: - raise + except PDFObjectNotFound, e: + print >>sys.stderr, 'not found: %r' % e dumptrailers(out, doc) out.write('') return # dumpoutline def dumpoutline(outfp, fname, objids, pagenos, password='', - dumpall=False, codec=None): - doc = PDFDocument() + dumpall=False, codec=None, extractdir=None): fp = file(fname, 'rb') parser = PDFParser(fp) - parser.set_document(doc) - doc.set_parser(parser) - doc.initialize(password) - pages = dict( (page.pageid, pageno) for (pageno,page) in enumerate(doc.get_pages()) ) + doc = PDFDocument(parser, password) + pages = dict( (page.pageid, pageno) for (pageno,page) + in enumerate(PDFPage.create_pages(doc)) ) def resolve_dest(dest): if isinstance(dest, str): dest = resolve1(doc.get_dest(dest)) @@ -152,21 +157,54 @@ fp.close() return +# extractembedded +LITERAL_FILESPEC = LIT('Filespec') +LITERAL_EMBEDDEDFILE = LIT('EmbeddedFile') +def extractembedded(outfp, fname, objids, pagenos, password='', + dumpall=False, codec=None, extractdir=None): + def extract1(obj): + filename = os.path.basename(obj['UF'] or obj['F']) + fileref = obj['EF']['F'] + fileobj = doc.getobj(fileref.objid) + if not isinstance(fileobj, PDFStream): + raise PDFValueError( + 'unable to process PDF: reference for %r is not a PDFStream' % + (filename)) + if fileobj.get('Type') is not LITERAL_EMBEDDEDFILE: + raise PDFValueError( + 'unable to process PDF: reference for %r is not an EmbeddedFile' % + (filename)) + path = os.path.join(extractdir, filename) + if os.path.exists(path): + raise IOError('file exists: %r' % path) + print >>sys.stderr, 'extracting: %r' % path + out = file(path, 'wb') + out.write(fileobj.get_data()) + out.close() + return + + fp = file(fname, 'rb') + parser = PDFParser(fp) + doc = PDFDocument(parser, password) + for xref in doc.xrefs: + for objid in xref.get_objids(): + obj = doc.getobj(objid) + if isinstance(obj, dict) and obj.get('Type') is LITERAL_FILESPEC: + extract1(obj) + return + # dumppdf def dumppdf(outfp, fname, objids, pagenos, password='', - dumpall=False, codec=None): - doc = PDFDocument() + dumpall=False, codec=None, extractdir=None): fp = file(fname, 'rb') parser = PDFParser(fp) - parser.set_document(doc) - doc.set_parser(parser) - doc.initialize(password) + doc = PDFDocument(parser, password) if objids: for objid in objids: obj = doc.getobj(objid) dumpxml(outfp, obj, codec=codec) if pagenos: - for (pageno,page) in enumerate(doc.get_pages()): + for (pageno,page) in enumerate(PDFPage.create_pages(doc)): if pageno in pagenos: if codec: for obj in page.contents: @@ -188,10 +226,10 @@ def main(argv): import getopt def usage(): - print 'usage: %s [-d] [-a] [-p pageid] [-P password] [-r|-b|-t] [-T] [-i objid] file ...' % argv[0] + print 'usage: %s [-d] [-a] [-p pageid] [-P password] [-r|-b|-t] [-T] [-E directory] [-i objid] file ...' % argv[0] return 100 try: - (opts, args) = getopt.getopt(argv[1:], 'dap:P:rbtTi:') + (opts, args) = getopt.getopt(argv[1:], 'dap:P:rbtTE:i:') except getopt.GetoptError: return usage() if not args: return usage() @@ -203,8 +241,10 @@ dumpall = False proc = dumppdf outfp = sys.stdout + extractdir = None for (k, v) in opts: if k == '-d': debug += 1 + elif k == '-o': outfp = file(v, 'wb') elif k == '-i': objids.extend( int(x) for x in v.split(',') ) elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') ) elif k == '-P': password = v @@ -213,14 +253,16 @@ elif k == '-b': codec = 'binary' elif k == '-t': codec = 'text' elif k == '-T': proc = dumpoutline - elif k == '-o': outfp = file(v, 'wb') + elif k == '-E': + extractdir = v + proc = extractembedded # PDFDocument.debug = debug PDFParser.debug = debug # for fname in args: proc(outfp, fname, objids, pagenos, password=password, - dumpall=dumpall, codec=codec) + dumpall=dumpall, codec=codec, extractdir=extractdir) return if __name__ == '__main__': sys.exit(main(sys.argv)) diff -Nru pdfminer-20110515+dfsg/tools/latin2ascii.py pdfminer-20140328+dfsg/tools/latin2ascii.py --- pdfminer-20110515+dfsg/tools/latin2ascii.py 2010-10-19 09:53:42.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/latin2ascii.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # # latin2ascii.py - converts latin1 characters into ascii. # @@ -14,7 +14,7 @@ LATIN2ASCII = { #0x00a0: '', #0x00a7: '', - + # iso-8859-1 0x00c0: 'A`', 0x00c1: "A'", diff -Nru pdfminer-20110515+dfsg/tools/pdf2html.cgi pdfminer-20140328+dfsg/tools/pdf2html.cgi --- pdfminer-20110515+dfsg/tools/pdf2html.cgi 2010-12-25 08:53:34.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/pdf2html.cgi 2015-10-11 18:33:29.000000000 +0000 @@ -159,7 +159,7 @@ def convert(self): self.form = cgi.FieldStorage(fp=self.infp, environ=self.environ) - if (self.method != 'POST' or + if (self.method != 'POST' or 'c' not in self.form or 'f' not in self.form): self.response_200() diff -Nru pdfminer-20110515+dfsg/tools/pdf2txt.py pdfminer-20140328+dfsg/tools/pdf2txt.py --- pdfminer-20110515+dfsg/tools/pdf2txt.py 2011-04-21 10:26:16.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/pdf2txt.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,22 +1,27 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys -from pdfminer.pdfparser import PDFDocument, PDFParser -from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf +from pdfminer.pdfdocument import PDFDocument +from pdfminer.pdfparser import PDFParser +from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.pdfdevice import PDFDevice, TagExtractor +from pdfminer.pdfpage import PDFPage from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter from pdfminer.cmapdb import CMapDB from pdfminer.layout import LAParams +from pdfminer.image import ImageWriter # main def main(argv): import getopt def usage(): - print ('usage: %s [-d] [-p pagenos] [-m maxpages] [-P password] [-o output] [-C] ' - '[-n] [-A] [-V] [-M char_margin] [-L line_margin] [-W word_margin] [-F boxes_flow] ' - '[-Y layout_mode] [-O output_dir] [-t text|html|xml|tag] [-c codec] [-s scale] file ...' % argv[0]) + print ('usage: %s [-d] [-p pagenos] [-m maxpages] [-P password] [-o output]' + ' [-C] [-n] [-A] [-V] [-M char_margin] [-L line_margin] [-W word_margin]' + ' [-F boxes_flow] [-Y layout_mode] [-O output_dir] [-R rotation]' + ' [-t text|html|xml|tag] [-c codec] [-s scale]' + ' file ...' % argv[0]) return 100 try: - (opts, args) = getopt.getopt(argv[1:], 'dp:m:P:o:CnAVM:L:W:F:Y:O:t:c:s:') + (opts, args) = getopt.getopt(argv[1:], 'dp:m:P:o:CnAVM:L:W:F:Y:O:R:t:c:s:') except getopt.GetoptError: return usage() if not args: return usage() @@ -29,7 +34,8 @@ # output option outfile = None outtype = None - outdir = None + imagewriter = None + rotation = 0 layoutmode = 'normal' codec = 'utf-8' pageno = 1 @@ -52,7 +58,8 @@ elif k == '-W': laparams.word_margin = float(v) elif k == '-F': laparams.boxes_flow = float(v) elif k == '-Y': layoutmode = v - elif k == '-O': outdir = v + elif k == '-O': imagewriter = ImageWriter(v) + elif k == '-R': rotation = int(v) elif k == '-t': outtype = v elif k == '-c': codec = v elif k == '-s': scale = float(v) @@ -79,20 +86,27 @@ else: outfp = sys.stdout if outtype == 'text': - device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams) + device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, + imagewriter=imagewriter) elif outtype == 'xml': - device = XMLConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, outdir=outdir) + device = XMLConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, + imagewriter=imagewriter) elif outtype == 'html': device = HTMLConverter(rsrcmgr, outfp, codec=codec, scale=scale, - layoutmode=layoutmode, laparams=laparams, outdir=outdir) + layoutmode=layoutmode, laparams=laparams, + imagewriter=imagewriter) elif outtype == 'tag': device = TagExtractor(rsrcmgr, outfp, codec=codec) else: return usage() for fname in args: fp = file(fname, 'rb') - process_pdf(rsrcmgr, device, fp, pagenos, maxpages=maxpages, password=password, - caching=caching, check_extractable=True) + interpreter = PDFPageInterpreter(rsrcmgr, device) + for page in PDFPage.get_pages(fp, pagenos, + maxpages=maxpages, password=password, + caching=caching, check_extractable=True): + page.rotate = (page.rotate+rotation) % 360 + interpreter.process_page(page) fp.close() device.close() outfp.close() diff -Nru pdfminer-20110515+dfsg/tools/prof.py pdfminer-20140328+dfsg/tools/prof.py --- pdfminer-20110515+dfsg/tools/prof.py 2010-10-19 09:53:50.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/prof.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python import sys def prof_main(argv): - import getopt import hotshot, hotshot.stats def usage(): print 'usage: %s module.function [args ...]' % argv[0] diff -Nru pdfminer-20110515+dfsg/tools/runapp.py pdfminer-20140328+dfsg/tools/runapp.py --- pdfminer-20110515+dfsg/tools/runapp.py 2010-12-25 08:28:01.000000000 +0000 +++ pdfminer-20140328+dfsg/tools/runapp.py 2015-10-11 18:33:29.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python ## ## WebApp class runner ##