Skip to content

Commit 30c64cb

Browse files
committed
make gd optional
1 parent 37d1fdc commit 30c64cb

3 files changed

Lines changed: 37 additions & 4 deletions

File tree

gf2bv/_internal.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "_internal.h"
22

3+
#include <dlfcn.h>
4+
35
// CPython does not have an public API for this yet
46
// ref: https://github.com/aleaxit/gmpy/issues/467
57
#if PY_VERSION_HEX >= 0x030C0000
@@ -673,9 +675,41 @@ PyObject *list_where(PyObject *self, PyObject *const *args, Py_ssize_t nargs) {
673675
return cond;
674676
}
675677

678+
// gd.h functions needed by eqs_to_sage_mat_helper
679+
void *(*gdImageCreate)(int, int);
680+
int (*gdImageColorAllocate)(void *, int, int, int);
681+
void (*gdImageFilledRectangle)(void *, int, int, int, int, int);
682+
void (*gdImageSetPixel)(void *, int, int, int);
683+
void *(*gdImagePngPtrEx)(void *, int *, int);
684+
void (*gdFree)(void *);
685+
void (*gdImageDestroy)(void *);
686+
676687
PyObject *eqs_to_sage_mat_helper(PyObject *self,
677688
PyObject *const *args,
678689
Py_ssize_t nargs) {
690+
if (!gdImageCreate) {
691+
// load gd library dynamically
692+
void *gd = dlopen("libgd.so", RTLD_LAZY);
693+
if (!gd) {
694+
PyErr_Format(PyExc_RuntimeError, "Failed to load libgd.so: %s",
695+
dlerror());
696+
return NULL;
697+
}
698+
gdImageCreate = dlsym(gd, "gdImageCreate");
699+
gdImageColorAllocate = dlsym(gd, "gdImageColorAllocate");
700+
gdImageFilledRectangle = dlsym(gd, "gdImageFilledRectangle");
701+
gdImageSetPixel = dlsym(gd, "gdImageSetPixel");
702+
gdImagePngPtrEx = dlsym(gd, "gdImagePngPtrEx");
703+
gdFree = dlsym(gd, "gdFree");
704+
gdImageDestroy = dlsym(gd, "gdImageDestroy");
705+
if (!gdImageCreate || !gdImageColorAllocate ||
706+
!gdImageFilledRectangle || !gdImageSetPixel || !gdImagePngPtrEx ||
707+
!gdFree || !gdImageDestroy) {
708+
PyErr_SetString(PyExc_RuntimeError,
709+
"Failed to load functions from libgd.so");
710+
return NULL;
711+
}
712+
}
679713
// see https://github.com/sagemath/sage/blob/7726cd9e1d01ad32b0f14374c9a4096989c87e14/src/sage/matrix/matrix_mod2_dense.pyx#L1764-L1808
680714
PyObject *linsys_list;
681715
Py_ssize_t cols;
@@ -701,7 +735,7 @@ PyObject *eqs_to_sage_mat_helper(PyObject *self,
701735
Py_ssize_t rows = PyList_GET_SIZE(linsys_list);
702736
PyObject *affine = PyList_New(rows);
703737

704-
gdImagePtr im = gdImageCreate(cols, rows);
738+
void *im = gdImageCreate(cols, rows);
705739
int black = gdImageColorAllocate(im, 0, 0, 0);
706740
int white = gdImageColorAllocate(im, 255, 255, 255);
707741
gdImageFilledRectangle(im, 0, 0, cols - 1, rows - 1, white);

gf2bv/_internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
#define PY_SSIZE_T_CLEAN
44
#include <Python.h>
5-
#include <gd.h>
65
#include <m4ri/m4ri.h>
76

87
typedef struct {

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def download_and_build_m4ri():
3131
return Extension(
3232
"gf2bv._internal",
3333
sources=["gf2bv/_internal.c"],
34-
libraries=["gomp", "gd"],
34+
libraries=["gomp"],
3535
extra_compile_args=["-O3", "-march=native", "-mtune=native"],
3636
include_dirs=[str(workdir)],
3737
extra_objects=[str(libm4ri_a)],
@@ -44,7 +44,7 @@ def download_and_build_m4ri():
4444
ext = Extension(
4545
"gf2bv._internal",
4646
sources=["gf2bv/_internal.c"],
47-
libraries=["m4ri", "gd"],
47+
libraries=["m4ri"],
4848
extra_compile_args=["-O3", "-march=native", "-mtune=native"],
4949
)
5050

0 commit comments

Comments
 (0)