o
    õ·i±)  ã                   @  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  sz   d| _ |dur/ddgdgddgdgddgg d¢d	œ}||vr(d
|› d�}t|ƒ‚|| | _dS |dur8|| _dS g | _dS )a  
        :param patterns: A list of input patterns, or None.
        :param op_name: The name of a known pattern. One of "corner", "dilation4",
           "dilation8", "erosion4", "erosion8" or "edge".
        :exception Exception: If the op_name is not recognized.
        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)ZcornerZ	dilation4Z	dilation8Zerosion4Zerosion8ZedgezUnknown pattern ú!)ÚlutÚ	Exceptionr   )Úselfr   r   Zknown_patternsÚmsg© r   úTC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\PIL/ImageMorph.pyÚ__init__A   s    	ú

zLutBuilder.__init__ú	list[str]c                 C  s   |  j |7  _ dS )z\
        Append to list of patterns.

        :param patterns: Additional patterns.
        N)r   )r   r   r   r   r   Úadd_patternsb   s   zLutBuilder.add_patternsÚ	bytearrayc                   s0   ddg‰d‰ t ‡ ‡fdd„ttƒD ƒƒ| _| jS )z‹
        Set the current LUT, and return it.

        This is the default LUT that patterns will be applied against when building.
        r   r   é   c                 3  s    � | ]}ˆ|ˆ @ d k V  qdS )r   Nr   )Ú.0Úi©ÚmÚsymbolsr   r   Ú	<genexpr>r   s   € z/LutBuilder.build_default_lut.<locals>.<genexpr>N)r   ÚrangeÚLUT_SIZEr   ©r   r   r#   r   Úbuild_default_lutj   s   zLutBuilder.build_default_lutúbytearray | Nonec                 C  s   | j S )z)
        Returns the current LUT
        N©r   r)   r   r   r   Úget_lutu   s   zLutBuilder.get_lutÚpatternÚstrÚpermutationú	list[int]c                   s(   t |ƒdksJ ‚d ‡ fdd„|D ƒ¡S )zuTakes 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©r.   r   r   r&   €   s   € z-LutBuilder._string_permute.<locals>.<genexpr>N)ÚlenÚjoin)r   r.   r0   r   r5   r   Ú_string_permute{   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¹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'   Úappendr8   ÚROTATION_MATRIXr6   ÚMIRROR_MATRIXÚreplacer<   )	r   r9   r:   r;   r   Úresr"   Únr.   r   r   r   Ú_pattern_permute‚   s$   
ÿzLutBuilder._pattern_permutec                 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 )zoCompile all patterns into a morphology LUT, and return it.

        This is the data to be passed into MorphOp.Nz(\w):?\s*\((.+?)\)\s*->\s*(\d)Ú
r3   zSyntax error in pattern "ú"r   r   r   ú r   Ú.ÚXz[01]rB   r2   r?   )r*   r   r   ÚreÚsearchrH   r   Úgroupr<   rK   rE   Úcompiler'   r(   Úbinr6   Úmatch)r   r   r4   r$   r   r:   r.   ÚresultZcompiled_patternsr"   Z
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   r+   )r.   r/   r0   r1   r   r/   )r9   r/   r:   r/   r;   r<   r   r=   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r*   r-   r8   rK   rY   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   r+   r   r   r   r   r   r   c                 C  s.   |du r|du r|| _ dS t||ƒ ¡ | _ dS )aÈ  Create a binary morphological operator.

        If the LUT is not provided, then it is built using LutBuilder from the op_name
        or the patterns.

        :param lut: The LUT data.
        :param patterns: A list of input patterns, or None.
        :param op_name: The name of a known pattern. One of "corner", "dilation4",
        "dilation8", "erosion4", "erosion8", "edge".
        :exception Exception: If the op_name is not recognized.
        N)r   r   rY   )r   r   r   r   r   r   r   r   Ð   s   
zMorphOp.__init__ÚimageúImage.Imageútuple[int, Image.Image]c                 C  s`   | j du rd}t|ƒ‚|jdvrd}t|ƒ‚t |j|j¡}t t	| j ƒ| 
¡ | 
¡ ¡}||fS )a9  Run a single morphological operation on an image.

        Returns a tuple of the number of changed pixels and the
        morphed image.

        :param image: A 1-mode or L-mode image.
        :exception Exception: If the current operator is None.
        :exception ValueError: If the image is not 1 or L mode.NúNo operator loaded©rD   ÚLúImage mode must be 1 or L)r   r   ÚmodeÚ
ValueErrorr   ÚnewÚsizer   ÚapplyÚbytesÚgetim)r   r_   r   ZoutimageÚcountr   r   r   rj   æ   s   
	
zMorphOp.applyúlist[tuple[int, int]]c                 C  sB   | j du rd}t|ƒ‚|jdvrd}t|ƒ‚t t| j ƒ| ¡ ¡S )ax  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`.

        :param image: A 1-mode or L-mode image.
        :exception Exception: If the current operator is None.
        :exception ValueError: If the image is not 1 or L mode.Nrb   rc   re   )r   r   rf   rg   r   rV   rk   rl   ©r   r_   r   r   r   r   rV   ú   s   


zMorphOp.matchc                 C  s$   |j dvrd}t|ƒ‚t | ¡ ¡S )a!  Get a list of all turned on pixels in a 1 or L mode image.

        Returns a list of tuples of (x,y) coordinates of all non-empty pixels. See
        :ref:`coordinate-system`.

        :param image: A 1-mode or L-mode image.
        :exception ValueError: If the image is not 1 or L mode.rc   re   N)rf   rg   r   Úget_on_pixelsrl   ro   r   r   r   rp     s   
	zMorphOp.get_on_pixelsÚfilenamer/   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

        :param filename: The file to read from.
        :exception Exception: If the length of the file data is not 512.
        ÚrbNzWrong size operator file!)Úopenr   Úreadr   r6   r(   r   )r   rq   Ú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 file.

        :param filename: The destination file.
        :exception Exception: If the current operator is None.
        Nrb   Úwb)r   r   rs   Úwrite)r   rq   r   ru   r   r   r   Úsave_lut*  s   
"ÿzMorphOp.save_lutc                 C  s
   || _ dS )zU
        Set the LUT from an external source

        :param lut: A new LUT.
        Nr,   )r   r   r   r   r   Úset_lut7  s   
zMorphOp.set_lut)NNN)r   r+   r   r   r   r   r   r   )r_   r`   r   ra   )r_   r`   r   rn   )rq   r/   r   r   )r   r+   r   r   )rZ   r[   r\   r]   r   rj   rV   rp   rv   ry   rz   r   r   r   r   r^   Í   s    ü




r^   )Ú
__future__r   rQ   r3   r   r   r(   rF   rG   r   r^   r   r   r   r   Ú<module>   s    1