
    hs!                    d    S SK Jr  S SKrSSKJrJr  Sr/ SQr/ SQr " S S	5      r	 " S
 S5      r
g)    )annotationsN   )Image_imagingmorphi   )	      r         r            )	r   r   r   r   r
   r   r   r	   r   c                  ~    \ rS rSrSr S     SS jjrSS jrSS jrSS jrSS jr	        SS	 jr
SS
 jrSrg)
LutBuilder   a  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                    Ub  Xl         O/ U l         S U l        Ub3  SS/S/SS/S/SS// SQS.nX#;  a  S	U S
3n[        U5      eX2   U l         g g )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        @/var/www/html/env/lib/python3.13/site-packages/PIL/ImageMorph.py__init__LutBuilder.__init__A   s     $MDM%)/1EF2324HI1213GHN ,(	3n$*3DM#     c                .    U =R                   U-  sl         g Nr   )r   r   s     r!   add_patternsLutBuilder.add_patterns\   s    !r$   c                d   ^^ SS/mSm[        UU4S j[        [        5       5       5      U l        g )Nr   r      c              3  :   >#    U  H  nTUT-  S :     v   M     g7f)r   N ).0imsymbolss     r!   	<genexpr>/LutBuilder.build_default_lut.<locals>.<genexpr>b   s     K?aWa!eq[1?s   )	bytearrayrangeLUT_SIZEr   )r   r0   r1   s    @@r!   build_default_lutLutBuilder.build_default_lut_   s'    a&K5?KKr$   c                    U R                   $ r&   r   )r   s    r!   get_lutLutBuilder.get_lutd   s    xxr$   c                \   ^ [        U5      S:X  d   eSR                  U4S jU 5       5      $ )ztstring_permute takes a pattern and a permutation and returns the
string permuted according to the permutation list.
	    c              3  .   >#    U  H
  nTU   v   M     g 7fr&   r-   )r.   ppatterns     r!   r2   -LutBuilder._string_permute.<locals>.<genexpr>l   s     7;awqz;s   )lenjoin)r   rB   permutations    ` r!   _string_permuteLutBuilder._string_permuteg   s-     ;1$$$ww7;777r$   c                   X4/nSU;   aG  US   S   n[        S5       H0  nUR                  U R                  US   S   [        5      U45        M2     SU;   a@  [	        U5      nUSU  H,  u  pUR                  U R                  U[
        5      U45        M.     SU;   ak  [	        U5      nUSU  HW  u  pUR                  S	S
5      R                  SS	5      R                  S
S5      nS[        U5      -
  nUR                  X45        MY     U$ )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)r5   appendrG   ROTATION_MATRIXrD   MIRROR_MATRIXreplaceint)	r   basic_patternoptionsbasic_resultr   resr/   nrB   s	            r!   _pattern_permuteLutBuilder._pattern_permuten   s    #12 '>2,q/C1X))(2,q/?KSQ 
 '>HA (!!5!5g}!Ms ST !- '>HA (!!//#s3;;CEMMcSVW#c(l/	 !- r$   c                   U R                  5         U R                  c   e/ nU R                   H  n[        R                  " SUR                  SS5      5      nU(       d  SU-   S-   n[        U5      eUR                  S5      nUR                  S5      n[        UR                  S	5      5      nUR                  S
S5      R                  SS5      nXR                  XeU5      -  nM     / nU HR  nUS   R                  SS5      R                  SS5      nUR                  [        R                  " U5      US   45        MT     [        [        5       Hb  n	[        U	5      SS n
SS[        U
5      -
  -  U
-   SSS2   n
U H1  u  pkUR!                  U
5      (       d  M  SS/U   U R                  U	'   M3     Md     U R                  $ )z\Compile 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]rN   r>   rK   )r7   r   r   researchrT   r   grouprU   r[   rQ   compiler5   r6   binrD   match)r   r   rA   r0   r    rW   rB   resultcompiled_patternsr/   
bitpatternrs               r!   	build_lutLutBuilder.build_lut   s   
 	 xx### A		<aiib>QRA1A5;n$ggajGggajG_F ooc2.66tR@G--gGGH  G
""3,44S&AA$$bjjmWQZ%@A   xAQJS_!45
BDbDIJ/
==,,#$a&)DHHQK 0 ! xxr$   )r   r   )NN)r   list[str] | Noner   
str | NonereturnNone)r   z	list[str]rq   rr   )rq   rr   )rq   bytearray | None)rB   strrF   z	list[int]rq   rt   )rV   rt   rW   rt   rX   rU   rq   zlist[tuple[str, int]])rq   r4   )__name__
__module____qualname____firstlineno____doc__r"   r(   r7   r;   rG   r[   rm   __static_attributes__r-   r$   r!   r   r      sl    !H HL4(4:D4	46"L
8 +.>A	@*r$   r   c                  v    \ rS rSrSr   S       SS jjrSS jrSS jrSS jrSS jr	SS	 jr
SS
 jrSrg)MorphOp   z*A class for binary morphological operatorsNc                    Xl         Ub  [        US9R                  5       U l         gUb  [        US9R                  5       U l         gg)z&Create a binary morphological operatorN)r   r'   )r   r   rm   )r   r   r   r   s       r!   r"   MorphOp.__init__   sD     !'2<<>DH!!84>>@DH "r$   c                \   U R                   c  Sn[        U5      eUR                  S:w  a  Sn[        U5      e[        R
                  " UR                  UR                  S5      n[        R                  " [        U R                   5      UR                  5       UR                  5       5      nXC4$ )zwRun 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   imager    outimagecounts        r!   r   MorphOp.apply   s    
 88&CC. ::(CS/!99UZZT:##E$((OU[[]HNNDTUr$   c                    U R                   c  Sn[        U5      eUR                  S:w  a  Sn[        U5      e[        R
                  " [        U R                   5      UR                  5       5      $ )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`.r   r   r   )r   r   r   r   r   rh   r   r   r   r   r    s      r!   rh   MorphOp.match   sY     88&CC. ::(CS/!""5?EKKMBBr$   c                    UR                   S:w  a  Sn[        U5      e[        R                  " UR	                  5       5      $ )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`.r   r   )r   r   r   get_on_pixelsr   r   s      r!   r   MorphOp.get_on_pixels   s6     ::(CS/!**5;;=99r$   c                    [        US5       n[        UR                  5       5      U l        SSS5        [	        U R                  5      [
        :w  a  SU l        Sn[        U5      eg! , (       d  f       N@= f)z!Load an operator from an mrl filerbNzWrong size operator file!)openr4   readr   rD   r6   r   )r   filenamefr    s       r!   load_lutMorphOp.load_lut   s[    (D!Q *DH " txx=H$DH-CC.  % "!s   A&&
A4c                    U R                   c  Sn[        U5      e[        US5       nUR                  U R                   5        SSS5        g! , (       d  f       g= f)zSave an operator to an mrl fileNr   wb)r   r   r   write)r   r   r    r   s       r!   save_lutMorphOp.save_lut   sC    88&CC. (D!QGGDHH "!!s   A
Ac                    Xl         g)z#Set the lut from an external sourceNr:   )r   r   s     r!   set_lutMorphOp.set_lut  s    r$   r:   )NNN)r   rs   r   rp   r   ro   rq   rr   )r   Image.Imagerq   ztuple[int, Image.Image])r   r   rq   zlist[tuple[int, int]])r   rt   rq   rr   )r   rs   rq   rr   )ru   rv   rw   rx   ry   r"   r   rh   r   r   r   r   rz   r-   r$   r!   r|   r|      s_    4 !%"%)	AA A #	A
 
A C	:!r$   r|   )
__future__r   rc   r?   r   r   r6   rR   rS   r   r|   r-   r$   r!   <module>r      s<    # 	 "
[ [|N Nr$   