From 590942ad14c91df4a1455496bfbf8fadb0541bf2 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Mon, 5 Nov 2018 01:48:38 -0800 Subject: [PATCH] Leptonica: Add barcode API --- src/ocrmypdf/leptonica.py | 43 ++++++++++++---- src/ocrmypdf/lib/_leptonica.py | 10 ++-- src/ocrmypdf/lib/compile_leptonica.py | 71 +++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 15 deletions(-) diff --git a/src/ocrmypdf/leptonica.py b/src/ocrmypdf/leptonica.py index ab26f750..a3a31c52 100644 --- a/src/ocrmypdf/leptonica.py +++ b/src/ocrmypdf/leptonica.py @@ -140,7 +140,7 @@ class Pix: def __init__(self, pix): if not pix: - raise ValueError('NULL box') + raise ValueError('NULL pix') self._pix = ffi.gc(pix, Pix._pix_destroy) def __repr__(self): @@ -485,14 +485,24 @@ class Pix: def invert(self): return Pix(lept.pixInvert(ffi.NULL, self._pix)) - def locate_barcodes(self, threshold=20): - p_mask = ffi.new('PIX **') - with _LeptonicaErrorTrap(): - result = lept.pixLocateBarcodes(self._pix, threshold, ffi.NULL, - p_mask) - if result == ffi.NULL: - return None, None - return BoxArray(result), Pix(p_mask[0]) + def locate_barcodes(self): + pixa_candidates = lept.pixExtractBarcodes(self._pix, 0) + if not pixa_candidates: + return + sarray = lept.pixReadBarcodes(pixa_candidates, + lept.L_BF_ANY, + lept.L_USE_WIDTHS, + ffi.NULL, + 0) + if not sarray: + return + for n in range(sarray[0].n): + decoded = ffi.string(sarray[0].array[n]).decode() + if decoded.strip() == '': + continue + box = pixa_candidates[0].boxa[0].box[n][0] + left, top, right, bottom = box.x, box.y, box.x + box.w, box.y + box.h + yield (decoded, (left, top, right, bottom)) @staticmethod @@ -542,6 +552,19 @@ class CompressedData: lept.l_CIDataDestroy(pp) +class PixArray: + + def __init__(self, pixa): + if not pixa: + raise ValueError('NULL pixa') + self._pixa = ffi.gc(pixa, PixArray._pixa_destroy) + + @staticmethod + def _pixa_destroy(pixa): + pp = ffi.new('PIXA **', pixa) + lept.pixaDestroy(pp) + + class Box: """Wrapper around Leptonica's BOX objects. @@ -607,7 +630,7 @@ class BoxArray: if not isinstance(n, int): raise TypeError('list indices must be integers') if 0 <= n < len(self): - return Box(lept.boxClone(self._boxa.box[n])) + return Box(lept.boxaGetBox(self._boxa, n, lept.L_CLONE)) raise IndexError(n) @staticmethod diff --git a/src/ocrmypdf/lib/_leptonica.py b/src/ocrmypdf/lib/_leptonica.py index e4bbc59b..a606c77f 100644 --- a/src/ocrmypdf/lib/_leptonica.py +++ b/src/ocrmypdf/lib/_leptonica.py @@ -3,9 +3,9 @@ import _cffi_backend ffi = _cffi_backend.FFI('ocrmypdf.lib._leptonica', _version = 0x2601, - _types = b'\x00\x00\x01\x0D\x00\x00\xD6\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xDB\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xDE\x03\x00\x00\x00\x0F\x00\x00\xD7\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x04\x03\x00\x00\x10\x11\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x01\x11\x00\x00\x01\x03\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x05\x03\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x0D\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x0B\x11\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\xEA\x03\x00\x00\x1C\x01\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x00\x0F\x00\x00\x52\x0D\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x28\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x77\x11\x00\x00\x77\x11\x00\x00\x77\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x77\x11\x00\x00\x77\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x52\x11\x00\x00\x52\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x52\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xD9\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x77\x11\x00\x00\x77\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x10\x11\x00\x00\x10\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x04\x11\x00\x00\xE9\x03\x00\x00\x6E\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x0B\x11\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x9B\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x0B\x11\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\xE7\x03\x00\x00\xB3\x11\x00\x00\x04\x11\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\xED\x0D\x00\x00\x19\x11\x00\x00\x00\x0F\x00\x00\xED\x0D\x00\x00\xD7\x03\x00\x00\x00\x0F\x00\x00\xED\x0D\x00\x00\x9B\x11\x00\x00\x00\x0F\x00\x00\xED\x0D\x00\x00\x10\x11\x00\x00\x00\x0F\x00\x00\xED\x0D\x00\x00\xED\x03\x00\x00\x00\x0F\x00\x00\x00\x09\x00\x00\xD8\x03\x00\x00\x01\x09\x00\x00\xDA\x03\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x04\x09\x00\x00\xDE\x03\x00\x00\x02\x01\x00\x00\x0E\x01\x00\x00\x00\x0B\x00\x00\x01\x0B\x00\x00\x02\x0B\x00\x00\x0B\x01\x00\x00\x05\x01\x00\x00\x03\x01\x00\x00\xDC\x03\x00\x00\xE8\x03\x00\x00\x04\x01\x00\x00\xEA\x03\x00\x00\x08\x01\x00\x00\x0C\x01\x00\x00\x06\x01\x00\x00\x00\x01', - _globals = (b'\xFF\xFF\xFF\x0BL_CLONE',2,b'\xFF\xFF\xFF\x0BL_COPY',1,b'\xFF\xFF\xFF\x0BL_COPY_CLONE',3,b'\xFF\xFF\xFF\x0BL_DEFAULT_ENCODE',0,b'\xFF\xFF\xFF\x0BL_FLATE_ENCODE',3,b'\xFF\xFF\xFF\x0BL_G4_ENCODE',2,b'\xFF\xFF\xFF\x0BL_INSERT',0,b'\xFF\xFF\xFF\x0BL_JP2K_ENCODE',4,b'\xFF\xFF\xFF\x0BL_JPEG_ENCODE',1,b'\xFF\xFF\xFF\x0BL_NOCOPY',0,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_BASED_ON_SRC',4,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_BINARY',0,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_FULL_COLOR',2,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_GRAYSCALE',1,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_WITH_ALPHA',3,b'\x00\x00\x00\x23boxClone',0,b'\x00\x00\xC7\x23boxDestroy',0,b'\x00\x00\xCA\x23boxaDestroy',0,b'\x00\x00\x70\x23getLeptonicaVersion',0,b'\x00\x00\xCD\x23l_CIDataDestroy',0,b'\x00\x00\xB5\x23l_generateCIDataForPdf',0,b'\x00\x00\xD3\x23lept_free',0,b'\x00\x00\x72\x23makePixelSumTab8',0,b'\x00\x00\x1F\x23pixAnd',0,b'\x00\x00\x2C\x23pixBackgroundNorm',0,b'\x00\x00\x24\x23pixCleanBackgroundToWhite',0,b'\x00\x00\x16\x23pixClipRectangle',0,b'\x00\x00\x9D\x23pixColorFraction',0,b'\x00\x00\x62\x23pixColorMagnitude',0,b'\x00\x00\x13\x23pixConvertRGBToLuminance',0,b'\x00\x00\x74\x23pixCorrelationBinary',0,b'\x00\x00\x89\x23pixCountPixels',0,b'\x00\x00\x6C\x23pixDeserializeFromMemory',0,b'\x00\x00\x59\x23pixDeskew',0,b'\x00\x00\xD0\x23pixDestroy',0,b'\x00\x00\x13\x23pixEndianByteSwapNew',0,b'\x00\x00\x03\x23pixFindPageForeground',0,b'\x00\x00\x84\x23pixFindSkew',0,b'\x00\x00\x38\x23pixGammaTRC',0,b'\x00\x00\x96\x23pixGenerateCIData',0,b'\x00\x00\x79\x23pixGetAverageMaskedRGB',0,b'\x00\x00\x3F\x23pixGlobalNormRGB',0,b'\x00\x00\x1B\x23pixInvert',0,b'\x00\x00\x0D\x23pixLocateBarcodes',0,b'\x00\x00\x5D\x23pixMaskOverColorPixels',0,b'\x00\x00\x8E\x23pixNumSignificantGrayColors',0,b'\x00\x00\xA6\x23pixOtsuAdaptiveThreshold',0,b'\x00\x00\x47\x23pixOtsuThreshOnBackgroundNorm',0,b'\x00\x00\x69\x23pixRead',0,b'\x00\x00\x59\x23pixRemoveColormap',0,b'\x00\x00\x5D\x23pixRemoveColormapGeneral',0,b'\x00\x00\x1B\x23pixRotate180',0,b'\x00\x00\x59\x23pixRotateOrth',0,b'\x00\x00\x54\x23pixScale',0,b'\x00\x00\xB0\x23pixSerializeToMemory',0,b'\x00\x00\xBB\x23pixWriteImpliedFormat',0,b'\x00\x00\xC1\x23pixWriteMemPng',0), - _struct_unions = ((b'\x00\x00\x00\xD6\x00\x00\x00\x02Box',b'\x00\x00\x05\x11x',b'\x00\x00\x05\x11y',b'\x00\x00\x05\x11w',b'\x00\x00\x05\x11h',b'\x00\x00\xEA\x11refcount'),(b'\x00\x00\x00\xD8\x00\x00\x00\x02Boxa',b'\x00\x00\x05\x11n',b'\x00\x00\x05\x11nalloc',b'\x00\x00\xEA\x11refcount',b'\x00\x00\x19\x11box'),(b'\x00\x00\x00\xDA\x00\x00\x00\x02L_Compressed_Data',b'\x00\x00\x05\x11type',b'\x00\x00\xE7\x11datacomp',b'\x00\x00\x6E\x11nbytescomp',b'\x00\x00\xDD\x11data85',b'\x00\x00\x6E\x11nbytes85',b'\x00\x00\xDD\x11cmapdata85',b'\x00\x00\xDD\x11cmapdatahex',b'\x00\x00\x05\x11ncolors',b'\x00\x00\x05\x11w',b'\x00\x00\x05\x11h',b'\x00\x00\x05\x11bps',b'\x00\x00\x05\x11spp',b'\x00\x00\x05\x11minisblack',b'\x00\x00\x05\x11predictor',b'\x00\x00\x6E\x11nbytes',b'\x00\x00\x05\x11res'),(b'\x00\x00\x00\xDB\x00\x00\x00\x02Pix',b'\x00\x00\xEA\x11w',b'\x00\x00\xEA\x11h',b'\x00\x00\xEA\x11d',b'\x00\x00\xEA\x11spp',b'\x00\x00\xEA\x11wpl',b'\x00\x00\xEA\x11refcount',b'\x00\x00\x05\x11xres',b'\x00\x00\x05\x11yres',b'\x00\x00\x05\x11informat',b'\x00\x00\x05\x11special',b'\x00\x00\xDD\x11text',b'\x00\x00\xE6\x11colormap',b'\x00\x00\xE9\x11data'),(b'\x00\x00\x00\xDC\x00\x00\x00\x02PixColormap',b'\x00\x00\xD4\x11array',b'\x00\x00\x05\x11depth',b'\x00\x00\x05\x11nalloc',b'\x00\x00\x05\x11n')), - _enums = (b'\x00\x00\x00\xE0\x00\x00\x00\x16$1\x00L_DEFAULT_ENCODE,L_JPEG_ENCODE,L_G4_ENCODE,L_FLATE_ENCODE,L_JP2K_ENCODE',b'\x00\x00\x00\xE1\x00\x00\x00\x16$2\x00REMOVE_CMAP_TO_BINARY,REMOVE_CMAP_TO_GRAYSCALE,REMOVE_CMAP_TO_FULL_COLOR,REMOVE_CMAP_WITH_ALPHA,REMOVE_CMAP_BASED_ON_SRC',b'\x00\x00\x00\xE2\x00\x00\x00\x16$3\x00L_NOCOPY,L_INSERT,L_COPY,L_CLONE,L_COPY_CLONE'), - _typenames = (b'\x00\x00\x00\xD6BOX',b'\x00\x00\x00\xD8BOXA',b'\x00\x00\x00\xDAL_COMP_DATA',b'\x00\x00\x00\xDBPIX',b'\x00\x00\x00\xDCPIXCMAP',b'\x00\x00\x00\x28l_float32',b'\x00\x00\x00\xDFl_float64',b'\x00\x00\x00\xE4l_int16',b'\x00\x00\x00\x05l_int32',b'\x00\x00\x00\xE3l_int64',b'\x00\x00\x00\xE5l_int8',b'\x00\x00\x00\xECl_uint16',b'\x00\x00\x00\xEAl_uint32',b'\x00\x00\x00\xEBl_uint64',b'\x00\x00\x00\xE8l_uint8'), + _types = b'\x00\x00\x01\x0D\x00\x00\xF6\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xF7\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xFA\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x01\x03\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x09\x03\x00\x00\x15\x11\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x01\x11\x00\x00\x01\x03\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x05\x03\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x0D\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x00\x10\x11\x00\x00\x00\x0F\x00\x00\x09\x0D\x00\x01\x0F\x03\x00\x00\x1C\x01\x00\x00\x00\x0F\x00\x00\x81\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\xFD\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xFD\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\xFD\x0D\x00\x00\xFB\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x7D\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x01\x00\x0D\x00\x00\x00\x0F\x00\x00\x57\x0D\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x04\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x2D\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x94\x11\x00\x00\x94\x11\x00\x00\x94\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x94\x11\x00\x00\x94\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x57\x11\x00\x00\x57\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x07\x01\x00\x00\x57\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xF8\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x94\x11\x00\x00\x94\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x09\x11\x00\x01\x0E\x03\x00\x00\x73\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x10\x11\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\xB8\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x10\x11\x00\x00\x09\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x01\x0C\x03\x00\x00\xD0\x11\x00\x00\x09\x11\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x01\x12\x0D\x00\x00\x1E\x11\x00\x00\x00\x0F\x00\x01\x12\x0D\x00\x00\x04\x03\x00\x00\x00\x0F\x00\x01\x12\x0D\x00\x00\xB8\x11\x00\x00\x00\x0F\x00\x01\x12\x0D\x00\x00\x15\x11\x00\x00\x00\x0F\x00\x01\x12\x0D\x00\x00\x81\x03\x00\x00\x00\x0F\x00\x01\x12\x0D\x00\x01\x12\x03\x00\x00\x00\x0F\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\xF9\x03\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x04\x09\x00\x00\xFE\x03\x00\x00\x06\x09\x00\x01\x00\x03\x00\x01\x01\x03\x00\x00\x02\x01\x00\x00\x0E\x01\x00\x00\x00\x0B\x00\x00\x01\x0B\x00\x00\x02\x0B\x00\x00\x03\x0B\x00\x00\x04\x0B\x00\x00\x0B\x01\x00\x00\x05\x01\x00\x00\x03\x01\x00\x00\xFC\x03\x00\x01\x0D\x03\x00\x00\x04\x01\x00\x01\x0F\x03\x00\x00\x08\x01\x00\x00\x0C\x01\x00\x00\x06\x01\x00\x00\x00\x01', + _globals = (b'\xFF\xFF\xFF\x0BL_BF_ANY',1,b'\xFF\xFF\xFF\x0BL_BF_CODABAR',9,b'\xFF\xFF\xFF\x0BL_BF_CODE128',2,b'\xFF\xFF\xFF\x0BL_BF_CODE2OF5',5,b'\xFF\xFF\xFF\x0BL_BF_CODE39',7,b'\xFF\xFF\xFF\x0BL_BF_CODE93',8,b'\xFF\xFF\xFF\x0BL_BF_CODEI2OF5',6,b'\xFF\xFF\xFF\x0BL_BF_EAN13',4,b'\xFF\xFF\xFF\x0BL_BF_EAN8',3,b'\xFF\xFF\xFF\x0BL_BF_UNKNOWN',0,b'\xFF\xFF\xFF\x0BL_BF_UPCA',10,b'\xFF\xFF\xFF\x0BL_CLONE',2,b'\xFF\xFF\xFF\x0BL_COPY',1,b'\xFF\xFF\xFF\x0BL_COPY_CLONE',3,b'\xFF\xFF\xFF\x0BL_DEFAULT_ENCODE',0,b'\xFF\xFF\xFF\x0BL_FLATE_ENCODE',3,b'\xFF\xFF\xFF\x0BL_G4_ENCODE',2,b'\xFF\xFF\xFF\x0BL_INSERT',0,b'\xFF\xFF\xFF\x0BL_JP2K_ENCODE',4,b'\xFF\xFF\xFF\x0BL_JPEG_ENCODE',1,b'\xFF\xFF\xFF\x0BL_NOCOPY',0,b'\xFF\xFF\xFF\x0BL_USE_WIDTHS',1,b'\xFF\xFF\xFF\x0BL_USE_WINDOWS',2,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_BASED_ON_SRC',4,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_BINARY',0,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_FULL_COLOR',2,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_TO_GRAYSCALE',1,b'\xFF\xFF\xFF\x0BREMOVE_CMAP_WITH_ALPHA',3,b'\x00\x00\x00\x23boxClone',0,b'\x00\x00\xE4\x23boxDestroy',0,b'\x00\x00\xE7\x23boxaDestroy',0,b'\x00\x00\x03\x23boxaGetBox',0,b'\x00\x00\x87\x23getLeptonicaVersion',0,b'\x00\x00\xEA\x23l_CIDataDestroy',0,b'\x00\x00\xD2\x23l_generateCIDataForPdf',0,b'\x00\x00\xF3\x23lept_free',0,b'\x00\x00\x89\x23makePixelSumTab8',0,b'\x00\x00\x24\x23pixAnd',0,b'\x00\x00\x31\x23pixBackgroundNorm',0,b'\x00\x00\x29\x23pixCleanBackgroundToWhite',0,b'\x00\x00\x1B\x23pixClipRectangle',0,b'\x00\x00\xBA\x23pixColorFraction',0,b'\x00\x00\x67\x23pixColorMagnitude',0,b'\x00\x00\x18\x23pixConvertRGBToLuminance',0,b'\x00\x00\x91\x23pixCorrelationBinary',0,b'\x00\x00\xA6\x23pixCountPixels',0,b'\x00\x00\x71\x23pixDeserializeFromMemory',0,b'\x00\x00\x5E\x23pixDeskew',0,b'\x00\x00\xED\x23pixDestroy',0,b'\x00\x00\x18\x23pixEndianByteSwapNew',0,b'\x00\x00\x75\x23pixExtractBarcodes',0,b'\x00\x00\x08\x23pixFindPageForeground',0,b'\x00\x00\xA1\x23pixFindSkew',0,b'\x00\x00\x3D\x23pixGammaTRC',0,b'\x00\x00\xB3\x23pixGenerateCIData',0,b'\x00\x00\x96\x23pixGetAverageMaskedRGB',0,b'\x00\x00\x44\x23pixGlobalNormRGB',0,b'\x00\x00\x20\x23pixInvert',0,b'\x00\x00\x12\x23pixLocateBarcodes',0,b'\x00\x00\x62\x23pixMaskOverColorPixels',0,b'\x00\x00\xAB\x23pixNumSignificantGrayColors',0,b'\x00\x00\xC3\x23pixOtsuAdaptiveThreshold',0,b'\x00\x00\x4C\x23pixOtsuThreshOnBackgroundNorm',0,b'\x00\x00\x79\x23pixProcessBarcodes',0,b'\x00\x00\x6E\x23pixRead',0,b'\x00\x00\x80\x23pixReadBarcodes',0,b'\x00\x00\x5E\x23pixRemoveColormap',0,b'\x00\x00\x62\x23pixRemoveColormapGeneral',0,b'\x00\x00\x8B\x23pixRenderBoxa',0,b'\x00\x00\x20\x23pixRotate180',0,b'\x00\x00\x5E\x23pixRotateOrth',0,b'\x00\x00\x59\x23pixScale',0,b'\x00\x00\xCD\x23pixSerializeToMemory',0,b'\x00\x00\xD8\x23pixWriteImpliedFormat',0,b'\x00\x00\xDE\x23pixWriteMemPng',0,b'\x00\x00\xF0\x23pixaDestroy',0), + _struct_unions = ((b'\x00\x00\x00\xF6\x00\x00\x00\x02Box',b'\x00\x00\x05\x11x',b'\x00\x00\x05\x11y',b'\x00\x00\x05\x11w',b'\x00\x00\x05\x11h',b'\x00\x01\x0F\x11refcount'),(b'\x00\x00\x00\xF7\x00\x00\x00\x02Boxa',b'\x00\x00\x05\x11n',b'\x00\x00\x05\x11nalloc',b'\x00\x01\x0F\x11refcount',b'\x00\x00\x1E\x11box'),(b'\x00\x00\x00\xF9\x00\x00\x00\x02L_Compressed_Data',b'\x00\x00\x05\x11type',b'\x00\x01\x0C\x11datacomp',b'\x00\x00\x73\x11nbytescomp',b'\x00\x01\x00\x11data85',b'\x00\x00\x73\x11nbytes85',b'\x00\x01\x00\x11cmapdata85',b'\x00\x01\x00\x11cmapdatahex',b'\x00\x00\x05\x11ncolors',b'\x00\x00\x05\x11w',b'\x00\x00\x05\x11h',b'\x00\x00\x05\x11bps',b'\x00\x00\x05\x11spp',b'\x00\x00\x05\x11minisblack',b'\x00\x00\x05\x11predictor',b'\x00\x00\x73\x11nbytes',b'\x00\x00\x05\x11res'),(b'\x00\x00\x00\xFA\x00\x00\x00\x02Pix',b'\x00\x01\x0F\x11w',b'\x00\x01\x0F\x11h',b'\x00\x01\x0F\x11d',b'\x00\x01\x0F\x11spp',b'\x00\x01\x0F\x11wpl',b'\x00\x01\x0F\x11refcount',b'\x00\x00\x05\x11xres',b'\x00\x00\x05\x11yres',b'\x00\x00\x05\x11informat',b'\x00\x00\x05\x11special',b'\x00\x01\x00\x11text',b'\x00\x01\x0B\x11colormap',b'\x00\x01\x0E\x11data'),(b'\x00\x00\x00\xFC\x00\x00\x00\x02PixColormap',b'\x00\x00\xF4\x11array',b'\x00\x00\x05\x11depth',b'\x00\x00\x05\x11nalloc',b'\x00\x00\x05\x11n'),(b'\x00\x00\x00\xFB\x00\x00\x00\x02Pixa',b'\x00\x00\x05\x11n',b'\x00\x00\x05\x11nalloc',b'\x00\x01\x0F\x11refcount',b'\x00\x00\x15\x11pix',b'\x00\x00\x04\x11boxa'),(b'\x00\x00\x00\xFE\x00\x00\x00\x02Sarray',b'\x00\x00\x05\x11nalloc',b'\x00\x00\x05\x11n',b'\x00\x00\x05\x11refcount',b'\x00\x00\xFF\x11array')), + _enums = (b'\x00\x00\x01\x03\x00\x00\x00\x16$1\x00L_DEFAULT_ENCODE,L_JPEG_ENCODE,L_G4_ENCODE,L_FLATE_ENCODE,L_JP2K_ENCODE',b'\x00\x00\x01\x04\x00\x00\x00\x16$2\x00REMOVE_CMAP_TO_BINARY,REMOVE_CMAP_TO_GRAYSCALE,REMOVE_CMAP_TO_FULL_COLOR,REMOVE_CMAP_WITH_ALPHA,REMOVE_CMAP_BASED_ON_SRC',b'\x00\x00\x01\x05\x00\x00\x00\x16$3\x00L_NOCOPY,L_INSERT,L_COPY,L_CLONE,L_COPY_CLONE',b'\x00\x00\x01\x06\x00\x00\x00\x16$4\x00L_USE_WIDTHS,L_USE_WINDOWS',b'\x00\x00\x01\x07\x00\x00\x00\x16$5\x00L_BF_UNKNOWN,L_BF_ANY,L_BF_CODE128,L_BF_EAN8,L_BF_EAN13,L_BF_CODE2OF5,L_BF_CODEI2OF5,L_BF_CODE39,L_BF_CODE93,L_BF_CODABAR,L_BF_UPCA'), + _typenames = (b'\x00\x00\x00\xF6BOX',b'\x00\x00\x00\xF7BOXA',b'\x00\x00\x00\xF9L_COMP_DATA',b'\x00\x00\x00\xFAPIX',b'\x00\x00\x00\xFBPIXA',b'\x00\x00\x00\xFCPIXCMAP',b'\x00\x00\x00\xFESARRAY',b'\x00\x00\x00\x2Dl_float32',b'\x00\x00\x01\x02l_float64',b'\x00\x00\x01\x09l_int16',b'\x00\x00\x00\x05l_int32',b'\x00\x00\x01\x08l_int64',b'\x00\x00\x01\x0Al_int8',b'\x00\x00\x00\x05l_ok',b'\x00\x00\x01\x11l_uint16',b'\x00\x00\x01\x0Fl_uint32',b'\x00\x00\x01\x10l_uint64',b'\x00\x00\x01\x0Dl_uint8'), ) diff --git a/src/ocrmypdf/lib/compile_leptonica.py b/src/ocrmypdf/lib/compile_leptonica.py index 963e45db..8582af2c 100644 --- a/src/ocrmypdf/lib/compile_leptonica.py +++ b/src/ocrmypdf/lib/compile_leptonica.py @@ -31,6 +31,8 @@ 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 */ @@ -60,6 +62,17 @@ struct PixColormap }; 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; + struct Box { l_int32 x; @@ -81,6 +94,16 @@ struct Boxa }; 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 */ @@ -130,6 +153,27 @@ enum { /*!< 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 */ +}; + """) ffibuilder.cdef(""" @@ -297,9 +341,27 @@ pixGenerateCIData(PIX *pixs, l_int32 ascii85, L_COMP_DATA **pcid); +SARRAY * +pixProcessBarcodes(PIX *pixs, + l_int32 format, + l_int32 method, + SARRAY **psaw, + l_int32 debugflag); + +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); + l_int32 l_generateCIDataForPdf(const char *fname, PIX *pix, @@ -309,12 +371,21 @@ l_generateCIDataForPdf(const char *fname, BOX * boxClone ( BOX *box ); +BOX * +boxaGetBox ( BOXA *boxa, l_int32 index, l_int32 accessflag ); + 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);