From 6b781a623bbc0a2d211facda1bd83d27fda2d509 Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Sun, 14 Aug 2022 16:21:46 +0300 Subject: [PATCH] Add raw encoders/decoders for 2 channel RG format --- Tests/test_file_vtf.py | 10 +++++----- src/PIL/VtfImagePlugin.py | 11 ++--------- src/libImaging/Pack.c | 15 ++++++++++++++- src/libImaging/Unpack.c | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/Tests/test_file_vtf.py b/Tests/test_file_vtf.py index f857ba2c0..d466cb725 100644 --- a/Tests/test_file_vtf.py +++ b/Tests/test_file_vtf.py @@ -74,14 +74,14 @@ def test_get_texture_size( ("Tests/images/vtf_i8.png", "Tests/images/vtf_i8.vtf", "L", 0.0), ("Tests/images/vtf_a8.png", "Tests/images/vtf_a8.vtf", "L", 0.0), ("Tests/images/vtf_ia88.png", "Tests/images/vtf_ia88.vtf", "LA", 0.0), - # ( - # "Tests/images/vtf_RG.png", - # "Tests/images/vtf_RG.vtf", "RGB", - # 0.0), + ( + "Tests/images/vtf_uv88.png", + "Tests/images/vtf_uv88.vtf", "RGB", + 0.0), ("Tests/images/vtf_rgb888.png", "Tests/images/vtf_rgb888.vtf", "RGB", 0.0), ("Tests/images/vtf_bgr888.png", "Tests/images/vtf_bgr888.vtf", "RGB", 0.0), ("Tests/images/vtf_dxt1.png", "Tests/images/vtf_dxt1.vtf", "RGBA", 3.0), - ("Tests/images/vtf_rgba8888.png", "Tests/images/vtf_rgba8888.vtf", "RGBA", 0.1), + ("Tests/images/vtf_rgba8888.png", "Tests/images/vtf_rgba8888.vtf", "RGBA", 0), ], ) def test_vtf_loading( diff --git a/src/PIL/VtfImagePlugin.py b/src/PIL/VtfImagePlugin.py index b6ecd6281..ba7e57260 100644 --- a/src/PIL/VtfImagePlugin.py +++ b/src/PIL/VtfImagePlugin.py @@ -230,14 +230,7 @@ def _write_image(fp: BufferedIOBase, im: Image.Image, pixel_format: VtfPF): im = im.convert("LA") elif pixel_format == VtfPF.UV88: encoder = "raw" - if im.mode == "RGB" or im.mode == "RGBA": - r, g, *_ = im.split() - im = Image.merge("LA", (r, g)) - elif im.mode == "LA": - pass - else: - raise VTFException(f"Cannot encode {im.mode} as {pixel_format}") - encoder_args = ("LA", 0, 0) + encoder_args = ("RG", 0, 0) else: raise VTFException(f"Unsupported pixel format: {pixel_format!r}") @@ -327,7 +320,7 @@ class VtfImageFile(ImageFile.ImageFile): elif pixel_format in (VtfPF.BGRA8888,): tile = ("raw", (0, 0) + self.size, data_start, ("BGRA", 0, 1)) elif pixel_format in (VtfPF.UV88,): - tile = ("raw", (0, 0) + self.size, data_start, ("LA", 0, 1)) + tile = ("raw", (0, 0) + self.size, data_start, ("RG", 0, 1)) elif pixel_format in L_FORMATS: tile = ("raw", (0, 0) + self.size, data_start, ("L", 0, 1)) elif pixel_format in LA_FORMATS: diff --git a/src/libImaging/Pack.c b/src/libImaging/Pack.c index 01760e742..1fef6435f 100644 --- a/src/libImaging/Pack.c +++ b/src/libImaging/Pack.c @@ -242,6 +242,17 @@ packLA(UINT8 *out, const UINT8 *in, int pixels) { in += 4; } } +static void +packRG(UINT8 *out, const UINT8 *in, int pixels) { + int i; + /* LA, pixel interleaved */ + for (i = 0; i < pixels; i++) { + out[0] = in[R]; + out[1] = in[G]; + out += 2; + in += 4; + } +} static void packLAL(UINT8 *out, const UINT8 *in, int pixels) { @@ -491,7 +502,7 @@ copy3(UINT8 *out, const UINT8 *in, int pixels) { static void copy4(UINT8 *out, const UINT8 *in, int pixels) { /* RGBA, CMYK quadruples */ - memcpy(out, in, 4 * pixels); + memcpy(out, in, pixels * 4); } static void @@ -580,6 +591,7 @@ static struct { {"RGB", "BGRX", 32, ImagingPackBGRX}, {"RGB", "XBGR", 32, ImagingPackXBGR}, {"RGB", "RGB;L", 24, packRGBL}, + {"RGB", "RG", 16, packRG}, {"RGB", "R", 8, band0}, {"RGB", "G", 8, band1}, {"RGB", "B", 8, band2}, @@ -592,6 +604,7 @@ static struct { {"RGBA", "BGRA", 32, ImagingPackBGRA}, {"RGBA", "ABGR", 32, ImagingPackABGR}, {"RGBA", "BGRa", 32, ImagingPackBGRa}, + {"RGBA", "RG", 16, packRG}, {"RGBA", "R", 8, band0}, {"RGBA", "G", 8, band1}, {"RGBA", "B", 8, band2}, diff --git a/src/libImaging/Unpack.c b/src/libImaging/Unpack.c index e426ed74f..6d97c2f19 100644 --- a/src/libImaging/Unpack.c +++ b/src/libImaging/Unpack.c @@ -424,6 +424,18 @@ unpackLA(UINT8 *_out, const UINT8 *in, int pixels) { } } +static void +unpackRG(UINT8 *_out, const UINT8 *in, int pixels) { + int i; + /* LA, pixel interleaved */ + for (i = 0; i < pixels; i++) { + _out[R] = in[0]; + _out[G] = in[1]; + in += 2; + _out += 4; + } +} + static void unpackLAL(UINT8 *_out, const UINT8 *in, int pixels) { int i; @@ -1547,6 +1559,9 @@ static struct { {"PA", "PA", 16, unpackLA}, {"PA", "PA;L", 16, unpackLAL}, + /*2 channel to RGB/RGBA*/ + {"RGB", "RG", 16, unpackRG}, + {"RGBA", "RG", 16, unpackRG}, /* true colour */ {"RGB", "RGB", 24, ImagingUnpackRGB}, {"RGB", "RGB;L", 24, unpackRGBL},