diff --git a/Tests/test_file_jxl.py b/Tests/test_file_jxl.py index bd2b1f0bc..9b09371a9 100644 --- a/Tests/test_file_jxl.py +++ b/Tests/test_file_jxl.py @@ -4,7 +4,7 @@ import re import pytest -from PIL import Image, JxlImagePlugin, features +from PIL import Image, JpegXlImagePlugin, features from .helper import ( assert_image_similar_tofile, @@ -12,39 +12,38 @@ from .helper import ( ) try: - from PIL import _jxl + from PIL import _jpegxl - HAVE_JXL = True + HAVE_JPEGXL = True except ImportError: - HAVE_JXL = False + HAVE_JPEGXL = False # cjxl v0.9.2 41b8cdab # hopper.jxl: cjxl hopper.png hopper.jxl -q 75 -e 8 -class TestUnsupportedJxl: +class TestUnsupportedJpegXl: def test_unsupported(self) -> None: - if HAVE_JXL: - JxlImagePlugin.SUPPORTED = False + if HAVE_JPEGXL: + JpegXlImagePlugin.SUPPORTED = False file_path = "Tests/images/hopper.jxl" - with pytest.warns(UserWarning): - with pytest.raises(OSError): - with Image.open(file_path): - pass + with pytest.raises(OSError): + with Image.open(file_path): + pass - if HAVE_JXL: - JxlImagePlugin.SUPPORTED = True + if HAVE_JPEGXL: + JpegXlImagePlugin.SUPPORTED = True -@skip_unless_feature("jxl") -class TestFileJxl: +@skip_unless_feature("jpegxl") +class TestFileJpegXl: def setup_method(self) -> None: self.rgb_mode = "RGB" def test_version(self) -> None: - _jxl.JxlDecoderVersion() - assert re.search(r"\d+\.\d+\.\d+$", features.version_module("jxl")) + _jpegxl.JpegXlDecoderVersion() + assert re.search(r"\d+\.\d+\.\d+$", features.version_module("jpegxl")) def test_read_rgb(self) -> None: """ @@ -63,10 +62,10 @@ class TestFileJxl: # djxl hopper.jxl hopper_jxl_bits.ppm assert_image_similar_tofile(image, "Tests/images/hopper_jxl_bits.ppm", 1.0) - def test_JxlDecode_with_invalid_args(self) -> None: + def test_JpegXlDecode_with_invalid_args(self) -> None: """ Calling decoder functions with no arguments should result in an error. """ with pytest.raises(TypeError): - _jxl.PILJxlDecoder() + _jpegxl.PILJpegXlDecoder() diff --git a/Tests/test_file_jxl_alpha.py b/Tests/test_file_jxl_alpha.py index d3f950621..8c3ab2b71 100644 --- a/Tests/test_file_jxl_alpha.py +++ b/Tests/test_file_jxl_alpha.py @@ -6,7 +6,7 @@ from PIL import Image from .helper import assert_image_similar_tofile -_webp = pytest.importorskip("PIL._jxl", reason="JXL support not installed") +_jpegxl = pytest.importorskip("PIL._jpegxl", reason="JPEG XL support not installed") def test_read_rgba() -> None: diff --git a/Tests/test_file_jxl_animated.py b/Tests/test_file_jxl_animated.py index e39eabcb0..e00c27639 100644 --- a/Tests/test_file_jxl_animated.py +++ b/Tests/test_file_jxl_animated.py @@ -10,7 +10,7 @@ from .helper import ( ) pytestmark = [ - skip_unless_feature("jxl"), + skip_unless_feature("jpegxl"), ] diff --git a/Tests/test_file_jxl_metadata.py b/Tests/test_file_jxl_metadata.py index 7e4a02912..a7cd2c925 100644 --- a/Tests/test_file_jxl_metadata.py +++ b/Tests/test_file_jxl_metadata.py @@ -9,7 +9,7 @@ from PIL import Image from .helper import skip_unless_feature pytestmark = [ - skip_unless_feature("jxl"), + skip_unless_feature("jpegxl"), ] ElementTree: ModuleType | None diff --git a/Tests/test_jxl_leaks.py b/Tests/test_jxl_leaks.py index b8b0835cd..cec9f1528 100644 --- a/Tests/test_jxl_leaks.py +++ b/Tests/test_jxl_leaks.py @@ -9,8 +9,8 @@ from .helper import PillowLeakTestCase, skip_unless_feature TEST_FILE = "Tests/images/hopper.jxl" -@skip_unless_feature("jxl") -class TestJxlLeaks(PillowLeakTestCase): +@skip_unless_feature("jpegxl") +class TestJpegXlLeaks(PillowLeakTestCase): mem_limit = 6 * 1024 # kb iterations = 1000 diff --git a/setup.py b/setup.py index 7698339be..a5424f6c6 100644 --- a/setup.py +++ b/setup.py @@ -286,7 +286,7 @@ class pil_build_ext(build_ext): features = [ "zlib", "jpeg", - "jxl", + "jpegxl", "tiff", "freetype", "raqm", @@ -695,13 +695,13 @@ class pil_build_ext(build_ext): feature.jpeg2000 = "openjp2" feature.openjpeg_version = ".".join(str(x) for x in best_version) - if feature.want("jxl"): - _dbg("Looking for jxl") + if feature.want("jpegxl"): + _dbg("Looking for jpegxl") if _find_include_file(self, "jxl/encode.h") and _find_include_file( self, "jxl/decode.h" ): if _find_library_file(self, "jxl"): - feature.jxl = "jxl jxl_threads" + feature.jpegxl = "jxl jxl_threads" if feature.want("imagequant"): _dbg("Looking for imagequant") @@ -786,14 +786,14 @@ class pil_build_ext(build_ext): # alternate Windows name. feature.lcms = "lcms2_static" - if feature.jxl: + if feature.jpegxl: # jxl and jxl_threads are required - libs = feature.jxl.split() + libs = feature.jpegxl.split() defs = [] - self._update_extension("PIL._jxl", libs, defs) + self._update_extension("PIL._jpegxl", libs, defs) else: - self._remove_extension("PIL._jxl") + self._remove_extension("PIL._jpegxl") if feature.want("webp"): _dbg("Looking for webp") @@ -955,7 +955,7 @@ class pil_build_ext(build_ext): (feature.freetype, "FREETYPE2"), (feature.raqm, "RAQM (Text shaping)", raqm_extra_info), (feature.lcms, "LITTLECMS2"), - (feature.jxl, "JXL"), + (feature.jpegxl, "JPEG XL"), (feature.webp, "WEBP"), (feature.webpmux, "WEBPMUX"), (feature.xcb, "XCB (X protocol)"), @@ -1000,7 +1000,7 @@ ext_modules = [ Extension("PIL._imaging", files), Extension("PIL._imagingft", ["src/_imagingft.c"]), Extension("PIL._imagingcms", ["src/_imagingcms.c"]), - Extension("PIL._jxl", ["src/_jxl.c"]), + Extension("PIL._jpegxl", ["src/_jpegxl.c"]), Extension("PIL._webp", ["src/_webp.c"]), Extension("PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"]), Extension("PIL._imagingmath", ["src/_imagingmath.c"]), diff --git a/src/PIL/JxlImagePlugin.py b/src/PIL/JpegXlImagePlugin.py similarity index 94% rename from src/PIL/JxlImagePlugin.py rename to src/PIL/JpegXlImagePlugin.py index 80278ae33..d14a2099f 100644 --- a/src/PIL/JxlImagePlugin.py +++ b/src/PIL/JpegXlImagePlugin.py @@ -6,7 +6,7 @@ from io import BytesIO from . import Image, ImageFile try: - from . import _jxl + from . import _jpegxl SUPPORTED = True except ImportError: @@ -33,14 +33,14 @@ def _accept(prefix: bytes) -> bool: return is_jxl -class JxlImageFile(ImageFile.ImageFile): +class JpegXlImageFile(ImageFile.ImageFile): format = "JPEG XL" format_description = "JPEG XL image" __loaded = 0 __logical_frame = 0 def _open(self) -> None: - self._decoder = _jxl.PILJxlDecoder(self.fp.read()) + self._decoder = _jpegxl.PILJpegXlDecoder(self.fp.read()) width, height, mode, has_anim, tps_num, tps_denom, n_loops, n_frames = ( self._decoder.get_info() @@ -174,6 +174,6 @@ class JxlImageFile(ImageFile.ImageFile): return self.__logical_frame -Image.register_open(JxlImageFile.format, JxlImageFile, _accept) -Image.register_extension(JxlImageFile.format, ".jxl") -Image.register_mime(JxlImageFile.format, "image/jxl") +Image.register_open(JpegXlImageFile.format, JpegXlImageFile, _accept) +Image.register_extension(JpegXlImageFile.format, ".jxl") +Image.register_mime(JpegXlImageFile.format, "image/jxl") diff --git a/src/PIL/__init__.py b/src/PIL/__init__.py index 768315d3b..09ea0f457 100644 --- a/src/PIL/__init__.py +++ b/src/PIL/__init__.py @@ -47,7 +47,7 @@ _plugins = [ "IptcImagePlugin", "JpegImagePlugin", "Jpeg2KImagePlugin", - "JxlImagePlugin", + "JpegXlImagePlugin", "McIdasImagePlugin", "MicImagePlugin", "MpegImagePlugin", diff --git a/src/PIL/_jxl.pyi b/src/PIL/_jpegxl.pyi similarity index 100% rename from src/PIL/_jxl.pyi rename to src/PIL/_jpegxl.pyi diff --git a/src/PIL/features.py b/src/PIL/features.py index 028aa0974..179e126f7 100644 --- a/src/PIL/features.py +++ b/src/PIL/features.py @@ -14,7 +14,7 @@ modules = { "tkinter": ("PIL._tkinter_finder", "tk_version"), "freetype2": ("PIL._imagingft", "freetype2_version"), "littlecms2": ("PIL._imagingcms", "littlecms_version"), - "jxl": ("PIL._jxl", "libjxl_version"), + "jpegxl": ("PIL._jpegxl", "libjxl_version"), "webp": ("PIL._webp", "webpdecoder_version"), } @@ -269,7 +269,7 @@ def pilinfo(out=None, supported_formats=True): ("transp_webp", "WEBP Transparency"), ("webp_mux", "WEBPMUX"), ("webp_anim", "WEBP Animation"), - ("jxl", "JPEG XL"), + ("jpegxl", "JPEG XL"), ("jpg", "JPEG"), ("jpg_2000", "OPENJPEG (JPEG2000)"), ("zlib", "ZLIB (PNG/ZIP)"), diff --git a/src/_jxl.c b/src/_jpegxl.c similarity index 91% rename from src/_jxl.c rename to src/_jpegxl.c index cf2fba3ca..1905651c7 100644 --- a/src/_jxl.c +++ b/src/_jpegxl.c @@ -83,13 +83,13 @@ typedef struct { Py_ssize_t n_frames; char *mode; -} PILJxlDecoderObject; +} PILJpegXlDecoderObject; -static PyTypeObject PILJxlDecoder_Type; +static PyTypeObject PILJpegXlDecoder_Type; void _jxl_decoder_dealloc(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; if (decp->jxl_data) { free(decp->jxl_data); @@ -131,7 +131,7 @@ _jxl_decoder_dealloc(PyObject *self) { // sets input jxl bitstream loaded into jxl_data // has to be called after every rewind void _jxl_decoder_set_input(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; decp->status = JxlDecoderSetInput(decp->decoder, decp->jxl_data, decp->jxl_data_len); @@ -144,7 +144,7 @@ void _jxl_decoder_set_input(PyObject *self) { PyObject * _jxl_decoder_rewind(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; JxlDecoderRewind(decp->decoder); Py_RETURN_NONE; @@ -152,7 +152,7 @@ _jxl_decoder_rewind(PyObject *self) { bool _jxl_decoder_count_frames(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; decp->n_frames = 0; @@ -179,8 +179,8 @@ PyObject * _jxl_decoder_new(PyObject *self, PyObject *args) { PyBytesObject *jxl_string; - PILJxlDecoderObject *decp = NULL; - decp = PyObject_New(PILJxlDecoderObject, &PILJxlDecoder_Type); + PILJpegXlDecoderObject *decp = NULL; + decp = PyObject_New(PILJpegXlDecoderObject, &PILJpegXlDecoder_Type); decp->mode = NULL; decp->jxl_data = NULL; decp->jxl_data_len = 0; @@ -202,7 +202,7 @@ _jxl_decoder_new(PyObject *self, PyObject *args) { return NULL; } - // this data needs to be copied to PILJxlDecoderObject + // this data needs to be copied to PILJpegXlDecoderObject // so that input bitstream is preserved across calls const uint8_t *_tmp_jxl_data; Py_ssize_t _tmp_jxl_data_len; @@ -393,7 +393,7 @@ _jxl_decoder_new(PyObject *self, PyObject *args) { PyObject * _jxl_decoder_get_info(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; return Py_BuildValue( "IIsiIIII", @@ -411,7 +411,7 @@ _jxl_decoder_get_info(PyObject *self) { PyObject * _jxl_decoder_get_next(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; PyObject *bytes; PyObject *ret; JxlFrameHeader fhdr = {}; @@ -500,7 +500,7 @@ _jxl_decoder_get_next(PyObject *self) { PyObject * _jxl_decoder_get_icc(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; if (!decp->jxl_icc) Py_RETURN_NONE; @@ -509,7 +509,7 @@ _jxl_decoder_get_icc(PyObject *self) { PyObject * _jxl_decoder_get_exif(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; if (!decp->jxl_exif) Py_RETURN_NONE; @@ -518,15 +518,15 @@ _jxl_decoder_get_exif(PyObject *self) { PyObject * _jxl_decoder_get_xmp(PyObject *self) { - PILJxlDecoderObject *decp = (PILJxlDecoderObject *)self; + PILJpegXlDecoderObject *decp = (PILJpegXlDecoderObject *)self; if (!decp->jxl_xmp) Py_RETURN_NONE; return PyBytes_FromStringAndSize((const char *)decp->jxl_xmp, decp->jxl_xmp_len); } -// PILJxlDecoder methods -static struct PyMethodDef _jxl_decoder_methods[] = { +// PILJpegXlDecoder methods +static struct PyMethodDef _jpegxl_decoder_methods[] = { {"get_info", (PyCFunction)_jxl_decoder_get_info, METH_NOARGS, "get_info"}, {"get_next", (PyCFunction)_jxl_decoder_get_next, METH_NOARGS, "get_next"}, {"get_icc", (PyCFunction)_jxl_decoder_get_icc, METH_NOARGS, "get_icc"}, @@ -536,10 +536,10 @@ static struct PyMethodDef _jxl_decoder_methods[] = { {NULL, NULL} /* sentinel */ }; -// PILJxlDecoder type definition -static PyTypeObject PILJxlDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) "PILJxlDecoder", /*tp_name */ - sizeof(PILJxlDecoderObject), /*tp_basicsize */ +// PILJpegXlDecoder type definition +static PyTypeObject PILJpegXlDecoder_Type = { + PyVarObject_HEAD_INIT(NULL, 0) "PILJpegXlDecoder", /*tp_name */ + sizeof(PILJpegXlDecoderObject), /*tp_basicsize */ 0, /*tp_itemsize */ /* methods */ (destructor)_jxl_decoder_dealloc, /*tp_dealloc*/ @@ -565,7 +565,7 @@ static PyTypeObject PILJxlDecoder_Type = { 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ - _jxl_decoder_methods, /*tp_methods*/ + _jpegxl_decoder_methods, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ }; @@ -573,13 +573,13 @@ static PyTypeObject PILJxlDecoder_Type = { // Return libjxl decoder version available as integer: // MAJ*1_000_000 + MIN*1_000 + PATCH PyObject * -JxlDecoderVersion_wrapper() { +JpegXlDecoderVersion_wrapper() { return Py_BuildValue("i", JxlDecoderVersion()); } // Version as string const char * -JxlDecoderVersion_str(void) { +JpegXlDecoderVersion_str(void) { static char version[20]; int version_number = JxlDecoderVersion(); sprintf( @@ -592,22 +592,22 @@ JxlDecoderVersion_str(void) { return version; } -static PyMethodDef jxlMethods[] = { - {"JxlDecoderVersion", JxlDecoderVersion_wrapper, METH_NOARGS, "JxlVersion"}, - {"PILJxlDecoder", _jxl_decoder_new, METH_VARARGS, "PILJxlDecoder"}, +static PyMethodDef jpegxlMethods[] = { + {"JpegXlDecoderVersion", JpegXlDecoderVersion_wrapper, METH_NOARGS, "JpegXlVersion"}, + {"PILJpegXlDecoder", _jxl_decoder_new, METH_VARARGS, "PILJpegXlDecoder"}, {NULL, NULL} }; static int setup_module(PyObject *m) { - if (PyType_Ready(&PILJxlDecoder_Type) < 0) { + if (PyType_Ready(&PILJpegXlDecoder_Type) < 0) { return -1; } // TODO(oloke) ready object types? PyObject *d = PyModule_GetDict(m); - PyObject *v = PyUnicode_FromString(JxlDecoderVersion_str()); + PyObject *v = PyUnicode_FromString(JpegXlDecoderVersion_str()); PyDict_SetItemString(d, "libjxl_version", v ? v : Py_None); Py_XDECREF(v); @@ -615,15 +615,15 @@ setup_module(PyObject *m) { } PyMODINIT_FUNC -PyInit__jxl(void) { +PyInit__jpegxl(void) { PyObject *m; static PyModuleDef module_def = { PyModuleDef_HEAD_INIT, - "_jxl", /* m_name */ + "_jpegxl", /* m_name */ NULL, /* m_doc */ -1, /* m_size */ - jxlMethods, /* m_methods */ + jpegxlMethods, /* m_methods */ }; m = PyModule_Create(&module_def);