From b362cad84ae45712c7cb717e7aff4be5b8cbd490 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 18 Jul 2022 19:59:13 +1000 Subject: [PATCH 1/2] Connect to BC6 decoding from Python --- src/PIL/DdsImagePlugin.py | 5 +++++ src/decode.c | 5 +---- src/libImaging/BcnDecode.c | 22 +++++++++------------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index 3a04bdb5d66..c24b5b72a49 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -101,6 +101,7 @@ DXGI_FORMAT_BC5_TYPELESS = 82 DXGI_FORMAT_BC5_UNORM = 83 DXGI_FORMAT_BC5_SNORM = 84 +DXGI_FORMAT_BC6H_UF16 = 95 DXGI_FORMAT_BC7_TYPELESS = 97 DXGI_FORMAT_BC7_UNORM = 98 DXGI_FORMAT_BC7_UNORM_SRGB = 99 @@ -173,6 +174,10 @@ def _open(self): self.pixel_format = "BC5S" n = 5 self.mode = "RGB" + elif dxgi_format == DXGI_FORMAT_BC6H_UF16: + self.pixel_format = "BC6" + n = 6 + self.mode = "RGB" elif dxgi_format in (DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM): self.pixel_format = "BC7" n = 7 diff --git a/src/decode.c b/src/decode.c index cb018a4e706..7a9b956c559 100644 --- a/src/decode.c +++ b/src/decode.c @@ -376,11 +376,8 @@ PyImaging_BcnDecoderNew(PyObject *self, PyObject *args) { actual = "L"; break; case 5: /* BC5: 2-channel 8-bit via 2 BC3 alpha blocks */ - actual = "RGB"; - break; case 6: /* BC6: 3-channel 16-bit float */ - /* TODO: support 4-channel floating point images */ - actual = "RGBAF"; + actual = "RGB"; break; default: PyErr_SetString(PyExc_ValueError, "block compression type unknown"); diff --git a/src/libImaging/BcnDecode.c b/src/libImaging/BcnDecode.c index 9e830cf072c..05fddfb629f 100644 --- a/src/libImaging/BcnDecode.c +++ b/src/libImaging/BcnDecode.c @@ -23,10 +23,6 @@ typedef struct { UINT8 l; } lum; -typedef struct { - FLOAT32 r, g, b; -} rgb32f; - typedef struct { UINT16 c0, c1; UINT32 lut; @@ -667,22 +663,22 @@ half_to_float(UINT16 h) { return o.f; } -static float +static UINT8 bc6_finalize(int v, int sign) { if (sign) { if (v < 0) { v = ((-v) * 31) / 32; - return half_to_float((UINT16)(0x8000 | v)); + return (UINT8)half_to_float((UINT16)(0x8000 | v)); } else { - return half_to_float((UINT16)((v * 31) / 32)); + return (UINT8)half_to_float((UINT16)((v * 31) / 32)); } } else { - return half_to_float((UINT16)((v * 31) / 64)); + return (UINT8)half_to_float((UINT16)((v * 31) / 64)); } } static void -bc6_lerp(rgb32f *col, int *e0, int *e1, int s, int sign) { +bc6_lerp(rgba *col, int *e0, int *e1, int s, int sign) { int r, g, b; int t = 64 - s; r = (e0[0] * t + e1[0] * s) >> 6; @@ -694,7 +690,7 @@ bc6_lerp(rgb32f *col, int *e0, int *e1, int s, int sign) { } static void -decode_bc6_block(rgb32f *col, const UINT8 *src, int sign) { +decode_bc6_block(rgba *col, const UINT8 *src, int sign) { UINT16 endpoints[12]; /* storage for r0, g0, b0, r1, ... */ int ueps[12]; int i, i0, ib2, di, dw, mask, numep, s; @@ -744,7 +740,7 @@ decode_bc6_block(rgb32f *col, const UINT8 *src, int sign) { } if (sign || info->tr) { /* sign-extend e1,2,3 if signed or deltas */ for (i = 3; i < numep; i += 3) { - bc6_sign_extend(&endpoints[i + 0], info->rb); + bc6_sign_extend(&endpoints[i], info->rb); bc6_sign_extend(&endpoints[i + 1], info->gb); bc6_sign_extend(&endpoints[i + 2], info->bb); } @@ -757,7 +753,7 @@ decode_bc6_block(rgb32f *col, const UINT8 *src, int sign) { } if (sign) { for (i = 3; i < numep; i += 3) { - bc6_sign_extend(&endpoints[i + 0], info->rb); + bc6_sign_extend(&endpoints[i], info->rb); bc6_sign_extend(&endpoints[i + 1], info->gb); bc6_sign_extend(&endpoints[i + 2], info->bb); } @@ -864,7 +860,7 @@ decode_bcn( break; case 6: while (bytes >= 16) { - rgb32f col[16]; + rgba col[16]; decode_bc6_block(col, ptr, (state->state >> 4) & 1); put_block(im, state, (const char *)col, sizeof(col[0]), C); ptr += 16; From 074afdbe0ba5d1adb260289c61f13209bd1a0c22 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 18 Jul 2022 18:56:36 +1000 Subject: [PATCH 2/2] UF16 is not FP16 --- src/libImaging/BcnDecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libImaging/BcnDecode.c b/src/libImaging/BcnDecode.c index 05fddfb629f..b0364f5d519 100644 --- a/src/libImaging/BcnDecode.c +++ b/src/libImaging/BcnDecode.c @@ -673,7 +673,7 @@ bc6_finalize(int v, int sign) { return (UINT8)half_to_float((UINT16)((v * 31) / 32)); } } else { - return (UINT8)half_to_float((UINT16)((v * 31) / 64)); + return v >> 8; } }