## 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:assertself.fpisnotNoneifnot_accept(self.fp.read(9)):msg="not an XPM file"raiseSyntaxError(msg)# skip forward to next stringwhileTrue:line=self.fp.readline()ifnotline:msg="broken XPM file"raiseSyntaxError(msg)m=xpm_head.match(line)ifm:breakself._size=int(m.group(1)),int(m.group(2))palette_length=int(m.group(3))bpp=int(m.group(4))## load palette descriptionpalette={}for_inrange(palette_length):line=self.fp.readline().rstrip()c=line[1:bpp+1]s=line[bpp+1:-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"#"):rgb_int=int(rgb[1:],16)palette[c]=(o8((rgb_int>>16)&255)+o8((rgb_int>>8)&255)+o8(rgb_int&255))else:# unknown colourmsg="cannot read this XPM file"raiseValueError(msg)breakelse:# missing colour keymsg="cannot read this XPM file"raiseValueError(msg)args:tuple[int,dict[bytes,bytes]|tuple[bytes,...]]ifpalette_length>256:self._mode="RGB"args=(bpp,palette)else:self._mode="P"self.palette=ImagePalette.raw("RGB",b"".join(palette.values()))args=(bpp,tuple(palette.keys()))self.tile=[ImageFile._Tile("xpm",(0,0)+self.size,self.fp.tell(),args)]
[docs]defload_read(self,read_bytes:int)->bytes:## load all image data in one chunkxsize,ysize=self.sizeassertself.fpisnotNones=[self.fp.readline()[1:xsize+1].ljust(xsize)foriinrange(ysize)]returnb"".join(s)