Pillow/PIL/FliImagePlugin.py
Brian Crowell fc035814bd py3k: map and filter to list comprehensions
What's really going on is that map() and filter() return iterators in py3k.
I've just gone ahead and turned them all into list comprehensions, because
I find them much easier to read.
2013-01-10 08:46:43 -06:00

144 lines
3.4 KiB
Python

#
# 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"
import Image, ImageFile, ImagePalette
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 not (magic in [0xAF11, 0xAF12] and
i16(s[14:16]) in [0, 3] and # flags
s[20:22] == '\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 = [chr(r)+chr(g)+chr(b) for (r,g,b) in palette]
self.palette = ImagePalette.raw("RGB", "".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")