add 16-bits grayscale support for jpeg xl images

This commit is contained in:
olokelo 2024-05-18 23:58:12 +02:00
parent 0b71605dbf
commit 1f00fb8eef
4 changed files with 24 additions and 1 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -20,6 +20,7 @@ except ImportError:
# 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 @@ class TestUnsupportedJpegXl:
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 @@ class TestFileJpegXl:
# 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.

View File

@ -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");