Fix Leptonica to use MuPDF memory allocators. 1.18.1-so-3.12.4
authorRobin Watts <[email protected]>
Tue, 13 Jul 2021 09:52:53 +0000 (10:52 +0100)
committerRobin Watts <[email protected]>
Wed, 14 Jul 2021 15:17:10 +0000 (16:17 +0100)
A typo in the Leptonica build options was causing Leptonica to use
native malloc/free on non-windows platforms.

Tesseract allocates via new/delete/new[]/delete[]. While these
can be trapped (see tessocr.cpp in the Ghostscript source for
an example of how), this does not help us here.

Tesseract calls new/delete etc as part of the static init it does
on startup. This means that any redirection of new/delete to
other allocators would have to happen before MuPDF starts up. This
does not fit with MuPDF's method of having the allocators defined
in the context.

We therefore live with Tesseract using the standard allocators
(new/delete). If this really is a problem for any particular
integrator, then we work with them to hardwire in allocator changes.

Makelists
source/fitz/tessocr.cpp

index 6a9080ae9b2559d160a6ddfbc31f25031670ffb5..af8a3dc5372f4bc958a9a41ae65e38be085bc49a 100644 (file)
--- a/Makelists
+++ b/Makelists
@@ -354,7 +354,7 @@ GLUT_LIBS += -lXrandr
 LEPTONICA_CFLAGS += -Ithirdparty/leptonica/src
 
 LEPTONICA_BUILD_CFLAGS += -Iscripts/tesseract
-LEPTONICA_BUILD_CFLAGS += -DLEPTONICA_INTERCEPT_MALLOC=1
+LEPTONICA_BUILD_CFLAGS += -DLEPTONICA_INTERCEPT_ALLOC=1
 LEPTONICA_BUILD_CFLAGS += -DHAVE_LIBPNG=0
 LEPTONICA_BUILD_CFLAGS += -DHAVE_LIBTIFF=0
 LEPTONICA_BUILD_CFLAGS += -DHAVE_LIBJPEG=0
index f2f032d5cb730f5cea5422344f967911395dc024..d326bb1e4bb71e264f76eb1aa03bcc231e9ddcdd 100644 (file)
@@ -10,32 +10,15 @@ extern "C" {
 
 #include "tessocr.h"
 
-/* Non-overridden leptonica alloc functions. These should never
- * actually be used. */
-void *leptonica_malloc(size_t blocksize)
-{
-       void *ret = malloc(blocksize);
-#ifdef DEBUG_ALLOCS
-       printf("%d LEPTONICA_MALLOC %d -> %p\n", event++, (int)blocksize, ret);
-       fflush(stdout);
-#endif
-       return ret;
-}
+/* Now the actual allocations to be used for leptonica. Unfortunately
+ * we have to use a nasty global here. */
+static fz_context *leptonica_mem = NULL;
 
-void *leptonica_calloc(size_t numelm, size_t elemsize)
+void *leptonica_malloc(size_t size)
 {
-       void *ret = calloc(numelm, elemsize);
-#ifdef DEBUG_ALLOCS
-       printf("%d LEPTONICA_CALLOC %d,%d -> %p\n", event++, (int)numelm, (int)elem> fflush(stdout);
-#endif
-       return ret;
-}
-
-void *leptonica_realloc(void *ptr, size_t blocksize)
-{
-       void *ret = realloc(ptr, blocksize);
+       void *ret = Memento_label(fz_malloc_no_throw(leptonica_mem, size), "leptonica_malloc");
 #ifdef DEBUG_ALLOCS
-       printf("%d LEPTONICA_REALLOC %p,%d -> %p\n", event++, ptr, (int)blocksize, ret);
+       printf("%d LEPTONICA_MALLOC(%p) %d -> %p\n", event++, leptonica_mem, (int)size, ret);
        fflush(stdout);
 #endif
        return ret;
@@ -44,33 +27,35 @@ void *leptonica_realloc(void *ptr, size_t blocksize)
 void leptonica_free(void *ptr)
 {
 #ifdef DEBUG_ALLOCS
-       printf("%d LEPTONICA_FREE %p\n", event++, ptr);
+       printf("%d LEPTONICA_FREE(%p) %p\n", event++, leptonica_mem, ptr);
        fflush(stdout);
 #endif
-       free(ptr);
+       fz_free(leptonica_mem, ptr);
 }
 
-/* Now the actual allocations to be used for leptonica. Unfortunately
- * we have to use a nasty global here. */
-static fz_context *leptonica_mem;
-
-static void *my_leptonica_malloc(size_t size)
+void *leptonica_calloc(size_t numelm, size_t elemsize)
 {
-       void *ret = Memento_label(fz_malloc_no_throw(leptonica_mem, size), "leptonica_malloc");
+       void *ret = leptonica_malloc(numelm * elemsize);
+
+       if (ret)
+               memset(ret, 0, numelm * elemsize);
 #ifdef DEBUG_ALLOCS
-       printf("%d MY_LEPTONICA_MALLOC(%p) %d -> %p\n", event++, leptonica_mem, (int)size, ret);
+       printf("%d LEPTONICA_CALLOC %d,%d -> %p\n", event++, (int)numelm, (int)elemsize, ret);
        fflush(stdout);
 #endif
        return ret;
 }
 
-static void my_leptonica_free(void *ptr)
+/* Not currently actually used */
+void *leptonica_realloc(void *ptr, size_t blocksize)
 {
+       void *ret = fz_realloc_no_throw(leptonica_mem, ptr, blocksize);
+
 #ifdef DEBUG_ALLOCS
-       printf("%d MY_LEPTONICA_FREE(%p) %p\n", event++, leptonica_mem, ptr);
+       printf("%d LEPTONICA_REALLOC %p,%d -> %p\n", event++, ptr, (int)blocksize, ret);
        fflush(stdout);
 #endif
-       fz_free(leptonica_mem, ptr);
+       return NULL;
 }
 
 #if TESSERACT_MAJOR_VERSION >= 5
@@ -177,7 +162,7 @@ void *ocr_init(fz_context *ctx, const char *language)
        tesseract::TessBaseAPI *api;
 
        set_leptonica_mem(ctx);
-       setPixMemoryManager(my_leptonica_malloc, my_leptonica_free);
+       setPixMemoryManager(leptonica_malloc, leptonica_free);
        api = new tesseract::TessBaseAPI();
 
        if (api == NULL)