@@ -518,30 +518,45 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
518
518
msg = f"cannot write mode { im .mode } as DDS"
519
519
raise OSError (msg )
520
520
521
- alpha = im .mode [- 1 ] == "A"
522
- if im .mode [0 ] == "L" :
523
- pixel_flags = DDPF .LUMINANCE
524
- rawmode = im .mode
525
- if alpha :
526
- rgba_mask = [0x000000FF , 0x000000FF , 0x000000FF ]
521
+ flags = DDSD .CAPS | DDSD .HEIGHT | DDSD .WIDTH | DDSD .PIXELFORMAT
522
+ bitcount = len (im .getbands ()) * 8
523
+ raw = im .encoderinfo .get ("mode" ) != "bcn"
524
+ if raw :
525
+ codec_name = "raw"
526
+ flags |= DDSD .PITCH
527
+ pitch = (im .width * bitcount + 7 ) // 8
528
+ mipmaps = 0
529
+
530
+ alpha = im .mode [- 1 ] == "A"
531
+ if im .mode [0 ] == "L" :
532
+ pixel_flags = DDPF .LUMINANCE
533
+ rawmode = im .mode
534
+ if alpha :
535
+ rgba_mask = [0x000000FF , 0x000000FF , 0x000000FF ]
536
+ else :
537
+ rgba_mask = [0xFF000000 , 0xFF000000 , 0xFF000000 ]
527
538
else :
528
- rgba_mask = [0xFF000000 , 0xFF000000 , 0xFF000000 ]
529
- else :
530
- pixel_flags = DDPF .RGB
531
- rawmode = im .mode [::- 1 ]
532
- rgba_mask = [0x00FF0000 , 0x0000FF00 , 0x000000FF ]
539
+ pixel_flags = DDPF .RGB
540
+ rawmode = im .mode [::- 1 ]
541
+ rgba_mask = [0x00FF0000 , 0x0000FF00 , 0x000000FF ]
533
542
543
+ if alpha :
544
+ r , g , b , a = im .split ()
545
+ im = Image .merge ("RGBA" , (a , r , g , b ))
534
546
if alpha :
535
- r , g , b , a = im .split ()
536
- im = Image .merge ("RGBA" , (a , r , g , b ))
537
- if alpha :
538
- pixel_flags |= DDPF .ALPHAPIXELS
539
- rgba_mask .append (0xFF000000 if alpha else 0 )
540
-
541
- flags = DDSD .CAPS | DDSD .HEIGHT | DDSD .WIDTH | DDSD .PITCH | DDSD .PIXELFORMAT
542
- bitcount = len (im .getbands ()) * 8
543
- pitch = (im .width * bitcount + 7 ) // 8
547
+ pixel_flags |= DDPF .ALPHAPIXELS
548
+ rgba_mask .append (0xFF000000 if alpha else 0 )
544
549
550
+ fourcc = 0
551
+ else :
552
+ codec_name = "bcn"
553
+ flags |= DDSD .MIPMAPCOUNT | DDSD .LINEARSIZE
554
+ pitch = (im .width + 3 ) * 4
555
+ mipmaps = 1
556
+ rawmode = None
557
+ rgba_mask = [0 , 0 , 0 , 0 ]
558
+ pixel_flags = DDPF .FOURCC
559
+ fourcc = D3DFMT .DXT1
545
560
fp .write (
546
561
o32 (DDS_MAGIC )
547
562
+ struct .pack (
@@ -552,15 +567,15 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
552
567
im .width ,
553
568
pitch ,
554
569
0 , # depth
555
- 0 , # mipmaps
570
+ mipmaps , # mipmaps
556
571
)
557
572
+ struct .pack ("11I" , * ((0 ,) * 11 )) # reserved
558
573
# pfsize, pfflags, fourcc, bitcount
559
- + struct .pack ("<4I" , 32 , pixel_flags , 0 , bitcount )
574
+ + struct .pack ("<4I" , 32 , pixel_flags , fourcc , bitcount )
560
575
+ struct .pack ("<4I" , * rgba_mask ) # dwRGBABitMask
561
576
+ struct .pack ("<5I" , DDSCAPS .TEXTURE , 0 , 0 , 0 , 0 )
562
577
)
563
- ImageFile ._save (im , fp , [ImageFile ._Tile ("raw" , (0 , 0 ) + im .size , 0 , rawmode )])
578
+ ImageFile ._save (im , fp , [ImageFile ._Tile (codec_name , (0 , 0 ) + im .size , 0 , rawmode )])
564
579
565
580
566
581
def _accept (prefix : bytes ) -> bool :
0 commit comments