Skip to content

Commit

Permalink
Merge pull request #5618 from radarhere/wal
Browse files Browse the repository at this point in the history
Added WalImageFile class
  • Loading branch information
mergify[bot] committed Aug 6, 2021
2 parents 887d111 + b3fda8c commit 545196c
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 42 deletions.
Binary file added Tests/images/hopper_wal.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 12 additions & 6 deletions Tests/test_file_wal.py
@@ -1,15 +1,21 @@
from PIL import WalImageFile

from .helper import assert_image_equal_tofile


def test_open():
# Arrange
TEST_FILE = "Tests/images/hopper.wal"

# Act
im = WalImageFile.open(TEST_FILE)
with WalImageFile.open(TEST_FILE) as im:

# Assert
assert im.format == "WAL"
assert im.format_description == "Quake2 Texture"
assert im.mode == "P"
assert im.size == (128, 128)

assert isinstance(im, WalImageFile.WalImageFile)

# Assert
assert im.format == "WAL"
assert im.format_description == "Quake2 Texture"
assert im.mode == "P"
assert im.size == (128, 128)
assert_image_equal_tofile(im, "Tests/images/hopper_wal.png")
8 changes: 5 additions & 3 deletions docs/releasenotes/8.4.0.rst
Expand Up @@ -19,10 +19,12 @@ the default required length, also removing the need for the size parameter.
API Additions
=============

TODO
^^^^
Added WalImageFile class
^^^^^^^^^^^^^^^^^^^^^^^^

TODO
:py:func:`PIL.WalImageFile.open()` previously returned a generic
:py:class:`PIL.Image.Image` instance. It now returns a dedicated
:py:class:`PIL.WalImageFile.WalImageFile` class.

Security
========
Expand Down
67 changes: 34 additions & 33 deletions src/PIL/WalImageFile.py
Expand Up @@ -23,54 +23,55 @@
To open a WAL file, use the :py:func:`PIL.WalImageFile.open()` function instead.
"""

import builtins

from . import Image
from . import Image, ImageFile
from ._binary import i32le as i32


def open(filename):
"""
Load texture from a Quake2 WAL texture file.
class WalImageFile(ImageFile.ImageFile):

By default, a Quake2 standard palette is attached to the texture.
To override the palette, use the :py:func:`PIL.Image.Image.putpalette()` method.
format = "WAL"
format_description = "Quake2 Texture"

:param filename: WAL file name, or an opened file handle.
:returns: An image instance.
"""
# FIXME: modify to return a WalImageFile instance instead of
# plain Image object ?
def _open(self):
self.mode = "P"

def imopen(fp):
# read header fields
header = fp.read(32 + 24 + 32 + 12)
size = i32(header, 32), i32(header, 36)
offset = i32(header, 40)
header = self.fp.read(32 + 24 + 32 + 12)
self._size = i32(header, 32), i32(header, 36)
Image._decompression_bomb_check(self.size)

# load pixel data
fp.seek(offset)

Image._decompression_bomb_check(size)
im = Image.frombytes("P", size, fp.read(size[0] * size[1]))
im.putpalette(quake2palette)

im.format = "WAL"
im.format_description = "Quake2 Texture"
offset = i32(header, 40)
self.fp.seek(offset)

# strings are null-terminated
im.info["name"] = header[:32].split(b"\0", 1)[0]
self.info["name"] = header[:32].split(b"\0", 1)[0]
next_name = header[56 : 56 + 32].split(b"\0", 1)[0]
if next_name:
im.info["next_name"] = next_name
self.info["next_name"] = next_name

return im
def load(self):
if self.im:
# Already loaded
return

if hasattr(filename, "read"):
return imopen(filename)
else:
with builtins.open(filename, "rb") as fp:
return imopen(fp)
self.im = Image.core.new(self.mode, self.size)
self.frombytes(self.fp.read(self.size[0] * self.size[1]))
self.putpalette(quake2palette)
Image.Image.load(self)


def open(filename):
"""
Load texture from a Quake2 WAL texture file.
By default, a Quake2 standard palette is attached to the texture.
To override the palette, use the :py:func:`PIL.Image.Image.putpalette()` method.
:param filename: WAL file name, or an opened file handle.
:returns: An image instance.
"""
return WalImageFile(filename)


quake2palette = (
Expand Down

0 comments on commit 545196c

Please sign in to comment.