diff options
Diffstat (limited to 'PIL/FliImagePlugin.py')
-rw-r--r-- | PIL/FliImagePlugin.py | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/PIL/FliImagePlugin.py b/PIL/FliImagePlugin.py new file mode 100644 index 0000000..5b1bf8e --- /dev/null +++ b/PIL/FliImagePlugin.py @@ -0,0 +1,142 @@ +# +# The Python Imaging Library. +# $Id: FliImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $ +# +# FLI/FLC file handling. +# +# History: +# 95-09-01 fl Created +# 97-01-03 fl Fixed parser, setup decoder tile +# 98-07-15 fl Renamed offset attribute to avoid name clash +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.2" + +import Image, ImageFile, ImagePalette +import string + + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + +# +# decoder + +def _accept(prefix): + return i16(prefix[4:6]) in [0xAF11, 0xAF12] + +## +# Image plugin for the FLI/FLC animation format. Use the <b>seek</b> +# method to load individual frames. + +class FliImageFile(ImageFile.ImageFile): + + format = "FLI" + format_description = "Autodesk FLI/FLC Animation" + + def _open(self): + + # HEAD + s = self.fp.read(128) + magic = i16(s[4:6]) + if magic not in [0xAF11, 0xAF12]: + raise SyntaxError, "not an FLI/FLC file" + + # image characteristics + self.mode = "P" + self.size = i16(s[8:10]), i16(s[10:12]) + + # animation speed + duration = i32(s[16:20]) + if magic == 0xAF11: + duration = (duration * 1000) / 70 + self.info["duration"] = duration + + # look for palette + palette = map(lambda a: (a,a,a), range(256)) + + s = self.fp.read(16) + + self.__offset = 128 + + if i16(s[4:6]) == 0xF100: + # prefix chunk; ignore it + self.__offset = self.__offset + i32(s) + s = self.fp.read(16) + + if i16(s[4:6]) == 0xF1FA: + # look for palette chunk + s = self.fp.read(6) + if i16(s[4:6]) == 11: + self._palette(palette, 2) + elif i16(s[4:6]) == 4: + self._palette(palette, 0) + + palette = map(lambda (r,g,b): chr(r)+chr(g)+chr(b), palette) + self.palette = ImagePalette.raw("RGB", string.join(palette, "")) + + # set things up to decode first frame + self.frame = -1 + self.__fp = self.fp + + self.seek(0) + + def _palette(self, palette, shift): + # load palette + + i = 0 + for e in range(i16(self.fp.read(2))): + s = self.fp.read(2) + i = i + ord(s[0]) + n = ord(s[1]) + if n == 0: + n = 256 + s = self.fp.read(n * 3) + for n in range(0, len(s), 3): + r = ord(s[n]) << shift + g = ord(s[n+1]) << shift + b = ord(s[n+2]) << shift + palette[i] = (r, g, b) + i = i + 1 + + def seek(self, frame): + + if frame != self.frame + 1: + raise ValueError, "cannot seek to frame %d" % frame + self.frame = frame + + # move to next frame + self.fp = self.__fp + self.fp.seek(self.__offset) + + s = self.fp.read(4) + if not s: + raise EOFError + + framesize = i32(s) + + self.decodermaxblock = framesize + self.tile = [("fli", (0,0)+self.size, self.__offset, None)] + + self.__offset = self.__offset + framesize + + def tell(self): + + return self.frame + +# +# registry + +Image.register_open("FLI", FliImageFile, _accept) + +Image.register_extension("FLI", ".fli") +Image.register_extension("FLI", ".flc") |