Skip to content

Commit

Permalink
MAINT: Split long functions
Browse files Browse the repository at this point in the history
I hope this makes them easier to understand / extend
  • Loading branch information
MartinThoma committed Apr 18, 2022
1 parent b08f9aa commit 80b0146
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 172 deletions.
72 changes: 38 additions & 34 deletions PyPDF2/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,45 +145,49 @@ def decode(data, decodeParms):
columns = decodeParms[LZW.COLUMNS]
# PNG prediction:
if predictor >= 10 and predictor <= 15:
output = StringIO()
# PNG prediction can vary from row to row
rowlength = columns + 1
assert len(data) % rowlength == 0
prev_rowdata = (0,) * rowlength
for row in range(len(data) // rowlength):
rowdata = [ord_(x) for x in data[(row*rowlength):((row+1)*rowlength)]]
filterByte = rowdata[0]
if filterByte == 0:
pass
elif filterByte == 1:
for i in range(2, rowlength):
rowdata[i] = (rowdata[i] + rowdata[i-1]) % 256
elif filterByte == 2:
for i in range(1, rowlength):
rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256
elif filterByte == 3:
for i in range(1, rowlength):
left = rowdata[i-1] if i > 1 else 0
floor = math.floor(left + prev_rowdata[i])/2
rowdata[i] = (rowdata[i] + int(floor)) % 256
elif filterByte == 4:
for i in range(1, rowlength):
left = rowdata[i - 1] if i > 1 else 0
up = prev_rowdata[i]
up_left = prev_rowdata[i - 1] if i > 1 else 0
paeth = paethPredictor(left, up, up_left)
rowdata[i] = (rowdata[i] + paeth) % 256
else:
# unsupported PNG filter
raise PdfReadError("Unsupported PNG filter %r" % filterByte)
prev_rowdata = rowdata
output.write(''.join([chr(x) for x in rowdata[1:]]))
data = output.getvalue()
data = FlateDecode._decode_png_prediction(data, columns)
else:
# unsupported predictor
raise PdfReadError("Unsupported flatedecode predictor %r" % predictor)
return data

@staticmethod
def _decode_png_prediction(data, columns):
output = StringIO()
# PNG prediction can vary from row to row
rowlength = columns + 1
assert len(data) % rowlength == 0
prev_rowdata = (0,) * rowlength
for row in range(len(data) // rowlength):
rowdata = [ord_(x) for x in data[(row*rowlength):((row+1)*rowlength)]]
filterByte = rowdata[0]
if filterByte == 0:
pass
elif filterByte == 1:
for i in range(2, rowlength):
rowdata[i] = (rowdata[i] + rowdata[i-1]) % 256
elif filterByte == 2:
for i in range(1, rowlength):
rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256
elif filterByte == 3:
for i in range(1, rowlength):
left = rowdata[i-1] if i > 1 else 0
floor = math.floor(left + prev_rowdata[i])/2
rowdata[i] = (rowdata[i] + int(floor)) % 256
elif filterByte == 4:
for i in range(1, rowlength):
left = rowdata[i - 1] if i > 1 else 0
up = prev_rowdata[i]
up_left = prev_rowdata[i - 1] if i > 1 else 0
paeth = paethPredictor(left, up, up_left)
rowdata[i] = (rowdata[i] + paeth) % 256
else:
# unsupported PNG filter
raise PdfReadError("Unsupported PNG filter %r" % filterByte)
prev_rowdata = rowdata
output.write(''.join([chr(x) for x in rowdata[1:]]))
return output.getvalue()

@staticmethod
def encode(data):
return compress(data)
Expand Down
11 changes: 7 additions & 4 deletions PyPDF2/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from PyPDF2.errors import (
STREAM_TRUNCATED_PREMATURELY,
PdfReadError,
PdfReadWarning,
PdfStreamError,
)

Expand Down Expand Up @@ -595,11 +596,13 @@ def readFromStream(stream, pdf):
data[key] = value
elif pdf.strict:
# multiple definitions of key not permitted
raise PdfReadError("Multiple definitions in dictionary at byte %s for key %s" \
% (utils.hexStr(stream.tell()), key))
raise PdfReadError(
"Multiple definitions in dictionary at byte %s for key %s" \
% (utils.hexStr(stream.tell()), key))
else:
warnings.warn("Multiple definitions in dictionary at byte %s for key %s" \
% (utils.hexStr(stream.tell()), key), utils.PdfReadWarning)
warnings.warn(
"Multiple definitions in dictionary at byte %s for key %s" \
% (utils.hexStr(stream.tell()), key), PdfReadWarning)

pos = stream.tell()
s = readNonWhitespace(stream)
Expand Down
113 changes: 58 additions & 55 deletions PyPDF2/merger.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,6 @@ def _write_dests(self):
self.output.addNamedDestinationObject(v)

def _write_bookmarks(self, bookmarks=None, parent=None):

if bookmarks is None:
bookmarks = self.bookmarks

Expand All @@ -382,64 +381,68 @@ def _write_bookmarks(self, bookmarks=None, parent=None):
if '/Page' in b:
for i, p in enumerate(self.pages):
if p.id == b['/Page']:
# b[NameObject('/Page')] = p.out_pagedata
args = [NumberObject(p.id), NameObject(b['/Type'])]
# nothing more to add
# if b['/Type'] == '/Fit' or b['/Type'] == '/FitB'
if b['/Type'] == '/FitH' or b['/Type'] == '/FitBH':
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
del b['/Top']
elif b['/Type'] == '/FitV' or b['/Type'] == '/FitBV':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
del b['/Left']
elif b['/Type'] == '/XYZ':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
if '/Zoom' in b and not isinstance(b['/Zoom'], NullObject):
args.append(FloatObject(b['/Zoom']))
else:
args.append(FloatObject(0))
del b['/Top'], b['/Zoom'], b['/Left']
elif b['/Type'] == '/FitR':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
if '/Bottom' in b and not isinstance(b['/Bottom'], NullObject):
args.append(FloatObject(b['/Bottom']))
else:
args.append(FloatObject(0))
if '/Right' in b and not isinstance(b['/Right'], NullObject):
args.append(FloatObject(b['/Right']))
else:
args.append(FloatObject(0))
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
del b['/Left'], b['/Right'], b['/Bottom'], b['/Top']

b[NameObject('/A')] = DictionaryObject({NameObject('/S'): NameObject('/GoTo'), NameObject('/D'): ArrayObject(args)})

pageno = i
pdf = p.src # noqa: F841
pageno, pdf = self._write_bookmark_on_page(b, p, i)
break
if pageno is not None:
del b['/Page'], b['/Type']
last_added = self.output.addBookmarkDict(b, parent)

def _write_bookmark_on_page(self, b, p, i):
# b[NameObject('/Page')] = p.out_pagedata
args = [NumberObject(p.id), NameObject(b['/Type'])]
# nothing more to add
# if b['/Type'] == '/Fit' or b['/Type'] == '/FitB'
if b['/Type'] == '/FitH' or b['/Type'] == '/FitBH':
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
del b['/Top']
elif b['/Type'] == '/FitV' or b['/Type'] == '/FitBV':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
del b['/Left']
elif b['/Type'] == '/XYZ':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
if '/Zoom' in b and not isinstance(b['/Zoom'], NullObject):
args.append(FloatObject(b['/Zoom']))
else:
args.append(FloatObject(0))
del b['/Top'], b['/Zoom'], b['/Left']
elif b['/Type'] == '/FitR':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
if '/Bottom' in b and not isinstance(b['/Bottom'], NullObject):
args.append(FloatObject(b['/Bottom']))
else:
args.append(FloatObject(0))
if '/Right' in b and not isinstance(b['/Right'], NullObject):
args.append(FloatObject(b['/Right']))
else:
args.append(FloatObject(0))
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
del b['/Left'], b['/Right'], b['/Bottom'], b['/Top']

b[NameObject('/A')] = DictionaryObject({NameObject('/S'): NameObject('/GoTo'), NameObject('/D'): ArrayObject(args)})

pageno = i
pdf = p.src # noqa: F841
return (pageno, pdf)

def _associate_dests_to_pages(self, pages):
for nd in self.named_dests:
pageno = None
Expand Down Expand Up @@ -570,6 +573,6 @@ def add(self, title, pagenum):
self.tree.addChild(bookmark)

def removeAll(self):
for child in [x for x in self.tree.children()]:
for child in self.tree.children():
self.tree.removeChild(child)
self.pop()
Loading

0 comments on commit 80b0146

Please sign in to comment.