Skip to content

Commit 8067c22

Browse files
authored
Merge pull request #2 from radarhere/vtf-support
Restored black formatting, and minor changes
2 parents 6485071 + df129de commit 8067c22

File tree

3 files changed

+85
-59
lines changed

3 files changed

+85
-59
lines changed

src/PIL/VtfImagePlugin.py

+71-51
Original file line numberDiff line numberDiff line change
@@ -142,28 +142,30 @@ class VtfPF(IntEnum):
142142
VtfPF.UV88,
143143
)
144144

145-
BLOCK_COMPRESSED = (
146-
VtfPF.DXT1,
147-
VtfPF.DXT1_ONEBITALPHA,
148-
VtfPF.DXT3,
149-
VtfPF.DXT5)
145+
BLOCK_COMPRESSED = (VtfPF.DXT1, VtfPF.DXT1_ONEBITALPHA, VtfPF.DXT3, VtfPF.DXT5)
150146
SUPPORTED_FORMATS = RGBA_FORMATS + RGB_FORMATS + LA_FORMATS + L_FORMATS
151-
HEADER_V70 = '<I2HI2H4x3f4xfIbI2b'
152-
HEADER_V72 = '<I2HI2H4x3f4xfIbI2bH'
153-
HEADER_V73 = '<I2HI2H4x3f4xfIbI2bH3xI8x'
147+
HEADER_V70 = "<I2HI2H4x3f4xfIbI2b"
148+
HEADER_V72 = "<I2HI2H4x3f4xfIbI2bH"
149+
HEADER_V73 = "<I2HI2H4x3f4xfIbI2bH3xI8x"
154150

155151

156-
# fmt: off
157152
def _get_texture_size(pixel_format: VtfPF, width, height):
158153
if pixel_format in (VtfPF.DXT1, VtfPF.DXT1_ONEBITALPHA):
159154
return width * height // 2
160-
elif pixel_format in (VtfPF.DXT3, VtfPF.DXT5,) + L_FORMATS:
155+
elif (
156+
pixel_format
157+
in (
158+
VtfPF.DXT3,
159+
VtfPF.DXT5,
160+
)
161+
+ L_FORMATS
162+
):
161163
return width * height
162164
elif pixel_format in LA_FORMATS:
163165
return width * height * 2
164-
elif pixel_format in (VtfPF.RGB888,):
166+
elif pixel_format == VtfPF.RGB888:
165167
return width * height * 3
166-
elif pixel_format in (VtfPF.RGBA8888,):
168+
elif pixel_format == VtfPF.RGBA8888:
167169
return width * height * 4
168170
raise VTFException(f"Unsupported VTF pixel format: {pixel_format}")
169171

@@ -181,17 +183,13 @@ def _get_mipmap_count(width: int, height: int):
181183

182184
def closest_power(x):
183185
possible_results = round(log(x, 2)), ceil(log(x, 2))
184-
return 2 ** min(possible_results, key=lambda z: abs(x - 2 ** z))
185-
186-
187-
# fmt: on
186+
return 2 ** min(possible_results, key=lambda z: abs(x - 2**z))
188187

189188

190189
class VtfImageFile(ImageFile.ImageFile):
191190
format = "VTF"
192191
format_description = "Valve Texture Format"
193192

194-
# fmt: off
195193
def _open(self):
196194
if not _accept(self.fp.read(12)):
197195
raise SyntaxError("not a VTF file")
@@ -200,16 +198,26 @@ def _open(self):
200198
if version <= (7, 2):
201199
header = VTFHeader(
202200
*struct.unpack(HEADER_V70, self.fp.read(struct.calcsize(HEADER_V70))),
203-
0, 0, 0, 0, 0)
201+
0,
202+
0,
203+
0,
204+
0,
205+
0,
206+
)
204207
self.fp.seek(header.header_size)
205-
elif (7, 2) <= version < (7, 3):
208+
elif version < (7, 3):
206209
header = VTFHeader(
207210
*struct.unpack(HEADER_V72, self.fp.read(struct.calcsize(HEADER_V72))),
208-
0, 0, 0, 0)
211+
0,
212+
0,
213+
0,
214+
0,
215+
)
209216
self.fp.seek(header.header_size)
210-
elif (7, 3) <= version < (7, 5):
217+
elif version < (7, 5):
211218
header = VTFHeader(
212-
*struct.unpack(HEADER_V73, self.fp.read(struct.calcsize(HEADER_V73))))
219+
*struct.unpack(HEADER_V73, self.fp.read(struct.calcsize(HEADER_V73)))
220+
)
213221
self.fp.seek(header.header_size)
214222
else:
215223
raise VTFException(f"Unsupported VTF version: {version}")
@@ -232,7 +240,7 @@ def _open(self):
232240

233241
data_start = self.fp.tell()
234242
data_start += _get_texture_size(low_format, header.low_width, header.low_height)
235-
min_res = (4 if pixel_format in BLOCK_COMPRESSED else 1)
243+
min_res = 4 if pixel_format in BLOCK_COMPRESSED else 1
236244
for mip_id in range(header.mipmap_count - 1, 0, -1):
237245
mip_width = max(header.width >> mip_id, min_res)
238246
mip_height = max(header.height >> mip_id, min_res)
@@ -256,22 +264,21 @@ def _open(self):
256264
else:
257265
raise VTFException(f"Unsupported VTF pixel format: {pixel_format}")
258266
self.tile = [tile]
259-
# fmt: on
260267

261268

262269
def _save(im, fp, filename):
263270
im: Image.Image
264271
if im.mode not in ("RGB", "RGBA"):
265272
raise OSError(f"cannot write mode {im.mode} as VTF")
266-
arguments = im.encoderinfo
267-
pixel_format = VtfPF(arguments.get('pixel_format', VtfPF.RGBA8888))
268-
version = arguments.get('version', (7, 4))
273+
encoderinfo = im.encoderinfo
274+
pixel_format = VtfPF(encoderinfo.get("pixel_format", VtfPF.RGBA8888))
275+
version = encoderinfo.get("version", (7, 4))
269276
flags = CompiledVtfFlags(0)
270-
if 'A' in im.mode:
277+
if "A" in im.mode:
271278
if pixel_format == VtfPF.DXT1_ONEBITALPHA:
272279
flags |= CompiledVtfFlags.ONEBITALPHA
273280
elif pixel_format == VtfPF.DXT1:
274-
im = im.convert('RGB')
281+
im = im.convert("RGB")
275282
else:
276283
flags |= CompiledVtfFlags.EIGHTBITALPHA
277284

@@ -281,21 +288,32 @@ def _save(im, fp, filename):
281288
mipmap_count = _get_mipmap_count(width, height)
282289

283290
thumb_buffer = BytesIO()
284-
thumb = im.convert('RGB')
291+
thumb = im.convert("RGB")
285292
thumb.thumbnail(((min(16, width)), (min(16, height))))
286293
thumb = thumb.resize((closest_power(thumb.width), closest_power(thumb.height)))
287-
ImageFile._save(thumb, thumb_buffer, [("bcn", (0, 0) + thumb.size, 0, (1, 'DXT1'))])
288-
289-
header = VTFHeader(0, width, height, flags,
290-
1, 0, 1.0, 1.0, 1.0,
291-
1.0, pixel_format, mipmap_count, VtfPF.DXT1,
292-
thumb.width, thumb.height,
293-
1, 2)
294-
295-
fp.write(
296-
b"VTF\x00"
297-
+ struct.pack('<2I', *version)
294+
ImageFile._save(thumb, thumb_buffer, [("bcn", (0, 0) + thumb.size, 0, (1, "DXT1"))])
295+
296+
header = VTFHeader(
297+
0,
298+
width,
299+
height,
300+
flags,
301+
1,
302+
0,
303+
1.0,
304+
1.0,
305+
1.0,
306+
1.0,
307+
pixel_format,
308+
mipmap_count,
309+
VtfPF.DXT1,
310+
thumb.width,
311+
thumb.height,
312+
1,
313+
2,
298314
)
315+
316+
fp.write(b"VTF\x00" + struct.pack("<2I", *version))
299317
if version < (7, 2):
300318
size = struct.calcsize(HEADER_V70) + 12
301319
header = header._replace(header_size=size + (16 - size % 16))
@@ -309,15 +327,15 @@ def _save(im, fp, filename):
309327
header = header._replace(header_size=size + (16 - size % 16))
310328
fp.write(struct.pack(HEADER_V73, *header))
311329
else:
312-
raise VTFException(f'Unsupported version {version}')
330+
raise VTFException(f"Unsupported version {version}")
313331

314332
if version > (7, 2):
315-
fp.write(b'\x01\x00\x00\x00')
316-
fp.write(struct.pack('<I', header.header_size))
317-
fp.write(b'\x30\x00\x00\x00')
318-
fp.write(struct.pack('<I', header.header_size + len(thumb_buffer.getbuffer())))
333+
fp.write(b"\x01\x00\x00\x00")
334+
fp.write(struct.pack("<I", header.header_size))
335+
fp.write(b"\x30\x00\x00\x00")
336+
fp.write(struct.pack("<I", header.header_size + len(thumb_buffer.getbuffer())))
319337
else:
320-
fp.write(b'\x00' * (16 - fp.tell() % 16))
338+
fp.write(b"\x00" * (16 - fp.tell() % 16))
321339
fp.write(thumb_buffer.getbuffer())
322340

323341
for mip_id in range(mipmap_count - 1, 0, -1):
@@ -326,11 +344,13 @@ def _save(im, fp, filename):
326344
mip = im.resize((mip_width, mip_height))
327345
buffer_size = mip_width * mip_height // 2
328346
extents = (0, 0) + mip.size
329-
ImageFile._save(mip, fp,
330-
[("bcn", extents, fp.tell(), (1, 'DXT1'))], buffer_size)
347+
ImageFile._save(
348+
mip, fp, [("bcn", extents, fp.tell(), (1, "DXT1"))], buffer_size
349+
)
331350
buffer_size = im.width * im.height // 2
332-
ImageFile._save(im, fp,
333-
[("bcn", (0, 0) + im.size, fp.tell(), (1, 'DXT1'))], buffer_size)
351+
ImageFile._save(
352+
im, fp, [("bcn", (0, 0) + im.size, fp.tell(), (1, "DXT1"))], buffer_size
353+
)
334354

335355

336356
def _accept(prefix):

src/encode.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ get_packer(ImagingEncoderObject *encoder, const char *mode, const char *rawmode)
376376
}
377377

378378
/* -------------------------------------------------------------------- */
379-
/* BNC */
379+
/* BCN */
380380
/* -------------------------------------------------------------------- */
381381

382382
PyObject *

src/libImaging/BcnEncode.c

+13-7
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ selection_sort(Color arr[], UINT32 n) {
7777

7878
for (i = 0; i < n - 1; i++) {
7979
min_idx = i;
80-
for (j = i + 1; j < n; j++)
81-
if (arr[j].frequency < arr[min_idx].frequency)
80+
for (j = i + 1; j < n; j++) {
81+
if (arr[j].frequency < arr[min_idx].frequency) {
8282
min_idx = j;
83+
}
84+
}
8385
SWAP(Color, arr[min_idx], arr[i]);
8486
}
8587
}
@@ -103,8 +105,9 @@ pick_2_major_colors(
103105

104106
if (color_count == 1) {
105107
*color1 = colors[color_count - 1].value;
106-
} else
108+
} else {
107109
*color1 = colors[color_count - 2].value;
110+
}
108111
}
109112

110113
static UINT8
@@ -131,8 +134,9 @@ encode_bc1(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
131134
bc1_color *blocks = (bc1_color *)buf;
132135
UINT8 no_alpha = 0;
133136
INT32 block_index;
134-
if (strchr(im->mode, 'A') == NULL)
137+
if (strchr(im->mode, 'A') == NULL) {
135138
no_alpha = 1;
139+
}
136140
UINT32 block_count = (im->xsize * im->ysize) / 16;
137141
if (block_count * sizeof(bc1_color) > bytes) {
138142
state->errcode = IMAGING_CODEC_MEMORY;
@@ -185,8 +189,9 @@ encode_bc1(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
185189

186190
UINT16 c0 = 0, c1 = 0;
187191
pick_2_major_colors(unique_colors, color_frequency, unique_count, &c0, &c1);
188-
if (c0 < c1 && no_alpha)
192+
if (c0 < c1 && no_alpha) {
189193
SWAP(UINT16, c0, c1);
194+
}
190195

191196
UINT16 palette[4] = {c0, c1, 0, 0};
192197
if (no_alpha) {
@@ -203,10 +208,11 @@ encode_bc1(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
203208
UINT32 color_id;
204209
for (color_id = 0; color_id < 16; ++color_id) {
205210
UINT8 bc_color_id;
206-
if (opaque[color_id] || no_alpha)
211+
if (opaque[color_id] || no_alpha) {
207212
bc_color_id = get_closest_color_index(palette, all_colors[color_id]);
208-
else
213+
} else {
209214
bc_color_id = 3;
215+
}
210216
SET_BITS(block->lut, color_id * 2, 2, bc_color_id);
211217
}
212218
}

0 commit comments

Comments
 (0)