mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	Merge pull request #7 from radarhere/improved_dds
Support RGB bitcount 8
This commit is contained in:
		
						commit
						4c635e4ffc
					
				
							
								
								
									
										
											BIN
										
									
								
								Tests/images/bc1.dds
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/bc1.dds
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/images/bc1_typeless.dds
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/bc1_typeless.dds
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/images/rgb8.dds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/rgb8.dds
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/images/unsupported_bitcount_luminance.dds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/unsupported_bitcount_luminance.dds
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/images/unsupported_bitcount_rgb.dds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/unsupported_bitcount_rgb.dds
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -15,6 +15,8 @@ TEST_FILE_ATI2 = "Tests/images/ati2.dds"
 | 
				
			||||||
TEST_FILE_DX10_BC5_TYPELESS = "Tests/images/bc5_typeless.dds"
 | 
					TEST_FILE_DX10_BC5_TYPELESS = "Tests/images/bc5_typeless.dds"
 | 
				
			||||||
TEST_FILE_DX10_BC5_UNORM = "Tests/images/bc5_unorm.dds"
 | 
					TEST_FILE_DX10_BC5_UNORM = "Tests/images/bc5_unorm.dds"
 | 
				
			||||||
TEST_FILE_DX10_BC5_SNORM = "Tests/images/bc5_snorm.dds"
 | 
					TEST_FILE_DX10_BC5_SNORM = "Tests/images/bc5_snorm.dds"
 | 
				
			||||||
 | 
					TEST_FILE_DX10_BC1 = "Tests/images/bc1.dds"
 | 
				
			||||||
 | 
					TEST_FILE_DX10_BC1_TYPELESS = "Tests/images/bc1_typeless.dds"
 | 
				
			||||||
TEST_FILE_BC5S = "Tests/images/bc5s.dds"
 | 
					TEST_FILE_BC5S = "Tests/images/bc5s.dds"
 | 
				
			||||||
TEST_FILE_BC5U = "Tests/images/bc5u.dds"
 | 
					TEST_FILE_BC5U = "Tests/images/bc5u.dds"
 | 
				
			||||||
TEST_FILE_BC6H = "Tests/images/bc6h.dds"
 | 
					TEST_FILE_BC6H = "Tests/images/bc6h.dds"
 | 
				
			||||||
| 
						 | 
					@ -29,11 +31,20 @@ TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/hopper.dds"
 | 
				
			||||||
TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds"
 | 
					TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_sanity_dxt1():
 | 
					@pytest.mark.parametrize(
 | 
				
			||||||
 | 
					    "image_path",
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        TEST_FILE_DXT1,
 | 
				
			||||||
 | 
					        # hexeditted to use DX10 FourCC
 | 
				
			||||||
 | 
					        TEST_FILE_DX10_BC1,
 | 
				
			||||||
 | 
					        TEST_FILE_DX10_BC1_TYPELESS,
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					def test_sanity_bc1(image_path):
 | 
				
			||||||
    """Check DXT1 images can be opened"""
 | 
					    """Check DXT1 images can be opened"""
 | 
				
			||||||
    with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target:
 | 
					    with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target:
 | 
				
			||||||
        target = target.convert("RGBA")
 | 
					        target = target.convert("RGBA")
 | 
				
			||||||
    with Image.open(TEST_FILE_DXT1) as im:
 | 
					    with Image.open(image_path) as im:
 | 
				
			||||||
        im.load()
 | 
					        im.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert im.format == "DDS"
 | 
					        assert im.format == "DDS"
 | 
				
			||||||
| 
						 | 
					@ -306,8 +317,19 @@ def test_palette():
 | 
				
			||||||
@pytest.mark.parametrize(
 | 
					@pytest.mark.parametrize(
 | 
				
			||||||
    "test_file",
 | 
					    "test_file",
 | 
				
			||||||
    (
 | 
					    (
 | 
				
			||||||
        "Tests/images/unknown_fourcc.dds",
 | 
					        "Tests/images/unsupported_bitcount_rgb.dds",
 | 
				
			||||||
        "Tests/images/unimplemented_fourcc.dds",
 | 
					        "Tests/images/unsupported_bitcount_luminance.dds",
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					def test_unsupported_bitcount(test_file):
 | 
				
			||||||
 | 
					    with pytest.raises(OSError):
 | 
				
			||||||
 | 
					        with Image.open(test_file):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@pytest.mark.parametrize(
 | 
				
			||||||
 | 
					    "test_file",
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
        "Tests/images/unimplemented_dxgi_format.dds",
 | 
					        "Tests/images/unimplemented_dxgi_format.dds",
 | 
				
			||||||
        "Tests/images/unimplemented_pfflags.dds",
 | 
					        "Tests/images/unimplemented_pfflags.dds",
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
| 
						 | 
					@ -340,6 +362,12 @@ def test_open(mode, test_file):
 | 
				
			||||||
        assert_image_equal_tofile(im, test_file.replace(".dds", ".png"))
 | 
					        assert_image_equal_tofile(im, test_file.replace(".dds", ".png"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_open_rgb8():
 | 
				
			||||||
 | 
					    with Image.open("Tests/images/rgb8.dds") as im:
 | 
				
			||||||
 | 
					        assert im.mode == "L"
 | 
				
			||||||
 | 
					        assert_image_equal_tofile(im, "Tests/images/mode-l.png")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.mark.parametrize(
 | 
					@pytest.mark.parametrize(
 | 
				
			||||||
    ("mode", "test_file"),
 | 
					    ("mode", "test_file"),
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -346,34 +346,27 @@ class DdsImageFile(ImageFile.ImageFile):
 | 
				
			||||||
        # pixel format
 | 
					        # pixel format
 | 
				
			||||||
        pfsize, pfflags, fourcc, bitcount = struct.unpack("<4I", header.read(16))
 | 
					        pfsize, pfflags, fourcc, bitcount = struct.unpack("<4I", header.read(16))
 | 
				
			||||||
        masks = struct.unpack("<4I", header.read(16))
 | 
					        masks = struct.unpack("<4I", header.read(16))
 | 
				
			||||||
        if flags & DDSD.CAPS:
 | 
					 | 
				
			||||||
            header.seek(20, io.SEEK_CUR)
 | 
					 | 
				
			||||||
        n = 0
 | 
					        n = 0
 | 
				
			||||||
        rawmode = None
 | 
					        rawmode = None
 | 
				
			||||||
        if pfflags & DDPF.RGB:
 | 
					        if pfflags & DDPF.RGB:
 | 
				
			||||||
            # Texture contains uncompressed RGB data
 | 
					            # Texture contains uncompressed RGB data
 | 
				
			||||||
            masks = {mask: ["R", "G", "B", "A"][i] for i, mask in enumerate(masks)}
 | 
					            masks = {mask: ["R", "G", "B", "A"][i] for i, mask in enumerate(masks)}
 | 
				
			||||||
            if bitcount == 24:
 | 
					            if bitcount == 8:
 | 
				
			||||||
 | 
					                self._mode = "L"
 | 
				
			||||||
 | 
					            elif bitcount == 24:
 | 
				
			||||||
                self._mode = "RGB"
 | 
					                self._mode = "RGB"
 | 
				
			||||||
                rawmode = masks[0x00FF0000] + masks[0x0000FF00] + masks[0x000000FF]
 | 
					                rawmode = masks[0x000000FF] + masks[0x0000FF00] + masks[0x00FF0000]
 | 
				
			||||||
            elif bitcount == 32 and pfflags & DDPF.ALPHAPIXELS:
 | 
					            elif bitcount == 32 and pfflags & DDPF.ALPHAPIXELS:
 | 
				
			||||||
                self._mode = "RGBA"
 | 
					                self._mode = "RGBA"
 | 
				
			||||||
                rawmode = (
 | 
					                rawmode = (
 | 
				
			||||||
                    masks[0xFF000000]
 | 
					                    masks[0x000000FF]
 | 
				
			||||||
                    + masks[0x00FF0000]
 | 
					 | 
				
			||||||
                    + masks[0x0000FF00]
 | 
					                    + masks[0x0000FF00]
 | 
				
			||||||
                    + masks[0x000000FF]
 | 
					                    + masks[0x00FF0000]
 | 
				
			||||||
 | 
					                    + masks[0xFF000000]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                msg = f"Unsupported bitcount {bitcount} for {pfflags}"
 | 
					                msg = f"Unsupported bitcount {bitcount} for {pfflags}"
 | 
				
			||||||
                raise OSError(msg)
 | 
					                raise OSError(msg)
 | 
				
			||||||
            rawmode = rawmode[::-1]
 | 
					 | 
				
			||||||
        elif pfflags & DDPF.ALPHA:
 | 
					 | 
				
			||||||
            if bitcount == 8:
 | 
					 | 
				
			||||||
                self._mode = "L"
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                msg = f"Unsupported bitcount {bitcount} for {pfflags}"
 | 
					 | 
				
			||||||
                raise OSError(msg)
 | 
					 | 
				
			||||||
        elif pfflags & DDPF.LUMINANCE:
 | 
					        elif pfflags & DDPF.LUMINANCE:
 | 
				
			||||||
            if bitcount == 8:
 | 
					            if bitcount == 8:
 | 
				
			||||||
                self._mode = "L"
 | 
					                self._mode = "L"
 | 
				
			||||||
| 
						 | 
					@ -418,7 +411,6 @@ class DdsImageFile(ImageFile.ImageFile):
 | 
				
			||||||
                self.fp.read(16)
 | 
					                self.fp.read(16)
 | 
				
			||||||
                if dxgi_format in (
 | 
					                if dxgi_format in (
 | 
				
			||||||
                    DXGI_FORMAT.BC1_UNORM,
 | 
					                    DXGI_FORMAT.BC1_UNORM,
 | 
				
			||||||
                    DXGI_FORMAT.BC1_UNORM_SRGB,
 | 
					 | 
				
			||||||
                    DXGI_FORMAT.BC1_TYPELESS,
 | 
					                    DXGI_FORMAT.BC1_TYPELESS,
 | 
				
			||||||
                ):
 | 
					                ):
 | 
				
			||||||
                    self._mode = "RGBA"
 | 
					                    self._mode = "RGBA"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user