mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 17:36:18 +03:00
commit
28878c68e1
BIN
Tests/images/bc6h.dds
Normal file
BIN
Tests/images/bc6h.dds
Normal file
Binary file not shown.
BIN
Tests/images/bc6h.png
Normal file
BIN
Tests/images/bc6h.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
Tests/images/bc6h_sf.dds
Normal file
BIN
Tests/images/bc6h_sf.dds
Normal file
Binary file not shown.
BIN
Tests/images/bc6h_sf.png
Normal file
BIN
Tests/images/bc6h_sf.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
@ -16,6 +16,8 @@ TEST_FILE_DX10_BC5_TYPELESS = "Tests/images/bc5_typeless.dds"
|
|||
TEST_FILE_DX10_BC5_UNORM = "Tests/images/bc5_unorm.dds"
|
||||
TEST_FILE_DX10_BC5_SNORM = "Tests/images/bc5_snorm.dds"
|
||||
TEST_FILE_BC5S = "Tests/images/bc5s.dds"
|
||||
TEST_FILE_BC6H = "Tests/images/bc6h.dds"
|
||||
TEST_FILE_BC6HS = "Tests/images/bc6h_sf.dds"
|
||||
TEST_FILE_DX10_BC7 = "Tests/images/bc7-argb-8bpp_MipMaps-1.dds"
|
||||
TEST_FILE_DX10_BC7_UNORM_SRGB = "Tests/images/DXGI_FORMAT_BC7_UNORM_SRGB.dds"
|
||||
TEST_FILE_DX10_R8G8B8A8 = "Tests/images/argb-32bpp_MipMaps-1.dds"
|
||||
|
@ -114,6 +116,20 @@ def test_dx10_bc5(image_path, expected_path):
|
|||
assert_image_equal_tofile(im, expected_path.replace(".dds", ".png"))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("image_path", (TEST_FILE_BC6H, TEST_FILE_BC6HS))
|
||||
def test_dx10_bc6h(image_path):
|
||||
"""Check DX10 BC6H/BC6HS images can be opened"""
|
||||
|
||||
with Image.open(image_path) as im:
|
||||
im.load()
|
||||
|
||||
assert im.format == "DDS"
|
||||
assert im.mode == "RGB"
|
||||
assert im.size == (128, 128)
|
||||
|
||||
assert_image_equal_tofile(im, image_path.replace(".dds", ".png"))
|
||||
|
||||
|
||||
def test_dx10_bc7():
|
||||
"""Check DX10 images can be opened"""
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29
|
|||
DXGI_FORMAT_BC5_TYPELESS = 82
|
||||
DXGI_FORMAT_BC5_UNORM = 83
|
||||
DXGI_FORMAT_BC5_SNORM = 84
|
||||
DXGI_FORMAT_BC6H_UF16 = 95
|
||||
DXGI_FORMAT_BC6H_SF16 = 96
|
||||
DXGI_FORMAT_BC7_TYPELESS = 97
|
||||
DXGI_FORMAT_BC7_UNORM = 98
|
||||
DXGI_FORMAT_BC7_UNORM_SRGB = 99
|
||||
|
@ -181,6 +183,14 @@ class DdsImageFile(ImageFile.ImageFile):
|
|||
self.pixel_format = "BC5S"
|
||||
n = 5
|
||||
self.mode = "RGB"
|
||||
elif dxgi_format == DXGI_FORMAT_BC6H_UF16:
|
||||
self.pixel_format = "BC6H"
|
||||
n = 6
|
||||
self.mode = "RGB"
|
||||
elif dxgi_format == DXGI_FORMAT_BC6H_SF16:
|
||||
self.pixel_format = "BC6HS"
|
||||
n = 6
|
||||
self.mode = "RGB"
|
||||
elif dxgi_format in (DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM):
|
||||
self.pixel_format = "BC7"
|
||||
n = 7
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -23,10 +23,6 @@ typedef struct {
|
|||
UINT8 l;
|
||||
} lum;
|
||||
|
||||
typedef struct {
|
||||
FLOAT32 r, g, b;
|
||||
} rgb32f;
|
||||
|
||||
typedef struct {
|
||||
UINT16 c0, c1;
|
||||
UINT32 lut;
|
||||
|
@ -536,53 +532,53 @@ static const bc6_mode_info bc6_modes[] = {
|
|||
|
||||
/* Table.F, encoded as a sequence of bit indices */
|
||||
static const UINT8 bc6_bit_packings[][75] = {
|
||||
{116, 132, 176, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17,
|
||||
{116, 132, 180, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65,
|
||||
66, 67, 68, 172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128,
|
||||
129, 130, 131, 96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||
{117, 164, 165, 0, 1, 2, 3, 4, 5, 6, 172, 173, 132, 16, 17,
|
||||
18, 19, 20, 21, 22, 133, 174, 116, 32, 33, 34, 35, 36, 37, 38,
|
||||
175, 177, 176, 48, 49, 50, 51, 52, 53, 112, 113, 114, 115, 64, 65,
|
||||
66, 67, 68, 176, 160, 161, 162, 163, 80, 81, 82, 83, 84, 177, 128,
|
||||
129, 130, 131, 96, 97, 98, 99, 100, 178, 144, 145, 146, 147, 148, 179},
|
||||
{117, 164, 165, 0, 1, 2, 3, 4, 5, 6, 176, 177, 132, 16, 17,
|
||||
18, 19, 20, 21, 22, 133, 178, 116, 32, 33, 34, 35, 36, 37, 38,
|
||||
179, 181, 180, 48, 49, 50, 51, 52, 53, 112, 113, 114, 115, 64, 65,
|
||||
66, 67, 68, 69, 160, 161, 162, 163, 80, 81, 82, 83, 84, 85, 128,
|
||||
129, 130, 131, 96, 97, 98, 99, 100, 101, 144, 145, 146, 147, 148, 149},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
||||
48, 49, 50, 51, 52, 10, 112, 113, 114, 115, 64, 65, 66, 67, 26,
|
||||
172, 160, 161, 162, 163, 80, 81, 82, 83, 42, 173, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||
176, 160, 161, 162, 163, 80, 81, 82, 83, 42, 177, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 178, 144, 145, 146, 147, 148, 179},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
||||
48, 49, 50, 51, 10, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||
26, 160, 161, 162, 163, 80, 81, 82, 83, 42, 173, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 172, 174, 144, 145, 146, 147, 116, 175},
|
||||
26, 160, 161, 162, 163, 80, 81, 82, 83, 42, 177, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 176, 178, 144, 145, 146, 147, 116, 179},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
||||
48, 49, 50, 51, 10, 132, 112, 113, 114, 115, 64, 65, 66, 67, 26,
|
||||
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 42, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 173, 174, 144, 145, 146, 147, 176, 175},
|
||||
176, 160, 161, 162, 163, 80, 81, 82, 83, 84, 42, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 177, 178, 144, 145, 146, 147, 180, 179},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 132, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 116, 32, 33, 34, 35, 36, 37, 38, 39, 40, 176,
|
||||
21, 22, 23, 24, 116, 32, 33, 34, 35, 36, 37, 38, 39, 40, 180,
|
||||
48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||
176, 160, 161, 162, 163, 80, 81, 82, 83, 84, 177, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 178, 144, 145, 146, 147, 148, 179},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 164, 132, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 174, 116, 32, 33, 34, 35, 36, 37, 38, 39, 175, 176,
|
||||
21, 22, 23, 178, 116, 32, 33, 34, 35, 36, 37, 38, 39, 179, 180,
|
||||
48, 49, 50, 51, 52, 53, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128, 129, 130, 131,
|
||||
176, 160, 161, 162, 163, 80, 81, 82, 83, 84, 177, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 101, 144, 145, 146, 147, 148, 149},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 172, 132, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 117, 116, 32, 33, 34, 35, 36, 37, 38, 39, 165, 176,
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 176, 132, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 117, 116, 32, 33, 34, 35, 36, 37, 38, 39, 165, 180,
|
||||
48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||
69, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 173, 132, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 133, 116, 32, 33, 34, 35, 36, 37, 38, 39, 177, 176,
|
||||
69, 160, 161, 162, 163, 80, 81, 82, 83, 84, 177, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 178, 144, 145, 146, 147, 148, 179},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 177, 132, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 133, 116, 32, 33, 34, 35, 36, 37, 38, 39, 181, 180,
|
||||
48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 85, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||
{0, 1, 2, 3, 4, 5, 164, 172, 173, 132, 16, 17, 18, 19, 20,
|
||||
21, 117, 133, 174, 116, 32, 33, 34, 35, 36, 37, 165, 175, 177, 176,
|
||||
176, 160, 161, 162, 163, 80, 81, 82, 83, 84, 85, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 178, 144, 145, 146, 147, 148, 179},
|
||||
{0, 1, 2, 3, 4, 5, 164, 176, 177, 132, 16, 17, 18, 19, 20,
|
||||
21, 117, 133, 178, 116, 32, 33, 34, 35, 36, 37, 165, 179, 181, 180,
|
||||
48, 49, 50, 51, 52, 53, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||
69, 160, 161, 162, 163, 80, 81, 82, 83, 84, 85, 128, 129, 130, 131,
|
||||
96, 97, 98, 99, 100, 101, 144, 145, 146, 147, 148, 149},
|
||||
|
@ -681,20 +677,31 @@ bc6_finalize(int v, int sign) {
|
|||
}
|
||||
}
|
||||
|
||||
static UINT8
|
||||
bc6_clamp(float value) {
|
||||
if (value < 0.0f) {
|
||||
return 0;
|
||||
} else if (value > 1.0f) {
|
||||
return 255;
|
||||
} else {
|
||||
return (UINT8) (value * 255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
g = (e0[1] * t + e1[1] * s) >> 6;
|
||||
b = (e0[2] * t + e1[2] * s) >> 6;
|
||||
col->r = bc6_finalize(r, sign);
|
||||
col->g = bc6_finalize(g, sign);
|
||||
col->b = bc6_finalize(b, sign);
|
||||
col->r = bc6_clamp(bc6_finalize(r, sign));
|
||||
col->g = bc6_clamp(bc6_finalize(g, sign));
|
||||
col->b = bc6_clamp(bc6_finalize(b, 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,21 +751,16 @@ 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);
|
||||
}
|
||||
}
|
||||
if (info->tr) { /* apply deltas */
|
||||
for (i = 3; i < numep; i++) {
|
||||
for (i = 3; i < numep; i += 3) {
|
||||
endpoints[i] = (endpoints[i] + endpoints[0]) & mask;
|
||||
}
|
||||
if (sign) {
|
||||
for (i = 3; i < numep; i += 3) {
|
||||
bc6_sign_extend(&endpoints[i + 0], info->rb);
|
||||
bc6_sign_extend(&endpoints[i + 1], info->gb);
|
||||
bc6_sign_extend(&endpoints[i + 2], info->bb);
|
||||
}
|
||||
endpoints[i + 1] = (endpoints[i + 1] + endpoints[1]) & mask;
|
||||
endpoints[i + 2] = (endpoints[i + 2] + endpoints[2]) & mask;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < numep; i++) {
|
||||
|
@ -862,8 +864,8 @@ decode_bcn(
|
|||
break;
|
||||
case 6:
|
||||
while (bytes >= 16) {
|
||||
rgb32f col[16];
|
||||
decode_bc6_block(col, ptr, (state->state >> 4) & 1);
|
||||
rgba col[16];
|
||||
decode_bc6_block(col, ptr, strcmp(pixel_format, "BC6HS") == 0 ? 1 : 0);
|
||||
put_block(im, state, (const char *)col, sizeof(col[0]), C);
|
||||
ptr += 16;
|
||||
bytes -= 16;
|
||||
|
|
Loading…
Reference in New Issue
Block a user