Skip to content

Commit 5ce18b7

Browse files
authored
MAINT: Split long functions (#777)
I hope this makes them easier to understand
1 parent b08f9aa commit 5ce18b7

File tree

6 files changed

+213
-172
lines changed

6 files changed

+213
-172
lines changed

PyPDF2/filters.py

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -145,45 +145,49 @@ def decode(data, decodeParms):
145145
columns = decodeParms[LZW.COLUMNS]
146146
# PNG prediction:
147147
if predictor >= 10 and predictor <= 15:
148-
output = StringIO()
149-
# PNG prediction can vary from row to row
150-
rowlength = columns + 1
151-
assert len(data) % rowlength == 0
152-
prev_rowdata = (0,) * rowlength
153-
for row in range(len(data) // rowlength):
154-
rowdata = [ord_(x) for x in data[(row*rowlength):((row+1)*rowlength)]]
155-
filterByte = rowdata[0]
156-
if filterByte == 0:
157-
pass
158-
elif filterByte == 1:
159-
for i in range(2, rowlength):
160-
rowdata[i] = (rowdata[i] + rowdata[i-1]) % 256
161-
elif filterByte == 2:
162-
for i in range(1, rowlength):
163-
rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256
164-
elif filterByte == 3:
165-
for i in range(1, rowlength):
166-
left = rowdata[i-1] if i > 1 else 0
167-
floor = math.floor(left + prev_rowdata[i])/2
168-
rowdata[i] = (rowdata[i] + int(floor)) % 256
169-
elif filterByte == 4:
170-
for i in range(1, rowlength):
171-
left = rowdata[i - 1] if i > 1 else 0
172-
up = prev_rowdata[i]
173-
up_left = prev_rowdata[i - 1] if i > 1 else 0
174-
paeth = paethPredictor(left, up, up_left)
175-
rowdata[i] = (rowdata[i] + paeth) % 256
176-
else:
177-
# unsupported PNG filter
178-
raise PdfReadError("Unsupported PNG filter %r" % filterByte)
179-
prev_rowdata = rowdata
180-
output.write(''.join([chr(x) for x in rowdata[1:]]))
181-
data = output.getvalue()
148+
data = FlateDecode._decode_png_prediction(data, columns)
182149
else:
183150
# unsupported predictor
184151
raise PdfReadError("Unsupported flatedecode predictor %r" % predictor)
185152
return data
186153

154+
@staticmethod
155+
def _decode_png_prediction(data, columns):
156+
output = StringIO()
157+
# PNG prediction can vary from row to row
158+
rowlength = columns + 1
159+
assert len(data) % rowlength == 0
160+
prev_rowdata = (0,) * rowlength
161+
for row in range(len(data) // rowlength):
162+
rowdata = [ord_(x) for x in data[(row*rowlength):((row+1)*rowlength)]]
163+
filterByte = rowdata[0]
164+
if filterByte == 0:
165+
pass
166+
elif filterByte == 1:
167+
for i in range(2, rowlength):
168+
rowdata[i] = (rowdata[i] + rowdata[i-1]) % 256
169+
elif filterByte == 2:
170+
for i in range(1, rowlength):
171+
rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256
172+
elif filterByte == 3:
173+
for i in range(1, rowlength):
174+
left = rowdata[i-1] if i > 1 else 0
175+
floor = math.floor(left + prev_rowdata[i])/2
176+
rowdata[i] = (rowdata[i] + int(floor)) % 256
177+
elif filterByte == 4:
178+
for i in range(1, rowlength):
179+
left = rowdata[i - 1] if i > 1 else 0
180+
up = prev_rowdata[i]
181+
up_left = prev_rowdata[i - 1] if i > 1 else 0
182+
paeth = paethPredictor(left, up, up_left)
183+
rowdata[i] = (rowdata[i] + paeth) % 256
184+
else:
185+
# unsupported PNG filter
186+
raise PdfReadError("Unsupported PNG filter %r" % filterByte)
187+
prev_rowdata = rowdata
188+
output.write(''.join([chr(x) for x in rowdata[1:]]))
189+
return output.getvalue()
190+
187191
@staticmethod
188192
def encode(data):
189193
return compress(data)

PyPDF2/generic.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from PyPDF2.errors import (
4343
STREAM_TRUNCATED_PREMATURELY,
4444
PdfReadError,
45+
PdfReadWarning,
4546
PdfStreamError,
4647
)
4748

@@ -595,11 +596,13 @@ def readFromStream(stream, pdf):
595596
data[key] = value
596597
elif pdf.strict:
597598
# multiple definitions of key not permitted
598-
raise PdfReadError("Multiple definitions in dictionary at byte %s for key %s" \
599-
% (utils.hexStr(stream.tell()), key))
599+
raise PdfReadError(
600+
"Multiple definitions in dictionary at byte %s for key %s" \
601+
% (utils.hexStr(stream.tell()), key))
600602
else:
601-
warnings.warn("Multiple definitions in dictionary at byte %s for key %s" \
602-
% (utils.hexStr(stream.tell()), key), utils.PdfReadWarning)
603+
warnings.warn(
604+
"Multiple definitions in dictionary at byte %s for key %s" \
605+
% (utils.hexStr(stream.tell()), key), PdfReadWarning)
603606

604607
pos = stream.tell()
605608
s = readNonWhitespace(stream)

PyPDF2/merger.py

Lines changed: 58 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,6 @@ def _write_dests(self):
367367
self.output.addNamedDestinationObject(v)
368368

369369
def _write_bookmarks(self, bookmarks=None, parent=None):
370-
371370
if bookmarks is None:
372371
bookmarks = self.bookmarks
373372

@@ -382,64 +381,68 @@ def _write_bookmarks(self, bookmarks=None, parent=None):
382381
if '/Page' in b:
383382
for i, p in enumerate(self.pages):
384383
if p.id == b['/Page']:
385-
# b[NameObject('/Page')] = p.out_pagedata
386-
args = [NumberObject(p.id), NameObject(b['/Type'])]
387-
# nothing more to add
388-
# if b['/Type'] == '/Fit' or b['/Type'] == '/FitB'
389-
if b['/Type'] == '/FitH' or b['/Type'] == '/FitBH':
390-
if '/Top' in b and not isinstance(b['/Top'], NullObject):
391-
args.append(FloatObject(b['/Top']))
392-
else:
393-
args.append(FloatObject(0))
394-
del b['/Top']
395-
elif b['/Type'] == '/FitV' or b['/Type'] == '/FitBV':
396-
if '/Left' in b and not isinstance(b['/Left'], NullObject):
397-
args.append(FloatObject(b['/Left']))
398-
else:
399-
args.append(FloatObject(0))
400-
del b['/Left']
401-
elif b['/Type'] == '/XYZ':
402-
if '/Left' in b and not isinstance(b['/Left'], NullObject):
403-
args.append(FloatObject(b['/Left']))
404-
else:
405-
args.append(FloatObject(0))
406-
if '/Top' in b and not isinstance(b['/Top'], NullObject):
407-
args.append(FloatObject(b['/Top']))
408-
else:
409-
args.append(FloatObject(0))
410-
if '/Zoom' in b and not isinstance(b['/Zoom'], NullObject):
411-
args.append(FloatObject(b['/Zoom']))
412-
else:
413-
args.append(FloatObject(0))
414-
del b['/Top'], b['/Zoom'], b['/Left']
415-
elif b['/Type'] == '/FitR':
416-
if '/Left' in b and not isinstance(b['/Left'], NullObject):
417-
args.append(FloatObject(b['/Left']))
418-
else:
419-
args.append(FloatObject(0))
420-
if '/Bottom' in b and not isinstance(b['/Bottom'], NullObject):
421-
args.append(FloatObject(b['/Bottom']))
422-
else:
423-
args.append(FloatObject(0))
424-
if '/Right' in b and not isinstance(b['/Right'], NullObject):
425-
args.append(FloatObject(b['/Right']))
426-
else:
427-
args.append(FloatObject(0))
428-
if '/Top' in b and not isinstance(b['/Top'], NullObject):
429-
args.append(FloatObject(b['/Top']))
430-
else:
431-
args.append(FloatObject(0))
432-
del b['/Left'], b['/Right'], b['/Bottom'], b['/Top']
433-
434-
b[NameObject('/A')] = DictionaryObject({NameObject('/S'): NameObject('/GoTo'), NameObject('/D'): ArrayObject(args)})
435-
436-
pageno = i
437-
pdf = p.src # noqa: F841
384+
pageno, pdf = self._write_bookmark_on_page(b, p, i)
438385
break
439386
if pageno is not None:
440387
del b['/Page'], b['/Type']
441388
last_added = self.output.addBookmarkDict(b, parent)
442389

390+
def _write_bookmark_on_page(self, b, p, i):
391+
# b[NameObject('/Page')] = p.out_pagedata
392+
args = [NumberObject(p.id), NameObject(b['/Type'])]
393+
# nothing more to add
394+
# if b['/Type'] == '/Fit' or b['/Type'] == '/FitB'
395+
if b['/Type'] == '/FitH' or b['/Type'] == '/FitBH':
396+
if '/Top' in b and not isinstance(b['/Top'], NullObject):
397+
args.append(FloatObject(b['/Top']))
398+
else:
399+
args.append(FloatObject(0))
400+
del b['/Top']
401+
elif b['/Type'] == '/FitV' or b['/Type'] == '/FitBV':
402+
if '/Left' in b and not isinstance(b['/Left'], NullObject):
403+
args.append(FloatObject(b['/Left']))
404+
else:
405+
args.append(FloatObject(0))
406+
del b['/Left']
407+
elif b['/Type'] == '/XYZ':
408+
if '/Left' in b and not isinstance(b['/Left'], NullObject):
409+
args.append(FloatObject(b['/Left']))
410+
else:
411+
args.append(FloatObject(0))
412+
if '/Top' in b and not isinstance(b['/Top'], NullObject):
413+
args.append(FloatObject(b['/Top']))
414+
else:
415+
args.append(FloatObject(0))
416+
if '/Zoom' in b and not isinstance(b['/Zoom'], NullObject):
417+
args.append(FloatObject(b['/Zoom']))
418+
else:
419+
args.append(FloatObject(0))
420+
del b['/Top'], b['/Zoom'], b['/Left']
421+
elif b['/Type'] == '/FitR':
422+
if '/Left' in b and not isinstance(b['/Left'], NullObject):
423+
args.append(FloatObject(b['/Left']))
424+
else:
425+
args.append(FloatObject(0))
426+
if '/Bottom' in b and not isinstance(b['/Bottom'], NullObject):
427+
args.append(FloatObject(b['/Bottom']))
428+
else:
429+
args.append(FloatObject(0))
430+
if '/Right' in b and not isinstance(b['/Right'], NullObject):
431+
args.append(FloatObject(b['/Right']))
432+
else:
433+
args.append(FloatObject(0))
434+
if '/Top' in b and not isinstance(b['/Top'], NullObject):
435+
args.append(FloatObject(b['/Top']))
436+
else:
437+
args.append(FloatObject(0))
438+
del b['/Left'], b['/Right'], b['/Bottom'], b['/Top']
439+
440+
b[NameObject('/A')] = DictionaryObject({NameObject('/S'): NameObject('/GoTo'), NameObject('/D'): ArrayObject(args)})
441+
442+
pageno = i
443+
pdf = p.src # noqa: F841
444+
return (pageno, pdf)
445+
443446
def _associate_dests_to_pages(self, pages):
444447
for nd in self.named_dests:
445448
pageno = None
@@ -570,6 +573,6 @@ def add(self, title, pagenum):
570573
self.tree.addChild(bookmark)
571574

572575
def removeAll(self):
573-
for child in [x for x in self.tree.children()]:
576+
for child in self.tree.children():
574577
self.tree.removeChild(child)
575578
self.pop()

0 commit comments

Comments
 (0)