o
    'j6hs!                     @  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!   ]/var/www/html/chefvision.cloud.itp360.com/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 )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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 )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)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 ]\}}||
rddg| | j|	< qqp| 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 )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   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 )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`.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 )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`.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    