B
    eAd)  ã            	   @   sh   d dl Z ddlmZmZ dZddd dddd	d
dg	Zddd d
ddd	ddg	ZG dd„ dƒZG dd„ dƒZdS )é    Né   )ÚImageÚ_imagingmorphi   é   é   é   é   é   é   é   c               @   sJ   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dS )Ú
LutBuilderaT  A class for building a MorphLut from a descriptive language

    The input patterns is a list of a strings sequences like these::

        4:(...
           .1.
           111)->1

    (whitespaces including linebreaks are ignored). The option 4
    describes a series of symmetry operations (in this case a
    4-rotation), the pattern is described by:

    - . or X - Ignore
    - 1 - Pixel is on
    - 0 - Pixel is off

    The result of the operation is described after "->" string.

    The default is to return the current pixel value, which is
    returned if no other match is found.

    Operations:

    - 4 - 4 way rotation
    - N - Negate
    - 1 - Dummy op for no other operation (an op must always be given)
    - M - Mirroring

    Example::

        lb = LutBuilder(patterns = ["4:(... .1. 111)->1"])
        lut = lb.build_lut()

    Nc             C   sv   |d k	r|| _ ng | _ d | _|d k	rrddgdgddgdgddgdddgd	œ}||krhd
| d }t|ƒ‚|| | _ d S )Nz1:(... ... ...)->0z4:(00. 01. ...)->1z4:(... .0. .1.)->1z4:(... .0. ..1)->1z4:(... .1. .0.)->0z4:(... .1. ..0)->0z4:(.0. .1. ...)->1z4:(01. .1. ...)->1)ZcornerZ	dilation4Z	dilation8Zerosion4Zerosion8ÚedgezUnknown pattern ú!)ÚpatternsÚlutÚ	Exception)Úselfr   Úop_nameZknown_patternsÚmsg© r   ú@/var/www/html/venv/lib/python3.7/site-packages/PIL/ImageMorph.pyÚ__init__@   s"    
zLutBuilder.__init__c             C   s   |  j |7  _ d S )N)r   )r   r   r   r   r   Úadd_patternsY   s    zLutBuilder.add_patternsc                s.   ddg‰d‰ t ‡ ‡fdd„ttƒD ƒƒ| _d S )Nr   r   é   c             3   s   | ]}ˆ|ˆ @ d k V  qdS )r   Nr   )Ú.0Úi)ÚmÚsymbolsr   r   ú	<genexpr>_   s    z/LutBuilder.build_default_lut.<locals>.<genexpr>)Ú	bytearrayÚrangeÚLUT_SIZEr   )r   r   )r   r   r   Úbuild_default_lut\   s    zLutBuilder.build_default_lutc             C   s   | j S )N)r   )r   r   r   r   Úget_luta   s    zLutBuilder.get_lutc                s(   t |ƒdkst‚d ‡ fdd„|D ƒ¡S )z„string_permute takes a pattern and a permutation and returns the
        string permuted according to the permutation list.
        é	   Ú c             3   s   | ]}ˆ | V  qd S )Nr   )r   Úp)Úpatternr   r   r   i   s    z-LutBuilder._string_permute.<locals>.<genexpr>)ÚlenÚAssertionErrorÚjoin)r   r'   Zpermutationr   )r'   r   Ú_string_permuted   s    zLutBuilder._string_permutec       	      C   sò   ||fg}d|krN|d d }x.t dƒD ]"}| |  |d d t¡|f¡ q(W d|krŽt|ƒ}x.|d|… D ]\}}| |  |t¡|f¡ qlW d|krît|ƒ}xN|d|… D ]>\}}| d	d
¡ dd	¡ d
d¡}dt|ƒ }| ||f¡ q¬W |S )zÉpattern_permute takes a basic pattern and its result and clones
        the pattern according to the modifications described in the $options
        parameter. It returns a list of all cloned patterns.Ú4éÿÿÿÿr   r   r   ÚMNÚNÚ0ÚZÚ1)r    Úappendr+   ÚROTATION_MATRIXr(   ÚMIRROR_MATRIXÚreplaceÚint)	r   Zbasic_patternÚoptionsZbasic_resultr   Úresr   Únr'   r   r   r   Ú_pattern_permutek   s"    
zLutBuilder._pattern_permutec             C   sP  |   ¡  g }x‚| jD ]x}t d| dd¡¡}|sDd| d }t|ƒ‚| d¡}| d¡}t| d¡ƒ}| d	d¡ dd¡}||  |||¡7 }qW xFt	|ƒD ]:\}}|d
  dd¡ dd¡}t 
|¡}||d f||< qšW xpttƒD ]d}t|ƒdd… }	ddt|	ƒ  |	 ddd… }	x0|D ](\}}
| |	¡rd
dg|
 | j|< qW qâW | jS )zlCompile all patterns into a morphology lut.

        TBD :Build based on (file) morphlut:modify_lut
        z(\w*):?\s*\((.+?)\)\s*->\s*(\d)Ú
r%   zSyntax error in pattern "ú"r   r   r   ú r   Ú.ÚXz[01]Nr0   r$   r-   )r"   r   ÚreÚsearchr6   r   Úgroupr7   r;   Ú	enumerateÚcompiler    r!   Úbinr(   Úmatchr   )r   r   r&   r   r   r8   r'   Úresultr   Z
bitpatternÚrr   r   r   Ú	build_lut‰   s.    


zLutBuilder.build_lut)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r"   r#   r+   r;   rJ   r   r   r   r   r      s   "
r   c               @   sJ   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dS )ÚMorphOpz*A class for binary morphological operatorsNc             C   s<   || _ |dk	r t|d ¡ | _ n|dk	r8t|d ¡ | _ dS )z&Create a binary morphological operatorN)r   )r   )r   r   rJ   )r   r   r   r   r   r   r   r   ¸   s
    zMorphOp.__init__c             C   sb   | j dkrd}t|ƒ‚|jdkr,d}t|ƒ‚t |j|jd¡}t t	| j ƒ|j
j|j
j¡}||fS )z‡Run a single morphological operation on an image

        Returns a tuple of the number of changed pixels and the
        morphed imageNzNo operator loadedÚLzImage mode must be L)r   r   ÚmodeÚ
ValueErrorr   ÚnewÚsizer   ÚapplyÚbytesÚimÚid)r   Úimager   ZoutimageÚcountr   r   r   rU   À   s    

zMorphOp.applyc             C   sB   | j dkrd}t|ƒ‚|jdkr,d}t|ƒ‚t t| j ƒ|jj¡S )zÈGet a list of coordinates matching the morphological operation on
        an image.

        Returns a list of tuples of (x,y) coordinates
        of all matching pixels. See :ref:`coordinate-system`.NzNo operator loadedrP   zImage mode must be L)	r   r   rQ   rR   r   rG   rV   rW   rX   )r   rY   r   r   r   r   rG   Ð   s    

zMorphOp.matchc             C   s$   |j dkrd}t|ƒ‚t |jj¡S )z©Get a list of all turned on pixels in a binary image

        Returns a list of tuples of (x,y) coordinates
        of all matching pixels. See :ref:`coordinate-system`.rP   zImage mode must be L)rQ   rR   r   Úget_on_pixelsrW   rX   )r   rY   r   r   r   r   r[   ß   s    
zMorphOp.get_on_pixelsc          	   C   sH   t |dƒ}t| ¡ ƒ| _W dQ R X t| jƒtkrDd| _d}t|ƒ‚dS )z!Load an operator from an mrl fileÚrbNzWrong size operator file!)Úopenr   Úreadr   r(   r!   r   )r   ÚfilenameÚfr   r   r   r   Úload_lutê   s    zMorphOp.load_lutc          	   C   s<   | j dkrd}t|ƒ‚t|dƒ}| | j ¡ W dQ R X dS )zSave an operator to an mrl fileNzNo operator loadedÚwb)r   r   r]   Úwrite)r   r_   r   r`   r   r   r   Úsave_lutô   s
    
zMorphOp.save_lutc             C   s
   || _ dS )z#Set the lut from an external sourceN)r   )r   r   r   r   r   Úset_lutü   s    zMorphOp.set_lut)NNN)rK   rL   rM   rN   r   rU   rG   r[   ra   rd   re   r   r   r   r   rO   µ   s   

rO   )	rA   r%   r   r   r!   r4   r5   r   rO   r   r   r   r   Ú<module>   s   

 