o
    üÞhs!  ã                   @  sX   d dl mZ d dlZddlmZmZ dZg d¢Zg d¢ZG dd	„ d	ƒZ	G d
d„ dƒZ
dS )é    )ÚannotationsNé   )ÚImageÚ_imagingmorphi   )	é   é   r   é   é   r   é   é   é   )	r   r   r   r   r	   r   r
   r   r   c                   @  sZ   e Zd ZdZ	d#d$d	d
„Zd%dd„Zd&dd„Zd'dd„Zd(dd„Zd)dd„Z	d*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()

    NÚpatternsúlist[str] | NoneÚop_nameú
str | NoneÚreturnÚNonec                 C  sx   |d ur|| _ ng | _ d | _|d ur:ddgdgddgdgddgg d¢dœ}||vr3d	|› d
�}t|ƒ‚|| | _ d S d S )Nú1:(... ... ...)->0z4:(00. 01. ...)->1z4:(... .0. .1.)->1z4:(... .0. ..1)->1z4:(... .1. .0.)->0z4:(... .1. ..0)->0)r   z4:(.0. .1. ...)->1z4:(01. .1. ...)->1)ÚcornerÚ	dilation4Ú	dilation8Úerosion4Úerosion8ÚedgezUnknown pattern ú!)r   ÚlutÚ	Exception)Úselfr   r   Úknown_patternsÚmsg© r!   úN/var/www/html/premium_crap/venv/lib/python3.10/site-packages/PIL/ImageMorph.pyÚ__init__A   s"   úïzLutBuilder.__init__ú	list[str]c                 C  s   |  j |7  _ d S ©N©r   )r   r   r!   r!   r"   Úadd_patterns\   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>b   s   € z/LutBuilder.build_default_lut.<locals>.<genexpr>)Ú	bytearrayÚrangeÚLUT_SIZEr   ©r   r!   r+   r"   Úbuild_default_lut_   s   "zLutBuilder.build_default_lutúbytearray | Nonec                 C  s   | j S r%   ©r   r2   r!   r!   r"   Úget_lutd   s   zLutBuilder.get_lutÚpatternÚstrÚpermutationú	list[int]c                   s(   t |ƒdksJ ‚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 r%   r!   )r)   Úp©r7   r!   r"   r.   l   s   € z-LutBuilder._string_permute.<locals>.<genexpr>)ÚlenÚjoin)r   r7   r9   r!   r>   r"   Ú_string_permuteg   s   zLutBuilder._string_permuteÚbasic_patternÚoptionsÚbasic_resultÚintúlist[tuple[str, int]]c           	      C  sæ   ||fg}d|v r%|d d }t dƒD ]}| |  |d d t¡|f¡ qd|v rCt|ƒ}|d|… D ]\}}| |  |t¡|f¡ q3d|v rqt|ƒ}|d|… D ]\}}| d	d
¡ dd	¡ d
d¡}dt|ƒ }| ||f¡ qQ|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)r0   ÚappendrA   ÚROTATION_MATRIXr?   ÚMIRROR_MATRIXÚreplacerE   )	r   rB   rC   rD   r   Úresr*   Únr7   r!   r!   r"   Ú_pattern_permuten   s$   
ÿzLutBuilder._pattern_permuter/   c                 C  sD  |   ¡  | jdusJ ‚g }| jD ]<}t d| dd¡¡}|s(d| d }t|ƒ‚| d¡}| d¡}t| d	¡ƒ}| d
d¡ dd¡}||  	|||¡7 }qg }|D ]}|d  dd¡ dd¡}| 
t |¡|d f¡ qQttƒD ].}	t|	ƒdd… }
ddt|
ƒ  |
 ddd… }
|D ]\}}| |
¡r�ddg| | j|	< q‹qp| jS )zlCompile all patterns into a morphology lut.

        TBD :Build based on (file) morphlut:modify_lut
        Nz(\w*):?\s*\((.+?)\)\s*->\s*(\d)Ú
r<   zSyntax error in pattern "ú"r   r   r   ú r   Ú.ÚXz[01]rK   r;   rH   )r3   r   r   ÚreÚsearchrQ   r   ÚgrouprE   rT   rN   Úcompiler0   r1   Úbinr?   Úmatch)r   r   r=   r,   r    rC   r7   ÚresultÚcompiled_patternsr*   Ú
bitpatternÚrr!   r!   r"   Ú	build_lutŽ   s4   



€þzLutBuilder.build_lut)NN)r   r   r   r   r   r   )r   r$   r   r   )r   r   )r   r4   )r7   r8   r9   r:   r   r8   )rB   r8   rC   r8   rD   rE   r   rF   )r   r/   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   r'   r3   r6   rA   rT   rd   r!   r!   r!   r"   r      s    $ÿ




 r   c                   @  s^   e Zd ZdZ			dd dd„Zd!dd„Zd"dd„Zd"dd„Zd#dd„Zd#dd„Z	d$dd„Z
dS )%ÚMorphOpz*A class for binary morphological operatorsNr   r4   r   r   r   r   r   r   c                 C  sB   || _ |durt|d� ¡ | _ dS |durt|d� ¡ | _ dS dS )z&Create a binary morphological operatorN)r   r&   )r   r   rd   )r   r   r   r   r!   r!   r"   r#   ¾   s   ÿzMorphOp.__init__ÚimageúImage.Imageútuple[int, Image.Image]c                 C  sb   | j du rd}t|ƒ‚|jdkrd}t|ƒ‚t |j|jd¡}t t	| j ƒ| 
¡ | 
¡ ¡}||fS )z‡Run a single morphological operation on an image

        Returns a tuple of the number of changed pixels and the
        morphed imageNúNo operator loadedÚLúImage mode must be L)r   r   ÚmodeÚ
ValueErrorr   ÚnewÚsizer   ÚapplyÚbytesÚgetim)r   rj   r    ÚoutimageÚcountr!   r!   r"   rt   Ë   s   

zMorphOp.applyúlist[tuple[int, int]]c                 C  sB   | j du rd}t|ƒ‚|jdkrd}t|ƒ‚t t| 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`.Nrm   rn   ro   )r   r   rp   rq   r   r_   ru   rv   ©r   rj   r    r!   r!   r"   r_   Û   s   

zMorphOp.matchc                 C  s$   |j dkrd}t|ƒ‚t | ¡ ¡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`.rn   ro   )rp   rq   r   Úget_on_pixelsrv   rz   r!   r!   r"   r{   ê   s   
zMorphOp.get_on_pixelsÚfilenamer8   c                 C  s\   t |dƒ�}t| ¡ ƒ| _W d  ƒ n1 sw   Y  t| jƒtkr,d| _d}t|ƒ‚dS )z!Load an operator from an mrl fileÚrbNzWrong size operator file!)Úopenr/   Úreadr   r?   r1   r   )r   r|   Úfr    r!   r!   r"   Úload_lutõ   s   ÿýzMorphOp.load_lutc                 C  sR   | j du rd}t|ƒ‚t|dƒ�}| | j ¡ W d  ƒ dS 1 s"w   Y  dS )zSave an operator to an mrl fileNrm   Ú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 sourceNr5   )r   r   r!   r!   r"   Úset_lut  s   
zMorphOp.set_lut)NNN)r   r4   r   r   r   r   r   r   )rj   rk   r   rl   )rj   rk   r   ry   )r|   r8   r   r   )r   r4   r   r   )re   rf   rg   rh   r#   rt   r_   r{   r�   r„   r…   r!   r!   r!   r"   ri   »   s    ü





ri   )Ú
__future__r   rZ   r<   r   r   r1   rO   rP   r   ri   r!   r!   r!   r"   Ú<module>   s    