
    j5jJ                       d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
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 d d	lmZmZmZ erd d
lmZ d dlZd dlZd dlmZ d dl m!Z! d dl"m#Z#m$Z$ d dl%m&Z&m'Z' d dl(m)Z) d dl*m+Z+ d dl,m-Z- d dl.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@ d dlAmBZB d dlCmDZD d dlEmFZFmGZG d dlHmIZImJZJmKZKmLZLmMZM d dlNmOZO d dlPmQZQ  ej                  eS      ZT ej                         ZVdeV_W        d ZX eXeV       d0dZY G d de      ZZ G d dej                        Z\ G d d ej                        Z^e G d! d"             Z_	 d1	 	 	 	 	 d2d#Z`d3d$Zae	 	 	 	 d4d%       Zbd5d&Zced6d'       Zd	 	 	 	 	 	 	 	 d7d(Ze	 	 	 	 	 	 d8d)Zfd9d*Zg	 	 	 	 	 	 	 	 	 	 	 	 d:d+Zh	 	 	 	 	 	 d;d,Zid<d-Zj	 	 	 	 	 	 	 	 d=d.Zkd>d/Zly)?    )annotationsN)CallableSequence)BrokenProcessPool)BrokenThreadPool)contextmanager)	dataclassPath)TYPE_CHECKING
NamedTuplecast)
OcrElement)Pdf)remove_broken_goto_annotations)Executorsetup_executor)PageContext
PdfContext)PageNumberFilter)metadata_fixup)
OcrOptions)convert_to_pdfacreate_ocr_imagecreate_pdf_page_from_imagecreate_visible_page_jpggenerate_postscript_stubget_orientation_correctionget_pdf_save_settingsget_pdfinfooptimize_pdfpreprocess_cleanpreprocess_deskewpreprocess_remove_background	rasterizerasterize_previewshould_linearize!should_visible_page_image_use_jpgtry_auto_pdfatry_speculative_pdfa)OcrmypdfPluginManager)report_output_file_size)ExitCodeExitCodeException)	check_pdfpikepdf_enable_mmaprunning_in_dockerrunning_in_snapsamefile)file_claims_pdfa)PdfInfoc                f     t        j                          fd}t        j                  |       y)z=Inject current page number (when available) into log records.c                 R     | i |}t        d      rj                  |_        |S )Npageno)hasattrr8   )argskwargsrecordold_factorytlss      Q/var/www/html/qr/venv/lib/python3.12/site-packages/ocrmypdf/_pipelines/_common.pywrapperz!_set_logging_tls.<locals>.wrapperN   s,    d-f-3!JJFM    N)logginggetLogRecordFactorysetLogRecordFactory)r>   r@   r=   s   ` @r?   _set_logging_tlsrE   J   s&    --/K (rA   c                    | t         _        y)z@Set page number (1-based) that the current thread is processing.N)r>   r8   )r8   s    r?   set_thread_pagenorG   Z   s	    CJrA   c                  l    e Zd ZU dZded<   	 dZded<   	 dZded<   	 dZded<   	 d	Zded
<   	 dZ	ded<   y)
PageResultz*Result when a page is finished processing.intr8   NPath | Nonepdf_page_from_imageocrtextr   orientation_correctionOcrElement | Noneocr_tree)
__name__
__module____qualname____doc____annotations__rL   rM   rN   rO   rQ    rA   r?   rI   rI   _   sQ    4K'++%CD+ "#C#,"&H&ArA   rI   c                       e Zd Z fdZ xZS )HOCRResultEncoderc                \    t        |t              rdt        |      iS t        |   |      S Nr   )
isinstancer   strsuperdefault)selfobj	__class__s     r?   r_   zHOCRResultEncoder.defaultv   s+    c4 CH%%ws##rA   )rR   rS   rT   r_   __classcell__rb   s   @r?   rY   rY   u   s    $ $rA   rY   c                  $     e Zd Z fdZd Z xZS )HOCRResultDecoderc                B    | j                   |d<   t        |   |i | y )Nobject_hook)dict_to_objectr^   __init__)r`   r:   r;   rb   s      r?   rj   zHOCRResultDecoder.__init__}   s%     $ 3 3}$)&)rA   c                *    d|v rt        |d         S |S r[   r
   )r`   ds     r?   ri   z HOCRResultDecoder.dict_to_object   s    Q;&	?"rA   )rR   rS   rT   rj   ri   rc   rd   s   @r?   rf   rf   |   s    *rA   rf   c                      e Zd ZU dZded<   	 dZded<   	 dZded<   	 dZded<   	 d	Zded
<   	 dZ	ded<   	 e
dd       ZddZy)
HOCRResultz(Result when hOCR is finished processing.rJ   r8   NrK   rL   hocrtextpdfr   rO   rP   rQ   c                D     | di t        j                  |t              S )zCreate an instance from a dict.clsrW   )jsonloadsrf   )rs   json_strs     r?   	from_jsonzHOCRResult.from_json   s     ATZZ.?@AArA   c                L    t        j                  | j                  t              S )zSerialize to a JSON string.rr   )rt   dumps__dict__rY   )r`   s    r?   to_jsonzHOCRResult.to_json   s    zz$--->??rA   )rv   r]   returnrn   )r|   r]   )rR   rS   rT   rU   rV   rL   ro   rp   rO   rQ   classmethodrw   r{   rW   rA   r?   rn   rn      sk    2K'++%D+ G[,"#C#,"&H&AB B@rA   rn   c                L   t        j                  | d      j                  t         j                         t        j                  d      }j                  |       j                  t                      t        j                        j                         fd}|fS )a  Create a debug log file at a specified location.

    Returns the log handler, and a function to remove the handler.

    Args:
        log_filename: Where to the put the log file.
        prefix: The logging domain prefix that should be sent to the log.
    T)delayzA[%(asctime)s] - %(name)s - %(levelname)7s -%(pageno)s %(message)sc                     	 t        j                        j                         j                          y # t        $ r%} t        | t        j                         Y d } ~ y d } ~ ww xY w)Nfile)rB   	getLoggerremoveHandlercloseOSErrorprintsysstderr)elog_file_handlerprefixs    r?   removerz(configure_debug_logging.<locals>.remover   sO    	&f%334DE""$ 	&!#**%%	&s   48 	A&A!!A&)
rB   FileHandlersetLevelDEBUG	FormattersetFormatter	addFilterr   r   
addHandler)log_filenamer   	formatterr   r   s    `  @r?   configure_debug_loggingr      s     **<tDgmm,!!KI !!),/12f(()9:& W$$rA   c                B    | t         j                  _        t                y)z&Initialize a worker thread or process.N)PILImageMAX_IMAGE_PIXELSr0   )
max_pixelss    r?   worker_initr      s    
 ",CIIrA   c              #     K   d }| j                   s| j                  dk\  r3t        j                  j	                  dd      st        |dz  d      \  }}	 d  |r |        y y # |r |        w w xY ww)N   PYTEST_CURRENT_TEST z	debug.log)r   )keep_temporary_filesverboseosenvirongetr   )optionswork_folderr   _debug_log_handlers       r?   manage_debug_log_handlerr      st      G$$1(<bjjnnrG '>+%b'
#GI 7I s   AA2A# A2#A//A2c                    d|  g}t               r|j                  d       nt               r|j                  d       t        dj	                  |      t
        j                         y)z0Print the location of the temporary work folder.z%Temporary working files retained at:
zUOCRmyPDF is running in a Docker container, so the files will be inside the container.zSOCRmyPDF is running in a Snap container, so the files will be inside the container.
r   N)r1   appendr2   r   joinr   r   )r   msgss     r?   _print_temp_folder_locationr      sY    4[MBCD9	
 
	9	
 
$))D/

+rA   c              #     K   	 |  |r|r$t        |        y t        j                  | d       y y # |r|rt        |        w w t        j                  | d       w xY ww)NT)ignore_errors)r   shutilrmtree)r   retainprint_locations      r?   manage_work_folderr      sX     ;+K8MM+T:  +K8  MM+T:s   A1 )A*AAc                   	  | ||      S # t         $ rM |j                  dk\  rt        j                  d       nt        j	                  d       t
        j                  cY S t        $ r}t        t        |      }|j                  dk\  rt        j                  d       ngt        |      r4t        j	                  dt        |      j                  t        |             n(t        j	                  t        |      j                         |j                  cY d}~S d}~wt        $ r}dt        |      j                         v sdt        |      j                         v rY|j                  dk\  rt        j                  d       nt        j	                  d	t        |             t
        j                  cY d}~S  d}~wt         j"                  j$                  $ r( t        j                  d
       t
        j&                  cY S t(        t*        f$ r( t        j                  d       t
        j,                  cY S t.        $ r( t        j                  d       t
        j&                  cY S w xY w)aY  Convert exceptions into command line error messages and exit codes.

    When known exceptions are raised, the exception message is printed to stderr
    and the program exits with a non-zero exit code. When unknown exceptions are
    raised, the exception traceback is printed to stderr and the program exits
    with a non-zero exit code.
    r   KeyboardInterruptr.   z%s: %sNzvalidation errorzvalue errorzValidation errorzInvalid argument: %szA decompression bomb error was encountered while executing the pipeline. Use the argument --max-image-mpixels to raise the maximum image pixel limit.zA worker process was terminated unexpectedly. This is known to occur if processing your file takes all available swap space and RAM. It may help to try again with a smaller number of jobs, using the --jobs argument.z2An exception occurred while executing the pipeline)r   r   log	exceptionerrorr-   ctrl_cr.   r   r]   typerR   	exit_code
ValueErrorlowerbad_argsr   r   DecompressionBombErrorother_errorr   r   child_process_error	Exception)fnr   plugin_managerr   s       r?   cli_exception_handlerr     s   2$ '>** ??aMM-.II)* "A&??aMM-.VIIhQ 0 0#a&9IId1g&&'{{ 	Q/=CFLLN3R!#01		0#a&9$$$99++ $!	

 ### 
, 		
 +++ $JK###$sO    AI I(B'DII!B	F1*I0F11AI83I--IIc                   | j                   ]t        | j                   dz        t        j                  _        t        j                  j                  dk(  rd t        j                  _        t                t        |      }|S )Ni@B r   )max_image_mpixelsrJ   r   r   r   r0   r   )r   r   executors      r?   setup_pipeliner   B  s_       ,%()B)BY)N%O		"99%%*)-CII&n-HOrA   c           	     Z   |j                   }t        |t              rJddlm} t        j                  |       5 }t        |j                         }d d d         ||      }||_         t        | ||j                  |j                  |j                  |j                  |      S # 1 sw Y   TxY w)Nr   )_pages_from_ranges)total_pages)r   detailed_analysisprogbarmax_workersuse_threadscheck_pages)pagesr\   r]   ocrmypdf._optionsr   r   openlenr    redo_ocrprogress_barjobsr   )pdf_pathr   r   r   r   pdfr   s          r?   do_get_pdfinfor   Y  s     --K+s#8XXh 	)3cii.K	)(+N#!**$$LL'' 	) 	)s   B!!B*c                Z    |rt        ||       }|rt        ||       }|rt        ||       }|S )zPreprocess an image.)r$   r#   r"   )page_contextimageremove_backgrounddeskewcleans        r?   
preprocessr   q  s6     ,ULA!%6 5LrA   c                v   | j                   }dx}}t        | j                  | |d      }t        |j                  |j
                  |j                  g      s*t        | ||j                  |j                  d      x}}||fS |j                  s.t        | ||j                  |j                  |j
                        }|j                  rt        | j                  | |dd      }n|}|r$||k(  r|j                  |j
                  k(  r|}||fS t        | ||j                  |j                  |j                        }||fS )z4Create intermediate and preprocessed images for OCR.NF)
correctionremove_vectors)r   T_ocr)r   r   
output_tag)r   r%   originanyr   clean_finalr   r   r   r   lossless_reconstruction)r   rO   r   	ocr_imagepreprocess_outrasterize_outrasterize_ocr_outs          r?   make_intermediate_imagesr     s_    ""G!%%I)	M w22G4J4JKL%/%%NN&
 	
	NT n$$E ..'))))N !! )##1#!! !. !]2!4!44 'I n$$ #!))mmI n$$rA   c                   | j                   }d}|j                  r"t        | j                  |       }t	        ||       }t        | |      \  }}t        ||       }d}|j                  sU|sJ |}t        | j                        rt        ||       }| j                  j                  | |      }	|	|	}t        || |      }|||fS )zEProcess page to create OCR image, visible page image and orientation.r   N)pageimage_filename)r   rotate_pagesr&   r   r   r   r   r   r(   pageinfor   r   filter_page_imager   )
r   r   rO   rasterize_preview_outr   r   ocr_image_outpdf_page_from_image_outvisible_image_outfiltered_images
             r?   process_pager     s    ""G 1,2E2E| T!;!<"
 !9,!I~ %Y=M"**~*,\-B-BC 78I< X%44FF.? G 
 % ."<|-C#
 13IIIrA   c                   t        j                  |       5 }|j                  d      }t        |      r|j	                  |       |}n| }ddd       |j
                  j                  dk(  r)t        |      \  }}||j
                  j                  d<   nN|j
                  j                  j                  d      r)t        |      }||}nt        |      }t        |||      }|j                  j                  |      }	t        |j
                  j                        }
|	 xr t!        |      |
d<   t#        ||
      }t%        |||      S # 1 sw Y   xY w)	zPostprocess the PDF file.zfix_annots.pdfNauto_actual_output_typepdfa)context	linearize)pdf_save_settings)r   r   get_pathr   saver   output_typer)   extra_attrs
startswithr*   r   r   r   is_optimization_enabledr   r'   r   r!   )pdf_filer  r   r   
fix_annotspdf_outactual_typespeculative_resultps_stub_out
optimizingsave_settingss              r?   postprocessr    s=   
 
(	 s%%&67
)#.HHZ  GG ""f,,Wg>=H##$9:		$	$	/	/	71'7C)(G 37;K%g{GDG''???PJ)'//*E*EFM%/!V4DWg4VM+WgOG(337 s   3EEc                v   | j                   dk(  r%t        j                  d       t        j(                  S t        | j                   d      r?| j                   j	                         r%t        j                  d       t        j(                  S t        | j                   t        t        j                              r	 t        j(                  S | j                  dk(  r| j                  j                  dd      }t        | j                         }|dk(  r|d	   rt        j                  d
|d          n|d	   rt        j                  d|d          nt        j                  d       nx| j                  j                  d      r]t        | j                         }|d	   rt        j                  d|d          n)t        j                  d|d          t        j                   S t#        | j                         s%t        j                  d       t        j$                  S t'        | || j                   |       t        j(                  S )N-zOutput sent to stdoutwritablezOutput written to streamr  r  r   r  passz.Output file is a %s (auto mode achieved PDF/A)conformancezOutput file is a %sz Output file is a PDF (auto mode)z!Output file is a %s (as expected)zOOutput file is a valid PDF, but conversion to PDF/A did not succeed (issue: %s)z)Output file: The generated PDF is INVALID)output_filer   infor9   r  r3   r   r   devnullr
  r  r   r4   r  warningr-   pdfa_conversion_failedr/   invalid_output_pdfr,   ok)r   start_input_fileoptimize_messagesr  	pdfa_infos        r?   report_output_pdfr&    s   c!()L ;;K 
$$j	1g6I6I6R6R6T+,H ;;G 
'%%tBJJ'7	8D ;;A &(!--112GOK()<)<=If$6):Dm, 6".	-0HI ;<  ++F3()<)<=I <i>VW*m,
  666,,-KKCD...%w':':<M	
 ;;rA   )r8   
int | None)r   )r   r   r   r]   r|   z.tuple[logging.FileHandler, Callable[[], None]])r   r'  r|   None)r   r   r   r   )r   r   )r   r   r   boolr   r)  )r   z7Callable[[OcrOptions, OcrmypdfPluginManager], ExitCode]r   r   r   r+   r|   r-   )r   r   r   r+   r|   r   )r   r   r   r   r|   r5   )r   r   r   r   r   r)  r   r)  r   r)  r|   r   )r   r   rO   rJ   r|   ztuple[Path, Path | None])r   r   r|   ztuple[Path, Path | None, int])r  r   r  r   r   r   r|   ztuple[Path, Sequence[str]])r|   r-   )m
__future__r   rt   rB   logging.handlersr   r   r   	threadingcollections.abcr   r   concurrent.futures.processr   concurrent.futures.threadr   
contextlibr   dataclassesr	   pathlibr   typingr   r   r   ocrmypdf.hocrtransformr   r   	PIL.Imagepikepdfr   ocrmypdf._annotsr   ocrmypdf._concurrentr   r   ocrmypdf._jobcontextr   r   ocrmypdf._loggingr   ocrmypdf._metadatar   r   r   ocrmypdf._pipeliner   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   ocrmypdf._plugin_managerr+   ocrmypdf._validationr,   ocrmypdf.exceptionsr-   r.   ocrmypdf.helpersr/   r0   r1   r2   r3   ocrmypdf.pdfar4   ocrmypdf.pdfinfor5   r   rR   r   localr>   r8   rE   rG   rI   JSONEncoderrY   JSONDecoderrf   rn   r   r   r   r   r   r   r   r   r   r   r   r  r&  rW   rA   r?   <module>rF     s]   #    	  
  . 8 6 % !  2 21 
   ; 9 8 . - (    ( ; <  + $g!ioo

)  
B B,$(( $((  @ @ @@ ')%% #%3%<   ,,  ; ;>$?>$>$ *>$ 	>$B) .0  	
  
"9%9%7:9%9%xJB 4 4' 43; 4 4F(rA   