2323b_whitespace = b"\x20 \x09 \x0a \x0b \x0c \x0d "
2424
2525MODES = {
26- # standard, plain
27- b"P1" : ("ppm_plain" , "1" ),
28- b"P2" : ("ppm_plain" , "L" ),
29- b"P3" : ("ppm_plain" , "RGB" ),
30- # standard, raw
31- b"P4" : ("raw" , "1" ),
32- b"P5" : ("raw" , "L" ),
33- b"P6" : ("raw" , "RGB" ),
26+ # standard
27+ b"P1" : "1" ,
28+ b"P2" : "L" ,
29+ b"P3" : "RGB" ,
30+ b"P4" : "1" ,
31+ b"P5" : "L" ,
32+ b"P6" : "RGB" ,
3433 # extensions
35- b"P0CMYK" : ( "raw" , " CMYK") ,
34+ b"P0CMYK" : " CMYK" ,
3635 # PIL extensions (for test purposes only)
37- b"PyP" : ( "raw" , "P" ) ,
38- b"PyRGBA" : ( "raw" , " RGBA") ,
39- b"PyCMYK" : ( "raw" , " CMYK") ,
36+ b"PyP" : "P" ,
37+ b"PyRGBA" : " RGBA" ,
38+ b"PyCMYK" : " CMYK" ,
4039}
4140
4241
@@ -90,18 +89,16 @@ def _read_token(self):
9089 def _open (self ):
9190 magic_number = self ._read_magic ()
9291 try :
93- decoder , mode = MODES [magic_number ]
92+ mode = MODES [magic_number ]
9493 except KeyError :
9594 raise SyntaxError ("not a PPM file" )
9695
97- self .custom_mimetype = {
98- b"P1" : "image/x-portable-bitmap" ,
99- b"P2" : "image/x-portable-graymap" ,
100- b"P3" : "image/x-portable-pixmap" ,
101- b"P4" : "image/x-portable-bitmap" ,
102- b"P5" : "image/x-portable-graymap" ,
103- b"P6" : "image/x-portable-pixmap" ,
104- }.get (magic_number )
96+ if magic_number in (b"P1" , b"P4" ):
97+ self .custom_mimetype = "image/x-portable-bitmap"
98+ elif magic_number in (b"P2" , b"P5" ):
99+ self .custom_mimetype = "image/x-portable-graymap"
100+ elif magic_number in (b"P3" , b"P6" ):
101+ self .custom_mimetype = "image/x-portable-pixmap"
105102
106103 for ix in range (3 ):
107104 token = int (self ._read_token ())
@@ -127,14 +124,12 @@ def _open(self):
127124 self .mode = "I"
128125 rawmode = "I;32B"
129126
127+ decoder_name = "raw"
128+ if magic_number in (b"P1" , b"P2" , b"P3" ):
129+ decoder_name = "ppm_plain"
130130 self ._size = xsize , ysize
131131 self .tile = [
132- (
133- decoder , # decoder
134- (0 , 0 , xsize , ysize ), # region: whole image
135- self .fp .tell (), # offset to image data
136- (rawmode , 0 , 1 ), # parameters for decoder
137- )
132+ (decoder_name , (0 , 0 , xsize , ysize ), self .fp .tell (), (rawmode , 0 , 1 ))
138133 ]
139134
140135
@@ -145,8 +140,8 @@ def _open(self):
145140class PpmPlainDecoder (ImageFile .PyDecoder ):
146141 _pulls_fd = True
147142
148- def _read_block (self , block_size = 10 ** 6 ):
149- return bytearray ( self .fd .read (block_size ) )
143+ def _read_block (self ):
144+ return self .fd .read (10 ** 6 )
150145
151146 def _find_comment_end (self , block , start = 0 ):
152147 a = block .find (b"\n " , start )
@@ -155,20 +150,18 @@ def _find_comment_end(self, block, start=0):
155150
156151 def _ignore_comments (self , block ):
157152 """
158- Deletes comments from block. If comment does not end in this
159- block, raises a flag.
153+ Deletes comments from block.
154+ If comment does not end in this block, raises a flag.
160155 """
161-
162156 comment_spans = False
163157 while True :
164158 comment_start = block .find (b"#" ) # look for next comment
165159 if comment_start == - 1 : # no comment found
166160 break
167161 comment_end = self ._find_comment_end (block , comment_start )
168162 if comment_end != - 1 : # comment ends in this block
169- block = (
170- block [:comment_start ] + block [comment_end + 1 :]
171- ) # delete comment
163+ # delete comment
164+ block = block [:comment_start ] + block [comment_end + 1 :]
172165 else : # last comment continues to next block(s)
173166 block = block [:comment_start ]
174167 comment_spans = True
@@ -177,9 +170,8 @@ def _ignore_comments(self, block):
177170
178171 def _decode_bitonal (self ):
179172 """
180- The reason this is a separate method is that in the plain PBM
181- format all data tokens are exactly one byte, and so the
182- inter-token whitespace is optional.
173+ This is a separate method because the plain PBM format all data tokens
174+ are exactly one byte, and so the inter-token whitespace is optional.
183175 """
184176 decoded_data = bytearray ()
185177 total_tokens = self .size
@@ -217,10 +209,8 @@ def _decode_bitonal(self):
217209
218210 def _decode_blocks (self , channels = 1 , depth = 8 ):
219211 decoded_data = bytearray ()
220- if depth == 32 :
221- maxval = 2 ** 31 - 1 # HACK: 32-bit grayscale uses signed int
222- else :
223- maxval = 2 ** depth - 1 # FIXME: should be passed by _open
212+ # HACK: 32-bit grayscale uses signed int
213+ maxval = 2 ** (31 if depth == 32 else depth ) - 1
224214 max_len = 10
225215 bytes_per_sample = depth // 8
226216 total_tokens = self .size * channels
0 commit comments