
    &Th)                     X    d dl Z ddlmZmZ dZg dZg dZ G d d      Z G d	 d
      Zy)    N   )Image_imagingmorphi   )	      r         r            )	r   r   r   r   r	   r   r
   r   r   c                   <    e Zd ZdZd
dZd Zd Zd Zd Zd Z	d	 Z
y)
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                     ||| _         ng | _         d | _        |5ddgdgddgdgddgg dd}||vrd	|z   d
z   }t        |      ||   | _         y y )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 !)patternslut	Exception)selfr   op_nameknown_patternsmsgs        V/home/stella.sw7ft.com/public_html/venv/lib/python3.12/site-packages/PIL/ImageMorph.py__init__zLutBuilder.__init__@   s    $DMDM/1EF2324HI1213GHN n,(72S8n$*73DM#     c                 .    | xj                   |z  c_         y Nr   )r   r   s     r   add_patternszLutBuilder.add_patternsY   s    !r!   c                 b    ddgdt        fdt        t              D              | _        y )Nr   r      c              3   4   K   | ]  }|z  d kD       yw)r   N ).0imsymbolss     r   	<genexpr>z/LutBuilder.build_default_lut.<locals>.<genexpr>_   s     KaWa!eq[1Ks   )	bytearrayrangeLUT_SIZEr   )r   r,   r-   s    @@r   build_default_lutzLutBuilder.build_default_lut\   s'    a&K5?KKr!   c                     | j                   S r#   r   )r   s    r   get_lutzLutBuilder.get_luta   s    xxr!   c                 X    t        |      dk(  sJ dj                  fd|D              S )zstring_permute takes a pattern and a permutation and returns the
        string permuted according to the permutation list.
        	    c              3   (   K   | ]	  }|     y wr#   r)   )r*   ppatterns     r   r.   z-LutBuilder._string_permute.<locals>.<genexpr>i   s     7awqz7s   )lenjoin)r   r;   permutations    ` r   _string_permutezLutBuilder._string_permuted   s-     ;1$$$ww7;777r!   c                    ||fg}d|v rE|d   d   }t        d      D ]/  }|j                  | j                  |d   d   t              |f       1 d|v r?t	        |      }|d| D ],  \  }}|j                  | j                  |t
              |f       . d|v rkt	        |      }|d| D ]X  \  }}|j                  d	d
      j                  dd	      j                  d
d      }dt        |      z
  }|j                  ||f       Z |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   appendr?   ROTATION_MATRIXr<   MIRROR_MATRIXreplaceint)	r   basic_patternoptionsbasic_resultr   resr+   nr;   s	            r   _pattern_permutezLutBuilder._pattern_permutek   s(    #L12 '>2,q/C1X ))(2,q/?KSQ
 '>HA (! U!5!5g}!Ms STU '>HA (! 0!//#s3;;CEMMcSVW#c(l#/	0 r!   c                 D   | j                          g }| j                  D ]  }t        j                  d|j	                  dd            }|sd|z   dz   }t        |      |j                  d      }|j                  d      }t        |j                  d            }|j	                  d	d      j	                  dd      }|| j                  |||      z  } t        |      D ]I  \  }}|d
   j	                  dd      j	                  dd      }t        j                  |      }||d   f||<   K t        t              D ]Z  }t        |      dd }	ddt        |	      z
  z  |	z   ddd   }	|D ]+  \  }}
|j                  |	      sd
dg|
   | j                   |<   - \ | j                   S )zlCompile all patterns into a morphology lut.

        TBD :Build based on (file) morphlut:modify_lut
        z(\w*):?\s*\((.+?)\)\s*->\s*(\d)
r8   zSyntax error in pattern ""r   r   r    r   .Xz[01]NrE   r7   rB   )r2   r   researchrK   r   grouprL   rR   	enumeratecompiler0   r1   binr<   matchr   )r   r   r:   r,   r   rN   r;   resultr+   
bitpatternrs              r   	build_lutzLutBuilder.build_lut   s   
 	   	HA		<aiib>QRA1A5;n$ggajGggajG_F ooc2.66tR@G--gwGGH	H $H- 	*JAw
""3,44S&AA

1Agaj/HQK	* x 	,AQJS_!45
BDbDIJ  ,177:&#$a&)DHHQK,	, xxr!   )NN)__name__
__module____qualname____doc__r    r%   r2   r5   r?   rR   rc   r)   r!   r   r   r      s,    !F42"L
8<)r!   r   c                   <    e Zd ZdZd
dZd Zd Zd Zd Zd Z	d	 Z
y)MorphOpz*A class for binary morphological operatorsNc                     || _         | t        |      j                         | _         y| t        |      j                         | _         yy)z&Create a binary morphological operatorN)r   r$   )r   r   rc   )r   r   r   r   s       r   r    zMorphOp.__init__   sD    !'2<<>DH!!84>>@DH "r!   c                 n   | j                   d}t        |      |j                  dk7  rd}t        |      t	        j
                  |j                  |j                  d      }t        j                  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   outimagecounts        r   rs   zMorphOp.apply   s    
 88&CC. ::(CS/!99UZZT:##E$((OUXX[[(++..Qhr!   c                     | j                   d}t        |      |j                  dk7  rd}t        |      t	        j
                  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`.rl   rm   rn   )	r   r   ro   rp   r   r_   rt   ru   rv   r   rw   r   s      r   r_   zMorphOp.match   s[     88&CC. ::(CS/!""5?EHHKK@@r!   c                     |j                   dk7  rd}t        |      t        j                  |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`.rm   rn   )ro   rp   r   get_on_pixelsru   rv   r{   s      r   r}   zMorphOp.get_on_pixels   s8     ::(CS/!**588;;77r!   c                     t        |d      5 }t        |j                               | _        ddd       t	        | j                        t
        k7  rd| _        d}t        |      y# 1 sw Y   :xY w)z!Load an operator from an mrl filerbNzWrong size operator file!)openr/   readr   r<   r1   r   )r   filenamefr   s       r   load_lutzMorphOp.load_lut   sb    (D! 	+Q *DH	+ txx=H$DH-CC.  %	+ 	+s   A%%A.c                     | j                   d}t        |      t        |d      5 }|j                  | j                          ddd       y# 1 sw Y   yxY w)zSave an operator to an mrl fileNrl   wb)r   r   r   write)r   r   r   r   s       r   save_lutzMorphOp.save_lut   sL    88&CC. (D! 	QGGDHH	 	 	s   AAc                     || _         y)z#Set the lut from an external sourceNr4   )r   r   s     r   set_lutzMorphOp.set_lut   s	    r!   )NNN)rd   re   rf   rg   r    rs   r_   r}   r   r   r   r)   r!   r   ri   ri      s*    4A A	8!r!   ri   )	rY   r8   r   r   r1   rI   rJ   r   ri   r)   r!   r   <module>r      s9    
 "
V VrI Ir!   