Coverage for /pythoncovmergedfiles/medio/medio/src/pdfminer.six/pdfminer/ccitt.py: 61%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# CCITT Fax decoder
2#
3# Bugs: uncompressed mode untested.
4#
5# cf.
6# ITU-T Recommendation T.4
7# "Standardization of Group 3 facsimile terminals
8# for document transmission"
9# ITU-T Recommendation T.6
10# "FACSIMILE CODING SCHEMES AND CODING CONTROL FUNCTIONS
11# FOR GROUP 4 FACSIMILE APPARATUS"
14import array
15from collections.abc import Callable, Iterator, MutableSequence, Sequence
16from typing import (
17 Any,
18 ClassVar,
19 cast,
20)
22from pdfminer.pdfexceptions import PDFException, PDFValueError
25def get_bytes(data: bytes) -> Iterator[int]:
26 yield from data
29# Workaround https://github.com/python/mypy/issues/731
30BitParserState = MutableSequence[Any]
31# A better definition (not supported by mypy) would be:
32# BitParserState = MutableSequence[Union["BitParserState", int, str, None]]
35class BitParser:
36 _state: BitParserState
38 # _accept is declared Optional solely as a workaround for
39 # https://github.com/python/mypy/issues/708
40 _accept: Callable[[Any], BitParserState] | None
42 def __init__(self) -> None:
43 self._pos = 0
45 @classmethod
46 def add(cls, root: BitParserState, v: int | str, bits: str) -> None:
47 p: BitParserState = root
48 b = None
49 for i in range(len(bits)):
50 if i > 0:
51 assert b is not None
52 if p[b] is None:
53 p[b] = [None, None]
54 p = p[b]
55 b = 1 if bits[i] == "1" else 0
56 assert b is not None
57 p[b] = v
59 def feedbytes(self, data: bytes) -> None:
60 for byte in get_bytes(data):
61 for m in (128, 64, 32, 16, 8, 4, 2, 1):
62 self._parse_bit(byte & m)
64 def _parse_bit(self, x: object) -> None:
65 v = self._state[1] if x else self._state[0]
66 self._pos += 1
67 if isinstance(v, list):
68 self._state = v
69 else:
70 assert self._accept is not None
71 self._state = self._accept(v)
74class CCITTG4Parser(BitParser):
75 MODE: ClassVar[BitParserState] = [None, None]
76 BitParser.add(MODE, 0, "1")
77 BitParser.add(MODE, +1, "011")
78 BitParser.add(MODE, -1, "010")
79 BitParser.add(MODE, "h", "001")
80 BitParser.add(MODE, "p", "0001")
81 BitParser.add(MODE, +2, "000011")
82 BitParser.add(MODE, -2, "000010")
83 BitParser.add(MODE, +3, "0000011")
84 BitParser.add(MODE, -3, "0000010")
85 BitParser.add(MODE, "u", "0000001111")
86 BitParser.add(MODE, "x1", "0000001000")
87 BitParser.add(MODE, "x2", "0000001001")
88 BitParser.add(MODE, "x3", "0000001010")
89 BitParser.add(MODE, "x4", "0000001011")
90 BitParser.add(MODE, "x5", "0000001100")
91 BitParser.add(MODE, "x6", "0000001101")
92 BitParser.add(MODE, "x7", "0000001110")
93 BitParser.add(MODE, "e", "000000000001000000000001")
95 WHITE: ClassVar[BitParserState] = [None, None]
96 BitParser.add(WHITE, 0, "00110101")
97 BitParser.add(WHITE, 1, "000111")
98 BitParser.add(WHITE, 2, "0111")
99 BitParser.add(WHITE, 3, "1000")
100 BitParser.add(WHITE, 4, "1011")
101 BitParser.add(WHITE, 5, "1100")
102 BitParser.add(WHITE, 6, "1110")
103 BitParser.add(WHITE, 7, "1111")
104 BitParser.add(WHITE, 8, "10011")
105 BitParser.add(WHITE, 9, "10100")
106 BitParser.add(WHITE, 10, "00111")
107 BitParser.add(WHITE, 11, "01000")
108 BitParser.add(WHITE, 12, "001000")
109 BitParser.add(WHITE, 13, "000011")
110 BitParser.add(WHITE, 14, "110100")
111 BitParser.add(WHITE, 15, "110101")
112 BitParser.add(WHITE, 16, "101010")
113 BitParser.add(WHITE, 17, "101011")
114 BitParser.add(WHITE, 18, "0100111")
115 BitParser.add(WHITE, 19, "0001100")
116 BitParser.add(WHITE, 20, "0001000")
117 BitParser.add(WHITE, 21, "0010111")
118 BitParser.add(WHITE, 22, "0000011")
119 BitParser.add(WHITE, 23, "0000100")
120 BitParser.add(WHITE, 24, "0101000")
121 BitParser.add(WHITE, 25, "0101011")
122 BitParser.add(WHITE, 26, "0010011")
123 BitParser.add(WHITE, 27, "0100100")
124 BitParser.add(WHITE, 28, "0011000")
125 BitParser.add(WHITE, 29, "00000010")
126 BitParser.add(WHITE, 30, "00000011")
127 BitParser.add(WHITE, 31, "00011010")
128 BitParser.add(WHITE, 32, "00011011")
129 BitParser.add(WHITE, 33, "00010010")
130 BitParser.add(WHITE, 34, "00010011")
131 BitParser.add(WHITE, 35, "00010100")
132 BitParser.add(WHITE, 36, "00010101")
133 BitParser.add(WHITE, 37, "00010110")
134 BitParser.add(WHITE, 38, "00010111")
135 BitParser.add(WHITE, 39, "00101000")
136 BitParser.add(WHITE, 40, "00101001")
137 BitParser.add(WHITE, 41, "00101010")
138 BitParser.add(WHITE, 42, "00101011")
139 BitParser.add(WHITE, 43, "00101100")
140 BitParser.add(WHITE, 44, "00101101")
141 BitParser.add(WHITE, 45, "00000100")
142 BitParser.add(WHITE, 46, "00000101")
143 BitParser.add(WHITE, 47, "00001010")
144 BitParser.add(WHITE, 48, "00001011")
145 BitParser.add(WHITE, 49, "01010010")
146 BitParser.add(WHITE, 50, "01010011")
147 BitParser.add(WHITE, 51, "01010100")
148 BitParser.add(WHITE, 52, "01010101")
149 BitParser.add(WHITE, 53, "00100100")
150 BitParser.add(WHITE, 54, "00100101")
151 BitParser.add(WHITE, 55, "01011000")
152 BitParser.add(WHITE, 56, "01011001")
153 BitParser.add(WHITE, 57, "01011010")
154 BitParser.add(WHITE, 58, "01011011")
155 BitParser.add(WHITE, 59, "01001010")
156 BitParser.add(WHITE, 60, "01001011")
157 BitParser.add(WHITE, 61, "00110010")
158 BitParser.add(WHITE, 62, "00110011")
159 BitParser.add(WHITE, 63, "00110100")
160 BitParser.add(WHITE, 64, "11011")
161 BitParser.add(WHITE, 128, "10010")
162 BitParser.add(WHITE, 192, "010111")
163 BitParser.add(WHITE, 256, "0110111")
164 BitParser.add(WHITE, 320, "00110110")
165 BitParser.add(WHITE, 384, "00110111")
166 BitParser.add(WHITE, 448, "01100100")
167 BitParser.add(WHITE, 512, "01100101")
168 BitParser.add(WHITE, 576, "01101000")
169 BitParser.add(WHITE, 640, "01100111")
170 BitParser.add(WHITE, 704, "011001100")
171 BitParser.add(WHITE, 768, "011001101")
172 BitParser.add(WHITE, 832, "011010010")
173 BitParser.add(WHITE, 896, "011010011")
174 BitParser.add(WHITE, 960, "011010100")
175 BitParser.add(WHITE, 1024, "011010101")
176 BitParser.add(WHITE, 1088, "011010110")
177 BitParser.add(WHITE, 1152, "011010111")
178 BitParser.add(WHITE, 1216, "011011000")
179 BitParser.add(WHITE, 1280, "011011001")
180 BitParser.add(WHITE, 1344, "011011010")
181 BitParser.add(WHITE, 1408, "011011011")
182 BitParser.add(WHITE, 1472, "010011000")
183 BitParser.add(WHITE, 1536, "010011001")
184 BitParser.add(WHITE, 1600, "010011010")
185 BitParser.add(WHITE, 1664, "011000")
186 BitParser.add(WHITE, 1728, "010011011")
187 BitParser.add(WHITE, 1792, "00000001000")
188 BitParser.add(WHITE, 1856, "00000001100")
189 BitParser.add(WHITE, 1920, "00000001101")
190 BitParser.add(WHITE, 1984, "000000010010")
191 BitParser.add(WHITE, 2048, "000000010011")
192 BitParser.add(WHITE, 2112, "000000010100")
193 BitParser.add(WHITE, 2176, "000000010101")
194 BitParser.add(WHITE, 2240, "000000010110")
195 BitParser.add(WHITE, 2304, "000000010111")
196 BitParser.add(WHITE, 2368, "000000011100")
197 BitParser.add(WHITE, 2432, "000000011101")
198 BitParser.add(WHITE, 2496, "000000011110")
199 BitParser.add(WHITE, 2560, "000000011111")
201 BLACK: ClassVar[BitParserState] = [None, None]
202 BitParser.add(BLACK, 0, "0000110111")
203 BitParser.add(BLACK, 1, "010")
204 BitParser.add(BLACK, 2, "11")
205 BitParser.add(BLACK, 3, "10")
206 BitParser.add(BLACK, 4, "011")
207 BitParser.add(BLACK, 5, "0011")
208 BitParser.add(BLACK, 6, "0010")
209 BitParser.add(BLACK, 7, "00011")
210 BitParser.add(BLACK, 8, "000101")
211 BitParser.add(BLACK, 9, "000100")
212 BitParser.add(BLACK, 10, "0000100")
213 BitParser.add(BLACK, 11, "0000101")
214 BitParser.add(BLACK, 12, "0000111")
215 BitParser.add(BLACK, 13, "00000100")
216 BitParser.add(BLACK, 14, "00000111")
217 BitParser.add(BLACK, 15, "000011000")
218 BitParser.add(BLACK, 16, "0000010111")
219 BitParser.add(BLACK, 17, "0000011000")
220 BitParser.add(BLACK, 18, "0000001000")
221 BitParser.add(BLACK, 19, "00001100111")
222 BitParser.add(BLACK, 20, "00001101000")
223 BitParser.add(BLACK, 21, "00001101100")
224 BitParser.add(BLACK, 22, "00000110111")
225 BitParser.add(BLACK, 23, "00000101000")
226 BitParser.add(BLACK, 24, "00000010111")
227 BitParser.add(BLACK, 25, "00000011000")
228 BitParser.add(BLACK, 26, "000011001010")
229 BitParser.add(BLACK, 27, "000011001011")
230 BitParser.add(BLACK, 28, "000011001100")
231 BitParser.add(BLACK, 29, "000011001101")
232 BitParser.add(BLACK, 30, "000001101000")
233 BitParser.add(BLACK, 31, "000001101001")
234 BitParser.add(BLACK, 32, "000001101010")
235 BitParser.add(BLACK, 33, "000001101011")
236 BitParser.add(BLACK, 34, "000011010010")
237 BitParser.add(BLACK, 35, "000011010011")
238 BitParser.add(BLACK, 36, "000011010100")
239 BitParser.add(BLACK, 37, "000011010101")
240 BitParser.add(BLACK, 38, "000011010110")
241 BitParser.add(BLACK, 39, "000011010111")
242 BitParser.add(BLACK, 40, "000001101100")
243 BitParser.add(BLACK, 41, "000001101101")
244 BitParser.add(BLACK, 42, "000011011010")
245 BitParser.add(BLACK, 43, "000011011011")
246 BitParser.add(BLACK, 44, "000001010100")
247 BitParser.add(BLACK, 45, "000001010101")
248 BitParser.add(BLACK, 46, "000001010110")
249 BitParser.add(BLACK, 47, "000001010111")
250 BitParser.add(BLACK, 48, "000001100100")
251 BitParser.add(BLACK, 49, "000001100101")
252 BitParser.add(BLACK, 50, "000001010010")
253 BitParser.add(BLACK, 51, "000001010011")
254 BitParser.add(BLACK, 52, "000000100100")
255 BitParser.add(BLACK, 53, "000000110111")
256 BitParser.add(BLACK, 54, "000000111000")
257 BitParser.add(BLACK, 55, "000000100111")
258 BitParser.add(BLACK, 56, "000000101000")
259 BitParser.add(BLACK, 57, "000001011000")
260 BitParser.add(BLACK, 58, "000001011001")
261 BitParser.add(BLACK, 59, "000000101011")
262 BitParser.add(BLACK, 60, "000000101100")
263 BitParser.add(BLACK, 61, "000001011010")
264 BitParser.add(BLACK, 62, "000001100110")
265 BitParser.add(BLACK, 63, "000001100111")
266 BitParser.add(BLACK, 64, "0000001111")
267 BitParser.add(BLACK, 128, "000011001000")
268 BitParser.add(BLACK, 192, "000011001001")
269 BitParser.add(BLACK, 256, "000001011011")
270 BitParser.add(BLACK, 320, "000000110011")
271 BitParser.add(BLACK, 384, "000000110100")
272 BitParser.add(BLACK, 448, "000000110101")
273 BitParser.add(BLACK, 512, "0000001101100")
274 BitParser.add(BLACK, 576, "0000001101101")
275 BitParser.add(BLACK, 640, "0000001001010")
276 BitParser.add(BLACK, 704, "0000001001011")
277 BitParser.add(BLACK, 768, "0000001001100")
278 BitParser.add(BLACK, 832, "0000001001101")
279 BitParser.add(BLACK, 896, "0000001110010")
280 BitParser.add(BLACK, 960, "0000001110011")
281 BitParser.add(BLACK, 1024, "0000001110100")
282 BitParser.add(BLACK, 1088, "0000001110101")
283 BitParser.add(BLACK, 1152, "0000001110110")
284 BitParser.add(BLACK, 1216, "0000001110111")
285 BitParser.add(BLACK, 1280, "0000001010010")
286 BitParser.add(BLACK, 1344, "0000001010011")
287 BitParser.add(BLACK, 1408, "0000001010100")
288 BitParser.add(BLACK, 1472, "0000001010101")
289 BitParser.add(BLACK, 1536, "0000001011010")
290 BitParser.add(BLACK, 1600, "0000001011011")
291 BitParser.add(BLACK, 1664, "0000001100100")
292 BitParser.add(BLACK, 1728, "0000001100101")
293 BitParser.add(BLACK, 1792, "00000001000")
294 BitParser.add(BLACK, 1856, "00000001100")
295 BitParser.add(BLACK, 1920, "00000001101")
296 BitParser.add(BLACK, 1984, "000000010010")
297 BitParser.add(BLACK, 2048, "000000010011")
298 BitParser.add(BLACK, 2112, "000000010100")
299 BitParser.add(BLACK, 2176, "000000010101")
300 BitParser.add(BLACK, 2240, "000000010110")
301 BitParser.add(BLACK, 2304, "000000010111")
302 BitParser.add(BLACK, 2368, "000000011100")
303 BitParser.add(BLACK, 2432, "000000011101")
304 BitParser.add(BLACK, 2496, "000000011110")
305 BitParser.add(BLACK, 2560, "000000011111")
307 UNCOMPRESSED: ClassVar[BitParserState] = [None, None]
308 BitParser.add(UNCOMPRESSED, "1", "1")
309 BitParser.add(UNCOMPRESSED, "01", "01")
310 BitParser.add(UNCOMPRESSED, "001", "001")
311 BitParser.add(UNCOMPRESSED, "0001", "0001")
312 BitParser.add(UNCOMPRESSED, "00001", "00001")
313 BitParser.add(UNCOMPRESSED, "00000", "000001")
314 BitParser.add(UNCOMPRESSED, "T00", "00000011")
315 BitParser.add(UNCOMPRESSED, "T10", "00000010")
316 BitParser.add(UNCOMPRESSED, "T000", "000000011")
317 BitParser.add(UNCOMPRESSED, "T100", "000000010")
318 BitParser.add(UNCOMPRESSED, "T0000", "0000000011")
319 BitParser.add(UNCOMPRESSED, "T1000", "0000000010")
320 BitParser.add(UNCOMPRESSED, "T00000", "00000000011")
321 BitParser.add(UNCOMPRESSED, "T10000", "00000000010")
323 class CCITTException(PDFException):
324 pass
326 class EOFB(CCITTException):
327 pass
329 class InvalidData(CCITTException):
330 pass
332 class ByteSkip(CCITTException):
333 pass
335 _color: int
337 def __init__(self, width: int, bytealign: bool = False) -> None:
338 BitParser.__init__(self)
339 self.width = width
340 self.bytealign = bytealign
341 self.reset()
343 def feedbytes(self, data: bytes) -> None:
344 for byte in get_bytes(data):
345 try:
346 for m in (128, 64, 32, 16, 8, 4, 2, 1):
347 self._parse_bit(byte & m)
348 except self.ByteSkip:
349 self._accept = self._parse_mode
350 self._state = self.MODE
351 except self.EOFB:
352 break
354 def _parse_mode(self, mode: object) -> BitParserState:
355 if mode == "p":
356 self._do_pass()
357 self._flush_line()
358 return self.MODE
359 elif mode == "h":
360 self._n1 = 0
361 self._accept = self._parse_horiz1
362 if self._color:
363 return self.WHITE
364 else:
365 return self.BLACK
366 elif mode == "u":
367 self._accept = self._parse_uncompressed
368 return self.UNCOMPRESSED
369 elif mode == "e":
370 raise self.EOFB
371 elif isinstance(mode, int):
372 self._do_vertical(mode)
373 self._flush_line()
374 return self.MODE
375 else:
376 raise self.InvalidData(mode)
378 def _parse_horiz1(self, n: Any) -> BitParserState:
379 if n is None:
380 raise self.InvalidData
381 self._n1 += n
382 if n < 64:
383 self._n2 = 0
384 self._color = 1 - self._color
385 self._accept = self._parse_horiz2
386 if self._color:
387 return self.WHITE
388 else:
389 return self.BLACK
391 def _parse_horiz2(self, n: Any) -> BitParserState:
392 if n is None:
393 raise self.InvalidData
394 self._n2 += n
395 if n < 64:
396 self._color = 1 - self._color
397 self._accept = self._parse_mode
398 self._do_horizontal(self._n1, self._n2)
399 self._flush_line()
400 return self.MODE
401 elif self._color:
402 return self.WHITE
403 else:
404 return self.BLACK
406 def _parse_uncompressed(self, bits: str | None) -> BitParserState:
407 if not bits:
408 raise self.InvalidData
409 if bits.startswith("T"):
410 self._accept = self._parse_mode
411 self._color = int(bits[1])
412 self._do_uncompressed(bits[2:])
413 return self.MODE
414 else:
415 self._do_uncompressed(bits)
416 return self.UNCOMPRESSED
418 def _get_bits(self) -> str:
419 return "".join(str(b) for b in self._curline[: self._curpos])
421 def _get_refline(self, i: int) -> str:
422 if i < 0:
423 return "[]" + "".join(str(b) for b in self._refline)
424 elif len(self._refline) <= i:
425 return "".join(str(b) for b in self._refline) + "[]"
426 else:
427 return (
428 "".join(str(b) for b in self._refline[:i])
429 + "["
430 + str(self._refline[i])
431 + "]"
432 + "".join(str(b) for b in self._refline[i + 1 :])
433 )
435 def reset(self) -> None:
436 self._y = 0
437 self._curline = array.array("b", [1] * self.width)
438 self._reset_line()
439 self._accept = self._parse_mode
440 self._state = self.MODE
442 def output_line(self, y: int, bits: Sequence[int]) -> None:
443 print(y, "".join(str(b) for b in bits))
445 def _reset_line(self) -> None:
446 self._refline = self._curline
447 self._curline = array.array("b", [1] * self.width)
448 self._curpos = -1
449 self._color = 1
451 def _flush_line(self) -> None:
452 if self.width <= self._curpos:
453 self.output_line(self._y, self._curline)
454 self._y += 1
455 self._reset_line()
456 if self.bytealign:
457 raise self.ByteSkip
459 def _do_vertical(self, dx: int) -> None:
460 x1 = self._curpos + 1
461 while 1:
462 if x1 == 0:
463 if self._color == 1 and self._refline[x1] != self._color:
464 break
465 elif x1 == len(self._refline) or (
466 self._refline[x1 - 1] == self._color
467 and self._refline[x1] != self._color
468 ):
469 break
470 x1 += 1
471 x1 += dx
472 x0 = max(0, self._curpos)
473 x1 = max(0, min(self.width, x1))
474 if x1 < x0:
475 for x in range(x1, x0):
476 self._curline[x] = self._color
477 elif x0 < x1:
478 for x in range(x0, x1):
479 self._curline[x] = self._color
480 self._curpos = x1
481 self._color = 1 - self._color
483 def _do_pass(self) -> None:
484 x1 = self._curpos + 1
485 while 1:
486 if x1 == 0:
487 if self._color == 1 and self._refline[x1] != self._color:
488 break
489 elif x1 == len(self._refline) or (
490 self._refline[x1 - 1] == self._color
491 and self._refline[x1] != self._color
492 ):
493 break
494 x1 += 1
495 while 1:
496 if x1 == 0:
497 if self._color == 0 and self._refline[x1] == self._color:
498 break
499 elif x1 == len(self._refline) or (
500 self._refline[x1 - 1] != self._color
501 and self._refline[x1] == self._color
502 ):
503 break
504 x1 += 1
505 for x in range(self._curpos, x1):
506 self._curline[x] = self._color
507 self._curpos = x1
509 def _do_horizontal(self, n1: int, n2: int) -> None:
510 if self._curpos < 0:
511 self._curpos = 0
512 x = self._curpos
513 for _ in range(n1):
514 if len(self._curline) <= x:
515 break
516 self._curline[x] = self._color
517 x += 1
518 for _ in range(n2):
519 if len(self._curline) <= x:
520 break
521 self._curline[x] = 1 - self._color
522 x += 1
523 self._curpos = x
525 def _do_uncompressed(self, bits: str) -> None:
526 for c in bits:
527 self._curline[self._curpos] = int(c)
528 self._curpos += 1
529 self._flush_line()
532class CCITTFaxDecoder(CCITTG4Parser):
533 def __init__(
534 self,
535 width: int,
536 bytealign: bool = False,
537 reversed: bool = False,
538 ) -> None:
539 CCITTG4Parser.__init__(self, width, bytealign=bytealign)
540 self.reversed = reversed
541 self._buf = b""
543 def close(self) -> bytes:
544 return self._buf
546 def output_line(self, y: int, bits: Sequence[int]) -> None:
547 arr = array.array("B", [0] * ((len(bits) + 7) // 8))
548 if self.reversed:
549 bits = [1 - b for b in bits]
550 for i, b in enumerate(bits):
551 if b:
552 arr[i // 8] += (128, 64, 32, 16, 8, 4, 2, 1)[i % 8]
553 self._buf += arr.tobytes()
556def ccittfaxdecode(data: bytes, params: dict[str, object]) -> bytes:
557 K = params.get("K")
558 if K == -1:
559 cols = cast(int, params.get("Columns"))
560 bytealign = cast(bool, params.get("EncodedByteAlign"))
561 reversed = cast(bool, params.get("BlackIs1"))
562 parser = CCITTFaxDecoder(cols, bytealign=bytealign, reversed=reversed)
563 else:
564 raise PDFValueError(K)
565 parser.feedbytes(data)
566 return parser.close()
569# test
570def main(argv: list[str]) -> None:
571 if not argv[1:]:
572 import unittest
574 unittest.main()
575 return
577 class Parser(CCITTG4Parser):
578 def __init__(self, width: int, bytealign: bool = False) -> None:
579 import pygame # type: ignore[import]
581 CCITTG4Parser.__init__(self, width, bytealign=bytealign)
582 self.img = pygame.Surface((self.width, 1000))
584 def output_line(self, y: int, bits: Sequence[int]) -> None:
585 for x, b in enumerate(bits):
586 if b:
587 self.img.set_at((x, y), (255, 255, 255))
588 else:
589 self.img.set_at((x, y), (0, 0, 0))
591 def close(self) -> None:
592 import pygame
594 pygame.image.save(self.img, "out.bmp")
596 for path in argv[1:]:
597 with open(path, "rb") as fp:
598 (_, _, _k, w, _h, _) = path.split(".")
599 parser = Parser(int(w))
600 parser.feedbytes(fp.read())
601 parser.close()