summaryrefslogtreecommitdiffstats
path: root/lib/Python/Lib/PIL/FliImagePlugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Python/Lib/PIL/FliImagePlugin.py')
-rw-r--r--lib/Python/Lib/PIL/FliImagePlugin.py143
1 files changed, 143 insertions, 0 deletions
diff --git a/lib/Python/Lib/PIL/FliImagePlugin.py b/lib/Python/Lib/PIL/FliImagePlugin.py
new file mode 100644
index 000000000..4ecaccdc4
--- /dev/null
+++ b/lib/Python/Lib/PIL/FliImagePlugin.py
@@ -0,0 +1,143 @@
+#
+# The Python Imaging Library.
+# $Id$
+#
+# 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"
+
+from PIL import Image, ImageFile, ImagePalette, _binary
+
+i8 = _binary.i8
+i16 = _binary.i16le
+i32 = _binary.i32le
+o8 = _binary.o8
+
+
+#
+# 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 not (magic in [0xAF11, 0xAF12] and
+ i16(s[14:16]) in [0, 3] and # flags
+ s[20:22] == b"\x00\x00"): # reserved
+ 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 = [(a, a, a) for a in 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 = [o8(r)+o8(g)+o8(b) for (r, g, b) in palette]
+ self.palette = ImagePalette.raw("RGB", b"".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 + i8(s[0])
+ n = i8(s[1])
+ if n == 0:
+ n = 256
+ s = self.fp.read(n * 3)
+ for n in range(0, len(s), 3):
+ r = i8(s[n]) << shift
+ g = i8(s[n+1]) << shift
+ b = i8(s[n+2]) << shift
+ palette[i] = (r, g, b)
+ 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")