a
    z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                   @  s   e Zd ZdZd ddddddZd	dd
ddZddddZddddZddddddZdddddddZ	d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list[str] | None
str | NoneNone)patternsop_namereturnc                 C  st   |d ur|| _ ng | _ d | _|d urpddgdgddgdgddgg dd}||vrfd	| d
}t||| | _ 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)ZcornerZ	dilation4Z	dilation8Zerosion4Zerosion8edgezUnknown pattern !)r   lut	Exception)selfr   r   Zknown_patternsmsg r   J/var/www/html/assistant/venv/lib/python3.9/site-packages/PIL/ImageMorph.py__init__A   s     zLutBuilder.__init__z	list[str])r   r   c                 C  s   |  j |7  _ d S Nr   )r   r   r   r   r   add_patterns\   s    zLutBuilder.add_patterns)r   c                   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       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   r,   r   r   r   get_lutd   s    zLutBuilder.get_lutstrz	list[int])patternpermutationr   c                   s(   t |dksJ d fdd|D S )zstring_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r2   r   r   r'   l   r(   z-LutBuilder._string_permute.<locals>.<genexpr>)lenjoin)r   r2   r3   r   r7   r   _string_permuteg   s    zLutBuilder._string_permuteintzlist[tuple[str, int]])basic_patternoptionsbasic_resultr   c           	      C  s   ||fg}d|v rJ|d d }t dD ]"}|| |d d t|f q&d|v rt|}|d| D ]\}}|| |t|f qfd|v rt|}|d| D ]>\}}|d	d
dd	d
d}dt| }|||f q|S )zpattern_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.4r   r	   r   MNN0Z1)r*   appendr:   ROTATION_MATRIXr8   MIRROR_MATRIXreplacer;   )	r   r<   r=   r>   r   resr#   nr2   r   r   r   _pattern_permuten   s$    
zLutBuilder._pattern_permuter)   c                 C  sH  |    | jdusJ g }| jD ]x}td|dd}|sPd| d }t||d}|d}t|d	}|d
ddd}|| 	|||7 }q g }|D ]4}|d dddd}|
t||d f qttD ]`}	t|	dd }
ddt|
  |
 ddd }
|D ](\}}||
rddg| | j|	< qq| jS )zlCompile all patterns into a morphology lut.

        TBD :Build based on (file) morphlut:modify_lut
        Nz(\w*):?\s*\((.+?)\)\s*->\s*(\d)
r5   zSyntax error in pattern ""r   r   r    r   .Xz[01]rC   r4   r@   )r-   r   r   researchrI   r   groupr;   rL   rF   compiler*   r+   binr8   match)r   r   r6   r%   r   r=   r2   resultZcompiled_patternsr#   Z
bitpatternrr   r   r   	build_lut   s0    


zLutBuilder.build_lut)NN)__name__
__module____qualname____doc__r   r    r-   r0   r:   rL   rZ   r   r   r   r   r      s   $  r   c                   @  s   e Zd ZdZdddddddd	Zd
ddddZd
ddddZd
ddddZdddddZdddddZ	dd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 t|d | _ n|dur8t|d | _ dS )z&Create a binary morphological operatorN)r   r   )r   r   rZ   )r   r   r   r   r   r   r   r      s
    zMorphOp.__init__zImage.Imageztuple[int, Image.Image])imager   c                 C  sb   | j du rd}t||jdkr,d}t|t|j|jd}tt	| j |
 |
 }||fS )zRun 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   r`   r   Zoutimagecountr   r   r   rh      s    

zMorphOp.applyzlist[tuple[int, int]]c                 C  sB   | j du rd}t||jdkr,d}t|tt| j | S )zGet 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`.Nra   rb   rc   )r   r   rd   re   r   rW   ri   rj   r   r`   r   r   r   r   rW      s    

zMorphOp.matchc                 C  s$   |j dkrd}t|t| S )zGet 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`.rb   rc   )rd   re   r   get_on_pixelsrj   rl   r   r   r   rm      s    
zMorphOp.get_on_pixelsr1   )filenamer   c                 C  s\   t |d}t| | _W d   n1 s.0    Y  t| jtkrXd| _d}t|dS )z!Load an operator from an mrl filerbNzWrong size operator file!)openr)   readr   r8   r+   r   )r   rn   fr   r   r   r   load_lut   s    ,zMorphOp.load_lutc                 C  sP   | j du rd}t|t|d}|| j  W d   n1 sB0    Y  dS )zSave an operator to an mrl fileNra   wb)r   r   rp   write)r   rn   r   rr   r   r   r   save_lut   s
    
zMorphOp.save_lut)r   r   c                 C  s
   || _ dS )z#Set the lut from an external sourceNr/   )r   r   r   r   r   set_lut  s    zMorphOp.set_lut)NNN)r[   r\   r]   r^   r   rh   rW   rm   rs   rv   rw   r   r   r   r   r_      s      
r_   )
__future__r   rR   r5   r   r   r+   rG   rH   r   r_   r   r   r   r   <module>   s    