win2xcur/win2xcur/parser/cur.py
2020-09-27 00:55:55 -04:00

42 lines
1.4 KiB
Python

import struct
from typing import List, Tuple
from wand.image import Image
from win2xcur.cursor import CursorFrame, CursorImage
from win2xcur.parser.base import BaseParser
class CURParser(BaseParser):
MAGIC = b'\0\0\02\0'
ICON_DIR = struct.Struct('<HHH')
ICON_DIR_ENTRY = struct.Struct('<BBBBHHII')
@classmethod
def can_parse(cls, blob: bytes) -> bool:
return blob[:len(cls.MAGIC)] == cls.MAGIC
def __init__(self, blob: bytes) -> None:
super().__init__(blob)
self._image = Image(blob=blob, format='cur')
self._hotspots = self._parse_header()
self.frames = [CursorFrame([
CursorImage(image, hotspot) for image, hotspot in zip(self._image.sequence, self._hotspots)
])]
def _parse_header(self) -> List[Tuple[int, int]]:
reserved, ico_type, image_count = self.ICON_DIR.unpack(self.blob[:self.ICON_DIR.size])
assert reserved == 0
assert ico_type == 2
assert image_count == len(self._image.sequence)
offset = self.ICON_DIR.size
hotspots = []
for i in range(image_count):
width, height, palette, reserved, hx, hy, size, file_offset = self.ICON_DIR_ENTRY.unpack(
self.blob[offset:offset + self.ICON_DIR_ENTRY.size])
hotspots.append((hx, hy))
offset += self.ICON_DIR_ENTRY.size
return hotspots