From a78daa62dc613a7942c273cc01680377773fb751 Mon Sep 17 00:00:00 2001 From: Adam Stein Date: Thu, 14 Feb 2019 16:00:04 -0500 Subject: [PATCH 1/3] Fixed issue when a compressed font is too big for the default sized zlib buffer --- pdfminer/__init__.py | 2 +- pdfminer/pdftypes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdfminer/__init__.py b/pdfminer/__init__.py index a7bc049f..6829a80a 100644 --- a/pdfminer/__init__.py +++ b/pdfminer/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -__version__ = '20140328' +__version__ = '20190215' if __name__ == '__main__': print (__version__) diff --git a/pdfminer/pdftypes.py b/pdfminer/pdftypes.py index 20d981dd..82c29230 100644 --- a/pdfminer/pdftypes.py +++ b/pdfminer/pdftypes.py @@ -245,7 +245,7 @@ def decode(self): if f in LITERALS_FLATE_DECODE: # will get errors if the document is encrypted. try: - data = zlib.decompress(data) + data = zlib.decompressobj().decompress(data) except zlib.error as e: if STRICT: raise PDFException('Invalid zlib bytes: %r, %r' % (e, data)) From 57449c4b346fb67129e6cad8f75a77253f4b3d5c Mon Sep 17 00:00:00 2001 From: Adam Stein Date: Mon, 10 Jun 2019 06:35:32 -0400 Subject: [PATCH 2/3] Updated to handle exception in IdentityCMap.decode. A PDF has been seen with an odd length code to decode which causes unpack() to have an error. If unpack() fails for any reason, just return an empty tuple as if there were no data to unpack. --- pdfminer/__init__.py | 2 +- pdfminer/cmapdb.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pdfminer/__init__.py b/pdfminer/__init__.py index 6829a80a..90100917 100644 --- a/pdfminer/__init__.py +++ b/pdfminer/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -__version__ = '20190215' +__version__ = '20190610' if __name__ == '__main__': print (__version__) diff --git a/pdfminer/cmapdb.py b/pdfminer/cmapdb.py index dbe98717..7e828032 100644 --- a/pdfminer/cmapdb.py +++ b/pdfminer/cmapdb.py @@ -124,7 +124,10 @@ class IdentityCMap(CMapBase): def decode(self, code): n = len(code)//2 if n: - return struct.unpack('>%dH' % n, code) + try: + return struct.unpack('>%dH' % n, code) + except struct.error: + return () else: return () From 508400dac564b03a2dbc12159104573bc3923596 Mon Sep 17 00:00:00 2001 From: Adam Stein Date: Thu, 14 Nov 2019 15:30:23 -0500 Subject: [PATCH 3/3] Updated code base to pdfminer 20191103 with the following bug fixes: o Fixed issue where a PDF comment goes to end of line so matching fails. When fixed, the old problem of having an odd length code to decode comes back causing unpack() to have a problem. This is fixed by returning an empty tuple as if there was no data to unpack. o Fixed issue when a compressed font is too big for the default sized zlib buffer. --- .travis.yml | 5 +- LICENSE | 4 +- MANIFEST.in | 1 + Makefile | 38 +- README.md | 265 ++++---- docs/index.html | 4 +- pdfminer/Makefile | 1 + pdfminer/__init__.py | 2 +- pdfminer/arcfour.py | 24 +- pdfminer/ascii85.py | 28 +- pdfminer/ccitt.py | 36 +- pdfminer/cmapdb.py | 226 ++++++- pdfminer/converter.py | 45 +- pdfminer/encodingdb.py | 4 +- pdfminer/image.py | 81 ++- pdfminer/layout.py | 18 +- pdfminer/lzw.py | 12 +- pdfminer/pdfcolor.py | 4 +- pdfminer/pdfdevice.py | 19 +- pdfminer/pdfdocument.py | 48 +- pdfminer/pdffont.py | 67 +- pdfminer/pdfinterp.py | 30 +- pdfminer/pdfpage.py | 4 +- pdfminer/pdftypes.py | 14 +- pdfminer/psparser.py | 61 +- pdfminer/rijndael.py | 1300 +++++++++++++++++++-------------------- pdfminer/runlength.py | 18 +- pdfminer/utils.py | 49 +- samples/Makefile | 2 +- setup.py | 102 +-- tools/conv_cmap.py | 173 +----- tools/dumppdf.py | 226 +++---- tools/pdf2txt.py | 61 +- 33 files changed, 1476 insertions(+), 1496 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f3c2f0d..c125d63a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ language: python python: - - "2.6" - - "2.7" + - "3.7" install: - - pip install pycrypto + - pip install pycryptodome script: - make test diff --git a/LICENSE b/LICENSE index 39400677..d4ebcd4d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2004-2016 Yusuke Shinyama +MIT License + +Copyright (c) 2004-2019 Yusuke Shinyama Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/MANIFEST.in b/MANIFEST.in index 910eee5d..6e1ac4a5 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,6 +2,7 @@ include Makefile include LICENSE include *.txt include *.py +include *.md graft cmaprsrc graft docs graft pdfminer diff --git a/Makefile b/Makefile index 0ffd84f7..53a34bf2 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,8 @@ PACKAGE=pdfminer -PYTHON=python2 -GIT=git +PYTHON=python -B +TWINE=twine RM=rm -f CP=cp -f MKDIR=mkdir @@ -16,7 +16,7 @@ install: clean: -$(PYTHON) setup.py clean - -$(RM) -r build dist MANIFEST + -$(RM) -r build dist MANIFEST pdfminer.egg-info -cd $(PACKAGE) && $(MAKE) clean -cd tools && $(MAKE) clean -cd samples && $(MAKE) clean @@ -25,42 +25,42 @@ distclean: clean cmap_clean sdist: distclean MANIFEST.in $(PYTHON) setup.py sdist -register: distclean MANIFEST.in - $(PYTHON) setup.py sdist upload register +upload: sdist + $(TWINE) check dist/*.tar.gz + $(TWINE) upload dist/*.tar.gz -WEBDIR=../euske.github.io/$(PACKAGE) +WEBDIR=../github.io/$(PACKAGE) publish: $(CP) docs/*.html docs/*.png docs/*.css $(WEBDIR) -CONV_CMAP=$(PYTHON) tools/conv_cmap.py +CONV_CMAP=env PYTHONPATH=. $(PYTHON) tools/conv_cmap.py CMAPSRC=cmaprsrc CMAPDST=pdfminer/cmap -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: $(CMAPDST)/to-unicode-Adobe-CNS1.marshal.gz $(CMAPDST)/to-unicode-Adobe-GB1.marshal.gz \ + $(CMAPDST)/to-unicode-Adobe-Japan1.marshal.gz $(CMAPDST)/to-unicode-Adobe-Korea1.marshal.gz cmap_clean: -$(RM) -r $(CMAPDST) $(CMAPDST): $(MKDIR) $(CMAPDST) -$(CMAPDST)/to-unicode-Adobe-CNS1.pickle.gz: $(CMAPDST) +$(CMAPDST)/to-unicode-Adobe-CNS1.marshal.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) +$(CMAPDST)/to-unicode-Adobe-GB1.marshal.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) +$(CMAPDST)/to-unicode-Adobe-Japan1.marshal.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) +$(CMAPDST)/to-unicode-Adobe-Korea1.marshal.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 - $(PYTHON) -m doctest \ - pdfminer/arcfour.py \ - pdfminer/lzw.py \ - pdfminer/ascii85.py \ - pdfminer/runlength.py \ - pdfminer/rijndael.py + $(PYTHON) -m pdfminer.arcfour + $(PYTHON) -m pdfminer.ascii85 + $(PYTHON) -m pdfminer.lzw + $(PYTHON) -m pdfminer.rijndael + $(PYTHON) -m pdfminer.runlength $(PYTHON) -m pdfminer.ccitt $(PYTHON) -m pdfminer.psparser cd samples && $(MAKE) test diff --git a/README.md b/README.md index c74b1bd4..6ab9c0ea 100644 --- a/README.md +++ b/README.md @@ -1,161 +1,108 @@ -PDFMiner -======== +# PDFMiner -[![Build Status](https://travis-ci.org/euske/pdfminer.svg?branch=master)](https://travis-ci.org/euske/pdfminer) - -PDFMiner is a tool for extracting information from PDF documents. -Unlike other PDF-related tools, it focuses entirely on getting -and analyzing text data. PDFMiner allows one to obtain -the exact location of text 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 -PDF parser that can be used for other purposes than text analysis. - - * Webpage: https://euske.github.io/pdfminer/ - * Download (PyPI): https://pypi.python.org/pypi/pdfminer/ - * Demo WebApp: http://pdf2html.tabesugi.net:8080/ - - -Features --------- - - * Written entirely in Python. - * Parse, analyze, and convert PDF documents. - * PDF-1.7 specification support. (well, almost) - * CJK languages and vertical writing scripts support. - * Various font types (Type1, TrueType, Type3, and CID) support. - * Basic encryption (RC4) support. - * Outline (TOC) extraction. - * Tagged contents extraction. - * Automatic layout analysis. - - -How to Install --------------- - - * Install Python 2.6 or newer. (**For Python 3 support have a look at [pdfminer.six](https://github.com/goulu/pdfminer)**). - * Download the source code. - * Unpack it. - * Run `setup.py`: - - $ python setup.py install - - * Do the following test: - - $ pdf2txt.py samples/simple1.pdf - - -For CJK Languages ------------------ - -In order to process CJK languages, do the following before -running setup.py install: - - $ make cmap - python tools/conv_cmap.py pdfminer/cmap Adobe-CNS1 cmaprsrc/cid2code_Adobe_CNS1.txt - reading 'cmaprsrc/cid2code_Adobe_CNS1.txt'... - writing 'CNS1_H.py'... - ... - $ python setup.py install - -On Windows machines which don't have `make` command, -paste the following commands on a command line prompt: - - 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 - - -Command Line Tools ------------------- - -PDFMiner comes with two handy tools: -pdf2txt.py and dumppdf.py. - -**pdf2txt.py** +PDFMiner is a text extraction tool for PDF documents. -pdf2txt.py extracts text contents from a PDF file. -It extracts all the text that are to be rendered programmatically, -i.e. text represented as ASCII or Unicode strings. -It cannot recognize text drawn as images that would require optical character recognition. -It also extracts the corresponding locations, font names, font sizes, writing -direction (horizontal or vertical) for each text portion. -You need to provide a password for protected PDF documents when its access is restricted. -You cannot extract any text from a PDF document which does not have extraction permission. - -(For details, refer to the html document.) - -**dumppdf.py** - -dumppdf.py dumps the internal contents of a PDF file in pseudo-XML format. -This program is primarily for debugging purposes, -but it's also possible to extract some meaningful contents (e.g. images). - -(For details, refer to the html document.) - - -API Changes ------------ - -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 a class method PDFPage.get_pages. - - -TODO ----- - - * Replace STRICT variable with something better. - * Use logging module instead of sys.stderr. - * Proper test cases. - * PEP-8 and PEP-257 conformance. - * Better documentation. - * Crypt stream filter support. - - -Related Projects ----------------- - - * pyPdf - * xpdf - * pdfbox - * mupdf - - -Terms and Conditions --------------------- - -(This is so-called MIT/X License) - -Copyright (c) 2004-2016 Yusuke Shinyama - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +[![Build Status](https://travis-ci.org/euske/pdfminer.svg?branch=master)](https://travis-ci.org/euske/pdfminer) +[![PyPI](https://img.shields.io/pypi/v/pdfminer)](https://pypi.org/project/pdfminer/) + +**Warning**: Starting from version 20191010, PDFMiner supports **Python 3 only**. +For Python 2 support, check out +pdfminer.six. + +## Features: + + * Pure Python (3.6 or above). + * Supports PDF-1.7. (well, almost) + * Obtains the exact location of text as well as other layout information (fonts, etc.). + * Performs automatic layout analysis. + * Can convert PDF into other formats (HTML/XML). + * Can extract an outline (TOC). + * Can extract tagged contents. + * Supports basic encryption (RC4 and AES). + * Supports various font types (Type1, TrueType, Type3, and CID). + * Supports CJK languages and vertical writing scripts. + * Has an extensible PDF parser that can be used for other purposes. + + +## How to Use: + + 1. `> pip install pdfminer` + 1. `> pdf2txt.py samples/simple1.pdf` + + +## Command Line Syntax: + +### pdf2txt.py + +pdf2txt.py extracts all the texts that are rendered programmatically. +It also extracts the corresponding locations, font names, font sizes, +writing direction (horizontal or vertical) for each text segment. It +does not recognize text in images. A password needs to be provided for +restricted PDF documents. + + > pdf2txt.py [-P password] [-o output] [-t text|html|xml|tag] + [-O output_dir] [-c encoding] [-s scale] [-R rotation] + [-Y normal|loose|exact] [-p pagenos] [-m maxpages] + [-S] [-C] [-n] [-A] [-V] + [-M char_margin] [-L line_margin] [-W word_margin] + [-F boxes_flow] [-d] + input.pdf ... + + * `-P password` : PDF password. + * `-o output` : Output file name. + * `-t text|html|xml|tag` : Output type. (default: automatically inferred from the output file name.) + * `-O output_dir` : Output directory for extracted images. + * `-c encoding` : Output encoding. (default: utf-8) + * `-s scale` : Output scale. + * `-R rotation` : Rotates the page in degree. + * `-Y normal|loose|exact` : Specifies the layout mode. (only for HTML output.) + * `-p pagenos` : Processes certain pages only. + * `-m maxpages` : Limits the number of maximum pages to process. + * `-S` : Strips control characters. + * `-C` : Disables resource caching. + * `-n` : Disables layout analysis. + * `-A` : Applies layout analysis for all texts including figures. + * `-V` : Automatically detects vertical writing. + * `-M char_margin` : Speficies the char margin. + * `-W word_margin` : Speficies the word margin. + * `-L line_margin` : Speficies the line margin. + * `-F boxes_flow` : Speficies the box flow ratio. + * `-d` : Turns on Debug output. + +### dumppdf.py + +dumppdf.py is used for debugging PDFs. +It dumps all the internal contents in pseudo-XML format. + + > dumppdf.py [-P password] [-a] [-p pageid] [-i objid] + [-o output] [-r|-b|-t] [-T] [-O directory] [-d] + input.pdf ... + + * `-P password` : PDF password. + * `-a` : Extracts all objects. + * `-p pageid` : Extracts a Page object. + * `-i objid` : Extracts a certain object. + * `-o output` : Output file name. + * `-r` : Raw mode. Dumps the raw compressed/encoded streams. + * `-b` : Binary mode. Dumps the uncompressed/decoded streams. + * `-t` : Text mode. Dumps the streams in text format. + * `-T` : Tagged mode. Dumps the tagged contents. + * `-O output_dir` : Output directory for extracted streams. + +## TODO + + * Replace STRICT variable with something better. + * Improve the debugging functions. + * Use logging module instead of sys.stderr. + * Proper test cases. + * PEP-8 and PEP-257 conformance. + * Better documentation. + * Crypto stream filter support. + + +## Related Projects + + * pyPdf + * xpdf + * pdfbox + * mupdf diff --git a/docs/index.html b/docs/index.html index 1e13cf8f..6782cdfb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -103,8 +103,8 @@

Where to Ask

How to Install

    -
  1. Install Python 2.6 or newer. - (Python 3 is not supported.) +
  2. Install Python 3.6 or newer. + (Python 2 is not supported.)
  3. Download the PDFMiner source.
  4. Unpack it.
  5. Run setup.py to install:
    diff --git a/pdfminer/Makefile b/pdfminer/Makefile index 1d1661b6..e34c6e6e 100644 --- a/pdfminer/Makefile +++ b/pdfminer/Makefile @@ -6,4 +6,5 @@ all: clean: -$(RM) *.pyc *.pyo + -$(RM) -r __pycache__ cd cmap && make clean diff --git a/pdfminer/__init__.py b/pdfminer/__init__.py index 90100917..adc1f61d 100644 --- a/pdfminer/__init__.py +++ b/pdfminer/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -__version__ = '20190610' +__version__ = '20191103.1' if __name__ == '__main__': print (__version__) diff --git a/pdfminer/arcfour.py b/pdfminer/arcfour.py index 523d991a..bed83eb0 100644 --- a/pdfminer/arcfour.py +++ b/pdfminer/arcfour.py @@ -9,23 +9,23 @@ ## Arcfour ## -class Arcfour(object): +class Arcfour: """ - >>> Arcfour(b'Key').process(b'Plaintext').encode('hex') + >>> Arcfour(b'Key').process(b'Plaintext').hex() 'bbf316e8d940af0ad3' - >>> Arcfour(b'Wiki').process(b'pedia').encode('hex') + >>> Arcfour(b'Wiki').process(b'pedia').hex() '1021bf0420' - >>> Arcfour(b'Secret').process(b'Attack at dawn').encode('hex') + >>> Arcfour(b'Secret').process(b'Attack at dawn').hex() '45a01f645fc35b383552544b9bf5' """ def __init__(self, key): - s = range(256) + s = list(range(256)) j = 0 klen = len(key) - for i in xrange(256): - j = (j + s[i] + ord(key[i % klen])) % 256 + for i in range(256): + j = (j + s[i] + key[i % klen]) % 256 (s[i], s[j]) = (s[j], s[i]) self.s = s (self.i, self.j) = (0, 0) @@ -34,16 +34,16 @@ def __init__(self, key): def process(self, data): (i, j) = (self.i, self.j) s = self.s - r = b'' + r = [] for c in data: i = (i+1) % 256 j = (j+s[i]) % 256 (s[i], s[j]) = (s[j], s[i]) k = s[(s[i]+s[j]) % 256] - r += chr(ord(c) ^ k) + r.append(c ^ k) (self.i, self.j) = (i, j) - return r - + return bytes(r) + encrypt = decrypt = process new = Arcfour @@ -51,4 +51,4 @@ def process(self, data): # test if __name__ == '__main__': import doctest - doctest.testmod() + print('pdfminer.arcfour:', doctest.testmod()) diff --git a/pdfminer/ascii85.py b/pdfminer/ascii85.py index 067fccd5..b0af08c8 100644 --- a/pdfminer/ascii85.py +++ b/pdfminer/ascii85.py @@ -25,23 +25,23 @@ def ascii85decode(data): http://en.wikipedia.org/w/index.php?title=Ascii85 >>> ascii85decode(b'9jqo^BlbD-BleB1DJ+*+F(f,q') - 'Man is distinguished' + b'Man is distinguished' >>> ascii85decode(b'E,9)oF*2M7/c~>') - 'pleasure.' + b'pleasure.' """ n = b = 0 out = b'' for c in data: - if b'!' <= c and c <= b'u': + if 33 <= c and c <= 117: # b'!' <= c and c <= b'u' n += 1 - b = b*85+(ord(c)-33) + b = b*85+(c-33) if n == 5: out += struct.pack('>L', b) n = b = 0 - elif c == b'z': + elif c == 122: # b'z' assert n == 0 out += b'\0\0\0\0' - elif c == b'~': + elif c == 126: # b'~' if n: for _ in range(5-n): b = b*85+84 @@ -65,20 +65,20 @@ def asciihexdecode(data): will behave as if a 0 followed the last digit. >>> asciihexdecode(b'61 62 2e6364 65') - 'ab.cde' + b'ab.cde' >>> asciihexdecode(b'61 62 2e6364 657>') - 'ab.cdep' + b'ab.cdep' >>> asciihexdecode(b'7>') - 'p' + b'p' """ - decode = (lambda hx: chr(int(hx, 16))) - out = map(decode, hex_re.findall(data)) + data = data.decode('latin1') + out = [ int(hx,16) for hx in hex_re.findall(data) ] m = trail_re.search(data) if m: - out.append(decode('%c0' % m.group(1))) - return b''.join(out) + out.append(int(m.group(1),16) << 4) + return bytes(out) if __name__ == '__main__': import doctest - doctest.testmod() + print('pdfminer.ascii85', doctest.testmod()) diff --git a/pdfminer/ccitt.py b/pdfminer/ccitt.py index d0cc0934..727ba742 100644 --- a/pdfminer/ccitt.py +++ b/pdfminer/ccitt.py @@ -16,7 +16,7 @@ ## BitParser ## -class BitParser(object): +class BitParser: def __init__(self): self._pos = 0 @@ -26,7 +26,7 @@ def __init__(self): def add(klass, root, v, bits): p = root b = None - for i in xrange(len(bits)): + for i in range(len(bits)): if 0 < i: if p[b] is None: p[b] = [None, None] @@ -39,8 +39,7 @@ def add(klass, root, v, bits): return def feedbytes(self, data): - for c in data: - b = ord(c) + for b in data: for m in (128, 64, 32, 16, 8, 4, 2, 1): self._parse_bit(b & m) return @@ -327,8 +326,7 @@ def __init__(self, width, bytealign=False): return def feedbytes(self, data): - for c in data: - b = ord(c) + for b in data: try: for m in (128, 64, 32, 16, 8, 4, 2, 1): self._parse_bit(b & m) @@ -462,10 +460,10 @@ def _do_vertical(self, dx): x0 = max(0, self._curpos) x1 = max(0, min(self.width, x1)) if x1 < x0: - for x in xrange(x1, x0): + for x in range(x1, x0): self._curline[x] = self._color elif x0 < x1: - for x in xrange(x0, x1): + for x in range(x0, x1): self._curline[x] = self._color self._curpos = x1 self._color = 1-self._color @@ -495,7 +493,7 @@ def _do_pass(self): self._refline[x1] == self._color): break x1 += 1 - for x in xrange(self._curpos, x1): + for x in range(self._curpos, x1): self._curline[x] = self._color self._curpos = x1 return @@ -505,12 +503,12 @@ def _do_horizontal(self, n1, n2): if self._curpos < 0: self._curpos = 0 x = self._curpos - for _ in xrange(n1): + for _ in range(n1): if len(self._curline) <= x: break self._curline[x] = self._color x += 1 - for _ in xrange(n2): + for _ in range(n2): if len(self._curline) <= x: break self._curline[x] = 1-self._color @@ -727,6 +725,7 @@ def main(argv): return unittest.main() class Parser(CCITTG4Parser): + def __init__(self, width, bytealign=False): import pygame CCITTG4Parser.__init__(self, width, bytealign=bytealign) @@ -745,14 +744,13 @@ def close(self): import pygame 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() + with open(path, 'rb') as fp: + (_, _, k, w, h, _) = path.split('.') + parser = Parser(int(w)) + parser.feedbytes(fp.read()) + parser.close() return -if __name__ == '__main__': - sys.exit(main(sys.argv)) +if __name__ == '__main__': sys.exit(main(sys.argv)) diff --git a/pdfminer/cmapdb.py b/pdfminer/cmapdb.py index 7e828032..211b7dcc 100644 --- a/pdfminer/cmapdb.py +++ b/pdfminer/cmapdb.py @@ -15,10 +15,8 @@ import os import os.path import gzip -try: - import cPickle as pickle -except ImportError: - import pickle as pickle +import codecs +import marshal import struct import logging from .psparser import PSStackParser @@ -38,7 +36,7 @@ class CMapError(Exception): ## CMapBase ## -class CMapBase(object): +class CMapBase: debug = 0 @@ -79,7 +77,7 @@ def use_cmap(self, cmap): assert isinstance(cmap, CMap) def copy(dst, src): - for (k, v) in src.iteritems(): + for (k, v) in src.items(): if isinstance(v, dict): d = {} dst[k] = d @@ -94,7 +92,6 @@ def decode(self, code): logging.debug('decode: %r, %r' % (self, code)) d = self.code2cid for c in code: - c = ord(c) if c in d: d = d[c] if isinstance(d, int): @@ -108,7 +105,7 @@ def dump(self, out=sys.stdout, code2cid=None, code=None): if code2cid is None: code2cid = self.code2cid code = () - for (k, v) in sorted(code2cid.iteritems()): + for (k, v) in sorted(code2cid.items()): c = code+(k,) if isinstance(v, int): out.write('code %r = cid %d\n' % (c, v)) @@ -150,7 +147,7 @@ def get_unichr(self, cid): return self.cid2unichr[cid] def dump(self, out=sys.stdout): - for (k, v) in sorted(self.cid2unichr.iteritems()): + for (k, v) in sorted(self.cid2unichr.items()): out.write('cid %d = unicode %r\n' % (k, v)) return @@ -160,7 +157,7 @@ def dump(self, out=sys.stdout): class FileCMap(CMap): def add_code2cid(self, code, cid): - assert isinstance(code, str) and isinstance(cid, int) + assert isinstance(code, bytes) and isinstance(cid, int) d = self.code2cid for c in code[:-1]: c = ord(c) @@ -184,11 +181,11 @@ def add_cid2unichr(self, cid, code): if isinstance(code, PSLiteral): # Interpret as an Adobe glyph name. self.cid2unichr[cid] = name2unicode(code.name) - elif isinstance(code, str): + elif isinstance(code, bytes): # Interpret as UTF-16BE. - self.cid2unichr[cid] = unicode(code, 'UTF-16BE', 'ignore') + self.cid2unichr[cid] = code.decode('UTF-16BE', 'ignore') elif isinstance(code, int): - self.cid2unichr[cid] = unichr(code) + self.cid2unichr[cid] = chr(code) else: raise TypeError(code) return @@ -222,7 +219,7 @@ def __init__(self, name, module, vertical): ## CMapDB ## -class CMapDB(object): +class CMapDB: _cmap_cache = {} _umap_cache = {} @@ -232,7 +229,7 @@ class CMapNotFound(CMapError): @classmethod def _load_data(klass, name): - filename = '%s.pickle.gz' % name + filename = '%s.marshal.gz' % name logging.info('loading: %r' % name) cmap_paths = (os.environ.get('CMAP_PATH', '/usr/share/pdfminer/'), os.path.join(os.path.dirname(__file__), 'cmap'),) @@ -241,7 +238,7 @@ def _load_data(klass, name): if os.path.exists(path): gzfile = gzip.open(path) try: - return type(str(name), (), pickle.loads(gzfile.read())) + return type(str(name), (), marshal.loads(gzfile.read())) finally: gzfile.close() else: @@ -306,7 +303,7 @@ def run(self): KEYWORD_ENDBFCHAR = KWD(b'endbfchar') KEYWORD_BEGINNOTDEFRANGE = KWD(b'beginnotdefrange') KEYWORD_ENDNOTDEFRANGE = KWD(b'endnotdefrange') - + def do_keyword(self, pos, token): if token is self.KEYWORD_BEGINCMAP: self._in_cmap = True @@ -349,7 +346,7 @@ def do_keyword(self, pos, token): if token is self.KEYWORD_ENDCIDRANGE: 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 + if (not isinstance(s, bytes) or not isinstance(e, bytes) or not isinstance(cid, int) or len(s) != len(e)): continue sprefix = s[:-4] @@ -362,7 +359,7 @@ def do_keyword(self, pos, token): e1 = nunpack(evar) vlen = len(svar) #assert s1 <= e1 - for i in xrange(e1-s1+1): + for i in range(e1-s1+1): x = sprefix+struct.pack('>L', s1+i)[-vlen:] self.cmap.add_code2cid(x, cid+i) return @@ -373,7 +370,7 @@ def do_keyword(self, pos, token): if token is self.KEYWORD_ENDCIDCHAR: objs = [obj for (__, obj) in self.popall()] for (cid, code) in choplist(2, objs): - if isinstance(code, str) and isinstance(cid, str): + if isinstance(code, bytes) and isinstance(cid, bytes): self.cmap.add_code2cid(code, nunpack(cid)) return @@ -383,21 +380,21 @@ def do_keyword(self, pos, token): if token is self.KEYWORD_ENDBFRANGE: 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 + if (not isinstance(s, bytes) or not isinstance(e, bytes) or len(s) != len(e)): continue s1 = nunpack(s) e1 = nunpack(e) #assert s1 <= e1 if isinstance(code, list): - for i in xrange(e1-s1+1): + for i in range(e1-s1+1): self.cmap.add_cid2unichr(s1+i, code[i]) else: var = code[-4:] base = nunpack(var) prefix = code[:-4] vlen = len(var) - for i in xrange(e1-s1+1): + for i in range(e1-s1+1): x = prefix+struct.pack('>L', base+i)[-vlen:] self.cmap.add_cid2unichr(s1+i, x) return @@ -408,7 +405,7 @@ def do_keyword(self, pos, token): if token is self.KEYWORD_ENDBFCHAR: objs = [obj for (__, obj) in self.popall()] for (cid, code) in choplist(2, objs): - if isinstance(cid, str) and isinstance(code, str): + if isinstance(cid, bytes) and isinstance(code, bytes): self.cmap.add_cid2unichr(nunpack(cid), code) return @@ -423,16 +420,185 @@ def do_keyword(self, pos, token): return +## CMapConverter +## +class CMapConverter: + + 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: + 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]: + if b in dmap: + dmap = dmap[b] + else: + d = {} + dmap[b] = d + dmap = d + b = code[-1] + if force or ((b not in dmap) or dmap[b] == cid): + dmap[b] = cid + return + + def add(unimap, enc, code): + try: + 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 + return + + def pick(unimap): + chars = sorted( + unimap.items(), + key=(lambda x:(x[1],-ord(x[0]))), 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 = codecs.decode(code, 'hex') + except: + code = bytes([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) + + return + + def dump_cmap(self, fp, enc): + data = dict( + IS_VERTICAL=self.is_vertical.get(enc, False), + CODE2CID=self.code2cid.get(enc), + ) + fp.write(marshal.dumps(data)) + return + + def dump_unicodemap(self, fp): + data = dict( + CID2UNICHR_H=self.cid2unichr_h, + CID2UNICHR_V=self.cid2unichr_v, + ) + fp.write(marshal.dumps(data)) + return + +# convert_cmap +def convert_cmap(outdir, regname, enc2codec, paths): + converter = CMapConverter(enc2codec) + + for path in paths: + print('reading: %r...' % path) + with open(path) as fp: + converter.load(fp) + + files = [] + for enc in converter.get_encs(): + fname = '%s.marshal.gz' % enc + path = os.path.join(outdir, fname) + print('writing: %r...' % path) + with gzip.open(path, 'wb') as fp: + converter.dump_cmap(fp, enc) + files.append(path) + + fname = 'to-unicode-%s.marshal.gz' % regname + path = os.path.join(outdir, fname) + print ('writing: %r...' % path) + with gzip.open(path, 'wb') as fp: + converter.dump_unicodemap(fp) + files.append(path) + return files + + # test def main(argv): args = argv[1:] for fname in args: - fp = file(fname, 'rb') - cmap = FileUnicodeMap() - #cmap = FileCMap() - CMapParser(cmap, fp).run() - fp.close() - cmap.dump() + with open(fname, 'rb') as fp: + cmap = FileUnicodeMap() + #cmap = FileCMap() + CMapParser(cmap, fp).run() + cmap.dump() return if __name__ == '__main__': diff --git a/pdfminer/converter.py b/pdfminer/converter.py index 30ceb226..020ea97d 100644 --- a/pdfminer/converter.py +++ b/pdfminer/converter.py @@ -18,7 +18,7 @@ from .layout import LTTextGroup from .utils import apply_matrix_pt from .utils import mult_matrix -from .utils import enc +from .utils import q from .utils import bbox2str @@ -98,7 +98,7 @@ def paint_path(self, gstate, stroke, fill, evenodd, path): # other shapes pts = [] for p in path: - for i in xrange(1, len(p), 2): + for i in range(1, len(p), 2): pts.append(apply_matrix_pt(self.ctm, (p[i], p[i+1]))) self.cur_item.add(LTCurve(gstate.linewidth, pts)) return @@ -106,7 +106,7 @@ def paint_path(self, gstate, stroke, fill, evenodd, path): def render_char(self, matrix, font, fontsize, scaling, rise, cid): try: text = font.to_unichr(cid) - assert isinstance(text, unicode), text + assert isinstance(text, str), text except PDFUnicodeNotDefined: text = self.handle_undefined_char(font, cid) textwidth = font.char_width(cid) @@ -117,7 +117,7 @@ def render_char(self, matrix, font, fontsize, scaling, rise, cid): def handle_undefined_char(self, font, cid): logging.info('undefined: %r, %r' % (font, cid)) - return '(cid:%d)' % cid + return f'(cid:{cid})' def receive_layout(self, ltpage): return @@ -144,10 +144,9 @@ def get_result(self): ## class PDFConverter(PDFLayoutAnalyzer): - def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, laparams=None): + def __init__(self, rsrcmgr, outfp, pageno=1, laparams=None): PDFLayoutAnalyzer.__init__(self, rsrcmgr, pageno=pageno, laparams=laparams) self.outfp = outfp - self.codec = codec return @@ -155,15 +154,15 @@ def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, laparams=None): ## class TextConverter(PDFConverter): - def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, laparams=None, + def __init__(self, rsrcmgr, outfp, pageno=1, laparams=None, showpageno=False, imagewriter=None): - PDFConverter.__init__(self, rsrcmgr, outfp, codec=codec, pageno=pageno, laparams=laparams) + PDFConverter.__init__(self, rsrcmgr, outfp, pageno=pageno, laparams=laparams) self.showpageno = showpageno self.imagewriter = imagewriter return def write_text(self, text): - self.outfp.write(text.encode(self.codec, 'ignore')) + self.outfp.write(text) return def receive_layout(self, ltpage): @@ -216,12 +215,12 @@ class HTMLConverter(PDFConverter): 'char': 'black', } - def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, laparams=None, + def __init__(self, rsrcmgr, outfp, pageno=1, laparams=None, scale=1, fontscale=1.0, layoutmode='normal', showpageno=True, pagemargin=50, imagewriter=None, debug=0, rect_colors={'curve': 'black', 'page': 'gray'}, text_colors={'char': 'black'}): - PDFConverter.__init__(self, rsrcmgr, outfp, codec=codec, pageno=pageno, laparams=laparams) + PDFConverter.__init__(self, rsrcmgr, outfp, pageno=pageno, laparams=laparams) self.scale = scale self.fontscale = fontscale self.layoutmode = layoutmode @@ -245,18 +244,18 @@ def write(self, text): def write_header(self): self.write('\n') - self.write('\n' % self.codec) + self.write('\n') self.write('\n') return 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 range(1, self.pageno))) self.write('\n') return def write_text(self, text): - self.write(enc(text, self.codec)) + self.write(q(text)) return def place_rect(self, color, borderwidth, x, y, w, h): @@ -278,7 +277,7 @@ def place_image(self, item, borderwidth, x, y, w, h): name = self.imagewriter.export_image(item) self.write('\n' % - (enc(name), borderwidth, + (q(name), borderwidth, x*self.scale, (self._yoffset-y)*self.scale, w*self.scale, h*self.scale)) return @@ -315,7 +314,7 @@ def put_text(self, text, fontname, fontsize): if self._font is not None: self.write('') self.write('' % - (enc(fontname), fontsize * self.scale * self.fontscale)) + (q(fontname), fontsize * self.scale * self.fontscale)) self._font = font self.write_text(text) return @@ -398,18 +397,18 @@ def close(self): ## class XMLConverter(PDFConverter): - CONTROL = re.compile(ur'[\x00-\x08\x0b-\x0c\x0e-\x1f]') + CONTROL = re.compile(r'[\x00-\x08\x0b-\x0c\x0e-\x1f]') - def __init__(self, rsrcmgr, outfp, codec='utf-8', pageno=1, + def __init__(self, rsrcmgr, outfp, pageno=1, laparams=None, imagewriter=None, stripcontrol=False): - PDFConverter.__init__(self, rsrcmgr, outfp, codec=codec, pageno=pageno, laparams=laparams) + PDFConverter.__init__(self, rsrcmgr, outfp, pageno=pageno, laparams=laparams) self.imagewriter = imagewriter self.stripcontrol = stripcontrol self.write_header() return def write_header(self): - self.outfp.write('\n' % self.codec) + self.outfp.write('\n') self.outfp.write('\n') return @@ -420,7 +419,7 @@ def write_footer(self): def write_text(self, text): if self.stripcontrol: text = self.CONTROL.sub(u'', text) - self.outfp.write(enc(text, self.codec)) + self.outfp.write(q(text)) return def receive_layout(self, ltpage): @@ -478,7 +477,7 @@ def render(item): self.outfp.write('\n') elif isinstance(item, LTChar): self.outfp.write('' % - (enc(item.fontname), bbox2str(item.bbox), item.size)) + (q(item.fontname), bbox2str(item.bbox), item.size)) self.write_text(item.get_text()) self.outfp.write('\n') elif isinstance(item, LTText): @@ -487,7 +486,7 @@ def render(item): if self.imagewriter is not None: name = self.imagewriter.export_image(item) self.outfp.write('\n' % - (enc(name), item.width, item.height)) + (q(name), item.width, item.height)) else: self.outfp.write('\n' % (item.width, item.height)) diff --git a/pdfminer/encodingdb.py b/pdfminer/encodingdb.py index b3263bda..648b8f0d 100644 --- a/pdfminer/encodingdb.py +++ b/pdfminer/encodingdb.py @@ -17,12 +17,12 @@ def name2unicode(name): m = STRIP_NAME.search(name) if not m: raise KeyError(name) - return unichr(int(m.group(0))) + return chr(int(m.group(0))) ## EncodingDB ## -class EncodingDB(object): +class EncodingDB: std2unicode = {} mac2unicode = {} diff --git a/pdfminer/image.py b/pdfminer/image.py index e7b98e8f..34f27adf 100644 --- a/pdfminer/image.py +++ b/pdfminer/image.py @@ -15,7 +15,7 @@ def align32(x): ## BMPWriter ## -class BMPWriter(object): +class BMPWriter: def __init__(self, fp, bits, width, height): self.fp = fp @@ -45,7 +45,7 @@ def __init__(self, fp, bits, width, height): self.fp.write(struct.pack('BBBx', i, i, i)) elif ncols == 256: # grayscale color table - for i in xrange(256): + for i in range(256): self.fp.write(struct.pack('BBBx', i, i, i)) self.pos0 = self.fp.tell() self.pos1 = self.pos0 + self.datasize @@ -59,7 +59,7 @@ def write_line(self, y, data): ## ImageWriter ## -class ImageWriter(object): +class ImageWriter: def __init__(self, outdir): self.outdir = outdir @@ -80,43 +80,42 @@ def export_image(self, image): ext = '.%d.%dx%d.img' % (image.bits, width, height) name = image.name+ext path = os.path.join(self.outdir, name) - fp = file(path, 'wb') - if ext == '.jpg': - raw_data = stream.get_rawdata() - if LITERAL_DEVICE_CMYK in image.colorspace: - from PIL import Image - from PIL import ImageChops - ifp = BytesIO(raw_data) - i = Image.open(ifp) - i = ImageChops.invert(i) - i = i.convert('RGB') - i.save(fp, 'JPEG') + with open(path, 'wb') as fp: + if ext == '.jpg': + raw_data = stream.get_rawdata() + if LITERAL_DEVICE_CMYK in image.colorspace: + from PIL import Image + from PIL import ImageChops + ifp = BytesIO(raw_data) + i = Image.open(ifp) + i = ImageChops.invert(i) + i = i.convert('RGB') + i.save(fp, 'JPEG') + else: + fp.write(raw_data) + elif image.bits == 1: + bmp = BMPWriter(fp, 1, width, height) + data = stream.get_data() + i = 0 + width = (width+7)//8 + for y in range(height): + bmp.write_line(y, data[i:i+width]) + i += width + elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_RGB: + bmp = BMPWriter(fp, 24, width, height) + data = stream.get_data() + i = 0 + width = width*3 + for y in range(height): + bmp.write_line(y, data[i:i+width]) + i += width + elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_GRAY: + bmp = BMPWriter(fp, 8, width, height) + data = stream.get_data() + i = 0 + for y in range(height): + bmp.write_line(y, data[i:i+width]) + i += width else: - fp.write(raw_data) - elif image.bits == 1: - bmp = BMPWriter(fp, 1, width, height) - data = stream.get_data() - i = 0 - width = (width+7)//8 - for y in xrange(height): - bmp.write_line(y, data[i:i+width]) - i += width - elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_RGB: - bmp = BMPWriter(fp, 24, width, height) - data = stream.get_data() - i = 0 - width = width*3 - for y in xrange(height): - bmp.write_line(y, data[i:i+width]) - i += width - elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_GRAY: - bmp = BMPWriter(fp, 8, width, height) - data = stream.get_data() - i = 0 - for y in xrange(height): - bmp.write_line(y, data[i:i+width]) - i += width - else: - fp.write(stream.get_data()) - fp.close() + fp.write(stream.get_data()) return name diff --git a/pdfminer/layout.py b/pdfminer/layout.py index 6477effa..9aff3d9c 100644 --- a/pdfminer/layout.py +++ b/pdfminer/layout.py @@ -12,7 +12,7 @@ ## IndexAssigner ## -class IndexAssigner(object): +class IndexAssigner: def __init__(self, index=0): self.index = index @@ -30,7 +30,7 @@ def run(self, obj): ## LAParams ## -class LAParams(object): +class LAParams: def __init__(self, line_overlap=0.5, @@ -56,7 +56,7 @@ def __repr__(self): ## LTItem ## -class LTItem(object): +class LTItem: def analyze(self, laparams): """Perform the layout analysis.""" @@ -65,7 +65,7 @@ def analyze(self, laparams): ## LTText ## -class LTText(object): +class LTText: def __repr__(self): return ('<%s %r>' % @@ -514,7 +514,7 @@ def group_objects(self, laparams, objs): obj0.voverlap(obj1)) and (obj0.hdistance(obj1) < max(obj0.width, obj1.width) * laparams.char_margin)) - + # valign: obj0 and obj1 is vertically aligned. # # +------+ @@ -536,7 +536,7 @@ def group_objects(self, laparams, objs): 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) @@ -630,12 +630,12 @@ def isany(obj1, obj2): def key_obj(t): (c,d,_,_) = t return (c,d) - + # XXX this still takes O(n^2) :( dists = [] - for i in xrange(len(boxes)): + for i in range(len(boxes)): obj1 = boxes[i] - for j in xrange(i+1, len(boxes)): + for j in range(i+1, len(boxes)): obj2 = boxes[j] dists.append((0, dist(obj1, obj2), obj1, obj2)) # We could use dists.sort(), but it would randomize the test result. diff --git a/pdfminer/lzw.py b/pdfminer/lzw.py index aef36671..203ee50c 100644 --- a/pdfminer/lzw.py +++ b/pdfminer/lzw.py @@ -8,7 +8,7 @@ class CorruptDataError(Exception): ## LZWDecoder ## -class LZWDecoder(object): +class LZWDecoder: def __init__(self, fp): self.fp = fp @@ -40,14 +40,14 @@ def readbits(self, bits): x = self.fp.read(1) if not x: raise EOFError - self.buff = ord(x) + self.buff = x[0] self.bpos = 0 return v def feed(self, code): x = b'' if code == 256: - self.table = [chr(c) for c in xrange(256)] # 0-255 + self.table = [bytes([c]) for c in range(256)] # 0-255 self.table.append(None) # 256 self.table.append(None) # 257 self.prevbuf = b'' @@ -95,12 +95,12 @@ def run(self): # lzwdecode def lzwdecode(data): """ - >>> lzwdecode(b'\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01') - '\x2d\x2d\x2d\x2d\x2d\x41\x2d\x2d\x2d\x42' + >>> lzwdecode(bytes.fromhex('800b6050220c0c8501')) + b'-----A---B' """ fp = BytesIO(data) return b''.join(LZWDecoder(fp).run()) if __name__ == '__main__': import doctest - doctest.testmod() + print('pdfminer.lzw', doctest.testmod()) diff --git a/pdfminer/pdfcolor.py b/pdfminer/pdfcolor.py index 83843961..e93f7df2 100644 --- a/pdfminer/pdfcolor.py +++ b/pdfminer/pdfcolor.py @@ -9,7 +9,7 @@ LITERAL_DEVICE_CMYK = LIT('DeviceCMYK') -class PDFColorSpace(object): +class PDFColorSpace: def __init__(self, name, ncomponents): self.name = name @@ -31,4 +31,4 @@ def __repr__(self): 'Separation': 1, 'Indexed': 1, 'Pattern': 1, - }.iteritems()) + }.items()) diff --git a/pdfminer/pdfdevice.py b/pdfminer/pdfdevice.py index 3efee9ed..70223ce5 100644 --- a/pdfminer/pdfdevice.py +++ b/pdfminer/pdfdevice.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from .utils import mult_matrix from .utils import translate_matrix -from .utils import enc +from .utils import q from .utils import bbox2str from .utils import isnumber from .pdffont import PDFUnicodeNotDefined @@ -9,7 +9,7 @@ ## PDFDevice ## -class PDFDevice(object): +class PDFDevice: def __init__(self, rsrcmgr): self.rsrcmgr = rsrcmgr @@ -128,10 +128,9 @@ def render_char(self, matrix, font, fontsize, scaling, rise, cid): ## class TagExtractor(PDFDevice): - def __init__(self, rsrcmgr, outfp, codec='utf-8'): + def __init__(self, rsrcmgr, outfp): PDFDevice.__init__(self, rsrcmgr) self.outfp = outfp - self.codec = codec self.pageno = 0 self._stack = [] return @@ -140,7 +139,7 @@ def render_string(self, textstate, seq): font = textstate.font text = '' for obj in seq: - if not isinstance(obj, str): + if not isinstance(obj, bytes): continue chars = font.decode(obj) for cid in chars: @@ -149,7 +148,7 @@ def render_string(self, textstate, seq): text += char except PDFUnicodeNotDefined: pass - self.outfp.write(enc(text, self.codec)) + self.outfp.write(q(text)) return def begin_page(self, page, ctm): @@ -165,16 +164,16 @@ def end_page(self, page): 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())) - self.outfp.write('<%s%s>' % (enc(tag.name), s)) + s = ''.join(' %s="%s"' % (q(k), q(str(v))) for (k, v) + in sorted(props.items())) + self.outfp.write('<%s%s>' % (q(tag.name), s)) self._stack.append(tag) return def end_tag(self): assert self._stack tag = self._stack.pop(-1) - self.outfp.write('' % enc(tag.name)) + self.outfp.write('' % q(tag.name)) return def do_tag(self, tag, props=None): diff --git a/pdfminer/pdfdocument.py b/pdfminer/pdfdocument.py index 66b575ae..86ab7e97 100644 --- a/pdfminer/pdfdocument.py +++ b/pdfminer/pdfdocument.py @@ -24,7 +24,7 @@ from .pdftypes import PDFObjectNotFound from .pdftypes import decipher_all from .pdftypes import int_value -from .pdftypes import str_value +from .pdftypes import bytes_value from .pdftypes import list_value from .pdftypes import dict_value from .pdftypes import stream_value @@ -63,10 +63,10 @@ class PDFTextExtractionNotAllowed(PDFEncryptionError): ## XRefs ## -class PDFBaseXRef(object): +class PDFBaseXRef: debug = False - + def get_trailer(self): raise NotImplementedError @@ -109,10 +109,10 @@ def load(self, parser): if len(f) != 2: raise PDFNoValidXRef('Trailer not found: %r: line=%r' % (parser, line)) try: - (start, nobjs) = map(long, f) + (start, nobjs) = map(int, f) except ValueError: raise PDFNoValidXRef('Invalid line: %r: line=%r' % (parser, line)) - for objid in xrange(start, start+nobjs): + for objid in range(start, start+nobjs): try: (_, line) = parser.nextline() except PSEOF: @@ -123,12 +123,12 @@ def load(self, parser): (pos, genno, use) = f if use != b'n': continue - self.offsets[objid] = (None, long(pos), int(genno)) + self.offsets[objid] = (None, int(pos), int(genno)) if self.debug: logging.info('xref objects: %r' % self.offsets) self.load_trailer(parser) return - KEYWORD_TRAILER = KWD('trailer') + KEYWORD_TRAILER = KWD(b'trailer') def load_trailer(self, parser): try: @@ -147,7 +147,7 @@ def get_trailer(self): return self.trailer def get_objids(self): - return self.offsets.iterkeys() + return self.offsets.keys() def get_pos(self, objid): try: @@ -163,7 +163,7 @@ class PDFXRefFallback(PDFXRef): def __repr__(self): return '' % (self.offsets.keys()) - PDFOBJ_CUE = re.compile(r'^(\d+)\s+(\d+)\s+obj\b') + PDFOBJ_CUE = re.compile(br'^(\d+)\s+(\d+)\s+obj\b') def load(self, parser): parser.seek(0) @@ -204,7 +204,7 @@ def load(self, parser): except PSEOF: pass n = min(n, len(objs)//2) - for index in xrange(n): + for index in range(n): objid1 = objs[index*2] self.offsets[objid1] = (objid, index, 0) return @@ -215,7 +215,7 @@ def load(self, parser): class PDFXRefStream(PDFBaseXRef): debug = False - + def __init__(self): self.data = None self.entlen = None @@ -253,7 +253,7 @@ def get_trailer(self): def get_objids(self): for (start, nobjs) in self.ranges: - for i in xrange(nobjs): + for i in range(nobjs): offset = self.entlen * i ent = self.data[offset:offset+self.entlen] f1 = nunpack(ent[:self.fl1], 1) @@ -287,7 +287,7 @@ def get_pos(self, objid): ## PDFSecurityHandler ## -class PDFStandardSecurityHandler(object): +class PDFStandardSecurityHandler: PASSWORD_PADDING = (b'(\xbfN^Nu\x8aAd\x00NV\xff\xfa\x01\x08' b'..\x00\xb6\xd0h>\x80/\x0c\xa9\xfedSiz') @@ -311,8 +311,8 @@ def init_params(self): self.v = int_value(self.param.get('V', 0)) self.r = int_value(self.param['R']) self.p = int_value(self.param['P']) - self.o = str_value(self.param['O']) - self.u = str_value(self.param['U']) + self.o = bytes_value(self.param['O']) + self.u = bytes_value(self.param['U']) self.length = int_value(self.param.get('Length', 40)) return @@ -341,7 +341,7 @@ def compute_u(self, key): hash.update(self.docid[0]) # 3 result = ARC4.new(key).encrypt(hash.digest()) # 4 for i in range(1, 20): # 5 - k = b''.join(chr(ord(c) ^ i) for c in key) + k = bytes( (c ^ i) for c in key ) result = ARC4.new(k).encrypt(result) result += result # 6 return result @@ -400,7 +400,7 @@ def authenticate_owner_password(self, password): else: user_password = self.o for i in range(19, -1, -1): - k = b''.join(chr(ord(c) ^ i) for c in key) + k = bytes( (c ^ i) for c in key ) user_password = ARC4.new(k).decrypt(user_password) return self.authenticate_user_password(user_password) @@ -472,8 +472,8 @@ class PDFStandardSecurityHandlerV5(PDFStandardSecurityHandlerV4): def init_params(self): super(PDFStandardSecurityHandlerV5, self).init_params() self.length = 256 - self.oe = str_value(self.param['OE']) - self.ue = str_value(self.param['UE']) + self.oe = bytes_value(self.param['OE']) + self.ue = bytes_value(self.param['UE']) self.o_hash = self.o[:32] self.o_validation_salt = self.o[32:40] self.o_key_salt = self.o[40:] @@ -489,7 +489,7 @@ def get_cfm(self, name): return None def authenticate(self, password): - password = password.encode('utf-8')[:127] + password = password[:127] hash = SHA256.new(password) hash.update(self.o_validation_salt) hash.update(self.u) @@ -512,7 +512,7 @@ def decrypt_aes256(self, objid, genno, data): ## PDFDocument ## -class PDFDocument(object): +class PDFDocument: """PDFDocument object represents a PDF document. @@ -639,7 +639,7 @@ def _get_objects(self, stream): pass return (objs, n) - KEYWORD_OBJ = KWD('obj') + KEYWORD_OBJ = KWD(b'obj') def _getobj_parse(self, pos, objid): self._parser.seek(pos) @@ -698,7 +698,7 @@ 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'])) + title = decode_text(bytes_value(entry['Title'])) dest = entry.get('Dest') action = entry.get('A') se = entry.get('SE') @@ -768,7 +768,7 @@ def find_xref(self, parser): raise PDFNoValidXRef('Unexpected EOF') if self.debug: logging.info('xref found: pos=%r' % prev) - return long(prev) + return int(prev) # read xref table def read_xref_from(self, parser, start, xrefs): diff --git a/pdfminer/pdffont.py b/pdfminer/pdffont.py index 6f8c6191..253119f0 100644 --- a/pdfminer/pdffont.py +++ b/pdfminer/pdffont.py @@ -19,6 +19,7 @@ from .pdftypes import resolve1 from .pdftypes import int_value from .pdftypes import num_value +from .pdftypes import bytes_value from .pdftypes import list_value from .pdftypes import dict_value from .pdftypes import stream_value @@ -43,7 +44,7 @@ def get_widths(seq): r.append(v) if len(r) == 3: (char1, char2, w) = r - for i in xrange(char1, char2+1): + for i in range(char1, char2+1): widths[i] = w r = [] return widths @@ -66,7 +67,7 @@ def get_widths2(seq): r.append(v) if len(r) == 5: (char1, char2, w, vx, vy) = r - for i in xrange(char1, char2+1): + for i in range(char1, char2+1): widths[i] = (w, (vx, vy)) r = [] return widths @@ -77,7 +78,7 @@ def get_widths2(seq): ## FontMetricsDB ## -class FontMetricsDB(object): +class FontMetricsDB: @classmethod def get_metrics(klass, fontname): @@ -175,7 +176,7 @@ def getdict(data): return d -class CFFFont(object): +class CFFFont: STANDARD_STRINGS = ( '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', @@ -258,13 +259,13 @@ class CFFFont(object): 'Light', 'Medium', 'Regular', 'Roman', 'Semibold', ) - class INDEX(object): + class INDEX: def __init__(self, fp): self.fp = fp self.offsets = [] (count, offsize) = struct.unpack('>HB', self.fp.read(3)) - for i in xrange(count+1): + for i in range(count+1): self.offsets.append(nunpack(self.fp.read(offsize))) self.base = self.fp.tell()-1 self.fp.seek(self.base+self.offsets[-1]) @@ -281,7 +282,7 @@ def __getitem__(self, i): 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 range(len(self))) def __init__(self, name, fp): self.name = name @@ -321,9 +322,9 @@ def __init__(self, name, fp): # Format 1 (n,) = struct.unpack('B', self.fp.read(1)) code = 0 - for i in xrange(n): + for i in range(n): (first, nleft) = struct.unpack('BB', self.fp.read(2)) - for gid in xrange(first, first+nleft+1): + for gid in range(first, first+nleft+1): self.code2gid[code] = gid self.gid2code[gid] = code code += 1 @@ -346,9 +347,9 @@ def __init__(self, name, fp): # Format 1 (n,) = struct.unpack('B', self.fp.read(1)) sid = 0 - for i in xrange(n): + for i in range(n): (first, nleft) = struct.unpack('BB', self.fp.read(2)) - for gid in xrange(first, first+nleft+1): + for gid in range(first, first+nleft+1): name = self.getstr(sid) self.name2gid[name] = gid self.gid2name[gid] = name @@ -371,7 +372,7 @@ def getstr(self, sid): ## TrueTypeFont ## -class TrueTypeFont(object): +class TrueTypeFont: class CMapNotFound(Exception): pass @@ -382,7 +383,7 @@ def __init__(self, name, fp): self.tables = {} self.fonttype = fp.read(4) (ntables, _1, _2, _3) = struct.unpack('>HHHH', fp.read(8)) - for _ in xrange(ntables): + for _ in range(ntables): (name, tsum, offset, length) = struct.unpack('>4sLLL', fp.read(16)) self.tables[name] = (offset, length) return @@ -395,7 +396,7 @@ def create_unicode_map(self): fp.seek(base_offset) (version, nsubtables) = struct.unpack('>HH', fp.read(4)) subtables = [] - for i in xrange(nsubtables): + for i in range(nsubtables): subtables.append(struct.unpack('>HHL', fp.read(8))) char2gid = {} # Only supports subtable type 0, 2 and 4. @@ -411,7 +412,7 @@ def create_unicode_map(self): firstbytes[k//8] = i nhdrs = max(subheaderkeys)//8 + 1 hdrs = [] - for i in xrange(nhdrs): + for i in range(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: @@ -419,7 +420,7 @@ def create_unicode_map(self): continue first = firstcode + (firstbytes[i] << 8) fp.seek(pos) - for c in xrange(entcount): + for c in range(entcount): gid = struct.unpack('>H', fp.read(2)) if gid: gid += delta @@ -436,16 +437,16 @@ def create_unicode_map(self): for (ec, sc, idd, idr) in zip(ecs, scs, idds, idrs): if idr: fp.seek(pos+idr) - for c in xrange(sc, ec+1): + for c in range(sc, ec+1): char2gid[c] = (struct.unpack('>H', fp.read(2))[0] + idd) & 0xffff else: - for c in xrange(sc, ec+1): + for c in range(sc, ec+1): char2gid[c] = (c + idd) & 0xffff else: assert 0 # create unicode map unicode_map = FileUnicodeMap() - for (char, gid) in char2gid.iteritems(): + for (char, gid) in char2gid.items(): unicode_map.add_cid2unichr(gid, char) return unicode_map @@ -464,7 +465,7 @@ class PDFUnicodeNotDefined(PDFFontError): # PDFFont -class PDFFont(object): +class PDFFont: def __init__(self, descriptor, widths, default_width=None): self.descriptor = descriptor @@ -491,8 +492,8 @@ def is_vertical(self): def is_multibyte(self): return False - def decode(self, bytes): - return map(ord, bytes) + def decode(self, data): + return list(data) def get_ascent(self): return self.ascent * self.vscale @@ -638,8 +639,9 @@ def __init__(self, rsrcmgr, spec): raise PDFFontError('BaseFont is missing') self.basefont = 'unknown' self.cidsysteminfo = dict_value(spec.get('CIDSystemInfo', {})) - self.cidcoding = '%s-%s' % (self.cidsysteminfo.get('Registry', 'unknown'), - self.cidsysteminfo.get('Ordering', 'unknown')) + registry = bytes_value(self.cidsysteminfo.get('Registry', b'unknown')) + ordering = bytes_value(self.cidsysteminfo.get('Ordering', b'unknown')) + self.cidcoding = (registry + b'-' + ordering).decode('ascii') try: name = literal_name(spec['Encoding']) except KeyError: @@ -684,10 +686,10 @@ def __init__(self, rsrcmgr, spec): 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()) + self.disps = dict((cid, (vx, vy)) for (cid, (_, (vx, vy))) in widths.items()) (vy, w) = spec.get('DW2', [880, -1000]) self.default_disp = (None, vy) - widths = dict((cid, w) for (cid, (w, _)) in widths.iteritems()) + widths = dict((cid, w) for (cid, (w, _)) in widths.items()) default_width = w else: # writing mode: horizontal @@ -707,8 +709,8 @@ def is_vertical(self): def is_multibyte(self): return True - def decode(self, bytes): - return self.cmap.decode(bytes) + def decode(self, data): + return self.cmap.decode(data) def char_disp(self, cid): "Returns an integer for horizontal fonts, a tuple for vertical fonts." @@ -726,11 +728,10 @@ def to_unichr(self, cid): # main def main(argv): for fname in argv[1:]: - fp = file(fname, 'rb') - #font = TrueTypeFont(fname, fp) - font = CFFFont(fname, fp) - print (font) - fp.close() + with open(fname, 'rb') as fp: + #font = TrueTypeFont(fname, fp) + font = CFFFont(fname, fp) + print (font) return if __name__ == '__main__': diff --git a/pdfminer/pdfinterp.py b/pdfminer/pdfinterp.py index 3f3f3934..0f0d7935 100644 --- a/pdfminer/pdfinterp.py +++ b/pdfminer/pdfinterp.py @@ -52,7 +52,7 @@ class PDFInterpreterError(PDFException): ## PDFTextState ## -class PDFTextState(object): +class PDFTextState: def __init__(self): self.font = None @@ -98,7 +98,7 @@ def reset(self): ## PDFGraphicState ## -class PDFGraphicState(object): +class PDFGraphicState: def __init__(self): self.linewidth = 0 @@ -130,7 +130,7 @@ def __repr__(self): ## Resource Manager ## -class PDFResourceManager(object): +class PDFResourceManager: """Repository of shared resources. @@ -140,7 +140,7 @@ class PDFResourceManager(object): """ debug = False - + def __init__(self, caching=True): self.caching = caching self._cached_fonts = {} @@ -256,12 +256,12 @@ def get_inline_data(self, pos, target=b'EI'): while i <= len(target): self.fillbuf() if i: - c = self.buf[self.charpos] + c = self.buf[self.charpos:self.charpos+1] data += c self.charpos += 1 if len(target) <= i and c.isspace(): i += 1 - elif i < len(target) and c == target[i]: + elif i < len(target) and c == target[i:i+1]: i += 1 else: i = 0 @@ -311,7 +311,7 @@ def do_keyword(self, pos, token): ## Interpreter ## -class PDFPageInterpreter(object): +class PDFPageInterpreter: debug = 0 @@ -344,23 +344,23 @@ def get_colorspace(spec): return PDFColorSpace(name, len(list_value(spec[1]))) else: return PREDEFINED_COLORSPACE.get(name) - for (k, v) in dict_value(resources).iteritems(): + for (k, v) in dict_value(resources).items(): if self.debug: logging.debug('Resource: %r: %r' % (k, v)) if k == 'Font': - for (fontid, spec) in dict_value(v).iteritems(): + for (fontid, spec) in dict_value(v).items(): 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).items(): 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).items(): self.xobjmap[xobjid] = xobjstrm return @@ -379,7 +379,9 @@ def init_state(self, ctm): # set some global states. self.scs = self.ncs = None if self.csmap: - self.scs = self.ncs = self.csmap.values()[0] + for v in self.csmap.values(): + self.scs = self.ncs = v + break return def push(self, obj): @@ -864,11 +866,11 @@ def execute(self, streams): except PSEOF: break if isinstance(obj, PSKeyword): - name = keyword_name(obj) + name = keyword_name(obj).decode('ascii') 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 + nargs = func.__code__.co_argcount-1 if nargs: args = self.pop(nargs) if self.debug: diff --git a/pdfminer/pdfpage.py b/pdfminer/pdfpage.py index a48767c6..debdf954 100644 --- a/pdfminer/pdfpage.py +++ b/pdfminer/pdfpage.py @@ -17,7 +17,7 @@ ## PDFPage ## -class PDFPage(object): +class PDFPage: """An object that holds the information about a page. @@ -84,7 +84,7 @@ def search(obj, parent): else: objid = obj.objid tree = dict_value(obj).copy() - for (k, v) in parent.iteritems(): + for (k, v) in parent.items(): 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: diff --git a/pdfminer/pdftypes.py b/pdfminer/pdftypes.py index 82c29230..3768210f 100644 --- a/pdfminer/pdftypes.py +++ b/pdfminer/pdftypes.py @@ -92,7 +92,7 @@ def resolve_all(x, default=None): if isinstance(x, list): x = [resolve_all(v, default=default) for v in x] elif isinstance(x, dict): - for (k, v) in x.iteritems(): + for (k, v) in x.items(): x[k] = resolve_all(v, default=default) return x @@ -100,12 +100,12 @@ def resolve_all(x, default=None): def decipher_all(decipher, objid, genno, x): """Recursively deciphers the given object. """ - if isinstance(x, str): + if isinstance(x, bytes): return decipher(objid, genno, x) if isinstance(x, list): 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.items(): x[k] = decipher_all(decipher, objid, genno, v) return x @@ -138,12 +138,12 @@ def num_value(x): return x -def str_value(x): +def bytes_value(x): x = resolve1(x) - if not isinstance(x, str): + if not isinstance(x, bytes): if STRICT: - raise PDFTypeError('String required: %r' % x) - return '' + raise PDFTypeError('Bytes required: %r' % x) + return b'' return x diff --git a/pdfminer/psparser.py b/pdfminer/psparser.py index 7270b454..d8894006 100644 --- a/pdfminer/psparser.py +++ b/pdfminer/psparser.py @@ -33,7 +33,7 @@ class PSValueError(PSException): ## PSObject ## -class PSObject(object): +class PSObject: """Base class for all PS or PDF-related data types.""" @@ -82,12 +82,12 @@ def __init__(self, name): return def __repr__(self): - return self.name + return self.name.decode('ascii') ## PSSymbolTable ## -class PSSymbolTable(object): +class PSSymbolTable: """A utility class for storing PSLiteral/PSKeyword objects. @@ -150,10 +150,13 @@ def keyword_name(x): END_KEYWORD = re.compile(br'[#/%\[\]()<>{}\s]') END_STRING = re.compile(br'[()\134]') OCT_STRING = re.compile(br'[0-7]') -ESC_STRING = {b'b': 8, b't': 9, b'n': 10, b'f': 12, b'r': 13, b'(': 40, b')': 41, b'\\': 92} +ESC_STRING = { + b'b': b'\x08', b't': b'\x09', b'n': b'\x0a', b'f': b'\x0c', + b'r': b'\x0d', b'(': b'(', b')': b')', b'\\': b'\\' +} -class PSBaseParser(object): +class PSBaseParser: """Most basic PostScript parser that performs only tokenization. """ @@ -225,7 +228,7 @@ def nextline(self): while 1: self.fillbuf() if eol: - c = self.buf[self.charpos] + c = self.buf[self.charpos:self.charpos+1] # handle b'\r\n' if c == b'\n': linebuf += c @@ -235,7 +238,7 @@ def nextline(self): if m: linebuf += self.buf[self.charpos:m.end(0)] self.charpos = m.end(0) - if linebuf[-1] == b'\r': + if linebuf[-1:] == b'\r': eol = True else: break @@ -276,7 +279,7 @@ def _parse_main(self, s, i): if not m: return len(s) j = m.start(0) - c = s[j] + c = s[j:j+1] self._curtokenpos = self.bufpos+j if c == b'%': self._curtoken = b'%' @@ -323,7 +326,7 @@ def _parse_comment(self, s, i): m = EOL.search(s, i) if not m: self._curtoken += s[i:] - return (self._parse_comment, len(s)) + return len(s) j = m.start(0) self._curtoken += s[i:j] self._parse1 = self._parse_main @@ -338,12 +341,12 @@ def _parse_literal(self, s, i): return len(s) j = m.start(0) self._curtoken += s[i:j] - c = s[j] + c = s[j:j+1] if c == b'#': self.hex = b'' self._parse1 = self._parse_literal_hex return j+1 - + try: # Try to interpret the token as a utf-8 string utoken = self._curtoken.decode('utf-8') @@ -356,13 +359,13 @@ def _parse_literal(self, s, i): return j def _parse_literal_hex(self, s, i): - c = s[i] + c = s[i:i+1] if HEX.match(c) and len(self.hex) < 2: self.hex += c return i+1 if self.hex: try: - self._curtoken += chr(int(self.hex, 16)) + self._curtoken += bytes([int(self.hex, 16)]) except ValueError: pass self._parse1 = self._parse_literal @@ -375,7 +378,7 @@ def _parse_number(self, s, i): return len(s) j = m.start(0) self._curtoken += s[i:j] - c = s[j] + c = s[j:j+1] if c == b'.': self._curtoken += c self._parse1 = self._parse_float @@ -425,7 +428,7 @@ def _parse_string(self, s, i): return len(s) j = m.start(0) self._curtoken += s[i:j] - c = s[j] + c = s[j:j+1] if c == b'\\': self.oct = b'' self._parse1 = self._parse_string_1 @@ -439,29 +442,29 @@ def _parse_string(self, s, i): if self.paren: # WTF, they said balanced parens need no special treatment. self._curtoken += c return j+1 - self._add_token(str(self._curtoken)) + self._add_token(self._curtoken) self._parse1 = self._parse_main return j+1 def _parse_string_1(self, s, i): - c = s[i] + c = s[i:i+1] if OCT_STRING.match(c) and len(self.oct) < 3: self.oct += c return i+1 if self.oct: try: - self._curtoken += chr(int(self.oct, 8)) + self._curtoken += bytes([int(self.oct, 8)]) except ValueError: pass self._parse1 = self._parse_string return i if c in ESC_STRING: - self._curtoken += chr(ESC_STRING[c]) + self._curtoken += ESC_STRING[c] self._parse1 = self._parse_string return i+1 def _parse_wopen(self, s, i): - c = s[i] + c = s[i:i+1] if c == b'<': self._add_token(KEYWORD_DICT_BEGIN) self._parse1 = self._parse_main @@ -471,7 +474,7 @@ def _parse_wopen(self, s, i): return i def _parse_wclose(self, s, i): - c = s[i] + c = s[i:i+1] if c == b'>': self._add_token(KEYWORD_DICT_END) i += 1 @@ -486,7 +489,7 @@ def _parse_hexstring(self, s, i): j = m.start(0) self._curtoken += s[i:j] try: - token = HEX_PAIR.sub(lambda m: chr(int(m.group(0), 16)), + token = HEX_PAIR.sub(lambda m: bytes([int(m.group(0), 16)]), SPC.sub(b'', self._curtoken)) self._add_token(token) except ValueError: @@ -573,7 +576,7 @@ def nextobject(self): while not self.results: (pos, token) = self.nexttoken() #print (pos,token), (self.curtype, self.curstack) - if isinstance(token, (int, long, float, bool, str, PSLiteral)): + if isinstance(token, (int, float, bool, bytes, PSLiteral)): # normal token self.push((pos, token)) elif token == KEYWORD_ARRAY_BEGIN: @@ -671,12 +674,12 @@ class TestPSBaseParser(unittest.TestCase): OBJS = [ (23, LIT('a')), (25, LIT('BCD')), (30, LIT('Some_Name')), (41, LIT('foo_xbaa')), (54, 0), (56, 1), (59, -2), (62, 0.5), - (65, 1.234), (71, 'abc'), (77, ''), (80, 'abc ( def ) ghi'), - (98, 'def \x00 4ghi'), (118, 'bach\\slask'), (132, 'foo\nbaa'), - (143, 'this % is not a comment.'), (170, 'foo\nbaa'), (180, 'foobaa'), - (191, ''), (194, ' '), (199, '@@ '), (211, '\xab\xcd\x00\x124\x05'), - (230, LIT('a')), (232, LIT('b')), (234, ['c']), (246, [1, 'z']), - (258, {'foo': 'bar'}), + (65, 1.234), (71, b'abc'), (77, b''), (80, b'abc ( def ) ghi'), + (98, b'def \x00 4ghi'), (118, b'bach\\slask'), (132, b'foo\nbaa'), + (143, b'this % is not a comment.'), (170, b'foo\nbaa'), (180, b'foobaa'), + (191, b''), (194, b' '), (199, b'@@ '), (211, b'\xab\xcd\x00\x124\x05'), + (230, LIT('a')), (232, LIT('b')), (234, [b'c']), (246, [1, b'z']), + (258, {'foo': b'bar'}), ] def get_tokens(self, s): diff --git a/pdfminer/rijndael.py b/pdfminer/rijndael.py index 756dd467..28854c46 100644 --- a/pdfminer/rijndael.py +++ b/pdfminer/rijndael.py @@ -25,673 +25,673 @@ 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, + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, + 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, + 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, + 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, + 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, + 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, + 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, + 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, + 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, + 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, + 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, + 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, + 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, + 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, + 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, + 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, + 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, + 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, + 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, + 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, + 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, + 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, + 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, + 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, + 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, + 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, + 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, + 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, + 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, + 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, + 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, + 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, + 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a, ] 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, + 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, + 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, + 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, + 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, + 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, + 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, + 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, + 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, + 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, + 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, + 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, + 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, + 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, + 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a, + 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, + 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, + 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, + 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, + 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, + 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, + 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, + 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, + 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, + 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, + 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, + 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, + 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, + 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, + 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, + 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, + 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, + 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2, + 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, + 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, + 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, + 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, + 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, + 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, + 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, + 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, + 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, + 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, + 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, + 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, + 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, + 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, + 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, + 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, + 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, + 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, + 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, + 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, + 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, + 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, + 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, + 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, + 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, + 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, + 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, + 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, + 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, + 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, + 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, + 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616, ] 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, + 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, + 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, + 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, + 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, + 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, + 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, + 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, + 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, + 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, + 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, + 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, + 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, + 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, + 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a, + 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, + 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, + 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, + 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, + 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, + 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, + 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, + 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, + 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, + 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, + 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, + 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, + 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, + 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, + 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, + 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, + 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, + 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, + 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, + 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, + 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, + 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, + 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, + 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, + 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, + 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, + 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, + 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, + 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, + 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, + 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, + 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, + 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, + 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, + 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, + 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, + 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, + 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, + 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, + 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, + 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, + 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, + 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, + 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, + 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, + 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, + 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, + 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, + 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, + 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16, ] 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, + 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, + 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, + 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, + 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, + 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, + 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, + 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, + 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, + 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, + 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, + 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, + 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, + 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, + 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f, + 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, + 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, + 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, + 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, + 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, + 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, + 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, + 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, + 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, + 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, + 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, + 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, + 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, + 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, + 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, + 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, + 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, + 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, + 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, + 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, + 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, + 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, + 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, + 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, + 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, + 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, + 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, + 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, + 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, + 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, + 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, + 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, + 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, + 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, + 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, + 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, + 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, + 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, + 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, + 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, + 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, + 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, + 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, + 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, + 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, + 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, + 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, + 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, + 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, + 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, ] 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, + 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, + 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, + 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, + 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, + 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, + 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, + 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, + 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, + 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, + 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, + 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, + 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515, + 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, + 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, + 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, + 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575, + 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, + 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, + 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, + 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, + 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, + 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, + 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, + 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, + 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, + 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, + 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, + 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8, + 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, + 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, + 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, + 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2, + 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, + 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, + 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, + 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373, + 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, + 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, + 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, + 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, + 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, + 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, + 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, + 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979, + 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, + 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, + 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, + 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, + 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, + 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, + 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, + 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a, + 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, + 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, + 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, + 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, + 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, + 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, + 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, + 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf, + 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, + 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, + 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, + 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616, ] 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, + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, + 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, + 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, + 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, + 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, + 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, + 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, + 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, + 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, + 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, + 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, + 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, + 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, + 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, + 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, + 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, + 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, + 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, + 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, + 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, + 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, + 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, + 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, + 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, + 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, + 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, + 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, + 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, + 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, + 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, + 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, + 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, + 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, + 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742, ] 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, + 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, + 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, + 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, + 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, + 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, + 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, + 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, + 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, + 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, + 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, + 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, + 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, + 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, + 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, + 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, + 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, + 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, + 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, + 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, + 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10, + 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, + 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, + 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, + 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, + 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, + 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, + 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, + 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, + 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, + 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, + 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, + 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, + 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, + 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, + 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, + 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, + 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, + 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, + 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, + 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, + 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, + 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, + 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, + 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, + 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, + 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, + 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, + 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, + 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, + 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, + 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, + 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, + 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, + 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, + 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, + 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, + 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, + 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, + 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, + 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, + 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, + 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95, + 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, + 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857, ] 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, + 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, + 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3, + 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, + 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, + 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, + 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, + 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, + 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, + 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, + 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, + 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, + 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, + 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, + 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655, + 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, + 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, + 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, + 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, + 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, + 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, + 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, + 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, + 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, + 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, + 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, + 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, + 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, + 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, + 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, + 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, + 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, + 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, + 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, + 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, + 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, + 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, + 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, + 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, + 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, + 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, + 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, + 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, + 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, + 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, + 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, + 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, + 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, + 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, + 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, + 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, + 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, + 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, + 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, + 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, + 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, + 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, + 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, + 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, + 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, + 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, + 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, + 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, + 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, + 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8, ] 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, + 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, + 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, + 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, + 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, + 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, + 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, + 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, + 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, + 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, + 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, + 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, + 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, + 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, + 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, + 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, + 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, + 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, + 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, + 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, + 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, + 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, + 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, + 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, + 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, + 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, + 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, + 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, + 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, + 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, + 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, + 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, + 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, + 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, + 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, + 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, + 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, + 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, + 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, + 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, + 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, + 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, + 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, + 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, + 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, + 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, + 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, + 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, + 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, + 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, + 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, + 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, + 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, + 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, + 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, + 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, + 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, + 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, + 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, + 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, + 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, + 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, + 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff, + 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, + 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0, ] 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, + 0x52525252, 0x09090909, 0x6a6a6a6a, 0xd5d5d5d5, + 0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838, + 0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e, + 0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb, + 0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282, + 0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787, + 0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444, + 0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb, + 0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232, + 0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d, + 0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0x0b0b0b0b, + 0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e, + 0x08080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666, + 0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2, + 0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949, + 0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525, + 0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464, + 0x86868686, 0x68686868, 0x98989898, 0x16161616, + 0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc, + 0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292, + 0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050, + 0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada, + 0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757, + 0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484, + 0x90909090, 0xd8d8d8d8, 0xabababab, 0x00000000, + 0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0x0a0a0a0a, + 0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x05050505, + 0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x06060606, + 0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f, + 0xcacacaca, 0x3f3f3f3f, 0x0f0f0f0f, 0x02020202, + 0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x03030303, + 0x01010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b, + 0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141, + 0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea, + 0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece, + 0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373, + 0x96969696, 0xacacacac, 0x74747474, 0x22222222, + 0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585, + 0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8, + 0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e, + 0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171, + 0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989, + 0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0x0e0e0e0e, + 0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b, + 0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b, + 0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020, + 0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe, + 0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4, + 0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333, + 0x88888888, 0x07070707, 0xc7c7c7c7, 0x31313131, + 0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959, + 0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f, + 0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9, + 0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0x0d0d0d0d, + 0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f, + 0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef, + 0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d, + 0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0, + 0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c, + 0x83838383, 0x53535353, 0x99999999, 0x61616161, + 0x17171717, 0x2b2b2b2b, 0x04040404, 0x7e7e7e7e, + 0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626, + 0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363, + 0x55555555, 0x21212121, 0x0c0c0c0c, 0x7d7d7d7d, ] rcon = [ @@ -806,7 +806,7 @@ def rijndaelSetupDecrypt(key, keybits): j -= 4 # apply the inverse MixColumn transform to all round keys but the first and the last: p = 0 - for i in xrange(1, nrounds): + for i in range(1, nrounds): p += 4 rk[p+0] = ( Td0[Te4[(rk[p+0] >> 24) ] & 0xff] ^ @@ -1039,12 +1039,12 @@ def rijndaelDecrypt(rk, nrounds, ciphertext): # decrypt(key, fin, fout, keybits=256) -class RijndaelDecryptor(object): +class RijndaelDecryptor: """ - >>> key = b'00010203050607080a0b0c0d0f101112'.decode('hex') - >>> ciphertext = b'd8f532538289ef7d06b506a4fd5be9c9'.decode('hex') - >>> RijndaelDecryptor(key, 128).decrypt(ciphertext).encode('hex') + >>> key = bytes.fromhex('00010203050607080a0b0c0d0f101112') + >>> ciphertext = bytes.fromhex('d8f532538289ef7d06b506a4fd5be9c9') + >>> RijndaelDecryptor(key, 128).decrypt(ciphertext).hex() '506812a45f08c889b97f5980038b8359' """ @@ -1061,12 +1061,12 @@ def decrypt(self, ciphertext): # encrypt(key, fin, fout, keybits=256) -class RijndaelEncryptor(object): +class RijndaelEncryptor: """ - >>> key = b'00010203050607080a0b0c0d0f101112'.decode('hex') - >>> plaintext = b'506812a45f08c889b97f5980038b8359'.decode('hex') - >>> RijndaelEncryptor(key, 128).encrypt(plaintext).encode('hex') + >>> key = bytes.fromhex('00010203050607080a0b0c0d0f101112') + >>> plaintext = bytes.fromhex('506812a45f08c889b97f5980038b8359') + >>> RijndaelEncryptor(key, 128).encrypt(plaintext).hex() 'd8f532538289ef7d06b506a4fd5be9c9' """ @@ -1084,4 +1084,4 @@ def encrypt(self, plaintext): if __name__ == '__main__': import doctest - doctest.testmod() + print('pdfminer.rijndael', doctest.testmod()) diff --git a/pdfminer/runlength.py b/pdfminer/runlength.py index ba7b7421..f8bbb1de 100644 --- a/pdfminer/runlength.py +++ b/pdfminer/runlength.py @@ -7,7 +7,7 @@ # def rldecode(data): - """ + r""" RunLength decoder (Adobe version) implementation based on PDF Reference version 1.4 section 3.3.4: The RunLengthDecode filter decodes data that has been encoded in a @@ -21,28 +21,28 @@ def rldecode(data): denotes EOD. >>> s = b'\x05123456\xfa7\x04abcde\x80junk' >>> rldecode(s) - '1234567777777abcde' + b'1234567777777abcde' """ - decoded = [] + decoded = b'' i = 0 while i < len(data): #print 'data[%d]=:%d:' % (i,ord(data[i])) - length = ord(data[i]) + length = data[i] if length == 128: break if length >= 0 and length < 128: run = data[i+1:(i+1)+(length+1)] #print 'length=%d, run=%s' % (length+1,run) - decoded.append(run) + decoded += run i = (i+1) + (length+1) if length > 128: - run = data[i+1]*(257-length) + run = data[i+1:i+2]*(257-length) #print 'length=%d, run=%s' % (257-length,run) - decoded.append(run) + decoded += run i = (i+1) + 1 - return b''.join(decoded) + return decoded if __name__ == '__main__': import doctest - doctest.testmod() + print('pdfminer.runlength', doctest.testmod()) diff --git a/pdfminer/utils.py b/pdfminer/utils.py index 307c5e79..1ff446ef 100644 --- a/pdfminer/utils.py +++ b/pdfminer/utils.py @@ -3,7 +3,7 @@ Miscellaneous Routines. """ import struct -from sys import maxint as INF +from sys import maxsize as INF ## PNG Predictor @@ -16,8 +16,8 @@ def apply_png_predictor(pred, colors, columns, bitspercomponent, data): i = 0 buf = b'' line0 = b'\x00' * columns - for i in xrange(0, len(data), nbytes+1): - ft = data[i] + for i in range(0, len(data), nbytes+1): + ft = data[i:i+1] i += 1 line1 = data[i:i+nbytes] line2 = b'' @@ -28,19 +28,19 @@ def apply_png_predictor(pred, colors, columns, bitspercomponent, data): # PNG sub (UNTESTED) c = 0 for b in line1: - c = (c+ord(b)) & 255 - line2 += chr(c) + c = (c+b) & 255 + line2 += bytes([c]) elif ft == b'\x02': # PNG up for (a, b) in zip(line0, line1): - c = (ord(a)+ord(b)) & 255 - line2 += chr(c) + c = (a+b) & 255 + line2 += bytes([c]) elif ft == b'\x03': # PNG average (UNTESTED) c = 0 for (a, b) in zip(line0, line1): - c = ((c+ord(a)+ord(b))//2) & 255 - line2 += chr(c) + c = ((c+a+b)//2) & 255 + line2 += bytes([c]) else: # unsupported raise ValueError("Unsupported predictor value: %d"%ft) @@ -89,7 +89,7 @@ def apply_matrix_norm(m, v): # isnumber def isnumber(x): - return isinstance(x, (int, long, float)) + return isinstance(x, (int, float)) # uniq def uniq(objs): @@ -106,7 +106,7 @@ def uniq(objs): # csort def csort(objs, key): """Order-preserving sorting function.""" - idxs = dict((obj, i) for (i, obj) in enumerate(objs)) + idxs = { obj:i for (i, obj) in enumerate(objs) } return sorted(objs, key=lambda obj: (key(obj), idxs[obj])) @@ -127,7 +127,7 @@ def fsplit(pred, objs): def drange(v0, v1, d): """Returns a discrete range.""" assert v0 < v1 - return xrange(int(v0)//d, int(v1+d)//d) + return range(int(v0)//d, int(v1+d)//d) # get_bound @@ -172,7 +172,7 @@ def nunpack(s, default=0): if not l: return default elif l == 1: - return ord(s) + return s[0] elif l == 2: return struct.unpack('>H', s)[0] elif l == 3: @@ -184,7 +184,7 @@ def nunpack(s, default=0): # decode_text -PDFDocEncoding = ''.join(unichr(x) for x in ( +PDFDocEncoding = ''.join(chr(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, @@ -221,19 +221,18 @@ def nunpack(s, default=0): def decode_text(s): - """Decodes a PDFDocEncoding string to Unicode.""" + """Decodes a PDFDocEncoding bytes to Unicode.""" if s.startswith(b'\xfe\xff'): - return unicode(s[2:], 'utf-16be', 'ignore') + return s[2:].decode('utf-16be', 'ignore') else: - 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('"', '"') - return x.encode(codec, 'xmlcharrefreplace') + return ''.join(PDFDocEncoding[c] for c in s) +def q(s): + """Quotes html string.""" + return (s.replace('&','&') + .replace('<','<') + .replace('>','>') + .replace('"','"')) def bbox2str(bbox): (x0, y0, x1, y1) = bbox @@ -252,7 +251,7 @@ def matrix2str(m): ## It maintains two parallel lists of objects, each of ## which is sorted by its x or y coordinate. ## -class Plane(object): +class Plane: def __init__(self, bbox, gridsize=50): self._seq = [] # preserve the object order. diff --git a/samples/Makefile b/samples/Makefile index ed848651..aae1f3a2 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -3,7 +3,7 @@ RM=rm -f CMP=: ECHO=echo -PYTHON=python2 +PYTHON=python PDF2TXT=PYTHONPATH=.. $(PYTHON) ../tools/pdf2txt.py -p1 -V diff --git a/setup.py b/setup.py index 51779e78..0bae82aa 100644 --- a/setup.py +++ b/setup.py @@ -1,44 +1,74 @@ #!/usr/bin/env python -from distutils.core import setup +from setuptools import setup +from setuptools.command.install import install from pdfminer import __version__ +class install_cmap(install): + + def run(self): + import os.path + import pdfminer + from pdfminer.cmapdb import convert_cmap + outdir = os.path.join(os.path.join(self.install_lib, 'pdfminer'), 'cmap') + print('installing cmap: %r...' % outdir) + os.makedirs(outdir, exist_ok=True) + convert_cmap( + outdir, 'Adobe-CNS1', + {'B5':'cp950', 'UniCNS-UTF8':'utf-8'}, + ['cmaprsrc/cid2code_Adobe_CNS1.txt']) + convert_cmap( + outdir, 'Adobe-GB1', + {'GBK-EUC':'cp936', 'UniGB-UTF8':'utf-8'}, + ['cmaprsrc/cid2code_Adobe_GB1.txt']) + convert_cmap( + outdir, 'Adobe-Japan1', + {'RKSJ':'cp932', 'EUC':'euc-jp', 'UniJIS-UTF8':'utf-8'}, + ['cmaprsrc/cid2code_Adobe_Japan1.txt']) + convert_cmap( + outdir, 'Adobe-Korea1', + {'KSC-EUC':'euc-kr', 'KSC-Johab':'johab', 'KSCms-UHC':'cp949', + 'UniKS-UTF8':'utf-8'}, + ['cmaprsrc/cid2code_Adobe_Korea1.txt']) + install.run(self) + return + +with open('README.md') as fp: + long_description = fp.read() + setup( - name='pdfminer', - 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 -and analyzing text data. PDFMiner allows to obtain -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 -PDF parser that can be used for other purposes instead of text analysis.''', - license='MIT/X', - author='Yusuke Shinyama', - author_email='yusuke at cs dot nyu dot edu', - url='http://euske.github.io/pdfminer/index.html', - install_requires=[ - 'pycrypto', + cmdclass = { 'install': install_cmap }, + name = 'pdfminer', + version = __version__, + description = 'PDF parser and analyzer', + long_description = long_description, + long_description_content_type = 'text/markdown', + license = 'MIT', + author = 'Yusuke Shinyama', + author_email = 'yusuke@shinyama.jp', + url = 'http://github.com/euske/pdfminer', + packages = [ + 'pdfminer', + ], + python_requires = '>=3.6', + install_requires = [ + 'pycryptodome', ], - packages=[ - 'pdfminer', + scripts = [ + 'tools/pdf2txt.py', + 'tools/dumppdf.py', ], - package_data={ - 'pdfminer': ['cmap/*.pickle.gz'] - }, - scripts=[ - 'tools/pdf2txt.py', - 'tools/dumppdf.py', - 'tools/latin2ascii.py', + keywords = [ + 'pdf parser', + 'pdf converter', + 'layout analysis', + 'text mining' ], - keywords=['pdf parser', 'pdf converter', 'layout analysis', 'text mining'], - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: MIT License', - 'Topic :: Text Processing', + classifiers = [ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: MIT License', + 'Topic :: Text Processing', ], - ) +) diff --git a/tools/conv_cmap.py b/tools/conv_cmap.py index 88cab575..2af93ceb 100755 --- a/tools/conv_cmap.py +++ b/tools/conv_cmap.py @@ -1,159 +1,10 @@ #!/usr/bin/env python import sys -try: - import cPickle as pickle -except ImportError: - import pickle as pickle - - -## 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: - 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 add(unimap, enc, code): - try: - 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 - 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) - - return - - 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 - - def dump_unicodemap(self, fp): - data = dict( - CID2UNICHR_H=self.cid2unichr_h, - CID2UNICHR_V=self.cid2unichr_v, - ) - fp.write(pickle.dumps(data)) - return +from pdfminer.cmapdb import convert_cmap # main def main(argv): import getopt - import gzip - import os.path def usage(): print ('usage: %s [-c enc=codec] output_dir regname [cid2code.txt ...]' % argv[0]) @@ -172,27 +23,7 @@ def usage(): if not args: return usage() regname = args.pop(0) - converter = CMapConverter(enc2codec) - for path in args: - print ('reading: %r...' % path) - fp = file(path) - converter.load(fp) - fp.close() - - for enc in converter.get_encs(): - fname = '%s.pickle.gz' % enc - path = os.path.join(outdir, fname) - print ('writing: %r...' % path) - fp = gzip.open(path, 'wb') - converter.dump_cmap(fp, enc) - fp.close() - - fname = 'to-unicode-%s.pickle.gz' % regname - path = os.path.join(outdir, fname) - print ('writing: %r...' % path) - fp = gzip.open(path, 'wb') - converter.dump_unicodemap(fp) - fp.close() + convert_cmap(outdir, regname, enc2codec, args) return if __name__ == '__main__': sys.exit(main(sys.argv)) diff --git a/tools/dumppdf.py b/tools/dumppdf.py index 29a11449..51255af6 100755 --- a/tools/dumppdf.py +++ b/tools/dumppdf.py @@ -7,29 +7,36 @@ # -i objid : object id # import sys, os.path, re +from io import StringIO 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 +from pdfminer.utils import isnumber, q -ESC_PAT = re.compile(r'[\000-\037&<>()"\042\047\134\177-\377]') -def e(s): - return ESC_PAT.sub(lambda m:'&#%d;' % ord(m.group(0)), s) +ESCAPE = set(map(ord, '&<>"')) +def encode(data): + buf = StringIO() + for b in data: + if b < 32 or 127 <= b or b in ESCAPE: + buf.write(f'&#{b};') + else: + buf.write(chr(b)) + return buf.getvalue() # dumpxml -def dumpxml(out, obj, codec=None): +def dumpxml(out, obj, mode=None): if obj is None: out.write('') return if isinstance(obj, dict): out.write('\n' % len(obj)) - for (k,v) in obj.iteritems(): + for (k,v) in obj.items(): out.write('%s\n' % k) out.write('') dumpxml(out, v) @@ -45,22 +52,22 @@ def dumpxml(out, obj, codec=None): out.write('') return - if isinstance(obj, str): - out.write('%s' % (len(obj), e(obj))) + if isinstance(obj, bytes): + out.write('%s' % (len(obj), encode(obj))) return if isinstance(obj, PDFStream): - if codec == 'raw': - out.write(obj.get_rawdata()) - elif codec == 'binary': - out.write(obj.get_data()) + if mode == 'raw': + out.buffer.write(obj.get_rawdata()) + elif mode == 'binary': + out.buffer.write(obj.get_data()) else: out.write('\n\n') dumpxml(out, obj.attrs) out.write('\n\n') - if codec == 'text': + if mode == 'text': data = obj.get_data() - out.write('%s\n' % (len(data), e(data))) + out.write('%s\n' % (len(data), encode(data))) out.write('') return @@ -91,7 +98,7 @@ def dumptrailers(out, doc): return # dumpallobjs -def dumpallobjs(out, doc, codec=None): +def dumpallobjs(out, doc, mode=None): visited = set() out.write('') for xref in doc.xrefs: @@ -102,7 +109,7 @@ def dumpallobjs(out, doc, codec=None): obj = doc.getobj(objid) if obj is None: continue out.write('\n' % objid) - dumpxml(out, obj, codec=codec) + dumpxml(out, obj, mode=mode) out.write('\n\n\n') except PDFObjectNotFound as e: print >>sys.stderr, 'not found: %r' % e @@ -111,57 +118,55 @@ def dumpallobjs(out, doc, codec=None): return # dumpoutline -def dumpoutline(outfp, fname, objids, pagenos, password='', - dumpall=False, codec=None, extractdir=None): - fp = file(fname, 'rb') - parser = PDFParser(fp) - 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)) - elif isinstance(dest, PSLiteral): - dest = resolve1(doc.get_dest(dest.name)) - if isinstance(dest, dict): - dest = dest['D'] - return dest - try: - outlines = doc.get_outlines() - outfp.write('\n') - for (level,title,dest,a,se) in outlines: - pageno = None - if dest: - dest = resolve_dest(dest) - pageno = pages[dest[0].objid] - elif a: - action = a.resolve() - if isinstance(action, dict): - subtype = action.get('S') - if subtype and repr(subtype) == '/GoTo' and action.get('D'): - dest = resolve_dest(action['D']) - pageno = pages[dest[0].objid] - s = e(title).encode('utf-8', 'xmlcharrefreplace') - outfp.write('\n' % (level, s)) - if dest is not None: - outfp.write('') - dumpxml(outfp, dest) - outfp.write('\n') - if pageno is not None: - outfp.write('%r\n' % pageno) - outfp.write('\n') - outfp.write('\n') - except PDFNoOutlines: - pass - parser.close() - fp.close() +def dumpoutline(outfp, fname, objids, pagenos, password=b'', + dumpall=False, mode=None, extractdir=None): + with open(fname, 'rb') as fp: + parser = PDFParser(fp) + 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)) + elif isinstance(dest, PSLiteral): + dest = resolve1(doc.get_dest(dest.name)) + if isinstance(dest, dict): + dest = dest['D'] + return dest + try: + outlines = doc.get_outlines() + outfp.write('\n') + for (level,title,dest,a,se) in outlines: + pageno = None + if dest: + dest = resolve_dest(dest) + pageno = pages[dest[0].objid] + elif a: + action = a.resolve() + if isinstance(action, dict): + subtype = action.get('S') + if subtype and repr(subtype) == '/GoTo' and action.get('D'): + dest = resolve_dest(action['D']) + pageno = pages[dest[0].objid] + outfp.write('\n' % (level, q(s))) + if dest is not None: + outfp.write('') + dumpxml(outfp, dest) + outfp.write('\n') + if pageno is not None: + outfp.write('%r\n' % pageno) + outfp.write('\n') + outfp.write('\n') + except PDFNoOutlines: + pass + parser.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 extractembedded(outfp, fname, objids, pagenos, password=b'', + dumpall=False, mode=None, extractdir=None): def extract1(obj): filename = os.path.basename(obj['UF'] or obj['F']) fileref = obj['EF']['F'] @@ -178,47 +183,45 @@ def extract1(obj): 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() + with open(path, 'wb') as out: + out.write(fileobj.get_data()) 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) + with open(fname, 'rb') as fp: + 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, extractdir=None): - fp = file(fname, 'rb') - parser = PDFParser(fp) - 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(PDFPage.create_pages(doc)): - if pageno in pagenos: - if codec: - for obj in page.contents: - obj = stream_value(obj) - dumpxml(outfp, obj, codec=codec) - else: - dumpxml(outfp, page.attrs) - if dumpall: - dumpallobjs(outfp, doc, codec=codec) - if (not objids) and (not pagenos) and (not dumpall): - dumptrailers(outfp, doc) - fp.close() - if codec not in ('raw','binary'): - outfp.write('\n') +def dumppdf(outfp, fname, objids, pagenos, password=b'', + dumpall=False, mode=None, extractdir=None): + with open(fname, 'rb') as fp: + parser = PDFParser(fp) + doc = PDFDocument(parser, password) + if objids: + for objid in objids: + obj = doc.getobj(objid) + dumpxml(outfp, obj, mode=mode) + if pagenos: + for (pageno,page) in enumerate(PDFPage.create_pages(doc)): + if pageno in pagenos: + if mode is not None: + for obj in page.contents: + obj = stream_value(obj) + dumpxml(outfp, obj, mode=mode) + else: + dumpxml(outfp, page.attrs) + if dumpall: + dumpallobjs(outfp, doc, mode=mode) + if (not objids) and (not pagenos) and (not dumpall): + dumptrailers(outfp, doc) + if mode not in ('raw','binary'): + outfp.write('\n') return @@ -226,34 +229,35 @@ def dumppdf(outfp, fname, objids, pagenos, password='', def main(argv): import getopt def usage(): - print ('usage: %s [-d] [-a] [-p pageid] [-P password] [-r|-b|-t] [-T] [-E directory] [-i objid] file ...' % argv[0]) + print ('usage: %s [-P password] [-a] [-p pageid] [-i objid] [-o output] ' + '[-r|-b|-t] [-T] [-O output_dir] [-d] input.pdf ...' % argv[0]) return 100 try: - (opts, args) = getopt.getopt(argv[1:], 'dap:P:rbtTE:i:') + (opts, args) = getopt.getopt(argv[1:], 'dP:ap:i:o:rbtTO:') except getopt.GetoptError: return usage() if not args: return usage() debug = 0 objids = [] pagenos = set() - codec = None - password = '' + mode = None + password = b'' 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 + elif k == '-P': password = v.encode('ascii') elif k == '-a': dumpall = True - elif k == '-r': codec = 'raw' - elif k == '-b': codec = 'binary' - elif k == '-t': codec = 'text' + elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') ) + elif k == '-i': objids.extend( int(x) for x in v.split(',') ) + elif k == '-o': outfp = open(v, 'wb') + elif k == '-r': mode = 'raw' + elif k == '-b': mode = 'binary' + elif k == '-t': mode = 'text' elif k == '-T': proc = dumpoutline - elif k == '-E': + elif k == '-O': extractdir = v proc = extractembedded # @@ -262,7 +266,7 @@ def usage(): # for fname in args: proc(outfp, fname, objids, pagenos, password=password, - dumpall=dumpall, codec=codec, extractdir=extractdir) + dumpall=dumpall, mode=mode, extractdir=extractdir) return if __name__ == '__main__': sys.exit(main(sys.argv)) diff --git a/tools/pdf2txt.py b/tools/pdf2txt.py index 5eb24bfd..d580c9eb 100755 --- a/tools/pdf2txt.py +++ b/tools/pdf2txt.py @@ -14,21 +14,21 @@ 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] [-R rotation] [-S]' - ' [-t text|html|xml|tag] [-c codec] [-s scale]' - ' file ...' % argv[0]) + print ('usage: %s [-P password] [-o output] [-t text|html|xml|tag]' + ' [-O output_dir] [-c encoding] [-s scale] [-R rotation]' + ' [-Y normal|loose|exact] [-p pagenos] [-m maxpages]' + ' [-S] [-C] [-n] [-A] [-V] [-M char_margin] [-L line_margin]' + ' [-W word_margin] [-F boxes_flow] [-d] input.pdf ...' % argv[0]) return 100 try: - (opts, args) = getopt.getopt(argv[1:], 'dp:m:P:o:CnAVM:L:W:F:Y:O:R:St:c:s:') + (opts, args) = getopt.getopt(argv[1:], 'dP:o:t:O:c:s:R:Y:p:m:SCnAVM:W:L:F:') except getopt.GetoptError: return usage() if not args: return usage() # debug option debug = 0 # input option - password = '' + password = b'' pagenos = set() maxpages = 0 # output option @@ -38,7 +38,7 @@ def usage(): rotation = 0 stripcontrol = False layoutmode = 'normal' - codec = 'utf-8' + encoding = 'utf-8' pageno = 1 scale = 1 caching = True @@ -46,25 +46,25 @@ def usage(): laparams = LAParams() for (k, v) in opts: if k == '-d': debug += 1 + elif k == '-P': password = v.encode('ascii') + elif k == '-o': outfile = v + elif k == '-t': outtype = v + elif k == '-O': imagewriter = ImageWriter(v) + elif k == '-c': encoding = v + elif k == '-s': scale = float(v) + elif k == '-R': rotation = int(v) + elif k == '-Y': layoutmode = v elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') ) elif k == '-m': maxpages = int(v) - elif k == '-P': password = v - elif k == '-o': outfile = v + elif k == '-S': stripcontrol = True elif k == '-C': caching = False elif k == '-n': laparams = None elif k == '-A': laparams.all_texts = True elif k == '-V': laparams.detect_vertical = True elif k == '-M': laparams.char_margin = float(v) - elif k == '-L': laparams.line_margin = float(v) elif k == '-W': laparams.word_margin = float(v) + elif k == '-L': laparams.line_margin = float(v) elif k == '-F': laparams.boxes_flow = float(v) - elif k == '-Y': layoutmode = v - elif k == '-O': imagewriter = ImageWriter(v) - elif k == '-R': rotation = int(v) - elif k == '-S': stripcontrol = True - elif k == '-t': outtype = v - elif k == '-c': codec = v - elif k == '-s': scale = float(v) # PDFDocument.debug = debug PDFParser.debug = debug @@ -82,33 +82,32 @@ def usage(): elif outfile.endswith('.tag'): outtype = 'tag' if outfile: - outfp = file(outfile, 'w') + outfp = open(outfile, 'w', encoding=encoding) else: outfp = sys.stdout if outtype == 'text': - device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, + device = TextConverter(rsrcmgr, outfp, laparams=laparams, imagewriter=imagewriter) elif outtype == 'xml': - device = XMLConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, + device = XMLConverter(rsrcmgr, outfp, laparams=laparams, imagewriter=imagewriter, stripcontrol=stripcontrol) elif outtype == 'html': - device = HTMLConverter(rsrcmgr, outfp, codec=codec, scale=scale, + device = HTMLConverter(rsrcmgr, outfp, scale=scale, layoutmode=layoutmode, laparams=laparams, imagewriter=imagewriter, debug=debug) elif outtype == 'tag': - device = TagExtractor(rsrcmgr, outfp, codec=codec) + device = TagExtractor(rsrcmgr, outfp) else: return usage() for fname in args: - fp = file(fname, 'rb') - 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() + with open(fname, 'rb') as fp: + 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) device.close() outfp.close() return