-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathdds.py
147 lines (113 loc) · 4.51 KB
/
dds.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright © 2016-2017 AboodXD
"""dds.py: DDS Header generator."""
dx10_formats = ["BC4U", "BC4S", "BC5U", "BC5S", "BC6H_UF16", "BC6H_SF16", "BC7"]
def generateHeader(num_mipmaps, w, h, format_, compSel, size, compressed):
hdr = bytearray(128)
luminance = False
RGB = False
has_alpha = True
if format_ == 28: # ABGR8
RGB = True
compSels = {2: 0x000000ff, 3: 0x0000ff00, 4: 0x00ff0000, 5: 0xff000000, 1: 0}
fmtbpp = 4
elif format_ == 24: # A2RGB10
RGB = True
compSels = {2: 0x3ff00000, 3: 0x000ffc00, 4: 0x000003ff, 5: 0xc0000000, 1: 0}
fmtbpp = 4
elif format_ == 85: # RGB565
RGB = True
compSels = {2: 0x0000f800, 3: 0x000007e0, 4: 0x0000001f, 5: 0, 1: 0}
fmtbpp = 2
has_alpha = False
elif format_ == 86: # A1RGB5
RGB = True
compSels = {2: 0x00007c00, 3: 0x000003e0, 4: 0x0000001f, 5: 0x00008000, 1: 0}
fmtbpp = 2
elif format_ == 115: # ARGB4
RGB = True
compSels = {2: 0x00000f00, 3: 0x000000f0, 4: 0x0000000f, 5: 0x0000f000, 1: 0}
fmtbpp = 2
elif format_ == 61: # L8
luminance = True
compSels = {2: 0x000000ff, 3: 0, 4: 0, 5: 0, 1: 0}
fmtbpp = 1
if compSel[3] != 2:
has_alpha = False
elif format_ == 49: # A8L8
luminance = True
compSels = {2: 0x000000ff, 3: 0x0000ff00, 4: 0, 5: 0, 1: 0}
fmtbpp = 2
elif format_ == 112: # A4L4
luminance = True
compSels = {2: 0x0000000f, 3: 0x000000f0, 4: 0, 5: 0, 1: 0}
fmtbpp = 1
flags = 0x00000001 | 0x00001000 | 0x00000004 | 0x00000002
caps = 0x00001000
if num_mipmaps == 0:
num_mipmaps = 1
elif num_mipmaps != 1:
flags |= 0x00020000
caps |= 0x00000008 | 0x00400000
if not compressed:
flags |= 0x00000008
a = False
if compSel[0] != 2 and compSel[1] != 2 and compSel[2] != 2 and compSel[3] == 2: # ALPHA
a = True
pflags = 0x00000002
elif luminance: # LUMINANCE
pflags = 0x00020000
elif RGB: # RGB
pflags = 0x00000040
else: # Not possible...
return b''
if has_alpha and not a:
pflags |= 0x00000001
size = w * fmtbpp
else:
flags |= 0x00080000
pflags = 0x00000004
if format_ == "ETC1":
fourcc = b'ETC1'
elif format_ == "BC1":
fourcc = b'DXT1'
elif format_ == "BC2":
fourcc = b'DXT3'
elif format_ == "BC3":
fourcc = b'DXT5'
elif format_ in dx10_formats:
fourcc = b'DX10'
hdr[:4] = b'DDS '
hdr[4:4 + 4] = 124 .to_bytes(4, 'little')
hdr[8:8 + 4] = flags.to_bytes(4, 'little')
hdr[12:12 + 4] = h.to_bytes(4, 'little')
hdr[16:16 + 4] = w.to_bytes(4, 'little')
hdr[20:20 + 4] = size.to_bytes(4, 'little')
hdr[28:28 + 4] = num_mipmaps.to_bytes(4, 'little')
hdr[76:76 + 4] = 32 .to_bytes(4, 'little')
hdr[80:80 + 4] = pflags.to_bytes(4, 'little')
if compressed:
hdr[84:84 + 4] = fourcc
else:
hdr[88:88 + 4] = (fmtbpp << 3).to_bytes(4, 'little')
hdr[92:92 + 4] = compSels[compSel[0]].to_bytes(4, 'little')
hdr[96:96 + 4] = compSels[compSel[1]].to_bytes(4, 'little')
hdr[100:100 + 4] = compSels[compSel[2]].to_bytes(4, 'little')
hdr[104:104 + 4] = compSels[compSel[3]].to_bytes(4, 'little')
hdr[108:108 + 4] = caps.to_bytes(4, 'little')
if format_ == "BC4U":
hdr += bytearray(b"\x50\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
elif format_ == "BC4S":
hdr += bytearray(b"\x51\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
elif format_ == "BC5U":
hdr += bytearray(b"\x53\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
elif format_ == "BC5S":
hdr += bytearray(b"\x54\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
elif format_ == "BC6H_UF16":
hdr += bytearray(b"\x5F\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
elif format_ == "BC6H_SF16":
hdr += bytearray(b"\x60\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
elif format_ == "BC7":
hdr += bytearray(b"\x62\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
return hdr