
    _it(                    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                    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Ub  Xl        g/ U l        g)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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 !)lut	Exceptionpatterns)selfr   op_nameknown_patternsmsgs        J/var/www/html/land-ocr/venv/lib/python3.13/site-packages/PIL/ImageMorph.py__init__LutBuilder.__init__A   s     &*/1EF2324HI1213GHN ,(	3n$*3DM!$MDM    c                .    U =R                   U-  sl         g)zD
Append to list of patterns.

:param patterns: Additional patterns.
N)r   )r   r   s     r!   add_patternsLutBuilder.add_patternsb   s     	!r$   c                z   ^^ SS/mSm[        UU4S j[        [        5       5       5      U l        U R                  $ )zs
Set the current LUT, and return it.

This is the default LUT that patterns will be applied against when building.
r   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>r   s     K?aWa!eq[1?s   )	bytearrayrangeLUT_SIZEr   )r   r.   r/   s    @@r!   build_default_lutLutBuilder.build_default_lutj   s2     a&K5?KKxxr$   c                    U R                   $ )z
Returns the current LUT
r   )r   s    r!   get_lutLutBuilder.get_lutu   s     xxr$   c                \   ^ [        U5      S:X  d   eSR                  U4S jU 5       5      $ )zeTakes 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)Nr+   )r,   ppatterns     r!   r0   -LutBuilder._string_permute.<locals>.<genexpr>   s     7;awqz;s   )lenjoin)r   r@   permutations    ` r!   _string_permuteLutBuilder._string_permute{   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$ )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.4r   r
   r   MNN0Z1)r3   appendrE   ROTATION_MATRIXrB   MIRROR_MATRIXreplaceint)	r   basic_patternoptionsbasic_resultr   resr-   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                   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                  $ )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)
r=   zSyntax error in pattern ""r   r   r    r   .Xz[01]rL   r<   rI   )r5   r   r   researchrR   r   grouprS   rY   rO   compiler3   r4   binrB   match)r   r   r?   r.   r    rU   r@   resultcompiled_patternsr-   
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)r   list[str] | Noner   
str | NonereturnNone)r   z	list[str]ro   rp   )ro   r2   )ro   bytearray | None)r@   strrD   z	list[int]ro   rr   )rT   rr   rU   rr   rV   rS   ro   zlist[tuple[str, int]])__name__
__module____qualname____firstlineno____doc__r"   r&   r5   r9   rE   rY   rk   __static_attributes__r+   r$   r!   r   r      sl    !H HL(:D	B"	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                Z    Uc
  Uc  Xl         g[        X25      R                  5       U l         g)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   rk   )r   r   r   r   s       r!   r"   MorphOp.__init__   s(    " H!(4>>@DHr$   c                Z   U R                   c  Sn[        U5      eUR                  S;  a  Sn[        U5      e[        R
                  " UR                  UR                  5      n[        R                  " [        U R                   5      UR                  5       UR                  5       5      nXC4$ )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rN   LImage mode must be 1 or L)r   r   mode
ValueErrorr   newsizer   applybytesgetim)r   imager    outimagecounts        r!   r   MorphOp.apply   s     88&CC. ::Z'-CS/!99UZZ4##E$((OU[[]HNNDTUr$   c                    U R                   c  Sn[        U5      eUR                  S;  a  Sn[        U5      e[        R
                  " [        U R                   5      UR                  5       5      $ )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   rf   r   r   r   r   r    s      r!   rf   MorphOp.match   sY     88&CC. ::Z'-CS/!""5?EKKMBBr$   c                    UR                   S;  a  Sn[        U5      e[        R                  " UR	                  5       5      $ )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                    [        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

:param filename: The file to read from.
:exception Exception: If the length of the file data is not 512.
rbNzWrong size operator file!)openr2   readr   rB   r4   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 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*  sE     88&CC. (D!QGGDHH "!!s   A
Ac                    Xl         g)z=
Set the LUT from an external source

:param lut: A new LUT.
Nr8   )r   r   s     r!   set_lutMorphOp.set_lut7  s	     r$   r8   )NNN)r   rq   r   rn   r   rm   ro   rp   )r   Image.Imagero   ztuple[int, Image.Image])r   r   ro   zlist[tuple[int, int]])r   rr   ro   rp   )r   rq   ro   rp   )rs   rt   ru   rv   rw   r"   r   rf   r   r   r   r   rx   r+   r$   r!   rz   rz      s_    4 !%"%)	AA A #	A
 
A,(C&:!r$   rz   )
__future__r   ra   r=   r   r   r4   rP   rQ   r   rz   r+   r$   r!   <module>r      s<    # 	 "
m m`p pr$   