Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/releasenotes/11.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,10 @@ others prepare for 3.13, and to ensure Pillow could be used immediately at the r
of 3.13.0 final (2024-10-01, :pep:`719`).

Pillow 11.0.0 now officially supports Python 3.13.

C-level Flags
^^^^^^^^^^^^^

Some compiling flags like ``WITH_THREADING``, ``WITH_IMAGECHOPS``, and other
``WITH_*`` were removed. These flags were not available through the build system,
but they could be edited in the C source.
104 changes: 11 additions & 93 deletions src/_imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,6 @@
#define _USE_MATH_DEFINES
#include <math.h>

/* Configuration stuff. Feel free to undef things you don't need. */
#define WITH_IMAGECHOPS /* ImageChops support */
#define WITH_IMAGEDRAW /* ImageDraw support */
#define WITH_MAPPING /* use memory mapping to read some file formats */
#define WITH_IMAGEPATH /* ImagePath stuff */
#define WITH_ARROW /* arrow graphics stuff (experimental) */
#define WITH_EFFECTS /* special effects */
#define WITH_QUANTIZE /* quantization support */
#define WITH_RANKFILTER /* rank filter */
#define WITH_MODEFILTER /* mode filter */
#define WITH_THREADING /* "friendly" threading support */
#define WITH_UNSHARPMASK /* Kevin Cazabon's unsharpmask module */

#undef VERBOSE

#define B16(p, i) ((((int)p[(i)]) << 8) + p[(i) + 1])
Expand All @@ -123,8 +110,6 @@ typedef struct {

static PyTypeObject Imaging_Type;

#ifdef WITH_IMAGEDRAW

typedef struct {
/* to write a character, cut out sxy from glyph data, place
at current position plus dxy, and advance by (dx, dy) */
Expand All @@ -151,8 +136,6 @@ typedef struct {

static PyTypeObject ImagingDraw_Type;

#endif

typedef struct {
PyObject_HEAD ImagingObject *image;
int readonly;
Expand Down Expand Up @@ -215,16 +198,12 @@ PyImaging_AsImaging(PyObject *op) {

void
ImagingSectionEnter(ImagingSectionCookie *cookie) {
#ifdef WITH_THREADING
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to measure performance penalty for saving state.

Empty function call:

In [2]: %timeit Image.core.test_threading()
64.1 ns ± 0.842 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

With ImagingSectionEnter/ImagingSectionLeave:

In [6]: %timeit Image.core.test_threading()
109 ns ± 0.951 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

*cookie = (PyThreadState *)PyEval_SaveThread();
#endif
}

void
ImagingSectionLeave(ImagingSectionCookie *cookie) {
#ifdef WITH_THREADING
PyEval_RestoreThread((PyThreadState *)*cookie);
#endif
}

/* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -1091,7 +1070,6 @@ _filter(ImagingObject *self, PyObject *args) {
return imOut;
}

#ifdef WITH_UNSHARPMASK
static PyObject *
_gaussian_blur(ImagingObject *self, PyObject *args) {
Imaging imIn;
Expand All @@ -1116,7 +1094,6 @@ _gaussian_blur(ImagingObject *self, PyObject *args) {

return PyImagingNew(imOut);
}
#endif

static PyObject *
_getpalette(ImagingObject *self, PyObject *args) {
Expand Down Expand Up @@ -1374,7 +1351,6 @@ _entropy(ImagingObject *self, PyObject *args) {
return PyFloat_FromDouble(-entropy);
}

#ifdef WITH_MODEFILTER
static PyObject *
_modefilter(ImagingObject *self, PyObject *args) {
int size;
Expand All @@ -1384,7 +1360,6 @@ _modefilter(ImagingObject *self, PyObject *args) {

return PyImagingNew(ImagingModeFilter(self->image, size));
}
#endif

static PyObject *
_offset(ImagingObject *self, PyObject *args) {
Expand Down Expand Up @@ -1716,8 +1691,6 @@ _putdata(ImagingObject *self, PyObject *args) {
return Py_None;
}

#ifdef WITH_QUANTIZE

static PyObject *
_quantize(ImagingObject *self, PyObject *args) {
int colours = 256;
Expand All @@ -1734,7 +1707,6 @@ _quantize(ImagingObject *self, PyObject *args) {

return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans));
}
#endif

static PyObject *
_putpalette(ImagingObject *self, PyObject *args) {
Expand Down Expand Up @@ -1870,7 +1842,6 @@ _putpixel(ImagingObject *self, PyObject *args) {
return Py_None;
}

#ifdef WITH_RANKFILTER
static PyObject *
_rankfilter(ImagingObject *self, PyObject *args) {
int size, rank;
Expand All @@ -1880,7 +1851,6 @@ _rankfilter(ImagingObject *self, PyObject *args) {

return PyImagingNew(ImagingRankFilter(self->image, size, rank));
}
#endif

static PyObject *
_resize(ImagingObject *self, PyObject *args) {
Expand Down Expand Up @@ -2162,7 +2132,6 @@ _transpose(ImagingObject *self, PyObject *args) {
return PyImagingNew(imOut);
}

#ifdef WITH_UNSHARPMASK
static PyObject *
_unsharp_mask(ImagingObject *self, PyObject *args) {
Imaging imIn;
Expand All @@ -2186,7 +2155,6 @@ _unsharp_mask(ImagingObject *self, PyObject *args) {

return PyImagingNew(imOut);
}
#endif

static PyObject *
_box_blur(ImagingObject *self, PyObject *args) {
Expand Down Expand Up @@ -2463,9 +2431,7 @@ _split(ImagingObject *self) {
return list;
}

/* -------------------------------------------------------------------- */

#ifdef WITH_IMAGECHOPS
/* Channel operations (ImageChops) ------------------------------------ */

static PyObject *
_chop_invert(ImagingObject *self) {
Expand Down Expand Up @@ -2646,11 +2612,8 @@ _chop_overlay(ImagingObject *self, PyObject *args) {

return PyImagingNew(ImagingOverlay(self->image, imagep->image));
}
#endif

/* -------------------------------------------------------------------- */

#ifdef WITH_IMAGEDRAW
/* Fonts (ImageDraw and ImageFont) ------------------------------------ */

static PyObject *
_font_new(PyObject *self_, PyObject *args) {
Expand Down Expand Up @@ -2879,7 +2842,7 @@ static struct PyMethodDef _font_methods[] = {
{NULL, NULL} /* sentinel */
};

/* -------------------------------------------------------------------- */
/* Graphics (ImageDraw) ----------------------------------------------- */

static PyObject *
_draw_new(PyObject *self_, PyObject *args) {
Expand Down Expand Up @@ -3233,8 +3196,6 @@ _draw_points(ImagingDrawObject *self, PyObject *args) {
return Py_None;
}

#ifdef WITH_ARROW

/* from outline.c */
extern ImagingOutline
PyOutline_AsOutline(PyObject *outline);
Expand Down Expand Up @@ -3264,8 +3225,6 @@ _draw_outline(ImagingDrawObject *self, PyObject *args) {
return Py_None;
}

#endif

static PyObject *
_draw_pieslice(ImagingDrawObject *self, PyObject *args) {
double *xy;
Expand Down Expand Up @@ -3431,12 +3390,9 @@ _draw_rectangle(ImagingDrawObject *self, PyObject *args) {
}

static struct PyMethodDef _draw_methods[] = {
#ifdef WITH_IMAGEDRAW
/* Graphics (ImageDraw) */
{"draw_lines", (PyCFunction)_draw_lines, METH_VARARGS},
#ifdef WITH_ARROW
{"draw_outline", (PyCFunction)_draw_outline, METH_VARARGS},
#endif
{"draw_polygon", (PyCFunction)_draw_polygon, METH_VARARGS},
{"draw_rectangle", (PyCFunction)_draw_rectangle, METH_VARARGS},
{"draw_points", (PyCFunction)_draw_points, METH_VARARGS},
Expand All @@ -3446,12 +3402,9 @@ static struct PyMethodDef _draw_methods[] = {
{"draw_ellipse", (PyCFunction)_draw_ellipse, METH_VARARGS},
{"draw_pieslice", (PyCFunction)_draw_pieslice, METH_VARARGS},
{"draw_ink", (PyCFunction)_draw_ink, METH_VARARGS},
#endif
{NULL, NULL} /* sentinel */
};

#endif

static PyObject *
pixel_access_new(ImagingObject *imagep, PyObject *args) {
PixelAccessObject *self;
Expand Down Expand Up @@ -3532,11 +3485,9 @@ pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color) {
}

/* -------------------------------------------------------------------- */
/* EFFECTS (experimental) */
/* EFFECTS (experimental) */
/* -------------------------------------------------------------------- */

#ifdef WITH_EFFECTS

static PyObject *
_effect_mandelbrot(ImagingObject *self, PyObject *args) {
int xsize = 512;
Expand Down Expand Up @@ -3588,8 +3539,6 @@ _effect_spread(ImagingObject *self, PyObject *args) {
return PyImagingNew(ImagingEffectSpread(self->image, dist));
}

#endif

/* -------------------------------------------------------------------- */
/* UTILITIES */
/* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -3670,20 +3619,14 @@ static struct PyMethodDef methods[] = {
{"filter", (PyCFunction)_filter, METH_VARARGS},
{"histogram", (PyCFunction)_histogram, METH_VARARGS},
{"entropy", (PyCFunction)_entropy, METH_VARARGS},
#ifdef WITH_MODEFILTER
{"modefilter", (PyCFunction)_modefilter, METH_VARARGS},
#endif
{"offset", (PyCFunction)_offset, METH_VARARGS},
{"paste", (PyCFunction)_paste, METH_VARARGS},
{"point", (PyCFunction)_point, METH_VARARGS},
{"point_transform", (PyCFunction)_point_transform, METH_VARARGS},
{"putdata", (PyCFunction)_putdata, METH_VARARGS},
#ifdef WITH_QUANTIZE
{"quantize", (PyCFunction)_quantize, METH_VARARGS},
#endif
#ifdef WITH_RANKFILTER
{"rankfilter", (PyCFunction)_rankfilter, METH_VARARGS},
#endif
{"resize", (PyCFunction)_resize, METH_VARARGS},
{"reduce", (PyCFunction)_reduce, METH_VARARGS},
{"transpose", (PyCFunction)_transpose, METH_VARARGS},
Expand All @@ -3709,7 +3652,6 @@ static struct PyMethodDef methods[] = {
{"putpalettealpha", (PyCFunction)_putpalettealpha, METH_VARARGS},
{"putpalettealphas", (PyCFunction)_putpalettealphas, METH_VARARGS},

#ifdef WITH_IMAGECHOPS
/* Channel operations (ImageChops) */
{"chop_invert", (PyCFunction)_chop_invert, METH_NOARGS},
{"chop_lighter", (PyCFunction)_chop_lighter, METH_VARARGS},
Expand All @@ -3728,20 +3670,14 @@ static struct PyMethodDef methods[] = {
{"chop_hard_light", (PyCFunction)_chop_hard_light, METH_VARARGS},
{"chop_overlay", (PyCFunction)_chop_overlay, METH_VARARGS},

#endif

#ifdef WITH_UNSHARPMASK
/* Kevin Cazabon's unsharpmask extension */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for clarity - you're removing 'Kevin Cazabon' presumably because the code has been modified over time?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the reason were due to modifications over time, I would have included additional names accordingly. The actual reason is that I was unsure of the specific value this information provides in the comments. However, if this is important, I can revert the change.

/* Unsharpmask extension */
{"gaussian_blur", (PyCFunction)_gaussian_blur, METH_VARARGS},
{"unsharp_mask", (PyCFunction)_unsharp_mask, METH_VARARGS},
#endif

{"box_blur", (PyCFunction)_box_blur, METH_VARARGS},

#ifdef WITH_EFFECTS
/* Special effects */
{"effect_spread", (PyCFunction)_effect_spread, METH_VARARGS},
#endif

/* Misc. */
{"new_block", (PyCFunction)_new_block, METH_VARARGS},
Expand Down Expand Up @@ -3870,8 +3806,6 @@ static PyTypeObject Imaging_Type = {
getsetters, /*tp_getset*/
};

#ifdef WITH_IMAGEDRAW

static PyTypeObject ImagingFont_Type = {
PyVarObject_HEAD_INIT(NULL, 0) "ImagingFont", /*tp_name*/
sizeof(ImagingFontObject), /*tp_basicsize*/
Expand Down Expand Up @@ -3938,8 +3872,6 @@ static PyTypeObject ImagingDraw_Type = {
0, /*tp_getset*/
};

#endif

static PyMappingMethods pixel_access_as_mapping = {
(lenfunc)NULL, /*mp_length*/
(binaryfunc)pixel_access_getitem, /*mp_subscript*/
Expand Down Expand Up @@ -4282,13 +4214,11 @@ static PyMethodDef functions[] = {
{"zip_encoder", (PyCFunction)PyImaging_ZipEncoderNew, METH_VARARGS},
#endif

/* Memory mapping */
#ifdef WITH_MAPPING
/* Memory mapping */
{"map_buffer", (PyCFunction)PyImaging_MapBuffer, METH_VARARGS},
#endif

/* Display support */
#ifdef _WIN32
/* Display support */
{"display", (PyCFunction)PyImaging_DisplayWin32, METH_VARARGS},
{"display_mode", (PyCFunction)PyImaging_DisplayModeWin32, METH_VARARGS},
{"grabscreen_win32", (PyCFunction)PyImaging_GrabScreenWin32, METH_VARARGS},
Expand All @@ -4304,30 +4234,22 @@ static PyMethodDef functions[] = {
/* Utilities */
{"getcodecstatus", (PyCFunction)_getcodecstatus, METH_VARARGS},

/* Special effects (experimental) */
#ifdef WITH_EFFECTS
/* Special effects (experimental) */
{"effect_mandelbrot", (PyCFunction)_effect_mandelbrot, METH_VARARGS},
{"effect_noise", (PyCFunction)_effect_noise, METH_VARARGS},
{"linear_gradient", (PyCFunction)_linear_gradient, METH_VARARGS},
{"radial_gradient", (PyCFunction)_radial_gradient, METH_VARARGS},
{"wedge", (PyCFunction)_linear_gradient, METH_VARARGS}, /* Compatibility */
#endif

/* Drawing support stuff */
#ifdef WITH_IMAGEDRAW
/* Drawing support stuff */
{"font", (PyCFunction)_font_new, METH_VARARGS},
{"draw", (PyCFunction)_draw_new, METH_VARARGS},
#endif

/* Experimental path stuff */
#ifdef WITH_IMAGEPATH
/* Experimental path stuff */
{"path", (PyCFunction)PyPath_Create, METH_VARARGS},
#endif

/* Experimental arrow graphics stuff */
#ifdef WITH_ARROW
/* Experimental arrow graphics stuff */
{"outline", (PyCFunction)PyOutline_Create, METH_VARARGS},
#endif

/* Resource management */
{"get_stats", (PyCFunction)_get_stats, METH_VARARGS},
Expand All @@ -4352,16 +4274,12 @@ setup_module(PyObject *m) {
if (PyType_Ready(&Imaging_Type) < 0) {
return -1;
}

#ifdef WITH_IMAGEDRAW
if (PyType_Ready(&ImagingFont_Type) < 0) {
return -1;
}

if (PyType_Ready(&ImagingDraw_Type) < 0) {
return -1;
}
#endif
if (PyType_Ready(&PixelAccess_Type) < 0) {
return -1;
}
Expand Down
Loading