Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/PIL/FliImagePlugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'PIL/FliImagePlugin.py')
-rw-r--r--PIL/FliImagePlugin.py142
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")