mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Add support for BC7 to DdsImagePlugin
This commit is contained in:
		
							parent
							
								
									b46804ea27
								
							
						
					
					
						commit
						2be760ca79
					
				| 
						 | 
				
			
			@ -93,6 +93,13 @@ DXT3_FOURCC = 0x33545844
 | 
			
		|||
DXT5_FOURCC = 0x35545844
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# dxgiformat.h
 | 
			
		||||
 | 
			
		||||
DXGI_FORMAT_BC7_TYPELESS = 97
 | 
			
		||||
DXGI_FORMAT_BC7_UNORM = 98
 | 
			
		||||
DXGI_FORMAT_BC7_UNORM_SRGB = 99
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DdsImageFile(ImageFile.ImageFile):
 | 
			
		||||
    format = "DDS"
 | 
			
		||||
    format_description = "DirectDraw Surface"
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +126,8 @@ class DdsImageFile(ImageFile.ImageFile):
 | 
			
		|||
        bitcount, rmask, gmask, bmask, amask = struct.unpack("<5I",
 | 
			
		||||
                                                             header.read(20))
 | 
			
		||||
 | 
			
		||||
        data_start = header_size + 4
 | 
			
		||||
        n = 0
 | 
			
		||||
        if fourcc == b"DXT1":
 | 
			
		||||
            self.pixel_format = "DXT1"
 | 
			
		||||
            n = 1
 | 
			
		||||
| 
						 | 
				
			
			@ -128,12 +137,27 @@ class DdsImageFile(ImageFile.ImageFile):
 | 
			
		|||
        elif fourcc == b"DXT5":
 | 
			
		||||
            self.pixel_format = "DXT5"
 | 
			
		||||
            n = 3
 | 
			
		||||
        elif fourcc == b"DX10":
 | 
			
		||||
            data_start += 20
 | 
			
		||||
            # ignoring flags which pertain to volume textures and cubemaps
 | 
			
		||||
            dxt10 = BytesIO(self.fp.read(20))
 | 
			
		||||
            dxgi_format, dimension = struct.unpack("<II", dxt10.read(8))
 | 
			
		||||
            if dxgi_format in (DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM):
 | 
			
		||||
                self.pixel_format = "BC7"
 | 
			
		||||
                n = 7
 | 
			
		||||
            elif dxgi_format == DXGI_FORMAT_BC7_UNORM_SRGB:
 | 
			
		||||
                self.pixel_format = "BC7"
 | 
			
		||||
                self.im_info["gamma"] = 1/2.2
 | 
			
		||||
                n = 7
 | 
			
		||||
            else:
 | 
			
		||||
                raise NotImplementedError("Unimplemented DXGI format %d" %
 | 
			
		||||
                                          (dxgi_format))
 | 
			
		||||
        else:
 | 
			
		||||
            raise NotImplementedError("Unimplemented pixel format %r" %
 | 
			
		||||
                                      (fourcc))
 | 
			
		||||
 | 
			
		||||
        self.tile = [
 | 
			
		||||
            ("bcn", (0, 0) + self.size, 4 + header_size, (n))
 | 
			
		||||
            ("bcn", (0, 0) + self.size, data_start, (n))
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    def load_seek(self, pos):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										
											BIN
										
									
								
								Tests/images/bc7-argb-8bpp_MipMaps-1.dds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/bc7-argb-8bpp_MipMaps-1.dds
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/images/bc7-argb-8bpp_MipMaps-1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/bc7-argb-8bpp_MipMaps-1.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 122 KiB  | 
| 
						 | 
				
			
			@ -6,6 +6,7 @@ from PIL import Image, DdsImagePlugin
 | 
			
		|||
TEST_FILE_DXT1 = "Tests/images/dxt1-rgb-4bbp-noalpha_MipMaps-1.dds"
 | 
			
		||||
TEST_FILE_DXT3 = "Tests/images/dxt3-argb-8bbp-explicitalpha_MipMaps-1.dds"
 | 
			
		||||
TEST_FILE_DXT5 = "Tests/images/dxt5-argb-8bbp-interpolatedalpha_MipMaps-1.dds"
 | 
			
		||||
TEST_FILE_DX10_BC7 = "Tests/images/bc7-argb-8bpp_MipMaps-1.dds"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestFileDds(PillowTestCase):
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +53,20 @@ class TestFileDds(PillowTestCase):
 | 
			
		|||
 | 
			
		||||
        self.assert_image_equal(target, im)
 | 
			
		||||
 | 
			
		||||
    def test_dx10_bc7(self):
 | 
			
		||||
        """Check DX10 images can be opened"""
 | 
			
		||||
 | 
			
		||||
        target = Image.open(TEST_FILE_DX10_BC7.replace('.dds', '.png'))
 | 
			
		||||
 | 
			
		||||
        im = Image.open(TEST_FILE_DX10_BC7)
 | 
			
		||||
        im.load()
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(im.format, "DDS")
 | 
			
		||||
        self.assertEqual(im.mode, "RGBA")
 | 
			
		||||
        self.assertEqual(im.size, (256, 256))
 | 
			
		||||
 | 
			
		||||
        self.assert_image_equal(target, im)
 | 
			
		||||
 | 
			
		||||
    def test__validate_true(self):
 | 
			
		||||
        """Check valid prefix"""
 | 
			
		||||
        # Arrange
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -327,10 +327,10 @@ static UINT8 expand_quantized(UINT8 v, int bits) {
 | 
			
		|||
static void bc7_lerp(rgba *dst, const rgba *e, int s0, int s1) {
 | 
			
		||||
	int t0 = 64 - s0;
 | 
			
		||||
	int t1 = 64 - s1;
 | 
			
		||||
	dst->r = (UINT8)((t0 * e[0].r + s0 * e[1].r) >> 6);
 | 
			
		||||
	dst->g = (UINT8)((t0 * e[0].g + s0 * e[1].g) >> 6);
 | 
			
		||||
	dst->b = (UINT8)((t0 * e[0].b + s0 * e[1].b) >> 6);
 | 
			
		||||
	dst->a = (UINT8)((t1 * e[0].a + s1 * e[1].a) >> 6);
 | 
			
		||||
	dst->r = (UINT8)((t0 * e[0].r + s0 * e[1].r + 32) >> 6);
 | 
			
		||||
	dst->g = (UINT8)((t0 * e[0].g + s0 * e[1].g + 32) >> 6);
 | 
			
		||||
	dst->b = (UINT8)((t0 * e[0].b + s0 * e[1].b + 32) >> 6);
 | 
			
		||||
	dst->a = (UINT8)((t1 * e[0].a + s1 * e[1].a + 32) >> 6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void decode_bc7_block(rgba *col, const UINT8* src) {
 | 
			
		||||
| 
						 | 
				
			
			@ -359,7 +359,7 @@ static void decode_bc7_block(rgba *col, const UINT8* src) {
 | 
			
		|||
	cb = info->cb;
 | 
			
		||||
	ab = info->ab;
 | 
			
		||||
	cw = bc7_get_weights(info->ib);
 | 
			
		||||
	aw = bc7_get_weights(ab ? info->ib2 : info->ib);
 | 
			
		||||
	aw = bc7_get_weights((ab && info->ib2) ? info->ib2 : info->ib);
 | 
			
		||||
 | 
			
		||||
#define LOAD(DST, N) \
 | 
			
		||||
	DST = get_bits(src, bit, N); \
 | 
			
		||||
| 
						 | 
				
			
			@ -401,29 +401,33 @@ static void decode_bc7_block(rgba *col, const UINT8* src) {
 | 
			
		|||
#define ASSIGN_P(x) x = (x << 1) | val
 | 
			
		||||
	if (info->epb) {
 | 
			
		||||
		/* per endpoint */
 | 
			
		||||
		cb++;
 | 
			
		||||
		if (ab) {
 | 
			
		||||
			ab++;
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 0; i < numep; i++) {
 | 
			
		||||
			LOAD(val, 1);
 | 
			
		||||
			cb++;
 | 
			
		||||
			ASSIGN_P(endpoints[i].r);
 | 
			
		||||
			ASSIGN_P(endpoints[i].g);
 | 
			
		||||
			ASSIGN_P(endpoints[i].b);
 | 
			
		||||
			if (ab) {
 | 
			
		||||
				ab++;
 | 
			
		||||
				ASSIGN_P(endpoints[i].a);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (info->spb) {
 | 
			
		||||
		/* per subset */
 | 
			
		||||
		cb++;
 | 
			
		||||
		if (ab) {
 | 
			
		||||
			ab++;
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 0; i < numep; i+=2) {
 | 
			
		||||
			LOAD(val, 1);
 | 
			
		||||
			cb++;
 | 
			
		||||
			for (j = 0; j < 2; j++) {
 | 
			
		||||
				ASSIGN_P(endpoints[i+j].r);
 | 
			
		||||
				ASSIGN_P(endpoints[i+j].g);
 | 
			
		||||
				ASSIGN_P(endpoints[i+j].b);
 | 
			
		||||
				if (ab) {
 | 
			
		||||
					ab++;
 | 
			
		||||
					ASSIGN_P(endpoints[i+j].a);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -462,7 +466,7 @@ static void decode_bc7_block(rgba *col, const UINT8* src) {
 | 
			
		|||
		i0 = get_bits(src, cibit, ib);
 | 
			
		||||
		cibit += ib;
 | 
			
		||||
 | 
			
		||||
		if (ab) {
 | 
			
		||||
		if (ab && info->ib2) {
 | 
			
		||||
			ib2 = info->ib2;
 | 
			
		||||
			if (ib2 && i == 0) {
 | 
			
		||||
				ib2--;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user