o
    6d'                      @   sL   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 )    N   )Image_imagingmorphi   )	      r         r            )	r   r   r   r
   r   r   r	   r   r   c                   @   J   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   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)ZcornerZ	dilation4Z	dilation8Zerosion4Zerosion8edgezUnknown pattern !)patternslut	Exception)selfr   op_nameZknown_patternsmsg r   eC:\Users\jesus\OneDrive\Desktop\erpjis_fastapi\backend\jisbackend\Lib\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   build_default_lut\   s   "zLutBuilder.build_default_lutc                 C   s   | j S r   r   r'   r   r   r   get_luta   s   zLutBuilder.get_lutc                    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patternr   r   r#   i   s    z-LutBuilder._string_permute.<locals>.<genexpr>)lenjoin)r   r/   Zpermutationr   r.   r   _string_permuted   s   zLutBuilder._string_permutec           	      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)r%   appendr2   ROTATION_MATRIXr0   MIRROR_MATRIXreplaceint)	r   Zbasic_patternoptionsZbasic_resultr   resr   nr/   r   r   r   _pattern_permutek   s$   
zLutBuilder._pattern_permutec                 C   s<  |    g }| jD ]<}td|dd}|s!d| d }t||d}|d}t|d}|d	ddd}|| |||7 }q	t	|D ]\}}|d
 dddd}t
|}||d f||< qJttD ].}t|dd }	ddt|	  |	 ddd }	|D ]\}}
||	rd
dg|
 | j|< qql| 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]Nr7   r+   r4   )r(   r   researchr=   r   groupr>   rB   	enumeratecompiler%   r&   binr0   matchr   )r   r   r-   r!   r   r?   r/   resultr   Z
bitpatternrr   r   r   	build_lut   s2   




zLutBuilder.build_lut)NN)__name__
__module____qualname____doc__r   r   r(   r*   r2   rB   rQ   r   r   r   r   r      s    
#r   c                   @   r   )MorphOpz*A class for binary morphological operatorsNc                 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   rQ   )r   r   r   r   r   r   r   r      s   zMorphOp.__init__c                 C   sb   | j du rd}t||jdkrd}t|t|j|jd}tt	| j |j
j|j
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imid)r   imager   Zoutimagecountr   r   r   r^      s   

zMorphOp.applyc                 C   sB   | j du rd}t||jdkrd}t|tt| j |j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`.NrW   rX   rY   )	r   r   rZ   r[   r   rN   r_   r`   ra   r   rb   r   r   r   r   rN      s   

zMorphOp.matchc                 C   s$   |j dkrd}t|t|jj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`.rX   rY   )rZ   r[   r   get_on_pixelsr`   ra   rd   r   r   r   re      s   
zMorphOp.get_on_pixelsc                 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   r0   r&   r   )r   filename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 fileNrW   wb)r   r   rg   write)r   ri   r   rj   r   r   r   save_lut   s   
"zMorphOp.save_lutc                 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)rR   rS   rT   rU   r   r^   rN   re   rk   rn   ro   r   r   r   r   rV      s    

rV   )	rH   r,   r   r   r&   r;   r<   r   rV   r   r   r   r   <module>   s    