## The Python Imaging Library.# $Id$## XPM File handling## History:# 1996-12-29 fl Created# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7)## Copyright (c) Secret Labs AB 1997-2001.# Copyright (c) Fredrik Lundh 1996-2001.## See the README file for information on usage and redistribution.#from__future__importannotationsimportrefrom.importImage,ImageFile,ImagePalettefrom._binaryimporto8# XPM headerxpm_head=re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)')def_accept(prefix:bytes)->bool:returnprefix.startswith(b"/* XPM */")### Image plugin for X11 pixel maps.
[docs]classXpmImageFile(ImageFile.ImageFile):format="XPM"format_description="X11 Pixel Map"def_open(self)->None:ifnot_accept(self.fp.read(9)):msg="not an XPM file"raiseSyntaxError(msg)# skip forward to next stringwhileTrue:s=self.fp.readline()ifnots:msg="broken XPM file"raiseSyntaxError(msg)m=xpm_head.match(s)ifm:breakself._size=int(m.group(1)),int(m.group(2))pal=int(m.group(3))bpp=int(m.group(4))ifpal>256orbpp!=1:msg="cannot read this XPM file"raiseValueError(msg)## load palette descriptionpalette=[b"\0\0\0"]*256for_inrange(pal):s=self.fp.readline()ifs.endswith(b"\r\n"):s=s[:-2]elifs.endswith((b"\r",b"\n")):s=s[:-1]c=s[1]s=s[2:-2].split()foriinrange(0,len(s),2):ifs[i]==b"c":# process colour keyrgb=s[i+1]ifrgb==b"None":self.info["transparency"]=celifrgb.startswith(b"#"):# FIXME: handle colour names (see ImagePalette.py)rgb=int(rgb[1:],16)palette[c]=(o8((rgb>>16)&255)+o8((rgb>>8)&255)+o8(rgb&255))else:# unknown colourmsg="cannot read this XPM file"raiseValueError(msg)breakelse:# missing colour keymsg="cannot read this XPM file"raiseValueError(msg)self._mode="P"self.palette=ImagePalette.raw("RGB",b"".join(palette))self.tile=[ImageFile._Tile("raw",(0,0)+self.size,self.fp.tell(),"P")]
[docs]defload_read(self,read_bytes:int)->bytes:## load all image data in one chunkxsize,ysize=self.sizes=[self.fp.readline()[1:xsize+1].ljust(xsize)foriinrange(ysize)]returnb"".join(s)