Work around Leptonica < 1.72 bug that breaks Travis

This commit is contained in:
James R. Barlow
2016-02-16 07:03:50 -08:00
parent ee5223eea8
commit ab3c1988c1
2 changed files with 34 additions and 5 deletions
+30 -5
View File
@@ -16,6 +16,7 @@ import logging
from tempfile import TemporaryFile
from ctypes.util import find_library
from .lib._leptonica import ffi
from functools import lru_cache
lept = ffi.dlopen(find_library('lept'))
@@ -166,11 +167,34 @@ class Pix:
@staticmethod
def correlation_binary(pix1, pix2):
correlation = ffi.new('float *', 0.0)
result = lept.pixCorrelationBinary(pix1.cpix, pix2.cpix, correlation)
if result != 0:
raise LeptonicaError("Correlation failed")
return float(correlation[0])
if getLeptonicaVersion() < 'leptonica-1.72':
# Older versions of Leptonica (pre-1.72) have a buggy
# implementation of pixCorrelationBinary that overflows on larger
# images.
pix1_count = ffi.new('l_int32 *', 0)
pix2_count = ffi.new('l_int32 *', 0)
pixn_count = ffi.new('l_int32 *', 0)
tab8 = lept.makePixelSumTab8() # Small memory leak on each call
lept.pixCountPixels(pix1.cpix, pix1_count, tab8)
lept.pixCountPixels(pix2.cpix, pix2_count, tab8)
pixn = Pix(lept.pixAnd(ffi.NULL, pix1.cpix, pix2.cpix))
lept.pixCountPixels(pixn.cpix, pixn_count, tab8)
# Python converts these int32s to larger units as needed
# to avoid overflow. Overflow happens easily here.
correlation = (
(pixn_count[0] * pixn_count[0]) /
(pix1_count[0] * pix2_count[0])
)
return correlation
else:
correlation = ffi.new('float *', 0.0)
result = lept.pixCorrelationBinary(pix1.cpix, pix2.cpix,
correlation)
if result != 0:
raise LeptonicaError("Correlation failed")
return correlation[0]
@staticmethod
def _pix_destroy(pix):
@@ -179,6 +203,7 @@ class Pix:
# print('pix destroy ' + repr(pix))
@lru_cache(maxsize=1)
def getLeptonicaVersion():
"""Get Leptonica version string.
+4
View File
@@ -54,6 +54,10 @@ 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);
l_int32 pixCountPixels ( PIX *pix, l_int32 *pcount, l_int32 *tab8 );
PIX * pixAnd ( PIX *pixd, PIX *pixs1, PIX *pixs2 );
l_int32 * makePixelSumTab8 ( void );
""")
if __name__ == '__main__':