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