HEX
Server: Apache
System: Linux srv1.prosuiteplus.com 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: prosuiteplus (1001)
PHP: 8.3.20
Disabled: NONE
Upload Files
File: //lib/python3/dist-packages/ocrmypdf/__pycache__/leptonica.cpython-38.pyc
U

��Z^dv�
@s�ddlZddlZddlZddlZddlZddlmZddlmZddl	m
Z
ddlmZddl
mZddlmZddlmZd	d
lmZd	dlmZd	dlmZe�e�Zejd
kr�dZe�ejd<ndZe
e�Zes�ed��ze�e�Z e �!e j"�Wn8ej#k
�r0Z$zede�d��e$�W5dZ$[$XYnXGdd�d�Z%Gdd�de&�Z'Gdd�de'�Z(Gdd�d�Z)Gdd�de)�Z*Gdd�de)�Z+Gd d!�d!e)e�Z,Gd"d#�d#e)�Z-Gd$d%�d%e)e�Z.Gd&d'�d'e)e�Z/Gd(d)�d)e)�Z0ed	d*�d+d,��Z1d-d.�Z2dHd3d4�Z3ed5k�r�ej4d6d7�Z5e5j6d8d9d:�Z7e7�8d.�Z9e9j:d;d<d=d>e;d?d@dA�e9j:dBdCdD�e9j:dEdFdD�e9j<e2dG�e5�=�Z>e>�?e>�dS)I�N)�Sequence)�suppress)�find_library)�	lru_cache)�BytesIO)�fspath)�
TemporaryFile�)�MissingDependencyError)�shim_paths_with_program_files)�ffi�ntz	liblept-5�PATH�lepta�
        ---------------------------------------------------------------------
        This error normally occurs when ocrmypdf can't find the Leptonica
        library, which is usually installed with Tesseract OCR. It could be that
        Tesseract is not installed properly, we can't find the installation
        on your system PATH environment variable.

        The library we are looking for is usually called:
            liblept-5.dll   (Windows)
            liblept*.dylib  (macOS)
            liblept*.so     (Linux/BSD)

        Please review our installation procedures to find a solution:
            https://ocrmypdf.readthedocs.io/en/latest/installation.html
        ---------------------------------------------------------------------
        zLeptonica library found at z, but we could not access itc@s(eZdZdZdd�Zdd�Zdd�ZdS)	�_LeptonicaErrorTrapa+
    Context manager to trap errors reported by Leptonica.

    Leptonica's error return codes don't provide much informatino about what
    went wrong. Leptonica does, however, write more detailed errors to stderr
    (provided this is not disabled at compile time). The Leptonica source
    code is very consistent in its use of macros to generate errors.

    This context manager redirects stderr to a temporary file which is then
    read and parsed for error messages.  As a side benefit, debug messages
    from Leptonica are also suppressed.

    cCsd|_d|_d|_dS)N���F)�tmpfile�copy_of_stderr�	no_stderr��self�r�4/usr/lib/python3/dist-packages/ocrmypdf/leptonica.py�__init__]sz_LeptonicaErrorTrap.__init__c	Cs�ddlm}t�|_tt��tj��W5QRXz2t	�
tj���|_t	j
|j��tj��dd�WnNtk
r�d|_d|_t	j
|j��ddd�Yn|k
r�d|_YnXdS)Nr)�UnsupportedOperationF)ZinheritableT�)�iorrrr�AttributeError�sys�stderr�flush�os�dup�filenor�dup2r)rrrrr�	__enter__bs
 z_LeptonicaErrorTrap.__enter__c	Cs�tt��tj��W5QRX|jdk	rHt�|jtj���t�	|j�|j
rXt�	d�|j�d�|j�
�jdd�}|j�	�|r�t�|�d|kr�d|kr�t��d|kr�t��d|kr�t��t|��d	S)
Nrr�replace)�errors�Errorzimage file not foundzpixWrite: stream not openedzindex not validF)rrrrr rr!r$r#�closerr�seek�read�decode�loggerZwarning�FileNotFoundError�LeptonicaIOError�
IndexError�LeptonicaError)r�exc_type�	exc_value�	tracebackZleptonica_outputrrr�__exit__xs*




z_LeptonicaErrorTrap.__exit__N)�__name__�
__module__�__qualname__�__doc__rr%r5rrrrrNsrc@seZdZdS)r1N�r6r7r8rrrrr1�sr1c@seZdZdS)r/Nr:rrrrr/�sr/c@s0eZdZdZdd�ZdZdd�Zedd��Zd	S)
�LeptonicaObjecta�General wrapper for Leptonica objects

    When Leptonica returns an object, we bundled it in a wrapper class, which
    manages its memory. The wrapper class assumes that it will be calling some
    sort of lept.thingDestroy() function when the instance is deleted. Most
    Leptonica objects are reference counted, and destroy decrements the
    refcount.

    Most of the time, when Leptonica returns something, we wrap and it the job
    is done. When wrapping objects that came from a Leptonica container, like
    a PIXA returning PIX, the subclass must clone the object before passing it
    here, to maintain the reference count.

    CFFI ensures that the destroy function is called at garbage collection time
    so we do not need to mess with __del__.
    cCsdS�Nr)�cdatarrr�<lambda>��zLeptonicaObject.<lambda>�cCs&|std|j��t�||j�|_dS)NzTried to wrap a NULL )�
ValueError�LEPTONICA_TYPENAMEr�gc�_destroy�_cdata)rr=rrrr�szLeptonicaObject.__init__cCs"t�d�|j�|�}|�|�dS)zDestroy some cdataz{} **N)r�new�formatrB�
cdata_destroy)�clsr=ZpprrrrD�szLeptonicaObject._destroyN)	r6r7r8r9rHrBr�classmethodrDrrrrr;�sr;c@s�eZdZdZdZejZdd�Zdd�Z	dd�Z
d	d
�Zdd�Ze
d
d��Ze
dd��Ze
dd��Ze
dd��Ze
dd��Ze
dd��Zedd��Zedd��Zdadd�Zed d!��Zd"d#�Zd$d%�Zdbd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Z d2d3�Z!dcd7d8�Z"ddd?d@�Z#dedAdB�Z$dCdDdEddde%j&fdFdG�Z'dfdIdJ�Z(dgdKdL�Z)dhdQdR�Z*e+e,dSdT�dUdV���Z-e+dWdX��Z.dYdZ�Z/d[d\�Z0d]d^�Z1d_d`�Z2d9S)i�Pixa�
    Wrapper around leptonica's PIX object.

    Leptonica uses referencing counting on PIX objects. Also, many Leptonica
    functions return the original object with an increased reference count
    if the operation had no effect (for example, image skew was found to be 0).
    This has complications for memory management in Python. Whenever Leptonica
    returns a PIX object (new or old), we wrap it in this class, which
    registers it with the FFI garbage collector. pixDestroy() decrements the
    reference count and only destroys when the last reference is removed.

    Leptonica's reference counting is not threadsafe. This class can be used
    in a threadsafe manner if a Python threading.Lock protects the data.

    This class treats Pix objects as immutable.  All methods return new
    modified objects.  This allows convenient chaining:

    >>>   Pix.open('filename.jpg').scale((0.5, 0.5)).deskew().show()
    ZPIXc
CsJ|jrBd}|�|jj|jj|jjtt�d|j��|jjr<dnd�SdSdS)Nz:<leptonica.Pix image size={0}x{1} depth={2}{4} at 0x{3:x}>Zintptr_tz
(colormapped)r@z<leptonica.Pix image NULL>)	rErG�w�h�d�intr�cast�colormap)r�srrr�__repr__�s�zPix.__repr__cCs^t�d�}t�d�}t�|||jd�}|dkr6td��t�d|d�}t�||d�dd�S)zCiPython display hook

        returns png version of image
        z
l_uint8 **�size_t *r�pixWriteMemPng�char *N)rrFrrUrEr/rP�buffer)r�data�size�err�	char_datarrr�
_repr_png_�s

zPix._repr_png_cCspt�d�}t�d�}t�|j||�}|dkr4td��t�d|d�}t�||d�dd�}t�|�t	|d�S)Nzl_uint32 **rTr�pixSerializeToMemoryrV)rX)
rrFrr]rEr/rPrW�	lept_free�dict)rrXrYrZr[Z
data_bytesrrr�__getstate__�s


zPix.__getstate__cCs@t�d|d�}t�d|�}t�|t|d��}t�||�dS)Nzchar[]rXz
l_uint32 *)rrFrPrZpixDeserializeFromMemory�lenrKr)r�stateZcdata_bytesZcdata_uint32�pixrrr�__setstate__
szPix.__setstate__c	CsTt|t�stSt�dd�}t��"t�|j|j|�}|r>t	��W5QRXt
|d�S)Nz	l_int32 *r)�
isinstancerK�NotImplementedrrFrrZpixEqualrE�	TypeError�bool)r�otherZsamerZrrr�__eq__s
z
Pix.__eq__cCs|jjSr<�rErLrrrr�widthsz	Pix.widthcCs|jjSr<�rErMrrrr�heightsz
Pix.heightcCs|jjSr<)rErNrrrr�depth#sz	Pix.depthcCs|jj|jjfSr<)rErLrMrrrrrY'szPix.sizecCsd|jj|jjfiS)N�dpi)rEZxresZyresrrrr�info+szPix.infocCs0|jdkrdS|jdkrdS|jjs(dSdSdS)zReturn mode like PIL.Imager	�1��RGB�L�PN)rorErQrrrr�mode/s

zPix.modecCst�dt�|�|�S)NzUse Pix.open() instead)�warnings�warn�DeprecationWarning�open)rI�pathrrrr+;szPix.readcCsft|d��R}|��}t�|�}t��.|t�|t|���W5QR�W5QR�SQRXW5QRXdS)z�Load an image file into a PIX object.

        Leptonica can load TIFF, PNM (PBM, PGM, PPM), PNG, and JPEG.  If
        loading fails then the object will wrap a C null pointer.
        �rbN)r{r+r�from_bufferrr�
pixReadMemra)rIr|�py_filerXrWrrrr{@s

zPix.openrc	
Cs�t�t�|��}t|d��|}t�d�}t�d�}t��8|tjkrXt�	|||j
||�nt�|||j
|�W5QRXt�|d|d�}|�
|�W5QRXdS)z�Write pix to the filename, with the extension indicating format.

        jpeg_quality -- quality (iff JPEG; 1 - 100, 0 for default)
        jpeg_progressive -- (iff JPEG; 0 for baseline seq., 1 for progressive)
        �wbzl_uint8 **pdataz
size_t *psizerN)rZgetImpliedFileFormatr!�fsencoder{rrFrZ
L_JPEG_ENCODEZpixWriteMemJpegrEZpixWriteMemrW�write)	rr|�jpeg_qualityZjpeg_progressiveZlept_formatr�rXrYrWrrr�write_implied_formatMs 


�zPix.write_implied_formatc
Cs^t�}|j|ddd�|��}t�|�}t��&tt�|t	|���}|W5QR�SQRXdS)z*Create a copy of a PIL.Image from this PixZpngr	)rGZcompress_levelN)
rZsave�	getbufferrr~rrKrrra)rZpillow_imageZbioZ	py_bufferZc_bufferrcrrr�frompilas
zPix.frompilc	Cs�ddlm}|}tjdkrr|jdkr*d}qx|jdkr:d}qx|jdkrZd	}tt�|j��}qx|j}tt�|j��}n|j}|jj	|jj
f}|jjd
|jj
}t�
|jj|�}|jjd
}|�|j||d||�}|S)z'Returns a PIL.Image version of this Pixr)�Image�littlertZXBGRZRGBAZABGRrrz1;I��raw)ZPILr�r�	byteorderrwrKrZpixEndianByteSwapNewrErLrMZwplrrWrXZ	frombytes)	rr�rcZraw_moderYZ	bytecount�bufZstrideZimrrr�topills&



z	Pix.topilcCs|����Sr<)r��showrrrrr��szPix.showc
Cs0t�� tt�|j|��W5QR�SQRXdS)aReturns the deskewed pix object.

        A clone of the original is returned when the algorithm cannot find a
        skew angle with sufficient confidence.

        reduction_factor -- amount to downsample (0 for default) when searching
            for skew angle
        N)rrKrZ	pixDeskewrE)r�reduction_factorrrr�deskew�s	z
Pix.deskewc
Cs:t��*tt�|j|d|d��W5QR�SQRXdS)zCReturns the pix object rescaled according to the proportions given.rr	N)rrKrZpixScalerE)rZscale_xyrrr�scale�sz	Pix.scalec
Cs2t��"tt�tj|j��W5QR�SQRXdSr<)rrKrZpixRotate180r�NULLrErrrr�	rotate180�sz
Pix.rotate180c
Cs0t�� tt�|j|��W5QR�SQRXdS)z@Orthographic rotation, quads: 0-3, number of clockwise rotationsN)rrKrZ
pixRotateOrthrE)rZquadsrrr�rotate_orth�szPix.rotate_orthc
Cspt��`t�dd�}t�dd�}t�|j||�}|dkrT|d|dfW5QR�SW5QR�dSW5QRXdS)z}Returns a tuple (deskew angle in degrees, confidence value).

        Returns (None, None) if no angle is available.
        �float *�r)NNN)rrrFrZpixFindSkewrE)rZangleZ
confidence�resultrrr�	find_skew�sz
Pix.find_skewc
CsDt��4t�|j�}|r,t|�W5QR�SW5QR�dSQRXdSr<)rrZpixConvertRGBToLuminancerErK)rZgray_pixrrr�convert_rgb_to_luminance�s
zPix.convert_rgb_to_luminancec
Cs4t��$tt�|j|tj��W5QR�SQRXdS)z�Remove a palette (colormap); if no colormap, returns a copy of this
        image

            removal_type - any of lept.REMOVE_CMAP_*

        N)rrKrZpixRemoveColormapGeneralrEZL_COPY)rZremoval_typerrr�remove_colormap�s�zPix.remove_colormap��,r��r�r�皙�����?cCs�t��||\}}|\}}t�d�}tt�|jd��}	t�|	j|||||tj|�}
|
dkrpt|d�W5QR�SW5QR�dSW5QRXdS)NzPIX **r)	rrrFrKr�
pixConvertTo8rEZpixOtsuAdaptiveThresholdr�)r�	tile_size�kernel_size�
scorefract�sx�sy�smoothx�smoothyZp_pixrcr�rrr�otsu_adaptive_threshold�s$
�zPix.otsu_adaptive_thresholdN��
��d�2��rrcCs�t��p|\}}	|\}
}tj}t|t�r.|j}tt�|jd��}t�|j|||	||||
||tj�}
t|
�W5QR�SQRXdS�Nr)	rrr�rerKrErr�ZpixOtsuThreshOnBackgroundNorm)r�maskr��thresh�mincountZbgvalr�r�r�r�r�r�rc�
thresh_pixrrr�!otsu_threshold_on_background_norm�s*

�
z%Pix.otsu_threshold_on_background_normc

Cs~t��n|\}}|\}	}
tj}t|t�r.|j}tt�|jd��}t�|j||||||	|
|tj�
}t|�W5QR�SQRXdSr�)	rrr�rerKrErr�ZpixMaskedThreshOnBackgroundNorm)
rr�r�r�r�r�r�r�r�r�r�rcr�rrr�#masked_threshold_on_background_norm�s(	
�z'Pix.masked_threshold_on_background_norm��F�c

Csht�dkrtd��t��Ftt�|j||||tj��}t�	|j|jtj�}	t
|	�W5QR�SQRXdS)Nzleptonica-1.76z*Not available in this version of Leptonica)�get_leptonica_versionr1r�BoxrZpixFindPageForegroundrErr�ZpixClipRectanglerK)
rZ	thresholdZmindistZ	erasedistZpagenumZ	showmorphZdisplayZpdfdirZcropboxZcropped_pixrrr�crop_to_foregrounds

��zPix.crop_to_foreground��?c
CsDt��4tt�|j|ptj|p"tj|||��W5QR�SQRXdSr<)rrKrZpixCleanBackgroundToWhiterErr�)rr��	grayscale�gammaZblackZwhiterrr�clean_background_to_white2s��zPix.clean_background_to_whitec
Cs8t��(tt�tj|j|||��W5QR�SQRXdSr<)rrKrZpixGammaTRCrr�rE)rr�ZminvalZmaxvalrrr�	gamma_trcAsz
Pix.gamma_trc�<�(���rr	c	Csh|�tj�}t��Ltt�|j|p&tj|p.tj|d|d||||d|d�
�W5QR�SQRXdS)Nrr	)	r�rZREMOVE_CMAP_BASED_ON_SRCrrKZpixBackgroundNormrErr�)	rr�r�r�Zfg_thresholdZ	min_countZbg_valZ
smooth_kernelZ
target_pixrrr�background_normEs ��zPix.background_normr	��maxsizecCst��Sr<)rZmakePixelSumTab8rrrr�make_pixel_sum_tab8aszPix.make_pixel_sum_tab8cCsHt�dkrtd��t�dd�}t�|j|j|�}|dkr@td��|dS)Nzleptonica-1.72zLeptonica version is too oldr�r�rzCorrelation failed)r�r1rrFrZpixCorrelationBinaryrE)Zpix1Zpix2Zcorrelationr�rrr�correlation_binaryfs
zPix.correlation_binarycCs:t�d�}t�|j||d|�}|dkr.td��t|d�S)z%Convert to PDF data, with transcoding�L_COMP_DATA **rzGenerate PDF data failed)rrFrZpixGenerateCIDatarEr1�CompressedData)r�type_Zquality�
p_compdatar�rrr�generate_pdf_ci_dataus

zPix.generate_pdf_ci_datacCstt�tj|j��Sr<)rKrZ	pixInvertrr�rErrrr�invert}sz
Pix.invertccs6z�zpt��`tt�|jd��}t	t�
|jd��}|sHW5QR�WW�TdStt�|jtj
tjtjd��}W5QRXWn tttfk
r�YW�
dSXW5d}|D]"}tt��t�|�W5QRXq�Xt|�D]b\}}|��}|��dkr�q�|�|�}	|	j|	j}
}|	j|	j|	j|	j}}
||
|||
ffVq�dS)N)zjunkpixt.pngZjunkpixtrr@)rr.r!�unlinkrrKrr�rE�PixArrayZpixExtractBarcodes�StringArrayZpixReadBarcodesZL_BF_ANYZL_USE_WIDTHSrr�r1rAr0�	enumerater,�strip�get_box�x�yrLrM)rZleptonica_junkZjunkrcZpixa_candidatesZsarray�nrRZdecoded�box�left�top�rightZbottomrrr�locate_barcodes�s:��	

zPix.locate_barcodesc	Cs�|dkr.d}t�|d�}t�ddddtj�}n6|dkr\d}t�|d�}t�ddddtj�}nt|��tt�tj	|j
|j
��}tt�tj	|j
|j
��}tt�tj	|j
|j
��}|S)Nrze
                oooo
                oC o
                o  o
                oooo
                �speckle2r�z
                ooooo
                oC  o
                o   o
                o   o
                ooooo
                �speckle3)
�Sel�from_selstr�create_brickrZSEL_HITrArKZpixHMTrr�rEZ	pixDilateZpixSubtract)	rrYr�Zsel1Zsel2r�ZpixhmtZ
pixdilatedZpixsubrrr�	despeckle�sz
Pix.despeckle)rr)r)r�r�r�)Nr�r�r�r�r�r�)Nr�r�r�r�r�)NNr�rr�)r�rr�)NNr�r�r�r�r�)3r6r7r8r9rBrZ
pixDestroyrHrSr\r`rdrj�propertyrlrnrorYrqrwrJr+r{r�r�r�r�r�r�r�r�r�r�r�r�r�r�rr�r�r�r�r��staticmethodrr�r�r�r�r�r�rrrrrK�s�














�
�
#�
!�
�

�

!rKc@sHeZdZdZdZejZeddd��Z	dd�Z
dd	�Zd
d�Zdd
�Z
dS)r�z8Wrapper for L_COMP_DATA - abstract compressed image dataZL_COMP_DATA�KcCsFt|�}t�d�}t�t�|�tj||�}|dkr:td��t	|d�S)z)Open compressed data, without transcodingr�r�CompressedData.open)
rrrFrZl_generateCIDataForPdfr!r�r�r1r�)rIr|r��filenamer�r�rrrr{�s
�r�cCs|jjSr<)rE�
nbytescomprrrr�__len__�szCompressedData.__len__cCst�|jj|jj�}t|�Sr<)rrWrEZdatacompr��bytes)rr�rrrr+�szCompressedData.readcCs$t|j|�rt|j|�St|��dSr<)�hasattrrE�getattrr)r�namerrr�__getattr__�szCompressedData.__getattr__cCs8td�td�|jjtd�}t�|jj|�}t|�S)z,Returns palette pre-formatted for use in PDFz< z rrggbb�>)rarEZncolorsrrWZcmapdatahexr�)rZbuflenr�rrr�get_palette_pdf_string�s z%CompressedData.get_palette_pdf_stringN)r�)r6r7r8r9rBrZl_CIDataDestroyrHrJr{r�r+r�r�rrrrr��sr�c@s2eZdZdZdZejZdd�Zdd�Z	dd�Z
d	S)
r�z"Wrapper around PIXA (array of PIX)ZPIXAcCs|jdjSr��rEr�rrrrr��szPixArray.__len__c
Cs4t��$tt�|j|tj��W5QR�SQRXdSr<)rrKrZ
pixaGetPixrE�L_CLONE�rr�rrr�__getitem__�szPixArray.__getitem__c
Cs4t��$tt�|j|tj��W5QR�SQRXdSr<)rr�rZ
pixaGetBoxrEr�r�rrrr��szPixArray.get_boxN)r6r7r8r9rBrZpixaDestroyrHr�r�r�rrrrr��sr�c@sReZdZdZdZejZdd�Ze	dd��Z
e	dd��Ze	d	d
��Ze	dd��Z
d
S)r�zaWrapper around Leptonica's BOX objects (a pixel rectangle)

    Uses x, y, w, h coordinates.
    ZBOXcCs"|jrd�|j|j|j|j�SdS)Nz'<leptonica.Box x={0} y={1} w={2} h={3}>z<leptonica.Box NULL>)rErGr�r�rLrMrrrrrSs�zBox.__repr__cCs|jjSr<)rEr�rrrrr�szBox.xcCs|jjSr<)rEr�rrrrr�szBox.ycCs|jjSr<rkrrrrrLszBox.wcCs|jjSr<rmrrrrrMszBox.hN)r6r7r8r9rBrZ
boxDestroyrHrSr�r�r�rLrMrrrrr��s


r�c@s2eZdZdZdZejZdd�Zdd�Z	dd�Z
d	S)
�BoxArrayz7Wrapper around Leptonica's BOXA (Array of BOX) objects.ZBOXAcCs*|js
dSdd�|D�}dd�|�dS)Nz
<BoxArray>css|]}t|�VqdSr<)�repr)�.0r�rrr�	<genexpr>!sz$BoxArray.__repr__.<locals>.<genexpr>z<BoxArray [z, z]>)rE�join)rZboxesrrrrSszBoxArray.__repr__cCs|jjSr<r�rrrrr�$szBoxArray.__len__cCsPt|t�std��d|kr*t|�krDnntt�|j|tj��St	|��dS)Nzlist indices must be integersr)
rerOrgrar�rZ
boxaGetBoxrEr�r0r�rrrr�'s

zBoxArray.__getitem__N)r6r7r8r9rBrZboxaDestroyrHrSr�r�rrrrr�sr�c@s*eZdZdZdZejZdd�Zdd�Z	dS)r�zLeptonica SARRAY/string arrayZSARRAYcCs|jjSr<r�rrrrr�5szStringArray.__len__cCs:d|krt|�kr.nnt�|jj|�St|��dSr�)rar�stringrEZarrayr0r�rrrr�8szStringArray.__getitem__N)
r6r7r8r9rBrZ
sarrayDestroyrHr�r�rrrrr�/s
r�c@s:eZdZdZdZejZedd��Z	edd��Z
dd�Zd	S)
r�z8Leptonica 'sel'/selection element for hit-miss transformZSELcCs�dd�|�d�D�}t|�}t|d�}tdd�|D��}t|�dkrNtd��d	�d
d�|D��}t�|�d��}t�|�d��}	t�	||||	�}
||
�S)NcSsg|]}|��r|���qSr�r��r��linerrr�
<listcomp>Gsz#Sel.from_selstr.<locals>.<listcomp>�
rcss|]}t|�VqdSr<)rar�rrrr�Jsz"Sel.from_selstr.<locals>.<genexpr>r	z'All lines in selstr must be same lengthr@css|]}|��VqdSr<r�r�rrrr�Ns�ascii)
�splitra�setrAr�rr~�encoderZselCreateFromString)rI�selstrr��linesrMrLZlengthsZrepackedZ
buf_selstrZbuf_name�selrrrr�DszSel.from_selstrcCst�|||||�}||�Sr<)rZselCreateBrick)rIrMrLZcyZcxr�r	rrrr�TszSel.create_brickcCs.t�t�|j�tj�}dt�|��d�dS)Nz<Sel 
rz
>)rrCrZselPrintToStringrEr^r�r,)rrrrrrSYszSel.__repr__N)r6r7r8r9rBrZ
selDestroyrHrJr�r�rSrrrrr�>s

r�r�cCst�t�����S)z�Get Leptonica version string.

    Caveat: Leptonica expects the caller to free this memory.  We don't,
    since that would involve binding to libc to access libc.free(),
    a pointless effort to reclaim 100 bytes of memory.
    )rr�rZgetLeptonicaVersionr,rrrrr�^sr�cCs�zt�|�}Wn tk
r.td|��YnX|dkr>d}nd}|�|�}z|�|�Wn tk
rztd|��YnXdS)N�Failed to open file: %s�r	r�#Failed to open destination file: %s)rKr{r/r�r�)�infile�outfilerpZ
pix_sourcer�Zpix_deskewedrrrr�is
r��r�r�r�r��cCszzt�|�}Wn tk
r.td|��YnX|j|d��|||�}z|�|�Wn tk
rttd|��YnXdS)Nr
)r�r)rKr{r/r�r�r�)r
rr�r�Zblack_thresholdZwhite_thresholdrcrrr�remove_background{s�r�__main__z"Python wrapper to access Leptonica)�descriptionZcommandszsupported operations)�titlerz-rz--dpirpZstorer�zinput resolution)�dest�action�type�default�helpr
zimage to deskew)rrzdeskewed output image)�func)rr�r�r)@�argparseZloggingr!rrxZcollections.abcr�
contextlibrZctypes.utilr�	functoolsrrrrZtempfiler�
exceptionsr
�execrZlib._leptonicarZ	getLoggerr6r-r�Zlibname�environZ_libpathZdlopenrZsetMsgSeverityZL_SEVERITY_WARNING�error�er�	Exceptionr1r/r;rKr�r�r�r�r�r�r�r�r�ArgumentParser�parserZadd_subparsersZ
subparsersZ
add_parserZ
parser_deskew�add_argumentrOZset_defaults�
parse_args�argsrrrrr�<module>s�

�

��J$~&! 

�

�
�