From 1f00fb8eefda7cbcddc051026f25ae34f9afaff4 Mon Sep 17 00:00:00 2001 From: olokelo Date: Sat, 18 May 2024 23:58:12 +0200 Subject: [PATCH] add 16-bits grayscale support for jpeg xl images --- Tests/images/jxl/16bit_subcutaneous.cropped.jxl | Bin 0 -> 9275 bytes Tests/images/jxl/16bit_subcutaneous.cropped.png | Bin 0 -> 12298 bytes Tests/test_file_jxl.py | 16 ++++++++++++++++ src/_jpegxl.c | 9 ++++++++- 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 Tests/images/jxl/16bit_subcutaneous.cropped.jxl create mode 100644 Tests/images/jxl/16bit_subcutaneous.cropped.png diff --git a/Tests/images/jxl/16bit_subcutaneous.cropped.jxl b/Tests/images/jxl/16bit_subcutaneous.cropped.jxl new file mode 100644 index 0000000000000000000000000000000000000000..eae30759603bfbce6bfcb48ee203f85f9c41dc84 GIT binary patch literal 9275 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�vb%nHJv-hC!%S*~*_^L=Z@<+=M89F$Z!;Awpky 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 literal 0 HcmV?d00001 diff --git a/Tests/test_file_jxl.py b/Tests/test_file_jxl.py index 9b09371a998..f6173a57e80 100644 --- a/Tests/test_file_jxl.py +++ b/Tests/test_file_jxl.py @@ -20,6 +20,7 @@ # cjxl v0.9.2 41b8cdab # hopper.jxl: cjxl hopper.png hopper.jxl -q 75 -e 8 +# 16_bit_binary.jxl: cjxl 16_bit_binary.pgm 16_bit_binary.jxl -q 100 -e 9 class TestUnsupportedJpegXl: @@ -40,6 +41,7 @@ def test_unsupported(self) -> None: class TestFileJpegXl: def setup_method(self) -> None: self.rgb_mode = "RGB" + self.i16_mode = "I;16" def test_version(self) -> None: _jpegxl.JpegXlDecoderVersion() @@ -62,6 +64,20 @@ def test_read_rgb(self) -> None: # djxl hopper.jxl hopper_jxl_bits.ppm assert_image_similar_tofile(image, "Tests/images/hopper_jxl_bits.ppm", 1.0) + def test_read_i16(self) -> None: + """ + Can we read 16-bit Grayscale Jpeg XL image? + """ + + with Image.open("Tests/images/jxl/16bit_subcutaneous.cropped.jxl") as image: + assert image.mode == self.i16_mode + assert image.size == (128, 64) + assert image.format == "JPEG XL" + image.load() + image.getdata() + + assert_image_similar_tofile(image, "Tests/images/jxl/16bit_subcutaneous.cropped.png", 1.0) + def test_JpegXlDecode_with_invalid_args(self) -> None: """ Calling decoder functions with no arguments should result in an error. diff --git a/src/_jpegxl.c b/src/_jpegxl.c index 1905651c77f..471aa17ed7a 100644 --- a/src/_jpegxl.c +++ b/src/_jpegxl.c @@ -33,6 +33,11 @@ void _pil_jxl_get_pixel_format(JxlPixelFormat *pf, const JxlBasicInfo *bi) { // TODO: floating point mode char* _pil_jxl_get_mode(const JxlBasicInfo *bi) { + // 16-bit single channel images are supported + if (bi->bits_per_sample == 16 && bi->num_color_channels == 1 && + bi->alpha_bits == 0 && !bi->alpha_premultiplied + ) return "I;16"; + // PIL doesn't support high bit depth images // it will throw an exception but that's for your own good // you wouldn't want to see distorted image @@ -261,7 +266,9 @@ _jxl_decoder_new(PyObject *self, PyObject *args) { _PIL_JXL_CHECK("JxlDecoderGetBasicInfo"); _pil_jxl_get_pixel_format(&decp->pixel_format, &decp->basic_info); - if (decp->pixel_format.data_type != JXL_TYPE_UINT8) { + if (decp->pixel_format.data_type != JXL_TYPE_UINT8 && + decp->pixel_format.data_type != JXL_TYPE_UINT16) { + // only 8 bit integer value images are supported for now PyErr_SetString(PyExc_NotImplementedError, "unsupported pixel data type");