|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations |
|
|
|
from . import Image |
|
from ._binary import i32le as i32 |
|
from ._util import DeferredError |
|
from .PcxImagePlugin import PcxImageFile |
|
|
|
MAGIC = 0x3ADE68B1 |
|
|
|
|
|
def _accept(prefix: bytes) -> bool: |
|
return len(prefix) >= 4 and i32(prefix) == MAGIC |
|
|
|
|
|
|
|
|
|
|
|
|
|
class DcxImageFile(PcxImageFile): |
|
format = "DCX" |
|
format_description = "Intel DCX" |
|
_close_exclusive_fp_after_loading = False |
|
|
|
def _open(self) -> None: |
|
|
|
s = self.fp.read(4) |
|
if not _accept(s): |
|
msg = "not a DCX file" |
|
raise SyntaxError(msg) |
|
|
|
|
|
self._offset = [] |
|
for i in range(1024): |
|
offset = i32(self.fp.read(4)) |
|
if not offset: |
|
break |
|
self._offset.append(offset) |
|
|
|
self._fp = self.fp |
|
self.frame = -1 |
|
self.n_frames = len(self._offset) |
|
self.is_animated = self.n_frames > 1 |
|
self.seek(0) |
|
|
|
def seek(self, frame: int) -> None: |
|
if not self._seek_check(frame): |
|
return |
|
if isinstance(self._fp, DeferredError): |
|
raise self._fp.ex |
|
self.frame = frame |
|
self.fp = self._fp |
|
self.fp.seek(self._offset[frame]) |
|
PcxImageFile._open(self) |
|
|
|
def tell(self) -> int: |
|
return self.frame |
|
|
|
|
|
Image.register_open(DcxImageFile.format, DcxImageFile, _accept) |
|
|
|
Image.register_extension(DcxImageFile.format, ".dcx") |
|
|