diff options
Diffstat (limited to 'PIL/GifImagePlugin.py')
-rw-r--r-- | PIL/GifImagePlugin.py | 405 |
1 files changed, 0 insertions, 405 deletions
diff --git a/PIL/GifImagePlugin.py b/PIL/GifImagePlugin.py deleted file mode 100644 index cce0fe2..0000000 --- a/PIL/GifImagePlugin.py +++ /dev/null @@ -1,405 +0,0 @@ -# -# The Python Imaging Library. -# $Id: GifImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $ -# -# GIF file handling -# -# History: -# 1995-09-01 fl Created -# 1996-12-14 fl Added interlace support -# 1996-12-30 fl Added animation support -# 1997-01-05 fl Added write support, fixed local colour map bug -# 1997-02-23 fl Make sure to load raster data in getdata() -# 1997-07-05 fl Support external decoder (0.4) -# 1998-07-09 fl Handle all modes when saving (0.5) -# 1998-07-15 fl Renamed offset attribute to avoid name clash -# 2001-04-16 fl Added rewind support (seek to frame 0) (0.6) -# 2001-04-17 fl Added palette optimization (0.7) -# 2002-06-06 fl Added transparency support for save (0.8) -# 2004-02-24 fl Disable interlacing for small images -# -# Copyright (c) 1997-2004 by Secret Labs AB -# Copyright (c) 1995-2004 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.9" - - -import Image, ImageFile, ImagePalette - - -# -------------------------------------------------------------------- -# Helpers - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def o16(i): - return chr(i&255) + chr(i>>8&255) - - -# -------------------------------------------------------------------- -# Identify/read GIF files - -def _accept(prefix): - return prefix[:6] in ["GIF87a", "GIF89a"] - -## -# Image plugin for GIF images. This plugin supports both GIF87 and -# GIF89 images. - -class GifImageFile(ImageFile.ImageFile): - - format = "GIF" - format_description = "Compuserve GIF" - - global_palette = None - - def data(self): - s = self.fp.read(1) - if s and ord(s): - return self.fp.read(ord(s)) - return None - - def _open(self): - - # Screen - s = self.fp.read(13) - if s[:6] not in ["GIF87a", "GIF89a"]: - raise SyntaxError, "not a GIF file" - - self.info["version"] = s[:6] - - self.size = i16(s[6:]), i16(s[8:]) - - self.tile = [] - - flags = ord(s[10]) - - bits = (flags & 7) + 1 - - if flags & 128: - # get global palette - self.info["background"] = ord(s[11]) - # check if palette contains colour indices - p = self.fp.read(3<<bits) - for i in range(0, len(p), 3): - if not (chr(i/3) == p[i] == p[i+1] == p[i+2]): - p = ImagePalette.raw("RGB", p) - self.global_palette = self.palette = p - break - - self.__fp = self.fp # FIXME: hack - self.__rewind = self.fp.tell() - self.seek(0) # get ready to read first frame - - def seek(self, frame): - - if frame == 0: - # rewind - self.__offset = 0 - self.dispose = None - self.__frame = -1 - self.__fp.seek(self.__rewind) - - if frame != self.__frame + 1: - raise ValueError, "cannot seek to frame %d" % frame - self.__frame = frame - - self.tile = [] - - self.fp = self.__fp - if self.__offset: - # backup to last frame - self.fp.seek(self.__offset) - while self.data(): - pass - self.__offset = 0 - - if self.dispose: - self.im = self.dispose - self.dispose = None - - self.palette = self.global_palette - - while 1: - - s = self.fp.read(1) - if not s or s == ";": - break - - elif s == "!": - # - # extensions - # - s = self.fp.read(1) - block = self.data() - if ord(s) == 249: - # - # graphic control extension - # - flags = ord(block[0]) - if flags & 1: - self.info["transparency"] = ord(block[3]) - self.info["duration"] = i16(block[1:3]) * 10 - try: - # disposal methods - if flags & 8: - # replace with background colour - self.dispose = Image.core.fill("P", self.size, - self.info["background"]) - elif flags & 16: - # replace with previous contents - self.dispose = self.im.copy() - except (AttributeError, KeyError): - pass - elif ord(s) == 255: - # - # application extension - # - self.info["extension"] = block, self.fp.tell() - if block[:11] == "NETSCAPE2.0": - self.info["loop"] = 1 # FIXME - while self.data(): - pass - - elif s == ",": - # - # local image - # - s = self.fp.read(9) - - # extent - x0, y0 = i16(s[0:]), i16(s[2:]) - x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:]) - flags = ord(s[8]) - - interlace = (flags & 64) != 0 - - if flags & 128: - bits = (flags & 7) + 1 - self.palette =\ - ImagePalette.raw("RGB", self.fp.read(3<<bits)) - - # image data - bits = ord(self.fp.read(1)) - self.__offset = self.fp.tell() - self.tile = [("gif", - (x0, y0, x1, y1), - self.__offset, - (bits, interlace))] - break - - else: - pass - # raise IOError, "illegal GIF tag `%x`" % ord(s) - - if not self.tile: - # self.__fp = None - raise EOFError, "no more images in GIF file" - - self.mode = "L" - if self.palette: - self.mode = "P" - - def tell(self): - return self.__frame - - -# -------------------------------------------------------------------- -# Write GIF files - -try: - import _imaging_gif -except ImportError: - _imaging_gif = None - -RAWMODE = { - "1": "L", - "L": "L", - "P": "P", -} - -def _save(im, fp, filename): - - if _imaging_gif: - # call external driver - try: - _imaging_gif.save(im, fp, filename) - return - except IOError: - pass # write uncompressed file - - try: - rawmode = RAWMODE[im.mode] - imOut = im - except KeyError: - # convert on the fly (EXPERIMENTAL -- I'm not sure PIL - # should automatically convert images on save...) - if Image.getmodebase(im.mode) == "RGB": - imOut = im.convert("P") - rawmode = "P" - else: - imOut = im.convert("L") - rawmode = "L" - - # header - for s in getheader(imOut, im.encoderinfo): - fp.write(s) - - flags = 0 - - try: - interlace = im.encoderinfo["interlace"] - except KeyError: - interlace = 1 - - # workaround for @PIL153 - if min(im.size) < 16: - interlace = 0 - - if interlace: - flags = flags | 64 - - try: - transparency = im.encoderinfo["transparency"] - except KeyError: - pass - else: - # transparency extension block - fp.write("!" + - chr(249) + # extension intro - chr(4) + # length - chr(1) + # transparency info present - o16(0) + # duration - chr(int(transparency)) # transparency index - + chr(0)) - - # local image header - fp.write("," + - o16(0) + o16(0) + # bounding box - o16(im.size[0]) + # size - o16(im.size[1]) + - chr(flags) + # flags - chr(8)) # bits - - imOut.encoderconfig = (8, interlace) - - ImageFile._save(imOut, fp, [("gif", (0,0)+im.size, 0, rawmode)]) - - fp.write("\0") # end of image data - - fp.write(";") # end of file - - try: - fp.flush() - except: pass - -def _save_netpbm(im, fp, filename): - - # - # If you need real GIF compression and/or RGB quantization, you - # can use the external NETPBM/PBMPLUS utilities. See comments - # below for information on how to enable this. - - import os - file = im._dump() - if im.mode != "RGB": - os.system("ppmtogif %s >%s" % (file, filename)) - else: - os.system("ppmquant 256 %s | ppmtogif >%s" % (file, filename)) - try: os.unlink(file) - except: pass - - -# -------------------------------------------------------------------- -# GIF utilities - -def getheader(im, info=None): - """Return a list of strings representing a GIF header""" - - optimize = info and info.get("optimize", 0) - - s = [ - "GIF87a" + # magic - o16(im.size[0]) + # size - o16(im.size[1]) + - chr(7 + 128) + # flags: bits + palette - chr(0) + # background - chr(0) # reserved/aspect - ] - - if optimize: - # minimize color palette - i = 0 - maxcolor = 0 - for count in im.histogram(): - if count: - maxcolor = i - i = i + 1 - else: - maxcolor = 256 - - # global palette - if im.mode == "P": - # colour palette - s.append(im.im.getpalette("RGB")[:maxcolor*3]) - else: - # greyscale - for i in range(maxcolor): - s.append(chr(i) * 3) - - return s - -def getdata(im, offset = (0, 0), **params): - """Return a list of strings representing this image. - The first string is a local image header, the rest contains - encoded image data.""" - - class collector: - data = [] - def write(self, data): - self.data.append(data) - - im.load() # make sure raster data is available - - fp = collector() - - try: - im.encoderinfo = params - - # local image header - fp.write("," + - o16(offset[0]) + # offset - o16(offset[1]) + - o16(im.size[0]) + # size - o16(im.size[1]) + - chr(0) + # flags - chr(8)) # bits - - ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])]) - - fp.write("\0") # end of image data - - finally: - del im.encoderinfo - - return fp.data - - -# -------------------------------------------------------------------- -# Registry - -Image.register_open(GifImageFile.format, GifImageFile, _accept) -Image.register_save(GifImageFile.format, _save) -Image.register_extension(GifImageFile.format, ".gif") -Image.register_mime(GifImageFile.format, "image/gif") - -# -# Uncomment the following line if you wish to use NETPBM/PBMPLUS -# instead of the built-in "uncompressed" GIF encoder - -# Image.register_save(GifImageFile.format, _save_netpbm) |