+
     is!  c                  sf    ^ RI Ht ^ RIt^RIHtHt Rt. R	Ot. R
Ot ! R R4      t	 ! R R4      t
R# )    )annotationsN)Image_imagingmorphc                  sr    ] tR t^tRtRR R lltR R ltR R ltR	 R
 ltR R lt	R R lt
R R ltRtR# )
LutBuildera  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               s$    V ^8  d   QhRRRRRR/# )   patternslist[str] | Noneop_name
str | NonereturnNone Zformat   "5/usr/lib64/python3.14/site-packages/PIL/ImageMorph.py__annotate__LutBuilder.__annotate__A   s$     4 4(4:D4	4    c                	s    Ve   Wn         M. V n         R V n        Ve?   RRR.RR.RRR.RR	.R
R	R.R. RO/pW#9  d   RV R2p\        V4      hW2,          V n         R # R # )NZcorner1:(... ... ...)->0z4:(00. 01. ...)->1Z	dilation4z4:(... .0. .1.)->1Z	dilation8z4:(... .0. ..1)->1Zerosion4z4:(... .1. .0.)->0Zerosion8z4:(... .1. ..0)->0ZedgezUnknown pattern Z!)r   z4:(.0. .1. ...)->1z4:(01. .1. ...)->1)r   lut	Exception)selfr   r   Zknown_patternsmsgs   &&&  r   __init__ZLutBuilder.__init__A   s     $MDM%)/1EF2324HI1213GH N ,(	3n$*3DM# r   c                    V ^8  d   QhRRRR/# )r   r   z	list[str]r
   r   r   r   r   r   r   r   \   s     " "Y "4 "r   c                	s8    V ;P                   V,          un         R # Nr   )r   r      &&r   add_patternsZLutBuilder.add_patterns\   s    !r   c                   V ^8  d   QhRR/# )r   r
   r   r   r   r   r   r   r   _   s     L L4 Lr   c                	sf   aa ^ ^.o^o\        VV3R l\        \        4       4       4      V n        R# )r    c              3  sJ   <"   T F  pSVS,          ^ 8  ,          x  K  	  R# 5i)r    Nr   ).0imsymbolss   & r   	<genexpr>Z/LutBuilder.build_default_lut.<locals>.<genexpr>b   s!     K?aWa!eq[11?s    #N)	bytearrayrangeLUT_SIZEr   )r   r!   r"   s   &@@r   build_default_lutZLutBuilder.build_default_lut_   s'    a&K5?KKr   c               r   )r   r
   bytearray | Noner   r   r   r   r   r   d   s      ) r   c                	s    V P                   # r   r   )r   s   &r   get_lutZLutBuilder.get_lutd   s    xxr   c               s$    V ^8  d   QhRRRRRR/# )r   patternstrpermutationz	list[int]r
   r   r   r   r   r   r   g   s!     8 8s 8 8s 8r   c                s^   a \        V4      ^	8X  g   Q hRP                  V3R lV 4       4      # )ztstring_permute takes a pattern and a permutation and returns the
string permuted according to the permutation list.
 c              3  s6   <"   T F  pSV,          x  K  	  R # 5ir   r   )r   pr+   s   & r   r#   Z-LutBuilder._string_permute.<locals>.<genexpr>l   s     7;awqzz;s   )lenZjoin)r   r+   r-   s   &f&r   _string_permuteZLutBuilder._string_permuteg   s-     ;1$$$ww7;777r   c               s(    V ^8  d   QhRRRRRRRR/# )r   basic_patternr,   optionsbasic_resultintr
   zlist[tuple[str, int]]r   r   r   r   r   r   n   s,       +.>A	r   c                sD   W3.pRV9   dX   VR,          ^,          p\        ^4       F8  pVP                  V P                  VR,          ^ ,          \        4      V34       K:  	  RV9   dA   \	        V4      pVRV  F,  w  rVP                  V P                  V\
        4      V34       K.  	  RV9   dp   \	        V4      pVRV  F[  w  rVP                  RR4      P                  RR4      P                  RR4      p^\        V4      ,
          pVP                  W34       K]  	  V# )	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.Z4ZMNZN0ZZZ1)r%   appendr1   ROTATION_MATRIXr0   MIRROR_MATRIXreplacer5   )	r   r2   r3   r4   r   Zresr    Znr+   s	   &&&&     r   _pattern_permuteZ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               r   )r   r
   r$   r   r   r   r   r   r      s     * *9 *r   c                s   V P                  4        V P                  f   Q h. pV P                   F  p\        P                  ! RVP                  RR4      4      pV'       g   RV,           R,           p\        V4      hVP                  ^4      pVP                  ^4      p\        VP                  ^4      4      pVP                  RR4      P                  RR4      pWP                  WeV4      ,          pK  	  . pV FZ  pV^ ,          P                  RR	4      P                  R	R
4      pVP                  \        P                  ! V4      V^,          34       K\  	  \        \        4       F{  p	\        V	4      R,          p
R^	\        V
4      ,
          ,          V
,           RRR1,          p
V F6  w  rkVP!                  V
4      '       g   K  ^ ^.V,          V P                  V	&   K8  	  K}  	  V P                  # )z\Compile all patterns into a morphology lut.

TBD :Build based on (file) morphlut:modify_lut
Nz(\w*):?\s*\((.+?)\)\s*->\s*(\d)Z
r.   zSyntax error in pattern "Z"Z Z.ZXz[01]:r   NNr6   r7   )r'   r   r   reZsearchr;   r   Zgroupr5   r<   r8   Zcompiler%   r&   Zbinr0   match)r   r   r/   r!   r   r3   r+   ZresultZcompiled_patternsr    Z
bitpatternZrs   &           r   	build_lutZ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)__name__
__module____qualname____firstlineno____doc__r   r   r'   r*   r1   r<   r?   __static_attributes__r   r   r   r   r      s2    !F46"L
8@* *r   r   c                  sr    ] tR t^tRtRR R lltR R ltR R ltR	 R
 ltR R lt	R R lt
R R ltRtR# )MorphOpz*A class for binary morphological operatorsNc               s(    V ^8  d   QhRRRRRRRR/# )	r   r   r(   r   r	   r   r   r
   r   r   r   r   r   r   MorphOp.__annotate__   s8     A AA A #	A
 
Ar   c                s    Wn         Ve"   \        VR7      P                  4       V n         R# Ve"   \        VR7      P                  4       V n         R# R# )z&Create a binary morphological operatorN)r   r   )r   r   r?   )r   r   r   r   s   &&&&r   r   ZMorphOp.__init__   sD     !'2<<>DH!!84>>@DH "r   c               r   )r   imageImage.Imager
   ztuple[int, Image.Image]r   r   r   r   r   rG      s      ; +B r   c                s`   V P                   f   Rp\        V4      hVP                  R8w  d   Rp\        V4      h\        P
                  ! VP                  VP                  R4      p\        P                  ! \        V P                   4      VP                  4       VP                  4       4      pWC3# )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   ZnewZsizer   applybytesgetim)r   rH   r   ZoutimageZcounts   &&   r   rO   ZMorphOp.apply   s    
 88&CC. ::(CS/!99UZZT:##E$((OU[[]HNNDTUr   c               r   r   rH   rI   r
   zlist[tuple[int, int]]r   r   r   r   r   rG      s     C C; C+@ Cr   c                s    V P                   f   Rp\        V4      hVP                  R8w  d   Rp\        V4      h\        P
                  ! \        V P                   4      VP                  4       4      # )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`.rJ   rK   rL   )r   r   rM   rN   r   r>   rP   rQ   r   rH   r      && r   r>   ZMorphOp.match   sY     88&CC. ::(CS/!""5?EKKMBBr   c               r   rR   r   r   r   r   r   rG      s     	: 	:; 	:3H 	:r   c                s    VP                   R8w  d   Rp\        V4      h\        P                  ! VP	                  4       4      # )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`.rK   rL   )rM   rN   r   get_on_pixelsrQ   rS   rT   r   rU   ZMorphOp.get_on_pixels   s6     ::(CS/!**5;;=99r   c               r   r   filenamer,   r
   r   r   r   r   r   r   rG      s     ! ! ! !r   c                s   \        VR4      ;_uu_ 4       p\        VP                  4       4      V n        RRR4       \	        V P                  4      \
        8w  d   RV n        Rp\        V4      hR#   + '       g   i     LD; i)z!Load an operator from an mrl fileZrbNzWrong size operator file!)openr$   Zreadr   r0   r&   r   )r   rW   fr      &&  r   load_lutZMorphOp.load_lut   s^    (D!!Q *DH " txx=H$DH-CC.  % "!s   A00B 	c               r   rV   r   r   r   r   r   rG      s        r   c                s    V P                   f   Rp\        V4      h\        VR4      ;_uu_ 4       pVP                  V P                   4       RRR4       R#   + '       g   i     R# ; i)zSave an operator to an mrl fileNrJ   Zwb)r   r   rX   Zwrite)r   rW   r   rY   rZ   r   save_lutZMorphOp.save_lut   sI    88&CC. (D!!QGGDHH "!!!s   AA'	c               r   )r   r   r(   r
   r   r   r   r   r   r   rG     s      +  r   c                s    Wn         R# )z#Set the lut from an external sourceNr)   )r   r   r   r   set_lutZMorphOp.set_lut  s    r   r)   )NNN)r@   rA   rB   rC   rD   r   rO   r>   rU   r[   r\   r]   rE   r   r   r   rF   rF      s/    4A C	:! r   rF   i   )	      r                   r   )	r   rb   r    rd   ra   r_   rc   r`   r^   )Z
__future__r   r=   r.   r   r   r&   r9   r:   r   rF   r   r   r   <module>re      s<    # 	 "
[ [|N Nr   