517 lines
18 KiB
Python
517 lines
18 KiB
Python
#!/usr/bin/env python3
|
|
# © 2017 James R. Barlow: github.com/jbarlow83
|
|
#
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
from cffi import FFI
|
|
|
|
ffibuilder = FFI()
|
|
ffibuilder.cdef(
|
|
"""
|
|
typedef signed char l_int8;
|
|
typedef unsigned char l_uint8;
|
|
typedef short l_int16;
|
|
typedef unsigned short l_uint16;
|
|
typedef int l_int32;
|
|
typedef unsigned int l_uint32;
|
|
typedef float l_float32;
|
|
typedef double l_float64;
|
|
typedef long long l_int64;
|
|
typedef unsigned long long l_uint64;
|
|
|
|
typedef int l_ok; /*!< return type 0 if OK, 1 on error */
|
|
|
|
struct Pix
|
|
{
|
|
l_uint32 w; /* width in pixels */
|
|
l_uint32 h; /* height in pixels */
|
|
l_uint32 d; /* depth in bits (bpp) */
|
|
l_uint32 spp; /* number of samples per pixel */
|
|
l_uint32 wpl; /* 32-bit words/line */
|
|
l_uint32 refcount; /* reference count (1 if no clones) */
|
|
l_int32 xres; /* image res (ppi) in x direction */
|
|
/* (use 0 if unknown) */
|
|
l_int32 yres; /* image res (ppi) in y direction */
|
|
/* (use 0 if unknown) */
|
|
l_int32 informat; /* input file format, IFF_* */
|
|
l_int32 special; /* special instructions for I/O, etc */
|
|
char *text; /* text string associated with pix */
|
|
struct PixColormap *colormap; /* colormap (may be null) */
|
|
l_uint32 *data; /* the image data */
|
|
};
|
|
typedef struct Pix PIX;
|
|
|
|
struct PixColormap
|
|
{
|
|
void *array; /* colormap table (array of RGBA_QUAD) */
|
|
l_int32 depth; /* of pix (1, 2, 4 or 8 bpp) */
|
|
l_int32 nalloc; /* number of color entries allocated */
|
|
l_int32 n; /* number of color entries used */
|
|
};
|
|
typedef struct PixColormap PIXCMAP;
|
|
|
|
/*! Array of pix */
|
|
struct Pixa
|
|
{
|
|
l_int32 n; /*!< number of Pix in ptr array */
|
|
l_int32 nalloc; /*!< number of Pix ptrs allocated */
|
|
l_uint32 refcount; /*!< reference count (1 if no clones) */
|
|
struct Pix **pix; /*!< the array of ptrs to pix */
|
|
struct Boxa *boxa; /*!< array of boxes */
|
|
};
|
|
typedef struct Pixa PIXA;
|
|
|
|
/*! Array of compressed pix */
|
|
struct PixaComp
|
|
{
|
|
l_int32 n; /*!< number of PixComp in ptr array */
|
|
l_int32 nalloc; /*!< number of PixComp ptrs allocated */
|
|
l_int32 offset; /*!< indexing offset into ptr array */
|
|
struct PixComp **pixc; /*!< the array of ptrs to PixComp */
|
|
struct Boxa *boxa; /*!< array of boxes */
|
|
};
|
|
typedef struct PixaComp PIXAC;
|
|
|
|
struct Box
|
|
{
|
|
l_int32 x;
|
|
l_int32 y;
|
|
l_int32 w;
|
|
l_int32 h;
|
|
l_uint32 refcount; /* reference count (1 if no clones) */
|
|
|
|
};
|
|
typedef struct Box BOX;
|
|
|
|
/*! Array of Box */
|
|
struct Boxa
|
|
{
|
|
l_int32 n; /*!< number of box in ptr array */
|
|
l_int32 nalloc; /*!< number of box ptrs allocated */
|
|
l_uint32 refcount; /*!< reference count (1 if no clones) */
|
|
struct Box **box; /*!< box ptr array */
|
|
};
|
|
typedef struct Boxa BOXA;
|
|
|
|
/*! String array: an array of C strings */
|
|
struct Sarray
|
|
{
|
|
l_int32 nalloc; /*!< size of allocated ptr array */
|
|
l_int32 n; /*!< number of strings allocated */
|
|
l_int32 refcount; /*!< reference count (1 if no clones) */
|
|
char **array; /*!< string array */
|
|
};
|
|
typedef struct Sarray SARRAY;
|
|
|
|
/*! Pdf formatted encoding types */
|
|
enum {
|
|
L_DEFAULT_ENCODE = 0, /*!< use default encoding based on image */
|
|
L_JPEG_ENCODE = 1, /*!< use dct encoding: 8 and 32 bpp, no cmap */
|
|
L_G4_ENCODE = 2, /*!< use ccitt g4 fax encoding: 1 bpp */
|
|
L_FLATE_ENCODE = 3, /*!< use flate encoding: any depth, cmap ok */
|
|
L_JP2K_ENCODE = 4 /*!< use jp2k encoding: 8 and 32 bpp, no cmap */
|
|
};
|
|
|
|
/*! Compressed image data */
|
|
struct L_Compressed_Data
|
|
{
|
|
l_int32 type; /*!< encoding type: L_JPEG_ENCODE, etc */
|
|
l_uint8 *datacomp; /*!< gzipped raster data */
|
|
size_t nbytescomp; /*!< number of compressed bytes */
|
|
char *data85; /*!< ascii85-encoded gzipped raster data */
|
|
size_t nbytes85; /*!< number of ascii85 encoded bytes */
|
|
char *cmapdata85; /*!< ascii85-encoded uncompressed cmap */
|
|
char *cmapdatahex; /*!< hex pdf array for the cmap */
|
|
l_int32 ncolors; /*!< number of colors in cmap */
|
|
l_int32 w; /*!< image width */
|
|
l_int32 h; /*!< image height */
|
|
l_int32 bps; /*!< bits/sample; typ. 1, 2, 4 or 8 */
|
|
l_int32 spp; /*!< samples/pixel; typ. 1 or 3 */
|
|
l_int32 minisblack; /*!< tiff g4 photometry */
|
|
l_int32 predictor; /*!< flate data has PNG predictors */
|
|
size_t nbytes; /*!< number of uncompressed raster bytes */
|
|
l_int32 res; /*!< resolution (ppi) */
|
|
};
|
|
typedef struct L_Compressed_Data L_COMP_DATA;
|
|
|
|
/*! Selection */
|
|
struct Sel
|
|
{
|
|
l_int32 sy; /*!< sel height */
|
|
l_int32 sx; /*!< sel width */
|
|
l_int32 cy; /*!< y location of sel origin */
|
|
l_int32 cx; /*!< x location of sel origin */
|
|
l_int32 **data; /*!< {0,1,2}; data[i][j] in [row][col] order */
|
|
char *name; /*!< used to find sel by name */
|
|
};
|
|
typedef struct Sel SEL;
|
|
|
|
enum {
|
|
REMOVE_CMAP_TO_BINARY = 0, /*!< remove colormap for conv to 1 bpp */
|
|
REMOVE_CMAP_TO_GRAYSCALE = 1, /*!< remove colormap for conv to 8 bpp */
|
|
REMOVE_CMAP_TO_FULL_COLOR = 2, /*!< remove colormap for conv to 32 bpp */
|
|
REMOVE_CMAP_WITH_ALPHA = 3, /*!< remove colormap and alpha */
|
|
REMOVE_CMAP_BASED_ON_SRC = 4 /*!< remove depending on src format */
|
|
};
|
|
|
|
/*! Access and storage flags */
|
|
enum {
|
|
L_NOCOPY = 0, /*!< do not copy the object; do not delete the ptr */
|
|
L_INSERT = L_NOCOPY, /*!< stuff it in; do not copy or clone */
|
|
L_COPY = 1, /*!< make/use a copy of the object */
|
|
L_CLONE = 2, /*!< make/use clone (ref count) of the object */
|
|
L_COPY_CLONE = 3 /*!< make a new array object (e.g., pixa) and fill */
|
|
/*!< the array with clones (e.g., pix) */
|
|
};
|
|
|
|
/*! Flags for method of extracting barcode widths */
|
|
enum {
|
|
L_USE_WIDTHS = 1, /*!< use histogram of barcode widths */
|
|
L_USE_WINDOWS = 2 /*!< find best window for decoding transitions */
|
|
};
|
|
|
|
/*! Flags for barcode formats */
|
|
enum {
|
|
L_BF_UNKNOWN = 0, /*!< unknown format */
|
|
L_BF_ANY = 1, /*!< try decoding with all known formats */
|
|
L_BF_CODE128 = 2, /*!< decode with Code128 format */
|
|
L_BF_EAN8 = 3, /*!< decode with EAN8 format */
|
|
L_BF_EAN13 = 4, /*!< decode with EAN13 format */
|
|
L_BF_CODE2OF5 = 5, /*!< decode with Code 2 of 5 format */
|
|
L_BF_CODEI2OF5 = 6, /*!< decode with Interleaved 2 of 5 format */
|
|
L_BF_CODE39 = 7, /*!< decode with Code39 format */
|
|
L_BF_CODE93 = 8, /*!< decode with Code93 format */
|
|
L_BF_CODABAR = 9, /*!< decode with Code93 format */
|
|
L_BF_UPCA = 10 /*!< decode with UPC A format */
|
|
};
|
|
|
|
enum {
|
|
L_SEVERITY_EXTERNAL = 0, /* Get the severity from the environment */
|
|
L_SEVERITY_ALL = 1, /* Lowest severity: print all messages */
|
|
L_SEVERITY_DEBUG = 2, /* Print debugging and higher messages */
|
|
L_SEVERITY_INFO = 3, /* Print informational and higher messages */
|
|
L_SEVERITY_WARNING = 4, /* Print warning and higher messages */
|
|
L_SEVERITY_ERROR = 5, /* Print error and higher messages */
|
|
L_SEVERITY_NONE = 6 /* Highest severity: print no messages */
|
|
};
|
|
|
|
enum {
|
|
SEL_DONT_CARE = 0,
|
|
SEL_HIT = 1,
|
|
SEL_MISS = 2
|
|
};
|
|
|
|
"""
|
|
)
|
|
|
|
ffibuilder.cdef(
|
|
"""
|
|
PIX * pixRead ( const char *filename );
|
|
PIX * pixReadMem ( const l_uint8 *data, size_t size );
|
|
PIX * pixReadStream ( FILE *fp, l_int32 hint );
|
|
PIX * pixScale ( PIX *pixs, l_float32 scalex, l_float32 scaley );
|
|
l_int32 pixFindSkew ( PIX *pixs, l_float32 *pangle, l_float32 *pconf );
|
|
l_int32 pixWriteImpliedFormat ( const char *filename, PIX *pix, l_int32 quality, l_int32 progressive );
|
|
l_int32 getImpliedFileFormat ( const char *filename );
|
|
l_ok pixWriteStream ( FILE *fp, PIX *pix, l_int32 format );
|
|
l_ok pixWriteStreamJpeg ( FILE *fp, PIX *pixs, l_int32 quality, l_int32 progressive );
|
|
l_ok pixWriteMem ( l_uint8 **pdata, size_t *psize, PIX *pix, l_int32 format );
|
|
l_ok pixWriteMemJpeg ( l_uint8 **pdata, size_t *psize, PIX *pix, l_int32 quality, l_int32 progressive );
|
|
l_int32
|
|
pixWriteMemPng(l_uint8 **pdata,
|
|
size_t *psize,
|
|
PIX *pix,
|
|
l_float32 gamma);
|
|
|
|
void pixDestroy ( PIX **ppix );
|
|
|
|
l_ok
|
|
pixEqual(PIX *pix1,
|
|
PIX *pix2,
|
|
l_int32 *psame);
|
|
|
|
PIX *
|
|
pixEndianByteSwapNew(PIX *pixs);
|
|
|
|
PIX * pixDeskew ( PIX *pixs, l_int32 redsearch );
|
|
char * getLeptonicaVersion ( );
|
|
l_int32 pixCorrelationBinary(PIX *pix1, PIX *pix2, l_float32 *pval);
|
|
PIX *pixRotate180(PIX *pixd, PIX *pixs);
|
|
PIX *
|
|
pixRotateOrth(PIX *pixs,
|
|
l_int32 quads);
|
|
|
|
l_int32 pixCountPixels ( PIX *pix, l_int32 *pcount, l_int32 *tab8 );
|
|
PIX * pixAnd ( PIX *pixd, PIX *pixs1, PIX *pixs2 );
|
|
l_int32 * makePixelSumTab8 ( void );
|
|
|
|
PIX * pixDeserializeFromMemory ( const l_uint32 *data, size_t nbytes );
|
|
l_int32 pixSerializeToMemory ( PIX *pixs, l_uint32 **pdata, size_t *pnbytes );
|
|
|
|
PIX * pixConvertRGBToLuminance(PIX *pixs);
|
|
|
|
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag);
|
|
|
|
PIX * pixRemoveColormap(PIX *pixs, l_int32 type);
|
|
|
|
l_int32
|
|
pixOtsuAdaptiveThreshold(PIX *pixs,
|
|
l_int32 sx,
|
|
l_int32 sy,
|
|
l_int32 smoothx,
|
|
l_int32 smoothy,
|
|
l_float32 scorefract,
|
|
PIX **ppixth,
|
|
PIX **ppixd);
|
|
|
|
PIX *
|
|
pixOtsuThreshOnBackgroundNorm(PIX *pixs,
|
|
PIX *pixim,
|
|
l_int32 sx,
|
|
l_int32 sy,
|
|
l_int32 thresh,
|
|
l_int32 mincount,
|
|
l_int32 bgval,
|
|
l_int32 smoothx,
|
|
l_int32 smoothy,
|
|
l_float32 scorefract,
|
|
l_int32 *pthresh);
|
|
|
|
PIX *
|
|
pixMaskedThreshOnBackgroundNorm(PIX *pixs,
|
|
PIX *pixim,
|
|
l_int32 sx,
|
|
l_int32 sy,
|
|
l_int32 thresh,
|
|
l_int32 mincount,
|
|
l_int32 smoothx,
|
|
l_int32 smoothy,
|
|
l_float32 scorefract,
|
|
l_int32 *pthresh);
|
|
|
|
PIX *
|
|
pixCleanBackgroundToWhite(PIX *pixs,
|
|
PIX *pixim,
|
|
PIX *pixg,
|
|
l_float32 gamma,
|
|
l_int32 blackval,
|
|
l_int32 whiteval);
|
|
|
|
BOX *
|
|
pixFindPageForeground ( PIX *pixs,
|
|
l_int32 threshold,
|
|
l_int32 mindist,
|
|
l_int32 erasedist,
|
|
l_int32 showmorph,
|
|
PIXAC *pixac );
|
|
|
|
PIX *
|
|
pixClipRectangle(PIX *pixs,
|
|
BOX *box,
|
|
BOX **pboxc);
|
|
|
|
PIX *
|
|
pixBackgroundNorm(PIX *pixs,
|
|
PIX *pixim,
|
|
PIX *pixg,
|
|
l_int32 sx,
|
|
l_int32 sy,
|
|
l_int32 thresh,
|
|
l_int32 mincount,
|
|
l_int32 bgval,
|
|
l_int32 smoothx,
|
|
l_int32 smoothy);
|
|
|
|
PIX *
|
|
pixGammaTRC(PIX *pixd,
|
|
PIX *pixs,
|
|
l_float32 gamma,
|
|
l_int32 minval,
|
|
l_int32 maxval);
|
|
|
|
|
|
l_int32
|
|
pixNumSignificantGrayColors(PIX *pixs,
|
|
l_int32 darkthresh,
|
|
l_int32 lightthresh,
|
|
l_float32 minfract,
|
|
l_int32 factor,
|
|
l_int32 *pncolors);
|
|
|
|
l_int32
|
|
pixColorFraction(PIX *pixs,
|
|
l_int32 darkthresh,
|
|
l_int32 lightthresh,
|
|
l_int32 diffthresh,
|
|
l_int32 factor,
|
|
l_float32 *ppixfract,
|
|
l_float32 *pcolorfract);
|
|
|
|
PIX *
|
|
pixColorMagnitude(PIX *pixs,
|
|
l_int32 rwhite,
|
|
l_int32 gwhite,
|
|
l_int32 bwhite,
|
|
l_int32 type);
|
|
|
|
PIX *
|
|
pixMaskOverColorPixels(PIX *pixs,
|
|
l_int32 threshdiff,
|
|
l_int32 mindist);
|
|
|
|
l_int32
|
|
pixGetAverageMaskedRGB(PIX *pixs,
|
|
PIX *pixm,
|
|
l_int32 x,
|
|
l_int32 y,
|
|
l_int32 factor,
|
|
l_int32 type,
|
|
l_float32 *prval,
|
|
l_float32 *pgval,
|
|
l_float32 *pbval);
|
|
|
|
PIX *
|
|
pixGlobalNormRGB(PIX * pixd,
|
|
PIX * pixs,
|
|
l_int32 rval,
|
|
l_int32 gval,
|
|
l_int32 bval,
|
|
l_int32 mapval);
|
|
|
|
PIX *
|
|
pixInvert(PIX * pixd,
|
|
PIX * pixs);
|
|
|
|
PIX *
|
|
pixRemoveColormapGeneral(PIX *pixs,
|
|
l_int32 type,
|
|
l_int32 ifnocmap);
|
|
|
|
l_int32
|
|
pixGenerateCIData(PIX *pixs,
|
|
l_int32 type,
|
|
l_int32 quality,
|
|
l_int32 ascii85,
|
|
L_COMP_DATA **pcid);
|
|
|
|
SARRAY *
|
|
pixProcessBarcodes(PIX *pixs,
|
|
l_int32 format,
|
|
l_int32 method,
|
|
SARRAY **psaw,
|
|
l_int32 debugflag);
|
|
|
|
PIX *
|
|
pixaGetPix(PIXA *pixa,
|
|
l_int32 index,
|
|
l_int32 accesstype);
|
|
|
|
BOX*
|
|
pixaGetBox (PIXA * pixa,
|
|
l_int32 index,
|
|
l_int32 accesstype );
|
|
|
|
PIXA *
|
|
pixExtractBarcodes(PIX *pixs,
|
|
l_int32 debugflag);
|
|
|
|
BOXA *
|
|
pixLocateBarcodes ( PIX *pixs,
|
|
l_int32 thresh,
|
|
PIX **ppixb,
|
|
PIX **ppixm );
|
|
|
|
SARRAY *
|
|
pixReadBarcodes(PIXA *pixa,
|
|
l_int32 format,
|
|
l_int32 method,
|
|
SARRAY **psaw,
|
|
l_int32 debugflag);
|
|
|
|
PIX *
|
|
pixGenHalftoneMask(PIX *pixs,
|
|
PIX **ppixtext,
|
|
l_int32 *phtfound,
|
|
PIXA *pixadb);
|
|
|
|
l_int32
|
|
l_generateCIDataForPdf(const char *fname,
|
|
PIX *pix,
|
|
l_int32 quality,
|
|
L_COMP_DATA **pcid);
|
|
|
|
|
|
BOX *
|
|
boxClone ( BOX *box );
|
|
|
|
BOX *
|
|
boxaGetBox ( BOXA *boxa, l_int32 index, l_int32 accessflag );
|
|
|
|
SEL *
|
|
selCreateFromString ( const char *text, l_int32 h, l_int32 w, const char *name );
|
|
|
|
SEL *
|
|
selCreateBrick ( l_int32 h, l_int32 w, l_int32 cy, l_int32 cx, l_int32 type );
|
|
|
|
char *
|
|
selPrintToString(SEL *sel);
|
|
|
|
PIX *
|
|
pixDilate ( PIX *pixd, PIX *pixs, SEL *sel );
|
|
|
|
PIX *
|
|
pixErode ( PIX *pixd, PIX *pixs, SEL *sel );
|
|
|
|
PIX *
|
|
pixHMT ( PIX *pixd, PIX *pixs, SEL *sel );
|
|
|
|
PIX *
|
|
pixSubtract ( PIX *pixd, PIX *pixs1, PIX *pixs2 );
|
|
|
|
void
|
|
boxDestroy(BOX **pbox);
|
|
|
|
void
|
|
boxaDestroy ( BOXA **pboxa );
|
|
|
|
void
|
|
pixaDestroy(PIXA **ppixa);
|
|
|
|
l_ok
|
|
pixRenderBoxa ( PIX *pix, BOXA *boxa, l_int32 width, l_int32 op );
|
|
|
|
void
|
|
l_CIDataDestroy(L_COMP_DATA **pcid);
|
|
|
|
void
|
|
sarrayDestroy(SARRAY **psa);
|
|
|
|
void
|
|
lept_free(void *ptr);
|
|
|
|
void selDestroy ( SEL **psel );
|
|
|
|
l_int32
|
|
setMsgSeverity(l_int32 newsev);
|
|
|
|
void
|
|
leptSetStderrHandler(void (*handler)(const char *));
|
|
"""
|
|
)
|
|
|
|
|
|
ffibuilder.set_source("ocrmypdf.lib._leptonica", None)
|
|
|
|
if __name__ == '__main__':
|
|
ffibuilder.compile(verbose=True)
|
|
if Path('ocrmypdf/lib/_leptonica.py').exists() and Path('src/ocrmypdf').exists():
|
|
output = Path('ocrmypdf/lib/_leptonica.py')
|
|
output.rename('src/ocrmypdf/lib/_leptonica.py')
|
|
Path('ocrmypdf/lib').rmdir()
|
|
Path('ocrmypdf').rmdir()
|