@@ -267,6 +267,10 @@ class BLPFormatError(NotImplementedError):
267267 pass
268268
269269
270+ def _accept (prefix ):
271+ return prefix [:4 ] in (b"BLP1" , b"BLP2" )
272+
273+
270274class BlpImageFile (ImageFile .ImageFile ):
271275 """
272276 Blizzard Mipmap Format
@@ -304,7 +308,7 @@ def decode(self, buffer):
304308 self ._read_blp_header ()
305309 self ._load ()
306310 except struct .error as e :
307- raise OSError ("Truncated Blp file" ) from e
311+ raise OSError ("Truncated BLP file" ) from e
308312 return 0 , 0
309313
310314 def _safe_read (self , length ):
@@ -439,12 +443,54 @@ def _load(self):
439443 self .set_as_raw (bytes (data ))
440444
441445
442- def _accept (prefix ):
443- return prefix [:4 ] in (b"BLP1" , b"BLP2" )
446+ class BLP2Encoder (ImageFile .PyEncoder ):
447+ _pushes_fd = True
448+
449+ def _write_palette (self ):
450+ data = b""
451+ palette = self .im .getpalette ("RGBA" , "RGBA" )
452+ for i in range (256 ):
453+ r , g , b , a = palette [i * 4 : (i + 1 ) * 4 ]
454+ data += struct .pack ("<4B" , b , g , r , a )
455+ return data
456+
457+ def encode (self , bufsize ):
458+ palette_data = self ._write_palette ()
459+
460+ offset = 20 + 16 * 4 * 2 + len (palette_data )
461+ data = struct .pack ("<16I" , offset , * ((0 ,) * 15 ))
462+
463+ w , h = self .im .size
464+ data += struct .pack ("<16I" , w * h , * ((0 ,) * 15 ))
465+
466+ data += palette_data
467+
468+ for y in range (h ):
469+ for x in range (w ):
470+ data += struct .pack ("<B" , self .im .getpixel ((x , y )))
471+
472+ return len (data ), 0 , data
473+
474+
475+ def _save (im , fp , filename , save_all = False ):
476+ if im .mode != "P" :
477+ raise ValueError ("Unsupported BLP image mode" )
478+
479+ fp .write (b"BLP2" )
480+ fp .write (struct .pack ("<i" , 1 )) # Uncompressed or DirectX compression
481+ fp .write (struct .pack ("<b" , Encoding .UNCOMPRESSED ))
482+ fp .write (struct .pack ("<b" , 1 if im .palette .mode == "RGBA" else 0 ))
483+ fp .write (struct .pack ("<b" , 0 )) # alpha encoding
484+ fp .write (struct .pack ("<b" , 0 )) # mips
485+ fp .write (struct .pack ("<II" , * im .size ))
486+
487+ ImageFile ._save (im , fp , [("BLP2" , (0 , 0 ) + im .size , 0 , im .mode )])
444488
445489
446490Image .register_open (BlpImageFile .format , BlpImageFile , _accept )
447491Image .register_extension (BlpImageFile .format , ".blp" )
448-
449492Image .register_decoder ("BLP1" , BLP1Decoder )
450493Image .register_decoder ("BLP2" , BLP2Decoder )
494+
495+ Image .register_save (BlpImageFile .format , _save )
496+ Image .register_encoder ("BLP2" , BLP2Encoder )
0 commit comments