
    j5j>?                       U d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZmZmZmZ dd
lmZ ddlmZ ddlmZmZmZ ddlmZ ddlmZ  ej@                  e!      Z"d+dZ# G d de	      Z$e$jJ                  e$jL                  e$jN                  e$jP                  dZ)de*d<    G d dejV                        Z,dZ- G d de      Z. edde.      Z/e/j`                  Z0e/jb                  Z1d,dZ2d-dZ3d.dZ4d/d Z5	 d0	 	 	 	 	 	 	 	 	 d1d!Z6d" Z7	 d0	 	 	 	 	 	 	 	 	 	 	 d2d#Z8d3d$Z9d4d%Z:d5d&Z;dd'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d6d(Z<d7d)Z=dd'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d8d*Z>y)9z"Interface to Tesseract executable.    )annotationsN)suppress)IntEnum)pi)fspath)Path)PIPESTDOUTCalledProcessErrorTimeoutExpired)Version)	ToolProbe)MissingDependencyErrorSubprocessOutputErrorTesseractConfigError)OrientationConfidence)runc                d    | yt         j                  j                         }t        |       |d<   |S )zMCreate environment dict with OMP_THREAD_LIMIT set for Tesseract subprocesses.NOMP_THREAD_LIMIT)osenvironcopystr)omp_thread_limitenvs     N/var/www/html/qr/venv/lib/python3.12/site-packages/ocrmypdf/_exec/tesseract.py_tesseract_envr       s1    
**//
C!"23CJ    c                       e Zd ZdZdZdZdZdZy)ThresholdingMethodz6Tesseract thresholding methods for image binarization.r         N)__name__
__module____qualname____doc__AUTOOTSUADAPTIVE_OTSUSAUVOLA r   r   r    r    )   s    @DDMGr   r    )autootsuzadaptive-otsusauvolazdict[str, int]TESSERACT_THRESHOLDING_METHODSc                      e Zd ZdZd Zy)TesseractLoggerAdapterz7Prepend [tesseract] to messages emitted from tesseract.c                .    | j                   |d<   d| |fS )Nextraz[tesseract] r3   )selfmsgkwargss      r   processzTesseractLoggerAdapter.process>   s!    **wcU#V++r   N)r#   r$   r%   r&   r8   r+   r   r   r1   r1   ;   s
    A,r   r1   a  
    v?
    (?:
        (?:(?P<epoch>[0-9]+)!)?                           # epoch
        (?P<release>[0-9]+(?:\.[0-9]+)*)                  # release segment
        (?P<pre>                                          # pre-release
            [-_\.]?
            (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
            [-_\.]?
            (?P<pre_n>[0-9]+)?
        )?
        (?P<post>                                         # post release
            (?:-(?P<post_n1>[0-9]+))
            |
            (?:
                [-_\.]?
                (?P<post_l>post|rev|r)
                [-_\.]?
                (?P<post_n2>[0-9]+)?
            )
        )?
        (?P<dev>                                          # dev release
            [-_\.]?
            (?P<dev_l>dev)
            [-_\.]?
            (?P<dev_n>[0-9]+)?
        )?
        (?P<date>
            [-_\.]
            (?:20[0-9][0-9] [0-1][0-9] [0-3][0-9])       # yyyy mm dd
        )?
        (?P<gitcount>
            [-_\.]?
            [0-9]+
        )?
        (?P<gitcommit>
            [-_\.]?
            g[0-9a-f]{2,10}
        )?
    )
    (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
c                  p    e Zd ZdZ ej
                  dez   dz   ej                  ej                  z        Z	y)TesseractVersionzLModify standard packaging.Version regex to support Tesseract idiosyncrasies.z^\s*z\s*$N)
r#   r$   r%   r&   recompileTESSERACT_VERSION_PATTERNVERBOSE
IGNORECASE_regexr+   r   r   r:   r:   o   s2    VRZZ++g5rzzBMM7QFr   r:   	tesseractztesseract\s(.+))programversion_regexversion_clsc                 .    t               t        d      k\  S )z6Does Tesseract have -c thresholding method capability?z5.0)versionr   r+   r   r   has_thresholdingrG      s    9&&r   c                    d } ddg}	 t        |dt        t        dd      }|j                  }|j                         D ]$  }|j                  d      st         | |             |j                         ^}}|D ch c]  }|j                          c}S # t        $ r!}t         | |j                              |d }~ww xY wc c}w )Nc                    d}|| z  }|S )NzSTesseract failed to report available languages.
Output from Tesseract:
-----------
r+   )outputr6   s     r   
lang_errorz!get_languages.<locals>.lang_error   s     	
 	v
r   rA   z--list-langsT)textstdoutstderrlogs_errors_to_stdoutcheckError)
r   r	   r
   rM   r   r   rJ   
splitlines
startswithstrip)	rK   	args_tessprocrJ   eline_headerrestlangs	            r   get_languagesr\      s     n-IB"&
  !!# =??7#(F);<<= &&(NGd%)*TDJJL**  B$Z%9:AB +s   %B ;C	B?B::B?c                    dg}| r"|j                  ddj                  |       g       ||j                  dt        |      g       |S )NrA   z-l+z--oem)extendjoinr   )langsengine_modeargss      r   tess_base_argsrd      sF    =DT388E?+,Wc+./0Kr   c                .      fd}t         |             S )Nc               3    K   j                         j                         D ]\  } | j                         } | j                  dd      }t	        |      dk(  s5|d   j                         |d   j                         f ^ y w)N:r"   )maxsplitr   r!   )decoderR   rT   splitlen)rX   partsbinary_outputs     r   genz$_parse_tesseract_output.<locals>.gen   sq     !((*557 	9D::<DJJsQJ/E5zQAhnn&a(888		9s   AB+B)dict)rm   rn   s   ` r   _parse_tesseract_outputrp      s    9 ;r   c           
     `   t        dg|      ddt        |       dgz   }	 t        |t        t        |dt        |            }t        |j                        }t        |j!                  dd            }	t        |	t#        |j!                  dd            	      }
|
S # t        $ r t        dd	      cY S t        $ rt}t        |j                         t        |j                         |j                  xs d
|j                  xs d
z   }d|v sd|v rt        dd      cY d }~S t               |d }~ww xY w)Nosd--psm0rM   TrM   rN   timeoutrP   r   r           )angle
confidencer   s&   Too few characters. Skipping this page   Image too largezOrientation in degreeszOrientation confidence)rd   r   r   r	   r
   r   r   r   r   tesseract_log_outputrM   rN   rJ   r   rp   intgetfloat)
input_filerb   rv   r   args_tesseractprW   
all_outputrr   rx   orient_confs              r   get_orientationr      s#    $UG[9z	= N-/0
, "!((
+C0!45E'cgg.F&J KK '  >$1== 
-QXX&QXX&hho#!((/c:
5C!Z/(A..#%1,
-s*   "B D-1D-9AD(D-D((D-c                    d| j                   v ry| j                  dk(  xr, | j                   dk(  xs | j                   j                  d      S )N   Empty page!!Tr!   r   s2   Error in boxClipToRectangle: box outside rectangle)rJ   
returncoderS   )excs    r   _is_empty_page_errorr      sL    #**$>>Q 

c 	X::  !VW	r   c           
        t        ||      ddt        |       dgz   }	 t        |t        t        |dt        |            }t        |j                        }t        |j                  dd	            }	d
t         z  |	z  }
t"        j%                  d|
d       |
S # t        $ r Y yt        $ rJ}t        |j                         t        |j                         t        |      rY d}~yt               |d}~ww xY w)z+Gets angle to deskew this page, in degrees.rs   2rM   Tru   rw   NzDeskew angler      zDeskew angle: z.3f)rd   r   r   r	   r
   r   r   r   r{   rM   rN   r   r   rp   r~   r}   r   logdebug)r   	languagesrb   rv   r   r   r   rW   parseddeskew_radiansdeskew_degreess              r   
get_deskewr      s     $I{;z	? N-/0
$ %QXX.F6::na89N2X.NII~c234   -QXX&QXX&"#%1,-s#   "B 	C4"C4*5C/$C//C4c                   t        t        t        t        d      rt        j                  nd       }| sy 	 | j	                         }|j                         }|D ]  }|j                  d      rd|v r1|j                  d       |j                  |j                                K|j                  d      r|j                  d	       nd
|v rsd|v rxd|j                         v r>|j                  |j                                |j                  d      d   }t        |      d|j                         v sd|j                         v r!|j                  |j                                d|j                         v r!|j                  |j                                @d|j                         v rf|j                  |j                                d|v r$|j                  dd      d   j                         }n|j                         }t        d| d      |j                  |j                                 y # t
        $ r | j	                  dd      }Y w xY w)Nr3   r4   utf-8ignore)zTesseract Open SourcezWarning in pixReadMem
diacriticsz&lots of diacritics - possibly poor OCRzOSD: Weak marginzunsure about page orientationzError in pixScanForForegroundzError in boxClipToRectanglezparameter not found: zfound: r!   error	exceptionwarningread_params_filez
Can't openz'Tesseract cannot open its config file 'a  '. This usually means Tesseract is installed but its config files are missing from the tessdata configs/ directory. On Debian/Ubuntu, ensure the 'tesseract-ocr' package is fully installed. If you set TESSDATA_PREFIX, verify its configs/ subdirectory contains the required files.)r1   r   hasattrr3   ri   UnicodeDecodeErrorrR   rS   r   r   rT   lowerr   rj   r   info)streamtlogrL   linesrX   problemmissings          r   r{   r{     s   !"30ciidD
 0}} OOE +$??MNT!LLAB JJtzz|$__/0LL89,4*d2$

4JJtzz|$jj+A.G&w//

$tzz|(CJJtzz|$$**,&LL&4::</JJtzz|$ t#**\15a8>>@**,&9' CE E  IIdjjl#W+$	  0}}Wh/0s   H3 3IIc                :    | dk(  ry t         j                  d       y )Nr   z+[tesseract] took too long to OCR - skipping)r   r   )rv   s    r   page_timedoutr   U  s    !|KK=>r   c                P    | j                  dd       |j                  dd       y)zXProduce an empty .hocr file.

    Ensures page is the same size as the input image.
     r   encoding[skipped page]N)
write_text)output_hocroutput_textimages      r   _generate_null_hocrr   [  s+    
 20+g>r   )r   c           
        |j                  d      }t        ||      }||j                  dt        |      g       |t        j
                  k7  r t               r|j                  dd| g       |	r|j                  d|	g       |
r|j                  d|
g       |j                  t        |       t        |      dd	g       |j                  |       	 t        |t        t        |d
t        |            }|j                  }t        |       |j                         s,t        d| d|r|j!                  d      z         dz         t#        t$              5  |j                  d      j'                  |       ddd       y# 1 sw Y   yxY w# t(        $ r t+        |       t-        |||        Y yt.        $ rS}t        |j0                         d|j0                  v sd|j0                  v rt-        |||        Y d}~yt               |d}~ww xY w)z5Generate a hOCR file, which must be converted to PDF.r   Nrs   -cthresholding_method=--user-words--user-patternshocrtxtTru   zNTesseract exited successfully but did not produce the expected hOCR output at . Tesseract output:
replaceerrors(empty).txtrz   r   )with_suffixrd   r_   r   r    r'   rG   r   r   r	   r
   r   rM   r{   existsr   ri   r   FileNotFoundErrorr   r   r   r   r   rJ   )r   r   r   r   rb   
tessconfigrv   pagesegmodethresholding
user_wordsuser_patternsr   prefixr   r   rM   rW   s                    r   generate_hocrr   d  s     $$R(F#I{;NwK(89:)...3C3Et';L>%JKL~z:;0-@A 6*-vf~vuMN*%"</0
  	V$!!#'++6-7LN6<6==	=2M  CLM  '( 	<v&..{;	< 	< 	</  B 	gKjA -QXX&)_-H[*E#%1,-s0   .F !F  F	!H
/H
7>H:HH
c                L    |j                  dd       | j                  d       y )Nr   r   r   r   )r   write_bytes)
output_pdfr   s     r   use_skip_pager     s&    +g> 3r   c           
     `   t        ||      }||j                  dt        |      g       |j                  ddg       |t        j                  k7  r t               r|j                  dd| g       |	r|j                  d|	g       |
r|j                  d|
g       |j                  t        |j                        z  }|j                  t        |       t        |      dd	g       |j                  |       	 t        |t        t        |d
t        |            }|j                  }t        t               5  |j#                  d      j%                  |       ddd       |j'                         s,t)        d| d|r|j+                  d      z         dz         	 t-        |       y# 1 sw Y   RxY w# t.        $ r t1        |       t3        ||       Y yt4        $ rR}t-        |j6                         d|j6                  v sd|j6                  v rt3        ||       Y d}~yt)               |d}~ww xY w)zGenerate a PDF using Tesseract's internal PDF generator.

    We specifically a text-only PDF which is more suitable for combining with
    the input page.
    Nrs   r   ztextonly_pdf=1r   r   r   pdfr   Tru   r   zMTesseract exited successfully but did not produce the expected PDF output at r   r   r   r   rz   r   )rd   r_   r   r    r'   rG   parentr   stemr   r   r	   r
   r   rM   r   r   r   r   r   r   ri   r{   r   r   r   r   rJ   )r   r   r   r   rb   r   rv   r   r   r   r   r   r   r   r   rM   rW   s                    r   generate_pdfr     s   ( $I{;NwK(89:4!123)...3C3Et';L>%JKL~z:;0-@Ajoo!66F
 6*-vf~ueLM*%%/0
 '( 	<v&..{;	<  "'**45JL6<6==	=2M  CLM  #  	V$%	< 	<  /gj+. -QXX&)_-H*k2#%1,-s=   6=F1 3!F%AF1 %F.*F1 1 H-H-=H(H((H-)r   
int | Nonereturnzdict[str, str] | None)r   bool)r   zset[str])ra   	list[str]rb   r   r   r   )rm   bytesr   zdict[str, str])N)
r   r   rb   r   rv   r~   r   r   r   r   )r   r   r   r   rb   r   rv   r~   r   r   r   r~   )r   r   r   None)rv   r~   r   r   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   rb   r|   r   r   rv   r~   r   r|   r   r    r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   r   r   rb   r|   r   r   rv   r~   r   r|   r   r    r   r   r   r   )?r&   
__future__r   loggingr   r;   
contextlibr   enumr   mathr   r   pathlibr   
subprocessr	   r
   r   r   packaging.versionr   ocrmypdf._exec._prober   ocrmypdf.exceptionsr   r   r   ocrmypdf.pluginspecr   ocrmypdf.subprocessr   	getLoggerr#   r   r   r    r'   r(   r)   r*   r/   __annotations__LoggerAdapterr1   r=   r:   PROBErF   	availablerG   r\   rd   rp   r   r   r   r{   r   r   r   r   r   r+   r   r   <module>r      s   ) "  	 	      G G % + 
 6 #g!  ####'55!))	2  ,W22 ,) Xw  	$ 	
 --OO	'
+> $(	))) ) !	)
 )X	" $(&&& & 	&
 !& &R9$x??, $(F<F< F< 	F<
 F< F< F< F< F< %F< !F< 
F<R ( $(G%G% G% 	G%
 G% G% G% G% G% %G% !G% 
G%r   