+
    it(                    f    ^ 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                  r    ] 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               $    V ^8  d   QhRRRRRR/# )   patternslist[str] | Noneop_name
str | NonereturnNone )formats   "n/Users/tonyclaw/.openclaw/workspace/skills/math-calculator/venv/lib/python3.14/site-packages/PIL/ImageMorph.py__annotate__LutBuilder.__annotate__A   s$      (:D	    c                    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# Ve	   Wn        R# . V n        R# )z
:param patterns: A list of input patterns, or None.
:param op_name: The name of a known pattern. One of "corner", "dilation4",
   "dilation8", "erosion4", "erosion8" or "edge".
:exception Exception: If the op_name is not recognized.
Ncorner1:(... ... ...)->0z4:(00. 01. ...)->1	dilation4z4:(... .0. .1.)->1	dilation8z4:(... .0. ..1)->1erosion4z4:(... .1. .0.)->0erosion8z4:(... .1. ..0)->0edgezUnknown pattern !)r   z4:(.0. .1. ...)->1z4:(01. .1. ...)->1)lut	Exceptionr
   )selfr
   r   known_patternsmsgs   &&&  r   __init__LutBuilder.__init__A   s     &*/1EF2324HI1213GH N ,(	3n$*3DM!$MDMr   c                    V ^8  d   QhRRRR/# )r	   r
   z	list[str]r   r   r   )r   s   "r   r   r   b   s     " "Y "4 "r   c                8    V ;P                   V,          un         R# )zD
Append to list of patterns.

:param patterns: Additional patterns.
N)r
   )r!   r
   s   &&r   add_patternsLutBuilder.add_patternsb   s     	!r   c                   V ^8  d   QhRR/# r	   r   	bytearrayr   )r   s   "r   r   r   j   s     	 	9 	r   c                z   aa ^ ^.o^o\        VV3R l\        \        4       4       4      V n        V P                  # )zs
Set the current LUT, and return it.

This is the default LUT that patterns will be applied against when building.
c              3  J   <"   T F  pSVS,          ^ 8  ,          x  K  	  R# 5i)r   Nr   ).0imsymbolss   & r   	<genexpr>/LutBuilder.build_default_lut.<locals>.<genexpr>r   s!     K?aWa!eq[11?s    #)r,   rangeLUT_SIZEr   )r!   r1   r2   s   &@@r   build_default_lutLutBuilder.build_default_lutj   s2     a&K5?KKxxr   c                   V ^8  d   QhRR/# )r	   r   bytearray | Noner   )r   s   "r   r   r   u   s      ) r   c                    V P                   # )z
Returns the current LUT
r   )r!   s   &r   get_lutLutBuilder.get_lutu   s     xxr   c               $    V ^8  d   QhRRRRRR/# )r	   patternstrpermutationz	list[int]r   r   )r   s   "r   r   r   {   s!     8 8s 8 8s 8r   c                ^   a \        V4      ^	8X  g   Q hRP                  V3R lV 4       4      # )zeTakes a pattern and a permutation and returns the
string permuted according to the permutation list.
 c              3  6   <"   T F  pSV,          x  K  	  R # 5i)Nr   )r/   pr@   s   & r   r3   -LutBuilder._string_permute.<locals>.<genexpr>   s     7;awqzz;s   )lenjoin)r!   r@   rB   s   &f&r   _string_permuteLutBuilder._string_permute{   s-     ;1$$$ww7;777r   c               (    V ^8  d   QhRRRRRRRR/# )r	   basic_patternrA   optionsbasic_resultintr   zlist[tuple[str, int]]r   )r   s   "r   r   r      s,       +.>A	r   c                D   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# )	zTakes 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.4MNN0Z1)r5   appendrJ   ROTATION_MATRIXrH   MIRROR_MATRIXreplacerP   )	r!   rM   rN   rO   r
   resr0   nr@   s	   &&&&     r   _pattern_permuteLutBuilder._pattern_permute   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                   V ^8  d   QhRR/# r+   r   )r   s   "r   r   r      s     ( (9 (r   c                   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                  # )zgCompile all patterns into a morphology LUT, and return it.

This is the data to be passed into MorphOp.Nz(\w):?\s*\((.+?)\)\s*->\s*(\d)
rD   zSyntax error in pattern "" .Xz[01]:r	   NNrU   rX   )r7   r   r
   researchr\   r    grouprP   r_   rY   compiler5   r6   binrH   match)r!   r
   rF   r1   r#   rN   r@   resultcompiled_patternsr0   
bitpatternrs   &           r   	build_lutLutBuilder.build_lut   s    	 xx### A		;QYYtR=PQA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(   r7   r=   rJ   r_   rr   __static_attributes__r   r   r   r   r      s2    !FB"	8@( (r   r   c                  r    ] 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               (    V ^8  d   QhRRRRRRRR/# )	r	   r   r:   r   r   r
   r   r   r   r   )r   s   "r   r   MorphOp.__annotate__   s8     A AA A #	A
 
Ar   c                b    Vf   Vf	   Wn         R# \        W24      P                  4       V n         R# )a  Create a binary morphological operator.

If the LUT is not provided, then it is built using LutBuilder from the op_name
or the patterns.

:param lut: The LUT data.
:param patterns: A list of input patterns, or None.
:param op_name: The name of a known pattern. One of "corner", "dilation4",
"dilation8", "erosion4", "erosion8", "edge".
:exception Exception: If the op_name is not recognized.
N)r   r   rr   )r!   r   r   r
   s   &&&&r   r$   MorphOp.__init__   s(    " H!(4>>@DHr   c                    V ^8  d   QhRRRR/# )r	   imageImage.Imager   ztuple[int, Image.Image]r   )r   s   "r   r   r}      s      ; +B r   c                ^   V P                   f   Rp\        V4      hVP                  R9  d   Rp\        V4      h\        P
                  ! VP                  VP                  4      p\        P                  ! \        V P                   4      VP                  4       VP                  4       4      pWC3# )a  Run a single morphological operation on an image.

Returns a tuple of the number of changed pixels and the
morphed image.

:param image: A 1-mode or L-mode image.
:exception Exception: If the current operator is None.
:exception ValueError: If the image is not 1 or L mode.No operator loadedImage mode must be 1 or LrW   L)r   r    mode
ValueErrorr   newsizer   applybytesgetim)r!   r   r#   outimagecounts   &&   r   r   MorphOp.apply   s     88&CC. ::Z'-CS/!99UZZ4##E$((OU[[]HNNDTUr   c                    V ^8  d   QhRRRR/# r	   r   r   r   zlist[tuple[int, int]]r   )r   s   "r   r   r}      s     C C; C+@ Cr   c                    V P                   f   Rp\        V4      hVP                  R9  d   Rp\        V4      h\        P
                  ! \        V P                   4      VP                  4       4      # )aH  Get 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`.

:param image: A 1-mode or L-mode image.
:exception Exception: If the current operator is None.
:exception ValueError: If the image is not 1 or L mode.r   r   r   )r   r    r   r   r   rm   r   r   r!   r   r#   s   && r   rm   MorphOp.match   sY     88&CC. ::Z'-CS/!""5?EKKMBBr   c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r}     s     : :; :3H :r   c                    VP                   R9  d   Rp\        V4      h\        P                  ! VP	                  4       4      # )a  Get a list of all turned on pixels in a 1 or L mode image.

Returns a list of tuples of (x,y) coordinates of all non-empty pixels. See
:ref:`coordinate-system`.

:param image: A 1-mode or L-mode image.
:exception ValueError: If the image is not 1 or L mode.r   r   )r   r   r   get_on_pixelsr   r   s   && r   r   MorphOp.get_on_pixels  s6     ::Z'-CS/!**5;;=99r   c                    V ^8  d   QhRRRR/# r	   filenamerA   r   r   r   )r   s   "r   r   r}     s     ! ! ! !r   c                   \        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 file

:param filename: The file to read from.
:exception Exception: If the length of the file data is not 512.
rbNzWrong size operator file!)openr,   readr   rH   r6   r    )r!   r   fr#   s   &&  r   load_lutMorphOp.load_lut  s`     (D!!Q *DH " txx=H$DH-CC.  % "!s   A00B 	c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r}   *  s        r   c                    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 file.

:param filename: The destination file.
:exception Exception: If the current operator is None.
Nr   wb)r   r    r   write)r!   r   r#   r   s   &&  r   save_lutMorphOp.save_lut*  sK     88&CC. (D!!QGGDHH "!!!s   AA'	c                    V ^8  d   QhRRRR/# )r	   r   r:   r   r   r   )r   s   "r   r   r}   7  s      +  r   c                    Wn         R# )z=
Set the LUT from an external source

:param lut: A new LUT.
Nr<   )r!   r   s   &&r   set_lutMorphOp.set_lut7  s	     r   r<   )NNN)rt   ru   rv   rw   rx   r$   r   rm   r   r   r   r   ry   r   r   r   r{   r{      s/    4A,(C&:! r   r{   i   )	      r                  r	   )	r	   r   r   r   r   r   r   r   r   )
__future__r   rh   rD   r   r   r6   rZ   r[   r   r{   r   r   r   <module>r      s<    # 	 "
m m`p pr   