Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeshav Sharma <keshav7890@gmail.com>2011-07-13 07:23:54 (GMT)
committer Keshav Sharma <keshav7890@gmail.com>2011-07-13 07:23:54 (GMT)
commit37096ab43aa041ab13c7cafbdf4957a01a182ffe (patch)
tree4dd7eebf257fa77463a320d810957eefe9ccf255
parentff9e8108a9912e60e8d341272c443590eaadb890 (diff)
added camera feature and save on exitHEADmaster
-rw-r--r--AUTHORS.txt12
-rw-r--r--ImageProcess.py6
-rw-r--r--ImageProcessorActivity.py34
-rw-r--r--PIL/ArgImagePlugin.py498
-rw-r--r--PIL/BdfFontFile.py133
-rw-r--r--PIL/BmpImagePlugin.py245
-rw-r--r--PIL/BufrStubImagePlugin.py68
-rw-r--r--PIL/ContainerIO.py116
-rw-r--r--PIL/CurImagePlugin.py90
-rw-r--r--PIL/DcxImagePlugin.py78
-rw-r--r--PIL/EpsImagePlugin.py349
-rw-r--r--PIL/ExifTags.py157
-rw-r--r--PIL/FitsStubImagePlugin.py73
-rw-r--r--PIL/FliImagePlugin.py142
-rw-r--r--PIL/FontFile.py146
-rw-r--r--PIL/FpxImagePlugin.py226
-rw-r--r--PIL/GbrImagePlugin.py70
-rw-r--r--PIL/GdImageFile.py86
-rw-r--r--PIL/GifImagePlugin.py405
-rw-r--r--PIL/GimpGradientFile.py124
-rw-r--r--PIL/GimpPaletteFile.py61
-rw-r--r--PIL/GribStubImagePlugin.py68
-rw-r--r--PIL/Hdf5StubImagePlugin.py70
-rw-r--r--PIL/IcnsImagePlugin.py211
-rw-r--r--PIL/IcoImagePlugin.py88
-rw-r--r--PIL/ImImagePlugin.py335
-rw-r--r--PIL/Image.py2093
-rw-r--r--PIL/ImageChops.py302
-rw-r--r--PIL/ImageColor.py262
-rw-r--r--PIL/ImageDraw.py378
-rw-r--r--PIL/ImageDraw2.py108
-rw-r--r--PIL/ImageEnhance.py89
-rw-r--r--PIL/ImageFile.py520
-rw-r--r--PIL/ImageFileIO.py47
-rw-r--r--PIL/ImageFilter.py263
-rw-r--r--PIL/ImageFont.py377
-rw-r--r--PIL/ImageGL.py28
-rw-r--r--PIL/ImageGrab.py71
-rw-r--r--PIL/ImageMath.py207
-rw-r--r--PIL/ImageMode.py46
-rw-r--r--PIL/ImageOps.py408
-rw-r--r--PIL/ImagePalette.py161
-rw-r--r--PIL/ImagePath.py71
-rw-r--r--PIL/ImageQt.py84
-rw-r--r--PIL/ImageSequence.py38
-rw-r--r--PIL/ImageStat.py179
-rw-r--r--PIL/ImageTk.py296
-rw-r--r--PIL/ImageTransform.py91
-rw-r--r--PIL/ImageWin.py215
-rw-r--r--PIL/ImtImagePlugin.py93
-rw-r--r--PIL/IptcImagePlugin.py280
-rw-r--r--PIL/JpegImagePlugin.py430
-rw-r--r--PIL/McIdasImagePlugin.py74
-rw-r--r--PIL/MicImagePlugin.py96
-rw-r--r--PIL/MpegImagePlugin.py83
-rw-r--r--PIL/MspImagePlugin.py103
-rw-r--r--PIL/OleFileIO.py528
-rw-r--r--PIL/PSDraw.py199
-rw-r--r--PIL/PaletteFile.py53
-rw-r--r--PIL/PalmImagePlugin.py226
-rw-r--r--PIL/PcdImagePlugin.py76
-rw-r--r--PIL/PcfFontFile.py256
-rw-r--r--PIL/PcxImagePlugin.py167
-rw-r--r--PIL/PdfImagePlugin.py210
-rw-r--r--PIL/PixarImagePlugin.py71
-rw-r--r--PIL/PngImagePlugin.py558
-rw-r--r--PIL/PpmImagePlugin.py131
-rw-r--r--PIL/PsdImagePlugin.py271
-rw-r--r--PIL/SgiImagePlugin.py91
-rw-r--r--PIL/SpiderImagePlugin.py294
-rw-r--r--PIL/SunImagePlugin.py87
-rw-r--r--PIL/TarIO.py57
-rw-r--r--PIL/TgaImagePlugin.py133
-rw-r--r--PIL/TiffImagePlugin.py763
-rw-r--r--PIL/TiffTags.py200
-rw-r--r--PIL/WalImageFile.py125
-rw-r--r--PIL/WmfImagePlugin.py148
-rw-r--r--PIL/XVThumbImagePlugin.py68
-rw-r--r--PIL/XbmImagePlugin.py94
-rw-r--r--PIL/XpmImagePlugin.py129
-rw-r--r--PIL/__init__.py12
-rw-r--r--activity/activity.info2
-rw-r--r--activity/activity.info.rtfbin520 -> 0 bytes
-rw-r--r--toolbar.py13
84 files changed, 45 insertions, 16301 deletions
diff --git a/AUTHORS.txt b/AUTHORS.txt
deleted file mode 100644
index bf4dfb3..0000000
--- a/AUTHORS.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Contributors
-============
-Keshav Sharma <keshav7890@gmail.com>
-Vaibhav Sharma
-
-Original author
----------------
-Keshav Sharma <keshav7890@gmail.com>
-
-Maintainers
------------
-Vaibhav Sharma
diff --git a/ImageProcess.py b/ImageProcess.py
index 26506a5..430b852 100644
--- a/ImageProcess.py
+++ b/ImageProcess.py
@@ -528,7 +528,11 @@ class ImageProcessor(gtk.DrawingArea):
rect = gdk.Rectangle(alloc.x, alloc.y, alloc.width, alloc.height)
self.window.invalidate_rect(rect, True)
self.window.process_updates(True)
-
+
+ def save_cb(self,file_path):
+ pixbuf=self.pixbuf
+ pixbuf.save(file_path, 'png', {})
+
#check working of functions
def update(view_object):
view.grey("g")
diff --git a/ImageProcessorActivity.py b/ImageProcessorActivity.py
index 7d41306..a3382e1 100644
--- a/ImageProcessorActivity.py
+++ b/ImageProcessorActivity.py
@@ -184,6 +184,7 @@ class ImageProcessorActivity(activity.Activity):
self._view_toolbar.connect('redo', self.__redo_cb)
self._view_toolbar.connect('save', self.__save_cb)
self._view_toolbar.connect('paste',self.__paste_cb)
+ self._view_toolbar.connect('original',self.view.original_cb)
view_toolbar_button = ToolbarButton(page=self._view_toolbar, icon_name='toolbar-view')
self._view_toolbar.show()
toolbar_box.toolbar.insert(view_toolbar_button, -1)
@@ -232,18 +233,18 @@ class ImageProcessorActivity(activity.Activity):
spacer.props.draw = False
toolbar_box.toolbar.insert(spacer, -1)
spacer.show()
-
- original_button = ToolButton('original')
- original_button.set_tooltip(_('original pic'))
- original_button.connect('clicked', self.view.original_cb)
- toolbar_box.toolbar.insert(original_button, -1)
- original_button.show()
fullscreen_button = ToolButton('view-fullscreen')
fullscreen_button.set_tooltip(_('Fullscreen'))
fullscreen_button.connect('clicked', self.__fullscreen_cb)
toolbar_box.toolbar.insert(fullscreen_button, -1)
fullscreen_button.show()
+
+ cam_button = ToolButton('camera')
+ cam_button.set_tooltip(_('take a pic'))
+ cam_button.connect('clicked', self.cam_cb)
+ toolbar_box.toolbar.insert(cam_button, -1)
+ cam_button.show()
@@ -258,6 +259,24 @@ class ImageProcessorActivity(activity.Activity):
stop_button.show()
+ def cam_cb(self, button):
+ import gst, sys, time
+ from random import *
+ from sugar.datastore import datastore
+ photocmd = 'v4l2src ! ffmpegcolorspace ! jpegenc ! filesink location=/tmp/photo' + '.jpg'
+ # take photo
+ pipeline = gst.parse_launch (photocmd)
+ pipeline.set_state(gst.STATE_PLAYING)
+ time.sleep(3)
+ pipeline.set_state(gst.STATE_NULL)
+ journal_object = datastore.create()
+ journal_object.metadata['title'] = 'new-image'
+ journal_object.metadata['mime_type'] = 'image/jpeg57'
+ journal_object.file_path = '/tmp/photo' + '.jpg'
+ self.view.set_file_location(journal_object.file_path)
+ datastore.write( journal_object )
+ journal_object.destroy()
+
def watermrk_cb(self, button,pos):
self.w="kuch"
self.do_load_an_image_cb(button)
@@ -381,8 +400,7 @@ class ImageProcessorActivity(activity.Activity):
self.metadata['activity'] = self.get_bundle_id()
self.metadata['zoom'] = str(self.zoom)
if self._close_requested:
- os.link(self._tempfile, file_path)
- os.unlink(self._tempfile)
+ self.view.save_cb(file_path)
self._tempfile = None
else:
raise NotImplementedError
diff --git a/PIL/ArgImagePlugin.py b/PIL/ArgImagePlugin.py
deleted file mode 100644
index 48582d9..0000000
--- a/PIL/ArgImagePlugin.py
+++ /dev/null
@@ -1,498 +0,0 @@
-#
-# THIS IS WORK IN PROGRESS
-#
-# The Python Imaging Library.
-# $Id: ArgImagePlugin.py 2309 2005-03-02 15:06:34Z fredrik $
-#
-# ARG animation support code
-#
-# history:
-# 1996-12-30 fl Created
-# 1996-01-06 fl Added safe scripting environment
-# 1996-01-10 fl Added JHDR, UHDR and sYNC support
-# 2005-03-02 fl Removed AAPP and ARUN support
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996-97.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.4"
-
-import marshal, string
-
-import Image, ImageFile, ImagePalette
-
-from PngImagePlugin import i16, i32, ChunkStream, _MODES
-
-MAGIC = "\212ARG\r\n\032\n"
-
-# --------------------------------------------------------------------
-# ARG parser
-
-class ArgStream(ChunkStream):
- "Parser callbacks for ARG data"
-
- def __init__(self, fp):
-
- ChunkStream.__init__(self, fp)
-
- self.eof = 0
-
- self.im = None
- self.palette = None
-
- self.__reset()
-
- def __reset(self):
-
- # reset decoder state (called on init and sync)
-
- self.count = 0
- self.id = None
- self.action = ("NONE",)
-
- self.images = {}
- self.names = {}
-
-
- def chunk_AHDR(self, offset, bytes):
- "AHDR -- animation header"
-
- # assertions
- if self.count != 0:
- raise SyntaxError, "misplaced AHDR chunk"
-
- s = self.fp.read(bytes)
- self.size = i32(s), i32(s[4:])
- try:
- self.mode, self.rawmode = _MODES[(ord(s[8]), ord(s[9]))]
- except:
- raise SyntaxError, "unknown ARG mode"
-
- if Image.DEBUG:
- print "AHDR size", self.size
- print "AHDR mode", self.mode, self.rawmode
-
- return s
-
- def chunk_AFRM(self, offset, bytes):
- "AFRM -- next frame follows"
-
- # assertions
- if self.count != 0:
- raise SyntaxError, "misplaced AFRM chunk"
-
- self.show = 1
- self.id = 0
- self.count = 1
- self.repair = None
-
- s = self.fp.read(bytes)
- if len(s) >= 2:
- self.id = i16(s)
- if len(s) >= 4:
- self.count = i16(s[2:4])
- if len(s) >= 6:
- self.repair = i16(s[4:6])
- else:
- self.repair = None
-
- if Image.DEBUG:
- print "AFRM", self.id, self.count
-
- return s
-
- def chunk_ADEF(self, offset, bytes):
- "ADEF -- store image"
-
- # assertions
- if self.count != 0:
- raise SyntaxError, "misplaced ADEF chunk"
-
- self.show = 0
- self.id = 0
- self.count = 1
- self.repair = None
-
- s = self.fp.read(bytes)
- if len(s) >= 2:
- self.id = i16(s)
- if len(s) >= 4:
- self.count = i16(s[2:4])
-
- if Image.DEBUG:
- print "ADEF", self.id, self.count
-
- return s
-
- def chunk_NAME(self, offset, bytes):
- "NAME -- name the current image"
-
- # assertions
- if self.count == 0:
- raise SyntaxError, "misplaced NAME chunk"
-
- name = self.fp.read(bytes)
- self.names[self.id] = name
-
- return name
-
- def chunk_AEND(self, offset, bytes):
- "AEND -- end of animation"
-
- if Image.DEBUG:
- print "AEND"
-
- self.eof = 1
-
- raise EOFError, "end of ARG file"
-
- def __getmodesize(self, s, full=1):
-
- size = i32(s), i32(s[4:])
-
- try:
- mode, rawmode = _MODES[(ord(s[8]), ord(s[9]))]
- except:
- raise SyntaxError, "unknown image mode"
-
- if full:
- if ord(s[12]):
- pass # interlace not yet supported
- if ord(s[11]):
- raise SyntaxError, "unknown filter category"
-
- return size, mode, rawmode
-
- def chunk_PAST(self, offset, bytes):
- "PAST -- paste one image into another"
-
- # assertions
- if self.count == 0:
- raise SyntaxError, "misplaced PAST chunk"
-
- if self.repair is not None:
- # we must repair the target image before we
- # start pasting
-
- # brute force; a better solution would be to
- # update only the dirty rectangles in images[id].
- # note that if images[id] doesn't exist, it must
- # be created
-
- self.images[self.id] = self.images[self.repair].copy()
- self.repair = None
-
- s = self.fp.read(bytes)
- im = self.images[i16(s)]
- x, y = i32(s[2:6]), i32(s[6:10])
- bbox = x, y, im.size[0]+x, im.size[1]+y
-
- if im.mode in ["RGBA"]:
- # paste with transparency
- # FIXME: should handle P+transparency as well
- self.images[self.id].paste(im, bbox, im)
- else:
- # paste without transparency
- self.images[self.id].paste(im, bbox)
-
- self.action = ("PAST",)
- self.__store()
-
- return s
-
- def chunk_BLNK(self, offset, bytes):
- "BLNK -- create blank image"
-
- # assertions
- if self.count == 0:
- raise SyntaxError, "misplaced BLNK chunk"
-
- s = self.fp.read(bytes)
- size, mode, rawmode = self.__getmodesize(s, 0)
-
- # store image (FIXME: handle colour)
- self.action = ("BLNK",)
- self.im = Image.core.fill(mode, size, 0)
- self.__store()
-
- return s
-
- def chunk_IHDR(self, offset, bytes):
- "IHDR -- full image follows"
-
- # assertions
- if self.count == 0:
- raise SyntaxError, "misplaced IHDR chunk"
-
- # image header
- s = self.fp.read(bytes)
- size, mode, rawmode = self.__getmodesize(s)
-
- # decode and store image
- self.action = ("IHDR",)
- self.im = Image.core.new(mode, size)
- self.decoder = Image.core.zip_decoder(rawmode)
- self.decoder.setimage(self.im, (0,0) + size)
- self.data = ""
-
- return s
-
- def chunk_DHDR(self, offset, bytes):
- "DHDR -- delta image follows"
-
- # assertions
- if self.count == 0:
- raise SyntaxError, "misplaced DHDR chunk"
-
- s = self.fp.read(bytes)
-
- size, mode, rawmode = self.__getmodesize(s)
-
- # delta header
- diff = ord(s[13])
- offs = i32(s[14:18]), i32(s[18:22])
-
- bbox = offs + (offs[0]+size[0], offs[1]+size[1])
-
- if Image.DEBUG:
- print "DHDR", diff, bbox
-
- # FIXME: decode and apply image
- self.action = ("DHDR", diff, bbox)
-
- # setup decoder
- self.im = Image.core.new(mode, size)
-
- self.decoder = Image.core.zip_decoder(rawmode)
- self.decoder.setimage(self.im, (0,0) + size)
-
- self.data = ""
-
- return s
-
- def chunk_JHDR(self, offset, bytes):
- "JHDR -- JPEG image follows"
-
- # assertions
- if self.count == 0:
- raise SyntaxError, "misplaced JHDR chunk"
-
- # image header
- s = self.fp.read(bytes)
- size, mode, rawmode = self.__getmodesize(s, 0)
-
- # decode and store image
- self.action = ("JHDR",)
- self.im = Image.core.new(mode, size)
- self.decoder = Image.core.jpeg_decoder(rawmode)
- self.decoder.setimage(self.im, (0,0) + size)
- self.data = ""
-
- return s
-
- def chunk_UHDR(self, offset, bytes):
- "UHDR -- uncompressed image data follows (EXPERIMENTAL)"
-
- # assertions
- if self.count == 0:
- raise SyntaxError, "misplaced UHDR chunk"
-
- # image header
- s = self.fp.read(bytes)
- size, mode, rawmode = self.__getmodesize(s, 0)
-
- # decode and store image
- self.action = ("UHDR",)
- self.im = Image.core.new(mode, size)
- self.decoder = Image.core.raw_decoder(rawmode)
- self.decoder.setimage(self.im, (0,0) + size)
- self.data = ""
-
- return s
-
- def chunk_IDAT(self, offset, bytes):
- "IDAT -- image data block"
-
- # pass compressed chunks through the decoder
- s = self.fp.read(bytes)
- self.data = self.data + s
- n, e = self.decoder.decode(self.data)
- if n < 0:
- # end of image
- if e < 0:
- raise IOError, "decoder error %d" % e
- else:
- self.data = self.data[n:]
-
- return s
-
- def chunk_DEND(self, offset, bytes):
- return self.chunk_IEND(offset, bytes)
-
- def chunk_JEND(self, offset, bytes):
- return self.chunk_IEND(offset, bytes)
-
- def chunk_UEND(self, offset, bytes):
- return self.chunk_IEND(offset, bytes)
-
- def chunk_IEND(self, offset, bytes):
- "IEND -- end of image"
-
- # we now have a new image. carry out the operation
- # defined by the image header.
-
- # won't need these anymore
- del self.decoder
- del self.data
-
- self.__store()
-
- return self.fp.read(bytes)
-
- def __store(self):
-
- # apply operation
- cid = self.action[0]
-
- if cid in ["BLNK", "IHDR", "JHDR", "UHDR"]:
- # store
- self.images[self.id] = self.im
-
- elif cid == "DHDR":
- # paste
- cid, mode, bbox = self.action
- im0 = self.images[self.id]
- im1 = self.im
- if mode == 0:
- im1 = im1.chop_add_modulo(im0.crop(bbox))
- im0.paste(im1, bbox)
-
- self.count = self.count - 1
-
- if self.count == 0 and self.show:
- self.im = self.images[self.id]
- raise EOFError # end of this frame
-
- def chunk_PLTE(self, offset, bytes):
- "PLTE -- palette data"
-
- s = self.fp.read(bytes)
- if self.mode == "P":
- self.palette = ImagePalette.raw("RGB", s)
- return s
-
- def chunk_sYNC(self, offset, bytes):
- "SYNC -- reset decoder"
-
- if self.count != 0:
- raise SyntaxError, "misplaced sYNC chunk"
-
- s = self.fp.read(bytes)
- self.__reset()
- return s
-
-
-# --------------------------------------------------------------------
-# ARG reader
-
-def _accept(prefix):
- return prefix[:8] == MAGIC
-
-##
-# Image plugin for the experimental Animated Raster Graphics format.
-
-class ArgImageFile(ImageFile.ImageFile):
-
- format = "ARG"
- format_description = "Animated raster graphics"
-
- def _open(self):
-
- if self.fp.read(8) != MAGIC:
- raise SyntaxError, "not an ARG file"
-
- self.arg = ArgStream(self.fp)
-
- # read and process the first chunk (AHDR)
-
- cid, offset, bytes = self.arg.read()
-
- if cid != "AHDR":
- raise SyntaxError, "expected an AHDR chunk"
-
- s = self.arg.call(cid, offset, bytes)
-
- self.arg.crc(cid, s)
-
- # image characteristics
- self.mode = self.arg.mode
- self.size = self.arg.size
-
- def load(self):
-
- if self.arg.im is None:
- self.seek(0)
-
- # image data
- self.im = self.arg.im
- self.palette = self.arg.palette
-
- # set things up for further processing
- Image.Image.load(self)
-
- def seek(self, frame):
-
- if self.arg.eof:
- raise EOFError, "end of animation"
-
- self.fp = self.arg.fp
-
- while 1:
-
- #
- # process chunks
-
- cid, offset, bytes = self.arg.read()
-
- if self.arg.eof:
- raise EOFError, "end of animation"
-
- try:
- s = self.arg.call(cid, offset, bytes)
- except EOFError:
- break
-
- except "glurk": # AttributeError
- if Image.DEBUG:
- print cid, bytes, "(unknown)"
- s = self.fp.read(bytes)
-
- self.arg.crc(cid, s)
-
- self.fp.read(4) # ship extra CRC
-
- def tell(self):
- return 0
-
- def verify(self):
- "Verify ARG file"
-
- # back up to first chunk
- self.fp.seek(8)
-
- self.arg.verify(self)
- self.arg.close()
-
- self.fp = None
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("ARG", ArgImageFile, _accept)
-
-Image.register_extension("ARG", ".arg")
-
-Image.register_mime("ARG", "video/x-arg")
diff --git a/PIL/BdfFontFile.py b/PIL/BdfFontFile.py
deleted file mode 100644
index 9297a18..0000000
--- a/PIL/BdfFontFile.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: BdfFontFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# bitmap distribution font (bdf) file parser
-#
-# history:
-# 1996-05-16 fl created (as bdf2pil)
-# 1997-08-25 fl converted to FontFile driver
-# 2001-05-25 fl removed bogus __init__ call
-# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev)
-# 2003-04-22 fl more robustification (from Graham Dumpleton)
-#
-# Copyright (c) 1997-2003 by Secret Labs AB.
-# Copyright (c) 1997-2003 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import FontFile
-
-import string
-
-# --------------------------------------------------------------------
-# parse X Bitmap Distribution Format (BDF)
-# --------------------------------------------------------------------
-
-bdf_slant = {
- "R": "Roman",
- "I": "Italic",
- "O": "Oblique",
- "RI": "Reverse Italic",
- "RO": "Reverse Oblique",
- "OT": "Other"
-}
-
-bdf_spacing = {
- "P": "Proportional",
- "M": "Monospaced",
- "C": "Cell"
-}
-
-def bdf_char(f):
-
- # skip to STARTCHAR
- while 1:
- s = f.readline()
- if not s:
- return None
- if s[:9] == "STARTCHAR":
- break
- id = string.strip(s[9:])
-
- # load symbol properties
- props = {}
- while 1:
- s = f.readline()
- if not s or s[:6] == "BITMAP":
- break
- i = string.find(s, " ")
- props[s[:i]] = s[i+1:-1]
-
- # load bitmap
- bitmap = []
- while 1:
- s = f.readline()
- if not s or s[:7] == "ENDCHAR":
- break
- bitmap.append(s[:-1])
- bitmap = string.join(bitmap, "")
-
- [x, y, l, d] = map(int, string.split(props["BBX"]))
- [dx, dy] = map(int, string.split(props["DWIDTH"]))
-
- bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y)
-
- try:
- im = Image.fromstring("1", (x, y), bitmap, "hex", "1")
- except ValueError:
- # deal with zero-width characters
- im = Image.new("1", (x, y))
-
- return id, int(props["ENCODING"]), bbox, im
-
-##
-# Font file plugin for the X11 BDF format.
-
-class BdfFontFile(FontFile.FontFile):
-
- def __init__(self, fp):
-
- FontFile.FontFile.__init__(self)
-
- s = fp.readline()
- if s[:13] != "STARTFONT 2.1":
- raise SyntaxError, "not a valid BDF file"
-
- props = {}
- comments = []
-
- while 1:
- s = fp.readline()
- if not s or s[:13] == "ENDPROPERTIES":
- break
- i = string.find(s, " ")
- props[s[:i]] = s[i+1:-1]
- if s[:i] in ["COMMENT", "COPYRIGHT"]:
- if string.find(s, "LogicalFontDescription") < 0:
- comments.append(s[i+1:-1])
-
- font = string.split(props["FONT"], "-")
-
- font[4] = bdf_slant[string.upper(font[4])]
- font[11] = bdf_spacing[string.upper(font[11])]
-
- ascent = int(props["FONT_ASCENT"])
- descent = int(props["FONT_DESCENT"])
-
- fontname = string.join(font[1:], ";")
-
- # print "#", fontname
- # for i in comments:
- # print "#", i
-
- font = []
- while 1:
- c = bdf_char(fp)
- if not c:
- break
- id, ch, (xy, dst, src), im = c
- if ch >= 0 and ch < len(self.glyph):
- self.glyph[ch] = xy, dst, src, im
diff --git a/PIL/BmpImagePlugin.py b/PIL/BmpImagePlugin.py
deleted file mode 100644
index a939d9b..0000000
--- a/PIL/BmpImagePlugin.py
+++ /dev/null
@@ -1,245 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: BmpImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# BMP file handler
-#
-# Windows (and OS/2) native bitmap storage format.
-#
-# history:
-# 1995-09-01 fl Created
-# 1996-04-30 fl Added save
-# 1997-08-27 fl Fixed save of 1-bit images
-# 1998-03-06 fl Load P images as L where possible
-# 1998-07-03 fl Load P images as 1 where possible
-# 1998-12-29 fl Handle small palettes
-# 2002-12-30 fl Fixed load of 1-bit palette images
-# 2003-04-21 fl Fixed load of 1-bit monochrome images
-# 2003-04-23 fl Added limited support for BI_BITFIELDS compression
-#
-# Copyright (c) 1997-2003 by Secret Labs AB
-# Copyright (c) 1995-2003 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.7"
-
-
-import string
-import Image, ImageFile, ImagePalette
-
-
-#
-# --------------------------------------------------------------------
-# Read BMP file
-
-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)
-
-
-BIT2MODE = {
- # bits => mode, rawmode
- 1: ("P", "P;1"),
- 4: ("P", "P;4"),
- 8: ("P", "P"),
- 16: ("RGB", "BGR;16"),
- 24: ("RGB", "BGR"),
- 32: ("RGB", "BGRX")
-}
-
-def _accept(prefix):
- return prefix[:2] == "BM"
-
-##
-# Image plugin for the Windows BMP format.
-
-class BmpImageFile(ImageFile.ImageFile):
-
- format = "BMP"
- format_description = "Windows Bitmap"
-
- def _bitmap(self, header = 0, offset = 0):
-
- if header:
- self.fp.seek(header)
-
- read = self.fp.read
-
- # CORE/INFO
- s = read(4)
- s = s + ImageFile._safe_read(self.fp, i32(s)-4)
-
- if len(s) == 12:
-
- # OS/2 1.0 CORE
- bits = i16(s[10:])
- self.size = i16(s[4:]), i16(s[6:])
- compression = 0
- lutsize = 3
- colors = 0
-
- elif len(s) in [40, 64]:
-
- # WIN 3.1 or OS/2 2.0 INFO
- bits = i16(s[14:])
- self.size = i32(s[4:]), i32(s[8:])
- compression = i32(s[16:])
- lutsize = 4
- colors = i32(s[32:])
-
- else:
- raise IOError("Unsupported BMP header type (%d)" % len(s))
-
- if not colors:
- colors = 1 << bits
-
- # MODE
- try:
- self.mode, rawmode = BIT2MODE[bits]
- except KeyError:
- raise IOError("Unsupported BMP pixel depth (%d)" % bits)
-
- if compression == 3:
- # BI_BITFIELDS compression
- mask = i32(read(4)), i32(read(4)), i32(read(4))
- if bits == 32 and mask == (0xff0000, 0x00ff00, 0x0000ff):
- rawmode = "BGRX"
- elif bits == 16 and mask == (0x00f800, 0x0007e0, 0x00001f):
- rawmode = "BGR;16"
- elif bits == 16 and mask == (0x007c00, 0x0003e0, 0x00001f):
- rawmode = "BGR;15"
- else:
- # print bits, map(hex, mask)
- raise IOError("Unsupported BMP bitfields layout")
- elif compression != 0:
- raise IOError("Unsupported BMP compression (%d)" % compression)
-
- # LUT
- if self.mode == "P":
- palette = []
- greyscale = 1
- if colors == 2:
- indices = (0, 255)
- else:
- indices = range(colors)
- for i in indices:
- rgb = read(lutsize)[:3]
- if rgb != chr(i)*3:
- greyscale = 0
- palette.append(rgb)
- if greyscale:
- if colors == 2:
- self.mode = rawmode = "1"
- else:
- self.mode = rawmode = "L"
- else:
- self.mode = "P"
- self.palette = ImagePalette.raw(
- "BGR", string.join(palette, "")
- )
-
- if not offset:
- offset = self.fp.tell()
-
- self.tile = [("raw",
- (0, 0) + self.size,
- offset,
- (rawmode, ((self.size[0]*bits+31)>>3)&(~3), -1))]
-
- self.info["compression"] = compression
-
- def _open(self):
-
- # HEAD
- s = self.fp.read(14)
- if s[:2] != "BM":
- raise SyntaxError("Not a BMP file")
- offset = i32(s[10:])
-
- self._bitmap(offset=offset)
-
-
-class DibImageFile(BmpImageFile):
-
- format = "DIB"
- format_description = "Windows Bitmap"
-
- def _open(self):
- self._bitmap()
-
-#
-# --------------------------------------------------------------------
-# Write BMP file
-
-def o16(i):
- return chr(i&255) + chr(i>>8&255)
-
-def o32(i):
- return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
-
-SAVE = {
- "1": ("1", 1, 2),
- "L": ("L", 8, 256),
- "P": ("P", 8, 256),
- "RGB": ("BGR", 24, 0),
-}
-
-def _save(im, fp, filename, check=0):
-
- try:
- rawmode, bits, colors = SAVE[im.mode]
- except KeyError:
- raise IOError("cannot write mode %s as BMP" % im.mode)
-
- if check:
- return check
-
- stride = ((im.size[0]*bits+7)/8+3)&(~3)
- header = 40 # or 64 for OS/2 version 2
- offset = 14 + header + colors * 4
- image = stride * im.size[1]
-
- # bitmap header
- fp.write("BM" + # file type (magic)
- o32(offset+image) + # file size
- o32(0) + # reserved
- o32(offset)) # image data offset
-
- # bitmap info header
- fp.write(o32(header) + # info header size
- o32(im.size[0]) + # width
- o32(im.size[1]) + # height
- o16(1) + # planes
- o16(bits) + # depth
- o32(0) + # compression (0=uncompressed)
- o32(image) + # size of bitmap
- o32(1) + o32(1) + # resolution
- o32(colors) + # colors used
- o32(colors)) # colors important
-
- fp.write("\000" * (header - 40)) # padding (for OS/2 format)
-
- if im.mode == "1":
- for i in (0, 255):
- fp.write(chr(i) * 4)
- elif im.mode == "L":
- for i in range(256):
- fp.write(chr(i) * 4)
- elif im.mode == "P":
- fp.write(im.im.getpalette("RGB", "BGRX"))
-
- ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, stride, -1))])
-
-#
-# --------------------------------------------------------------------
-# Registry
-
-Image.register_open(BmpImageFile.format, BmpImageFile, _accept)
-Image.register_save(BmpImageFile.format, _save)
-
-Image.register_extension(BmpImageFile.format, ".bmp")
diff --git a/PIL/BufrStubImagePlugin.py b/PIL/BufrStubImagePlugin.py
deleted file mode 100644
index ee02659..0000000
--- a/PIL/BufrStubImagePlugin.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: BufrStubImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# BUFR stub adapter
-#
-# Copyright (c) 1996-2003 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageFile
-
-_handler = None
-
-##
-# Install application-specific BUFR image handler.
-#
-# @param handler Handler object.
-
-def register_handler(handler):
- global _handler
- _handler = handler
-
-# --------------------------------------------------------------------
-# Image adapter
-
-def _accept(prefix):
- return prefix[:4] == "BUFR" or prefix[:4] == "ZCZC"
-
-class BufrStubImageFile(ImageFile.StubImageFile):
-
- format = "BUFR"
- format_description = "BUFR"
-
- def _open(self):
-
- offset = self.fp.tell()
-
- if not _accept(self.fp.read(8)):
- raise SyntaxError("Not a BUFR file")
-
- self.fp.seek(offset)
-
- # make something up
- self.mode = "F"
- self.size = 1, 1
-
- loader = self._load()
- if loader:
- loader.open(self)
-
- def _load(self):
- return _handler
-
-def _save(im, fp, filename):
- if _handler is None or not hasattr("_handler", "save"):
- raise IOError("BUFR save handler not installed")
- _handler.save(im, fp, filename)
-
-
-# --------------------------------------------------------------------
-# Registry
-
-Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept)
-Image.register_save(BufrStubImageFile.format, _save)
-
-Image.register_extension(BufrStubImageFile.format, ".bufr")
diff --git a/PIL/ContainerIO.py b/PIL/ContainerIO.py
deleted file mode 100644
index 7b7283f..0000000
--- a/PIL/ContainerIO.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ContainerIO.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# a class to read from a container file
-#
-# History:
-# 1995-06-18 fl Created
-# 1995-09-07 fl Added readline(), readlines()
-#
-# Copyright (c) 1997-2001 by Secret Labs AB
-# Copyright (c) 1995 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-##
-# A file object that provides read access to a part of an existing
-# file (for example a TAR file).
-
-class ContainerIO:
-
- ##
- # Create file object.
- #
- # @param file Existing file.
- # @param offset Start of region, in bytes.
- # @param length Size of region, in bytes.
-
- def __init__(self, file, offset, length):
- self.fh = file
- self.pos = 0
- self.offset = offset
- self.length = length
- self.fh.seek(offset)
-
- ##
- # Always false.
-
- def isatty(self):
- return 0
-
- ##
- # Move file pointer.
- #
- # @param offset Offset in bytes.
- # @param mode Starting position. Use 0 for beginning of region, 1
- # for current offset, and 2 for end of region. You cannot move
- # the pointer outside the defined region.
-
- def seek(self, offset, mode = 0):
- if mode == 1:
- self.pos = self.pos + offset
- elif mode == 2:
- self.pos = self.length + offset
- else:
- self.pos = offset
- # clamp
- self.pos = max(0, min(self.pos, self.length))
- self.fh.seek(self.offset + self.pos)
-
- ##
- # Get current file pointer.
- #
- # @return Offset from start of region, in bytes.
-
- def tell(self):
- return self.pos
-
- ##
- # Read data.
- #
- # @def read(bytes=0)
- # @param bytes Number of bytes to read. If omitted or zero,
- # read until end of region.
- # @return An 8-bit string.
-
- def read(self, n = 0):
- if n:
- n = min(n, self.length - self.pos)
- else:
- n = self.length - self.pos
- if not n: # EOF
- return ""
- self.pos = self.pos + n
- return self.fh.read(n)
-
- ##
- # Read a line of text.
- #
- # @return An 8-bit string.
-
- def readline(self):
- s = ""
- while 1:
- c = self.read(1)
- if not c:
- break
- s = s + c
- if c == "\n":
- break
- return s
-
- ##
- # Read multiple lines of text.
- #
- # @return A list of 8-bit strings.
-
- def readlines(self):
- l = []
- while 1:
- s = self.readline()
- if not s:
- break
- l.append(s)
- return l
diff --git a/PIL/CurImagePlugin.py b/PIL/CurImagePlugin.py
deleted file mode 100644
index b879da3..0000000
--- a/PIL/CurImagePlugin.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: CurImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# Windows Cursor support for PIL
-#
-# notes:
-# uses BmpImagePlugin.py to read the bitmap data.
-#
-# history:
-# 96-05-27 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.1"
-
-import string
-
-import Image, BmpImagePlugin
-
-
-#
-# --------------------------------------------------------------------
-
-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)
-
-
-def _accept(prefix):
- return prefix[:4] == "\0\0\2\0"
-
-##
-# Image plugin for Windows Cursor files.
-
-class CurImageFile(BmpImagePlugin.BmpImageFile):
-
- format = "CUR"
- format_description = "Windows Cursor"
-
- def _open(self):
-
- offset = self.fp.tell()
-
- # check magic
- s = self.fp.read(6)
- if not _accept(s):
- raise SyntaxError, "not an CUR file"
-
- # pick the largest cursor in the file
- m = ""
- for i in range(i16(s[4:])):
- s = self.fp.read(16)
- if not m:
- m = s
- elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
- m = s
- #print "width", ord(s[0])
- #print "height", ord(s[1])
- #print "colors", ord(s[2])
- #print "reserved", ord(s[3])
- #print "hotspot x", i16(s[4:])
- #print "hotspot y", i16(s[6:])
- #print "bytes", i32(s[8:])
- #print "offset", i32(s[12:])
-
- # load as bitmap
- self._bitmap(i32(m[12:]) + offset)
-
- # patch up the bitmap height
- self.size = self.size[0], self.size[1]/2
- d, e, o, a = self.tile[0]
- self.tile[0] = d, (0,0)+self.size, o, a
-
- return
-
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("CUR", CurImageFile, _accept)
-
-Image.register_extension("CUR", ".cur")
diff --git a/PIL/DcxImagePlugin.py b/PIL/DcxImagePlugin.py
deleted file mode 100644
index 3a0df01..0000000
--- a/PIL/DcxImagePlugin.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: DcxImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# DCX file handling
-#
-# DCX is a container file format defined by Intel, commonly used
-# for fax applications. Each DCX file consists of a directory
-# (a list of file offsets) followed by a set of (usually 1-bit)
-# PCX files.
-#
-# History:
-# 1995-09-09 fl Created
-# 1996-03-20 fl Properly derived from PcxImageFile.
-# 1998-07-15 fl Renamed offset attribute to avoid name clash
-# 2002-07-30 fl Fixed file handling
-#
-# Copyright (c) 1997-98 by Secret Labs AB.
-# Copyright (c) 1995-96 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.2"
-
-import Image, ImageFile
-
-from PcxImagePlugin import PcxImageFile
-
-MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then?
-
-def i32(c):
- return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
-
-def _accept(prefix):
- return i32(prefix) == MAGIC
-
-##
-# Image plugin for the Intel DCX format.
-
-class DcxImageFile(PcxImageFile):
-
- format = "DCX"
- format_description = "Intel DCX"
-
- def _open(self):
-
- # Header
- s = self.fp.read(4)
- if i32(s) != MAGIC:
- raise SyntaxError, "not a DCX file"
-
- # Component directory
- self._offset = []
- for i in range(1024):
- offset = i32(self.fp.read(4))
- if not offset:
- break
- self._offset.append(offset)
-
- self.__fp = self.fp
- self.seek(0)
-
- def seek(self, frame):
- if frame >= len(self._offset):
- raise EOFError("attempt to seek outside DCX directory")
- self.frame = frame
- self.fp = self.__fp
- self.fp.seek(self._offset[frame])
- PcxImageFile._open(self)
-
- def tell(self):
- return self.frame
-
-
-Image.register_open("DCX", DcxImageFile, _accept)
-
-Image.register_extension("DCX", ".dcx")
diff --git a/PIL/EpsImagePlugin.py b/PIL/EpsImagePlugin.py
deleted file mode 100644
index e0a608e..0000000
--- a/PIL/EpsImagePlugin.py
+++ /dev/null
@@ -1,349 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: EpsImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# EPS file handling
-#
-# History:
-# 1995-09-01 fl Created (0.1)
-# 1996-05-18 fl Don't choke on "atend" fields, Ghostscript interface (0.2)
-# 1996-08-22 fl Don't choke on floating point BoundingBox values
-# 1996-08-23 fl Handle files from Macintosh (0.3)
-# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4)
-# 2003-09-07 fl Check gs.close status (from Federico Di Gregorio) (0.5)
-#
-# Copyright (c) 1997-2003 by Secret Labs AB.
-# Copyright (c) 1995-2003 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.5"
-
-import re, string
-import Image, ImageFile
-
-#
-# --------------------------------------------------------------------
-
-def i32(c):
- return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
-
-def o32(i):
- return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
-
-split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$")
-field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$")
-
-def Ghostscript(tile, size, fp):
- """Render an image using Ghostscript (Unix only)"""
-
- # Unpack decoder tile
- decoder, tile, offset, data = tile[0]
- length, bbox = data
-
- import tempfile, os
-
- file = tempfile.mktemp()
-
- # Build ghostscript command
- command = ["gs",
- "-q", # quite mode
- "-g%dx%d" % size, # set output geometry (pixels)
- "-dNOPAUSE -dSAFER", # don't pause between pages, safe mode
- "-sDEVICE=ppmraw", # ppm driver
- "-sOutputFile=%s" % file,# output file
- "- >/dev/null 2>/dev/null"]
-
- command = string.join(command)
-
- # push data through ghostscript
- try:
- gs = os.popen(command, "w")
- # adjust for image origin
- if bbox[0] != 0 or bbox[1] != 0:
- gs.write("%d %d translate\n" % (-bbox[0], -bbox[1]))
- fp.seek(offset)
- while length > 0:
- s = fp.read(8192)
- if not s:
- break
- length = length - len(s)
- gs.write(s)
- status = gs.close()
- if status:
- raise IOError("gs failed (status %d)" % status)
- im = Image.core.open_ppm(file)
- finally:
- try: os.unlink(file)
- except: pass
-
- return im
-
-
-class PSFile:
- """Wrapper that treats either CR or LF as end of line."""
- def __init__(self, fp):
- self.fp = fp
- self.char = None
- def __getattr__(self, id):
- v = getattr(self.fp, id)
- setattr(self, id, v)
- return v
- def seek(self, offset, whence=0):
- self.char = None
- self.fp.seek(offset, whence)
- def tell(self):
- pos = self.fp.tell()
- if self.char:
- pos = pos - 1
- return pos
- def readline(self):
- s = ""
- if self.char:
- c = self.char
- self.char = None
- else:
- c = self.fp.read(1)
- while c not in "\r\n":
- s = s + c
- c = self.fp.read(1)
- if c == "\r":
- self.char = self.fp.read(1)
- if self.char == "\n":
- self.char = None
- return s + "\n"
-
-
-def _accept(prefix):
- return prefix[:4] == "%!PS" or i32(prefix) == 0xC6D3D0C5L
-
-##
-# Image plugin for Encapsulated Postscript. This plugin supports only
-# a few variants of this format.
-
-class EpsImageFile(ImageFile.ImageFile):
- """EPS File Parser for the Python Imaging Library"""
-
- format = "EPS"
- format_description = "Encapsulated Postscript"
-
- def _open(self):
-
- # FIXME: should check the first 512 bytes to see if this
- # really is necessary (platform-dependent, though...)
-
- fp = PSFile(self.fp)
-
- # HEAD
- s = fp.read(512)
- if s[:4] == "%!PS":
- offset = 0
- fp.seek(0, 2)
- length = fp.tell()
- elif i32(s) == 0xC6D3D0C5L:
- offset = i32(s[4:])
- length = i32(s[8:])
- fp.seek(offset)
- else:
- raise SyntaxError, "not an EPS file"
-
- fp.seek(offset)
-
- box = None
-
- self.mode = "RGB"
- self.size = 1, 1 # FIXME: huh?
-
- #
- # Load EPS header
-
- s = fp.readline()
-
- while s:
-
- if len(s) > 255:
- raise SyntaxError, "not an EPS file"
-
- if s[-2:] == '\r\n':
- s = s[:-2]
- elif s[-1:] == '\n':
- s = s[:-1]
-
- try:
- m = split.match(s)
- except re.error, v:
- raise SyntaxError, "not an EPS file"
-
- if m:
- k, v = m.group(1, 2)
- self.info[k] = v
- if k == "BoundingBox":
- try:
- # Note: The DSC spec says that BoundingBox
- # fields should be integers, but some drivers
- # put floating point values there anyway.
- box = map(int, map(float, string.split(v)))
- self.size = box[2] - box[0], box[3] - box[1]
- self.tile = [("eps", (0,0) + self.size, offset,
- (length, box))]
- except:
- pass
-
- else:
-
- m = field.match(s)
-
- if m:
- k = m.group(1)
- if k == "EndComments":
- break
- if k[:8] == "PS-Adobe":
- self.info[k[:8]] = k[9:]
- else:
- self.info[k] = ""
- else:
- raise IOError, "bad EPS header"
-
- s = fp.readline()
-
- if s[:1] != "%":
- break
-
-
- #
- # Scan for an "ImageData" descriptor
-
- while s[0] == "%":
-
- if len(s) > 255:
- raise SyntaxError, "not an EPS file"
-
- if s[-2:] == '\r\n':
- s = s[:-2]
- elif s[-1:] == '\n':
- s = s[:-1]
-
- if s[:11] == "%ImageData:":
-
- [x, y, bi, mo, z3, z4, en, id] =\
- string.split(s[11:], maxsplit=7)
-
- x = int(x); y = int(y)
-
- bi = int(bi)
- mo = int(mo)
-
- en = int(en)
-
- if en == 1:
- decoder = "eps_binary"
- elif en == 2:
- decoder = "eps_hex"
- else:
- break
- if bi != 8:
- break
- if mo == 1:
- self.mode = "L"
- elif mo == 2:
- self.mode = "LAB"
- elif mo == 3:
- self.mode = "RGB"
- else:
- break
-
- if id[:1] == id[-1:] == '"':
- id = id[1:-1]
-
- # Scan forward to the actual image data
- while 1:
- s = fp.readline()
- if not s:
- break
- if s[:len(id)] == id:
- self.size = x, y
- self.tile2 = [(decoder,
- (0, 0, x, y),
- fp.tell(),
- 0)]
- return
-
- s = fp.readline()
- if not s:
- break
-
- if not box:
- raise IOError, "cannot determine EPS bounding box"
-
- def load(self):
- # Load EPS via Ghostscript
- if not self.tile:
- return
- self.im = Ghostscript(self.tile, self.size, self.fp)
- self.mode = self.im.mode
- self.size = self.im.size
- self.tile = []
-
-#
-# --------------------------------------------------------------------
-
-def _save(im, fp, filename, eps=1):
- """EPS Writer for the Python Imaging Library."""
-
- #
- # make sure image data is available
- im.load()
-
- #
- # determine postscript image mode
- if im.mode == "L":
- operator = (8, 1, "image")
- elif im.mode == "RGB":
- operator = (8, 3, "false 3 colorimage")
- elif im.mode == "CMYK":
- operator = (8, 4, "false 4 colorimage")
- else:
- raise ValueError, "image mode is not supported"
-
- if eps:
- #
- # write EPS header
- fp.write("%!PS-Adobe-3.0 EPSF-3.0\n")
- fp.write("%%Creator: PIL 0.1 EpsEncode\n")
- #fp.write("%%CreationDate: %s"...)
- fp.write("%%%%BoundingBox: 0 0 %d %d\n" % im.size)
- fp.write("%%Pages: 1\n")
- fp.write("%%EndComments\n")
- fp.write("%%Page: 1 1\n")
- fp.write("%%ImageData: %d %d " % im.size)
- fp.write("%d %d 0 1 1 \"%s\"\n" % operator)
-
- #
- # image header
- fp.write("gsave\n")
- fp.write("10 dict begin\n")
- fp.write("/buf %d string def\n" % (im.size[0] * operator[1]))
- fp.write("%d %d scale\n" % im.size)
- fp.write("%d %d 8\n" % im.size) # <= bits
- fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]))
- fp.write("{ currentfile buf readhexstring pop } bind\n")
- fp.write("%s\n" % operator[2])
-
- ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)])
-
- fp.write("\n%%%%EndBinary\n")
- fp.write("grestore end\n")
- fp.flush()
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open(EpsImageFile.format, EpsImageFile, _accept)
-
-Image.register_save(EpsImageFile.format, _save)
-
-Image.register_extension(EpsImageFile.format, ".ps")
-Image.register_extension(EpsImageFile.format, ".eps")
-
-Image.register_mime(EpsImageFile.format, "application/postscript")
diff --git a/PIL/ExifTags.py b/PIL/ExifTags.py
deleted file mode 100644
index 01a6b74..0000000
--- a/PIL/ExifTags.py
+++ /dev/null
@@ -1,157 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ExifTags.py 2631 2006-02-12 23:41:52Z fredrik $
-#
-# EXIF tags
-#
-# Copyright (c) 2003 by Secret Labs AB
-#
-# See the README file for information on usage and redistribution.
-#
-
-##
-# This module provides constants and clear-text names for various
-# well-known EXIF tags.
-##
-
-##
-# Maps EXIF tags to tag names.
-
-TAGS = {
-
- # possibly incomplete
- 0x0100: "ImageWidth",
- 0x0101: "ImageLength",
- 0x0102: "BitsPerSample",
- 0x0103: "Compression",
- 0x0106: "PhotometricInterpretation",
- 0x010e: "ImageDescription",
- 0x010f: "Make",
- 0x0110: "Model",
- 0x0111: "StripOffsets",
- 0x0112: "Orientation",
- 0x0115: "SamplesPerPixel",
- 0x0116: "RowsPerStrip",
- 0x0117: "StripByteConunts",
- 0x011a: "XResolution",
- 0x011a: "XResolution",
- 0x011b: "YResolution",
- 0x011b: "YResolution",
- 0x011c: "PlanarConfiguration",
- 0x0128: "ResolutionUnit",
- 0x0128: "ResolutionUnit",
- 0x012d: "TransferFunction",
- 0x0131: "Software",
- 0x0132: "DateTime",
- 0x013b: "Artist",
- 0x013e: "WhitePoint",
- 0x013f: "PrimaryChromaticities",
- 0x0201: "JpegIFOffset",
- 0x0202: "JpegIFByteCount",
- 0x0211: "YCbCrCoefficients",
- 0x0211: "YCbCrCoefficients",
- 0x0212: "YCbCrSubSampling",
- 0x0213: "YCbCrPositioning",
- 0x0213: "YCbCrPositioning",
- 0x0214: "ReferenceBlackWhite",
- 0x0214: "ReferenceBlackWhite",
- 0x1000: "RelatedImageFileFormat",
- 0x1001: "RelatedImageLength",
- 0x1001: "RelatedImageWidth",
- 0x828d: "CFARepeatPatternDim",
- 0x828e: "CFAPattern",
- 0x828f: "BatteryLevel",
- 0x8298: "Copyright",
- 0x829a: "ExposureTime",
- 0x829d: "FNumber",
- 0x8769: "ExifOffset",
- 0x8773: "InterColorProfile",
- 0x8822: "ExposureProgram",
- 0x8824: "SpectralSensitivity",
- 0x8825: "GPSInfo",
- 0x8827: "ISOSpeedRatings",
- 0x8828: "OECF",
- 0x8829: "Interlace",
- 0x882a: "TimeZoneOffset",
- 0x882b: "SelfTimerMode",
- 0x9000: "ExifVersion",
- 0x9003: "DateTimeOriginal",
- 0x9004: "DateTimeDigitized",
- 0x9101: "ComponentsConfiguration",
- 0x9102: "CompressedBitsPerPixel",
- 0x9201: "ShutterSpeedValue",
- 0x9202: "ApertureValue",
- 0x9203: "BrightnessValue",
- 0x9204: "ExposureBiasValue",
- 0x9205: "MaxApertureValue",
- 0x9206: "SubjectDistance",
- 0x9207: "MeteringMode",
- 0x9208: "LightSource",
- 0x9209: "Flash",
- 0x920a: "FocalLength",
- 0x920b: "FlashEnergy",
- 0x920c: "SpatialFrequencyResponse",
- 0x920d: "Noise",
- 0x9211: "ImageNumber",
- 0x9212: "SecurityClassification",
- 0x9213: "ImageHistory",
- 0x9214: "SubjectLocation",
- 0x9215: "ExposureIndex",
- 0x9216: "TIFF/EPStandardID",
- 0x927c: "MakerNote",
- 0x9286: "UserComment",
- 0x9290: "SubsecTime",
- 0x9291: "SubsecTimeOriginal",
- 0x9292: "SubsecTimeDigitized",
- 0xa000: "FlashPixVersion",
- 0xa001: "ColorSpace",
- 0xa002: "ExifImageWidth",
- 0xa003: "ExifImageHeight",
- 0xa004: "RelatedSoundFile",
- 0xa005: "ExifInteroperabilityOffset",
- 0xa20b: "FlashEnergy",
- 0xa20c: "SpatialFrequencyResponse",
- 0xa20e: "FocalPlaneXResolution",
- 0xa20f: "FocalPlaneYResolution",
- 0xa210: "FocalPlaneResolutionUnit",
- 0xa214: "SubjectLocation",
- 0xa215: "ExposureIndex",
- 0xa217: "SensingMethod",
- 0xa300: "FileSource",
- 0xa301: "SceneType",
- 0xa302: "CFAPattern",
-
-}
-
-##
-# Maps EXIF GSP tags to tag names.
-
-GPSTAGS = {
- 0: "GPSVersionID",
- 1: "GPSLatitudeRef",
- 2: "GPSLatitude",
- 3: "GPSLongitudeRef",
- 4: "GPSLongitude",
- 5: "GPSAltitudeRef",
- 6: "GPSAltitude",
- 7: "GPSTimeStamp",
- 8: "GPSSatellites",
- 9: "GPSStatus",
- 10: "GPSMeasureMode",
- 11: "GPSDOP",
- 12: "GPSSpeedRef",
- 13: "GPSSpeed",
- 14: "GPSTrackRef",
- 15: "GPSTrack",
- 16: "GPSImgDirectionRef",
- 17: "GPSImgDirection",
- 18: "GPSMapDatum",
- 19: "GPSDestLatitudeRef",
- 20: "GPSDestLatitude",
- 21: "GPSDestLongitudeRef",
- 22: "GPSDestLongitude",
- 23: "GPSDestBearingRef",
- 24: "GPSDestBearing",
- 25: "GPSDestDistanceRef",
- 26: "GPSDestDistance"
-}
diff --git a/PIL/FitsStubImagePlugin.py b/PIL/FitsStubImagePlugin.py
deleted file mode 100644
index 05f5d46..0000000
--- a/PIL/FitsStubImagePlugin.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: FitsStubImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# FITS stub adapter
-#
-# Copyright (c) 1998-2003 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageFile
-
-_handler = None
-
-##
-# Install application-specific FITS image handler.
-#
-# @param handler Handler object.
-
-def register_handler(handler):
- global _handler
- _handler = handler
-
-# --------------------------------------------------------------------
-# Image adapter
-
-def _accept(prefix):
- return prefix[:6] == "SIMPLE"
-
-class FITSStubImageFile(ImageFile.StubImageFile):
-
- format = "FITS"
- format_description = "FITS"
-
- def _open(self):
-
- offset = self.fp.tell()
-
- if not _accept(self.fp.read(6)):
- raise SyntaxError("Not a FITS file")
-
- # FIXME: add more sanity checks here; mandatory header items
- # include SIMPLE, BITPIX, NAXIS, etc.
-
- self.fp.seek(offset)
-
- # make something up
- self.mode = "F"
- self.size = 1, 1
-
- loader = self._load()
- if loader:
- loader.open(self)
-
- def _load(self):
- return _handler
-
-
-def _save(im, fp, filename):
- if _handler is None or not hasattr("_handler", "save"):
- raise IOError("FITS save handler not installed")
- _handler.save(im, fp, filename)
-
-
-# --------------------------------------------------------------------
-# Registry
-
-Image.register_open(FITSStubImageFile.format, FITSStubImageFile, _accept)
-Image.register_save(FITSStubImageFile.format, _save)
-
-Image.register_extension(FITSStubImageFile.format, ".fit")
-Image.register_extension(FITSStubImageFile.format, ".fits")
diff --git a/PIL/FliImagePlugin.py b/PIL/FliImagePlugin.py
deleted file mode 100644
index 5b1bf8e..0000000
--- a/PIL/FliImagePlugin.py
+++ /dev/null
@@ -1,142 +0,0 @@
-#
-# 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")
diff --git a/PIL/FontFile.py b/PIL/FontFile.py
deleted file mode 100644
index bf4b905..0000000
--- a/PIL/FontFile.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: FontFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# base class for raster font file parsers
-#
-# history:
-# 1997-06-05 fl created
-# 1997-08-19 fl restrict image width
-#
-# Copyright (c) 1997-1998 by Secret Labs AB
-# Copyright (c) 1997-1998 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import os
-import Image
-
-import marshal
-
-try:
- import zlib
-except ImportError:
- zlib = None
-
-WIDTH = 800
-
-def puti16(fp, values):
- # write network order (big-endian) 16-bit sequence
- for v in values:
- if v < 0:
- v = v + 65536
- fp.write(chr(v>>8&255) + chr(v&255))
-
-##
-# Base class for raster font file handlers.
-
-class FontFile:
-
- bitmap = None
-
- def __init__(self):
-
- self.info = {}
- self.glyph = [None] * 256
-
- def __getitem__(self, ix):
- return self.glyph[ix]
-
- def compile(self):
- "Create metrics and bitmap"
-
- if self.bitmap:
- return
-
- # create bitmap large enough to hold all data
- h = w = maxwidth = 0
- lines = 1
- for glyph in self:
- if glyph:
- d, dst, src, im = glyph
- h = max(h, src[3] - src[1])
- w = w + (src[2] - src[0])
- if w > WIDTH:
- lines = lines + 1
- w = (src[2] - src[0])
- maxwidth = max(maxwidth, w)
-
- xsize = maxwidth
- ysize = lines * h
-
- if xsize == 0 and ysize == 0:
- return ""
-
- self.ysize = h
-
- # paste glyphs into bitmap
- self.bitmap = Image.new("1", (xsize, ysize))
- self.metrics = [None] * 256
- x = y = 0
- for i in range(256):
- glyph = self[i]
- if glyph:
- d, dst, src, im = glyph
- xx, yy = src[2] - src[0], src[3] - src[1]
- x0, y0 = x, y
- x = x + xx
- if x > WIDTH:
- x, y = 0, y + h
- x0, y0 = x, y
- x = xx
- s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0
- self.bitmap.paste(im.crop(src), s)
- # print chr(i), dst, s
- self.metrics[i] = d, dst, s
-
-
- def save1(self, filename):
- "Save font in version 1 format"
-
- self.compile()
-
- # font data
- self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG")
-
- # font metrics
- fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
- fp.write("PILfont\n")
- fp.write(";;;;;;%d;\n" % self.ysize) # HACK!!!
- fp.write("DATA\n")
- for id in range(256):
- m = self.metrics[id]
- if not m:
- puti16(fp, [0] * 10)
- else:
- puti16(fp, m[0] + m[1] + m[2])
- fp.close()
-
-
- def save2(self, filename):
- "Save font in version 2 format"
-
- # THIS IS WORK IN PROGRESS
-
- self.compile()
-
- data = marshal.dumps((self.metrics, self.info))
-
- if zlib:
- data = "z" + zlib.compress(data, 9)
- else:
- data = "u" + data
-
- fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
-
- fp.write("PILfont2\n" + self.name + "\n" + "DATA\n")
-
- fp.write(data)
-
- self.bitmap.save(fp, "PNG")
-
- fp.close()
-
-
- save = save1 # for now
diff --git a/PIL/FpxImagePlugin.py b/PIL/FpxImagePlugin.py
deleted file mode 100644
index d4a1aef..0000000
--- a/PIL/FpxImagePlugin.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#
-# THIS IS WORK IN PROGRESS
-#
-# The Python Imaging Library.
-# $Id: FpxImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# FlashPix support for PIL
-#
-# History:
-# 97-01-25 fl Created (reads uncompressed RGB images only)
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1997.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.1"
-
-
-import string
-
-import Image, ImageFile
-from OleFileIO import *
-
-
-# we map from colour field tuples to (mode, rawmode) descriptors
-MODES = {
- # opacity
- (0x00007ffe): ("A", "L"),
- # monochrome
- (0x00010000,): ("L", "L"),
- (0x00018000, 0x00017ffe): ("RGBA", "LA"),
- # photo YCC
- (0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"),
- (0x00028000, 0x00028001, 0x00028002, 0x00027ffe): ("RGBA", "YCCA;P"),
- # standard RGB (NIFRGB)
- (0x00030000, 0x00030001, 0x00030002): ("RGB","RGB"),
- (0x00038000, 0x00038001, 0x00038002, 0x00037ffe): ("RGBA","RGBA"),
-}
-
-#
-# --------------------------------------------------------------------
-
-def _accept(prefix):
- return prefix[:8] == MAGIC
-
-##
-# Image plugin for the FlashPix images.
-
-class FpxImageFile(ImageFile.ImageFile):
-
- format = "FPX"
- format_description = "FlashPix"
-
- def _open(self):
- #
- # read the OLE directory and see if this is a likely
- # to be a FlashPix file
-
- try:
- self.ole = OleFileIO(self.fp)
- except IOError:
- raise SyntaxError, "not an FPX file; invalid OLE file"
-
- if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
- raise SyntaxError, "not an FPX file; bad root CLSID"
-
- self._open_index(1)
-
- def _open_index(self, index = 1):
- #
- # get the Image Contents Property Set
-
- prop = self.ole.getproperties([
- "Data Object Store %06d" % index,
- "\005Image Contents"
- ])
-
- # size (highest resolution)
-
- self.size = prop[0x1000002], prop[0x1000003]
-
- size = max(self.size)
- i = 1
- while size > 64:
- size = size / 2
- i = i + 1
- self.maxid = i - 1
-
- # mode. instead of using a single field for this, flashpix
- # requires you to specify the mode for each channel in each
- # resolution subimage, and leaves it to the decoder to make
- # sure that they all match. for now, we'll cheat and assume
- # that this is always the case.
-
- id = self.maxid << 16
-
- s = prop[0x2000002|id]
-
- colors = []
- for i in range(i32(s, 4)):
- # note: for now, we ignore the "uncalibrated" flag
- colors.append(i32(s, 8+i*4) & 0x7fffffff)
-
- self.mode, self.rawmode = MODES[tuple(colors)]
-
- # load JPEG tables, if any
- self.jpeg = {}
- for i in range(256):
- id = 0x3000001|(i << 16)
- if prop.has_key(id):
- self.jpeg[i] = prop[id]
-
- # print len(self.jpeg), "tables loaded"
-
- self._open_subimage(1, self.maxid)
-
- def _open_subimage(self, index = 1, subimage = 0):
- #
- # setup tile descriptors for a given subimage
-
- stream = [
- "Data Object Store %06d" % index,
- "Resolution %04d" % subimage,
- "Subimage 0000 Header"
- ]
-
- fp = self.ole.openstream(stream)
-
- # skip prefix
- p = fp.read(28)
-
- # header stream
- s = fp.read(36)
-
- size = i32(s, 4), i32(s, 8)
- tilecount = i32(s, 12)
- tilesize = i32(s, 16), i32(s, 20)
- channels = i32(s, 24)
- offset = i32(s, 28)
- length = i32(s, 32)
-
- # print size, self.mode, self.rawmode
-
- if size != self.size:
- raise IOError, "subimage mismatch"
-
- # get tile descriptors
- fp.seek(28 + offset)
- s = fp.read(i32(s, 12) * length)
-
- x = y = 0
- xsize, ysize = size
- xtile, ytile = tilesize
- self.tile = []
-
- for i in range(0, len(s), length):
-
- compression = i32(s, i+8)
-
- if compression == 0:
- self.tile.append(("raw", (x,y,x+xtile,y+ytile),
- i32(s, i) + 28, (self.rawmode)))
-
- elif compression == 1:
-
- # FIXME: the fill decoder is not implemented
- self.tile.append(("fill", (x,y,x+xtile,y+ytile),
- i32(s, i) + 28, (self.rawmode, s[12:16])))
-
- elif compression == 2:
-
- internal_color_conversion = ord(s[14])
- jpeg_tables = ord(s[15])
- rawmode = self.rawmode
-
- if internal_color_conversion:
- # The image is stored as usual (usually YCbCr).
- if rawmode == "RGBA":
- # For "RGBA", data is stored as YCbCrA based on
- # negative RGB. The following trick works around
- # this problem :
- jpegmode, rawmode = "YCbCrK", "CMYK"
- else:
- jpegmode = None # let the decoder decide
-
- else:
- # The image is stored as defined by rawmode
- jpegmode = rawmode
-
- self.tile.append(("jpeg", (x,y,x+xtile,y+ytile),
- i32(s, i) + 28, (rawmode, jpegmode)))
-
- # FIXME: jpeg tables are tile dependent; the prefix
- # data must be placed in the tile descriptor itself!
-
- if jpeg_tables:
- self.tile_prefix = self.jpeg[jpeg_tables]
-
- else:
- raise IOError, "unknown/invalid compression"
-
- x = x + xtile
- if x >= xsize:
- x, y = 0, y + ytile
- if y >= ysize:
- break # isn't really required
-
- self.stream = stream
- self.fp = None
-
- def load(self):
-
- if not self.fp:
- self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"])
-
- ImageFile.ImageFile.load(self)
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("FPX", FpxImageFile, _accept)
-
-Image.register_extension("FPX", ".fpx")
diff --git a/PIL/GbrImagePlugin.py b/PIL/GbrImagePlugin.py
deleted file mode 100644
index 273e1f8..0000000
--- a/PIL/GbrImagePlugin.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: GbrImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# load a GIMP brush file
-#
-# History:
-# 96-03-14 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageFile
-
-def i32(c):
- return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24L)
-
-def _accept(prefix):
- return i32(prefix) >= 20 and i32(prefix[4:8]) == 1
-
-##
-# Image plugin for the GIMP brush format.
-
-class GbrImageFile(ImageFile.ImageFile):
-
- format = "GBR"
- format_description = "GIMP brush file"
-
- def _open(self):
-
- header_size = i32(self.fp.read(4))
- version = i32(self.fp.read(4))
- if header_size < 20 or version != 1:
- raise SyntaxError, "not a GIMP brush"
-
- width = i32(self.fp.read(4))
- height = i32(self.fp.read(4))
- bytes = i32(self.fp.read(4))
- if width <= 0 or height <= 0 or bytes != 1:
- raise SyntaxError, "not a GIMP brush"
-
- comment = self.fp.read(header_size - 20)[:-1]
-
- self.mode = "L"
- self.size = width, height
-
- self.info["comment"] = comment
-
- # Since the brush is so small, we read the data immediately
- self.data = self.fp.read(width * height)
-
- def load(self):
-
- if not self.data:
- return
-
- # create an image out of the brush data block
- self.im = Image.core.new(self.mode, self.size)
- self.im.fromstring(self.data)
- self.data = ""
-
-#
-# registry
-
-Image.register_open("GBR", GbrImageFile, _accept)
-
-Image.register_extension("GBR", ".gbr")
diff --git a/PIL/GdImageFile.py b/PIL/GdImageFile.py
deleted file mode 100644
index e6ddfa7..0000000
--- a/PIL/GdImageFile.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: GdImageFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# GD file handling
-#
-# History:
-# 1996-04-12 fl Created
-#
-# Copyright (c) 1997 by Secret Labs AB.
-# Copyright (c) 1996 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-# NOTE: This format cannot be automatically recognized, so the
-# class is not registered for use with Image.open(). To open a
-# gd file, use the GdImageFile.open() function instead.
-
-# THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This
-# implementation is provided for convenience and demonstrational
-# purposes only.
-
-
-__version__ = "0.1"
-
-import string
-import Image, ImageFile, ImagePalette
-
-def i16(c):
- return ord(c[1]) + (ord(c[0])<<8)
-
-##
-# Image plugin for the GD uncompressed format. Note that this format
-# is not supported by the standard <b>Image.open</b> function. To use
-# this plugin, you have to import the <b>GdImageFile</b> module and
-# use the <b>GdImageFile.open</b> function.
-
-class GdImageFile(ImageFile.ImageFile):
-
- format = "GD"
- format_description = "GD uncompressed images"
-
- def _open(self):
-
- # Header
- s = self.fp.read(775)
-
- self.mode = "L" # FIXME: "P"
- self.size = i16(s[0:2]), i16(s[2:4])
-
- # transparency index
- tindex = i16(s[5:7])
- if tindex < 256:
- self.info["transparent"] = tindex
-
- self.palette = ImagePalette.raw("RGB", s[7:])
-
- self.tile = [("raw", (0,0)+self.size, 775, ("L", 0, -1))]
-
-##
-# Load texture from a GD image file.
-#
-# @param filename GD file name, or an opened file handle.
-# @param mode Optional mode. In this version, if the mode argument
-# is given, it must be "r".
-# @return An image instance.
-# @exception IOError If the image could not be read.
-
-def open(fp, mode = "r"):
-
- if mode != "r":
- raise ValueError("bad mode")
-
- if type(fp) == type(""):
- import __builtin__
- filename = fp
- fp = __builtin__.open(fp, "rb")
- else:
- filename = ""
-
- try:
- return GdImageFile(fp, filename)
- except SyntaxError:
- raise IOError("cannot identify this image file")
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)
diff --git a/PIL/GimpGradientFile.py b/PIL/GimpGradientFile.py
deleted file mode 100644
index e246d6d..0000000
--- a/PIL/GimpGradientFile.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#
-# Python Imaging Library
-# $Id: GimpGradientFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# stuff to read (and render) GIMP gradient files
-#
-# History:
-# 97-08-23 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1997.
-#
-# See the README file for information on usage and redistribution.
-#
-
-from math import pi, log, sin, sqrt
-import string
-
-# --------------------------------------------------------------------
-# Stuff to translate curve segments to palette values (derived from
-# the corresponding code in GIMP, written by Federico Mena Quintero.
-# See the GIMP distribution for more information.)
-#
-
-EPSILON = 1e-10
-
-def linear(middle, pos):
- if pos <= middle:
- if middle < EPSILON:
- return 0.0
- else:
- return 0.5 * pos / middle
- else:
- pos = pos - middle
- middle = 1.0 - middle
- if middle < EPSILON:
- return 1.0
- else:
- return 0.5 + 0.5 * pos / middle
-
-def curved(middle, pos):
- return pos ** (log(0.5) / log(max(middle, EPSILON)))
-
-def sine(middle, pos):
- return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0
-
-def sphere_increasing(middle, pos):
- return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2)
-
-def sphere_decreasing(middle, pos):
- return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2)
-
-SEGMENTS = [ linear, curved, sine, sphere_increasing, sphere_decreasing ]
-
-class GradientFile:
-
- gradient = None
-
- def getpalette(self, entries = 256):
-
- palette = []
-
- ix = 0
- x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix]
-
- for i in range(entries):
-
- x = i / float(entries-1)
-
- while x1 < x:
- ix = ix + 1
- x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix]
-
- w = x1 - x0
-
- if w < EPSILON:
- scale = segment(0.5, 0.5)
- else:
- scale = segment((xm - x0) / w, (x - x0) / w)
-
- # expand to RGBA
- r = chr(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5))
- g = chr(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5))
- b = chr(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5))
- a = chr(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5))
-
- # add to palette
- palette.append(r + g + b + a)
-
- return string.join(palette, ""), "RGBA"
-
-##
-# File handler for GIMP's gradient format.
-
-class GimpGradientFile(GradientFile):
-
- def __init__(self, fp):
-
- if fp.readline()[:13] != "GIMP Gradient":
- raise SyntaxError, "not a GIMP gradient file"
-
- count = int(fp.readline())
-
- gradient = []
-
- for i in range(count):
-
- s = string.split(fp.readline())
- w = map(float, s[:11])
-
- x0, x1 = w[0], w[2]
- xm = w[1]
- rgb0 = w[3:7]
- rgb1 = w[7:11]
-
- segment = SEGMENTS[int(s[11])]
- cspace = int(s[12])
-
- if cspace != 0:
- raise IOError, "cannot handle HSV colour space"
-
- gradient.append((x0, x1, xm, rgb0, rgb1, segment))
-
- self.gradient = gradient
diff --git a/PIL/GimpPaletteFile.py b/PIL/GimpPaletteFile.py
deleted file mode 100644
index 3939147..0000000
--- a/PIL/GimpPaletteFile.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Python Imaging Library
-# $Id: GimpPaletteFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# stuff to read GIMP palette files
-#
-# History:
-# 1997-08-23 fl Created
-# 2004-09-07 fl Support GIMP 2.0 palette files.
-#
-# Copyright (c) Secret Labs AB 1997-2004. All rights reserved.
-# Copyright (c) Fredrik Lundh 1997-2004.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import re, string
-
-##
-# File handler for GIMP's palette format.
-
-class GimpPaletteFile:
-
- rawmode = "RGB"
-
- def __init__(self, fp):
-
- self.palette = map(lambda i: chr(i)*3, range(256))
-
- if fp.readline()[:12] != "GIMP Palette":
- raise SyntaxError, "not a GIMP palette file"
-
- i = 0
-
- while i <= 255:
-
- s = fp.readline()
-
- if not s:
- break
- # skip fields and comment lines
- if re.match("\w+:|#", s):
- continue
- if len(s) > 100:
- raise SyntaxError, "bad palette file"
-
- v = tuple(map(int, string.split(s)[:3]))
- if len(v) != 3:
- raise ValueError, "bad palette entry"
-
- if 0 <= i <= 255:
- self.palette[i] = chr(v[0]) + chr(v[1]) + chr(v[2])
-
- i = i + 1
-
- self.palette = string.join(self.palette, "")
-
-
- def getpalette(self):
-
- return self.palette, self.rawmode
diff --git a/PIL/GribStubImagePlugin.py b/PIL/GribStubImagePlugin.py
deleted file mode 100644
index 73d5404..0000000
--- a/PIL/GribStubImagePlugin.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: GribStubImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# GRIB stub adapter
-#
-# Copyright (c) 1996-2003 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageFile
-
-_handler = None
-
-##
-# Install application-specific GRIB image handler.
-#
-# @param handler Handler object.
-
-def register_handler(handler):
- global _handler
- _handler = handler
-
-# --------------------------------------------------------------------
-# Image adapter
-
-def _accept(prefix):
- return prefix[0:4] == "GRIB" and prefix[7] == chr(1)
-
-class GribStubImageFile(ImageFile.StubImageFile):
-
- format = "GRIB"
- format_description = "GRIB"
-
- def _open(self):
-
- offset = self.fp.tell()
-
- if not _accept(self.fp.read(8)):
- raise SyntaxError("Not a GRIB file")
-
- self.fp.seek(offset)
-
- # make something up
- self.mode = "F"
- self.size = 1, 1
-
- loader = self._load()
- if loader:
- loader.open(self)
-
- def _load(self):
- return _handler
-
-def _save(im, fp, filename):
- if _handler is None or not hasattr("_handler", "save"):
- raise IOError("GRIB save handler not installed")
- _handler.save(im, fp, filename)
-
-
-# --------------------------------------------------------------------
-# Registry
-
-Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept)
-Image.register_save(GribStubImageFile.format, _save)
-
-Image.register_extension(GribStubImageFile.format, ".grib")
diff --git a/PIL/Hdf5StubImagePlugin.py b/PIL/Hdf5StubImagePlugin.py
deleted file mode 100644
index 31d4f6e..0000000
--- a/PIL/Hdf5StubImagePlugin.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: Hdf5StubImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# HDF5 stub adapter
-#
-# Copyright (c) 2000-2003 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageFile
-
-_handler = None
-
-##
-# Install application-specific HDF5 image handler.
-#
-# @param handler Handler object.
-
-def register_handler(handler):
- global _handler
- _handler = handler
-
-# --------------------------------------------------------------------
-# Image adapter
-
-def _accept(prefix):
- return prefix[:8] == "\x89HDF\r\n\x1a\n"
-
-class HDF5StubImageFile(ImageFile.StubImageFile):
-
- format = "HDF5"
- format_description = "HDF5"
-
- def _open(self):
-
- offset = self.fp.tell()
-
- if not _accept(self.fp.read(8)):
- raise SyntaxError("Not an HDF file")
-
- self.fp.seek(offset)
-
- # make something up
- self.mode = "F"
- self.size = 1, 1
-
- loader = self._load()
- if loader:
- loader.open(self)
-
- def _load(self):
- return _handler
-
-
-def _save(im, fp, filename):
- if _handler is None or not hasattr("_handler", "save"):
- raise IOError("HDF5 save handler not installed")
- _handler.save(im, fp, filename)
-
-
-# --------------------------------------------------------------------
-# Registry
-
-Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept)
-Image.register_save(HDF5StubImageFile.format, _save)
-
-Image.register_extension(HDF5StubImageFile.format, ".h5")
-Image.register_extension(HDF5StubImageFile.format, ".hdf")
diff --git a/PIL/IcnsImagePlugin.py b/PIL/IcnsImagePlugin.py
deleted file mode 100644
index a85695d..0000000
--- a/PIL/IcnsImagePlugin.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# Mac OS X icns file decoder, based on icns.py by Bob Ippolito.
-#
-# history:
-# 2004-10-09 fl Turned into a PIL plugin; removed 2.3 dependencies.
-#
-# Copyright (c) 2004 by Bob Ippolito.
-# Copyright (c) 2004 by Secret Labs.
-# Copyright (c) 2004 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageFile
-import string, struct
-
-HEADERSIZE = 8
-
-def nextheader(fobj):
- return struct.unpack('>4sI', fobj.read(HEADERSIZE))
-
-def read_32t(fobj, (start, length), (width, height)):
- # The 128x128 icon seems to have an extra header for some reason.
- fobj.seek(start)
- sig = fobj.read(4)
- if sig != '\x00\x00\x00\x00':
- raise SyntaxError, 'Unknown signature, expecting 0x00000000'
- return read_32(fobj, (start + 4, length - 4), (width, height))
-
-def read_32(fobj, (start, length), size):
- """
- Read a 32bit RGB icon resource. Seems to be either uncompressed or
- an RLE packbits-like scheme.
- """
- fobj.seek(start)
- sizesq = size[0] * size[1]
- if length == sizesq * 3:
- # uncompressed ("RGBRGBGB")
- indata = fobj.read(length)
- im = Image.frombuffer("RGB", size, indata, "raw", "RGB", 0, 1)
- else:
- # decode image
- im = Image.new("RGB", size, None)
- for band_ix in range(3):
- data = []
- bytesleft = sizesq
- while bytesleft > 0:
- byte = fobj.read(1)
- if not byte:
- break
- byte = ord(byte)
- if byte & 0x80:
- blocksize = byte - 125
- byte = fobj.read(1)
- for i in range(blocksize):
- data.append(byte)
- else:
- blocksize = byte + 1
- data.append(fobj.read(blocksize))
- bytesleft = bytesleft - blocksize
- if bytesleft <= 0:
- break
- if bytesleft != 0:
- raise SyntaxError(
- "Error reading %r channel [%r]" % (channel, bytesleft)
- )
- band = Image.frombuffer(
- "L", size, string.join(data, ""), "raw", "L", 0, 1
- )
- im.im.putband(band.im, band_ix)
- return {"RGB": im}
-
-def read_mk(fobj, (start, length), size):
- # Alpha masks seem to be uncompressed
- fobj.seek(start)
- band = Image.frombuffer(
- "L", size, fobj.read(size[0]*size[1]), "raw", "L", 0, 1
- )
- return {"A": band}
-
-class IcnsFile:
-
- SIZES = {
- (128, 128): [
- ('it32', read_32t),
- ('t8mk', read_mk),
- ],
- (48, 48): [
- ('ih32', read_32),
- ('h8mk', read_mk),
- ],
- (32, 32): [
- ('il32', read_32),
- ('l8mk', read_mk),
- ],
- (16, 16): [
- ('is32', read_32),
- ('s8mk', read_mk),
- ],
- }
-
- def __init__(self, fobj):
- """
- fobj is a file-like object as an icns resource
- """
- # signature : (start, length)
- self.dct = dct = {}
- self.fobj = fobj
- sig, filesize = nextheader(fobj)
- if sig != 'icns':
- raise SyntaxError, 'not an icns file'
- i = HEADERSIZE
- while i < filesize:
- sig, blocksize = nextheader(fobj)
- i = i + HEADERSIZE
- blocksize = blocksize - HEADERSIZE
- dct[sig] = (i, blocksize)
- fobj.seek(blocksize, 1)
- i = i + blocksize
-
- def itersizes(self):
- sizes = []
- for size, fmts in self.SIZES.items():
- for (fmt, reader) in fmts:
- if self.dct.has_key(fmt):
- sizes.append(size)
- break
- return sizes
-
- def bestsize(self):
- sizes = self.itersizes()
- if not sizes:
- raise SyntaxError, "No 32bit icon resources found"
- return max(sizes)
-
- def dataforsize(self, size):
- """
- Get an icon resource as {channel: array}. Note that
- the arrays are bottom-up like windows bitmaps and will likely
- need to be flipped or transposed in some way.
- """
- dct = {}
- for code, reader in self.SIZES[size]:
- desc = self.dct.get(code)
- if desc is not None:
- dct.update(reader(self.fobj, desc, size))
- return dct
-
- def getimage(self, size=None):
- if size is None:
- size = self.bestsize()
- channels = self.dataforsize(size)
- im = channels.get("RGB").copy()
- try:
- im.putalpha(channels["A"])
- except KeyError:
- pass
- return im
-
-##
-# Image plugin for Mac OS icons.
-
-class IcnsImageFile(ImageFile.ImageFile):
- """
- PIL read-only image support for Mac OS .icns files.
- Chooses the best resolution, but will possibly load
- a different size image if you mutate the size attribute
- before calling 'load'.
-
- The info dictionary has a key 'sizes' that is a list
- of sizes that the icns file has.
- """
-
- format = "ICNS"
- format_description = "Mac OS icns resource"
-
- def _open(self):
- self.icns = IcnsFile(self.fp)
- self.mode = 'RGBA'
- self.size = self.icns.bestsize()
- self.info['sizes'] = self.icns.itersizes()
- # Just use this to see if it's loaded or not yet.
- self.tile = ('',)
-
- def load(self):
- Image.Image.load(self)
- if not self.tile:
- return
- self.load_prepare()
- # This is likely NOT the best way to do it, but whatever.
- im = self.icns.getimage(self.size)
- self.im = im.im
- self.mode = im.mode
- self.size = im.size
- self.fp = None
- self.icns = None
- self.tile = ()
- self.load_end()
-
-
-Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == 'icns')
-Image.register_extension("ICNS", '.icns')
-
-if __name__ == '__main__':
- import os, sys
- im = Image.open(open(sys.argv[1], "rb"))
- im.save("out.png")
- os.startfile("out.png")
diff --git a/PIL/IcoImagePlugin.py b/PIL/IcoImagePlugin.py
deleted file mode 100644
index 5cdd284..0000000
--- a/PIL/IcoImagePlugin.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: IcoImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# Windows Icon support for PIL
-#
-# Notes:
-# uses BmpImagePlugin.py to read the bitmap data.
-#
-# History:
-# 96-05-27 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.1"
-
-import string
-
-import Image, BmpImagePlugin
-
-
-#
-# --------------------------------------------------------------------
-
-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)
-
-
-def _accept(prefix):
- return prefix[:4] == "\0\0\1\0"
-
-##
-# Image plugin for Windows Icon files.
-
-class IcoImageFile(BmpImagePlugin.BmpImageFile):
-
- format = "ICO"
- format_description = "Windows Icon"
-
- def _open(self):
-
- # check magic
- s = self.fp.read(6)
- if not _accept(s):
- raise SyntaxError, "not an ICO file"
-
- # pick the largest icon in the file
- m = ""
- for i in range(i16(s[4:])):
- s = self.fp.read(16)
- if not m:
- m = s
- elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
- m = s
- #print "width", ord(s[0])
- #print "height", ord(s[1])
- #print "colors", ord(s[2])
- #print "reserved", ord(s[3])
- #print "planes", i16(s[4:])
- #print "bitcount", i16(s[6:])
- #print "bytes", i32(s[8:])
- #print "offset", i32(s[12:])
-
- # load as bitmap
- self._bitmap(i32(m[12:]))
-
- # patch up the bitmap height
- self.size = self.size[0], self.size[1]/2
- d, e, o, a = self.tile[0]
- self.tile[0] = d, (0,0)+self.size, o, a
-
- return
-
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("ICO", IcoImageFile, _accept)
-
-Image.register_extension("ICO", ".ico")
diff --git a/PIL/ImImagePlugin.py b/PIL/ImImagePlugin.py
deleted file mode 100644
index 17b8c0e..0000000
--- a/PIL/ImImagePlugin.py
+++ /dev/null
@@ -1,335 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImImagePlugin.py 2285 2005-02-07 23:52:14Z fredrik $
-#
-# IFUNC IM file handling for PIL
-#
-# history:
-# 1995-09-01 fl Created.
-# 1997-01-03 fl Save palette images
-# 1997-01-08 fl Added sequence support
-# 1997-01-23 fl Added P and RGB save support
-# 1997-05-31 fl Read floating point images
-# 1997-06-22 fl Save floating point images
-# 1997-08-27 fl Read and save 1-bit images
-# 1998-06-25 fl Added support for RGB+LUT images
-# 1998-07-02 fl Added support for YCC images
-# 1998-07-15 fl Renamed offset attribute to avoid name clash
-# 1998-12-29 fl Added I;16 support
-# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7)
-# 2003-09-26 fl Added LA/PA support
-#
-# Copyright (c) 1997-2003 by Secret Labs AB.
-# Copyright (c) 1995-2001 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.7"
-
-import re, string
-import Image, ImageFile, ImagePalette
-
-
-# --------------------------------------------------------------------
-# Standard tags
-
-COMMENT = "Comment"
-DATE = "Date"
-EQUIPMENT = "Digitalization equipment"
-FRAMES = "File size (no of images)"
-LUT = "Lut"
-NAME = "Name"
-SCALE = "Scale (x,y)"
-SIZE = "Image size (x*y)"
-MODE = "Image type"
-
-TAGS = { COMMENT:0, DATE:0, EQUIPMENT:0, FRAMES:0, LUT:0, NAME:0,
- SCALE:0, SIZE:0, MODE:0 }
-
-OPEN = {
- # ifunc93/p3cfunc formats
- "0 1 image": ("1", "1"),
- "L 1 image": ("1", "1"),
- "Greyscale image": ("L", "L"),
- "Grayscale image": ("L", "L"),
- "RGB image": ("RGB", "RGB;L"),
- "RLB image": ("RGB", "RLB"),
- "RYB image": ("RGB", "RLB"),
- "B1 image": ("1", "1"),
- "B2 image": ("P", "P;2"),
- "B4 image": ("P", "P;4"),
- "X 24 image": ("RGB", "RGB"),
- "L 32 S image": ("I", "I;32"),
- "L 32 F image": ("F", "F;32"),
- # old p3cfunc formats
- "RGB3 image": ("RGB", "RGB;T"),
- "RYB3 image": ("RGB", "RYB;T"),
- # extensions
- "LA image": ("LA", "LA;L"),
- "RGBA image": ("RGBA", "RGBA;L"),
- "RGBX image": ("RGBX", "RGBX;L"),
- "CMYK image": ("CMYK", "CMYK;L"),
- "YCC image": ("YCbCr", "YCbCr;L"),
-}
-
-# ifunc95 extensions
-for i in ["8", "8S", "16", "16S", "32", "32F"]:
- OPEN["L %s image" % i] = ("F", "F;%s" % i)
- OPEN["L*%s image" % i] = ("F", "F;%s" % i)
-for i in ["16", "16B"]:
- OPEN["L %s image" % i] = ("I;%s" % i, "I;%s" % i)
- OPEN["L*%s image" % i] = ("I;%s" % i, "I;%s" % i)
-for i in ["32S"]:
- OPEN["L %s image" % i] = ("I", "I;%s" % i)
- OPEN["L*%s image" % i] = ("I", "I;%s" % i)
-for i in range(2, 33):
- OPEN["L*%s image" % i] = ("F", "F;%s" % i)
-
-
-# --------------------------------------------------------------------
-# Read IM directory
-
-split = re.compile(r"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
-
-def number(s):
- try:
- return int(s)
- except ValueError:
- return float(s)
-
-##
-# Image plugin for the IFUNC IM file format.
-
-class ImImageFile(ImageFile.ImageFile):
-
- format = "IM"
- format_description = "IFUNC Image Memory"
-
- def _open(self):
-
- # Quick rejection: if there's not an LF among the first
- # 100 bytes, this is (probably) not a text header.
-
- if not "\n" in self.fp.read(100):
- raise SyntaxError, "not an IM file"
- self.fp.seek(0)
-
- n = 0
-
- # Default values
- self.info[MODE] = "L"
- self.info[SIZE] = (512, 512)
- self.info[FRAMES] = 1
-
- self.rawmode = "L"
-
- while 1:
-
- s = self.fp.read(1)
-
- # Some versions of IFUNC uses \n\r instead of \r\n...
- if s == "\r":
- continue
-
- if not s or s[0] == chr(0) or s[0] == chr(26):
- break
-
- # FIXME: this may read whole file if not a text file
- s = s + self.fp.readline()
-
- if len(s) > 100:
- raise SyntaxError, "not an IM file"
-
- if s[-2:] == '\r\n':
- s = s[:-2]
- elif s[-1:] == '\n':
- s = s[:-1]
-
- try:
- m = split.match(s)
- except re.error, v:
- raise SyntaxError, "not an IM file"
-
- if m:
-
- k, v = m.group(1,2)
-
- # Convert value as appropriate
- if k in [FRAMES, SCALE, SIZE]:
- v = string.replace(v, "*", ",")
- v = tuple(map(number, string.split(v, ",")))
- if len(v) == 1:
- v = v[0]
- elif k == MODE and OPEN.has_key(v):
- v, self.rawmode = OPEN[v]
-
- # Add to dictionary. Note that COMMENT tags are
- # combined into a list of strings.
- if k == COMMENT:
- if self.info.has_key(k):
- self.info[k].append(v)
- else:
- self.info[k] = [v]
- else:
- self.info[k] = v
-
- if TAGS.has_key(k):
- n = n + 1
-
- else:
-
- raise SyntaxError, "Syntax error in IM header: " + s
-
- if not n:
- raise SyntaxError, "Not an IM file"
-
- # Basic attributes
- self.size = self.info[SIZE]
- self.mode = self.info[MODE]
-
- # Skip forward to start of image data
- while s and s[0] != chr(26):
- s = self.fp.read(1)
- if not s:
- raise SyntaxError, "File truncated"
-
- if self.info.has_key(LUT):
- # convert lookup table to palette or lut attribute
- palette = self.fp.read(768)
- greyscale = 1 # greyscale palette
- linear = 1 # linear greyscale palette
- for i in range(256):
- if palette[i] == palette[i+256] == palette[i+512]:
- if palette[i] != chr(i):
- linear = 0
- else:
- greyscale = 0
- if self.mode == "L" or self.mode == "LA":
- if greyscale:
- if not linear:
- self.lut = map(ord, palette[:256])
- else:
- if self.mode == "L":
- self.mode = self.rawmode = "P"
- elif self.mode == "LA":
- self.mode = self.rawmode = "PA"
- self.palette = ImagePalette.raw("RGB;L", palette)
- elif self.mode == "RGB":
- if not greyscale or not linear:
- self.lut = map(ord, palette)
-
- self.frame = 0
-
- self.__offset = offs = self.fp.tell()
-
- self.__fp = self.fp # FIXME: hack
-
- if self.rawmode[:2] == "F;":
-
- # ifunc95 formats
- try:
- # use bit decoder (if necessary)
- bits = int(self.rawmode[2:])
- if bits not in [8, 16, 32]:
- self.tile = [("bit", (0,0)+self.size, offs,
- (bits, 8, 3, 0, -1))]
- return
- except ValueError:
- pass
-
- if self.rawmode in ["RGB;T", "RYB;T"]:
- # Old LabEye/3PC files. Would be very surprised if anyone
- # ever stumbled upon such a file ;-)
- size = self.size[0] * self.size[1]
- self.tile = [("raw", (0,0)+self.size, offs, ("G", 0, -1)),
- ("raw", (0,0)+self.size, offs+size, ("R", 0, -1)),
- ("raw", (0,0)+self.size, offs+2*size, ("B", 0, -1))]
- else:
- # LabEye/IFUNC files
- self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))]
-
- def seek(self, frame):
-
- if frame < 0 or frame >= self.info[FRAMES]:
- raise EOFError, "seek outside sequence"
-
- if self.frame == frame:
- return
-
- self.frame = frame
-
- if self.mode == "1":
- bits = 1
- else:
- bits = 8 * len(self.mode)
-
- size = ((self.size[0] * bits + 7) / 8) * self.size[1]
- offs = self.__offset + frame * size
-
- self.fp = self.__fp
-
- self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))]
-
- def tell(self):
-
- return self.frame
-
-#
-# --------------------------------------------------------------------
-# Save IM files
-
-SAVE = {
- # mode: (im type, raw mode)
- "1": ("0 1", "1"),
- "L": ("Greyscale", "L"),
- "LA": ("LA", "LA;L"),
- "P": ("Greyscale", "P"),
- "PA": ("LA", "PA;L"),
- "I": ("L 32S", "I;32S"),
- "I;16": ("L 16", "I;16"),
- "I;16B": ("L 16B", "I;16B"),
- "F": ("L 32F", "F;32F"),
- "RGB": ("RGB", "RGB;L"),
- "RGBA": ("RGBA", "RGBA;L"),
- "RGBX": ("RGBX", "RGBX;L"),
- "CMYK": ("CMYK", "CMYK;L"),
- "YCbCr": ("YCC", "YCbCr;L")
-}
-
-def _save(im, fp, filename, check=0):
-
- try:
- type, rawmode = SAVE[im.mode]
- except KeyError:
- raise ValueError, "Cannot save %s images as IM" % im.mode
-
- try:
- frames = im.encoderinfo["frames"]
- except KeyError:
- frames = 1
-
- if check:
- return check
-
- fp.write("Image type: %s image\r\n" % type)
- if filename:
- fp.write("Name: %s\r\n" % filename)
- fp.write("Image size (x*y): %d*%d\r\n" % im.size)
- fp.write("File size (no of images): %d\r\n" % frames)
- if im.mode == "P":
- fp.write("Lut: 1\r\n")
- fp.write("\000" * (511-fp.tell()) + "\032")
- if im.mode == "P":
- fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes
- ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))])
-
-#
-# --------------------------------------------------------------------
-# Registry
-
-Image.register_open("IM", ImImageFile)
-Image.register_save("IM", _save)
-
-Image.register_extension("IM", ".im")
diff --git a/PIL/Image.py b/PIL/Image.py
deleted file mode 100644
index 04ed316..0000000
--- a/PIL/Image.py
+++ /dev/null
@@ -1,2093 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: Image.py 2933 2006-12-03 12:08:22Z fredrik $
-#
-# the Image class wrapper
-#
-# partial release history:
-# 1995-09-09 fl Created
-# 1996-03-11 fl PIL release 0.0 (proof of concept)
-# 1996-04-30 fl PIL release 0.1b1
-# 1999-07-28 fl PIL release 1.0 final
-# 2000-06-07 fl PIL release 1.1
-# 2000-10-20 fl PIL release 1.1.1
-# 2001-05-07 fl PIL release 1.1.2
-# 2002-03-15 fl PIL release 1.1.3
-# 2003-05-10 fl PIL release 1.1.4
-# 2005-03-28 fl PIL release 1.1.5
-# 2006-12-02 fl PIL release 1.1.6
-#
-# Copyright (c) 1997-2006 by Secret Labs AB. All rights reserved.
-# Copyright (c) 1995-2006 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-VERSION = "1.1.6"
-
-try:
- import warnings
-except ImportError:
- warnings = None
-
-class _imaging_not_installed:
- # module placeholder
- def __getattr__(self, id):
- raise ImportError("The _imaging C module is not installed")
-
-try:
- # give Tk a chance to set up the environment, in case we're
- # using an _imaging module linked against libtcl/libtk (use
- # __import__ to hide this from naive packagers; we don't really
- # depend on Tk unless ImageTk is used, and that module already
- # imports Tkinter)
- __import__("FixTk")
-except ImportError:
- pass
-
-try:
- # If the _imaging C module is not present, you can still use
- # the "open" function to identify files, but you cannot load
- # them. Note that other modules should not refer to _imaging
- # directly; import Image and use the Image.core variable instead.
- import _imaging
- core = _imaging
- del _imaging
-except ImportError, v:
- core = _imaging_not_installed()
- if str(v)[:20] == "Module use of python" and warnings:
- # The _imaging C module is present, but not compiled for
- # the right version (windows only). Print a warning, if
- # possible.
- warnings.warn(
- "The _imaging extension was built for another version "
- "of Python; most PIL functions will be disabled",
- RuntimeWarning
- )
-
-import ImageMode
-import ImagePalette
-
-import os, string, sys
-
-# type stuff
-from types import IntType, StringType, TupleType
-
-try:
- UnicodeStringType = type(unicode(""))
- ##
- # (Internal) Checks if an object is a string. If the current
- # Python version supports Unicode, this checks for both 8-bit
- # and Unicode strings.
- def isStringType(t):
- return isinstance(t, StringType) or isinstance(t, UnicodeStringType)
-except NameError:
- def isStringType(t):
- return isinstance(t, StringType)
-
-##
-# (Internal) Checks if an object is a tuple.
-
-def isTupleType(t):
- return isinstance(t, TupleType)
-
-##
-# (Internal) Checks if an object is an image object.
-
-def isImageType(t):
- return hasattr(t, "im")
-
-##
-# (Internal) Checks if an object is a string, and that it points to a
-# directory.
-
-def isDirectory(f):
- return isStringType(f) and os.path.isdir(f)
-
-from operator import isNumberType, isSequenceType
-
-#
-# Debug level
-
-DEBUG = 0
-
-#
-# Constants (also defined in _imagingmodule.c!)
-
-NONE = 0
-
-# transpose
-FLIP_LEFT_RIGHT = 0
-FLIP_TOP_BOTTOM = 1
-ROTATE_90 = 2
-ROTATE_180 = 3
-ROTATE_270 = 4
-
-# transforms
-AFFINE = 0
-EXTENT = 1
-PERSPECTIVE = 2
-QUAD = 3
-MESH = 4
-
-# resampling filters
-NONE = 0
-NEAREST = 0
-ANTIALIAS = 1 # 3-lobed lanczos
-LINEAR = BILINEAR = 2
-CUBIC = BICUBIC = 3
-
-# dithers
-NONE = 0
-NEAREST = 0
-ORDERED = 1 # Not yet implemented
-RASTERIZE = 2 # Not yet implemented
-FLOYDSTEINBERG = 3 # default
-
-# palettes/quantizers
-WEB = 0
-ADAPTIVE = 1
-
-# categories
-NORMAL = 0
-SEQUENCE = 1
-CONTAINER = 2
-
-# --------------------------------------------------------------------
-# Registries
-
-ID = []
-OPEN = {}
-MIME = {}
-SAVE = {}
-EXTENSION = {}
-
-# --------------------------------------------------------------------
-# Modes supported by this version
-
-_MODEINFO = {
- # NOTE: this table will be removed in future versions. use
- # getmode* functions or ImageMode descriptors instead.
-
- # official modes
- "1": ("L", "L", ("1",)),
- "L": ("L", "L", ("L",)),
- "I": ("L", "I", ("I",)),
- "F": ("L", "F", ("F",)),
- "P": ("RGB", "L", ("P",)),
- "RGB": ("RGB", "L", ("R", "G", "B")),
- "RGBX": ("RGB", "L", ("R", "G", "B", "X")),
- "RGBA": ("RGB", "L", ("R", "G", "B", "A")),
- "CMYK": ("RGB", "L", ("C", "M", "Y", "K")),
- "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr")),
-
- # Experimental modes include I;16, I;16B, RGBa, BGR;15,
- # and BGR;24. Use these modes only if you know exactly
- # what you're doing...
-
-}
-
-if sys.byteorder == 'little':
- _ENDIAN = '<'
-else:
- _ENDIAN = '>'
-
-_MODE_CONV = {
- # official modes
- "1": ('|b1', None),
- "L": ('|u1', None),
- "I": ('%si4' % _ENDIAN, None), # FIXME: is this correct?
- "F": ('%sf4' % _ENDIAN, None), # FIXME: is this correct?
- "P": ('|u1', None),
- "RGB": ('|u1', 3),
- "RGBX": ('|u1', 4),
- "RGBA": ('|u1', 4),
- "CMYK": ('|u1', 4),
- "YCbCr": ('|u1', 4),
-}
-
-def _conv_type_shape(im):
- shape = im.size[::-1]
- typ, extra = _MODE_CONV[im.mode]
- if extra is None:
- return shape, typ
- else:
- return shape+(extra,), typ
-
-
-MODES = _MODEINFO.keys()
-MODES.sort()
-
-# raw modes that may be memory mapped. NOTE: if you change this, you
-# may have to modify the stride calculation in map.c too!
-_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16B")
-
-##
-# Gets the "base" mode for given mode. This function returns "L" for
-# images that contain grayscale data, and "RGB" for images that
-# contain color data.
-#
-# @param mode Input mode.
-# @return "L" or "RGB".
-# @exception KeyError If the input mode was not a standard mode.
-
-def getmodebase(mode):
- return ImageMode.getmode(mode).basemode
-
-##
-# Gets the storage type mode. Given a mode, this function returns a
-# single-layer mode suitable for storing individual bands.
-#
-# @param mode Input mode.
-# @return "L", "I", or "F".
-# @exception KeyError If the input mode was not a standard mode.
-
-def getmodetype(mode):
- return ImageMode.getmode(mode).basetype
-
-##
-# Gets a list of individual band names. Given a mode, this function
-# returns a tuple containing the names of individual bands (use
-# {@link #getmodetype} to get the mode used to store each individual
-# band.
-#
-# @param mode Input mode.
-# @return A tuple containing band names. The length of the tuple
-# gives the number of bands in an image of the given mode.
-# @exception KeyError If the input mode was not a standard mode.
-
-def getmodebandnames(mode):
- return ImageMode.getmode(mode).bands
-
-##
-# Gets the number of individual bands for this mode.
-#
-# @param mode Input mode.
-# @return The number of bands in this mode.
-# @exception KeyError If the input mode was not a standard mode.
-
-def getmodebands(mode):
- return len(ImageMode.getmode(mode).bands)
-
-# --------------------------------------------------------------------
-# Helpers
-
-_initialized = 0
-
-##
-# Explicitly loads standard file format drivers.
-
-def preinit():
- "Load standard file format drivers."
-
- global _initialized
- if _initialized >= 1:
- return
-
- try:
- import BmpImagePlugin
- except ImportError:
- pass
- try:
- import GifImagePlugin
- except ImportError:
- pass
- try:
- import JpegImagePlugin
- except ImportError:
- pass
- try:
- import PpmImagePlugin
- except ImportError:
- pass
- try:
- import PngImagePlugin
- except ImportError:
- pass
-# try:
-# import TiffImagePlugin
-# except ImportError:
-# pass
-
- _initialized = 1
-
-##
-# Explicitly initializes the Python Imaging Library. This function
-# loads all available file format drivers.
-
-def init():
- "Load all file format drivers."
-
- global _initialized
- if _initialized >= 2:
- return
-
- visited = {}
-
- directories = sys.path
-
- try:
- directories = directories + [os.path.dirname(__file__)]
- except NameError:
- pass
-
- # only check directories (including current, if present in the path)
- for directory in filter(isDirectory, directories):
- fullpath = os.path.abspath(directory)
- if visited.has_key(fullpath):
- continue
- for file in os.listdir(directory):
- if file[-14:] == "ImagePlugin.py":
- f, e = os.path.splitext(file)
- try:
- sys.path.insert(0, directory)
- try:
- __import__(f, globals(), locals(), [])
- finally:
- del sys.path[0]
- except ImportError:
- if DEBUG:
- print "Image: failed to import",
- print f, ":", sys.exc_value
- visited[fullpath] = None
-
- if OPEN or SAVE:
- _initialized = 2
-
-
-# --------------------------------------------------------------------
-# Codec factories (used by tostring/fromstring and ImageFile.load)
-
-def _getdecoder(mode, decoder_name, args, extra=()):
-
- # tweak arguments
- if args is None:
- args = ()
- elif not isTupleType(args):
- args = (args,)
-
- try:
- # get decoder
- decoder = getattr(core, decoder_name + "_decoder")
- # print decoder, (mode,) + args + extra
- return apply(decoder, (mode,) + args + extra)
- except AttributeError:
- raise IOError("decoder %s not available" % decoder_name)
-
-def _getencoder(mode, encoder_name, args, extra=()):
-
- # tweak arguments
- if args is None:
- args = ()
- elif not isTupleType(args):
- args = (args,)
-
- try:
- # get encoder
- encoder = getattr(core, encoder_name + "_encoder")
- # print encoder, (mode,) + args + extra
- return apply(encoder, (mode,) + args + extra)
- except AttributeError:
- raise IOError("encoder %s not available" % encoder_name)
-
-
-# --------------------------------------------------------------------
-# Simple expression analyzer
-
-class _E:
- def __init__(self, data): self.data = data
- def __coerce__(self, other): return self, _E(other)
- def __add__(self, other): return _E((self.data, "__add__", other.data))
- def __mul__(self, other): return _E((self.data, "__mul__", other.data))
-
-def _getscaleoffset(expr):
- stub = ["stub"]
- data = expr(_E(stub)).data
- try:
- (a, b, c) = data # simplified syntax
- if (a is stub and b == "__mul__" and isNumberType(c)):
- return c, 0.0
- if (a is stub and b == "__add__" and isNumberType(c)):
- return 1.0, c
- except TypeError: pass
- try:
- ((a, b, c), d, e) = data # full syntax
- if (a is stub and b == "__mul__" and isNumberType(c) and
- d == "__add__" and isNumberType(e)):
- return c, e
- except TypeError: pass
- raise ValueError("illegal expression")
-
-
-# --------------------------------------------------------------------
-# Implementation wrapper
-
-##
-# This class represents an image object. To create Image objects, use
-# the appropriate factory functions. There's hardly ever any reason
-# to call the Image constructor directly.
-#
-# @see #open
-# @see #new
-# @see #fromstring
-
-class Image:
-
- format = None
- format_description = None
-
- def __init__(self):
- self.im = None
- self.mode = ""
- self.size = (0, 0)
- self.palette = None
- self.info = {}
- self.category = NORMAL
- self.readonly = 0
-
- def _new(self, im):
- new = Image()
- new.im = im
- new.mode = im.mode
- new.size = im.size
- new.palette = self.palette
- if im.mode == "P":
- new.palette = ImagePalette.ImagePalette()
- try:
- new.info = self.info.copy()
- except AttributeError:
- # fallback (pre-1.5.2)
- new.info = {}
- for k, v in self.info:
- new.info[k] = v
- return new
-
- _makeself = _new # compatibility
-
- def _copy(self):
- self.load()
- self.im = self.im.copy()
- self.readonly = 0
-
- def _dump(self, file=None, format=None):
- import tempfile
- if not file:
- file = tempfile.mktemp()
- self.load()
- if not format or format == "PPM":
- self.im.save_ppm(file)
- else:
- file = file + "." + format
- self.save(file, format)
- return file
-
- def __getattr__(self, name):
- if name == "__array_interface__":
- # numpy array interface support
- new = {}
- shape, typestr = _conv_type_shape(self)
- new['shape'] = shape
- new['typestr'] = typestr
- new['data'] = self.tostring()
- return new
- raise AttributeError(name)
-
- ##
- # Returns a string containing pixel data.
- #
- # @param encoder_name What encoder to use. The default is to
- # use the standard "raw" encoder.
- # @param *args Extra arguments to the encoder.
- # @return An 8-bit string.
-
- def tostring(self, encoder_name="raw", *args):
- "Return image as a binary string"
-
- # may pass tuple instead of argument list
- if len(args) == 1 and isTupleType(args[0]):
- args = args[0]
-
- if encoder_name == "raw" and args == ():
- args = self.mode
-
- self.load()
-
- # unpack data
- e = _getencoder(self.mode, encoder_name, args)
- e.setimage(self.im)
-
- bufsize = max(65536, self.size[0] * 4) # see RawEncode.c
-
- data = []
- while 1:
- l, s, d = e.encode(bufsize)
- data.append(d)
- if s:
- break
- if s < 0:
- raise RuntimeError("encoder error %d in tostring" % s)
-
- return string.join(data, "")
-
- ##
- # Returns the image converted to an X11 bitmap. This method
- # only works for mode "1" images.
- #
- # @param name The name prefix to use for the bitmap variables.
- # @return A string containing an X11 bitmap.
- # @exception ValueError If the mode is not "1"
-
- def tobitmap(self, name="image"):
- "Return image as an XBM bitmap"
-
- self.load()
- if self.mode != "1":
- raise ValueError("not a bitmap")
- data = self.tostring("xbm")
- return string.join(["#define %s_width %d\n" % (name, self.size[0]),
- "#define %s_height %d\n"% (name, self.size[1]),
- "static char %s_bits[] = {\n" % name, data, "};"], "")
-
- ##
- # Loads this image with pixel data from a string.
- # <p>
- # This method is similar to the {@link #fromstring} function, but
- # loads data into this image instead of creating a new image
- # object.
-
- def fromstring(self, data, decoder_name="raw", *args):
- "Load data to image from binary string"
-
- # may pass tuple instead of argument list
- if len(args) == 1 and isTupleType(args[0]):
- args = args[0]
-
- # default format
- if decoder_name == "raw" and args == ():
- args = self.mode
-
- # unpack data
- d = _getdecoder(self.mode, decoder_name, args)
- d.setimage(self.im)
- s = d.decode(data)
-
- if s[0] >= 0:
- raise ValueError("not enough image data")
- if s[1] != 0:
- raise ValueError("cannot decode image data")
-
- ##
- # Allocates storage for the image and loads the pixel data. In
- # normal cases, you don't need to call this method, since the
- # Image class automatically loads an opened image when it is
- # accessed for the first time.
- #
- # @return An image access object.
-
- def load(self):
- "Explicitly load pixel data."
- if self.im and self.palette and self.palette.dirty:
- # realize palette
- apply(self.im.putpalette, self.palette.getdata())
- self.palette.dirty = 0
- self.palette.mode = "RGB"
- self.palette.rawmode = None
- if self.info.has_key("transparency"):
- self.im.putpalettealpha(self.info["transparency"], 0)
- self.palette.mode = "RGBA"
- if self.im:
- return self.im.pixel_access(self.readonly)
-
- ##
- # Verifies the contents of a file. For data read from a file, this
- # method attempts to determine if the file is broken, without
- # actually decoding the image data. If this method finds any
- # problems, it raises suitable exceptions. If you need to load
- # the image after using this method, you must reopen the image
- # file.
-
- def verify(self):
- "Verify file contents."
- pass
-
-
- ##
- # Returns a converted copy of this image. For the "P" mode, this
- # method translates pixels through the palette. If mode is
- # omitted, a mode is chosen so that all information in the image
- # and the palette can be represented without a palette.
- # <p>
- # The current version supports all possible conversions between
- # "L", "RGB" and "CMYK."
- # <p>
- # When translating a colour image to black and white (mode "L"),
- # the library uses the ITU-R 601-2 luma transform:
- # <p>
- # <b>L = R * 299/1000 + G * 587/1000 + B * 114/1000</b>
- # <p>
- # When translating a greyscale image into a bilevel image (mode
- # "1"), all non-zero values are set to 255 (white). To use other
- # thresholds, use the {@link #Image.point} method.
- #
- # @def convert(mode, matrix=None)
- # @param mode The requested mode.
- # @param matrix An optional conversion matrix. If given, this
- # should be 4- or 16-tuple containing floating point values.
- # @return An Image object.
-
- def convert(self, mode=None, data=None, dither=None,
- palette=WEB, colors=256):
- "Convert to other pixel format"
-
- if not mode:
- # determine default mode
- if self.mode == "P":
- self.load()
- if self.palette:
- mode = self.palette.mode
- else:
- mode = "RGB"
- else:
- return self.copy()
-
- self.load()
-
- if data:
- # matrix conversion
- if mode not in ("L", "RGB"):
- raise ValueError("illegal conversion")
- im = self.im.convert_matrix(mode, data)
- return self._new(im)
-
- if mode == "P" and palette == ADAPTIVE:
- im = self.im.quantize(colors)
- return self._new(im)
-
- # colourspace conversion
- if dither is None:
- dither = FLOYDSTEINBERG
-
- try:
- im = self.im.convert(mode, dither)
- except ValueError:
- try:
- # normalize source image and try again
- im = self.im.convert(getmodebase(self.mode))
- im = im.convert(mode, dither)
- except KeyError:
- raise ValueError("illegal conversion")
-
- return self._new(im)
-
- def quantize(self, colors=256, method=0, kmeans=0, palette=None):
-
- # methods:
- # 0 = median cut
- # 1 = maximum coverage
-
- # NOTE: this functionality will be moved to the extended
- # quantizer interface in a later version of PIL.
-
- self.load()
-
- if palette:
- # use palette from reference image
- palette.load()
- if palette.mode != "P":
- raise ValueError("bad mode for palette image")
- if self.mode != "RGB" and self.mode != "L":
- raise ValueError(
- "only RGB or L mode images can be quantized to a palette"
- )
- im = self.im.convert("P", 1, palette.im)
- return self._makeself(im)
-
- im = self.im.quantize(colors, method, kmeans)
- return self._new(im)
-
- ##
- # Copies this image. Use this method if you wish to paste things
- # into an image, but still retain the original.
- #
- # @return An Image object.
-
- def copy(self):
- "Copy raster data"
-
- self.load()
- im = self.im.copy()
- return self._new(im)
-
- ##
- # Returns a rectangular region from this image. The box is a
- # 4-tuple defining the left, upper, right, and lower pixel
- # coordinate.
- # <p>
- # This is a lazy operation. Changes to the source image may or
- # may not be reflected in the cropped image. To break the
- # connection, call the {@link #Image.load} method on the cropped
- # copy.
- #
- # @param The crop rectangle, as a (left, upper, right, lower)-tuple.
- # @return An Image object.
-
- def crop(self, box=None):
- "Crop region from image"
-
- self.load()
- if box is None:
- return self.copy()
-
- # lazy operation
- return _ImageCrop(self, box)
-
- ##
- # Configures the image file loader so it returns a version of the
- # image that as closely as possible matches the given mode and
- # size. For example, you can use this method to convert a colour
- # JPEG to greyscale while loading it, or to extract a 128x192
- # version from a PCD file.
- # <p>
- # Note that this method modifies the Image object in place. If
- # the image has already been loaded, this method has no effect.
- #
- # @param mode The requested mode.
- # @param size The requested size.
-
- def draft(self, mode, size):
- "Configure image decoder"
-
- pass
-
- def _expand(self, xmargin, ymargin=None):
- if ymargin is None:
- ymargin = xmargin
- self.load()
- return self._new(self.im.expand(xmargin, ymargin, 0))
-
- ##
- # Filters this image using the given filter. For a list of
- # available filters, see the <b>ImageFilter</b> module.
- #
- # @param filter Filter kernel.
- # @return An Image object.
- # @see ImageFilter
-
- def filter(self, filter):
- "Apply environment filter to image"
-
- self.load()
-
- from ImageFilter import Filter
- if not isinstance(filter, Filter):
- filter = filter()
-
- if self.im.bands == 1:
- return self._new(filter.filter(self.im))
- # fix to handle multiband images since _imaging doesn't
- ims = []
- for c in range(self.im.bands):
- ims.append(self._new(filter.filter(self.im.getband(c))))
- return merge(self.mode, ims)
-
- ##
- # Returns a tuple containing the name of each band in this image.
- # For example, <b>getbands</b> on an RGB image returns ("R", "G", "B").
- #
- # @return A tuple containing band names.
-
- def getbands(self):
- "Get band names"
-
- return ImageMode.getmode(self.mode).bands
-
- ##
- # Calculates the bounding box of the non-zero regions in the
- # image.
- #
- # @return The bounding box is returned as a 4-tuple defining the
- # left, upper, right, and lower pixel coordinate. If the image
- # is completely empty, this method returns None.
-
- def getbbox(self):
- "Get bounding box of actual data (non-zero pixels) in image"
-
- self.load()
- return self.im.getbbox()
-
- ##
- # Returns a list of colors used in this image.
- #
- # @param maxcolors Maximum number of colors. If this number is
- # exceeded, this method returns None. The default limit is
- # 256 colors.
- # @return An unsorted list of (count, pixel) values.
-
- def getcolors(self, maxcolors=256):
- "Get colors from image, up to given limit"
-
- self.load()
- if self.mode in ("1", "L", "P"):
- h = self.im.histogram()
- out = []
- for i in range(256):
- if h[i]:
- out.append((h[i], i))
- if len(out) > maxcolors:
- return None
- return out
- return self.im.getcolors(maxcolors)
-
- ##
- # Returns the contents of this image as a sequence object
- # containing pixel values. The sequence object is flattened, so
- # that values for line one follow directly after the values of
- # line zero, and so on.
- # <p>
- # Note that the sequence object returned by this method is an
- # internal PIL data type, which only supports certain sequence
- # operations. To convert it to an ordinary sequence (e.g. for
- # printing), use <b>list(im.getdata())</b>.
- #
- # @param band What band to return. The default is to return
- # all bands. To return a single band, pass in the index
- # value (e.g. 0 to get the "R" band from an "RGB" image).
- # @return A sequence-like object.
-
- def getdata(self, band = None):
- "Get image data as sequence object."
-
- self.load()
- if band is not None:
- return self.im.getband(band)
- return self.im # could be abused
-
- ##
- # Gets the the minimum and maximum pixel values for each band in
- # the image.
- #
- # @return For a single-band image, a 2-tuple containing the
- # minimum and maximum pixel value. For a multi-band image,
- # a tuple containing one 2-tuple for each band.
-
- def getextrema(self):
- "Get min/max value"
-
- self.load()
- if self.im.bands > 1:
- extrema = []
- for i in range(self.im.bands):
- extrema.append(self.im.getband(i).getextrema())
- return tuple(extrema)
- return self.im.getextrema()
-
- ##
- # Returns a PyCObject that points to the internal image memory.
- #
- # @return A PyCObject object.
-
- def getim(self):
- "Get PyCObject pointer to internal image memory"
-
- self.load()
- return self.im.ptr
-
-
- ##
- # Returns the image palette as a list.
- #
- # @return A list of color values [r, g, b, ...], or None if the
- # image has no palette.
-
- def getpalette(self):
- "Get palette contents."
-
- self.load()
- try:
- return map(ord, self.im.getpalette())
- except ValueError:
- return None # no palette
-
-
- ##
- # Returns the pixel value at a given position.
- #
- # @param xy The coordinate, given as (x, y).
- # @return The pixel value. If the image is a multi-layer image,
- # this method returns a tuple.
-
- def getpixel(self, xy):
- "Get pixel value"
-
- self.load()
- return self.im.getpixel(xy)
-
- ##
- # Returns the horizontal and vertical projection.
- #
- # @return Two sequences, indicating where there are non-zero
- # pixels along the X-axis and the Y-axis, respectively.
-
- def getprojection(self):
- "Get projection to x and y axes"
-
- self.load()
- x, y = self.im.getprojection()
- return map(ord, x), map(ord, y)
-
- ##
- # Returns a histogram for the image. The histogram is returned as
- # a list of pixel counts, one for each pixel value in the source
- # image. If the image has more than one band, the histograms for
- # all bands are concatenated (for example, the histogram for an
- # "RGB" image contains 768 values).
- # <p>
- # A bilevel image (mode "1") is treated as a greyscale ("L") image
- # by this method.
- # <p>
- # If a mask is provided, the method returns a histogram for those
- # parts of the image where the mask image is non-zero. The mask
- # image must have the same size as the image, and be either a
- # bi-level image (mode "1") or a greyscale image ("L").
- #
- # @def histogram(mask=None)
- # @param mask An optional mask.
- # @return A list containing pixel counts.
-
- def histogram(self, mask=None, extrema=None):
- "Take histogram of image"
-
- self.load()
- if mask:
- mask.load()
- return self.im.histogram((0, 0), mask.im)
- if self.mode in ("I", "F"):
- if extrema is None:
- extrema = self.getextrema()
- return self.im.histogram(extrema)
- return self.im.histogram()
-
- ##
- # (Deprecated) Returns a copy of the image where the data has been
- # offset by the given distances. Data wraps around the edges. If
- # yoffset is omitted, it is assumed to be equal to xoffset.
- # <p>
- # This method is deprecated. New code should use the <b>offset</b>
- # function in the <b>ImageChops</b> module.
- #
- # @param xoffset The horizontal distance.
- # @param yoffset The vertical distance. If omitted, both
- # distances are set to the same value.
- # @return An Image object.
-
- def offset(self, xoffset, yoffset=None):
- "(deprecated) Offset image in horizontal and/or vertical direction"
- if warnings:
- warnings.warn(
- "'offset' is deprecated; use 'ImageChops.offset' instead",
- DeprecationWarning, stacklevel=2
- )
- import ImageChops
- return ImageChops.offset(self, xoffset, yoffset)
-
- ##
- # Pastes another image into this image. The box argument is either
- # a 2-tuple giving the upper left corner, a 4-tuple defining the
- # left, upper, right, and lower pixel coordinate, or None (same as
- # (0, 0)). If a 4-tuple is given, the size of the pasted image
- # must match the size of the region.
- # <p>
- # If the modes don't match, the pasted image is converted to the
- # mode of this image (see the {@link #Image.convert} method for
- # details).
- # <p>
- # Instead of an image, the source can be a integer or tuple
- # containing pixel values. The method then fills the region
- # with the given colour. When creating RGB images, you can
- # also use colour strings as supported by the ImageColor module.
- # <p>
- # If a mask is given, this method updates only the regions
- # indicated by the mask. You can use either "1", "L" or "RGBA"
- # images (in the latter case, the alpha band is used as mask).
- # Where the mask is 255, the given image is copied as is. Where
- # the mask is 0, the current value is preserved. Intermediate
- # values can be used for transparency effects.
- # <p>
- # Note that if you paste an "RGBA" image, the alpha band is
- # ignored. You can work around this by using the same image as
- # both source image and mask.
- #
- # @param im Source image or pixel value (integer or tuple).
- # @param box An optional 4-tuple giving the region to paste into.
- # If a 2-tuple is used instead, it's treated as the upper left
- # corner. If omitted or None, the source is pasted into the
- # upper left corner.
- # <p>
- # If an image is given as the second argument and there is no
- # third, the box defaults to (0, 0), and the second argument
- # is interpreted as a mask image.
- # @param mask An optional mask image.
- # @return An Image object.
-
- def paste(self, im, box=None, mask=None):
- "Paste other image into region"
-
- if isImageType(box) and mask is None:
- # abbreviated paste(im, mask) syntax
- mask = box; box = None
-
- if box is None:
- # cover all of self
- box = (0, 0) + self.size
-
- if len(box) == 2:
- # lower left corner given; get size from image or mask
- if isImageType(im):
- size = im.size
- elif isImageType(mask):
- size = mask.size
- else:
- # FIXME: use self.size here?
- raise ValueError(
- "cannot determine region size; use 4-item box"
- )
- box = box + (box[0]+size[0], box[1]+size[1])
-
- if isStringType(im):
- import ImageColor
- im = ImageColor.getcolor(im, self.mode)
-
- elif isImageType(im):
- im.load()
- if self.mode != im.mode:
- if self.mode != "RGB" or im.mode not in ("RGBA", "RGBa"):
- # should use an adapter for this!
- im = im.convert(self.mode)
- im = im.im
-
- self.load()
- if self.readonly:
- self._copy()
-
- if mask:
- mask.load()
- self.im.paste(im, box, mask.im)
- else:
- self.im.paste(im, box)
-
- ##
- # Maps this image through a lookup table or function.
- #
- # @param lut A lookup table, containing 256 values per band in the
- # image. A function can be used instead, it should take a single
- # argument. The function is called once for each possible pixel
- # value, and the resulting table is applied to all bands of the
- # image.
- # @param mode Output mode (default is same as input). In the
- # current version, this can only be used if the source image
- # has mode "L" or "P", and the output has mode "1".
- # @return An Image object.
-
- def point(self, lut, mode=None):
- "Map image through lookup table"
-
- self.load()
-
- if not isSequenceType(lut):
- # if it isn't a list, it should be a function
- if self.mode in ("I", "I;16", "F"):
- # check if the function can be used with point_transform
- scale, offset = _getscaleoffset(lut)
- return self._new(self.im.point_transform(scale, offset))
- # for other modes, convert the function to a table
- lut = map(lut, range(256)) * self.im.bands
-
- if self.mode == "F":
- # FIXME: _imaging returns a confusing error message for this case
- raise ValueError("point operation not supported for this mode")
-
- return self._new(self.im.point(lut, mode))
-
- ##
- # Adds or replaces the alpha layer in this image. If the image
- # does not have an alpha layer, it's converted to "LA" or "RGBA".
- # The new layer must be either "L" or "1".
- #
- # @param im The new alpha layer. This can either be an "L" or "1"
- # image having the same size as this image, or an integer or
- # other color value.
-
- def putalpha(self, alpha):
- "Set alpha layer"
-
- self.load()
- if self.readonly:
- self._copy()
-
- if self.mode not in ("LA", "RGBA"):
- # attempt to promote self to a matching alpha mode
- try:
- mode = getmodebase(self.mode) + "A"
- try:
- self.im.setmode(mode)
- except (AttributeError, ValueError):
- # do things the hard way
- im = self.im.convert(mode)
- if im.mode not in ("LA", "RGBA"):
- raise ValueError # sanity check
- self.im = im
- self.mode = self.im.mode
- except (KeyError, ValueError):
- raise ValueError("illegal image mode")
-
- if self.mode == "LA":
- band = 1
- else:
- band = 3
-
- if isImageType(alpha):
- # alpha layer
- if alpha.mode not in ("1", "L"):
- raise ValueError("illegal image mode")
- alpha.load()
- if alpha.mode == "1":
- alpha = alpha.convert("L")
- else:
- # constant alpha
- try:
- self.im.fillband(band, alpha)
- except (AttributeError, ValueError):
- # do things the hard way
- alpha = new("L", self.size, alpha)
- else:
- return
-
- self.im.putband(alpha.im, band)
-
- ##
- # Copies pixel data to this image. This method copies data from a
- # sequence object into the image, starting at the upper left
- # corner (0, 0), and continuing until either the image or the
- # sequence ends. The scale and offset values are used to adjust
- # the sequence values: <b>pixel = value*scale + offset</b>.
- #
- # @param data A sequence object.
- # @param scale An optional scale value. The default is 1.0.
- # @param offset An optional offset value. The default is 0.0.
-
- def putdata(self, data, scale=1.0, offset=0.0):
- "Put data from a sequence object into an image."
-
- self.load()
- if self.readonly:
- self._copy()
-
- self.im.putdata(data, scale, offset)
-
- ##
- # Attaches a palette to this image. The image must be a "P" or
- # "L" image, and the palette sequence must contain 768 integer
- # values, where each group of three values represent the red,
- # green, and blue values for the corresponding pixel
- # index. Instead of an integer sequence, you can use an 8-bit
- # string.
- #
- # @def putpalette(data)
- # @param data A palette sequence (either a list or a string).
-
- def putpalette(self, data, rawmode="RGB"):
- "Put palette data into an image."
-
- self.load()
- if self.mode not in ("L", "P"):
- raise ValueError("illegal image mode")
- if not isStringType(data):
- data = string.join(map(chr, data), "")
- self.mode = "P"
- self.palette = ImagePalette.raw(rawmode, data)
- self.palette.mode = "RGB"
- self.load() # install new palette
-
- ##
- # Modifies the pixel at the given position. The colour is given as
- # a single numerical value for single-band images, and a tuple for
- # multi-band images.
- # <p>
- # Note that this method is relatively slow. For more extensive
- # changes, use {@link #Image.paste} or the <b>ImageDraw</b> module
- # instead.
- #
- # @param xy The pixel coordinate, given as (x, y).
- # @param value The pixel value.
- # @see #Image.paste
- # @see #Image.putdata
- # @see ImageDraw
-
- def putpixel(self, xy, value):
- "Set pixel value"
-
- self.load()
- if self.readonly:
- self._copy()
-
- return self.im.putpixel(xy, value)
-
- ##
- # Returns a resized copy of this image.
- #
- # @def resize(size, filter=NEAREST)
- # @param size The requested size in pixels, as a 2-tuple:
- # (width, height).
- # @param filter An optional resampling filter. This can be
- # one of <b>NEAREST</b> (use nearest neighbour), <b>BILINEAR</b>
- # (linear interpolation in a 2x2 environment), <b>BICUBIC</b>
- # (cubic spline interpolation in a 4x4 environment), or
- # <b>ANTIALIAS</b> (a high-quality downsampling filter).
- # If omitted, or if the image has mode "1" or "P", it is
- # set <b>NEAREST</b>.
- # @return An Image object.
-
- def resize(self, size, resample=NEAREST):
- "Resize image"
-
- if resample not in (NEAREST, BILINEAR, BICUBIC, ANTIALIAS):
- raise ValueError("unknown resampling filter")
-
- self.load()
-
- if self.mode in ("1", "P"):
- resample = NEAREST
-
- if resample == ANTIALIAS:
- # requires stretch support (imToolkit & PIL 1.1.3)
- try:
- im = self.im.stretch(size, resample)
- except AttributeError:
- raise ValueError("unsupported resampling filter")
- else:
- im = self.im.resize(size, resample)
-
- return self._new(im)
-
- ##
- # Returns a rotated copy of this image. This method returns a
- # copy of this image, rotated the given number of degrees counter
- # clockwise around its centre.
- #
- # @def rotate(angle, filter=NEAREST)
- # @param angle In degrees counter clockwise.
- # @param filter An optional resampling filter. This can be
- # one of <b>NEAREST</b> (use nearest neighbour), <b>BILINEAR</b>
- # (linear interpolation in a 2x2 environment), or <b>BICUBIC</b>
- # (cubic spline interpolation in a 4x4 environment).
- # If omitted, or if the image has mode "1" or "P", it is
- # set <b>NEAREST</b>.
- # @param expand Optional expansion flag. If true, expands the output
- # image to make it large enough to hold the entire rotated image.
- # If false or omitted, make the output image the same size as the
- # input image.
- # @return An Image object.
-
- def rotate(self, angle, resample=NEAREST, expand=0):
- "Rotate image. Angle given as degrees counter-clockwise."
-
- if expand:
- import math
- angle = -angle * math.pi / 180
- matrix = [
- math.cos(angle), math.sin(angle), 0.0,
- -math.sin(angle), math.cos(angle), 0.0
- ]
- def transform(x, y, (a, b, c, d, e, f)=matrix):
- return a*x + b*y + c, d*x + e*y + f
-
- # calculate output size
- w, h = self.size
- xx = []
- yy = []
- for x, y in ((0, 0), (w, 0), (w, h), (0, h)):
- x, y = transform(x, y)
- xx.append(x)
- yy.append(y)
- w = int(math.ceil(max(xx)) - math.floor(min(xx)))
- h = int(math.ceil(max(yy)) - math.floor(min(yy)))
-
- # adjust center
- x, y = transform(w / 2.0, h / 2.0)
- matrix[2] = self.size[0] / 2.0 - x
- matrix[5] = self.size[1] / 2.0 - y
-
- return self.transform((w, h), AFFINE, matrix)
-
- if resample not in (NEAREST, BILINEAR, BICUBIC):
- raise ValueError("unknown resampling filter")
-
- self.load()
-
- if self.mode in ("1", "P"):
- resample = NEAREST
-
- return self._new(self.im.rotate(angle, resample))
-
- ##
- # Saves this image under the given filename. If no format is
- # specified, the format to use is determined from the filename
- # extension, if possible.
- # <p>
- # Keyword options can be used to provide additional instructions
- # to the writer. If a writer doesn't recognise an option, it is
- # silently ignored. The available options are described later in
- # this handbook.
- # <p>
- # You can use a file object instead of a filename. In this case,
- # you must always specify the format. The file object must
- # implement the <b>seek</b>, <b>tell</b>, and <b>write</b>
- # methods, and be opened in binary mode.
- #
- # @def save(file, format=None, **options)
- # @param file File name or file object.
- # @param format Optional format override. If omitted, the
- # format to use is determined from the filename extension.
- # If a file object was used instead of a filename, this
- # parameter should always be used.
- # @param **options Extra parameters to the image writer.
- # @return None
- # @exception KeyError If the output format could not be determined
- # from the file name. Use the format option to solve this.
- # @exception IOError If the file could not be written. The file
- # may have been created, and may contain partial data.
-
- def save(self, fp, format=None, **params):
- "Save image to file or stream"
-
- if isStringType(fp):
- filename = fp
- else:
- if hasattr(fp, "name") and isStringType(fp.name):
- filename = fp.name
- else:
- filename = ""
-
- # may mutate self!
- self.load()
-
- self.encoderinfo = params
- self.encoderconfig = ()
-
- preinit()
-
- ext = string.lower(os.path.splitext(filename)[1])
-
- if not format:
- try:
- format = EXTENSION[ext]
- except KeyError:
- init()
- try:
- format = EXTENSION[ext]
- except KeyError:
- raise KeyError(ext) # unknown extension
-
- try:
- save_handler = SAVE[string.upper(format)]
- except KeyError:
- init()
- save_handler = SAVE[string.upper(format)] # unknown format
-
- if isStringType(fp):
- import __builtin__
- fp = __builtin__.open(fp, "wb")
- close = 1
- else:
- close = 0
-
- try:
- save_handler(self, fp, filename)
- finally:
- # do what we can to clean up
- if close:
- fp.close()
-
- ##
- # Seeks to the given frame in this sequence file. If you seek
- # beyond the end of the sequence, the method raises an
- # <b>EOFError</b> exception. When a sequence file is opened, the
- # library automatically seeks to frame 0.
- # <p>
- # Note that in the current version of the library, most sequence
- # formats only allows you to seek to the next frame.
- #
- # @param frame Frame number, starting at 0.
- # @exception EOFError If the call attempts to seek beyond the end
- # of the sequence.
- # @see #Image.tell
-
- def seek(self, frame):
- "Seek to given frame in sequence file"
-
- # overridden by file handlers
- if frame != 0:
- raise EOFError
-
- ##
- # Displays this image. This method is mainly intended for
- # debugging purposes.
- # <p>
- # On Unix platforms, this method saves the image to a temporary
- # PPM file, and calls the <b>xv</b> utility.
- # <p>
- # On Windows, it saves the image to a temporary BMP file, and uses
- # the standard BMP display utility to show it (usually Paint).
- #
- # @def show(title=None)
- # @param title Optional title to use for the image window,
- # where possible.
-
- def show(self, title=None, command=None):
- "Display image (for debug purposes only)"
-
- _showxv(self, title, command)
-
- ##
- # Split this image into individual bands. This method returns a
- # tuple of individual image bands from an image. For example,
- # splitting an "RGB" image creates three new images each
- # containing a copy of one of the original bands (red, green,
- # blue).
- #
- # @return A tuple containing bands.
-
- def split(self):
- "Split image into bands"
-
- ims = []
- self.load()
- for i in range(self.im.bands):
- ims.append(self._new(self.im.getband(i)))
- return tuple(ims)
-
- ##
- # Returns the current frame number.
- #
- # @return Frame number, starting with 0.
- # @see #Image.seek
-
- def tell(self):
- "Return current frame number"
-
- return 0
-
- ##
- # Make this image into a thumbnail. This method modifies the
- # image to contain a thumbnail version of itself, no larger than
- # the given size. This method calculates an appropriate thumbnail
- # size to preserve the aspect of the image, calls the {@link
- # #Image.draft} method to configure the file reader (where
- # applicable), and finally resizes the image.
- # <p>
- # Note that the bilinear and bicubic filters in the current
- # version of PIL are not well-suited for thumbnail generation.
- # You should use <b>ANTIALIAS</b> unless speed is much more
- # important than quality.
- # <p>
- # Also note that this function modifies the Image object in place.
- # If you need to use the full resolution image as well, apply this
- # method to a {@link #Image.copy} of the original image.
- #
- # @param size Requested size.
- # @param resample Optional resampling filter. This can be one
- # of <b>NEAREST</b>, <b>BILINEAR</b>, <b>BICUBIC</b>, or
- # <b>ANTIALIAS</b> (best quality). If omitted, it defaults
- # to <b>NEAREST</b> (this will be changed to ANTIALIAS in a
- # future version).
- # @return None
-
- def thumbnail(self, size, resample=NEAREST):
- "Create thumbnail representation (modifies image in place)"
-
- # FIXME: the default resampling filter will be changed
- # to ANTIALIAS in future versions
-
- # preserve aspect ratio
- x, y = self.size
- if x > size[0]: y = max(y * size[0] / x, 1); x = size[0]
- if y > size[1]: x = max(x * size[1] / y, 1); y = size[1]
- size = x, y
-
- if size == self.size:
- return
-
- self.draft(None, size)
-
- self.load()
-
- try:
- im = self.resize(size, resample)
- except ValueError:
- if resample != ANTIALIAS:
- raise
- im = self.resize(size, NEAREST) # fallback
-
- self.im = im.im
- self.mode = im.mode
- self.size = size
-
- self.readonly = 0
-
- # FIXME: the different tranform methods need further explanation
- # instead of bloating the method docs, add a separate chapter.
-
- ##
- # Transforms this image. This method creates a new image with the
- # given size, and the same mode as the original, and copies data
- # to the new image using the given transform.
- # <p>
- # @def transform(size, method, data, resample=NEAREST)
- # @param size The output size.
- # @param method The transformation method. This is one of
- # <b>EXTENT</b> (cut out a rectangular subregion), <b>AFFINE</b>
- # (affine transform), <b>PERSPECTIVE</b> (perspective
- # transform), <b>QUAD</b> (map a quadrilateral to a
- # rectangle), or <b>MESH</b> (map a number of source quadrilaterals
- # in one operation).
- # @param data Extra data to the transformation method.
- # @param resample Optional resampling filter. It can be one of
- # <b>NEAREST</b> (use nearest neighbour), <b>BILINEAR</b>
- # (linear interpolation in a 2x2 environment), or
- # <b>BICUBIC</b> (cubic spline interpolation in a 4x4
- # environment). If omitted, or if the image has mode
- # "1" or "P", it is set to <b>NEAREST</b>.
- # @return An Image object.
-
- def transform(self, size, method, data=None, resample=NEAREST, fill=1):
- "Transform image"
-
- import ImageTransform
- if isinstance(method, ImageTransform.Transform):
- method, data = method.getdata()
- if data is None:
- raise ValueError("missing method data")
- im = new(self.mode, size, None)
- if method == MESH:
- # list of quads
- for box, quad in data:
- im.__transformer(box, self, QUAD, quad, resample, fill)
- else:
- im.__transformer((0, 0)+size, self, method, data, resample, fill)
-
- return im
-
- def __transformer(self, box, image, method, data,
- resample=NEAREST, fill=1):
-
- # FIXME: this should be turned into a lazy operation (?)
-
- w = box[2]-box[0]
- h = box[3]-box[1]
-
- if method == AFFINE:
- # change argument order to match implementation
- data = (data[2], data[0], data[1],
- data[5], data[3], data[4])
- elif method == EXTENT:
- # convert extent to an affine transform
- x0, y0, x1, y1 = data
- xs = float(x1 - x0) / w
- ys = float(y1 - y0) / h
- method = AFFINE
- data = (x0 + xs/2, xs, 0, y0 + ys/2, 0, ys)
- elif method == PERSPECTIVE:
- # change argument order to match implementation
- data = (data[2], data[0], data[1],
- data[5], data[3], data[4],
- data[6], data[7])
- elif method == QUAD:
- # quadrilateral warp. data specifies the four corners
- # given as NW, SW, SE, and NE.
- nw = data[0:2]; sw = data[2:4]; se = data[4:6]; ne = data[6:8]
- x0, y0 = nw; As = 1.0 / w; At = 1.0 / h
- data = (x0, (ne[0]-x0)*As, (sw[0]-x0)*At,
- (se[0]-sw[0]-ne[0]+x0)*As*At,
- y0, (ne[1]-y0)*As, (sw[1]-y0)*At,
- (se[1]-sw[1]-ne[1]+y0)*As*At)
- else:
- raise ValueError("unknown transformation method")
-
- if resample not in (NEAREST, BILINEAR, BICUBIC):
- raise ValueError("unknown resampling filter")
-
- image.load()
-
- self.load()
-
- if image.mode in ("1", "P"):
- resample = NEAREST
-
- self.im.transform2(box, image.im, method, data, resample, fill)
-
- ##
- # Returns a flipped or rotated copy of this image.
- #
- # @param method One of <b>FLIP_LEFT_RIGHT</b>, <b>FLIP_TOP_BOTTOM</b>,
- # <b>ROTATE_90</b>, <b>ROTATE_180</b>, or <b>ROTATE_270</b>.
-
- def transpose(self, method):
- "Transpose image (flip or rotate in 90 degree steps)"
-
- self.load()
- im = self.im.transpose(method)
- return self._new(im)
-
-# --------------------------------------------------------------------
-# Lazy operations
-
-class _ImageCrop(Image):
-
- def __init__(self, im, box):
-
- Image.__init__(self)
-
- x0, y0, x1, y1 = box
- if x1 < x0:
- x1 = x0
- if y1 < y0:
- y1 = y0
-
- self.mode = im.mode
- self.size = x1-x0, y1-y0
-
- self.__crop = x0, y0, x1, y1
-
- self.im = im.im
-
- def load(self):
-
- # lazy evaluation!
- if self.__crop:
- self.im = self.im.crop(self.__crop)
- self.__crop = None
-
- # FIXME: future versions should optimize crop/paste
- # sequences!
-
-# --------------------------------------------------------------------
-# Factories
-
-#
-# Debugging
-
-def _wedge():
- "Create greyscale wedge (for debugging only)"
-
- return Image()._new(core.wedge("L"))
-
-##
-# Creates a new image with the given mode and size.
-#
-# @param mode The mode to use for the new image.
-# @param size A 2-tuple, containing (width, height) in pixels.
-# @param color What colour to use for the image. Default is black.
-# If given, this should be a single integer or floating point value
-# for single-band modes, and a tuple for multi-band modes (one value
-# per band). When creating RGB images, you can also use colour
-# strings as supported by the ImageColor module. If the colour is
-# None, the image is not initialised.
-# @return An Image object.
-
-def new(mode, size, color=0):
- "Create a new image"
-
- if color is None:
- # don't initialize
- return Image()._new(core.new(mode, size))
-
- if isStringType(color):
- # css3-style specifier
-
- import ImageColor
- color = ImageColor.getcolor(color, mode)
-
- return Image()._new(core.fill(mode, size, color))
-
-##
-# Creates an image memory from pixel data in a string.
-# <p>
-# In its simplest form, this function takes three arguments
-# (mode, size, and unpacked pixel data).
-# <p>
-# You can also use any pixel decoder supported by PIL. For more
-# information on available decoders, see the section <a
-# href="pil-decoder.htm"><i>Writing Your Own File Decoder</i></a>.
-# <p>
-# Note that this function decodes pixel data only, not entire images.
-# If you have an entire image in a string, wrap it in a
-# <b>StringIO</b> object, and use {@link #open} to load it.
-#
-# @param mode The image mode.
-# @param size The image size.
-# @param data An 8-bit string containing raw data for the given mode.
-# @param decoder_name What decoder to use.
-# @param *args Additional parameters for the given decoder.
-# @return An Image object.
-
-def fromstring(mode, size, data, decoder_name="raw", *args):
- "Load image from string"
-
- # may pass tuple instead of argument list
- if len(args) == 1 and isTupleType(args[0]):
- args = args[0]
-
- if decoder_name == "raw" and args == ():
- args = mode
-
- im = new(mode, size)
- im.fromstring(data, decoder_name, args)
- return im
-
-##
-# (New in 1.1.4) Creates an image memory from pixel data in a string
-# or byte buffer.
-# <p>
-# This function is similar to {@link #fromstring}, but uses data in
-# the byte buffer, where possible. This means that changes to the
-# original buffer object are reflected in this image). Not all modes
-# can share memory; supported modes include "L", "RGBX", "RGBA", and
-# "CMYK".
-# <p>
-# Note that this function decodes pixel data only, not entire images.
-# If you have an entire image file in a string, wrap it in a
-# <b>StringIO</b> object, and use {@link #open} to load it.
-# <p>
-# In the current version, the default parameters used for the "raw"
-# decoder differs from that used for {@link fromstring}. This is a
-# bug, and will probably be fixed in a future release. The current
-# release issues a warning if you do this; to disable the warning,
-# you should provide the full set of parameters. See below for
-# details.
-#
-# @param mode The image mode.
-# @param size The image size.
-# @param data An 8-bit string or other buffer object containing raw
-# data for the given mode.
-# @param decoder_name What decoder to use.
-# @param *args Additional parameters for the given decoder. For the
-# default encoder ("raw"), it's recommended that you provide the
-# full set of parameters:
-# <b>frombuffer(mode, size, data, "raw", mode, 0, 1)</b>.
-# @return An Image object.
-# @since 1.1.4
-
-def frombuffer(mode, size, data, decoder_name="raw", *args):
- "Load image from string or buffer"
-
- # may pass tuple instead of argument list
- if len(args) == 1 and isTupleType(args[0]):
- args = args[0]
-
- if decoder_name == "raw":
- if args == ():
- if warnings:
- warnings.warn(
- "the frombuffer defaults may change in a future release; "
- "for portability, change the call to read:\n"
- " frombuffer(mode, size, data, 'raw', mode, 0, 1)",
- RuntimeWarning, stacklevel=2
- )
- args = mode, 0, -1 # may change to (mode, 0, 1) post-1.1.6
- if args[0] in _MAPMODES:
- im = new(mode, (1,1))
- im = im._new(
- core.map_buffer(data, size, decoder_name, None, 0, args)
- )
- im.readonly = 1
- return im
-
- return apply(fromstring, (mode, size, data, decoder_name, args))
-
-
-##
-# (New in 1.1.6) Create an image memory from an object exporting
-# the array interface (using the buffer protocol).
-#
-# If obj is not contiguous, then the tostring method is called
-# and {@link frombuffer} is used.
-#
-# @param obj Object with array interface
-# @param mode Mode to use (will be determined from type if None)
-# @return An image memory.
-
-def fromarray(obj, mode=None):
- arr = obj.__array_interface__
- shape = arr['shape']
- ndim = len(shape)
- try:
- strides = arr['strides']
- except KeyError:
- strides = None
- if mode is None:
- typestr = arr['typestr']
- if not (typestr[0] == '|' or typestr[0] == _ENDIAN or
- typestr[1:] not in ['u1', 'b1', 'i4', 'f4']):
- raise TypeError("cannot handle data-type")
- typestr = typestr[:2]
- if typestr == 'i4':
- mode = 'I'
- elif typestr == 'f4':
- mode = 'F'
- elif typestr == 'b1':
- mode = '1'
- elif ndim == 2:
- mode = 'L'
- elif ndim == 3:
- mode = 'RGB'
- elif ndim == 4:
- mode = 'RGBA'
- else:
- raise TypeError("Do not understand data.")
- ndmax = 4
- bad_dims=0
- if mode in ['1','L','I','P','F']:
- ndmax = 2
- elif mode == 'RGB':
- ndmax = 3
- if ndim > ndmax:
- raise ValueError("Too many dimensions.")
-
- size = shape[:2][::-1]
- if strides is not None:
- obj = obj.tostring()
-
- return frombuffer(mode, size, obj, "raw", mode, 0, 1)
-
-##
-# Opens and identifies the given image file.
-# <p>
-# This is a lazy operation; this function identifies the file, but the
-# actual image data is not read from the file until you try to process
-# the data (or call the {@link #Image.load} method).
-#
-# @def open(file, mode="r")
-# @param file A filename (string) or a file object. The file object
-# must implement <b>read</b>, <b>seek</b>, and <b>tell</b> methods,
-# and be opened in binary mode.
-# @param mode The mode. If given, this argument must be "r".
-# @return An Image object.
-# @exception IOError If the file cannot be found, or the image cannot be
-# opened and identified.
-# @see #new
-
-def open(fp, mode="r"):
- "Open an image file, without loading the raster data"
-
- if mode != "r":
- raise ValueError("bad mode")
-
- if isStringType(fp):
- import __builtin__
- filename = fp
- fp = __builtin__.open(fp, "rb")
- else:
- filename = ""
-
- prefix = fp.read(16)
-
- preinit()
-
- for i in ID:
- try:
- factory, accept = OPEN[i]
- if not accept or accept(prefix):
- fp.seek(0)
- return factory(fp, filename)
- except (SyntaxError, IndexError, TypeError):
- pass
-
- init()
-
- for i in ID:
- try:
- factory, accept = OPEN[i]
- if not accept or accept(prefix):
- fp.seek(0)
- return factory(fp, filename)
- except (SyntaxError, IndexError, TypeError):
- pass
-
- raise IOError("cannot identify image file")
-
-#
-# Image processing.
-
-##
-# Creates a new image by interpolating between two input images, using
-# a constant alpha.
-#
-# <pre>
-# out = image1 * (1.0 - alpha) + image2 * alpha
-# </pre>
-#
-# @param im1 The first image.
-# @param im2 The second image. Must have the same mode and size as
-# the first image.
-# @param alpha The interpolation alpha factor. If alpha is 0.0, a
-# copy of the first image is returned. If alpha is 1.0, a copy of
-# the second image is returned. There are no restrictions on the
-# alpha value. If necessary, the result is clipped to fit into
-# the allowed output range.
-# @return An Image object.
-
-def blend(im1, im2, alpha):
- "Interpolate between images."
-
- im1.load()
- im2.load()
- return im1._new(core.blend(im1.im, im2.im, alpha))
-
-##
-# Creates a new image by interpolating between two input images,
-# using the mask as alpha.
-#
-# @param image1 The first image.
-# @param image2 The second image. Must have the same mode and
-# size as the first image.
-# @param mask A mask image. This image can can have mode
-# "1", "L", or "RGBA", and must have the same size as the
-# other two images.
-
-def composite(image1, image2, mask):
- "Create composite image by blending images using a transparency mask"
-
- image = image2.copy()
- image.paste(image1, None, mask)
- return image
-
-##
-# Applies the function (which should take one argument) to each pixel
-# in the given image. If the image has more than one band, the same
-# function is applied to each band. Note that the function is
-# evaluated once for each possible pixel value, so you cannot use
-# random components or other generators.
-#
-# @def eval(image, function)
-# @param image The input image.
-# @param function A function object, taking one integer argument.
-# @return An Image object.
-
-def eval(image, *args):
- "Evaluate image expression"
-
- return image.point(args[0])
-
-##
-# Creates a new image from a number of single-band images.
-#
-# @param mode The mode to use for the output image.
-# @param bands A sequence containing one single-band image for
-# each band in the output image. All bands must have the
-# same size.
-# @return An Image object.
-
-def merge(mode, bands):
- "Merge a set of single band images into a new multiband image."
-
- if getmodebands(mode) != len(bands) or "*" in mode:
- raise ValueError("wrong number of bands")
- for im in bands[1:]:
- if im.mode != getmodetype(mode):
- raise ValueError("mode mismatch")
- if im.size != bands[0].size:
- raise ValueError("size mismatch")
- im = core.new(mode, bands[0].size)
- for i in range(getmodebands(mode)):
- bands[i].load()
- im.putband(bands[i].im, i)
- return bands[0]._new(im)
-
-# --------------------------------------------------------------------
-# Plugin registry
-
-##
-# Register an image file plugin. This function should not be used
-# in application code.
-#
-# @param id An image format identifier.
-# @param factory An image file factory method.
-# @param accept An optional function that can be used to quickly
-# reject images having another format.
-
-def register_open(id, factory, accept=None):
- id = string.upper(id)
- ID.append(id)
- OPEN[id] = factory, accept
-
-##
-# Registers an image MIME type. This function should not be used
-# in application code.
-#
-# @param id An image format identifier.
-# @param mimetype The image MIME type for this format.
-
-def register_mime(id, mimetype):
- MIME[string.upper(id)] = mimetype
-
-##
-# Registers an image save function. This function should not be
-# used in application code.
-#
-# @param id An image format identifier.
-# @param driver A function to save images in this format.
-
-def register_save(id, driver):
- SAVE[string.upper(id)] = driver
-
-##
-# Registers an image extension. This function should not be
-# used in application code.
-#
-# @param id An image format identifier.
-# @param extension An extension used for this format.
-
-def register_extension(id, extension):
- EXTENSION[string.lower(extension)] = string.upper(id)
-
-
-# --------------------------------------------------------------------
-# Simple display support
-
-def _showxv(image, title=None, command=None):
-
- if os.name == "nt":
- format = "BMP"
- elif sys.platform == "darwin":
- format = "JPEG"
- if not command:
- command = "open -a /Applications/Preview.app"
- else:
- format = None
- if not command:
- command = "xv"
- if title:
- command = command + " -name \"%s\"" % title
-
- if image.mode == "I;16":
- # @PIL88 @PIL101
- # "I;16" isn't an 'official' mode, but we still want to
- # provide a simple way to show 16-bit images.
- base = "L"
- else:
- base = getmodebase(image.mode)
- if base != image.mode and image.mode != "1":
- file = image.convert(base)._dump(format=format)
- else:
- file = image._dump(format=format)
-
- if os.name == "nt":
- command = "start /wait %s && del /f %s" % (file, file)
- elif sys.platform == "darwin":
- # on darwin open returns immediately resulting in the temp
- # file removal while app is opening
- command = "(%s %s; sleep 20; rm -f %s)&" % (command, file, file)
- else:
- command = "(%s %s; rm -f %s)&" % (command, file, file)
-
- os.system(command)
diff --git a/PIL/ImageChops.py b/PIL/ImageChops.py
deleted file mode 100644
index 6db0710..0000000
--- a/PIL/ImageChops.py
+++ /dev/null
@@ -1,302 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageChops.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# standard channel operations
-#
-# History:
-# 1996-03-24 fl Created
-# 1996-08-13 fl Added logical operations (for "1" images)
-# 2000-10-12 fl Added offset method (from Image.py)
-#
-# Copyright (c) 1997-2000 by Secret Labs AB
-# Copyright (c) 1996-2000 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-
-##
-# The <b>ImageChops</b> module contains a number of arithmetical image
-# operations, called <i>channel operations</i> ("chops"). These can be
-# used for various purposes, including special effects, image
-# compositions, algorithmic painting, and more.
-# <p>
-# At this time, channel operations are only implemented for 8-bit
-# images (e.g. &quot;L&quot; and &quot;RGB&quot;).
-# <p>
-# Most channel operations take one or two image arguments and returns
-# a new image. Unless otherwise noted, the result of a channel
-# operation is always clipped to the range 0 to MAX (which is 255 for
-# all modes supported by the operations in this module).
-##
-
-##
-# Return an image with the same size as the given image, but filled
-# with the given pixel value.
-#
-# @param image Reference image.
-# @param value Pixel value.
-# @return An image object.
-
-def constant(image, value):
- "Fill a channel with a given grey level"
-
- return Image.new("L", image.size, value)
-
-##
-# Copy image.
-#
-# @param image Source image.
-# @return A copy of the source image.
-
-def duplicate(image):
- "Create a copy of a channel"
-
- return image.copy()
-
-##
-# Inverts an image
-# (MAX - image).
-#
-# @param image Source image.
-# @return An image object.
-
-def invert(image):
- "Invert a channel"
-
- image.load()
- return image._new(image.im.chop_invert())
-
-##
-# Compare images, and return lighter pixel value
-# (max(image1, image2)).
-# <p>
-# Compares the two images, pixel by pixel, and returns a new image
-# containing the lighter values.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def lighter(image1, image2):
- "Select the lighter pixels from each image"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_lighter(image2.im))
-
-##
-# Compare images, and return darker pixel value
-# (min(image1, image2)).
-# <p>
-# Compares the two images, pixel by pixel, and returns a new image
-# containing the darker values.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def darker(image1, image2):
- "Select the darker pixels from each image"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_darker(image2.im))
-
-##
-# Calculate absolute difference
-# (abs(image1 - image2)).
-# <p>
-# Returns the absolute value of the difference between the two images.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def difference(image1, image2):
- "Subtract one image from another"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_difference(image2.im))
-
-##
-# Superimpose positive images
-# (image1 * image2 / MAX).
-# <p>
-# Superimposes two images on top of each other. If you multiply an
-# image with a solid black image, the result is black. If you multiply
-# with a solid white image, the image is unaffected.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def multiply(image1, image2):
- "Superimpose two positive images"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_multiply(image2.im))
-
-##
-# Superimpose negative images
-# (MAX - ((MAX - image1) * (MAX - image2) / MAX)).
-# <p>
-# Superimposes two inverted images on top of each other.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def screen(image1, image2):
- "Superimpose two negative images"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_screen(image2.im))
-
-##
-# Add images
-# ((image1 + image2) / scale + offset).
-# <p>
-# Adds two images, dividing the result by scale and adding the
-# offset. If omitted, scale defaults to 1.0, and offset to 0.0.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def add(image1, image2, scale=1.0, offset=0):
- "Add two images"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_add(image2.im, scale, offset))
-
-##
-# Subtract images
-# ((image1 - image2) / scale + offset).
-# <p>
-# Subtracts two images, dividing the result by scale and adding the
-# offset. If omitted, scale defaults to 1.0, and offset to 0.0.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def subtract(image1, image2, scale=1.0, offset=0):
- "Subtract two images"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_subtract(image2.im, scale, offset))
-
-##
-# Add images without clipping
-# ((image1 + image2) % MAX).
-# <p>
-# Adds two images, without clipping the result.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def add_modulo(image1, image2):
- "Add two images without clipping"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_add_modulo(image2.im))
-
-##
-# Subtract images without clipping
-# ((image1 - image2) % MAX).
-# <p>
-# Subtracts two images, without clipping the result.
-#
-# @param image1 First image.
-# @param image1 Second image.
-# @return An image object.
-
-def subtract_modulo(image1, image2):
- "Subtract two images without clipping"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_subtract_modulo(image2.im))
-
-##
-# Logical AND
-# (image1 and image2).
-
-def logical_and(image1, image2):
- "Logical and between two images"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_and(image2.im))
-
-##
-# Logical OR
-# (image1 or image2).
-
-def logical_or(image1, image2):
- "Logical or between two images"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_or(image2.im))
-
-##
-# Logical XOR
-# (image1 xor image2).
-
-def logical_xor(image1, image2):
- "Logical xor between two images"
-
- image1.load()
- image2.load()
- return image1._new(image1.im.chop_xor(image2.im))
-
-##
-# Blend images using constant transparency weight.
-# <p>
-# Same as the <b>blend</b> function in the <b>Image</b> module.
-
-def blend(image1, image2, alpha):
- "Blend two images using a constant transparency weight"
-
- return Image.blend(image1, image2, alpha)
-
-##
-# Create composite using transparency mask.
-# <p>
-# Same as the <b>composite</b> function in the <b>Image</b> module.
-
-def composite(image1, image2, mask):
- "Create composite image by blending images using a transparency mask"
-
- return Image.composite(image1, image2, mask)
-
-##
-# Offset image data.
-# <p>
-# Returns a copy of the image where data has been offset by the given
-# distances. Data wraps around the edges. If yoffset is omitted, it
-# is assumed to be equal to xoffset.
-#
-# @param image Source image.
-# @param xoffset The horizontal distance.
-# @param yoffset The vertical distance. If omitted, both
-# distances are set to the same value.
-# @return An Image object.
-
-def offset(image, xoffset, yoffset=None):
- "Offset image in horizontal and/or vertical direction"
- if yoffset is None:
- yoffset = xoffset
- image.load()
- return image._new(image.im.offset(xoffset, yoffset))
diff --git a/PIL/ImageColor.py b/PIL/ImageColor.py
deleted file mode 100644
index d97c0c4..0000000
--- a/PIL/ImageColor.py
+++ /dev/null
@@ -1,262 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: ImageColor.py 2813 2006-10-07 10:11:35Z fredrik $
-#
-# map CSS3-style colour description strings to RGB
-#
-# History:
-# 2002-10-24 fl Added support for CSS-style color strings
-# 2002-12-15 fl Added RGBA support
-# 2004-03-27 fl Fixed remaining int() problems for Python 1.5.2
-# 2004-07-19 fl Fixed gray/grey spelling issues
-#
-# Copyright (c) 2002-2004 by Secret Labs AB
-# Copyright (c) 2002-2004 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import re, string
-
-try:
- x = int("a", 16)
-except TypeError:
- # python 1.5.2 doesn't support int(x,b)
- str2int = string.atoi
-else:
- str2int = int
-
-##
-# Convert color string to RGB tuple.
-#
-# @param color A CSS3-style colour string.
-# @return An RGB-tuple.
-# @exception ValueError If the color string could not be interpreted
-# as an RGB value.
-
-def getrgb(color):
- # FIXME: add RGBA support
- try:
- rgb = colormap[color]
- except KeyError:
- try:
- # fall back on case-insensitive lookup
- rgb = colormap[string.lower(color)]
- except KeyError:
- rgb = None
- # found color in cache
- if rgb:
- if isinstance(rgb, type(())):
- return rgb
- colormap[color] = rgb = getrgb(rgb)
- return rgb
- # check for known string formats
- m = re.match("#\w\w\w$", color)
- if m:
- return (
- str2int(color[1]*2, 16),
- str2int(color[2]*2, 16),
- str2int(color[3]*2, 16)
- )
- m = re.match("#\w\w\w\w\w\w$", color)
- if m:
- return (
- str2int(color[1:3], 16),
- str2int(color[3:5], 16),
- str2int(color[5:7], 16)
- )
- m = re.match("rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color)
- if m:
- return (
- str2int(m.group(1)),
- str2int(m.group(2)),
- str2int(m.group(3))
- )
- m = re.match("rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color)
- if m:
- return (
- int((str2int(m.group(1)) * 255) / 100.0 + 0.5),
- int((str2int(m.group(2)) * 255) / 100.0 + 0.5),
- int((str2int(m.group(3)) * 255) / 100.0 + 0.5)
- )
- m = re.match("hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color)
- if m:
- from colorsys import hls_to_rgb
- rgb = hls_to_rgb(
- float(m.group(1)) / 360.0,
- float(m.group(3)) / 100.0,
- float(m.group(2)) / 100.0,
- )
- return (
- int(rgb[0] * 255 + 0.5),
- int(rgb[1] * 255 + 0.5),
- int(rgb[2] * 255 + 0.5)
- )
- raise ValueError("unknown color specifier: %r" % color)
-
-def getcolor(color, mode):
- # same as getrgb, but converts the result to the given mode
- color = getrgb(color)
- if mode == "RGB":
- return color
- if mode == "RGBA":
- r, g, b = color
- return r, g, b, 255
- if Image.getmodebase(mode) == "L":
- r, g, b = color
- return r*299/1000 + g*587/1000 + b*114/1000
- return color
-
-colormap = {
- # X11 colour table (from "CSS3 module: Color working draft"), with
- # gray/grey spelling issues fixed. This is a superset of HTML 4.0
- # colour names used in CSS 1.
- "aliceblue": "#f0f8ff",
- "antiquewhite": "#faebd7",
- "aqua": "#00ffff",
- "aquamarine": "#7fffd4",
- "azure": "#f0ffff",
- "beige": "#f5f5dc",
- "bisque": "#ffe4c4",
- "black": "#000000",
- "blanchedalmond": "#ffebcd",
- "blue": "#0000ff",
- "blueviolet": "#8a2be2",
- "brown": "#a52a2a",
- "burlywood": "#deb887",
- "cadetblue": "#5f9ea0",
- "chartreuse": "#7fff00",
- "chocolate": "#d2691e",
- "coral": "#ff7f50",
- "cornflowerblue": "#6495ed",
- "cornsilk": "#fff8dc",
- "crimson": "#dc143c",
- "cyan": "#00ffff",
- "darkblue": "#00008b",
- "darkcyan": "#008b8b",
- "darkgoldenrod": "#b8860b",
- "darkgray": "#a9a9a9",
- "darkgrey": "#a9a9a9",
- "darkgreen": "#006400",
- "darkkhaki": "#bdb76b",
- "darkmagenta": "#8b008b",
- "darkolivegreen": "#556b2f",
- "darkorange": "#ff8c00",
- "darkorchid": "#9932cc",
- "darkred": "#8b0000",
- "darksalmon": "#e9967a",
- "darkseagreen": "#8fbc8f",
- "darkslateblue": "#483d8b",
- "darkslategray": "#2f4f4f",
- "darkslategrey": "#2f4f4f",
- "darkturquoise": "#00ced1",
- "darkviolet": "#9400d3",
- "deeppink": "#ff1493",
- "deepskyblue": "#00bfff",
- "dimgray": "#696969",
- "dimgrey": "#696969",
- "dodgerblue": "#1e90ff",
- "firebrick": "#b22222",
- "floralwhite": "#fffaf0",
- "forestgreen": "#228b22",
- "fuchsia": "#ff00ff",
- "gainsboro": "#dcdcdc",
- "ghostwhite": "#f8f8ff",
- "gold": "#ffd700",
- "goldenrod": "#daa520",
- "gray": "#808080",
- "grey": "#808080",
- "green": "#008000",
- "greenyellow": "#adff2f",
- "honeydew": "#f0fff0",
- "hotpink": "#ff69b4",
- "indianred": "#cd5c5c",
- "indigo": "#4b0082",
- "ivory": "#fffff0",
- "khaki": "#f0e68c",
- "lavender": "#e6e6fa",
- "lavenderblush": "#fff0f5",
- "lawngreen": "#7cfc00",
- "lemonchiffon": "#fffacd",
- "lightblue": "#add8e6",
- "lightcoral": "#f08080",
- "lightcyan": "#e0ffff",
- "lightgoldenrodyellow": "#fafad2",
- "lightgreen": "#90ee90",
- "lightgray": "#d3d3d3",
- "lightgrey": "#d3d3d3",
- "lightpink": "#ffb6c1",
- "lightsalmon": "#ffa07a",
- "lightseagreen": "#20b2aa",
- "lightskyblue": "#87cefa",
- "lightslategray": "#778899",
- "lightslategrey": "#778899",
- "lightsteelblue": "#b0c4de",
- "lightyellow": "#ffffe0",
- "lime": "#00ff00",
- "limegreen": "#32cd32",
- "linen": "#faf0e6",
- "magenta": "#ff00ff",
- "maroon": "#800000",
- "mediumaquamarine": "#66cdaa",
- "mediumblue": "#0000cd",
- "mediumorchid": "#ba55d3",
- "mediumpurple": "#9370db",
- "mediumseagreen": "#3cb371",
- "mediumslateblue": "#7b68ee",
- "mediumspringgreen": "#00fa9a",
- "mediumturquoise": "#48d1cc",
- "mediumvioletred": "#c71585",
- "midnightblue": "#191970",
- "mintcream": "#f5fffa",
- "mistyrose": "#ffe4e1",
- "moccasin": "#ffe4b5",
- "navajowhite": "#ffdead",
- "navy": "#000080",
- "oldlace": "#fdf5e6",
- "olive": "#808000",
- "olivedrab": "#6b8e23",
- "orange": "#ffa500",
- "orangered": "#ff4500",
- "orchid": "#da70d6",
- "palegoldenrod": "#eee8aa",
- "palegreen": "#98fb98",
- "paleturquoise": "#afeeee",
- "palevioletred": "#db7093",
- "papayawhip": "#ffefd5",
- "peachpuff": "#ffdab9",
- "peru": "#cd853f",
- "pink": "#ffc0cb",
- "plum": "#dda0dd",
- "powderblue": "#b0e0e6",
- "purple": "#800080",
- "red": "#ff0000",
- "rosybrown": "#bc8f8f",
- "royalblue": "#4169e1",
- "saddlebrown": "#8b4513",
- "salmon": "#fa8072",
- "sandybrown": "#f4a460",
- "seagreen": "#2e8b57",
- "seashell": "#fff5ee",
- "sienna": "#a0522d",
- "silver": "#c0c0c0",
- "skyblue": "#87ceeb",
- "slateblue": "#6a5acd",
- "slategray": "#708090",
- "slategrey": "#708090",
- "snow": "#fffafa",
- "springgreen": "#00ff7f",
- "steelblue": "#4682b4",
- "tan": "#d2b48c",
- "teal": "#008080",
- "thistle": "#d8bfd8",
- "tomato": "#ff6347",
- "turquoise": "#40e0d0",
- "violet": "#ee82ee",
- "wheat": "#f5deb3",
- "white": "#ffffff",
- "whitesmoke": "#f5f5f5",
- "yellow": "#ffff00",
- "yellowgreen": "#9acd32",
-}
diff --git a/PIL/ImageDraw.py b/PIL/ImageDraw.py
deleted file mode 100644
index 7f9107b..0000000
--- a/PIL/ImageDraw.py
+++ /dev/null
@@ -1,378 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: ImageDraw.py 2817 2006-10-07 15:34:03Z fredrik $
-#
-# drawing interface operations
-#
-# History:
-# 1996-04-13 fl Created (experimental)
-# 1996-08-07 fl Filled polygons, ellipses.
-# 1996-08-13 fl Added text support
-# 1998-06-28 fl Handle I and F images
-# 1998-12-29 fl Added arc; use arc primitive to draw ellipses
-# 1999-01-10 fl Added shape stuff (experimental)
-# 1999-02-06 fl Added bitmap support
-# 1999-02-11 fl Changed all primitives to take options
-# 1999-02-20 fl Fixed backwards compatibility
-# 2000-10-12 fl Copy on write, when necessary
-# 2001-02-18 fl Use default ink for bitmap/text also in fill mode
-# 2002-10-24 fl Added support for CSS-style color strings
-# 2002-12-10 fl Added experimental support for RGBA-on-RGB drawing
-# 2002-12-11 fl Refactored low-level drawing API (work in progress)
-# 2004-08-26 fl Made Draw() a factory function, added getdraw() support
-# 2004-09-04 fl Added width support to line primitive
-# 2004-09-10 fl Added font mode handling
-# 2006-06-19 fl Added font bearing support (getmask2)
-#
-# Copyright (c) 1997-2006 by Secret Labs AB
-# Copyright (c) 1996-2006 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageColor
-
-try:
- import warnings
-except ImportError:
- warnings = None
-
-##
-# A simple 2D drawing interface for PIL images.
-# <p>
-# Application code should use the <b>Draw</b> factory, instead of
-# directly.
-
-class ImageDraw:
-
- ##
- # Create a drawing instance.
- #
- # @param im The image to draw in.
- # @param mode Optional mode to use for color values. For RGB
- # images, this argument can be RGB or RGBA (to blend the
- # drawing into the image). For all other modes, this argument
- # must be the same as the image mode. If omitted, the mode
- # defaults to the mode of the image.
-
- def __init__(self, im, mode=None):
- im.load()
- if im.readonly:
- im._copy() # make it writable
- blend = 0
- if mode is None:
- mode = im.mode
- if mode != im.mode:
- if mode == "RGBA" and im.mode == "RGB":
- blend = 1
- else:
- raise ValueError("mode mismatch")
- if mode == "P":
- self.palette = im.palette
- else:
- self.palette = None
- self.im = im.im
- self.draw = Image.core.draw(self.im, blend)
- self.mode = mode
- if mode in ("I", "F"):
- self.ink = self.draw.draw_ink(1, mode)
- else:
- self.ink = self.draw.draw_ink(-1, mode)
- if mode in ("1", "P", "I", "F"):
- # FIXME: fix Fill2 to properly support matte for I+F images
- self.fontmode = "1"
- else:
- self.fontmode = "L" # aliasing is okay for other modes
- self.fill = 0
- self.font = None
-
- ##
- # Set the default pen color.
-
- def setink(self, ink):
- # compatibility
- if warnings:
- warnings.warn(
- "'setink' is deprecated; use keyword arguments instead",
- DeprecationWarning, stacklevel=2
- )
- if Image.isStringType(ink):
- ink = ImageColor.getcolor(ink, self.mode)
- if self.palette and not Image.isNumberType(ink):
- ink = self.palette.getcolor(ink)
- self.ink = self.draw.draw_ink(ink, self.mode)
-
- ##
- # Set the default background color.
-
- def setfill(self, onoff):
- # compatibility
- if warnings:
- warnings.warn(
- "'setfill' is deprecated; use keyword arguments instead",
- DeprecationWarning, stacklevel=2
- )
- self.fill = onoff
-
- ##
- # Set the default font.
-
- def setfont(self, font):
- # compatibility
- self.font = font
-
- ##
- # Get the current default font.
-
- def getfont(self):
- if not self.font:
- # FIXME: should add a font repository
- import ImageFont
- self.font = ImageFont.load_default()
- return self.font
-
- def _getink(self, ink, fill=None):
- if ink is None and fill is None:
- if self.fill:
- fill = self.ink
- else:
- ink = self.ink
- else:
- if ink is not None:
- if Image.isStringType(ink):
- ink = ImageColor.getcolor(ink, self.mode)
- if self.palette and not Image.isNumberType(ink):
- ink = self.palette.getcolor(ink)
- ink = self.draw.draw_ink(ink, self.mode)
- if fill is not None:
- if Image.isStringType(fill):
- fill = ImageColor.getcolor(fill, self.mode)
- if self.palette and not Image.isNumberType(fill):
- fill = self.palette.getcolor(fill)
- fill = self.draw.draw_ink(fill, self.mode)
- return ink, fill
-
- ##
- # Draw an arc.
-
- def arc(self, xy, start, end, fill=None):
- ink, fill = self._getink(fill)
- if ink is not None:
- self.draw.draw_arc(xy, start, end, ink)
-
- ##
- # Draw a bitmap.
-
- def bitmap(self, xy, bitmap, fill=None):
- bitmap.load()
- ink, fill = self._getink(fill)
- if ink is None:
- ink = fill
- if ink is not None:
- self.draw.draw_bitmap(xy, bitmap.im, ink)
-
- ##
- # Draw a chord.
-
- def chord(self, xy, start, end, fill=None, outline=None):
- ink, fill = self._getink(outline, fill)
- if fill is not None:
- self.draw.draw_chord(xy, start, end, fill, 1)
- if ink is not None:
- self.draw.draw_chord(xy, start, end, ink, 0)
-
- ##
- # Draw an ellipse.
-
- def ellipse(self, xy, fill=None, outline=None):
- ink, fill = self._getink(outline, fill)
- if fill is not None:
- self.draw.draw_ellipse(xy, fill, 1)
- if ink is not None:
- self.draw.draw_ellipse(xy, ink, 0)
-
- ##
- # Draw a line, or a connected sequence of line segments.
-
- def line(self, xy, fill=None, width=0):
- ink, fill = self._getink(fill)
- if ink is not None:
- self.draw.draw_lines(xy, ink, width)
-
- ##
- # (Experimental) Draw a shape.
-
- def shape(self, shape, fill=None, outline=None):
- # experimental
- shape.close()
- ink, fill = self._getink(outline, fill)
- if fill is not None:
- self.draw.draw_outline(shape, fill, 1)
- if ink is not None:
- self.draw.draw_outline(shape, ink, 0)
-
- ##
- # Draw a pieslice.
-
- def pieslice(self, xy, start, end, fill=None, outline=None):
- ink, fill = self._getink(outline, fill)
- if fill is not None:
- self.draw.draw_pieslice(xy, start, end, fill, 1)
- if ink is not None:
- self.draw.draw_pieslice(xy, start, end, ink, 0)
-
- ##
- # Draw one or more individual pixels.
-
- def point(self, xy, fill=None):
- ink, fill = self._getink(fill)
- if ink is not None:
- self.draw.draw_points(xy, ink)
-
- ##
- # Draw a polygon.
-
- def polygon(self, xy, fill=None, outline=None):
- ink, fill = self._getink(outline, fill)
- if fill is not None:
- self.draw.draw_polygon(xy, fill, 1)
- if ink is not None:
- self.draw.draw_polygon(xy, ink, 0)
-
- ##
- # Draw a rectangle.
-
- def rectangle(self, xy, fill=None, outline=None):
- ink, fill = self._getink(outline, fill)
- if fill is not None:
- self.draw.draw_rectangle(xy, fill, 1)
- if ink is not None:
- self.draw.draw_rectangle(xy, ink, 0)
-
- ##
- # Draw text.
-
- def text(self, xy, text, fill=None, font=None, anchor=None):
- ink, fill = self._getink(fill)
- if font is None:
- font = self.getfont()
- if ink is None:
- ink = fill
- if ink is not None:
- try:
- mask, offset = font.getmask2(text, self.fontmode)
- xy = xy[0] + offset[0], xy[1] + offset[1]
- except AttributeError:
- try:
- mask = font.getmask(text, self.fontmode)
- except TypeError:
- mask = font.getmask(text)
- self.draw.draw_bitmap(xy, mask, ink)
-
- ##
- # Get the size of a given string, in pixels.
-
- def textsize(self, text, font=None):
- if font is None:
- font = self.getfont()
- return font.getsize(text)
-
-##
-# A simple 2D drawing interface for PIL images.
-#
-# @param im The image to draw in.
-# @param mode Optional mode to use for color values. For RGB
-# images, this argument can be RGB or RGBA (to blend the
-# drawing into the image). For all other modes, this argument
-# must be the same as the image mode. If omitted, the mode
-# defaults to the mode of the image.
-
-def Draw(im, mode=None):
- try:
- return im.getdraw(mode)
- except AttributeError:
- return ImageDraw(im, mode)
-
-# experimental access to the outline API
-try:
- Outline = Image.core.outline
-except:
- Outline = None
-
-##
-# (Experimental) A more advanced 2D drawing interface for PIL images,
-# based on the WCK interface.
-#
-# @param im The image to draw in.
-# @param hints An optional list of hints.
-# @return A (drawing context, drawing resource factory) tuple.
-
-def getdraw(im=None, hints=None):
- # FIXME: this needs more work!
- # FIXME: come up with a better 'hints' scheme.
- handler = None
- if not hints or "nicest" in hints:
- try:
- import _imagingagg
- handler = _imagingagg
- except ImportError:
- pass
- if handler is None:
- import ImageDraw2
- handler = ImageDraw2
- if im:
- im = handler.Draw(im)
- return im, handler
-
-##
-# (experimental) Fills a bounded region with a given color.
-#
-# @param image Target image.
-# @param xy Seed position (a 2-item coordinate tuple).
-# @param value Fill color.
-# @param border Optional border value. If given, the region consists of
-# pixels with a color different from the border color. If not given,
-# the region consists of pixels having the same color as the seed
-# pixel.
-
-def floodfill(image, xy, value, border=None):
- "Fill bounded region."
- # based on an implementation by Eric S. Raymond
- pixel = image.load()
- x, y = xy
- try:
- background = pixel[x, y]
- if background == value:
- return # seed point already has fill color
- pixel[x, y] = value
- except IndexError:
- return # seed point outside image
- edge = [(x, y)]
- if border is None:
- while edge:
- newedge = []
- for (x, y) in edge:
- for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)):
- try:
- p = pixel[s, t]
- except IndexError:
- pass
- else:
- if p == background:
- pixel[s, t] = value
- newedge.append((s, t))
- edge = newedge
- else:
- while edge:
- newedge = []
- for (x, y) in edge:
- for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)):
- try:
- p = pixel[s, t]
- except IndexError:
- pass
- else:
- if p != value and p != border:
- pixel[s, t] = value
- newedge.append((s, t))
- edge = newedge
diff --git a/PIL/ImageDraw2.py b/PIL/ImageDraw2.py
deleted file mode 100644
index 65c8cbb..0000000
--- a/PIL/ImageDraw2.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: ImageDraw.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# WCK-style drawing interface operations
-#
-# History:
-# 2003-12-07 fl created
-# 2005-05-15 fl updated; added to PIL as ImageDraw2
-# 2005-05-15 fl added text support
-# 2005-05-20 fl added arc/chord/pieslice support
-#
-# Copyright (c) 2003-2005 by Secret Labs AB
-# Copyright (c) 2003-2005 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageColor, ImageDraw, ImageFont, ImagePath
-
-class Pen:
- def __init__(self, color, width=1, opacity=255):
- self.color = ImageColor.getrgb(color)
- self.width = width
-
-class Brush:
- def __init__(self, color, opacity=255):
- self.color = ImageColor.getrgb(color)
-
-class Font:
- def __init__(self, color, file, size=12):
- # FIXME: add support for bitmap fonts
- self.color = ImageColor.getrgb(color)
- self.font = ImageFont.truetype(file, size)
-
-class Draw:
-
- def __init__(self, image, size=None, color=None):
- if not hasattr(image, "im"):
- image = Image.new(image, size, color)
- self.draw = ImageDraw.Draw(image)
- self.image = image
- self.transform = None
-
- def flush(self):
- return self.image
-
- def render(self, op, xy, pen, brush=None):
- # handle color arguments
- outline = fill = None; width = 1
- if isinstance(pen, Pen):
- outline = pen.color
- width = pen.width
- elif isinstance(brush, Pen):
- outline = brush.color
- width = brush.width
- if isinstance(brush, Brush):
- fill = brush.color
- elif isinstance(pen, Brush):
- fill = pen.color
- # handle transformation
- if self.transform:
- xy = ImagePath.Path(xy)
- xy.transform(self.transform)
- # render the item
- if op == "line":
- self.draw.line(xy, fill=outline, width=width)
- else:
- getattr(self.draw, op)(xy, fill=fill, outline=outline)
-
- def settransform(self, (xoffset, yoffset)):
- self.transform = (1, 0, xoffset, 0, 1, yoffset)
-
- def arc(self, xy, start, end, *options):
- self.render("arc", xy, start, end, *options)
-
- def chord(self, xy, start, end, *options):
- self.render("chord", xy, start, end, *options)
-
- def ellipse(self, xy, *options):
- self.render("ellipse", xy, *options)
-
- def pieslice(self, xy, start, end, *options):
- self.render("pieslice", xy, start, end, *options)
-
- def line(self, xy, *options):
- self.render("line", xy, *options)
-
- def rectangle(self, xy, *options):
- self.render("rectangle", xy, *options)
-
- def ellipse(self, xy, *options):
- self.render("ellipse", xy, *options)
-
- def polygon(self, xy, *options):
- self.render("polygon", xy, *options)
-
- def symbol(self, xy, symbol, *options):
- raise NotImplementedError("not in this version")
-
- def text(self, xy, text, font):
- if self.transform:
- xy = ImagePath.Path(xy)
- xy.transform(self.transform)
- self.draw.text(xy, text, font=font.font, fill=font.color)
-
- def textsize(self, text, font):
- return self.draw.textsize(text, font=font.font)
diff --git a/PIL/ImageEnhance.py b/PIL/ImageEnhance.py
deleted file mode 100644
index cddd084..0000000
--- a/PIL/ImageEnhance.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageEnhance.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# image enhancement classes
-#
-# For a background, see "Image Processing By Interpolation and
-# Extrapolation", Paul Haeberli and Douglas Voorhies. Available
-# at http://www.sgi.com/grafica/interp/index.html
-#
-# History:
-# 96-03-23 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image, ImageFilter
-
-class _Enhance:
-
- ##
- # Returns an enhanced image. The enhancement factor is a floating
- # point value controlling the enhancement. Factor 1.0 always
- # returns a copy of the original image, lower factors mean less
- # colour (brightness, contrast, etc), and higher values more.
- # There are no restrictions on this value.
- #
- # @param factor Enhancement factor.
- # @return An enhanced image.
-
- def enhance(self, factor):
- return Image.blend(self.degenerate, self.image, factor)
-
-##
-# Color enhancement object.
-# <p>
-# This class can be used to adjust the colour balance of an image, in
-# a manner similar to the controls on a colour TV set. An enhancement
-# factor of 0.0 gives a black and white image, a factor of 1.0 gives
-# the original image.
-
-class Color(_Enhance):
- "Adjust image colour balance"
- def __init__(self, image):
- self.image = image
- self.degenerate = image.convert("L").convert(image.mode)
-
-##
-# Contrast enhancement object.
-# <p>
-# This class can be used to control the contrast of an image, similar
-# to the contrast control on a TV set. An enhancement factor of 0.0
-# gives an solid grey image, factor 1.0 gives the original image.
-
-class Contrast(_Enhance):
- "Adjust image contrast"
- def __init__(self, image):
- self.image = image
- mean = reduce(lambda a,b: a+b, image.convert("L").histogram())/256.0
- self.degenerate = Image.new("L", image.size, mean).convert(image.mode)
-
-##
-# Brightness enhancement object.
-# <p>
-# This class can be used to control the brighntess of an image. An
-# enhancement factor of 0.0 gives a black image, factor 1.0 gives the
-# original image.
-
-class Brightness(_Enhance):
- "Adjust image brightness"
- def __init__(self, image):
- self.image = image
- self.degenerate = Image.new(image.mode, image.size, 0)
-
-##
-# Sharpness enhancement object.
-# <p>
-# This class can be used to adjust the sharpness of an image. The
-# enhancement factor 0.0 gives a blurred image, 1.0 gives the original
-# image, and a factor of 2.0 gives a sharpened image.
-
-class Sharpness(_Enhance):
- "Adjust image sharpness"
- def __init__(self, image):
- self.image = image
- self.degenerate = image.filter(ImageFilter.SMOOTH)
diff --git a/PIL/ImageFile.py b/PIL/ImageFile.py
deleted file mode 100644
index d51aff3..0000000
--- a/PIL/ImageFile.py
+++ /dev/null
@@ -1,520 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageFile.py 2930 2006-12-02 13:50:40Z fredrik $
-#
-# base class for image file handlers
-#
-# history:
-# 1995-09-09 fl Created
-# 1996-03-11 fl Fixed load mechanism.
-# 1996-04-15 fl Added pcx/xbm decoders.
-# 1996-04-30 fl Added encoders.
-# 1996-12-14 fl Added load helpers
-# 1997-01-11 fl Use encode_to_file where possible
-# 1997-08-27 fl Flush output in _save
-# 1998-03-05 fl Use memory mapping for some modes
-# 1999-02-04 fl Use memory mapping also for "I;16" and "I;16B"
-# 1999-05-31 fl Added image parser
-# 2000-10-12 fl Set readonly flag on memory-mapped images
-# 2002-03-20 fl Use better messages for common decoder errors
-# 2003-04-21 fl Fall back on mmap/map_buffer if map is not available
-# 2003-10-30 fl Added StubImageFile class
-# 2004-02-25 fl Made incremental parser more robust
-#
-# 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.
-#
-
-import Image
-import traceback, sys, string, os
-
-MAXBLOCK = 65536
-
-SAFEBLOCK = 1024*1024
-
-ERRORS = {
- -1: "image buffer overrun error",
- -2: "decoding error",
- -3: "unknown error",
- -8: "bad configuration",
- -9: "out of memory error"
-}
-
-#
-# --------------------------------------------------------------------
-# Helpers
-
-def _tilesort(t1, t2):
- # sort on offset
- return cmp(t1[2], t2[2])
-
-#
-# --------------------------------------------------------------------
-# ImageFile base class
-
-##
-# Base class for image file handlers.
-
-class ImageFile(Image.Image):
- "Base class for image file format handlers."
-
- def __init__(self, fp=None, filename=None):
- Image.Image.__init__(self)
-
- self.tile = None
- self.readonly = 1 # until we know better
-
- self.decoderconfig = ()
- self.decodermaxblock = MAXBLOCK
-
- if Image.isStringType(fp):
- # filename
- self.fp = open(fp, "rb")
- self.filename = fp
- else:
- # stream
- self.fp = fp
- self.filename = filename
-
- try:
- self._open()
- except IndexError, v: # end of data
- if Image.DEBUG > 1:
- traceback.print_exc()
- raise SyntaxError, v
- except TypeError, v: # end of data (ord)
- if Image.DEBUG > 1:
- traceback.print_exc()
- raise SyntaxError, v
- except KeyError, v: # unsupported mode
- if Image.DEBUG > 1:
- traceback.print_exc()
- raise SyntaxError, v
- except EOFError, v: # got header but not the first frame
- if Image.DEBUG > 1:
- traceback.print_exc()
- raise SyntaxError, v
-
- if not self.mode or self.size[0] <= 0:
- raise SyntaxError, "not identified by this driver"
-
- def draft(self, mode, size):
- "Set draft mode"
-
- pass
-
- def verify(self):
- "Check file integrity"
-
- # raise exception if something's wrong. must be called
- # directly after open, and closes file when finished.
- self.fp = None
-
- def load(self):
- "Load image data based on tile list"
-
- pixel = Image.Image.load(self)
-
- if self.tile is None:
- raise IOError("cannot load this image")
- if not self.tile:
- return pixel
-
- self.map = None
-
- readonly = 0
-
- if self.filename and len(self.tile) == 1:
- # try memory mapping
- d, e, o, a = self.tile[0]
- if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES:
- try:
- if hasattr(Image.core, "map"):
- # use built-in mapper
- self.map = Image.core.map(self.filename)
- self.map.seek(o)
- self.im = self.map.readimage(
- self.mode, self.size, a[1], a[2]
- )
- else:
- # use mmap, if possible
- import mmap
- file = open(self.filename, "r+")
- size = os.path.getsize(self.filename)
- # FIXME: on Unix, use PROT_READ etc
- self.map = mmap.mmap(file.fileno(), size)
- self.im = Image.core.map_buffer(
- self.map, self.size, d, e, o, a
- )
- readonly = 1
- except (AttributeError, EnvironmentError, ImportError):
- self.map = None
-
- self.load_prepare()
-
- # look for read/seek overrides
- try:
- read = self.load_read
- except AttributeError:
- read = self.fp.read
-
- try:
- seek = self.load_seek
- except AttributeError:
- seek = self.fp.seek
-
- if not self.map:
-
- # sort tiles in file order
- self.tile.sort(_tilesort)
-
- try:
- # FIXME: This is a hack to handle TIFF's JpegTables tag.
- prefix = self.tile_prefix
- except AttributeError:
- prefix = ""
-
- for d, e, o, a in self.tile:
- d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
- seek(o)
- try:
- d.setimage(self.im, e)
- except ValueError:
- continue
- b = prefix
- t = len(b)
- while 1:
- s = read(self.decodermaxblock)
- if not s:
- self.tile = []
- raise IOError("image file is truncated (%d bytes not processed)" % len(b))
- b = b + s
- n, e = d.decode(b)
- if n < 0:
- break
- b = b[n:]
- t = t + n
-
- self.tile = []
- self.readonly = readonly
-
- self.fp = None # might be shared
-
- if not self.map and e < 0:
- error = ERRORS.get(e, "decoder error %d" % e)
- raise IOError(error + " when reading image file")
-
- # post processing
- if hasattr(self, "tile_post_rotate"):
- # FIXME: This is a hack to handle rotated PCD's
- self.im = self.im.rotate(self.tile_post_rotate)
- self.size = self.im.size
-
- self.load_end()
-
- return Image.Image.load(self)
-
- def load_prepare(self):
- # create image memory if necessary
- if not self.im or\
- self.im.mode != self.mode or self.im.size != self.size:
- self.im = Image.core.new(self.mode, self.size)
- # create palette (optional)
- if self.mode == "P":
- Image.Image.load(self)
-
- def load_end(self):
- # may be overridden
- pass
-
- # may be defined for contained formats
- # def load_seek(self, pos):
- # pass
-
- # may be defined for blocked formats (e.g. PNG)
- # def load_read(self, bytes):
- # pass
-
-##
-# Base class for stub image loaders.
-# <p>
-# A stub loader is an image loader that can identify files of a
-# certain format, but relies on external code to load the file.
-
-class StubImageFile(ImageFile):
- "Base class for stub image loaders."
-
- def _open(self):
- raise NotImplementedError(
- "StubImageFile subclass must implement _open"
- )
-
- def load(self):
- loader = self._load()
- if loader is None:
- raise IOError("cannot find loader for this %s file" % self.format)
- image = loader.load(self)
- assert image is not None
- # become the other object (!)
- self.__class__ = image.__class__
- self.__dict__ = image.__dict__
-
- ##
- # (Hook) Find actual image loader.
-
- def _load(self):
- raise NotImplementedError(
- "StubImageFile subclass must implement _load"
- )
-
-##
-# (Internal) Support class for the <b>Parser</b> file.
-
-class _ParserFile:
- # parser support class.
-
- def __init__(self, data):
- self.data = data
- self.offset = 0
-
- def close(self):
- self.data = self.offset = None
-
- def tell(self):
- return self.offset
-
- def seek(self, offset, whence=0):
- if whence == 0:
- self.offset = offset
- elif whence == 1:
- self.offset = self.offset + offset
- else:
- # force error in Image.open
- raise IOError("illegal argument to seek")
-
- def read(self, bytes=0):
- pos = self.offset
- if bytes:
- data = self.data[pos:pos+bytes]
- else:
- data = self.data[pos:]
- self.offset = pos + len(data)
- return data
-
- def readline(self):
- # FIXME: this is slow!
- s = ""
- while 1:
- c = self.read(1)
- if not c:
- break
- s = s + c
- if c == "\n":
- break
- return s
-
-##
-# Incremental image parser. This class implements the standard
-# feed/close consumer interface.
-
-class Parser:
-
- incremental = None
- image = None
- data = None
- decoder = None
- finished = 0
-
- ##
- # (Consumer) Reset the parser. Note that you can only call this
- # method immediately after you've created a parser; parser
- # instances cannot be reused.
-
- def reset(self):
- assert self.data is None, "cannot reuse parsers"
-
- ##
- # (Consumer) Feed data to the parser.
- #
- # @param data A string buffer.
- # @exception IOError If the parser failed to parse the image file.
-
- def feed(self, data):
- # collect data
-
- if self.finished:
- return
-
- if self.data is None:
- self.data = data
- else:
- self.data = self.data + data
-
- # parse what we have
- if self.decoder:
-
- if self.offset > 0:
- # skip header
- skip = min(len(self.data), self.offset)
- self.data = self.data[skip:]
- self.offset = self.offset - skip
- if self.offset > 0 or not self.data:
- return
-
- n, e = self.decoder.decode(self.data)
-
- if n < 0:
- # end of stream
- self.data = None
- self.finished = 1
- if e < 0:
- # decoding error
- self.image = None
- error = ERRORS.get(e, "decoder error %d" % e)
- raise IOError(error + " when reading image file")
- else:
- # end of image
- return
- self.data = self.data[n:]
-
- elif self.image:
-
- # if we end up here with no decoder, this file cannot
- # be incrementally parsed. wait until we've gotten all
- # available data
- pass
-
- else:
-
- # attempt to open this file
- try:
- try:
- fp = _ParserFile(self.data)
- im = Image.open(fp)
- finally:
- fp.close() # explicitly close the virtual file
- except IOError:
- pass # not enough data
- else:
- flag = hasattr(im, "load_seek") or hasattr(im, "load_read")
- if flag or len(im.tile) != 1:
- # custom load code, or multiple tiles
- self.decode = None
- else:
- # initialize decoder
- im.load_prepare()
- d, e, o, a = im.tile[0]
- im.tile = []
- self.decoder = Image._getdecoder(
- im.mode, d, a, im.decoderconfig
- )
- self.decoder.setimage(im.im, e)
-
- # calculate decoder offset
- self.offset = o
- if self.offset <= len(self.data):
- self.data = self.data[self.offset:]
- self.offset = 0
-
- self.image = im
-
- ##
- # (Consumer) Close the stream.
- #
- # @return An image object.
- # @exception IOError If the parser failed to parse the image file.
-
- def close(self):
- # finish decoding
- if self.decoder:
- # get rid of what's left in the buffers
- self.feed("")
- self.data = self.decoder = None
- if not self.finished:
- raise IOError("image was incomplete")
- if not self.image:
- raise IOError("cannot parse this image")
- if self.data:
- # incremental parsing not possible; reopen the file
- # not that we have all data
- try:
- fp = _ParserFile(self.data)
- self.image = Image.open(fp)
- finally:
- fp.close() # explicitly close the virtual file
- return self.image
-
-# --------------------------------------------------------------------
-
-##
-# (Helper) Save image body to file.
-#
-# @param im Image object.
-# @param fp File object.
-# @param tile Tile list.
-
-def _save(im, fp, tile):
- "Helper to save image based on tile list"
-
- im.load()
- if not hasattr(im, "encoderconfig"):
- im.encoderconfig = ()
- tile.sort(_tilesort)
- # FIXME: make MAXBLOCK a configuration parameter
- bufsize = max(MAXBLOCK, im.size[0] * 4) # see RawEncode.c
- try:
- fh = fp.fileno()
- fp.flush()
- except AttributeError:
- # compress to Python file-compatible object
- for e, b, o, a in tile:
- e = Image._getencoder(im.mode, e, a, im.encoderconfig)
- if o > 0:
- fp.seek(o, 0)
- e.setimage(im.im, b)
- while 1:
- l, s, d = e.encode(bufsize)
- fp.write(d)
- if s:
- break
- if s < 0:
- raise IOError("encoder error %d when writing image file" % s)
- else:
- # slight speedup: compress to real file object
- for e, b, o, a in tile:
- e = Image._getencoder(im.mode, e, a, im.encoderconfig)
- if o > 0:
- fp.seek(o, 0)
- e.setimage(im.im, b)
- s = e.encode_to_file(fh, bufsize)
- if s < 0:
- raise IOError("encoder error %d when writing image file" % s)
- try:
- fp.flush()
- except: pass
-
-
-##
-# Reads large blocks in a safe way. Unlike fp.read(n), this function
-# doesn't trust the user. If the requested size is larger than
-# SAFEBLOCK, the file is read block by block.
-#
-# @param fp File handle. Must implement a <b>read</b> method.
-# @param size Number of bytes to read.
-# @return A string containing up to <i>size</i> bytes of data.
-
-def _safe_read(fp, size):
- if size <= 0:
- return ""
- if size <= SAFEBLOCK:
- return fp.read(size)
- data = []
- while size > 0:
- block = fp.read(min(size, SAFEBLOCK))
- if not block:
- break
- data.append(block)
- size = size - len(block)
- return string.join(data, "")
diff --git a/PIL/ImageFileIO.py b/PIL/ImageFileIO.py
deleted file mode 100644
index 7c6a5c1..0000000
--- a/PIL/ImageFileIO.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageFileIO.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# kludge to get basic ImageFileIO functionality
-#
-# History:
-# 1998-08-06 fl Recreated
-#
-# Copyright (c) Secret Labs AB 1998-2002.
-#
-# See the README file for information on usage and redistribution.
-#
-
-from StringIO import StringIO
-
-##
-# The <b>ImageFileIO</b> module can be used to read an image from a
-# socket, or any other stream device.
-# <p>
-# This module is deprecated. New code should use the <b>Parser</b>
-# class in the <a href="imagefile">ImageFile</a> module instead.
-#
-# @see ImageFile#Parser
-
-class ImageFileIO(StringIO):
-
- ##
- # Adds buffering to a stream file object, in order to
- # provide <b>seek</b> and <b>tell</b> methods required
- # by the <b>Image.open</b> method. The stream object must
- # implement <b>read</b> and <b>close</b> methods.
- #
- # @param fp Stream file handle.
- # @see Image#open
-
- def __init__(self, fp):
- data = fp.read()
- StringIO.__init__(self, data)
-
-if __name__ == "__main__":
-
- import Image
- fp = open("/images/clenna.im", "rb")
- im = Image.open(ImageFileIO(fp))
- im.load() # make sure we can read the raster data
- print im.mode, im.size
diff --git a/PIL/ImageFilter.py b/PIL/ImageFilter.py
deleted file mode 100644
index 5857686..0000000
--- a/PIL/ImageFilter.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageFilter.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# standard filters
-#
-# History:
-# 1995-11-27 fl Created
-# 2002-06-08 fl Added rank and mode filters
-# 2003-09-15 fl Fixed rank calculation in rank filter; added expand call
-#
-# Copyright (c) 1997-2003 by Secret Labs AB.
-# Copyright (c) 1995-2002 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-class Filter:
- pass
-
-##
-# Convolution filter kernel.
-
-class Kernel(Filter):
-
- ##
- # Create a convolution kernel. The current version only
- # supports 3x3 and 5x5 integer and floating point kernels.
- # <p>
- # In the current version, kernels can only be applied to
- # "L" and "RGB" images.
- #
- # @def __init__(size, kernel, **options)
- # @param size Kernel size, given as (width, height). In
- # the current version, this must be (3,3) or (5,5).
- # @param kernel A sequence containing kernel weights.
- # @param **options Optional keyword arguments.
- # @keyparam scale Scale factor. If given, the result for each
- # pixel is divided by this value. The default is the sum
- # of the kernel weights.
- # @keyparam offset Offset. If given, this value is added to the
- # result, after it has been divided by the scale factor.
-
- def __init__(self, size, kernel, scale=None, offset=0):
- if scale is None:
- # default scale is sum of kernel
- scale = reduce(lambda a,b: a+b, kernel)
- if size[0] * size[1] != len(kernel):
- raise ValueError("not enough coefficients in kernel")
- self.filterargs = size, scale, offset, kernel
-
- def filter(self, image):
- if image.mode == "P":
- raise ValueError("cannot filter palette images")
- return apply(image.filter, self.filterargs)
-
-class BuiltinFilter(Kernel):
- def __init__(self):
- pass
-
-##
-# Rank filter.
-
-class RankFilter(Filter):
- name = "Rank"
-
- ##
- # Create a rank filter. The rank filter sorts all pixels in
- # a window of the given size, and returns the rank'th value.
- #
- # @param size The kernel size, in pixels.
- # @param rank What pixel value to pick. Use 0 for a min filter,
- # size*size/2 for a median filter, size*size-1 for a max filter,
- # etc.
-
- def __init__(self, size, rank):
- self.size = size
- self.rank = rank
-
- def filter(self, image):
- image = image.expand(self.size/2, self.size/2)
- return image.rankfilter(self.size, self.rank)
-
-##
-# Median filter. Picks the median pixel value in a window with the
-# given size.
-
-class MedianFilter(RankFilter):
- name = "Median"
-
- ##
- # Create a median filter.
- #
- # @param size The kernel size, in pixels.
-
- def __init__(self, size=3):
- self.size = size
- self.rank = size*size/2
-
-##
-# Min filter. Picks the lowest pixel value in a window with the given
-# size.
-
-class MinFilter(RankFilter):
- name = "Min"
-
- ##
- # Create a min filter.
- #
- # @param size The kernel size, in pixels.
-
- def __init__(self, size=3):
- self.size = size
- self.rank = 0
-
-##
-# Max filter. Picks the largest pixel value in a window with the
-# given size.
-
-class MaxFilter(RankFilter):
- name = "Max"
-
- ##
- # Create a max filter.
- #
- # @param size The kernel size, in pixels.
-
- def __init__(self, size=3):
- self.size = size
- self.rank = size*size-1
-
-##
-# Mode filter. Picks the most frequent pixel value in a box with the
-# given size. Pixel values that occur only once or twice are ignored;
-# if no pixel value occurs more than twice, the original pixel value
-# is preserved.
-
-class ModeFilter(Filter):
- name = "Mode"
-
- ##
- # Create a mode filter.
- #
- # @param size The kernel size, in pixels.
-
- def __init__(self, size=3):
- self.size = size
- def filter(self, image):
- return image.modefilter(self.size)
-
-##
-# Blur filter.
-
-class BLUR(BuiltinFilter):
- name = "Blur"
- filterargs = (5, 5), 16, 0, (
- 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 1,
- 1, 0, 0, 0, 1,
- 1, 0, 0, 0, 1,
- 1, 1, 1, 1, 1
- )
-
-##
-# Contour filter.
-
-class CONTOUR(BuiltinFilter):
- name = "Contour"
- filterargs = (3, 3), 1, 255, (
- -1, -1, -1,
- -1, 8, -1,
- -1, -1, -1
- )
-
-##
-# Detail filter.
-
-class DETAIL(BuiltinFilter):
- name = "Detail"
- filterargs = (3, 3), 6, 0, (
- 0, -1, 0,
- -1, 10, -1,
- 0, -1, 0
- )
-
-##
-# Edge enhancement filter.
-
-class EDGE_ENHANCE(BuiltinFilter):
- name = "Edge-enhance"
- filterargs = (3, 3), 2, 0, (
- -1, -1, -1,
- -1, 10, -1,
- -1, -1, -1
- )
-
-##
-# Stronger edge enhancement filter.
-
-class EDGE_ENHANCE_MORE(BuiltinFilter):
- name = "Edge-enhance More"
- filterargs = (3, 3), 1, 0, (
- -1, -1, -1,
- -1, 9, -1,
- -1, -1, -1
- )
-
-##
-# Embossing filter.
-
-class EMBOSS(BuiltinFilter):
- name = "Emboss"
- filterargs = (3, 3), 1, 128, (
- -1, 0, 0,
- 0, 1, 0,
- 0, 0, 0
- )
-
-##
-# Edge-finding filter.
-
-class FIND_EDGES(BuiltinFilter):
- name = "Find Edges"
- filterargs = (3, 3), 1, 0, (
- -1, -1, -1,
- -1, 8, -1,
- -1, -1, -1
- )
-
-##
-# Smoothing filter.
-
-class SMOOTH(BuiltinFilter):
- name = "Smooth"
- filterargs = (3, 3), 13, 0, (
- 1, 1, 1,
- 1, 5, 1,
- 1, 1, 1
- )
-
-##
-# Stronger smoothing filter.
-
-class SMOOTH_MORE(BuiltinFilter):
- name = "Smooth More"
- filterargs = (5, 5), 100, 0, (
- 1, 1, 1, 1, 1,
- 1, 5, 5, 5, 1,
- 1, 5, 44, 5, 1,
- 1, 5, 5, 5, 1,
- 1, 1, 1, 1, 1
- )
-
-##
-# Sharpening filter.
-
-class SHARPEN(BuiltinFilter):
- name = "Sharpen"
- filterargs = (3, 3), 16, 0, (
- -2, -2, -2,
- -2, 32, -2,
- -2, -2, -2
- )
diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py
deleted file mode 100644
index b987a33..0000000
--- a/PIL/ImageFont.py
+++ /dev/null
@@ -1,377 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageFont.py 2813 2006-10-07 10:11:35Z fredrik $
-#
-# PIL raster font management
-#
-# History:
-# 1996-08-07 fl created (experimental)
-# 1997-08-25 fl minor adjustments to handle fonts from pilfont 0.3
-# 1999-02-06 fl rewrote most font management stuff in C
-# 1999-03-17 fl take pth files into account in load_path (from Richard Jones)
-# 2001-02-17 fl added freetype support
-# 2001-05-09 fl added TransposedFont wrapper class
-# 2002-03-04 fl make sure we have a "L" or "1" font
-# 2002-12-04 fl skip non-directory entries in the system path
-# 2003-04-29 fl add embedded default font
-# 2003-09-27 fl added support for truetype charmap encodings
-#
-# Todo:
-# Adapt to PILFONT2 format (16-bit fonts, compressed, single file)
-#
-# Copyright (c) 1997-2003 by Secret Labs AB
-# Copyright (c) 1996-2003 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import os, string, sys
-
-# FIXME: add support for pilfont2 format (see FontFile.py)
-
-# --------------------------------------------------------------------
-# Font metrics format:
-# "PILfont" LF
-# fontdescriptor LF
-# (optional) key=value... LF
-# "DATA" LF
-# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
-#
-# To place a character, cut out srcbox and paste at dstbox,
-# relative to the character position. Then move the character
-# position according to dx, dy.
-# --------------------------------------------------------------------
-
-##
-# The <b>ImageFont</b> module defines a class with the same name.
-# Instances of this class store bitmap fonts, and are used with the
-# <b>text</b> method of the <b>ImageDraw</b> class.
-# <p>
-# PIL uses it's own font file format to store bitmap fonts. You can
-# use the <b>pilfont</b> utility to convert BDF and PCF font
-# descriptors (X window font formats) to this format.
-# <p>
-# Starting with version 1.1.4, PIL can be configured to support
-# TrueType and OpenType fonts. For earlier version, TrueType
-# support is only available as part of the imToolkit package
-#
-# @see ImageDraw#ImageDraw.text
-# @see pilfont
-
-class ImageFont:
- "PIL font wrapper"
-
- def _load_pilfont(self, filename):
-
- file = open(filename, "rb")
-
- for ext in (".png", ".gif", ".pbm"):
- try:
- fullname = os.path.splitext(filename)[0] + ext
- image = Image.open(fullname)
- except:
- pass
- else:
- if image and image.mode in ("1", "L"):
- break
- else:
- raise IOError("cannot find glyph data file")
-
- self.file = fullname
-
- return self._load_pilfont_data(file, image)
-
- def _load_pilfont_data(self, file, image):
-
- # read PILfont header
- if file.readline() != "PILfont\n":
- raise SyntaxError("Not a PILfont file")
- d = string.split(file.readline(), ";")
- self.info = [] # FIXME: should be a dictionary
- s = file.readline()
- while s and s != "DATA\n":
- self.info.append(s)
-
- # read PILfont metrics
- data = file.read(256*20)
-
- # check image
- if image.mode not in ("1", "L"):
- raise TypeError("invalid font image mode")
-
- image.load()
-
- self.font = Image.core.font(image.im, data)
-
- # delegate critical operations to internal type
- self.getsize = self.font.getsize
- self.getmask = self.font.getmask
-
-##
-# Wrapper for FreeType fonts. Application code should use the
-# <b>truetype</b> factory function to create font objects.
-
-class FreeTypeFont:
- "FreeType font wrapper (requires _imagingft service)"
-
- def __init__(self, file, size, index=0, encoding=""):
- # FIXME: use service provider instead
- import _imagingft
- self.font = _imagingft.getfont(file, size, index, encoding)
-
- def getname(self):
- return self.font.family, self.font.style
-
- def getmetrics(self):
- return self.font.ascent, self.font.descent
-
- def getsize(self, text):
- return self.font.getsize(text)[0]
-
- def getmask(self, text, mode=""):
- return self.getmask2(text, mode)[0]
-
- def getmask2(self, text, mode="", fill=Image.core.fill):
- size, offset = self.font.getsize(text)
- im = fill("L", size, 0)
- self.font.render(text, im.id, mode=="1")
- return im, offset
-
-##
-# Wrapper that creates a transposed font from any existing font
-# object.
-#
-# @param font A font object.
-# @param orientation An optional orientation. If given, this should
-# be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM,
-# Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270.
-
-class TransposedFont:
- "Wrapper for writing rotated or mirrored text"
-
- def __init__(self, font, orientation=None):
- self.font = font
- self.orientation = orientation # any 'transpose' argument, or None
-
- def getsize(self, text):
- w, h = self.font.getsize(text)
- if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
- return h, w
- return w, h
-
- def getmask(self, text, mode=""):
- im = self.font.getmask(text, mode)
- if self.orientation is not None:
- return im.transpose(self.orientation)
- return im
-
-##
-# Load font file. This function loads a font object from the given
-# bitmap font file, and returns the corresponding font object.
-#
-# @param filename Name of font file.
-# @return A font object.
-# @exception IOError If the file could not be read.
-
-def load(filename):
- "Load a font file."
- f = ImageFont()
- f._load_pilfont(filename)
- return f
-
-##
-# Load a TrueType or OpenType font file, and create a font object.
-# This function loads a font object from the given file, and creates
-# a font object for a font of the given size.
-# <p>
-# This function requires the _imagingft service.
-#
-# @param filename A truetype font file. Under Windows, if the file
-# is not found in this filename, the loader also looks in Windows
-# <b>fonts</b> directory
-# @param size The requested size, in points.
-# @param index Which font face to load (default is first available face).
-# @param encoding Which font encoding to use (default is Unicode). Common
-# encodings are "unic" (Unicode), "symb" (Microsoft Symbol), "ADOB"
-# (Adobe Standard), "ADBE" (Adobe Expert), and "armn" (Apple Roman).
-# See the FreeType documentation for more information.
-# @return A font object.
-# @exception IOError If the file could not be read.
-
-def truetype(filename, size, index=0, encoding=""):
- "Load a truetype font file."
- try:
- return FreeTypeFont(filename, size, index, encoding)
- except IOError:
- if sys.platform == "win32":
- # check the windows font repository
- # NOTE: must use uppercase WINDIR, to work around bugs in
- # 1.5.2's os.environ.get()
- windir = os.environ.get("WINDIR")
- if windir:
- filename = os.path.join(windir, "fonts", filename)
- return FreeTypeFont(filename, size, index, encoding)
- raise
-
-##
-# Load font file. Same as load, but searches for a bitmap font along
-# the Python path.
-#
-# @param filename Name of font file.
-# @return A font object.
-# @exception IOError If the file could not be read.
-# @see #load
-
-def load_path(filename):
- "Load a font file, searching along the Python path."
- for dir in sys.path:
- if Image.isDirectory(dir):
- try:
- return load(os.path.join(dir, filename))
- except IOError:
- pass
- raise IOError("cannot find font file")
-
-##
-# Load a (probably rather ugly) default font.
-#
-# @return A font object.
-
-def load_default():
- "Load a default font."
- from StringIO import StringIO
- import base64
- f = ImageFont()
- f._load_pilfont_data(
- # courB08
- StringIO(base64.decodestring('''
-UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA
-BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL
-AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA
-AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB
-ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A
-BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB
-//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA
-AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH
-AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA
-ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv
-AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/
-/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5
-AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA
-AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG
-AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA
-BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA
-AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA
-2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF
-AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA////
-+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA
-////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA
-BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv
-AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA
-AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA
-AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA
-BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP//
-//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA
-AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF
-AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB
-mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn
-AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA
-AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7
-AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA
-Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB
-//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA
-AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ
-AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC
-DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ
-AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/
-+wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5
-AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/
-///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG
-AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA
-BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA
-Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC
-eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG
-AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA////
-+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA
-////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA
-BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT
-AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A
-AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA
-Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA
-Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP//
-//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA
-AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ
-AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA
-LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5
-AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA
-AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5
-AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA
-AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG
-AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA
-EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK
-AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
-pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
-AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
-+QAGAAIAzgAKANUAEw==
-''')), Image.open(StringIO(base64.decodestring('''
-iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
-Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
-M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
-LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
-IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
-Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
-NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
-in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
-SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
-AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
-y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
-ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
-lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
-/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
-AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
-c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
-/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
-pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
-oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
-evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
-AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
-Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
-w7IkEbzhVQAAAABJRU5ErkJggg==
-'''))))
- return f
-
-if __name__ == "__main__":
- # create font data chunk for embedding
- import base64, os, sys
- font = "../Images/courB08"
- print " f._load_pilfont_data("
- print " # %s" % os.path.basename(font)
- print " StringIO(base64.decodestring('''"
- base64.encode(open(font + ".pil", "rb"), sys.stdout)
- print "''')), Image.open(StringIO(base64.decodestring('''"
- base64.encode(open(font + ".pbm", "rb"), sys.stdout)
- print "'''))))"
diff --git a/PIL/ImageGL.py b/PIL/ImageGL.py
deleted file mode 100644
index 482f42d..0000000
--- a/PIL/ImageGL.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageGL.py 2438 2005-05-25 21:09:48Z Fredrik $
-#
-# OpenGL pixmap/texture interface (requires imToolkit OpenGL extensions)
-#
-# History:
-# 2003-09-13 fl Added
-#
-# Copyright (c) Secret Labs AB 2003.
-#
-# See the README file for information on usage and redistribution.
-#
-
-##
-# OpenGL pixmap/texture interface (requires imToolkit OpenGL
-# extensions.)
-##
-
-import _imaginggl
-
-##
-# Texture factory.
-
-class TextureFactory:
- pass # overwritten by the _imaginggl module
-
-from _imaginggl import *
diff --git a/PIL/ImageGrab.py b/PIL/ImageGrab.py
deleted file mode 100644
index ecbfbac..0000000
--- a/PIL/ImageGrab.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: ImageGrab.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# screen grabber (windows only)
-#
-# History:
-# 2001-04-26 fl created
-# 2001-09-17 fl use builtin driver, if present
-# 2002-11-19 fl added grabclipboard support
-#
-# Copyright (c) 2001-2002 by Secret Labs AB
-# Copyright (c) 2001-2002 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-
-##
-# (New in 1.1.3) The <b>ImageGrab</b> module can be used to copy
-# the contents of the screen to a PIL image memory.
-# <p>
-# The current version works on Windows only.</p>
-#
-# @since 1.1.3
-##
-
-try:
- # built-in driver (1.1.3 and later)
- grabber = Image.core.grabscreen
-except AttributeError:
- # stand-alone driver (pil plus)
- import _grabscreen
- grabber = _grabscreen.grab
-
-##
-# (New in 1.1.3) Take a snapshot of the screen. The pixels inside the
-# bounding box are returned as an "RGB" image. If the bounding box is
-# omitted, the entire screen is copied.
-#
-# @param bbox What region to copy. Default is the entire screen.
-# @return An image
-# @since 1.1.3
-
-def grab(bbox=None):
- size, data = grabber()
- im = Image.fromstring(
- "RGB", size, data,
- # RGB, 32-bit line padding, origo in lower left corner
- "raw", "BGR", (size[0]*3 + 3) & -4, -1
- )
- if bbox:
- im = im.crop(bbox)
- return im
-
-##
-# (New in 1.1.4) Take a snapshot of the clipboard image, if any.
-#
-# @return An image, a list of filenames, or None if the clipboard does
-# not contain image data or filenames. Note that if a list is
-# returned, the filenames may not represent image files.
-# @since 1.1.4
-
-def grabclipboard():
- debug = 0 # temporary interface
- data = Image.core.grabclipboard(debug)
- if Image.isStringType(data):
- import BmpImagePlugin, StringIO
- return BmpImagePlugin.DibImageFile(StringIO.StringIO(data))
- return data
diff --git a/PIL/ImageMath.py b/PIL/ImageMath.py
deleted file mode 100644
index 117a5ae..0000000
--- a/PIL/ImageMath.py
+++ /dev/null
@@ -1,207 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: ImageMath.py 2508 2005-09-12 19:01:03Z fredrik $
-#
-# a simple math add-on for the Python Imaging Library
-#
-# History:
-# 1999-02-15 fl Original PIL Plus release
-# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6
-# 2005-09-12 fl Fixed int() and float() for Python 2.4.1
-#
-# Copyright (c) 1999-2005 by Secret Labs AB
-# Copyright (c) 2005 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import _imagingmath
-
-VERBOSE = 0
-
-def _isconstant(v):
- return isinstance(v, type(0)) or isinstance(v, type(0.0))
-
-class _Operand:
- # wraps an image operand, providing standard operators
-
- def __init__(self, im):
- self.im = im
-
- def __fixup(self, im1):
- # convert image to suitable mode
- if isinstance(im1, _Operand):
- # argument was an image.
- if im1.im.mode in ("1", "L"):
- return im1.im.convert("I")
- elif im1.im.mode in ("I", "F"):
- return im1.im
- else:
- raise ValueError, "unsupported mode: %s" % im1.im.mode
- else:
- # argument was a constant
- if _isconstant(im1) and self.im.mode in ("1", "L", "I"):
- return Image.new("I", self.im.size, im1)
- else:
- return Image.new("F", self.im.size, im1)
-
- def apply(self, op, im1, im2=None, mode=None):
- im1 = self.__fixup(im1)
- if im2 is None:
- # unary operation
- out = Image.new(mode or im1.mode, im1.size, None)
- im1.load()
- try:
- op = getattr(_imagingmath, op+"_"+im1.mode)
- except AttributeError:
- raise TypeError, "bad operand type for '%s'" % op
- _imagingmath.unop(op, out.im.id, im1.im.id)
- else:
- # binary operation
- im2 = self.__fixup(im2)
- if im1.mode != im2.mode:
- # convert both arguments to floating point
- if im1.mode != "F": im1 = im1.convert("F")
- if im2.mode != "F": im2 = im2.convert("F")
- if im1.mode != im2.mode:
- raise ValueError, "mode mismatch"
- if im1.size != im2.size:
- # crop both arguments to a common size
- size = (min(im1.size[0], im2.size[0]),
- min(im1.size[1], im2.size[1]))
- if im1.size != size: im1 = im1.crop((0, 0) + size)
- if im2.size != size: im2 = im2.crop((0, 0) + size)
- out = Image.new(mode or im1.mode, size, None)
- else:
- out = Image.new(mode or im1.mode, im1.size, None)
- im1.load(); im2.load()
- try:
- op = getattr(_imagingmath, op+"_"+im1.mode)
- except AttributeError:
- raise TypeError, "bad operand type for '%s'" % op
- _imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id)
- return _Operand(out)
-
- # unary operators
- def __nonzero__(self):
- # an image is "true" if it contains at least one non-zero pixel
- return self.im.getbbox() is not None
- def __abs__(self):
- return self.apply("abs", self)
- def __pos__(self):
- return self
- def __neg__(self):
- return self.apply("neg", self)
-
- # binary operators
- def __add__(self, other):
- return self.apply("add", self, other)
- def __radd__(self, other):
- return self.apply("add", other, self)
- def __sub__(self, other):
- return self.apply("sub", self, other)
- def __rsub__(self, other):
- return self.apply("sub", other, self)
- def __mul__(self, other):
- return self.apply("mul", self, other)
- def __rmul__(self, other):
- return self.apply("mul", other, self)
- def __div__(self, other):
- return self.apply("div", self, other)
- def __rdiv__(self, other):
- return self.apply("div", other, self)
- def __mod__(self, other):
- return self.apply("mod", self, other)
- def __rmod__(self, other):
- return self.apply("mod", other, self)
- def __pow__(self, other):
- return self.apply("pow", self, other)
- def __rpow__(self, other):
- return self.apply("pow", other, self)
-
- # bitwise
- def __invert__(self):
- return self.apply("invert", self)
- def __and__(self, other):
- return self.apply("and", self, other)
- def __rand__(self, other):
- return self.apply("and", other, self)
- def __or__(self, other):
- return self.apply("or", self, other)
- def __ror__(self, other):
- return self.apply("or", other, self)
- def __xor__(self, other):
- return self.apply("xor", self, other)
- def __rxor__(self, other):
- return self.apply("xor", other, self)
- def __lshift__(self, other):
- return self.apply("lshift", self, other)
- def __rshift__(self, other):
- return self.apply("rshift", self, other)
-
- # logical
- def __eq__(self, other):
- return self.apply("eq", self, other)
- def __ne__(self, other):
- return self.apply("ne", self, other)
- def __lt__(self, other):
- return self.apply("lt", self, other)
- def __le__(self, other):
- return self.apply("le", self, other)
- def __gt__(self, other):
- return self.apply("gt", self, other)
- def __ge__(self, other):
- return self.apply("ge", self, other)
-
-# conversions
-def imagemath_int(self):
- return _Operand(self.im.convert("I"))
-def imagemath_float(self):
- return _Operand(self.im.convert("F"))
-
-# logical
-def imagemath_equal(self, other):
- return self.apply("eq", self, other, mode="I")
-def imagemath_notequal(self, other):
- return self.apply("ne", self, other, mode="I")
-
-def imagemath_min(self, other):
- return self.apply("min", self, other)
-def imagemath_max(self, other):
- return self.apply("max", self, other)
-
-def imagemath_convert(self, mode):
- return _Operand(self.im.convert(mode))
-
-ops = {}
-for k, v in globals().items():
- if k[:10] == "imagemath_":
- ops[k[10:]] = v
-
-##
-# Evaluates an image expression.
-#
-# @param expression A string containing a Python-style expression.
-# @keyparam options Values to add to the evaluation context. You
-# can either use a dictionary, or one or more keyword arguments.
-# @return The evaluated expression. This is usually an image object,
-# but can also be an integer, a floating point value, or a pixel
-# tuple, depending on the expression.
-
-def eval(expression, _dict={}, **kw):
-
- # build execution namespace
- args = ops.copy()
- args.update(_dict)
- args.update(kw)
- for k, v in args.items():
- if hasattr(v, "im"):
- args[k] = _Operand(v)
-
- import __builtin__
- out =__builtin__.eval(expression, args)
- try:
- return out.im
- except AttributeError:
- return out
diff --git a/PIL/ImageMode.py b/PIL/ImageMode.py
deleted file mode 100644
index 87a0e5a..0000000
--- a/PIL/ImageMode.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: /work/modules/pil/PIL/ImageFilter.py 486 2004-10-06T08:55:20.930352Z fredrik $
-#
-# standard mode descriptors
-#
-# History:
-# 2006-03-20 fl Added
-#
-# Copyright (c) 2006 by Secret Labs AB.
-# Copyright (c) 2006 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-# mode descriptor cache
-_modes = {}
-
-##
-# Wrapper for mode strings.
-
-class ModeDescriptor:
-
- def __init__(self, mode, bands, basemode, basetype):
- self.mode = mode
- self.bands = bands
- self.basemode = basemode
- self.basetype = basetype
-
- def __str__(self):
- return self.mode
-
-##
-# Gets a mode descriptor for the given mode.
-
-def getmode(mode):
- if not _modes:
- # initialize mode cache
- import Image
- # core modes
- for m, (basemode, basetype, bands) in Image._MODEINFO.items():
- _modes[m] = ModeDescriptor(m, bands, basemode, basetype)
- # extra experimental modes
- _modes["LA"] = ModeDescriptor("LA", ("L", "A"), "L", "L")
- _modes["PA"] = ModeDescriptor("PA", ("P", "A"), "RGB", "L")
- return _modes[mode]
diff --git a/PIL/ImageOps.py b/PIL/ImageOps.py
deleted file mode 100644
index 89b5e72..0000000
--- a/PIL/ImageOps.py
+++ /dev/null
@@ -1,408 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageOps.py 2760 2006-06-19 13:31:40Z fredrik $
-#
-# standard image operations
-#
-# History:
-# 2001-10-20 fl Created
-# 2001-10-23 fl Added autocontrast operator
-# 2001-12-18 fl Added Kevin's fit operator
-# 2004-03-14 fl Fixed potential division by zero in equalize
-# 2005-05-05 fl Fixed equalize for low number of values
-#
-# Copyright (c) 2001-2004 by Secret Labs AB
-# Copyright (c) 2001-2004 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import operator
-
-##
-# (New in 1.1.3) The <b>ImageOps</b> module contains a number of
-# 'ready-made' image processing operations. This module is somewhat
-# experimental, and most operators only work on L and RGB images.
-#
-# @since 1.1.3
-##
-
-#
-# helpers
-
-def _border(border):
- if type(border) is type(()):
- if len(border) == 2:
- left, top = right, bottom = border
- elif len(border) == 4:
- left, top, right, bottom = border
- else:
- left = top = right = bottom = border
- return left, top, right, bottom
-
-def _color(color, mode):
- if Image.isStringType(color):
- import ImageColor
- color = ImageColor.getcolor(color, mode)
- return color
-
-def _lut(image, lut):
- if image.mode == "P":
- # FIXME: apply to lookup table, not image data
- raise NotImplementedError("mode P support coming soon")
- elif image.mode in ("L", "RGB"):
- if image.mode == "RGB" and len(lut) == 256:
- lut = lut + lut + lut
- return image.point(lut)
- else:
- raise IOError, "not supported for this image mode"
-
-#
-# actions
-
-##
-# Maximize (normalize) image contrast. This function calculates a
-# histogram of the input image, removes <i>cutoff</i> percent of the
-# lightest and darkest pixels from the histogram, and remaps the image
-# so that the darkest pixel becomes black (0), and the lightest
-# becomes white (255).
-#
-# @param image The image to process.
-# @param cutoff How many percent to cut off from the histogram.
-# @param ignore The background pixel value (use None for no background).
-# @return An image.
-
-def autocontrast(image, cutoff=0, ignore=None):
- "Maximize image contrast, based on histogram"
- histogram = image.histogram()
- lut = []
- for layer in range(0, len(histogram), 256):
- h = histogram[layer:layer+256]
- if ignore is not None:
- # get rid of outliers
- try:
- h[ignore] = 0
- except TypeError:
- # assume sequence
- for ix in ignore:
- h[ix] = 0
- if cutoff:
- # cut off pixels from both ends of the histogram
- # get number of pixels
- n = 0
- for ix in range(256):
- n = n + h[ix]
- # remove cutoff% pixels from the low end
- cut = n * cutoff / 100
- for lo in range(256):
- if cut > h[lo]:
- cut = cut - h[lo]
- h[lo] = 0
- else:
- h[lo] = h[lo] - cut
- cut = 0
- if cut <= 0:
- break
- # remove cutoff% samples from the hi end
- cut = n * cutoff / 100
- for hi in range(255, -1, -1):
- if cut > h[hi]:
- cut = cut - h[hi]
- h[hi] = 0
- else:
- h[hi] = h[hi] - cut
- cut = 0
- if cut <= 0:
- break
- # find lowest/highest samples after preprocessing
- for lo in range(256):
- if h[lo]:
- break
- for hi in range(255, -1, -1):
- if h[hi]:
- break
- if hi <= lo:
- # don't bother
- lut.extend(range(256))
- else:
- scale = 255.0 / (hi - lo)
- offset = -lo * scale
- for ix in range(256):
- ix = int(ix * scale + offset)
- if ix < 0:
- ix = 0
- elif ix > 255:
- ix = 255
- lut.append(ix)
- return _lut(image, lut)
-
-##
-# Colorize grayscale image. The <i>black</i> and <i>white</i>
-# arguments should be RGB tuples; this function calculates a colour
-# wedge mapping all black pixels in the source image to the first
-# colour, and all white pixels to the second colour.
-#
-# @param image The image to colourize.
-# @param black The colour to use for black input pixels.
-# @param white The colour to use for white input pixels.
-# @return An image.
-
-def colorize(image, black, white):
- "Colorize a grayscale image"
- assert image.mode == "L"
- black = _color(black, "RGB")
- white = _color(white, "RGB")
- red = []; green = []; blue = []
- for i in range(256):
- red.append(black[0]+i*(white[0]-black[0])/255)
- green.append(black[1]+i*(white[1]-black[1])/255)
- blue.append(black[2]+i*(white[2]-black[2])/255)
- image = image.convert("RGB")
- return _lut(image, red + green + blue)
-
-##
-# Remove border from image. The same amount of pixels are removed
-# from all four sides. This function works on all image modes.
-#
-# @param image The image to crop.
-# @param border The number of pixels to remove.
-# @return An image.
-# @see Image#Image.crop
-
-def crop(image, border=0):
- "Crop border off image"
- left, top, right, bottom = _border(border)
- return image.crop(
- (left, top, image.size[0]-right, image.size[1]-bottom)
- )
-
-##
-# Deform the image.
-#
-# @param image The image to deform.
-# @param deformer A deformer object. Any object that implements a
-# <b>getmesh</b> method can be used.
-# @param resample What resampling filter to use.
-# @return An image.
-
-def deform(image, deformer, resample=Image.BILINEAR):
- "Deform image using the given deformer"
- return image.transform(
- image.size, Image.MESH, deformer.getmesh(image), resample
- )
-
-##
-# Equalize the image histogram. This function applies a non-linear
-# mapping to the input image, in order to create a uniform
-# distribution of grayscale values in the output image.
-#
-# @param image The image to equalize.
-# @param mask An optional mask. If given, only the pixels selected by
-# the mask are included in the analysis.
-# @return An image.
-
-def equalize(image, mask=None):
- "Equalize image histogram"
- if image.mode == "P":
- image = image.convert("RGB")
- h = image.histogram(mask)
- lut = []
- for b in range(0, len(h), 256):
- histo = filter(None, h[b:b+256])
- if len(histo) <= 1:
- lut.extend(range(256))
- else:
- step = (reduce(operator.add, histo) - histo[-1]) / 255
- if not step:
- lut.extend(range(256))
- else:
- n = step / 2
- for i in range(256):
- lut.append(n / step)
- n = n + h[i+b]
- return _lut(image, lut)
-
-##
-# Add border to the image
-#
-# @param image The image to expand.
-# @param border Border width, in pixels.
-# @param fill Pixel fill value (a colour value). Default is 0 (black).
-# @return An image.
-
-def expand(image, border=0, fill=0):
- "Add border to image"
- left, top, right, bottom = _border(border)
- width = left + image.size[0] + right
- height = top + image.size[1] + bottom
- out = Image.new(image.mode, (width, height), _color(fill, image.mode))
- out.paste(image, (left, top))
- return out
-
-##
-# Returns a sized and cropped version of the image, cropped to the
-# requested aspect ratio and size.
-# <p>
-# The <b>fit</b> function was contributed by Kevin Cazabon.
-#
-# @param size The requested output size in pixels, given as a
-# (width, height) tuple.
-# @param method What resampling method to use. Default is Image.NEAREST.
-# @param bleed Remove a border around the outside of the image (from all
-# four edges. The value is a decimal percentage (use 0.01 for one
-# percent). The default value is 0 (no border).
-# @param centering Control the cropping position. Use (0.5, 0.5) for
-# center cropping (e.g. if cropping the width, take 50% off of the
-# left side, and therefore 50% off the right side). (0.0, 0.0)
-# will crop from the top left corner (i.e. if cropping the width,
-# take all of the crop off of the right side, and if cropping the
-# height, take all of it off the bottom). (1.0, 0.0) will crop
-# from the bottom left corner, etc. (i.e. if cropping the width,
-# take all of the crop off the left side, and if cropping the height
-# take none from the top, and therefore all off the bottom).
-# @return An image.
-
-def fit(image, size, method=Image.NEAREST, bleed=0.0, centering=(0.5, 0.5)):
- """
- This method returns a sized and cropped version of the image,
- cropped to the aspect ratio and size that you request.
- """
-
- # by Kevin Cazabon, Feb 17/2000
- # kevin@cazabon.com
- # http://www.cazabon.com
-
- # ensure inputs are valid
- if type(centering) != type([]):
- centering = [centering[0], centering[1]]
-
- if centering[0] > 1.0 or centering[0] < 0.0:
- centering [0] = 0.50
- if centering[1] > 1.0 or centering[1] < 0.0:
- centering[1] = 0.50
-
- if bleed > 0.49999 or bleed < 0.0:
- bleed = 0.0
-
- # calculate the area to use for resizing and cropping, subtracting
- # the 'bleed' around the edges
-
- # number of pixels to trim off on Top and Bottom, Left and Right
- bleedPixels = (
- int((float(bleed) * float(image.size[0])) + 0.5),
- int((float(bleed) * float(image.size[1])) + 0.5)
- )
-
- liveArea = (
- bleedPixels[0], bleedPixels[1], image.size[0] - bleedPixels[0] - 1,
- image.size[1] - bleedPixels[1] - 1
- )
-
- liveSize = (liveArea[2] - liveArea[0], liveArea[3] - liveArea[1])
-
- # calculate the aspect ratio of the liveArea
- liveAreaAspectRatio = float(liveSize[0])/float(liveSize[1])
-
- # calculate the aspect ratio of the output image
- aspectRatio = float(size[0]) / float(size[1])
-
- # figure out if the sides or top/bottom will be cropped off
- if liveAreaAspectRatio >= aspectRatio:
- # liveArea is wider than what's needed, crop the sides
- cropWidth = int((aspectRatio * float(liveSize[1])) + 0.5)
- cropHeight = liveSize[1]
- else:
- # liveArea is taller than what's needed, crop the top and bottom
- cropWidth = liveSize[0]
- cropHeight = int((float(liveSize[0])/aspectRatio) + 0.5)
-
- # make the crop
- leftSide = int(liveArea[0] + (float(liveSize[0]-cropWidth) * centering[0]))
- if leftSide < 0:
- leftSide = 0
- topSide = int(liveArea[1] + (float(liveSize[1]-cropHeight) * centering[1]))
- if topSide < 0:
- topSide = 0
-
- out = image.crop(
- (leftSide, topSide, leftSide + cropWidth, topSide + cropHeight)
- )
-
- # resize the image and return it
- return out.resize(size, method)
-
-##
-# Flip the image vertically (top to bottom).
-#
-# @param image The image to flip.
-# @return An image.
-
-def flip(image):
- "Flip image vertically"
- return image.transpose(Image.FLIP_TOP_BOTTOM)
-
-##
-# Convert the image to grayscale.
-#
-# @param image The image to convert.
-# @return An image.
-
-def grayscale(image):
- "Convert to grayscale"
- return image.convert("L")
-
-##
-# Invert (negate) the image.
-#
-# @param image The image to invert.
-# @return An image.
-
-def invert(image):
- "Invert image (negate)"
- lut = []
- for i in range(256):
- lut.append(255-i)
- return _lut(image, lut)
-
-##
-# Flip image horizontally (left to right).
-#
-# @param image The image to mirror.
-# @return An image.
-
-def mirror(image):
- "Flip image horizontally"
- return image.transpose(Image.FLIP_LEFT_RIGHT)
-
-##
-# Reduce the number of bits for each colour channel.
-#
-# @param image The image to posterize.
-# @param bits The number of bits to keep for each channel (1-8).
-# @return An image.
-
-def posterize(image, bits):
- "Reduce the number of bits per color channel"
- lut = []
- mask = ~(2**(8-bits)-1)
- for i in range(256):
- lut.append(i & mask)
- return _lut(image, lut)
-
-##
-# Invert all pixel values above a threshold.
-#
-# @param image The image to posterize.
-# @param threshold All pixels above this greyscale level are inverted.
-# @return An image.
-
-def solarize(image, threshold=128):
- "Invert all values above threshold"
- lut = []
- for i in range(256):
- if i < threshold:
- lut.append(i)
- else:
- lut.append(255-i)
- return _lut(image, lut)
diff --git a/PIL/ImagePalette.py b/PIL/ImagePalette.py
deleted file mode 100644
index 0e9a93a..0000000
--- a/PIL/ImagePalette.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImagePalette.py 2339 2005-03-25 08:02:17Z fredrik $
-#
-# image palette object
-#
-# History:
-# 1996-03-11 fl Rewritten.
-# 1997-01-03 fl Up and running.
-# 1997-08-23 fl Added load hack
-# 2001-04-16 fl Fixed randint shadow bug in random()
-#
-# Copyright (c) 1997-2001 by Secret Labs AB
-# Copyright (c) 1996-1997 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import array
-import Image
-
-##
-# Colour palette wrapper for palette mapped images.
-
-class ImagePalette:
- "Colour palette for palette mapped images"
-
- def __init__(self, mode = "RGB", palette = None):
- self.mode = mode
- self.rawmode = None # if set, palette contains raw data
- self.palette = palette or range(256)*len(self.mode)
- self.colors = {}
- self.dirty = None
- if len(self.mode)*256 != len(self.palette):
- raise ValueError, "wrong palette size"
-
- def getdata(self):
- # experimental: get palette contains in format suitable
- # for the low-level im.putpalette primitive
- if self.rawmode:
- return self.rawmode, self.palette
- return self.mode + ";L", self.tostring()
-
- def tostring(self):
- # experimental: convert palette to string
- if self.rawmode:
- raise ValueError("palette contains raw palette data")
- if Image.isStringType(self.palette):
- return self.palette
- return array.array("B", self.palette).tostring()
-
- def getcolor(self, color):
- # experimental: given an rgb tuple, allocate palette entry
- if self.rawmode:
- raise ValueError("palette contains raw palette data")
- if Image.isTupleType(color):
- try:
- return self.colors[color]
- except KeyError:
- # allocate new color slot
- if Image.isStringType(self.palette):
- self.palette = map(int, self.palette)
- index = len(self.colors)
- if index >= 256:
- raise ValueError("cannot allocate more than 256 colors")
- self.colors[color] = index
- self.palette[index] = color[0]
- self.palette[index+256] = color[1]
- self.palette[index+512] = color[2]
- self.dirty = 1
- return index
- else:
- raise ValueError("unknown color specifier: %r" % color)
-
- def save(self, fp):
- # (experimental) save palette to text file
- if self.rawmode:
- raise ValueError("palette contains raw palette data")
- if type(fp) == type(""):
- fp = open(fp, "w")
- fp.write("# Palette\n")
- fp.write("# Mode: %s\n" % self.mode)
- for i in range(256):
- fp.write("%d" % i)
- for j in range(i, len(self.palette), 256):
- fp.write(" %d" % self.palette[j])
- fp.write("\n")
- fp.close()
-
-# --------------------------------------------------------------------
-# Internal
-
-def raw(rawmode, data):
- palette = ImagePalette()
- palette.rawmode = rawmode
- palette.palette = data
- palette.dirty = 1
- return palette
-
-# --------------------------------------------------------------------
-# Factories
-
-def new(mode, data):
- return Image.core.new_palette(mode, data)
-
-def negative(mode = "RGB"):
- palette = range(256)
- palette.reverse()
- return ImagePalette(mode, palette * len(mode))
-
-def random(mode = "RGB"):
- from random import randint
- palette = map(lambda a, randint=randint:
- randint(0, 255), [0]*256*len(mode))
- return ImagePalette(mode, palette)
-
-def wedge(mode = "RGB"):
- return ImagePalette(mode, range(256) * len(mode))
-
-def load(filename):
-
- # FIXME: supports GIMP gradients only
-
- fp = open(filename, "rb")
-
- lut = None
-
- if not lut:
- try:
- import GimpPaletteFile
- fp.seek(0)
- p = GimpPaletteFile.GimpPaletteFile(fp)
- lut = p.getpalette()
- except (SyntaxError, ValueError):
- pass
-
- if not lut:
- try:
- import GimpGradientFile
- fp.seek(0)
- p = GimpGradientFile.GimpGradientFile(fp)
- lut = p.getpalette()
- except (SyntaxError, ValueError):
- pass
-
- if not lut:
- try:
- import PaletteFile
- fp.seek(0)
- p = PaletteFile.PaletteFile(fp)
- lut = p.getpalette()
- except (SyntaxError, ValueError):
- pass
-
- if not lut:
- raise IOError, "cannot load palette"
-
- return lut # data, rawmode
-
-
-# add some psuedocolour palettes as well
diff --git a/PIL/ImagePath.py b/PIL/ImagePath.py
deleted file mode 100644
index 120a607..0000000
--- a/PIL/ImagePath.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: ImagePath.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# path interface
-#
-# History:
-# 1996-11-04 fl Created
-# 2002-04-14 fl Added documentation stub class
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-
-##
-# Path wrapper.
-
-class Path:
-
- ##
- # Creates a path object.
- #
- # @param xy Sequence. The sequence can contain 2-tuples [(x, y), ...]
- # or a flat list of numbers [x, y, ...].
-
- def __init__(self, xy):
- pass
-
- ##
- # Compacts the path, by removing points that are close to each
- # other. This method modifies the path in place.
-
- def compact(self, distance=2):
- pass
-
- ##
- # Gets the bounding box.
-
- def getbbox(self):
- pass
-
- ##
- # Maps the path through a function.
-
- def map(self, function):
- pass
-
- ##
- # Converts the path to Python list.
- #
- # @param flat By default, this function returns a list of 2-tuples
- # [(x, y), ...]. If this argument is true, it returns a flat
- # list [x, y, ...] instead.
- # @return A list of coordinates.
-
- def tolist(self, flat=0):
- pass
-
- ##
- # Transforms the path.
-
- def transform(self, matrix):
- pass
-
-
-# override with C implementation
-Path = Image.core.path
diff --git a/PIL/ImageQt.py b/PIL/ImageQt.py
deleted file mode 100644
index 2e9f476..0000000
--- a/PIL/ImageQt.py
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageQt.py 2741 2006-06-18 16:17:20Z fredrik $
-#
-# a simple Qt image interface.
-#
-# history:
-# 2006-06-03 fl: created
-# 2006-06-04 fl: inherit from QImage instead of wrapping it
-# 2006-06-05 fl: removed toimage helper; move string support to ImageQt
-#
-# Copyright (c) 2006 by Secret Labs AB
-# Copyright (c) 2006 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-
-from PyQt4.QtGui import QImage, qRgb
-
-##
-# (Internal) Turns an RGB color into a Qt compatible color integer.
-
-def rgb(r, g, b):
- # use qRgb to pack the colors, and then turn the resulting long
- # into a negative integer with the same bitpattern.
- return (qRgb(r, g, b) & 0xffffff) - 0x1000000
-
-##
-# An PIL image wrapper for Qt. This is a subclass of PyQt4's QImage
-# class.
-#
-# @param im A PIL Image object, or a file name (given either as Python
-# string or a PyQt string object).
-
-class ImageQt(QImage):
-
- def __init__(self, im):
-
- data = None
- colortable = None
-
- # handle filename, if given instead of image name
- if hasattr(im, "toUtf8"):
- # FIXME - is this really the best way to do this?
- im = unicode(im.toUtf8(), "utf-8")
- if Image.isStringType(im):
- im = Image.open(im)
-
- if im.mode == "1":
- format = QImage.Format_Mono
- elif im.mode == "L":
- format = QImage.Format_Indexed8
- colortable = []
- for i in range(256):
- colortable.append(rgb(i, i, i))
- elif im.mode == "P":
- format = QImage.Format_Indexed8
- colortable = []
- palette = im.getpalette()
- for i in range(0, len(palette), 3):
- colortable.append(rgb(*palette[i:i+3]))
- elif im.mode == "RGB":
- data = im.tostring("raw", "BGRX")
- format = QImage.Format_RGB32
- elif im.mode == "RGBA":
- try:
- data = im.tostring("raw", "BGRA")
- except SystemError:
- # workaround for earlier versions
- r, g, b, a = im.split()
- im = Image.merge("RGBA", (b, g, r, a))
- format = QImage.Format_ARGB32
- else:
- raise ValueError("unsupported image mode %r" % im.mode)
-
- # must keep a reference, or Qt will crash!
- self.__data = data or im.tostring()
-
- QImage.__init__(self, self.__data, im.size[0], im.size[1], format)
-
- if colortable:
- self.setColorTable(colortable)
diff --git a/PIL/ImageSequence.py b/PIL/ImageSequence.py
deleted file mode 100644
index 452b096..0000000
--- a/PIL/ImageSequence.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageSequence.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# sequence support classes
-#
-# history:
-# 1997-02-20 fl Created
-#
-# Copyright (c) 1997 by Secret Labs AB.
-# Copyright (c) 1997 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-##
-# This class implements an iterator object that can be used to loop
-# over an image sequence.
-
-class Iterator:
-
- ##
- # Create an iterator.
- #
- # @param im An image object.
-
- def __init__(self, im):
- if not hasattr(im, "seek"):
- raise AttributeError("im must have seek method")
- self.im = im
-
- def __getitem__(self, ix):
- try:
- if ix:
- self.im.seek(ix)
- return self.im
- except EOFError:
- raise IndexError # end of sequence
diff --git a/PIL/ImageStat.py b/PIL/ImageStat.py
deleted file mode 100644
index d53e645..0000000
--- a/PIL/ImageStat.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageStat.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# global image statistics
-#
-# History:
-# 1996-04-05 fl Created
-# 1997-05-21 fl Added mask; added rms, var, stddev attributes
-# 1997-08-05 fl Added median
-# 1998-07-05 hk Fixed integer overflow error
-#
-# Notes:
-# This class shows how to implement delayed evaluation of attributes.
-# To get a certain value, simply access the corresponding attribute.
-# The __getattr__ dispatcher takes care of the rest.
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996-97.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import operator, math
-
-##
-# The <b>ImageStat</b> module calculates global statistics for an
-# image, or a region of an image.
-##
-
-##
-# Calculate statistics for the given image. If a mask is included,
-# only the regions covered by that mask are included in the
-# statistics.
-
-class Stat:
- "Get image or feature statistics"
-
- ##
- # Create a statistics object.
- #
- # @def __init__(image, mask=None)
- # @param image A PIL image, or a precalculate histogram.
- # @param mask An optional mask.
-
- def __init__(self, image_or_list, mask = None):
- try:
- if mask:
- self.h = image_or_list.histogram(mask)
- else:
- self.h = image_or_list.histogram()
- except AttributeError:
- self.h = image_or_list # assume it to be a histogram list
- if type(self.h) != type([]):
- raise TypeError, "first argument must be image or list"
- self.bands = range(len(self.h) / 256)
-
- def __getattr__(self, id):
- "Calculate missing attribute"
- if id[:4] == "_get":
- raise AttributeError, id
- # calculate missing attribute
- v = getattr(self, "_get" + id)()
- setattr(self, id, v)
- return v
-
- def _getextrema(self):
- "Get min/max values for each band in the image"
-
- def minmax(histogram):
- n = 255
- x = 0
- for i in range(256):
- if histogram[i]:
- n = min(n, i)
- x = max(x, i)
- return n, x # returns (255, 0) if there's no data in the histogram
-
- v = []
- for i in range(0, len(self.h), 256):
- v.append(minmax(self.h[i:]))
- return v
-
- def _getcount(self):
- "Get total number of pixels in each layer"
-
- v = []
- for i in range(0, len(self.h), 256):
- v.append(reduce(operator.add, self.h[i:i+256]))
- return v
-
- def _getsum(self):
- "Get sum of all pixels in each layer"
-
- v = []
- for i in range(0, len(self.h), 256):
- sum = 0.0
- for j in range(256):
- sum = sum + j * self.h[i+j]
- v.append(sum)
- return v
-
- def _getsum2(self):
- "Get squared sum of all pixels in each layer"
-
- v = []
- for i in range(0, len(self.h), 256):
- sum2 = 0.0
- for j in range(256):
- sum2 = sum2 + (j ** 2) * float(self.h[i+j])
- v.append(sum2)
- return v
-
- def _getmean(self):
- "Get average pixel level for each layer"
-
- v = []
- for i in self.bands:
- v.append(self.sum[i] / self.count[i])
- return v
-
- def _getmedian(self):
- "Get median pixel level for each layer"
-
- v = []
- for i in self.bands:
- s = 0
- l = self.count[i]/2
- b = i * 256
- for j in range(256):
- s = s + self.h[b+j]
- if s > l:
- break
- v.append(j)
- return v
-
- def _getrms(self):
- "Get RMS for each layer"
-
- v = []
- for i in self.bands:
- v.append(math.sqrt(self.sum2[i] / self.count[i]))
- return v
-
-
- def _getvar(self):
- "Get variance for each layer"
-
- v = []
- for i in self.bands:
- n = self.count[i]
- v.append((self.sum2[i]-(self.sum[i]**2.0)/n)/n)
- return v
-
- def _getstddev(self):
- "Get standard deviation for each layer"
-
- v = []
- for i in self.bands:
- v.append(math.sqrt(self.var[i]))
- return v
-
-Global = Stat # compatibility
-
-if __name__ == "__main__":
-
- im = Image.open("Images/lena.ppm")
-
- st = Stat(im)
-
- print "extrema", st.extrema
- print "sum ", st.sum
- print "mean ", st.mean
- print "median ", st.median
- print "rms ", st.rms
- print "sum2 ", st.sum2
- print "var ", st.var
- print "stddev ", st.stddev
diff --git a/PIL/ImageTk.py b/PIL/ImageTk.py
deleted file mode 100644
index 30f7c0e..0000000
--- a/PIL/ImageTk.py
+++ /dev/null
@@ -1,296 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageTk.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# a Tk display interface
-#
-# History:
-# 96-04-08 fl Created
-# 96-09-06 fl Added getimage method
-# 96-11-01 fl Rewritten, removed image attribute and crop method
-# 97-05-09 fl Use PyImagingPaste method instead of image type
-# 97-05-12 fl Minor tweaks to match the IFUNC95 interface
-# 97-05-17 fl Support the "pilbitmap" booster patch
-# 97-06-05 fl Added file= and data= argument to image constructors
-# 98-03-09 fl Added width and height methods to Image classes
-# 98-07-02 fl Use default mode for "P" images without palette attribute
-# 98-07-02 fl Explicitly destroy Tkinter image objects
-# 99-07-24 fl Support multiple Tk interpreters (from Greg Couch)
-# 99-07-26 fl Automatically hook into Tkinter (if possible)
-# 99-08-15 fl Hook uses _imagingtk instead of _imaging
-#
-# Copyright (c) 1997-1999 by Secret Labs AB
-# Copyright (c) 1996-1997 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Tkinter, Image
-
-##
-# The <b>ImageTk</b> module contains support to create and modify
-# Tkinter <b>BitmapImage</b> and <b>PhotoImage</b> objects.
-# <p>
-# For examples, see the demo programs in the <i>Scripts</i>
-# directory.
-##
-
-# --------------------------------------------------------------------
-# Check for Tkinter interface hooks
-
-_pilbitmap_ok = None
-
-def _pilbitmap_check():
- global _pilbitmap_ok
- if _pilbitmap_ok is None:
- try:
- im = Image.new("1", (1,1))
- Tkinter.BitmapImage(data="PIL:%d" % im.im.id)
- _pilbitmap_ok = 1
- except Tkinter.TclError:
- _pilbitmap_ok = 0
- return _pilbitmap_ok
-
-# --------------------------------------------------------------------
-# PhotoImage
-
-##
-# Creates a Tkinter-compatible photo image. This can be used
-# everywhere Tkinter expects an image object. If the image is an RGBA
-# image, pixels having alpha 0 are treated as transparent.
-
-class PhotoImage:
-
- ##
- # Create a photo image object. The constructor takes either
- # a PIL image, or a mode and a size. Alternatively, you can
- # use the <b>file</b> or <b>data</b> options to initialize
- # the photo image object.
- # <p>
- # @def __init__(image=None, size=None, **options)
- # @param image Either a PIL image, or a mode string. If a
- # mode string is used, a size must also be given.
- # @param size If the first argument is a mode string, this
- # defines the size of the image.
- # @keyparam file A filename to load the image from (using
- # Image.open(file)).
- # @keyparam data An 8-bit string containing image data (as
- # loaded from an image file).
-
- def __init__(self, image=None, size=None, **kw):
-
- # Tk compatibility: file or data
- if image is None:
- if kw.has_key("file"):
- image = Image.open(kw["file"])
- del kw["file"]
- elif kw.has_key("data"):
- from StringIO import StringIO
- image = Image.open(StringIO(kw["data"]))
- del kw["data"]
-
- if hasattr(image, "mode") and hasattr(image, "size"):
- # got an image instead of a mode
- mode = image.mode
- if mode == "P":
- # palette mapped data
- image.load()
- try:
- mode = image.palette.mode
- except AttributeError:
- mode = "RGB" # default
- size = image.size
- kw["width"], kw["height"] = size
- else:
- mode = image
- image = None
-
- if mode not in ["1", "L", "RGB", "RGBA"]:
- mode = Image.getmodebase(mode)
-
- self.__mode = mode
- self.__size = size
- self.__photo = apply(Tkinter.PhotoImage, (), kw)
- self.tk = self.__photo.tk
- if image:
- self.paste(image)
-
- def __del__(self):
- name = self.__photo.name
- self.__photo.name = None
- try:
- self.__photo.tk.call("image", "delete", name)
- except:
- pass # ignore internal errors
-
- ##
- # Get the Tkinter photo image identifier. This method is
- # automatically called by Tkinter whenever a PhotoImage object is
- # passed to a Tkinter method.
- #
- # @return A Tkinter photo image identifier (a string).
-
- def __str__(self):
- return str(self.__photo)
-
- ##
- # Get the width of the image.
- #
- # @return The width, in pixels.
-
- def width(self):
- return self.__size[0]
-
- ##
- # Get the height of the image.
- #
- # @return The height, in pixels.
-
- def height(self):
- return self.__size[1]
-
- ##
- # Paste a PIL image into the photo image. Note that this can
- # be very slow if the photo image is displayed.
- #
- # @param im A PIL image. The size must match the target region.
- # If the mode does not match, the image is converted to the
- # mode of the bitmap image.
- # @param box A 4-tuple defining the left, upper, right, and
- # lower pixel coordinate. If None is given instead of a
- # tuple, all of the image is assumed.
-
- def paste(self, im, box=None):
-
- # convert to blittable
- im.load()
- image = im.im
- if image.isblock() and im.mode == self.__mode:
- block = image
- else:
- block = image.new_block(self.__mode, im.size)
- image.convert2(block, image) # convert directly between buffers
-
- tk = self.__photo.tk
-
- try:
- tk.call("PyImagingPhoto", self.__photo, block.id)
- except Tkinter.TclError, v:
- # activate Tkinter hook
- try:
- import _imagingtk
- try:
- _imagingtk.tkinit(tk.interpaddr(), 1)
- except AttributeError:
- _imagingtk.tkinit(id(tk), 0)
- tk.call("PyImagingPhoto", self.__photo, block.id)
- except (ImportError, AttributeError, Tkinter.TclError):
- raise # configuration problem; cannot attach to Tkinter
-
-# --------------------------------------------------------------------
-# BitmapImage
-
-##
-# Create a Tkinter-compatible bitmap image. This can be used
-# everywhere Tkinter expects an image object.
-
-class BitmapImage:
-
- ##
- # Create a Tkinter-compatible bitmap image.
- # <p>
- # The given image must have mode "1". Pixels having value 0 are
- # treated as transparent. Options, if any, are passed on to
- # Tkinter. The most commonly used option is <b>foreground</b>,
- # which is used to specify the colour for the non-transparent
- # parts. See the Tkinter documentation for information on how to
- # specify colours.
- #
- # @def __init__(image=None, **options)
- # @param image A PIL image.
-
- def __init__(self, image=None, **kw):
-
- # Tk compatibility: file or data
- if image is None:
- if kw.has_key("file"):
- image = Image.open(kw["file"])
- del kw["file"]
- elif kw.has_key("data"):
- from StringIO import StringIO
- image = Image.open(StringIO(kw["data"]))
- del kw["data"]
-
- self.__mode = image.mode
- self.__size = image.size
-
- if _pilbitmap_check():
- # fast way (requires the pilbitmap booster patch)
- image.load()
- kw["data"] = "PIL:%d" % image.im.id
- self.__im = image # must keep a reference
- else:
- # slow but safe way
- kw["data"] = image.tobitmap()
- self.__photo = apply(Tkinter.BitmapImage, (), kw)
-
- def __del__(self):
- name = self.__photo.name
- self.__photo.name = None
- try:
- self.__photo.tk.call("image", "delete", name)
- except:
- pass # ignore internal errors
-
- ##
- # Get the width of the image.
- #
- # @return The width, in pixels.
-
- def width(self):
- return self.__size[0]
-
- ##
- # Get the height of the image.
- #
- # @return The height, in pixels.
-
- def height(self):
- return self.__size[1]
-
- ##
- # Get the Tkinter bitmap image identifier. This method is
- # automatically called by Tkinter whenever a BitmapImage object
- # is passed to a Tkinter method.
- #
- # @return A Tkinter bitmap image identifier (a string).
-
- def __str__(self):
- return str(self.__photo)
-
-##
-# Copies the contents of a PhotoImage to a PIL image memory.
-
-def getimage(photo):
- photo.tk.call("PyImagingPhotoGet", photo)
-
-# --------------------------------------------------------------------
-# Helper for the Image.show method.
-
-def _show(image, title):
-
- class UI(Tkinter.Label):
- def __init__(self, master, im):
- if im.mode == "1":
- self.image = BitmapImage(im, foreground="white", master=master)
- else:
- self.image = PhotoImage(im, master=master)
- Tkinter.Label.__init__(self, master, image=self.image,
- bg="black", bd=0)
-
- if not Tkinter._default_root:
- raise IOError, "tkinter not initialized"
- top = Tkinter.Toplevel()
- if title:
- top.title(title)
- UI(top, image).pack()
diff --git a/PIL/ImageTransform.py b/PIL/ImageTransform.py
deleted file mode 100644
index 2944cd3..0000000
--- a/PIL/ImageTransform.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageTransform.py 2813 2006-10-07 10:11:35Z fredrik $
-#
-# transform wrappers
-#
-# History:
-# 2002-04-08 fl Created
-#
-# Copyright (c) 2002 by Secret Labs AB
-# Copyright (c) 2002 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-
-class Transform:
- def __init__(self, data):
- self.data = data
- def getdata(self):
- return self.method, self.data
-
-##
-# Define an affine image transform.
-# <p>
-# This function takes a 6-tuple (<i>a, b, c, d, e, f</i>) which
-# contain the first two rows from an affine transform matrix. For
-# each pixel (<i>x, y</i>) in the output image, the new value is
-# taken from a position (a <i>x</i> + b <i>y</i> + c,
-# d <i>x</i> + e <i>y</i> + f) in the input image, rounded to
-# nearest pixel.
-# <p>
-# This function can be used to scale, translate, rotate, and shear the
-# original image.
-#
-# @def AffineTransform(matrix)
-# @param matrix A 6-tuple (<i>a, b, c, d, e, f</i>) containing
-# the first two rows from an affine transform matrix.
-# @see Image#Image.transform
-
-class AffineTransform(Transform):
- method = Image.AFFINE
-
-##
-# Define a transform to extract a subregion from an image.
-# <p>
-# Maps a rectangle (defined by two corners) from the image to a
-# rectangle of the given size. The resulting image will contain
-# data sampled from between the corners, such that (<i>x0, y0</i>)
-# in the input image will end up at (0,0) in the output image,
-# and (<i>x1, y1</i>) at <i>size</i>.
-# <p>
-# This method can be used to crop, stretch, shrink, or mirror an
-# arbitrary rectangle in the current image. It is slightly slower than
-# <b>crop</b>, but about as fast as a corresponding <b>resize</b>
-# operation.
-#
-# @def ExtentTransform(bbox)
-# @param bbox A 4-tuple (<i>x0, y0, x1, y1</i>) which specifies
-# two points in the input image's coordinate system.
-# @see Image#Image.transform
-
-class ExtentTransform(Transform):
- method = Image.EXTENT
-
-##
-# Define an quad image transform.
-# <p>
-# Maps a quadrilateral (a region defined by four corners) from the
-# image to a rectangle of the given size.
-#
-# @def QuadTransform(xy)
-# @param xy An 8-tuple (<i>x0, y0, x1, y1, x2, y2, y3, y3</i>) which
-# contain the upper left, lower left, lower right, and upper right
-# corner of the source quadrilateral.
-# @see Image#Image.transform
-
-class QuadTransform(Transform):
- method = Image.QUAD
-
-##
-# Define an mesh image transform. A mesh transform consists of one
-# or more individual quad transforms.
-#
-# @def MeshTransform(data)
-# @param data A list of (bbox, quad) tuples.
-# @see Image#Image.transform
-
-class MeshTransform(Transform):
- method = Image.MESH
diff --git a/PIL/ImageWin.py b/PIL/ImageWin.py
deleted file mode 100644
index 13c56b9..0000000
--- a/PIL/ImageWin.py
+++ /dev/null
@@ -1,215 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageWin.py 2662 2006-03-21 22:41:02Z fredrik $
-#
-# a Windows DIB display interface
-#
-# History:
-# 1996-05-20 fl Created
-# 1996-09-20 fl Fixed subregion exposure
-# 1997-09-21 fl Added draw primitive (for tzPrint)
-# 2003-05-21 fl Added experimental Window/ImageWindow classes
-# 2003-09-05 fl Added fromstring/tostring methods
-#
-# Copyright (c) Secret Labs AB 1997-2003.
-# Copyright (c) Fredrik Lundh 1996-2003.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-
-##
-# The <b>ImageWin</b> module contains support to create and display
-# images under Windows 95/98, NT, 2000 and later.
-
-class HDC:
- def __init__(self, dc):
- self.dc = dc
- def __int__(self):
- return self.dc
-
-class HWND:
- def __init__(self, wnd):
- self.wnd = wnd
- def __int__(self):
- return self.wnd
-
-##
-# Create a Windows bitmap with the given mode and size. The mode can
-# be one of "1", "L", "P", or "RGB".
-#
-# If the display requires a palette, this constructor creates a
-# suitable palette and associates it with the image. For an "L" image,
-# 128 greylevels are allocated. For an "RGB" image, a 6x6x6 colour
-# cube is used, together with 20 greylevels.
-#
-# To make sure that palettes work properly under Windows, you must
-# call the <b>palette</b> method upon certain events from Windows.
-
-class Dib:
-
- ##
- # Create Windows bitmap.
- #
- # @param image Either a PIL image, or a mode string. If a
- # mode string is used, a size must also be given. The
- # mode can be one of "1", "L", "P", or "RGB".
- # @param size If the first argument is a mode string, this
- # defines the size of the image.
-
- def __init__(self, image, size=None):
- if hasattr(image, "mode") and hasattr(image, "size"):
- mode = image.mode
- size = image.size
- else:
- mode = image
- image = None
- if mode not in ["1", "L", "P", "RGB"]:
- mode = Image.getmodebase(mode)
- self.image = Image.core.display(mode, size)
- self.mode = mode
- self.size = size
- if image:
- self.paste(image)
-
- ##
- # Copy the bitmap contents to a device context.
- #
- # @param handle Device context (HDC), cast to a Python integer,
- # or a HDC or HWND instance. In PythonWin, you can use the
- # <b>GetHandleAttrib</b> method of the <b>CDC</b> class to get
- # a suitable handle.
-
- def expose(self, handle):
- if isinstance(handle, HWND):
- dc = self.image.getdc(handle)
- try:
- result = self.image.expose(dc)
- finally:
- self.image.releasedc(handle, dc)
- else:
- result = self.image.expose(handle)
- return result
-
- def draw(self, handle, dst, src=None):
- if not src:
- src = (0,0) + self.size
- if isinstance(handle, HWND):
- dc = self.image.getdc(handle)
- try:
- result = self.image.draw(dc, dst, src)
- finally:
- self.image.releasedc(handle, dc)
- else:
- result = self.image.draw(handle, dst, src)
- return result
-
- ##
- # Installs the palette associated with the image in the
- # given device context.
- # <p>
- # This method should be called upon <b>QUERYNEWPALETTE</b>
- # and <b>PALETTECHANGED</b> events from Windows. If this
- # method returns a non-zero value, one or more display
- # palette entries were changed, and the image should be
- # redrawn.
- #
- # @param handle Device context (HDC), cast to a Python integer,
- # or an HDC or HWND instance.
- # @return A true value if one or more entries were changed
- # (this indicates that the image should be redrawn).
-
- def query_palette(self, handle):
- if isinstance(handle, HWND):
- handle = self.image.getdc(handle)
- try:
- result = self.image.query_palette(handle)
- finally:
- self.image.releasedc(handle, handle)
- else:
- result = self.image.query_palette(handle)
- return result
-
- ##
- # Paste a PIL image into the bitmap image.
- #
- # @param im A PIL image. The size must match the target region.
- # If the mode does not match, the image is converted to the
- # mode of the bitmap image.
- # @param box A 4-tuple defining the left, upper, right, and
- # lower pixel coordinate. If None is given instead of a
- # tuple, all of the image is assumed.
-
- def paste(self, im, box=None):
- im.load()
- if self.mode != im.mode:
- im = im.convert(self.mode)
- if box:
- self.image.paste(im.im, box)
- else:
- self.image.paste(im.im)
-
- ##
- # Load display memory contents from string buffer.
- #
- # @param buffer A string buffer containing display data (usually
- # data returned from <b>tostring</b>)
-
- def fromstring(self, buffer):
- return self.image.fromstring(buffer)
-
- ##
- # Copy display memory contents to string buffer.
- #
- # @return A string buffer containing display data.
-
- def tostring(self):
- return self.image.tostring()
-
-
-##
-# Create a Window with the given title size.
-
-class Window:
-
- def __init__(self, title="PIL", width=None, height=None):
- self.hwnd = Image.core.createwindow(
- title, self.__dispatcher, width or 0, height or 0
- )
-
- def __dispatcher(self, action, *args):
- return apply(getattr(self, "ui_handle_" + action), args)
-
- def ui_handle_clear(self, dc, x0, y0, x1, y1):
- pass
-
- def ui_handle_damage(self, x0, y0, x1, y1):
- pass
-
- def ui_handle_destroy(self):
- pass
-
- def ui_handle_repair(self, dc, x0, y0, x1, y1):
- pass
-
- def ui_handle_resize(self, width, height):
- pass
-
- def mainloop(self):
- Image.core.eventloop()
-
-##
-# Create an image window which displays the given image.
-
-class ImageWindow(Window):
-
- def __init__(self, image, title="PIL"):
- if not isinstance(image, Dib):
- image = Dib(image)
- self.image = image
- width, height = image.size
- Window.__init__(self, title, width=width, height=height)
-
- def ui_handle_repair(self, dc, x0, y0, x1, y1):
- self.image.draw(dc, (x0, y0, x1, y1))
diff --git a/PIL/ImtImagePlugin.py b/PIL/ImtImagePlugin.py
deleted file mode 100644
index f321ae3..0000000
--- a/PIL/ImtImagePlugin.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImtImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# IM Tools support for PIL
-#
-# history:
-# 1996-05-27 fl Created (read 8-bit images only)
-# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.2)
-#
-# Copyright (c) Secret Labs AB 1997-2001.
-# Copyright (c) Fredrik Lundh 1996-2001.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.2"
-
-import string, re
-
-import Image, ImageFile
-
-#
-# --------------------------------------------------------------------
-
-field = re.compile(r"([a-z]*) ([^ \r\n]*)")
-
-##
-# Image plugin for IM Tools images.
-
-class ImtImageFile(ImageFile.ImageFile):
-
- format = "IMT"
- format_description = "IM Tools"
-
- def _open(self):
-
- # Quick rejection: if there's not a LF among the first
- # 100 bytes, this is (probably) not a text header.
-
- if not "\n" in self.fp.read(100):
- raise SyntaxError, "not an IM file"
- self.fp.seek(0)
-
- xsize = ysize = 0
-
- while 1:
-
- s = self.fp.read(1)
- if not s:
- break
-
- if s == chr(12):
-
- # image data begins
- self.tile = [("raw", (0,0)+self.size,
- self.fp.tell(),
- (self.mode, 0, 1))]
-
- break
-
- else:
-
- # read key/value pair
- # FIXME: dangerous, may read whole file
- s = s + self.fp.readline()
- if len(s) == 1 or len(s) > 100:
- break
- if s[0] == "*":
- continue # comment
-
- m = field.match(s)
- if not m:
- break
- k, v = m.group(1,2)
- if k == "width":
- xsize = int(v)
- self.size = xsize, ysize
- elif k == "height":
- ysize = int(v)
- self.size = xsize, ysize
- elif k == "pixel" and v == "n8":
- self.mode = "L"
-
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("IMT", ImtImageFile)
-
-#
-# no extension registered (".im" is simply too common)
diff --git a/PIL/IptcImagePlugin.py b/PIL/IptcImagePlugin.py
deleted file mode 100644
index 3535759..0000000
--- a/PIL/IptcImagePlugin.py
+++ /dev/null
@@ -1,280 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: IptcImagePlugin.py 2813 2006-10-07 10:11:35Z fredrik $
-#
-# IPTC/NAA file handling
-#
-# history:
-# 1995-10-01 fl Created
-# 1998-03-09 fl Cleaned up and added to PIL
-# 2002-06-18 fl Added getiptcinfo helper
-#
-# Copyright (c) Secret Labs AB 1997-2002.
-# Copyright (c) Fredrik Lundh 1995.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.3"
-
-
-import Image, ImageFile
-import os, tempfile
-
-
-COMPRESSION = {
- 1: "raw",
- 5: "jpeg"
-}
-
-PAD = chr(0) * 4
-
-#
-# Helpers
-
-def i16(c):
- return ord(c[1]) + (ord(c[0])<<8)
-
-def i32(c):
- return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
-
-def i(c):
- return i32((PAD + c)[-4:])
-
-def dump(c):
- for i in c:
- print "%02x" % ord(i),
- print
-
-##
-# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields
-# from TIFF and JPEG files, use the <b>getiptcinfo</b> function.
-
-class IptcImageFile(ImageFile.ImageFile):
-
- format = "IPTC"
- format_description = "IPTC/NAA"
-
- def getint(self, key):
- return i(self.info[key])
-
- def field(self):
- #
- # get a IPTC field header
- s = self.fp.read(5)
- if not len(s):
- return None, 0
-
- tag = ord(s[1]), ord(s[2])
-
- # syntax
- if ord(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9:
- raise SyntaxError, "invalid IPTC/NAA file"
-
- # field size
- size = ord(s[3])
- if size > 132:
- raise IOError, "illegal field length in IPTC/NAA file"
- elif size == 128:
- size = 0
- elif size > 128:
- size = i(self.fp.read(size-128))
- else:
- size = i16(s[3:])
-
- return tag, size
-
- def _is_raw(self, offset, size):
- #
- # check if the file can be mapped
-
- # DISABLED: the following only slows things down...
- return 0
-
- self.fp.seek(offset)
- t, sz = self.field()
- if sz != size[0]:
- return 0
- y = 1
- while 1:
- self.fp.seek(sz, 1)
- t, s = self.field()
- if t != (8, 10):
- break
- if s != sz:
- return 0
- y = y + 1
- return y == size[1]
-
- def _open(self):
-
- # load descriptive fields
- while 1:
- offset = self.fp.tell()
- tag, size = self.field()
- if not tag or tag == (8,10):
- break
- if size:
- self.info[tag] = self.fp.read(size)
- else:
- self.info[tag] = None
- # print tag, self.info[tag]
-
- # mode
- layers = ord(self.info[(3,60)][0])
- component = ord(self.info[(3,60)][1])
- if self.info.has_key((3,65)):
- id = ord(self.info[(3,65)][0])-1
- else:
- id = 0
- if layers == 1 and not component:
- self.mode = "L"
- elif layers == 3 and component:
- self.mode = "RGB"[id]
- elif layers == 4 and component:
- self.mode = "CMYK"[id]
-
- # size
- self.size = self.getint((3,20)), self.getint((3,30))
-
- # compression
- try:
- compression = COMPRESSION[self.getint((3,120))]
- except KeyError:
- raise IOError, "Unknown IPTC image compression"
-
- # tile
- if tag == (8,10):
- if compression == "raw" and self._is_raw(offset, self.size):
- self.tile = [(compression, (offset, size + 5, -1),
- (0, 0, self.size[0], self.size[1]))]
- else:
- self.tile = [("iptc", (compression, offset),
- (0, 0, self.size[0], self.size[1]))]
-
- def load(self):
-
- if len(self.tile) != 1 or self.tile[0][0] != "iptc":
- return ImageFile.ImageFile.load(self)
-
- type, tile, box = self.tile[0]
-
- encoding, offset = tile
-
- self.fp.seek(offset)
-
- # Copy image data to temporary file
- outfile = tempfile.mktemp()
- o = open(outfile, "wb")
- if encoding == "raw":
- # To simplify access to the extracted file,
- # prepend a PPM header
- o.write("P5\n%d %d\n255\n" % self.size)
- while 1:
- type, size = self.field()
- if type != (8, 10):
- break
- while size > 0:
- s = self.fp.read(min(size, 8192))
- if not s:
- break
- o.write(s)
- size = size - len(s)
- o.close()
-
- try:
- try:
- # fast
- self.im = Image.core.open_ppm(outfile)
- except:
- # slightly slower
- im = Image.open(outfile)
- im.load()
- self.im = im.im
- finally:
- try: os.unlink(outfile)
- except: pass
-
-
-Image.register_open("IPTC", IptcImageFile)
-
-Image.register_extension("IPTC", ".iim")
-
-##
-# Get IPTC information from TIFF, JPEG, or IPTC file.
-#
-# @param im An image containing IPTC data.
-# @return A dictionary containing IPTC information, or None if
-# no IPTC information block was found.
-
-def getiptcinfo(im):
-
- import TiffImagePlugin, JpegImagePlugin
- import StringIO
-
- data = None
-
- if isinstance(im, IptcImageFile):
- # return info dictionary right away
- return im.info
-
- elif isinstance(im, JpegImagePlugin.JpegImageFile):
- # extract the IPTC/NAA resource
- try:
- app = im.app["APP13"]
- if app[:14] == "Photoshop 3.0\x00":
- app = app[14:]
- # parse the image resource block
- offset = 0
- while app[offset:offset+4] == "8BIM":
- offset = offset + 4
- # resource code
- code = JpegImagePlugin.i16(app, offset)
- offset = offset + 2
- # resource name (usually empty)
- name_len = ord(app[offset])
- name = app[offset+1:offset+1+name_len]
- offset = 1 + offset + name_len
- if offset & 1:
- offset = offset + 1
- # resource data block
- size = JpegImagePlugin.i32(app, offset)
- offset = offset + 4
- if code == 0x0404:
- # 0x0404 contains IPTC/NAA data
- data = app[offset:offset+size]
- break
- offset = offset + size
- if offset & 1:
- offset = offset + 1
- except (AttributeError, KeyError):
- pass
-
- elif isinstance(im, TiffImagePlugin.TiffImageFile):
- # get raw data from the IPTC/NAA tag (PhotoShop tags the data
- # as 4-byte integers, so we cannot use the get method...)
- try:
- type, data = im.tag.tagdata[TiffImagePlugin.IPTC_NAA_CHUNK]
- except (AttributeError, KeyError):
- pass
-
- if data is None:
- return None # no properties
-
- # create an IptcImagePlugin object without initializing it
- class FakeImage:
- pass
- im = FakeImage()
- im.__class__ = IptcImageFile
-
- # parse the IPTC information chunk
- im.info = {}
- im.fp = StringIO.StringIO(data)
-
- try:
- im._open()
- except (IndexError, KeyError):
- pass # expected failure
-
- return im.info
diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py
deleted file mode 100644
index b8ba8e4..0000000
--- a/PIL/JpegImagePlugin.py
+++ /dev/null
@@ -1,430 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: JpegImagePlugin.py 2763 2006-06-22 21:43:28Z fredrik $
-#
-# JPEG (JFIF) file handling
-#
-# See "Digital Compression and Coding of Continous-Tone Still Images,
-# Part 1, Requirements and Guidelines" (CCITT T.81 / ISO 10918-1)
-#
-# History:
-# 1995-09-09 fl Created
-# 1995-09-13 fl Added full parser
-# 1996-03-25 fl Added hack to use the IJG command line utilities
-# 1996-05-05 fl Workaround Photoshop 2.5 CMYK polarity bug
-# 1996-05-28 fl Added draft support, JFIF version (0.1)
-# 1996-12-30 fl Added encoder options, added progression property (0.2)
-# 1997-08-27 fl Save mode 1 images as BW (0.3)
-# 1998-07-12 fl Added YCbCr to draft and save methods (0.4)
-# 1998-10-19 fl Don't hang on files using 16-bit DQT's (0.4.1)
-# 2001-04-16 fl Extract DPI settings from JFIF files (0.4.2)
-# 2002-07-01 fl Skip pad bytes before markers; identify Exif files (0.4.3)
-# 2003-04-25 fl Added experimental EXIF decoder (0.5)
-# 2003-06-06 fl Added experimental EXIF GPSinfo decoder
-# 2003-09-13 fl Extract COM markers
-#
-# Copyright (c) 1997-2003 by Secret Labs AB.
-# Copyright (c) 1995-1996 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.5"
-
-import array, string
-import Image, ImageFile
-
-def i16(c,o=0):
- return ord(c[o+1]) + (ord(c[o])<<8)
-
-def i32(c,o=0):
- return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24)
-
-#
-# Parser
-
-def Skip(self, marker):
- n = i16(self.fp.read(2))-2
- ImageFile._safe_read(self.fp, n)
-
-def APP(self, marker):
- #
- # Application marker. Store these in the APP dictionary.
- # Also look for well-known application markers.
-
- n = i16(self.fp.read(2))-2
- s = ImageFile._safe_read(self.fp, n)
-
- app = "APP%d" % (marker&15)
-
- self.app[app] = s # compatibility
- self.applist.append((app, s))
-
- if marker == 0xFFE0 and s[:4] == "JFIF":
- # extract JFIF information
- self.info["jfif"] = version = i16(s, 5) # version
- self.info["jfif_version"] = divmod(version, 256)
- # extract JFIF properties
- try:
- jfif_unit = ord(s[7])
- jfif_density = i16(s, 8), i16(s, 10)
- except:
- pass
- else:
- if jfif_unit == 1:
- self.info["dpi"] = jfif_density
- self.info["jfif_unit"] = jfif_unit
- self.info["jfif_density"] = jfif_density
- elif marker == 0xFFE1 and s[:5] == "Exif\0":
- # extract Exif information (incomplete)
- self.info["exif"] = s # FIXME: value will change
- elif marker == 0xFFE2 and s[:5] == "FPXR\0":
- # extract FlashPix information (incomplete)
- self.info["flashpix"] = s # FIXME: value will change
- elif marker == 0xFFEE and s[:5] == "Adobe":
- self.info["adobe"] = i16(s, 5)
- # extract Adobe custom properties
- try:
- adobe_transform = ord(s[1])
- except:
- pass
- else:
- self.info["adobe_transform"] = adobe_transform
-
-def COM(self, marker):
- #
- # Comment marker. Store these in the APP dictionary.
-
- n = i16(self.fp.read(2))-2
- s = ImageFile._safe_read(self.fp, n)
-
- self.app["COM"] = s # compatibility
- self.applist.append(("COM", s))
-
-def SOF(self, marker):
- #
- # Start of frame marker. Defines the size and mode of the
- # image. JPEG is colour blind, so we use some simple
- # heuristics to map the number of layers to an appropriate
- # mode. Note that this could be made a bit brighter, by
- # looking for JFIF and Adobe APP markers.
-
- n = i16(self.fp.read(2))-2
- s = ImageFile._safe_read(self.fp, n)
- self.size = i16(s[3:]), i16(s[1:])
-
- self.bits = ord(s[0])
- if self.bits != 8:
- raise SyntaxError("cannot handle %d-bit layers" % self.bits)
-
- self.layers = ord(s[5])
- if self.layers == 1:
- self.mode = "L"
- elif self.layers == 3:
- self.mode = "RGB"
- elif self.layers == 4:
- self.mode = "CMYK"
- else:
- raise SyntaxError("cannot handle %d-layer images" % self.layers)
-
- if marker in [0xFFC2, 0xFFC6, 0xFFCA, 0xFFCE]:
- self.info["progression"] = 1
-
- for i in range(6, len(s), 3):
- t = s[i:i+3]
- # 4-tuples: id, vsamp, hsamp, qtable
- self.layer.append((t[0], ord(t[1])/16, ord(t[1])&15, ord(t[2])))
-
-def DQT(self, marker):
- #
- # Define quantization table. Support baseline 8-bit tables
- # only. Note that there might be more than one table in
- # each marker.
-
- # FIXME: The quantization tables can be used to estimate the
- # compression quality.
-
- n = i16(self.fp.read(2))-2
- s = ImageFile._safe_read(self.fp, n)
- while len(s):
- if len(s) < 65:
- raise SyntaxError("bad quantization table marker")
- v = ord(s[0])
- if v/16 == 0:
- self.quantization[v&15] = array.array("b", s[1:65])
- s = s[65:]
- else:
- return # FIXME: add code to read 16-bit tables!
- # raise SyntaxError, "bad quantization table element size"
-
-
-#
-# JPEG marker table
-
-MARKER = {
- 0xFFC0: ("SOF0", "Baseline DCT", SOF),
- 0xFFC1: ("SOF1", "Extended Sequential DCT", SOF),
- 0xFFC2: ("SOF2", "Progressive DCT", SOF),
- 0xFFC3: ("SOF3", "Spatial lossless", SOF),
- 0xFFC4: ("DHT", "Define Huffman table", Skip),
- 0xFFC5: ("SOF5", "Differential sequential DCT", SOF),
- 0xFFC6: ("SOF6", "Differential progressive DCT", SOF),
- 0xFFC7: ("SOF7", "Differential spatial", SOF),
- 0xFFC8: ("JPG", "Extension", None),
- 0xFFC9: ("SOF9", "Extended sequential DCT (AC)", SOF),
- 0xFFCA: ("SOF10", "Progressive DCT (AC)", SOF),
- 0xFFCB: ("SOF11", "Spatial lossless DCT (AC)", SOF),
- 0xFFCC: ("DAC", "Define arithmetic coding conditioning", Skip),
- 0xFFCD: ("SOF13", "Differential sequential DCT (AC)", SOF),
- 0xFFCE: ("SOF14", "Differential progressive DCT (AC)", SOF),
- 0xFFCF: ("SOF15", "Differential spatial (AC)", SOF),
- 0xFFD0: ("RST0", "Restart 0", None),
- 0xFFD1: ("RST1", "Restart 1", None),
- 0xFFD2: ("RST2", "Restart 2", None),
- 0xFFD3: ("RST3", "Restart 3", None),
- 0xFFD4: ("RST4", "Restart 4", None),
- 0xFFD5: ("RST5", "Restart 5", None),
- 0xFFD6: ("RST6", "Restart 6", None),
- 0xFFD7: ("RST7", "Restart 7", None),
- 0xFFD8: ("SOI", "Start of image", None),
- 0xFFD9: ("EOI", "End of image", None),
- 0xFFDA: ("SOS", "Start of scan", Skip),
- 0xFFDB: ("DQT", "Define quantization table", DQT),
- 0xFFDC: ("DNL", "Define number of lines", Skip),
- 0xFFDD: ("DRI", "Define restart interval", Skip),
- 0xFFDE: ("DHP", "Define hierarchical progression", SOF),
- 0xFFDF: ("EXP", "Expand reference component", Skip),
- 0xFFE0: ("APP0", "Application segment 0", APP),
- 0xFFE1: ("APP1", "Application segment 1", APP),
- 0xFFE2: ("APP2", "Application segment 2", APP),
- 0xFFE3: ("APP3", "Application segment 3", APP),
- 0xFFE4: ("APP4", "Application segment 4", APP),
- 0xFFE5: ("APP5", "Application segment 5", APP),
- 0xFFE6: ("APP6", "Application segment 6", APP),
- 0xFFE7: ("APP7", "Application segment 7", APP),
- 0xFFE8: ("APP8", "Application segment 8", APP),
- 0xFFE9: ("APP9", "Application segment 9", APP),
- 0xFFEA: ("APP10", "Application segment 10", APP),
- 0xFFEB: ("APP11", "Application segment 11", APP),
- 0xFFEC: ("APP12", "Application segment 12", APP),
- 0xFFED: ("APP13", "Application segment 13", APP),
- 0xFFEE: ("APP14", "Application segment 14", APP),
- 0xFFEF: ("APP15", "Application segment 15", APP),
- 0xFFF0: ("JPG0", "Extension 0", None),
- 0xFFF1: ("JPG1", "Extension 1", None),
- 0xFFF2: ("JPG2", "Extension 2", None),
- 0xFFF3: ("JPG3", "Extension 3", None),
- 0xFFF4: ("JPG4", "Extension 4", None),
- 0xFFF5: ("JPG5", "Extension 5", None),
- 0xFFF6: ("JPG6", "Extension 6", None),
- 0xFFF7: ("JPG7", "Extension 7", None),
- 0xFFF8: ("JPG8", "Extension 8", None),
- 0xFFF9: ("JPG9", "Extension 9", None),
- 0xFFFA: ("JPG10", "Extension 10", None),
- 0xFFFB: ("JPG11", "Extension 11", None),
- 0xFFFC: ("JPG12", "Extension 12", None),
- 0xFFFD: ("JPG13", "Extension 13", None),
- 0xFFFE: ("COM", "Comment", COM)
-}
-
-
-def _accept(prefix):
- return prefix[0] == "\377"
-
-##
-# Image plugin for JPEG and JFIF images.
-
-class JpegImageFile(ImageFile.ImageFile):
-
- format = "JPEG"
- format_description = "JPEG (ISO 10918)"
-
- def _open(self):
-
- s = self.fp.read(1)
-
- if ord(s[0]) != 255:
- raise SyntaxError("not a JPEG file")
-
- # Create attributes
- self.bits = self.layers = 0
-
- # JPEG specifics (internal)
- self.layer = []
- self.huffman_dc = {}
- self.huffman_ac = {}
- self.quantization = {}
- self.app = {} # compatibility
- self.applist = []
-
- while 1:
-
- s = s + self.fp.read(1)
-
- i = i16(s)
-
- if MARKER.has_key(i):
- name, description, handler = MARKER[i]
- # print hex(i), name, description
- if handler is not None:
- handler(self, i)
- if i == 0xFFDA: # start of scan
- rawmode = self.mode
- if self.mode == "CMYK":
- rawmode = "CMYK;I"
- self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))]
- # self.__offset = self.fp.tell()
- break
- s = self.fp.read(1)
- elif i == 0 or i == 65535:
- # padded marker or junk; move on
- s = "\xff"
- else:
- raise SyntaxError("no marker found")
-
- def draft(self, mode, size):
-
- if len(self.tile) != 1:
- return
-
- d, e, o, a = self.tile[0]
- scale = 0
-
- if a[0] == "RGB" and mode in ["L", "YCbCr"]:
- self.mode = mode
- a = mode, ""
-
- if size:
- scale = max(self.size[0] / size[0], self.size[1] / size[1])
- for s in [8, 4, 2, 1]:
- if scale >= s:
- break
- e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1]
- self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s)
- scale = s
-
- self.tile = [(d, e, o, a)]
- self.decoderconfig = (scale, 1)
-
- return self
-
- def load_djpeg(self):
-
- # ALTERNATIVE: handle JPEGs via the IJG command line utilities
-
- import tempfile, os
- file = tempfile.mktemp()
- os.system("djpeg %s >%s" % (self.filename, file))
-
- try:
- self.im = Image.core.open_ppm(file)
- finally:
- try: os.unlink(file)
- except: pass
-
- self.mode = self.im.mode
- self.size = self.im.size
-
- self.tile = []
-
- def _getexif(self):
- # Extract EXIF information. This method is highly experimental,
- # and is likely to be replaced with something better in a future
- # version.
- import TiffImagePlugin, StringIO
- def fixup(value):
- if len(value) == 1:
- return value[0]
- return value
- # The EXIF record consists of a TIFF file embedded in a JPEG
- # application marker (!).
- try:
- data = self.info["exif"]
- except KeyError:
- return None
- file = StringIO.StringIO(data[6:])
- head = file.read(8)
- exif = {}
- # process dictionary
- info = TiffImagePlugin.ImageFileDirectory(head)
- info.load(file)
- for key, value in info.items():
- exif[key] = fixup(value)
- # get exif extension
- file.seek(exif[0x8769])
- info = TiffImagePlugin.ImageFileDirectory(head)
- info.load(file)
- for key, value in info.items():
- exif[key] = fixup(value)
- # get gpsinfo extension
- try:
- file.seek(exif[0x8825])
- except KeyError:
- pass
- else:
- info = TiffImagePlugin.ImageFileDirectory(head)
- info.load(file)
- exif[0x8825] = gps = {}
- for key, value in info.items():
- gps[key] = fixup(value)
- return exif
-
-# --------------------------------------------------------------------
-# stuff to save JPEG files
-
-RAWMODE = {
- "1": "L",
- "L": "L",
- "RGB": "RGB",
- "RGBA": "RGB",
- "RGBX": "RGB",
- "CMYK": "CMYK;I",
- "YCbCr": "YCbCr",
-}
-
-def _save(im, fp, filename):
-
- try:
- rawmode = RAWMODE[im.mode]
- except KeyError:
- raise IOError("cannot write mode %s as JPEG" % im.mode)
-
- info = im.encoderinfo
-
- dpi = info.get("dpi", (0, 0))
-
- # get keyword arguments
- im.encoderconfig = (
- info.get("quality", 0),
- # "progressive" is the official name, but older documentation
- # says "progression"
- # FIXME: issue a warning if the wrong form is used (post-1.1.5)
- info.has_key("progressive") or info.has_key("progression"),
- info.get("smooth", 0),
- info.has_key("optimize"),
- info.get("streamtype", 0),
- dpi[0], dpi[1]
- )
-
- ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
-
-def _save_cjpeg(im, fp, filename):
- # ALTERNATIVE: handle JPEGs via the IJG command line utilities.
- import os
- file = im._dump()
- os.system("cjpeg %s >%s" % (file, filename))
- try: os.unlink(file)
- except: pass
-
-# -------------------------------------------------------------------q-
-# Registry stuff
-
-Image.register_open("JPEG", JpegImageFile, _accept)
-Image.register_save("JPEG", _save)
-
-Image.register_extension("JPEG", ".jfif")
-Image.register_extension("JPEG", ".jpe")
-Image.register_extension("JPEG", ".jpg")
-Image.register_extension("JPEG", ".jpeg")
-
-Image.register_mime("JPEG", "image/jpeg")
diff --git a/PIL/McIdasImagePlugin.py b/PIL/McIdasImagePlugin.py
deleted file mode 100644
index b3b48ec..0000000
--- a/PIL/McIdasImagePlugin.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: McIdasImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# Basic McIdas support for PIL
-#
-# History:
-# 97-05-05 fl Created (8-bit images only)
-#
-# Thanks to Richard Jones <richard.jones@bom.gov.au> for specs
-# and samples.
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1997.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.1"
-
-import string
-
-import Image, ImageFile
-
-def i16(c,i=0):
- return ord(c[1+i])+(ord(c[i])<<8)
-
-def i32(c,i=0):
- return ord(c[3+i])+(ord(c[2+i])<<8)+(ord(c[1+i])<<16)+(ord(c[i])<<24)
-
-def _accept(s):
- return i32(s) == 0 and i32(s, 4) == 4
-
-##
-# Image plugin for McIdas area images.
-
-class McIdasImageFile(ImageFile.ImageFile):
-
- format = "MCIDAS"
- format_description = "McIdas area file"
-
- def _open(self):
-
- # parse area file directory
- s = self.fp.read(256)
- if not _accept(s):
- raise SyntaxError, "not an McIdas area file"
-
- # get mode
- if i32(s, 40) != 1 or i32(s, 52) != 1:
- raise SyntaxError, "unsupported McIdas format"
-
- self.mode = "L"
-
- # get size
- self.size = i32(s, 36), i32(s, 32)
-
- # setup image descriptor
- prefix = i32(s, 56)
- offset = i32(s, 132)
-
- self.tile = [("raw", (0, 0) + self.size, offset,
- ("L", prefix + self.size[0], 1))]
-
- # FIXME: should store the navigation and calibration blocks
- # somewhere (or perhaps extract some basic information from
- # them...)
-
-# --------------------------------------------------------------------
-# registry
-
-Image.register_open("MCIDAS", McIdasImageFile, _accept)
-
-# no default extension
diff --git a/PIL/MicImagePlugin.py b/PIL/MicImagePlugin.py
deleted file mode 100644
index b7b108e..0000000
--- a/PIL/MicImagePlugin.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: MicImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# Microsoft Image Composer support for PIL
-#
-# Notes:
-# uses TiffImagePlugin.py to read the actual image streams
-#
-# History:
-# 97-01-20 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1997.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.1"
-
-import string
-
-import Image, TiffImagePlugin
-from OleFileIO import *
-
-
-#
-# --------------------------------------------------------------------
-
-
-def _accept(prefix):
- return prefix[:8] == MAGIC
-
-##
-# Image plugin for Microsoft's Image Composer file format.
-
-class MicImageFile(TiffImagePlugin.TiffImageFile):
-
- format = "MIC"
- format_description = "Microsoft Image Composer"
-
- def _open(self):
-
- # read the OLE directory and see if this is a likely
- # to be a Microsoft Image Composer file
-
- try:
- self.ole = OleFileIO(self.fp)
- except IOError:
- raise SyntaxError, "not an MIC file; invalid OLE file"
-
- # find ACI subfiles with Image members (maybe not the
- # best way to identify MIC files, but what the... ;-)
-
- self.images = []
- for file in self.ole.listdir():
- if file[1:] and file[0][-4:] == ".ACI" and file[1] == "Image":
- self.images.append(file)
-
- # if we didn't find any images, this is probably not
- # an MIC file.
- if not self.images:
- raise SyntaxError, "not an MIC file; no image entries"
-
- self.__fp = self.fp
- self.frame = 0
-
- if len(self.images) > 1:
- self.category = Image.CONTAINER
-
- self.seek(0)
-
- def seek(self, frame):
-
- try:
- filename = self.images[frame]
- except IndexError:
- raise EOFError, "no such frame"
-
- self.fp = self.ole.openstream(filename)
-
- TiffImagePlugin.TiffImageFile._open(self)
-
- self.frame = frame
-
- def tell(self):
-
- return self.frame
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("MIC", MicImageFile, _accept)
-
-Image.register_extension("MIC", ".mic")
diff --git a/PIL/MpegImagePlugin.py b/PIL/MpegImagePlugin.py
deleted file mode 100644
index 9623c7a..0000000
--- a/PIL/MpegImagePlugin.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: MpegImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# MPEG file handling
-#
-# History:
-# 95-09-09 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1995.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.1"
-
-import array, string
-import Image, ImageFile
-
-#
-# Bitstream parser
-
-class BitStream:
-
- def __init__(self, fp):
- self.fp = fp
- self.bits = 0
- self.bitbuffer = 0
-
- def next(self):
- return ord(self.fp.read(1))
-
- def peek(self, bits):
- while self.bits < bits:
- c = self.next()
- if c < 0:
- self.bits = 0
- continue
- self.bitbuffer = (self.bitbuffer << 8) + c
- self.bits = self.bits + 8
- return self.bitbuffer >> (self.bits - bits) & (1L << bits) - 1
-
- def skip(self, bits):
- while self.bits < bits:
- self.bitbuffer = (self.bitbuffer << 8) + ord(self.fp.read(1))
- self.bits = self.bits + 8
- self.bits = self.bits - bits
-
- def read(self, bits):
- v = self.peek(bits)
- self.bits = self.bits - bits
- return v
-
-##
-# Image plugin for MPEG streams. This plugin can identify a stream,
-# but it cannot read it.
-
-class MpegImageFile(ImageFile.ImageFile):
-
- format = "MPEG"
- format_description = "MPEG"
-
- def _open(self):
-
- s = BitStream(self.fp)
-
- if s.read(32) != 0x1B3:
- raise SyntaxError, "not an MPEG file"
-
- self.mode = "RGB"
- self.size = s.read(12), s.read(12)
-
-
-# --------------------------------------------------------------------
-# Registry stuff
-
-Image.register_open("MPEG", MpegImageFile)
-
-Image.register_extension("MPEG", ".mpg")
-Image.register_extension("MPEG", ".mpeg")
-
-Image.register_mime("MPEG", "video/mpeg")
diff --git a/PIL/MspImagePlugin.py b/PIL/MspImagePlugin.py
deleted file mode 100644
index 40aac19..0000000
--- a/PIL/MspImagePlugin.py
+++ /dev/null
@@ -1,103 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: MspImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# MSP file handling
-#
-# This is the format used by the Paint program in Windows 1 and 2.
-#
-# History:
-# 95-09-05 fl Created
-# 97-01-03 fl Read/write MSP images
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1995-97.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.1"
-
-import Image, ImageFile
-
-
-#
-# read MSP files
-
-def i16(c):
- return ord(c[0]) + (ord(c[1])<<8)
-
-def _accept(prefix):
- return prefix[:4] in ["DanM", "LinS"]
-
-##
-# Image plugin for Windows MSP images. This plugin supports both
-# uncompressed (Windows 1.0).
-
-class MspImageFile(ImageFile.ImageFile):
-
- format = "MSP"
- format_description = "Windows Paint"
-
- def _open(self):
-
- # Header
- s = self.fp.read(32)
- if s[:4] not in ["DanM", "LinS"]:
- raise SyntaxError, "not an MSP file"
-
- # Header checksum
- sum = 0
- for i in range(0, 32, 2):
- sum = sum ^ i16(s[i:i+2])
- if sum != 0:
- raise SyntaxError, "bad MSP checksum"
-
- self.mode = "1"
- self.size = i16(s[4:]), i16(s[6:])
-
- if s[:4] == "DanM":
- self.tile = [("raw", (0,0)+self.size, 32, ("1", 0, 1))]
- else:
- self.tile = [("msp", (0,0)+self.size, 32+2*self.size[1], None)]
-
-#
-# write MSP files (uncompressed only)
-
-def o16(i):
- return chr(i&255) + chr(i>>8&255)
-
-def _save(im, fp, filename):
-
- if im.mode != "1":
- raise IOError, "cannot write mode %s as MSP" % im.mode
-
- # create MSP header
- header = [0] * 16
-
- header[0], header[1] = i16("Da"), i16("nM") # version 1
- header[2], header[3] = im.size
- header[4], header[5] = 1, 1
- header[6], header[7] = 1, 1
- header[8], header[9] = im.size
-
- sum = 0
- for h in header:
- sum = sum ^ h
- header[12] = sum # FIXME: is this the right field?
-
- # header
- for h in header:
- fp.write(o16(h))
-
- # image body
- ImageFile._save(im, fp, [("raw", (0,0)+im.size, 32, ("1", 0, 1))])
-
-#
-# registry
-
-Image.register_open("MSP", MspImageFile, _accept)
-Image.register_save("MSP", _save)
-
-Image.register_extension("MSP", ".msp")
diff --git a/PIL/OleFileIO.py b/PIL/OleFileIO.py
deleted file mode 100644
index 9383eca..0000000
--- a/PIL/OleFileIO.py
+++ /dev/null
@@ -1,528 +0,0 @@
-#
-# THIS IS WORK IN PROGRESS
-#
-# The Python Imaging Library
-# $Id: OleFileIO.py 2339 2005-03-25 08:02:17Z fredrik $
-#
-# stuff to deal with OLE2 Structured Storage files. this module is
-# used by PIL to read Image Composer and FlashPix files, but can also
-# be used to read other files of this type.
-#
-# History:
-# 1997-01-20 fl Created
-# 1997-01-22 fl Fixed 64-bit portability quirk
-# 2003-09-09 fl Fixed typo in OleFileIO.loadfat (noted by Daniel Haertle)
-# 2004-02-29 fl Changed long hex constants to signed integers
-#
-# Notes:
-# FIXME: sort out sign problem (eliminate long hex constants)
-# FIXME: change filename to use "a/b/c" instead of ["a", "b", "c"]
-# FIXME: provide a glob mechanism function (using fnmatchcase)
-#
-# Literature:
-#
-# "FlashPix Format Specification, Appendix A", Kodak and Microsoft,
-# September 1996.
-#
-# Quotes:
-#
-# "If this document and functionality of the Software conflict,
-# the actual functionality of the Software represents the correct
-# functionality" -- Microsoft, in the OLE format specification
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1997.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import string, StringIO
-
-
-def i16(c, o = 0):
- return ord(c[o])+(ord(c[o+1])<<8)
-
-def i32(c, o = 0):
- return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24)
-
-
-MAGIC = '\320\317\021\340\241\261\032\341'
-
-#
-# --------------------------------------------------------------------
-# property types
-
-VT_EMPTY=0; VT_NULL=1; VT_I2=2; VT_I4=3; VT_R4=4; VT_R8=5; VT_CY=6;
-VT_DATE=7; VT_BSTR=8; VT_DISPATCH=9; VT_ERROR=10; VT_BOOL=11;
-VT_VARIANT=12; VT_UNKNOWN=13; VT_DECIMAL=14; VT_I1=16; VT_UI1=17;
-VT_UI2=18; VT_UI4=19; VT_I8=20; VT_UI8=21; VT_INT=22; VT_UINT=23;
-VT_VOID=24; VT_HRESULT=25; VT_PTR=26; VT_SAFEARRAY=27; VT_CARRAY=28;
-VT_USERDEFINED=29; VT_LPSTR=30; VT_LPWSTR=31; VT_FILETIME=64;
-VT_BLOB=65; VT_STREAM=66; VT_STORAGE=67; VT_STREAMED_OBJECT=68;
-VT_STORED_OBJECT=69; VT_BLOB_OBJECT=70; VT_CF=71; VT_CLSID=72;
-VT_VECTOR=0x1000;
-
-# map property id to name (for debugging purposes)
-
-VT = {}
-for k, v in vars().items():
- if k[:3] == "VT_":
- VT[v] = k
-
-#
-# --------------------------------------------------------------------
-# Some common document types (root.clsid fields)
-
-WORD_CLSID = "00020900-0000-0000-C000-000000000046"
-
-
-#
-# --------------------------------------------------------------------
-
-class _OleStream(StringIO.StringIO):
-
- """OLE2 Stream
-
- Returns a read-only file object which can be used to read
- the contents of a OLE stream. To open a stream, use the
- openstream method in the OleFile class.
-
- This function can be used with either ordinary streams,
- or ministreams, depending on the offset, sectorsize, and
- fat table arguments.
- """
-
- # FIXME: should store the list of sects obtained by following
- # the fat chain, and load new sectors on demand instead of
- # loading it all in one go.
-
- def __init__(self, fp, sect, size, offset, sectorsize, fat):
-
- data = []
-
- while sect != -2: # 0xFFFFFFFEL:
- fp.seek(offset + sectorsize * sect)
- data.append(fp.read(sectorsize))
- sect = fat[sect]
-
- data = string.join(data, "")
-
- # print len(data), size
-
- StringIO.StringIO.__init__(self, data[:size])
-
-#
-# --------------------------------------------------------------------
-
-# FIXME: should add a counter in here to avoid looping forever
-# if the tree is broken.
-
-class _OleDirectoryEntry:
-
- """OLE2 Directory Entry
-
- Encapsulates a stream directory entry. Note that the
- constructor builds a tree of all subentries, so we only
- have to call it with the root object.
- """
-
- def __init__(self, sidlist, sid):
-
- # store directory parameters. the caller provides
- # a complete list of directory entries, as read from
- # the directory stream.
-
- name, type, sect, size, sids, clsid = sidlist[sid]
-
- self.sid = sid
- self.name = name
- self.type = type # 1=storage 2=stream
- self.sect = sect
- self.size = size
- self.clsid = clsid
-
- # process child nodes, if any
-
- self.kids = []
-
- sid = sidlist[sid][4][2]
-
- if sid != -1:
-
- # the directory entries are organized as a red-black tree.
- # the following piece of code does an ordered traversal of
- # such a tree (at least that's what I hope ;-)
-
- stack = [self.sid]
-
- # start at leftmost position
-
- left, right, child = sidlist[sid][4]
-
- while left != -1: # 0xFFFFFFFFL:
- stack.append(sid)
- sid = left
- left, right, child = sidlist[sid][4]
-
- while sid != self.sid:
-
- self.kids.append(_OleDirectoryEntry(sidlist, sid))
-
- # try to move right
- left, right, child = sidlist[sid][4]
- if right != -1: # 0xFFFFFFFFL:
- # and then back to the left
- sid = right
- while 1:
- left, right, child = sidlist[sid][4]
- if left == -1: # 0xFFFFFFFFL:
- break
- stack.append(sid)
- sid = left
- else:
- # couldn't move right; move up instead
- while 1:
- ptr = stack[-1]
- del stack[-1]
- left, right, child = sidlist[ptr][4]
- if right != sid:
- break
- sid = right
- left, right, child = sidlist[sid][4]
- if right != ptr:
- sid = ptr
-
- # in the OLE file, entries are sorted on (length, name).
- # for convenience, we sort them on name instead.
-
- self.kids.sort()
-
- def __cmp__(self, other):
- "Compare entries by name"
-
- return cmp(self.name, other.name)
-
- def dump(self, tab = 0):
- "Dump this entry, and all its subentries (for debug purposes only)"
-
- TYPES = ["(invalid)", "(storage)", "(stream)", "(lockbytes)",
- "(property)", "(root)"]
-
- print " "*tab + repr(self.name), TYPES[self.type],
- if self.type in (2, 5):
- print self.size, "bytes",
- print
- if self.type in (1, 5) and self.clsid:
- print " "*tab + "{%s}" % self.clsid
-
- for kid in self.kids:
- kid.dump(tab + 2)
-
-#
-# --------------------------------------------------------------------
-
-##
-# This class encapsulates the interface to an OLE 2 structured
-# storage file. Use the {@link listdir} and {@link openstream}
-# methods to access the contents of this file.
-
-class OleFileIO:
- """OLE container object
-
- This class encapsulates the interface to an OLE 2 structured
- storage file. Use the listdir and openstream methods to access
- the contents of this file.
-
- Object names are given as a list of strings, one for each subentry
- level. The root entry should be omitted. For example, the following
- code extracts all image streams from a Microsoft Image Composer file:
-
- ole = OleFileIO("fan.mic")
-
- for entry in ole.listdir():
- if entry[1:2] == "Image":
- fin = ole.openstream(entry)
- fout = open(entry[0:1], "wb")
- while 1:
- s = fin.read(8192)
- if not s:
- break
- fout.write(s)
-
- You can use the viewer application provided with the Python Imaging
- Library to view the resulting files (which happens to be standard
- TIFF files).
- """
-
- def __init__(self, filename = None):
-
- if filename:
- self.open(filename)
-
- ##
- # Open an OLE2 file.
-
- def open(self, filename):
- """Open an OLE2 file"""
-
- if type(filename) == type(""):
- self.fp = open(filename, "rb")
- else:
- self.fp = filename
-
- header = self.fp.read(512)
-
- if len(header) != 512 or header[:8] != MAGIC:
- raise IOError, "not an OLE2 structured storage file"
-
- # file clsid (probably never used, so we don't store it)
- clsid = self._clsid(header[8:24])
-
- # FIXME: could check version and byte order fields
-
- self.sectorsize = 1 << i16(header, 30)
- self.minisectorsize = 1 << i16(header, 32)
-
- self.minisectorcutoff = i32(header, 56)
-
- # Load file allocation tables
- self.loadfat(header)
-
- # Load direcory. This sets both the sidlist (ordered by id)
- # and the root (ordered by hierarchy) members.
- self.loaddirectory(i32(header, 48))
-
- self.ministream = None
- self.minifatsect = i32(header, 60)
-
- def loadfat(self, header):
- # Load the FAT table. The header contains a sector numbers
- # for the first 109 FAT sectors. Additional sectors are
- # described by DIF blocks (FIXME: not yet implemented)
-
- sect = header[76:512]
- fat = []
- for i in range(0, len(sect), 4):
- ix = i32(sect, i)
- if ix == -2 or ix == -1: # ix == 0xFFFFFFFEL or ix == 0xFFFFFFFFL:
- break
- s = self.getsect(ix)
- fat = fat + map(lambda i, s=s: i32(s, i), range(0, len(s), 4))
- self.fat = fat
-
- def loadminifat(self):
- # Load the MINIFAT table. This is stored in a standard sub-
- # stream, pointed to by a header field.
-
- s = self._open(self.minifatsect).read()
-
- self.minifat = map(lambda i, s=s: i32(s, i), range(0, len(s), 4))
-
- def getsect(self, sect):
- # Read given sector
-
- self.fp.seek(512 + self.sectorsize * sect)
- return self.fp.read(self.sectorsize)
-
- def _unicode(self, s):
- # Map unicode string to Latin 1
-
- # FIXME: some day, Python will provide an official way to handle
- # Unicode strings, but until then, this will have to do...
- return filter(ord, s)
-
- def loaddirectory(self, sect):
- # Load the directory. The directory is stored in a standard
- # substream, independent of its size.
-
- # read directory stream
- fp = self._open(sect)
-
- # create list of sid entries
- self.sidlist = []
- while 1:
- entry = fp.read(128)
- if not entry:
- break
- type = ord(entry[66])
- name = self._unicode(entry[0:0+i16(entry, 64)])
- ptrs = i32(entry, 68), i32(entry, 72), i32(entry, 76)
- sect, size = i32(entry, 116), i32(entry, 120)
- clsid = self._clsid(entry[80:96])
- self.sidlist.append((name, type, sect, size, ptrs, clsid))
-
- # create hierarchical list of directory entries
- self.root = _OleDirectoryEntry(self.sidlist, 0)
-
- def dumpdirectory(self):
- # Dump directory (for debugging only)
-
- self.root.dump()
-
- def _clsid(self, clsid):
- if clsid == "\0" * len(clsid):
- return ""
- return (("%08X-%04X-%04X-%02X%02X-" + "%02X" * 6) %
- ((i32(clsid, 0), i16(clsid, 4), i16(clsid, 6)) +
- tuple(map(ord, clsid[8:16]))))
-
- def _list(self, files, prefix, node):
- # listdir helper
-
- prefix = prefix + [node.name]
- for entry in node.kids:
- if entry.kids:
- self._list(files, prefix, entry)
- else:
- files.append(prefix[1:] + [entry.name])
-
- def _find(self, filename):
- # openstream helper
-
- node = self.root
- for name in filename:
- for kid in node.kids:
- if kid.name == name:
- break
- else:
- raise IOError, "file not found"
- node = kid
- return node.sid
-
- def _open(self, start, size = 0x7FFFFFFF):
- # openstream helper.
-
- if size < self.minisectorcutoff:
- # ministream object
- if not self.ministream:
- self.loadminifat()
- self.ministream = self._open(self.sidlist[0][2])
- return _OleStream(self.ministream, start, size, 0,
- self.minisectorsize, self.minifat)
-
- # standard stream
- return _OleStream(self.fp, start, size, 512,
- self.sectorsize, self.fat)
-
- ##
- # Returns a list of streams stored in this file.
-
- def listdir(self):
- """Return a list of streams stored in this file"""
-
- files = []
- self._list(files, [], self.root)
- return files
-
- ##
- # Opens a stream as a read-only file object.
-
- def openstream(self, filename):
- """Open a stream as a read-only file object"""
-
- slot = self._find(filename)
- name, type, sect, size, sids, clsid = self.sidlist[slot]
- if type != 2:
- raise IOError, "this file is not a stream"
- return self._open(sect, size)
-
- ##
- # Gets a list of properties described in substream.
-
- def getproperties(self, filename):
- """Return properties described in substream"""
-
- fp = self.openstream(filename)
-
- data = {}
-
- # header
- s = fp.read(28)
- clsid = self._clsid(s[8:24])
-
- # format id
- s = fp.read(20)
- fmtid = self._clsid(s[:16])
- fp.seek(i32(s, 16))
-
- # get section
- s = "****" + fp.read(i32(fp.read(4))-4)
-
- for i in range(i32(s, 4)):
-
- id = i32(s, 8+i*8)
- offset = i32(s, 12+i*8)
- type = i32(s, offset)
-
- # test for common types first (should perhaps use
- # a dictionary instead?)
-
- if type == VT_I2:
- value = i16(s, offset+4)
- if value >= 32768:
- value = value - 65536
- elif type == VT_UI2:
- value = i16(s, offset+4)
- elif type in (VT_I4, VT_ERROR):
- value = i32(s, offset+4)
- elif type == VT_UI4:
- value = i32(s, offset+4) # FIXME
- elif type in (VT_BSTR, VT_LPSTR):
- count = i32(s, offset+4)
- value = s[offset+8:offset+8+count-1]
- elif type == VT_BLOB:
- count = i32(s, offset+4)
- value = s[offset+8:offset+8+count]
- elif type == VT_LPWSTR:
- count = i32(s, offset+4)
- value = self._unicode(s[offset+8:offset+8+count*2])
- elif type == VT_FILETIME:
- value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32)
- # FIXME: this is a 64-bit int: "number of 100ns periods
- # since Jan 1,1601". Should map this to Python time
- value = value / 10000000L # seconds
- elif type == VT_UI1:
- value = ord(s[offset+4])
- elif type == VT_CLSID:
- value = self._clsid(s[offset+4:offset+20])
- elif type == VT_CF:
- count = i32(s, offset+4)
- value = s[offset+8:offset+8+count]
- else:
- value = None # everything else yields "None"
-
- # FIXME: add support for VT_VECTOR
-
- #print "%08x" % id, repr(value),
- #print "(%s)" % VT[i32(s, offset) & 0xFFF]
-
- data[id] = value
-
- return data
-
-#
-# --------------------------------------------------------------------
-# This script can be used to dump the directory of any OLE2 structured
-# storage file.
-
-if __name__ == "__main__":
-
- import sys
-
- for file in sys.argv[1:]:
- try:
- ole = OleFileIO(file)
- print "-" * 68
- print file
- print "-" * 68
- ole.dumpdirectory()
- for file in ole.listdir():
- if file[-1][0] == "\005":
- print file
- props = ole.getproperties(file)
- props = props.items()
- props.sort()
- for k, v in props:
- print " ", k, v
- except IOError, v:
- print "***", "cannot read", file, "-", v
diff --git a/PIL/PSDraw.py b/PIL/PSDraw.py
deleted file mode 100644
index 7e88f55..0000000
--- a/PIL/PSDraw.py
+++ /dev/null
@@ -1,199 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: PSDraw.py 2813 2006-10-07 10:11:35Z fredrik $
-#
-# simple postscript graphics interface
-#
-# History:
-# 1996-04-20 fl Created
-# 1999-01-10 fl Added gsave/grestore to image method
-# 2005-05-04 fl Fixed floating point issue in image (from Eric Etheridge)
-#
-# Copyright (c) 1997-2005 by Secret Labs AB. All rights reserved.
-# Copyright (c) 1996 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import EpsImagePlugin
-import string
-
-##
-# Simple Postscript graphics interface.
-
-class PSDraw:
-
- def __init__(self, fp=None):
- if not fp:
- import sys
- fp = sys.stdout
- self.fp = fp
-
- def begin_document(self, id = None):
- "Write Postscript DSC header"
- # FIXME: incomplete
- self.fp.write("%!PS-Adobe-3.0\n"
- "save\n"
- "/showpage { } def\n"
- "%%EndComments\n"
- "%%BeginDocument\n")
- #self.fp.write(ERROR_PS) # debugging!
- self.fp.write(EDROFF_PS)
- self.fp.write(VDI_PS)
- self.fp.write("%%EndProlog\n")
- self.isofont = {}
-
- def end_document(self):
- "Write Postscript DSC footer"
- self.fp.write("%%EndDocument\n"
- "restore showpage\n"
- "%%End\n")
- if hasattr(self.fp, "flush"):
- self.fp.flush()
-
- def setfont(self, font, size):
- if not self.isofont.has_key(font):
- # reencode font
- self.fp.write("/PSDraw-%s ISOLatin1Encoding /%s E\n" %\
- (font, font))
- self.isofont[font] = 1
- # rough
- self.fp.write("/F0 %d /PSDraw-%s F\n" % (size, font))
-
- def setink(self, ink):
- print "*** NOT YET IMPLEMENTED ***"
-
- def line(self, xy0, xy1):
- xy = xy0 + xy1
- self.fp.write("%d %d %d %d Vl\n" % xy)
-
- def rectangle(self, box):
- self.fp.write("%d %d M %d %d 0 Vr\n" % box)
-
- def text(self, xy, text):
- text = string.joinfields(string.splitfields(text, "("), "\\(")
- text = string.joinfields(string.splitfields(text, ")"), "\\)")
- xy = xy + (text,)
- self.fp.write("%d %d M (%s) S\n" % xy)
-
- def image(self, box, im, dpi = None):
- "Write an PIL image"
- # default resolution depends on mode
- if not dpi:
- if im.mode == "1":
- dpi = 200 # fax
- else:
- dpi = 100 # greyscale
- # image size (on paper)
- x = float(im.size[0] * 72) / dpi
- y = float(im.size[1] * 72) / dpi
- # max allowed size
- xmax = float(box[2] - box[0])
- ymax = float(box[3] - box[1])
- if x > xmax:
- y = y * xmax / x; x = xmax
- if y > ymax:
- x = x * ymax / y; y = ymax
- dx = (xmax - x) / 2 + box[0]
- dy = (ymax - y) / 2 + box[1]
- self.fp.write("gsave\n%f %f translate\n" % (dx, dy))
- if (x, y) != im.size:
- # EpsImagePlugin._save prints the image at (0,0,xsize,ysize)
- sx = x / im.size[0]
- sy = y / im.size[1]
- self.fp.write("%f %f scale\n" % (sx, sy))
- EpsImagePlugin._save(im, self.fp, None, 0)
- self.fp.write("\ngrestore\n")
-
-# --------------------------------------------------------------------
-# Postscript driver
-
-#
-# EDROFF.PS -- Postscript driver for Edroff 2
-#
-# History:
-# 94-01-25 fl: created (edroff 2.04)
-#
-# Copyright (c) Fredrik Lundh 1994.
-#
-
-EDROFF_PS = """\
-/S { show } bind def
-/P { moveto show } bind def
-/M { moveto } bind def
-/X { 0 rmoveto } bind def
-/Y { 0 exch rmoveto } bind def
-/E { findfont
- dup maxlength dict begin
- {
- 1 index /FID ne { def } { pop pop } ifelse
- } forall
- /Encoding exch def
- dup /FontName exch def
- currentdict end definefont pop
-} bind def
-/F { findfont exch scalefont dup setfont
- [ exch /setfont cvx ] cvx bind def
-} bind def
-"""
-
-#
-# VDI.PS -- Postscript driver for VDI meta commands
-#
-# History:
-# 94-01-25 fl: created (edroff 2.04)
-#
-# Copyright (c) Fredrik Lundh 1994.
-#
-
-VDI_PS = """\
-/Vm { moveto } bind def
-/Va { newpath arcn stroke } bind def
-/Vl { moveto lineto stroke } bind def
-/Vc { newpath 0 360 arc closepath } bind def
-/Vr { exch dup 0 rlineto
- exch dup neg 0 exch rlineto
- exch neg 0 rlineto
- 0 exch rlineto
- 100 div setgray fill 0 setgray } bind def
-/Tm matrix def
-/Ve { Tm currentmatrix pop
- translate scale newpath 0 0 .5 0 360 arc closepath
- Tm setmatrix
-} bind def
-/Vf { currentgray exch setgray fill setgray } bind def
-"""
-
-#
-# ERROR.PS -- Error handler
-#
-# History:
-# 89-11-21 fl: created (pslist 1.10)
-#
-
-ERROR_PS = """\
-/landscape false def
-/errorBUF 200 string def
-/errorNL { currentpoint 10 sub exch pop 72 exch moveto } def
-errordict begin /handleerror {
- initmatrix /Courier findfont 10 scalefont setfont
- newpath 72 720 moveto $error begin /newerror false def
- (PostScript Error) show errorNL errorNL
- (Error: ) show
- /errorname load errorBUF cvs show errorNL errorNL
- (Command: ) show
- /command load dup type /stringtype ne { errorBUF cvs } if show
- errorNL errorNL
- (VMstatus: ) show
- vmstatus errorBUF cvs show ( bytes available, ) show
- errorBUF cvs show ( bytes used at level ) show
- errorBUF cvs show errorNL errorNL
- (Operand stargck: ) show errorNL /ostargck load {
- dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL
- } forall errorNL
- (Execution stargck: ) show errorNL /estargck load {
- dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL
- } forall
- end showpage
-} def end
-"""
diff --git a/PIL/PaletteFile.py b/PIL/PaletteFile.py
deleted file mode 100644
index bbbebfa..0000000
--- a/PIL/PaletteFile.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Python Imaging Library
-# $Id: PaletteFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# stuff to read simple, teragon-style palette files
-#
-# History:
-# 97-08-23 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1997.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import string
-
-##
-# File handler for Teragon-style palette files.
-
-class PaletteFile:
-
- rawmode = "RGB"
-
- def __init__(self, fp):
-
- self.palette = map(lambda i: (i, i, i), range(256))
-
- while 1:
-
- s = fp.readline()
-
- if not s:
- break
- if len(s) > 100:
- raise SyntaxError, "bad palette file"
-
- v = map(int, string.split(s))
- try:
- [i, r, g, b] = v
- except ValueError:
- [i, r] = v
- g = b = r
-
- if 0 <= i <= 255:
- self.palette[i] = chr(r) + chr(g) + chr(b)
-
- self.palette = string.join(self.palette, "")
-
-
- def getpalette(self):
-
- return self.palette, self.rawmode
diff --git a/PIL/PalmImagePlugin.py b/PIL/PalmImagePlugin.py
deleted file mode 100644
index 19f0c2f..0000000
--- a/PIL/PalmImagePlugin.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: PalmImagePlugin.py 2438 2005-05-25 21:09:48Z Fredrik $
-#
-
-##
-# Image plugin for Palm pixmap images (output only).
-##
-
-__version__ = "1.0"
-
-import Image, ImageFile
-import StringIO
-
-_Palm8BitColormapValues = (
- ( 255, 255, 255 ), ( 255, 204, 255 ), ( 255, 153, 255 ), ( 255, 102, 255 ),
- ( 255, 51, 255 ), ( 255, 0, 255 ), ( 255, 255, 204 ), ( 255, 204, 204 ),
- ( 255, 153, 204 ), ( 255, 102, 204 ), ( 255, 51, 204 ), ( 255, 0, 204 ),
- ( 255, 255, 153 ), ( 255, 204, 153 ), ( 255, 153, 153 ), ( 255, 102, 153 ),
- ( 255, 51, 153 ), ( 255, 0, 153 ), ( 204, 255, 255 ), ( 204, 204, 255 ),
- ( 204, 153, 255 ), ( 204, 102, 255 ), ( 204, 51, 255 ), ( 204, 0, 255 ),
- ( 204, 255, 204 ), ( 204, 204, 204 ), ( 204, 153, 204 ), ( 204, 102, 204 ),
- ( 204, 51, 204 ), ( 204, 0, 204 ), ( 204, 255, 153 ), ( 204, 204, 153 ),
- ( 204, 153, 153 ), ( 204, 102, 153 ), ( 204, 51, 153 ), ( 204, 0, 153 ),
- ( 153, 255, 255 ), ( 153, 204, 255 ), ( 153, 153, 255 ), ( 153, 102, 255 ),
- ( 153, 51, 255 ), ( 153, 0, 255 ), ( 153, 255, 204 ), ( 153, 204, 204 ),
- ( 153, 153, 204 ), ( 153, 102, 204 ), ( 153, 51, 204 ), ( 153, 0, 204 ),
- ( 153, 255, 153 ), ( 153, 204, 153 ), ( 153, 153, 153 ), ( 153, 102, 153 ),
- ( 153, 51, 153 ), ( 153, 0, 153 ), ( 102, 255, 255 ), ( 102, 204, 255 ),
- ( 102, 153, 255 ), ( 102, 102, 255 ), ( 102, 51, 255 ), ( 102, 0, 255 ),
- ( 102, 255, 204 ), ( 102, 204, 204 ), ( 102, 153, 204 ), ( 102, 102, 204 ),
- ( 102, 51, 204 ), ( 102, 0, 204 ), ( 102, 255, 153 ), ( 102, 204, 153 ),
- ( 102, 153, 153 ), ( 102, 102, 153 ), ( 102, 51, 153 ), ( 102, 0, 153 ),
- ( 51, 255, 255 ), ( 51, 204, 255 ), ( 51, 153, 255 ), ( 51, 102, 255 ),
- ( 51, 51, 255 ), ( 51, 0, 255 ), ( 51, 255, 204 ), ( 51, 204, 204 ),
- ( 51, 153, 204 ), ( 51, 102, 204 ), ( 51, 51, 204 ), ( 51, 0, 204 ),
- ( 51, 255, 153 ), ( 51, 204, 153 ), ( 51, 153, 153 ), ( 51, 102, 153 ),
- ( 51, 51, 153 ), ( 51, 0, 153 ), ( 0, 255, 255 ), ( 0, 204, 255 ),
- ( 0, 153, 255 ), ( 0, 102, 255 ), ( 0, 51, 255 ), ( 0, 0, 255 ),
- ( 0, 255, 204 ), ( 0, 204, 204 ), ( 0, 153, 204 ), ( 0, 102, 204 ),
- ( 0, 51, 204 ), ( 0, 0, 204 ), ( 0, 255, 153 ), ( 0, 204, 153 ),
- ( 0, 153, 153 ), ( 0, 102, 153 ), ( 0, 51, 153 ), ( 0, 0, 153 ),
- ( 255, 255, 102 ), ( 255, 204, 102 ), ( 255, 153, 102 ), ( 255, 102, 102 ),
- ( 255, 51, 102 ), ( 255, 0, 102 ), ( 255, 255, 51 ), ( 255, 204, 51 ),
- ( 255, 153, 51 ), ( 255, 102, 51 ), ( 255, 51, 51 ), ( 255, 0, 51 ),
- ( 255, 255, 0 ), ( 255, 204, 0 ), ( 255, 153, 0 ), ( 255, 102, 0 ),
- ( 255, 51, 0 ), ( 255, 0, 0 ), ( 204, 255, 102 ), ( 204, 204, 102 ),
- ( 204, 153, 102 ), ( 204, 102, 102 ), ( 204, 51, 102 ), ( 204, 0, 102 ),
- ( 204, 255, 51 ), ( 204, 204, 51 ), ( 204, 153, 51 ), ( 204, 102, 51 ),
- ( 204, 51, 51 ), ( 204, 0, 51 ), ( 204, 255, 0 ), ( 204, 204, 0 ),
- ( 204, 153, 0 ), ( 204, 102, 0 ), ( 204, 51, 0 ), ( 204, 0, 0 ),
- ( 153, 255, 102 ), ( 153, 204, 102 ), ( 153, 153, 102 ), ( 153, 102, 102 ),
- ( 153, 51, 102 ), ( 153, 0, 102 ), ( 153, 255, 51 ), ( 153, 204, 51 ),
- ( 153, 153, 51 ), ( 153, 102, 51 ), ( 153, 51, 51 ), ( 153, 0, 51 ),
- ( 153, 255, 0 ), ( 153, 204, 0 ), ( 153, 153, 0 ), ( 153, 102, 0 ),
- ( 153, 51, 0 ), ( 153, 0, 0 ), ( 102, 255, 102 ), ( 102, 204, 102 ),
- ( 102, 153, 102 ), ( 102, 102, 102 ), ( 102, 51, 102 ), ( 102, 0, 102 ),
- ( 102, 255, 51 ), ( 102, 204, 51 ), ( 102, 153, 51 ), ( 102, 102, 51 ),
- ( 102, 51, 51 ), ( 102, 0, 51 ), ( 102, 255, 0 ), ( 102, 204, 0 ),
- ( 102, 153, 0 ), ( 102, 102, 0 ), ( 102, 51, 0 ), ( 102, 0, 0 ),
- ( 51, 255, 102 ), ( 51, 204, 102 ), ( 51, 153, 102 ), ( 51, 102, 102 ),
- ( 51, 51, 102 ), ( 51, 0, 102 ), ( 51, 255, 51 ), ( 51, 204, 51 ),
- ( 51, 153, 51 ), ( 51, 102, 51 ), ( 51, 51, 51 ), ( 51, 0, 51 ),
- ( 51, 255, 0 ), ( 51, 204, 0 ), ( 51, 153, 0 ), ( 51, 102, 0 ),
- ( 51, 51, 0 ), ( 51, 0, 0 ), ( 0, 255, 102 ), ( 0, 204, 102 ),
- ( 0, 153, 102 ), ( 0, 102, 102 ), ( 0, 51, 102 ), ( 0, 0, 102 ),
- ( 0, 255, 51 ), ( 0, 204, 51 ), ( 0, 153, 51 ), ( 0, 102, 51 ),
- ( 0, 51, 51 ), ( 0, 0, 51 ), ( 0, 255, 0 ), ( 0, 204, 0 ),
- ( 0, 153, 0 ), ( 0, 102, 0 ), ( 0, 51, 0 ), ( 17, 17, 17 ),
- ( 34, 34, 34 ), ( 68, 68, 68 ), ( 85, 85, 85 ), ( 119, 119, 119 ),
- ( 136, 136, 136 ), ( 170, 170, 170 ), ( 187, 187, 187 ), ( 221, 221, 221 ),
- ( 238, 238, 238 ), ( 192, 192, 192 ), ( 128, 0, 0 ), ( 128, 0, 128 ),
- ( 0, 128, 0 ), ( 0, 128, 128 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
- ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
- ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
- ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
- ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
- ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
- ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ))
-
-# so build a prototype image to be used for palette resampling
-def build_prototype_image():
- image = Image.new("L", (1,len(_Palm8BitColormapValues),))
- image.putdata(range(len(_Palm8BitColormapValues)))
- palettedata = ()
- for i in range(len(_Palm8BitColormapValues)):
- palettedata = palettedata + _Palm8BitColormapValues[i]
- for i in range(256 - len(_Palm8BitColormapValues)):
- palettedata = palettedata + (0, 0, 0)
- image.putpalette(palettedata)
- return image
-
-Palm8BitColormapImage = build_prototype_image()
-
-# OK, we now have in Palm8BitColormapImage, a "P"-mode image with the right palette
-#
-# --------------------------------------------------------------------
-
-_FLAGS = {
- "custom-colormap": 0x4000,
- "is-compressed": 0x8000,
- "has-transparent": 0x2000,
- }
-
-_COMPRESSION_TYPES = {
- "none": 0xFF,
- "rle": 0x01,
- "scanline": 0x00,
- }
-
-def o16b(i):
- return chr(i>>8&255) + chr(i&255)
-
-#
-# --------------------------------------------------------------------
-
-##
-# (Internal) Image save plugin for the Palm format.
-
-def _save(im, fp, filename, check=0):
-
- if im.mode == "P":
-
- # we assume this is a color Palm image with the standard colormap,
- # unless the "info" dict has a "custom-colormap" field
-
- rawmode = "P"
- bpp = 8
- version = 1
-
- elif im.mode == "L" and im.encoderinfo.has_key("bpp") and im.encoderinfo["bpp"] in (1, 2, 4):
-
- # this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because
- # Palm does greyscale from white (0) to black (1)
- bpp = im.encoderinfo["bpp"]
- im = im.point(lambda x, shift=8-bpp, maxval=(1 << bpp)-1: maxval - (x >> shift))
- # we ignore the palette here
- im.mode = "P"
- rawmode = "P;" + str(bpp)
- version = 1
-
- elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2, 4):
-
- # here we assume that even though the inherent mode is 8-bit grayscale, only
- # the lower bpp bits are significant. We invert them to match the Palm.
- bpp = im.info["bpp"]
- im = im.point(lambda x, maxval=(1 << bpp)-1: maxval - (x & maxval))
- # we ignore the palette here
- im.mode = "P"
- rawmode = "P;" + str(bpp)
- version = 1
-
- elif im.mode == "1":
-
- # monochrome -- write it inverted, as is the Palm standard
- rawmode = "1;I"
- bpp = 1
- version = 0
-
- else:
-
- raise IOError, "cannot write mode %s as Palm" % im.mode
-
- if check:
- return check
-
- #
- # make sure image data is available
- im.load()
-
- # write header
-
- cols = im.size[0]
- rows = im.size[1]
-
- rowbytes = ((cols + (16/bpp - 1)) / (16 / bpp)) * 2;
- transparent_index = 0
- compression_type = _COMPRESSION_TYPES["none"]
-
- flags = 0;
- if im.mode == "P" and im.info.has_key("custom-colormap"):
- flags = flags & _FLAGS["custom-colormap"]
- colormapsize = 4 * 256 + 2;
- colormapmode = im.palette.mode
- colormap = im.getdata().getpalette()
- else:
- colormapsize = 0
-
- if im.info.has_key("offset"):
- offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4;
- else:
- offset = 0
-
- fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags))
- fp.write(chr(bpp))
- fp.write(chr(version))
- fp.write(o16b(offset))
- fp.write(chr(transparent_index))
- fp.write(chr(compression_type))
- fp.write(o16b(0)) # reserved by Palm
-
- # now write colormap if necessary
-
- if colormapsize > 0:
- fp.write(o16b(256))
- for i in range(256):
- fp.write(chr(i))
- if colormapmode == 'RGB':
- fp.write(chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2]))
- elif colormapmode == 'RGBA':
- fp.write(chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2]))
-
- # now convert data to raw form
- ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))])
-
- fp.flush()
-
-
-#
-# --------------------------------------------------------------------
-
-Image.register_save("Palm", _save)
-
-Image.register_extension("Palm", ".palm")
-
-Image.register_mime("Palm", "image/palm")
diff --git a/PIL/PcdImagePlugin.py b/PIL/PcdImagePlugin.py
deleted file mode 100644
index 957da24..0000000
--- a/PIL/PcdImagePlugin.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: PcdImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# PCD file handling
-#
-# History:
-# 96-05-10 fl Created
-# 96-05-27 fl Added draft mode (128x192, 256x384)
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.1"
-
-
-import Image, ImageFile
-
-##
-# Image plugin for PhotoCD images. This plugin only reads the 768x512
-# image from the file; higher resolutions are encoded in a proprietary
-# encoding.
-
-class PcdImageFile(ImageFile.ImageFile):
-
- format = "PCD"
- format_description = "Kodak PhotoCD"
-
- def _open(self):
-
- # rough
- self.fp.seek(2048)
- s = self.fp.read(2048)
-
- if s[:4] != "PCD_":
- raise SyntaxError, "not a PCD file"
-
- orientation = ord(s[1538]) & 3
- if orientation == 1:
- self.tile_post_rotate = 90 # hack
- elif orientation == 3:
- self.tile_post_rotate = -90
-
- self.mode = "RGB"
- self.size = 768, 512 # FIXME: not correct for rotated images!
- self.tile = [("pcd", (0,0)+self.size, 96*2048, None)]
-
- def draft(self, mode, size):
-
- if len(self.tile) != 1:
- return
-
- d, e, o, a = self.tile[0]
-
- if size:
- scale = max(self.size[0] / size[0], self.size[1] / size[1])
- for s, o in [(4,0*2048), (2,0*2048), (1,96*2048)]:
- if scale >= s:
- break
- # e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1]
- # self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s)
-
- self.tile = [(d, e, o, a)]
-
- return self
-
-#
-# registry
-
-Image.register_open("PCD", PcdImageFile)
-
-Image.register_extension("PCD", ".pcd")
diff --git a/PIL/PcfFontFile.py b/PIL/PcfFontFile.py
deleted file mode 100644
index 9a689b2..0000000
--- a/PIL/PcfFontFile.py
+++ /dev/null
@@ -1,256 +0,0 @@
-#
-# THIS IS WORK IN PROGRESS
-#
-# The Python Imaging Library
-# $Id: PcfFontFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# portable compiled font file parser
-#
-# history:
-# 1997-08-19 fl created
-# 2003-09-13 fl fixed loading of unicode fonts
-#
-# Copyright (c) 1997-2003 by Secret Labs AB.
-# Copyright (c) 1997-2003 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import FontFile
-
-import string
-
-# --------------------------------------------------------------------
-# declarations
-
-PCF_MAGIC = 0x70636601 # "\x01fcp"
-
-PCF_PROPERTIES = (1<<0)
-PCF_ACCELERATORS = (1<<1)
-PCF_METRICS = (1<<2)
-PCF_BITMAPS = (1<<3)
-PCF_INK_METRICS = (1<<4)
-PCF_BDF_ENCODINGS = (1<<5)
-PCF_SWIDTHS = (1<<6)
-PCF_GLYPH_NAMES = (1<<7)
-PCF_BDF_ACCELERATORS = (1<<8)
-
-BYTES_PER_ROW = [
- lambda bits: ((bits+7) >> 3),
- lambda bits: ((bits+15) >> 3) & ~1,
- lambda bits: ((bits+31) >> 3) & ~3,
- lambda bits: ((bits+63) >> 3) & ~7,
-]
-
-
-def l16(c):
- return ord(c[0]) + (ord(c[1])<<8)
-def l32(c):
- return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
-
-def b16(c):
- return ord(c[1]) + (ord(c[0])<<8)
-def b32(c):
- return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
-
-def sz(s, o):
- return s[o:string.index(s, "\0", o)]
-
-##
-# Font file plugin for the X11 PCF format.
-
-class PcfFontFile(FontFile.FontFile):
-
- name = "name"
-
- def __init__(self, fp):
-
- magic = l32(fp.read(4))
- if magic != PCF_MAGIC:
- raise SyntaxError, "not a PCF file"
-
- FontFile.FontFile.__init__(self)
-
- count = l32(fp.read(4))
- self.toc = {}
- for i in range(count):
- type = l32(fp.read(4))
- self.toc[type] = l32(fp.read(4)), l32(fp.read(4)), l32(fp.read(4))
-
- self.fp = fp
-
- self.info = self._load_properties()
-
- metrics = self._load_metrics()
- bitmaps = self._load_bitmaps(metrics)
- encoding = self._load_encoding()
-
- #
- # create glyph structure
-
- for ch in range(256):
- ix = encoding[ch]
- if ix is not None:
- x, y, l, r, w, a, d, f = metrics[ix]
- glyph = (w, 0), (l, d-y, x+l, d), (0, 0, x, y), bitmaps[ix]
- self.glyph[ch] = glyph
-
- def _getformat(self, tag):
-
- format, size, offset = self.toc[tag]
-
- fp = self.fp
- fp.seek(offset)
-
- format = l32(fp.read(4))
-
- if format & 4:
- i16, i32 = b16, b32
- else:
- i16, i32 = l16, l32
-
- return fp, format, i16, i32
-
- def _load_properties(self):
-
- #
- # font properties
-
- properties = {}
-
- fp, format, i16, i32 = self._getformat(PCF_PROPERTIES)
-
- nprops = i32(fp.read(4))
-
- # read property description
- p = []
- for i in range(nprops):
- p.append((i32(fp.read(4)), ord(fp.read(1)), i32(fp.read(4))))
- if nprops & 3:
- fp.seek(4 - (nprops & 3), 1) # pad
-
- data = fp.read(i32(fp.read(4)))
-
- for k, s, v in p:
- k = sz(data, k)
- if s:
- v = sz(data, v)
- properties[k] = v
-
- return properties
-
- def _load_metrics(self):
-
- #
- # font metrics
-
- metrics = []
-
- fp, format, i16, i32 = self._getformat(PCF_METRICS)
-
- append = metrics.append
-
- if (format & 0xff00) == 0x100:
-
- # "compressed" metrics
- for i in range(i16(fp.read(2))):
- left = ord(fp.read(1)) - 128
- right = ord(fp.read(1)) - 128
- width = ord(fp.read(1)) - 128
- ascent = ord(fp.read(1)) - 128
- descent = ord(fp.read(1)) - 128
- xsize = right - left
- ysize = ascent + descent
- append(
- (xsize, ysize, left, right, width,
- ascent, descent, 0)
- )
-
- else:
-
- # "jumbo" metrics
- for i in range(i32(fp.read(4))):
- left = i16(fp.read(2))
- right = i16(fp.read(2))
- width = i16(fp.read(2))
- ascent = i16(fp.read(2))
- descent = i16(fp.read(2))
- attributes = i16(fp.read(2))
- xsize = right - left
- ysize = ascent + descent
- append(
- (xsize, ysize, left, right, width,
- ascent, descent, attributes)
- )
-
- return metrics
-
- def _load_bitmaps(self, metrics):
-
- #
- # bitmap data
-
- bitmaps = []
-
- fp, format, i16, i32 = self._getformat(PCF_BITMAPS)
-
- nbitmaps = i32(fp.read(4))
-
- if nbitmaps != len(metrics):
- raise IOError, "Wrong number of bitmaps"
-
- offsets = []
- for i in range(nbitmaps):
- offsets.append(i32(fp.read(4)))
-
- bitmapSizes = []
- for i in range(4):
- bitmapSizes.append(i32(fp.read(4)))
-
- byteorder = format & 4 # non-zero => MSB
- bitorder = format & 8 # non-zero => MSB
- padindex = format & 3
-
- bitmapsize = bitmapSizes[padindex]
- offsets.append(bitmapsize)
-
- data = fp.read(bitmapsize)
-
- pad = BYTES_PER_ROW[padindex]
- mode = "1;R"
- if bitorder:
- mode = "1"
-
- for i in range(nbitmaps):
- x, y, l, r, w, a, d, f = metrics[i]
- b, e = offsets[i], offsets[i+1]
- bitmaps.append(
- Image.fromstring("1", (x, y), data[b:e], "raw", mode, pad(x))
- )
-
- return bitmaps
-
- def _load_encoding(self):
-
- # map character code to bitmap index
- encoding = [None] * 256
-
- fp, format, i16, i32 = self._getformat(PCF_BDF_ENCODINGS)
-
- firstCol, lastCol = i16(fp.read(2)), i16(fp.read(2))
- firstRow, lastRow = i16(fp.read(2)), i16(fp.read(2))
-
- default = i16(fp.read(2))
-
- nencoding = (lastCol - firstCol + 1) * (lastRow - firstRow + 1)
-
- for i in range(nencoding):
- encodingOffset = i16(fp.read(2))
- if encodingOffset != 0xFFFF:
- try:
- encoding[i+firstCol] = encodingOffset
- except IndexError:
- break # only load ISO-8859-1 glyphs
-
- return encoding
diff --git a/PIL/PcxImagePlugin.py b/PIL/PcxImagePlugin.py
deleted file mode 100644
index 8c0cd11..0000000
--- a/PIL/PcxImagePlugin.py
+++ /dev/null
@@ -1,167 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: PcxImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# PCX file handling
-#
-# This format was originally used by ZSoft's popular PaintBrush
-# program for the IBM PC. It is also supported by many MS-DOS and
-# Windows applications, including the Windows PaintBrush program in
-# Windows 3.
-#
-# history:
-# 1995-09-01 fl Created
-# 1996-05-20 fl Fixed RGB support
-# 1997-01-03 fl Fixed 2-bit and 4-bit support
-# 1999-02-03 fl Fixed 8-bit support (broken in 1.0b1)
-# 1999-02-07 fl Added write support
-# 2002-06-09 fl Made 2-bit and 4-bit support a bit more robust
-# 2002-07-30 fl Seek from to current position, not beginning of file
-# 2003-06-03 fl Extract DPI settings (info["dpi"])
-#
-# Copyright (c) 1997-2003 by Secret Labs AB.
-# Copyright (c) 1995-2003 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.6"
-
-import Image, ImageFile, ImagePalette
-
-def i16(c,o):
- return ord(c[o]) + (ord(c[o+1])<<8)
-
-def _accept(prefix):
- return ord(prefix[0]) == 10 and ord(prefix[1]) in [0, 2, 3, 5]
-
-##
-# Image plugin for Paintbrush images.
-
-class PcxImageFile(ImageFile.ImageFile):
-
- format = "PCX"
- format_description = "Paintbrush"
-
- def _open(self):
-
- # header
- s = self.fp.read(128)
- if not _accept(s):
- raise SyntaxError, "not a PCX file"
-
- # image
- bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1
- if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:
- raise SyntaxError, "bad PCX image size"
-
- # format
- version = ord(s[1])
- bits = ord(s[3])
- planes = ord(s[65])
- stride = i16(s,66)
-
- self.info["dpi"] = i16(s,12), i16(s,14)
-
- if bits == 1 and planes == 1:
- mode = rawmode = "1"
-
- elif bits == 1 and planes in (2, 4):
- mode = "P"
- rawmode = "P;%dL" % planes
- self.palette = ImagePalette.raw("RGB", s[16:64])
-
- elif version == 5 and bits == 8 and planes == 1:
- mode = rawmode = "L"
- # FIXME: hey, this doesn't work with the incremental loader !!!
- self.fp.seek(-769, 2)
- s = self.fp.read(769)
- if len(s) == 769 and ord(s[0]) == 12:
- # check if the palette is linear greyscale
- for i in range(256):
- if s[i*3+1:i*3+4] != chr(i)*3:
- mode = rawmode = "P"
- break
- if mode == "P":
- self.palette = ImagePalette.raw("RGB", s[1:])
- self.fp.seek(128)
-
- elif version == 5 and bits == 8 and planes == 3:
- mode = "RGB"
- rawmode = "RGB;L"
-
- else:
- raise IOError, "unknown PCX mode"
-
- self.mode = mode
- self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]
-
- bbox = (0, 0) + self.size
-
- self.tile = [("pcx", bbox, self.fp.tell(), (rawmode, planes * stride))]
-
-# --------------------------------------------------------------------
-# save PCX files
-
-SAVE = {
- # mode: (version, bits, planes, raw mode)
- "1": (2, 1, 1, "1"),
- "L": (5, 8, 1, "L"),
- "P": (5, 8, 1, "P"),
- "RGB": (5, 8, 3, "RGB;L"),
-}
-
-def o16(i):
- return chr(i&255) + chr(i>>8&255)
-
-def _save(im, fp, filename, check=0):
-
- try:
- version, bits, planes, rawmode = SAVE[im.mode]
- except KeyError:
- raise ValueError, "Cannot save %s images as PCX" % im.mode
-
- if check:
- return check
-
- # bytes per plane
- stride = (im.size[0] * bits + 7) / 8
-
- # under windows, we could determine the current screen size with
- # "Image.core.display_mode()[1]", but I think that's overkill...
-
- screen = im.size
-
- dpi = 100, 100
-
- # PCX header
- fp.write(
- chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) +
- o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) +
- o16(dpi[1]) + chr(0)*24 + chr(255)*24 + chr(0) + chr(planes) +
- o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) +
- chr(0)*54
- )
-
- assert fp.tell() == 128
-
- ImageFile._save(im, fp, [("pcx", (0,0)+im.size, 0,
- (rawmode, bits*planes))])
-
- if im.mode == "P":
- # colour palette
- fp.write(chr(12))
- fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes
- elif im.mode == "L":
- # greyscale palette
- fp.write(chr(12))
- for i in range(256):
- fp.write(chr(i)*3)
-
-# --------------------------------------------------------------------
-# registry
-
-Image.register_open("PCX", PcxImageFile, _accept)
-Image.register_save("PCX", _save)
-
-Image.register_extension("PCX", ".pcx")
diff --git a/PIL/PdfImagePlugin.py b/PIL/PdfImagePlugin.py
deleted file mode 100644
index 86567d6..0000000
--- a/PIL/PdfImagePlugin.py
+++ /dev/null
@@ -1,210 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: PdfImagePlugin.py 2438 2005-05-25 21:09:48Z Fredrik $
-#
-# PDF (Acrobat) file handling
-#
-# History:
-# 1996-07-16 fl Created
-# 1997-01-18 fl Fixed header
-# 2004-02-21 fl Fixes for 1/L/CMYK images, etc.
-# 2004-02-24 fl Fixes for 1 and P images.
-#
-# Copyright (c) 1997-2004 by Secret Labs AB. All rights reserved.
-# Copyright (c) 1996-1997 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-##
-# Image plugin for PDF images (output only).
-##
-
-__version__ = "0.4"
-
-import Image, ImageFile
-import StringIO
-
-
-#
-# --------------------------------------------------------------------
-
-# object ids:
-# 1. catalogue
-# 2. pages
-# 3. image
-# 4. page
-# 5. page contents
-
-def _obj(fp, obj, **dict):
- fp.write("%d 0 obj\n" % obj)
- if dict:
- fp.write("<<\n")
- for k, v in dict.items():
- if v is not None:
- fp.write("/%s %s\n" % (k, v))
- fp.write(">>\n")
-
-def _endobj(fp):
- fp.write("endobj\n")
-
-##
-# (Internal) Image save plugin for the PDF format.
-
-def _save(im, fp, filename):
-
- #
- # make sure image data is available
- im.load()
-
- xref = [0]*(5+1) # placeholders
-
- fp.write("%PDF-1.2\n")
- fp.write("% created by PIL PDF driver " + __version__ + "\n")
-
- #
- # Get image characteristics
-
- width, height = im.size
-
- # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)
- # or LZWDecode (tiff/lzw compression). Note that PDF 1.2 also supports
- # Flatedecode (zip compression).
-
- bits = 8
- params = None
-
- if im.mode == "1":
- filter = "/ASCIIHexDecode"
- colorspace = "/DeviceGray"
- procset = "/ImageB" # grayscale
- bits = 1
- elif im.mode == "L":
- filter = "/DCTDecode"
- # params = "<< /Predictor 15 /Columns %d >>" % (width-2)
- colorspace = "/DeviceGray"
- procset = "/ImageB" # grayscale
- elif im.mode == "P":
- filter = "/ASCIIHexDecode"
- colorspace = "[ /Indexed /DeviceRGB 255 <"
- palette = im.im.getpalette("RGB")
- for i in range(256):
- r = ord(palette[i*3])
- g = ord(palette[i*3+1])
- b = ord(palette[i*3+2])
- colorspace = colorspace + "%02x%02x%02x " % (r, g, b)
- colorspace = colorspace + "> ]"
- procset = "/ImageI" # indexed color
- elif im.mode == "RGB":
- filter = "/DCTDecode"
- colorspace = "/DeviceRGB"
- procset = "/ImageC" # color images
- elif im.mode == "CMYK":
- filter = "/DCTDecode"
- colorspace = "/DeviceCMYK"
- procset = "/ImageC" # color images
- else:
- raise ValueError("cannot save mode %s" % im.mode)
-
- #
- # catalogue
-
- xref[1] = fp.tell()
- _obj(fp, 1, Type = "/Catalog",
- Pages = "2 0 R")
- _endobj(fp)
-
- #
- # pages
-
- xref[2] = fp.tell()
- _obj(fp, 2, Type = "/Pages",
- Count = 1,
- Kids = "[4 0 R]")
- _endobj(fp)
-
- #
- # image
-
- op = StringIO.StringIO()
-
- if filter == "/ASCIIHexDecode":
- if bits == 1:
- # FIXME: the hex encoder doesn't support packed 1-bit
- # images; do things the hard way...
- data = im.tostring("raw", "1")
- im = Image.new("L", (len(data), 1), None)
- im.putdata(data)
- ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, im.mode)])
- elif filter == "/DCTDecode":
- ImageFile._save(im, op, [("jpeg", (0,0)+im.size, 0, im.mode)])
- elif filter == "/FlateDecode":
- ImageFile._save(im, op, [("zip", (0,0)+im.size, 0, im.mode)])
- elif filter == "/RunLengthDecode":
- ImageFile._save(im, op, [("packbits", (0,0)+im.size, 0, im.mode)])
- else:
- raise ValueError("unsupported PDF filter (%s)" % filter)
-
- xref[3] = fp.tell()
- _obj(fp, 3, Type = "/XObject",
- Subtype = "/Image",
- Width = width,
- Height = height,
- Length = len(op.getvalue()),
- Filter = filter,
- BitsPerComponent = bits,
- DecodeParams = params,
- ColorSpace = colorspace)
-
- fp.write("stream\n")
- fp.write(op.getvalue())
- fp.write("\nendstream\n")
-
- _endobj(fp)
-
- #
- # page
-
- xref[4] = fp.tell()
- _obj(fp, 4)
- fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\
- "/Resources <<\n/ProcSet [ /PDF %s ]\n"\
- "/XObject << /image 3 0 R >>\n>>\n"\
- "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\
- (procset, width, height))
- _endobj(fp)
-
- #
- # page contents
-
- op = StringIO.StringIO()
-
- op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (width, height))
-
- xref[5] = fp.tell()
- _obj(fp, 5, Length = len(op.getvalue()))
-
- fp.write("stream\n")
- fp.write(op.getvalue())
- fp.write("\nendstream\n")
-
- _endobj(fp)
-
- #
- # trailer
- startxref = fp.tell()
- fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref))
- for x in xref[1:]:
- fp.write("%010d 00000 n \n" % x)
- fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref))
- fp.write("startxref\n%d\n%%%%EOF\n" % startxref)
- fp.flush()
-
-#
-# --------------------------------------------------------------------
-
-Image.register_save("PDF", _save)
-
-Image.register_extension("PDF", ".pdf")
-
-Image.register_mime("PDF", "application/pdf")
diff --git a/PIL/PixarImagePlugin.py b/PIL/PixarImagePlugin.py
deleted file mode 100644
index d4b136f..0000000
--- a/PIL/PixarImagePlugin.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: PixarImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# PIXAR raster support for PIL
-#
-# history:
-# 97-01-29 fl Created
-#
-# notes:
-# This is incomplete; it is based on a few samples created with
-# Photoshop 2.5 and 3.0, and a summary description provided by
-# Greg Coats <gcoats@labiris.er.usgs.gov>. Hopefully, "L" and
-# "RGBA" support will be added in future versions.
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1997.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.1"
-
-import Image, ImageFile
-
-#
-# helpers
-
-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)
-
-##
-# Image plugin for PIXAR raster images.
-
-class PixarImageFile(ImageFile.ImageFile):
-
- format = "PIXAR"
- format_description = "PIXAR raster image"
-
- def _open(self):
-
- # assuming a 4-byte magic label (FIXME: add "_accept" hook)
- s = self.fp.read(4)
- if s != "\200\350\000\000":
- raise SyntaxError, "not a PIXAR file"
-
- # read rest of header
- s = s + self.fp.read(508)
-
- self.size = i16(s[418:420]), i16(s[416:418])
-
- # get channel/depth descriptions
- mode = i16(s[424:426]), i16(s[426:428])
-
- if mode == (14, 2):
- self.mode = "RGB"
- # FIXME: to be continued...
-
- # create tile descriptor (assuming "dumped")
- self.tile = [("raw", (0,0)+self.size, 1024, (self.mode, 0, 1))]
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("PIXAR", PixarImageFile)
-
-#
-# FIXME: what's the standard extension?
diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py
deleted file mode 100644
index 0e8ce9f..0000000
--- a/PIL/PngImagePlugin.py
+++ /dev/null
@@ -1,558 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: PngImagePlugin.py 2203 2004-12-19 14:32:32Z fredrik $
-#
-# PNG support code
-#
-# See "PNG (Portable Network Graphics) Specification, version 1.0;
-# W3C Recommendation", 1996-10-01, Thomas Boutell (ed.).
-#
-# history:
-# 1996-05-06 fl Created (couldn't resist it)
-# 1996-12-14 fl Upgraded, added read and verify support (0.2)
-# 1996-12-15 fl Separate PNG stream parser
-# 1996-12-29 fl Added write support, added getchunks
-# 1996-12-30 fl Eliminated circular references in decoder (0.3)
-# 1998-07-12 fl Read/write 16-bit images as mode I (0.4)
-# 2001-02-08 fl Added transparency support (from Zircon) (0.5)
-# 2001-04-16 fl Don't close data source in "open" method (0.6)
-# 2004-02-24 fl Don't even pretend to support interlaced files (0.7)
-# 2004-08-31 fl Do basic sanity check on chunk identifiers (0.8)
-# 2004-09-20 fl Added PngInfo chunk container
-# 2004-12-18 fl Added DPI read support (based on code by Niki Spahiev)
-#
-# Copyright (c) 1997-2004 by Secret Labs AB
-# Copyright (c) 1996 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.8.2"
-
-import re, string
-
-import Image, ImageFile, ImagePalette
-
-
-def i16(c):
- return ord(c[1]) + (ord(c[0])<<8)
-def i32(c):
- return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
-
-is_cid = re.compile("\w\w\w\w").match
-
-
-_MAGIC = "\211PNG\r\n\032\n"
-
-
-_MODES = {
- # supported bits/color combinations, and corresponding modes/rawmodes
- (1, 0): ("1", "1"),
- (2, 0): ("L", "L;2"),
- (4, 0): ("L", "L;4"),
- (8, 0): ("L", "L"),
- (16,0): ("I", "I;16B"),
- (8, 2): ("RGB", "RGB"),
- (16,2): ("RGB", "RGB;16B"),
- (1, 3): ("P", "P;1"),
- (2, 3): ("P", "P;2"),
- (4, 3): ("P", "P;4"),
- (8, 3): ("P", "P"),
- (8, 4): ("LA", "LA"),
- (16,4): ("RGBA", "LA;16B"), # LA;16B->LA not yet available
- (8, 6): ("RGBA", "RGBA"),
- (16,6): ("RGBA", "RGBA;16B"),
-}
-
-
-# --------------------------------------------------------------------
-# Support classes. Suitable for PNG and related formats like MNG etc.
-
-class ChunkStream:
-
- def __init__(self, fp):
-
- self.fp = fp
- self.queue = []
-
- if not hasattr(Image.core, "crc32"):
- self.crc = self.crc_skip
-
- def read(self):
- "Fetch a new chunk. Returns header information."
-
- if self.queue:
- cid, pos, len = self.queue[-1]
- del self.queue[-1]
- self.fp.seek(pos)
- else:
- s = self.fp.read(8)
- cid = s[4:]
- pos = self.fp.tell()
- len = i32(s)
-
- if not is_cid(cid):
- raise SyntaxError, "broken PNG file (chunk %s)" % repr(cid)
-
- return cid, pos, len
-
- def close(self):
- self.queue = self.crc = self.fp = None
-
- def push(self, cid, pos, len):
-
- self.queue.append((cid, pos, len))
-
- def call(self, cid, pos, len):
- "Call the appropriate chunk handler"
-
- if Image.DEBUG:
- print "STREAM", cid, pos, len
- return getattr(self, "chunk_" + cid)(pos, len)
-
- def crc(self, cid, data):
- "Read and verify checksum"
-
- crc1 = Image.core.crc32(data, Image.core.crc32(cid))
- crc2 = i16(self.fp.read(2)), i16(self.fp.read(2))
- if crc1 != crc2:
- raise SyntaxError, "broken PNG file"\
- "(bad header checksum in %s)" % cid
-
- def crc_skip(self, cid, data):
- "Read checksum. Used if the C module is not present"
-
- self.fp.read(4)
-
- def verify(self, endchunk = "IEND"):
-
- # Simple approach; just calculate checksum for all remaining
- # blocks. Must be called directly after open.
-
- cids = []
-
- while 1:
- cid, pos, len = self.read()
- if cid == endchunk:
- break
- self.crc(cid, ImageFile._safe_read(self.fp, len))
- cids.append(cid)
-
- return cids
-
-
-# --------------------------------------------------------------------
-# PNG chunk container (for use with save(pnginfo=))
-
-class PngInfo:
-
- def __init__(self):
- self.chunks = []
-
- def add(self, cid, data):
- self.chunks.append((cid, data))
-
- def add_text(self, key, value, zip=0):
- if zip:
- import zlib
- self.add("zTXt", key + "\0\0" + zlib.compress(value))
- else:
- self.add("tEXt", key + "\0" + value)
-
-# --------------------------------------------------------------------
-# PNG image stream (IHDR/IEND)
-
-class PngStream(ChunkStream):
-
- def __init__(self, fp):
-
- ChunkStream.__init__(self, fp)
-
- # local copies of Image attributes
- self.im_info = {}
- self.im_size = (0,0)
- self.im_mode = None
- self.im_tile = None
- self.im_palette = None
-
- def chunk_IHDR(self, pos, len):
-
- # image header
- s = ImageFile._safe_read(self.fp, len)
- self.im_size = i32(s), i32(s[4:])
- try:
- self.im_mode, self.im_rawmode = _MODES[(ord(s[8]), ord(s[9]))]
- except:
- pass
- if ord(s[12]):
- self.im_info["interlace"] = 1
- if ord(s[11]):
- raise SyntaxError, "unknown filter category"
- return s
-
- def chunk_IDAT(self, pos, len):
-
- # image data
- self.im_tile = [("zip", (0,0)+self.im_size, pos, self.im_rawmode)]
- self.im_idat = len
- raise EOFError
-
- def chunk_IEND(self, pos, len):
-
- # end of PNG image
- raise EOFError
-
- def chunk_PLTE(self, pos, len):
-
- # palette
- s = ImageFile._safe_read(self.fp, len)
- if self.im_mode == "P":
- self.im_palette = "RGB", s
- return s
-
- def chunk_tRNS(self, pos, len):
-
- # transparency
- s = ImageFile._safe_read(self.fp, len)
- if self.im_mode == "P":
- i = string.find(s, chr(0))
- if i >= 0:
- self.im_info["transparency"] = i
- elif self.im_mode == "L":
- self.im_info["transparency"] = i16(s)
- return s
-
- def chunk_gAMA(self, pos, len):
-
- # gamma setting
- s = ImageFile._safe_read(self.fp, len)
- self.im_info["gamma"] = i32(s) / 100000.0
- return s
-
- def chunk_pHYs(self, pos, len):
-
- # pixels per unit
- s = ImageFile._safe_read(self.fp, len)
- px, py = i32(s), i32(s[4:])
- unit = ord(s[8])
- if unit == 1: # meter
- dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5)
- self.im_info["dpi"] = dpi
- elif unit == 0:
- self.im_info["aspect"] = px, py
- return s
-
- def chunk_tEXt(self, pos, len):
-
- # text
- s = ImageFile._safe_read(self.fp, len)
- try:
- k, v = string.split(s, "\0", 1)
- except ValueError:
- k = s; v = "" # fallback for broken tEXt tags
- if k:
- self.im_info[k] = v
- return s
-
-
-# --------------------------------------------------------------------
-# PNG reader
-
-def _accept(prefix):
- return prefix[:8] == _MAGIC
-
-##
-# Image plugin for PNG images.
-
-class PngImageFile(ImageFile.ImageFile):
-
- format = "PNG"
- format_description = "Portable network graphics"
-
- def _open(self):
-
- if self.fp.read(8) != _MAGIC:
- raise SyntaxError, "not a PNG file"
-
- #
- # Parse headers up to the first IDAT chunk
-
- self.png = PngStream(self.fp)
-
- while 1:
-
- #
- # get next chunk
-
- cid, pos, len = self.png.read()
-
- try:
- s = self.png.call(cid, pos, len)
- except EOFError:
- break
- except AttributeError:
- if Image.DEBUG:
- print cid, pos, len, "(unknown)"
- s = ImageFile._safe_read(self.fp, len)
-
- self.png.crc(cid, s)
-
- #
- # Copy relevant attributes from the PngStream. An alternative
- # would be to let the PngStream class modify these attributes
- # directly, but that introduces circular references which are
- # difficult to break if things go wrong in the decoder...
- # (believe me, I've tried ;-)
-
- self.mode = self.png.im_mode
- self.size = self.png.im_size
- self.info = self.png.im_info
- self.tile = self.png.im_tile
-
- if self.png.im_palette:
- rawmode, data = self.png.im_palette
- self.palette = ImagePalette.raw(rawmode, data)
-
- self.__idat = len # used by load_read()
-
-
- def verify(self):
- "Verify PNG file"
-
- if self.fp is None:
- raise RuntimeError("verify must be called directly after open")
-
- # back up to beginning of IDAT block
- self.fp.seek(self.tile[0][2] - 8)
-
- self.png.verify()
- self.png.close()
-
- self.fp = None
-
- def load_prepare(self):
- "internal: prepare to read PNG file"
-
- if self.info.get("interlace"):
- raise IOError("cannot read interlaced PNG files")
-
- ImageFile.ImageFile.load_prepare(self)
-
- def load_read(self, bytes):
- "internal: read more image data"
-
- while self.__idat == 0:
- # end of chunk, skip forward to next one
-
- self.fp.read(4) # CRC
-
- cid, pos, len = self.png.read()
-
- if cid not in ["IDAT", "DDAT"]:
- self.png.push(cid, pos, len)
- return ""
-
- self.__idat = len # empty chunks are allowed
-
- # read more data from this chunk
- if bytes <= 0:
- bytes = self.__idat
- else:
- bytes = min(bytes, self.__idat)
-
- self.__idat = self.__idat - bytes
-
- return self.fp.read(bytes)
-
-
- def load_end(self):
- "internal: finished reading image data"
-
- self.png.close()
- self.png = None
-
-
-# --------------------------------------------------------------------
-# PNG writer
-
-def o16(i):
- return chr(i>>8&255) + chr(i&255)
-
-def o32(i):
- return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255)
-
-_OUTMODES = {
- # supported PIL modes, and corresponding rawmodes/bits/color combinations
- "1": ("1", chr(1)+chr(0)),
- "L;1": ("L;1", chr(1)+chr(0)),
- "L;2": ("L;2", chr(2)+chr(0)),
- "L;4": ("L;4", chr(4)+chr(0)),
- "L": ("L", chr(8)+chr(0)),
- "LA": ("LA", chr(8)+chr(4)),
- "I": ("I;16B", chr(16)+chr(0)),
- "P;1": ("P;1", chr(1)+chr(3)),
- "P;2": ("P;2", chr(2)+chr(3)),
- "P;4": ("P;4", chr(4)+chr(3)),
- "P": ("P", chr(8)+chr(3)),
- "RGB": ("RGB", chr(8)+chr(2)),
- "RGBA":("RGBA", chr(8)+chr(6)),
-}
-
-def putchunk(fp, cid, *data):
- "Write a PNG chunk (including CRC field)"
-
- data = string.join(data, "")
-
- fp.write(o32(len(data)) + cid)
- fp.write(data)
- hi, lo = Image.core.crc32(data, Image.core.crc32(cid))
- fp.write(o16(hi) + o16(lo))
-
-class _idat:
- # wrap output from the encoder in IDAT chunks
-
- def __init__(self, fp, chunk):
- self.fp = fp
- self.chunk = chunk
- def write(self, data):
- self.chunk(self.fp, "IDAT", data)
-
-def _save(im, fp, filename, chunk=putchunk, check=0):
- # save an image to disk (called by the save method)
-
- mode = im.mode
-
- if mode == "P":
-
- #
- # attempt to minimize storage requirements for palette images
-
- if im.encoderinfo.has_key("bits"):
-
- # number of bits specified by user
- n = 1 << im.encoderinfo["bits"]
-
- else:
-
- # check palette contents
- n = 256 # FIXME
-
- if n <= 2:
- bits = 1
- elif n <= 4:
- bits = 2
- elif n <= 16:
- bits = 4
- else:
- bits = 8
-
- if bits != 8:
- mode = "%s;%d" % (mode, bits)
-
- # encoder options
- if im.encoderinfo.has_key("dictionary"):
- dictionary = im.encoderinfo["dictionary"]
- else:
- dictionary = ""
-
- im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary)
-
- # get the corresponding PNG mode
- try:
- rawmode, mode = _OUTMODES[mode]
- except KeyError:
- raise IOError, "cannot write mode %s as PNG" % mode
-
- if check:
- return check
-
- #
- # write minimal PNG file
-
- fp.write(_MAGIC)
-
- chunk(fp, "IHDR",
- o32(im.size[0]), o32(im.size[1]), # 0: size
- mode, # 8: depth/type
- chr(0), # 10: compression
- chr(0), # 11: filter category
- chr(0)) # 12: interlace flag
-
- if im.mode == "P":
- chunk(fp, "PLTE", im.im.getpalette("RGB"))
-
- if im.encoderinfo.has_key("transparency"):
- if im.mode == "P":
- transparency = max(0, min(255, im.encoderinfo["transparency"]))
- chunk(fp, "tRNS", chr(255) * transparency + chr(0))
- elif im.mode == "L":
- transparency = max(0, min(65535, im.encoderinfo["transparency"]))
- chunk(fp, "tRNS", o16(transparency))
- else:
- raise IOError, "cannot use transparency for this mode"
-
- if 0:
- # FIXME: to be supported some day
- chunk(fp, "gAMA", o32(int(gamma * 100000.0)))
-
- dpi = im.encoderinfo.get("dpi")
- if dpi:
- chunk(fp, "pHYs",
- o32(int(dpi[0] / 0.0254 + 0.5)),
- o32(int(dpi[1] / 0.0254 + 0.5)),
- chr(1))
-
- info = im.encoderinfo.get("pnginfo")
- if info:
- for cid, data in info.chunks:
- chunk(fp, cid, data)
-
- ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)])
-
- chunk(fp, "IEND", "")
-
- try:
- fp.flush()
- except:
- pass
-
-
-# --------------------------------------------------------------------
-# PNG chunk converter
-
-def getchunks(im, **params):
- """Return a list of PNG chunks representing this image."""
-
- class collector:
- data = []
- def write(self, data):
- pass
- def append(self, chunk):
- self.data.append(chunk)
-
- def append(fp, cid, *data):
- data = string.join(data, "")
- hi, lo = Image.core.crc32(data, Image.core.crc32(cid))
- crc = o16(hi) + o16(lo)
- fp.append((cid, data, crc))
-
- fp = collector()
-
- try:
- im.encoderinfo = params
- _save(im, fp, None, append)
- finally:
- del im.encoderinfo
-
- return fp.data
-
-
-# --------------------------------------------------------------------
-# Registry
-
-Image.register_open("PNG", PngImageFile, _accept)
-Image.register_save("PNG", _save)
-
-Image.register_extension("PNG", ".png")
-
-Image.register_mime("PNG", "image/png")
diff --git a/PIL/PpmImagePlugin.py b/PIL/PpmImagePlugin.py
deleted file mode 100644
index b9b9f81..0000000
--- a/PIL/PpmImagePlugin.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: PpmImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# PPM support for PIL
-#
-# History:
-# 96-03-24 fl Created
-# 98-03-06 fl Write RGBA images (as RGB, that is)
-#
-# Copyright (c) Secret Labs AB 1997-98.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.2"
-
-import string
-
-import Image, ImageFile
-
-#
-# --------------------------------------------------------------------
-
-MODES = {
- # standard
- "P4": "1",
- "P5": "L",
- "P6": "RGB",
- # extensions
- "P0CMYK": "CMYK",
- # PIL extensions (for test purposes only)
- "PyP": "P",
- "PyRGBA": "RGBA",
- "PyCMYK": "CMYK"
-}
-
-def _accept(prefix):
- return prefix[0] == "P" and prefix[1] in "0456y"
-
-##
-# Image plugin for PBM, PGM, and PPM images.
-
-class PpmImageFile(ImageFile.ImageFile):
-
- format = "PPM"
- format_description = "Pbmplus image"
-
- def _token(self, s = ""):
- while 1: # read until next whitespace
- c = self.fp.read(1)
- if not c or c in string.whitespace:
- break
- s = s + c
- return s
-
- def _open(self):
-
- # check magic
- s = self.fp.read(1)
- if s != "P":
- raise SyntaxError, "not a PPM file"
- mode = MODES[self._token(s)]
-
- if mode == "1":
- self.mode = "1"
- rawmode = "1;I"
- else:
- self.mode = rawmode = mode
-
- for ix in range(3):
- while 1:
- while 1:
- s = self.fp.read(1)
- if s not in string.whitespace:
- break
- if s != "#":
- break
- s = self.fp.readline()
- s = int(self._token(s))
- if ix == 0:
- xsize = s
- elif ix == 1:
- ysize = s
- if mode == "1":
- break
-
- self.size = xsize, ysize
- self.tile = [("raw",
- (0, 0, xsize, ysize),
- self.fp.tell(),
- (rawmode, 0, 1))]
-
- # ALTERNATIVE: load via builtin debug function
- # self.im = Image.core.open_ppm(self.filename)
- # self.mode = self.im.mode
- # self.size = self.im.size
-
-#
-# --------------------------------------------------------------------
-
-def _save(im, fp, filename):
- if im.mode == "1":
- rawmode, head = "1;I", "P4"
- elif im.mode == "L":
- rawmode, head = "L", "P5"
- elif im.mode == "RGB":
- rawmode, head = "RGB", "P6"
- elif im.mode == "RGBA":
- rawmode, head = "RGB", "P6"
- else:
- raise IOError, "cannot write mode %s as PPM" % im.mode
- fp.write(head + "\n%d %d\n" % im.size)
- if head != "P4":
- fp.write("255\n")
- ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))])
-
- # ALTERNATIVE: save via builtin debug function
- # im._dump(filename)
-
-#
-# --------------------------------------------------------------------
-
-Image.register_open("PPM", PpmImageFile, _accept)
-Image.register_save("PPM", _save)
-
-Image.register_extension("PPM", ".pbm")
-Image.register_extension("PPM", ".pgm")
-Image.register_extension("PPM", ".ppm")
diff --git a/PIL/PsdImagePlugin.py b/PIL/PsdImagePlugin.py
deleted file mode 100644
index 1e68c0d..0000000
--- a/PIL/PsdImagePlugin.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: PsdImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# Adobe PSD 2.5/3.0 file handling
-#
-# History:
-# 1995-09-01 fl Created
-# 1997-01-03 fl Read most PSD images
-# 1997-01-18 fl Fixed P and CMYK support
-# 2001-10-21 fl Added seek/tell support (for layers)
-#
-# Copyright (c) 1997-2001 by Secret Labs AB.
-# Copyright (c) 1995-2001 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.4"
-
-import string
-import Image, ImageFile, ImagePalette
-
-MODES = {
- # (photoshop mode, bits) -> (pil mode, required channels)
- (0, 1): ("1", 1),
- (0, 8): ("L", 1),
- (1, 8): ("L", 1),
- (2, 8): ("P", 1),
- (3, 8): ("RGB", 3),
- (4, 8): ("CMYK", 4),
- (7, 8): ("L", 1), # FIXME: multilayer
- (8, 8): ("L", 1), # duotone
- (9, 8): ("LAB", 3)
-}
-
-#
-# helpers
-
-def i16(c):
- return ord(c[1]) + (ord(c[0])<<8)
-
-def i32(c):
- return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
-
-# --------------------------------------------------------------------.
-# read PSD images
-
-def _accept(prefix):
- return prefix[:4] == "8BPS"
-
-##
-# Image plugin for Photoshop images.
-
-class PsdImageFile(ImageFile.ImageFile):
-
- format = "PSD"
- format_description = "Adobe Photoshop"
-
- def _open(self):
-
- read = self.fp.read
-
- #
- # header
-
- s = read(26)
- if s[:4] != "8BPS" or i16(s[4:]) != 1:
- raise SyntaxError, "not a PSD file"
-
- psd_bits = i16(s[22:])
- psd_channels = i16(s[12:])
- psd_mode = i16(s[24:])
-
- mode, channels = MODES[(psd_mode, psd_bits)]
-
- if channels > psd_channels:
- raise IOError, "not enough channels"
-
- self.mode = mode
- self.size = i32(s[18:]), i32(s[14:])
-
- #
- # color mode data
-
- size = i32(read(4))
- if size:
- data = read(size)
- if mode == "P" and size == 768:
- self.palette = ImagePalette.raw("RGB;L", data)
-
- #
- # image resources
-
- self.resources = []
-
- size = i32(read(4))
- if size:
- # load resources
- end = self.fp.tell() + size
- while self.fp.tell() < end:
- signature = read(4)
- id = i16(read(2))
- name = read(ord(read(1)))
- if not (len(name) & 1):
- read(1) # padding
- data = read(i32(read(4)))
- if (len(data) & 1):
- read(1) # padding
- self.resources.append((id, name, data))
-
- #
- # layer and mask information
-
- self.layers = []
-
- size = i32(read(4))
- if size:
- end = self.fp.tell() + size
- size = i32(read(4))
- if size:
- self.layers = _layerinfo(self.fp)
- self.fp.seek(end)
-
- #
- # image descriptor
-
- self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels)
-
- # keep the file open
- self._fp = self.fp
- self.frame = 0
-
- def seek(self, layer):
- # seek to given layer (1..max)
- if layer == self.frame:
- return
- try:
- if layer <= 0:
- raise IndexError
- name, mode, bbox, tile = self.layers[layer-1]
- self.mode = mode
- self.tile = tile
- self.frame = layer
- self.fp = self._fp
- return name, bbox
- except IndexError:
- raise EOFError, "no such layer"
-
- def tell(self):
- # return layer number (0=image, 1..max=layers)
- return self.frame
-
- def load_prepare(self):
- # create image memory if necessary
- if not self.im or\
- self.im.mode != self.mode or self.im.size != self.size:
- self.im = Image.core.fill(self.mode, self.size, 0)
- # create palette (optional)
- if self.mode == "P":
- Image.Image.load(self)
-
-def _layerinfo(file):
- # read layerinfo block
- layers = []
- read = file.read
-
- for i in range(abs(i16(read(2)))):
-
- # bounding box
- y0 = i32(read(4)); x0 = i32(read(4))
- y1 = i32(read(4)); x1 = i32(read(4))
-
- # image info
- info = []
- mode = []
- for i in range(i16(read(2))):
- type = i16(read(2))
- if type == 65535:
- m = "A"
- else:
- m = "RGB"[type]
- mode.append(m)
- size = i32(read(4))
- info.append((m, size))
-
- # figure out the image mode
- mode.sort()
- if mode == ["R"]:
- mode = "L"
- elif mode == ["B", "G", "R"]:
- mode = "RGB"
- elif mode == ["A", "B", "G", "R"]:
- mode = "RGBA"
- else:
- mode = None # unknown
-
- # skip over blend flags and extra information
- filler = read(12)
- name = None # FIXME
- file.seek(i32(read(4)), 1)
-
- layers.append((name, mode, (x0, y0, x1, y1)))
-
- # get tiles
- i = 0
- for name, mode, bbox in layers:
- tile = []
- for m in mode:
- t = _maketile(file, m, bbox, 1)
- if t:
- tile.extend(t)
- layers[i] = name, mode, bbox, tile
- i = i + 1
-
- return layers
-
-def _maketile(file, mode, bbox, channels):
-
- tile = None
- read = file.read
-
- compression = i16(read(2))
-
- xsize = bbox[2] - bbox[0]
- ysize = bbox[3] - bbox[1]
-
- offset = file.tell()
-
- if compression == 0:
- #
- # raw compression
- tile = []
- for channel in range(channels):
- layer = mode[channel]
- if mode == "CMYK":
- layer = layer + ";I"
- tile.append(("raw", bbox, offset, layer))
- offset = offset + xsize*ysize
-
- elif compression == 1:
- #
- # packbits compression
- i = 0
- tile = []
- bytecount = read(channels * ysize * 2)
- offset = file.tell()
- for channel in range(channels):
- layer = mode[channel]
- if mode == "CMYK":
- layer = layer + ";I"
- tile.append(
- ("packbits", bbox, offset, layer)
- )
- for y in range(ysize):
- offset = offset + i16(bytecount[i:i+2])
- i = i + 2
-
- file.seek(offset)
-
- if offset & 1:
- read(1) # padding
-
- return tile
-
-# --------------------------------------------------------------------
-# registry
-
-Image.register_open("PSD", PsdImageFile, _accept)
-
-Image.register_extension("PSD", ".psd")
diff --git a/PIL/SgiImagePlugin.py b/PIL/SgiImagePlugin.py
deleted file mode 100644
index 0ab741e..0000000
--- a/PIL/SgiImagePlugin.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: SgiImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# SGI image file handling
-#
-# See "The SGI Image File Format (Draft version 0.97)", Paul Haeberli.
-# <ftp://ftp.sgi.com/graphics/SGIIMAGESPEC>
-#
-# History:
-# 1995-09-10 fl Created
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1995.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.1"
-
-
-import string
-import Image, ImageFile
-
-
-def i16(c):
- return ord(c[1]) + (ord(c[0])<<8)
-
-def i32(c):
- return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
-
-
-def _accept(prefix):
- return i16(prefix) == 474
-
-##
-# Image plugin for SGI images.
-
-class SgiImageFile(ImageFile.ImageFile):
-
- format = "SGI"
- format_description = "SGI Image File Format"
-
- def _open(self):
-
- # HEAD
- s = self.fp.read(512)
- if i16(s) != 474:
- raise SyntaxError, "not an SGI image file"
-
- # relevant header entries
- compression = ord(s[2])
-
- # bytes, dimension, zsize
- layout = ord(s[3]), i16(s[4:]), i16(s[10:])
-
- # determine mode from bytes/zsize
- if layout == (1, 2, 1):
- self.mode = "L"
- elif layout == (1, 3, 3):
- self.mode = "RGB"
- else:
- raise SyntaxError, "unsupported SGI image mode"
-
- # size
- self.size = i16(s[6:]), i16(s[8:])
-
- # decoder info
- if compression == 0:
- if self.mode == "RGB":
- # RGB images are band interleaved
- size = self.size[0]*self.size[1]
- self.tile = [("raw", (0,0)+self.size, 512, ("R",0,1)),
- ("raw", (0,0)+self.size, 512+size, ("G",0,1)),
- ("raw", (0,0)+self.size, 512+2*size, ("B",0,1))]
- else:
- self.tile = [("raw", (0,0)+self.size, 512, (self.mode, 0, 1))]
- if compression == 1:
- self.tile = [("sgi_rle", (0,0)+self.size, 512, (self.mode, 0, 1))]
-
-#
-# registry
-
-Image.register_open("SGI", SgiImageFile, _accept)
-
-Image.register_extension("SGI", ".bw")
-Image.register_extension("SGI", ".rgb")
-Image.register_extension("SGI", ".rgba")
-
-Image.register_extension("SGI", ".sgi") # really?
diff --git a/PIL/SpiderImagePlugin.py b/PIL/SpiderImagePlugin.py
deleted file mode 100644
index e0fd045..0000000
--- a/PIL/SpiderImagePlugin.py
+++ /dev/null
@@ -1,294 +0,0 @@
-#
-# The Python Imaging Library.
-#
-# SPIDER image file handling
-#
-# History:
-# 2004-08-02 Created BB
-# 2006-03-02 added save method
-# 2006-03-13 added support for stack images
-#
-# Copyright (c) 2004 by Health Research Inc. (HRI) RENSSELAER, NY 12144.
-# Copyright (c) 2004 by William Baxter.
-# Copyright (c) 2004 by Secret Labs AB.
-# Copyright (c) 2004 by Fredrik Lundh.
-#
-
-##
-# Image plugin for the Spider image format. This format is is used
-# by the SPIDER software, in processing image data from electron
-# microscopy and tomography.
-##
-
-#
-# SpiderImagePlugin.py
-#
-# The Spider image format is used by SPIDER software, in processing
-# image data from electron microscopy and tomography.
-#
-# Spider home page:
-# http://www.wadsworth.org/spider_doc/spider/docs/spider.html
-#
-# Details about the Spider image format:
-# http://www.wadsworth.org/spider_doc/spider/docs/image_doc.html
-#
-
-import Image, ImageFile
-import os, string, struct, sys
-
-def isInt(f):
- try:
- i = int(f)
- if f-i == 0: return 1
- else: return 0
- except:
- return 0
-
-iforms = [1,3,-11,-12,-21,-22]
-
-# There is no magic number to identify Spider files, so just check a
-# series of header locations to see if they have reasonable values.
-# Returns no.of bytes in the header, if it is a valid Spider header,
-# otherwise returns 0
-
-def isSpiderHeader(t):
- h = (99,) + t # add 1 value so can use spider header index start=1
- # header values 1,2,5,12,13,22,23 should be integers
- for i in [1,2,5,12,13,22,23]:
- if not isInt(h[i]): return 0
- # check iform
- iform = int(h[5])
- if not iform in iforms: return 0
- # check other header values
- labrec = int(h[13]) # no. records in file header
- labbyt = int(h[22]) # total no. of bytes in header
- lenbyt = int(h[23]) # record length in bytes
- #print "labrec = %d, labbyt = %d, lenbyt = %d" % (labrec,labbyt,lenbyt)
- if labbyt != (labrec * lenbyt): return 0
- # looks like a valid header
- return labbyt
-
-def isSpiderImage(filename):
- fp = open(filename,'rb')
- f = fp.read(92) # read 23 * 4 bytes
- fp.close()
- bigendian = 1
- t = struct.unpack('>23f',f) # try big-endian first
- hdrlen = isSpiderHeader(t)
- if hdrlen == 0:
- bigendian = 0
- t = struct.unpack('<23f',f) # little-endian
- hdrlen = isSpiderHeader(t)
- return hdrlen
-
-
-class SpiderImageFile(ImageFile.ImageFile):
-
- format = "SPIDER"
- format_description = "Spider 2D image"
-
- def _open(self):
- # check header
- n = 27 * 4 # read 27 float values
- f = self.fp.read(n)
-
- try:
- self.bigendian = 1
- t = struct.unpack('>27f',f) # try big-endian first
- hdrlen = isSpiderHeader(t)
- if hdrlen == 0:
- self.bigendian = 0
- t = struct.unpack('<27f',f) # little-endian
- hdrlen = isSpiderHeader(t)
- if hdrlen == 0:
- raise SyntaxError, "not a valid Spider file"
- except struct.error:
- raise SyntaxError, "not a valid Spider file"
-
- h = (99,) + t # add 1 value : spider header index starts at 1
- iform = int(h[5])
- if iform != 1:
- raise SyntaxError, "not a Spider 2D image"
-
- self.size = int(h[12]), int(h[2]) # size in pixels (width, height)
- self.istack = int(h[24])
- self.imgnumber = int(h[27])
-
- if self.istack == 0 and self.imgnumber == 0:
- # stk=0, img=0: a regular 2D image
- offset = hdrlen
- self.nimages = 1
- elif self.istack > 0 and self.imgnumber == 0:
- # stk>0, img=0: Opening the stack for the first time
- self.imgbytes = int(h[12]) * int(h[2]) * 4
- self.hdrlen = hdrlen
- self.nimages = int(h[26])
- # Point to the first image in the stack
- offset = hdrlen * 2
- self.imgnumber = 1
- elif self.istack == 0 and self.imgnumber > 0:
- # stk=0, img>0: an image within the stack
- offset = hdrlen + self.stkoffset
- self.istack = 2 # So Image knows it's still a stack
- else:
- raise SyntaxError, "inconsistent stack header values"
-
- if self.bigendian:
- self.rawmode = "F;32BF"
- else:
- self.rawmode = "F;32F"
- self.mode = "F"
-
- self.tile = [("raw", (0, 0) + self.size, offset,
- (self.rawmode, 0, 1))]
- self.__fp = self.fp # FIXME: hack
-
- # 1st image index is zero (although SPIDER imgnumber starts at 1)
- def tell(self):
- if self.imgnumber < 1:
- return 0
- else:
- return self.imgnumber - 1
-
- def seek(self, frame):
- if self.istack == 0:
- return
- if frame >= self.nimages:
- raise EOFError, "attempt to seek past end of file"
- self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes)
- self.fp = self.__fp
- self.fp.seek(self.stkoffset)
- self._open()
-
- # returns a byte image after rescaling to 0..255
- def convert2byte(self, depth=255):
- (min, max) = self.getextrema()
- m = 1
- if max != min:
- m = depth / (max-min)
- b = -m * min
- return self.point(lambda i, m=m, b=b: i * m + b).convert("L")
-
- # returns a ImageTk.PhotoImage object, after rescaling to 0..255
- def tkPhotoImage(self):
- import ImageTk
- return ImageTk.PhotoImage(self.convert2byte(), palette=256)
-
-# --------------------------------------------------------------------
-# Image series
-
-# given a list of filenames, return a list of images
-def loadImageSeries(filelist=None):
- " create a list of Image.images for use in montage "
- if filelist == None or len(filelist) < 1:
- return
-
- imglist = []
- for img in filelist:
- if not os.path.exists(img):
- print "unable to find %s" % img
- continue
- try:
- im = Image.open(img).convert2byte()
- except:
- if not isSpiderImage(img):
- print img + " is not a Spider image file"
- continue
- im.info['filename'] = img
- imglist.append(im)
- return imglist
-
-# --------------------------------------------------------------------
-# For saving images in Spider format
-
-def makeSpiderHeader(im):
- nsam,nrow = im.size
- lenbyt = nsam * 4 # There are labrec records in the header
- labrec = 1024 / lenbyt
- if 1024%lenbyt != 0: labrec += 1
- labbyt = labrec * lenbyt
- hdr = []
- nvalues = labbyt / 4
- for i in range(nvalues):
- hdr.append(0.0)
-
- if len(hdr) < 23:
- return []
-
- # NB these are Fortran indices
- hdr[1] = 1.0 # nslice (=1 for an image)
- hdr[2] = float(nrow) # number of rows per slice
- hdr[5] = 1.0 # iform for 2D image
- hdr[12] = float(nsam) # number of pixels per line
- hdr[13] = float(labrec) # number of records in file header
- hdr[22] = float(labbyt) # total number of bytes in header
- hdr[23] = float(lenbyt) # record length in bytes
-
- # adjust for Fortran indexing
- hdr = hdr[1:]
- hdr.append(0.0)
- # pack binary data into a string
- hdrstr = []
- for v in hdr:
- hdrstr.append(struct.pack('f',v))
- return hdrstr
-
-def _save(im, fp, filename):
- if im.mode[0] != "F":
- im = im.convert('F')
-
- hdr = makeSpiderHeader(im)
- if len(hdr) < 256:
- raise IOError, "Error creating Spider header"
-
- # write the SPIDER header
- try:
- fp = open(filename, 'wb')
- except:
- raise IOError, "Unable to open %s for writing" % filename
- fp.writelines(hdr)
-
- rawmode = "F;32NF" #32-bit native floating point
- ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode,0,1))])
-
- fp.close()
-
-def _save_spider(im, fp, filename):
- # get the filename extension and register it with Image
- fn, ext = os.path.splitext(filename)
- Image.register_extension("SPIDER", ext)
- _save(im, fp, filename)
-
-# --------------------------------------------------------------------
-
-Image.register_open("SPIDER", SpiderImageFile)
-Image.register_save("SPIDER", _save_spider)
-
-if __name__ == "__main__":
-
- if not sys.argv[1:]:
- print "Syntax: python SpiderImagePlugin.py Spiderimage [outfile]"
- sys.exit()
-
- filename = sys.argv[1]
- if not isSpiderImage(filename):
- print "input image must be in Spider format"
- sys.exit()
-
- outfile = ""
- if len(sys.argv[1:]) > 1:
- outfile = sys.argv[2]
-
- im = Image.open(filename)
- print "image: " + str(im)
- print "format: " + str(im.format)
- print "size: " + str(im.size)
- print "mode: " + str(im.mode)
- print "max, min: ",
- print im.getextrema()
-
- if outfile != "":
- # perform some image operation
- im = im.transpose(Image.FLIP_LEFT_RIGHT)
- print "saving a flipped version of %s as %s " % (os.path.basename(filename), outfile)
- im.save(outfile, "SPIDER")
diff --git a/PIL/SunImagePlugin.py b/PIL/SunImagePlugin.py
deleted file mode 100644
index 2e7fe52..0000000
--- a/PIL/SunImagePlugin.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: SunImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# Sun image file handling
-#
-# History:
-# 1995-09-10 fl Created
-# 1996-05-28 fl Fixed 32-bit alignment
-# 1998-12-29 fl Import ImagePalette module
-# 2001-12-18 fl Fixed palette loading (from Jean-Claude Rimbault)
-#
-# Copyright (c) 1997-2001 by Secret Labs AB
-# Copyright (c) 1995-1996 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.3"
-
-
-import string
-import Image, ImageFile, ImagePalette
-
-
-def i16(c):
- return ord(c[1]) + (ord(c[0])<<8)
-
-def i32(c):
- return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
-
-
-def _accept(prefix):
- return i32(prefix) == 0x59a66a95
-
-##
-# Image plugin for Sun raster files.
-
-class SunImageFile(ImageFile.ImageFile):
-
- format = "SUN"
- format_description = "Sun Raster File"
-
- def _open(self):
-
- # HEAD
- s = self.fp.read(32)
- if i32(s) != 0x59a66a95:
- raise SyntaxError, "not an SUN raster file"
-
- offset = 32
-
- self.size = i32(s[4:8]), i32(s[8:12])
-
- depth = i32(s[12:16])
- if depth == 1:
- self.mode, rawmode = "1", "1;I"
- elif depth == 8:
- self.mode = rawmode = "L"
- elif depth == 24:
- self.mode, rawmode = "RGB", "BGR"
- else:
- raise SyntaxError, "unsupported mode"
-
- compression = i32(s[20:24])
-
- if i32(s[24:28]) != 0:
- length = i32(s[28:32])
- offset = offset + length
- self.palette = ImagePalette.raw("RGB;L", self.fp.read(length))
- if self.mode == "L":
- self.mode = rawmode = "P"
-
- stride = (((self.size[0] * depth + 7) / 8) + 3) & (~3)
-
- if compression == 1:
- self.tile = [("raw", (0,0)+self.size, offset, (rawmode, stride))]
- elif compression == 2:
- self.tile = [("sun_rle", (0,0)+self.size, offset, rawmode)]
-
-#
-# registry
-
-Image.register_open("SUN", SunImageFile, _accept)
-
-Image.register_extension("SUN", ".ras")
diff --git a/PIL/TarIO.py b/PIL/TarIO.py
deleted file mode 100644
index fbab8ca..0000000
--- a/PIL/TarIO.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: TarIO.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# read files from within a tar file
-#
-# History:
-# 95-06-18 fl Created
-# 96-05-28 fl Open files in binary mode
-#
-# Copyright (c) Secret Labs AB 1997.
-# Copyright (c) Fredrik Lundh 1995-96.
-#
-# See the README file for information on usage and redistribution.
-#
-
-import ContainerIO
-import string
-
-##
-# A file object that provides read access to a given member of a TAR
-# file.
-
-class TarIO(ContainerIO.ContainerIO):
-
- ##
- # Create file object.
- #
- # @param tarfile Name of TAR file.
- # @param file Name of member file.
-
- def __init__(self, tarfile, file):
-
- fh = open(tarfile, "rb")
-
- while 1:
-
- s = fh.read(512)
- if len(s) != 512:
- raise IOError, "unexpected end of tar file"
-
- name = s[:100]
- i = string.find(name, chr(0))
- if i == 0:
- raise IOError, "cannot find subfile"
- if i > 0:
- name = name[:i]
-
- size = string.atoi(s[124:136], 8)
-
- if file == name:
- break
-
- fh.seek((size + 511) & (~511), 1)
-
- # Open region
- ContainerIO.ContainerIO.__init__(self, fh, fh.tell(), size)
diff --git a/PIL/TgaImagePlugin.py b/PIL/TgaImagePlugin.py
deleted file mode 100644
index e709de8..0000000
--- a/PIL/TgaImagePlugin.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: TgaImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# TGA file handling
-#
-# History:
-# 95-09-01 fl created (reads 24-bit files only)
-# 97-01-04 fl support more TGA versions, including compressed images
-# 98-07-04 fl fixed orientation and alpha layer bugs
-# 98-09-11 fl fixed orientation for runlength decoder
-#
-# 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.3"
-
-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)
-
-
-MODES = {
- # map imagetype/depth to rawmode
- (1, 8): "P",
- (3, 1): "1",
- (3, 8): "L",
- (2, 16): "BGR;5",
- (2, 24): "BGR",
- (2, 32): "BGRA",
-}
-
-
-def _accept(prefix):
- return prefix[0] == "\0"
-
-##
-# Image plugin for Targa files.
-
-class TgaImageFile(ImageFile.ImageFile):
-
- format = "TGA"
- format_description = "Targa"
-
- def _open(self):
-
- # process header
- s = self.fp.read(18)
-
- id = ord(s[0])
-
- colormaptype = ord(s[1])
- imagetype = ord(s[2])
-
- depth = ord(s[16])
-
- flags = ord(s[17])
-
- self.size = i16(s[12:]), i16(s[14:])
-
- # validate header fields
- if id != 0 or colormaptype not in (0, 1) or\
- self.size[0] <= 0 or self.size[1] <= 0 or\
- depth not in (8, 16, 24, 32):
- raise SyntaxError, "not a TGA file"
-
- # image mode
- if imagetype in (3, 11):
- self.mode = "L"
- if depth == 1:
- self.mode = "1" # ???
- elif imagetype in (1, 9):
- self.mode = "P"
- elif imagetype in (2, 10):
- self.mode = "RGB"
- if depth == 32:
- self.mode = "RGBA"
- else:
- raise SyntaxError, "unknown TGA mode"
-
- # orientation
- orientation = flags & 0x30
- if orientation == 0x20:
- orientation = 1
- elif not orientation:
- orientation = -1
- else:
- raise SyntaxError, "unknown TGA orientation"
-
- if imagetype & 8:
- self.info["compression"] = "tga_rle"
-
- if colormaptype:
- # read palette
- start, size, mapdepth = i16(s[3:]), i16(s[5:]), i16(s[7:])
- if mapdepth == 16:
- self.palette = ImagePalette.raw("BGR;16",
- "\0"*2*start + self.fp.read(2*size))
- elif mapdepth == 24:
- self.palette = ImagePalette.raw("BGR",
- "\0"*3*start + self.fp.read(3*size))
- elif mapdepth == 32:
- self.palette = ImagePalette.raw("BGRA",
- "\0"*4*start + self.fp.read(4*size))
-
- # setup tile descriptor
- try:
- rawmode = MODES[(imagetype&7, depth)]
- if imagetype & 8:
- # compressed
- self.tile = [("tga_rle", (0, 0)+self.size,
- self.fp.tell(), (rawmode, orientation, depth))]
- else:
- self.tile = [("raw", (0, 0)+self.size,
- self.fp.tell(), (rawmode, 0, orientation))]
- except KeyError:
- pass # cannot decode
-
-#
-# registry
-
-Image.register_open("TGA", TgaImageFile, _accept)
-
-Image.register_extension("TGA", ".tga")
diff --git a/PIL/TiffImagePlugin.py b/PIL/TiffImagePlugin.py
deleted file mode 100644
index 178066c..0000000
--- a/PIL/TiffImagePlugin.py
+++ /dev/null
@@ -1,763 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: TiffImagePlugin.py 2803 2006-07-31 19:18:57Z fredrik $
-#
-# TIFF file handling
-#
-# TIFF is a flexible, if somewhat aged, image file format originally
-# defined by Aldus. Although TIFF supports a wide variety of pixel
-# layouts and compression methods, the name doesn't really stand for
-# "thousands of incompatible file formats," it just feels that way.
-#
-# To read TIFF data from a stream, the stream must be seekable. For
-# progressive decoding, make sure to use TIFF files where the tag
-# directory is placed first in the file.
-#
-# History:
-# 1995-09-01 fl Created
-# 1996-05-04 fl Handle JPEGTABLES tag
-# 1996-05-18 fl Fixed COLORMAP support
-# 1997-01-05 fl Fixed PREDICTOR support
-# 1997-08-27 fl Added support for rational tags (from Perry Stoll)
-# 1998-01-10 fl Fixed seek/tell (from Jan Blom)
-# 1998-07-15 fl Use private names for internal variables
-# 1999-06-13 fl Rewritten for PIL 1.0 (1.0)
-# 2000-10-11 fl Additional fixes for Python 2.0 (1.1)
-# 2001-04-17 fl Fixed rewind support (seek to frame 0) (1.2)
-# 2001-05-12 fl Added write support for more tags (from Greg Couch) (1.3)
-# 2001-12-18 fl Added workaround for broken Matrox library
-# 2002-01-18 fl Don't mess up if photometric tag is missing (D. Alan Stewart)
-# 2003-05-19 fl Check FILLORDER tag
-# 2003-09-26 fl Added RGBa support
-# 2004-02-24 fl Added DPI support; fixed rational write support
-# 2005-02-07 fl Added workaround for broken Corel Draw 10 files
-# 2006-01-09 fl Added support for float/double tags (from Russell Nelson)
-#
-# Copyright (c) 1997-2006 by Secret Labs AB. All rights reserved.
-# Copyright (c) 1995-1997 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "1.3.5"
-
-import Image, ImageFile
-import ImagePalette
-
-import array, string, sys
-
-try:
- if sys.byteorder == "little":
- byteorder = "II"
- else:
- byteorder = "MM"
-except AttributeError:
- if ord(array.array("i",[1]).tostring()[0]):
- byteorder = "II"
- else:
- byteorder = "MM"
-
-#
-# --------------------------------------------------------------------
-# Read TIFF files
-
-def il16(c,o=0):
- return ord(c[o]) + (ord(c[o+1])<<8)
-def il32(c,o=0):
- return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24)
-def ol16(i):
- return chr(i&255) + chr(i>>8&255)
-def ol32(i):
- return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
-
-def ib16(c,o=0):
- return ord(c[o+1]) + (ord(c[o])<<8)
-def ib32(c,o=0):
- return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24)
-
-# a few tag names, just to make the code below a bit more readable
-IMAGEWIDTH = 256
-IMAGELENGTH = 257
-BITSPERSAMPLE = 258
-COMPRESSION = 259
-PHOTOMETRIC_INTERPRETATION = 262
-FILLORDER = 266
-IMAGEDESCRIPTION = 270
-STRIPOFFSETS = 273
-SAMPLESPERPIXEL = 277
-ROWSPERSTRIP = 278
-STRIPBYTECOUNTS = 279
-X_RESOLUTION = 282
-Y_RESOLUTION = 283
-PLANAR_CONFIGURATION = 284
-RESOLUTION_UNIT = 296
-SOFTWARE = 305
-DATE_TIME = 306
-ARTIST = 315
-PREDICTOR = 317
-COLORMAP = 320
-EXTRASAMPLES = 338
-SAMPLEFORMAT = 339
-JPEGTABLES = 347
-COPYRIGHT = 33432
-IPTC_NAA_CHUNK = 33723 # newsphoto properties
-PHOTOSHOP_CHUNK = 34377 # photoshop properties
-
-COMPRESSION_INFO = {
- # Compression => pil compression name
- 1: "raw",
- 2: "tiff_ccitt",
- 3: "group3",
- 4: "group4",
- 5: "tiff_lzw",
- 6: "tiff_jpeg", # obsolete
- 7: "jpeg",
- 32771: "tiff_raw_16", # 16-bit padding
- 32773: "packbits"
-}
-
-OPEN_INFO = {
- # (PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample,
- # ExtraSamples) => mode, rawmode
- (0, 1, 1, (1,), ()): ("1", "1;I"),
- (0, 1, 2, (1,), ()): ("1", "1;IR"),
- (0, 1, 1, (8,), ()): ("L", "L;I"),
- (0, 1, 2, (8,), ()): ("L", "L;IR"),
- (1, 1, 1, (1,), ()): ("1", "1"),
- (1, 1, 2, (1,), ()): ("1", "1;R"),
- (1, 1, 1, (8,), ()): ("L", "L"),
- (1, 1, 1, (8,8), (2,)): ("LA", "LA"),
- (1, 1, 2, (8,), ()): ("L", "L;R"),
- (1, 1, 1, (16,), ()): ("I;16", "I;16"),
- (1, 2, 1, (16,), ()): ("I;16S", "I;16S"),
- (1, 2, 1, (32,), ()): ("I", "I;32S"),
- (1, 3, 1, (32,), ()): ("F", "F;32F"),
- (2, 1, 1, (8,8,8), ()): ("RGB", "RGB"),
- (2, 1, 2, (8,8,8), ()): ("RGB", "RGB;R"),
- (2, 1, 1, (8,8,8,8), (0,)): ("RGBX", "RGBX"),
- (2, 1, 1, (8,8,8,8), (1,)): ("RGBA", "RGBa"),
- (2, 1, 1, (8,8,8,8), (2,)): ("RGBA", "RGBA"),
- (2, 1, 1, (8,8,8,8), (999,)): ("RGBA", "RGBA"), # corel draw 10
- (3, 1, 1, (1,), ()): ("P", "P;1"),
- (3, 1, 2, (1,), ()): ("P", "P;1R"),
- (3, 1, 1, (2,), ()): ("P", "P;2"),
- (3, 1, 2, (2,), ()): ("P", "P;2R"),
- (3, 1, 1, (4,), ()): ("P", "P;4"),
- (3, 1, 2, (4,), ()): ("P", "P;4R"),
- (3, 1, 1, (8,), ()): ("P", "P"),
- (3, 1, 1, (8,8), (2,)): ("PA", "PA"),
- (3, 1, 2, (8,), ()): ("P", "P;R"),
- (5, 1, 1, (8,8,8,8), ()): ("CMYK", "CMYK"),
- (6, 1, 1, (8,8,8), ()): ("YCbCr", "YCbCr"),
- (8, 1, 1, (8,8,8), ()): ("LAB", "LAB"),
-}
-
-PREFIXES = ["MM\000\052", "II\052\000", "II\xBC\000"]
-
-def _accept(prefix):
- return prefix[:4] in PREFIXES
-
-##
-# Wrapper for TIFF IFDs.
-
-class ImageFileDirectory:
-
- # represents a TIFF tag directory. to speed things up,
- # we don't decode tags unless they're asked for.
-
- def __init__(self, prefix="II"):
- self.prefix = prefix[:2]
- if self.prefix == "MM":
- self.i16, self.i32 = ib16, ib32
- # FIXME: save doesn't yet support big-endian mode...
- elif self.prefix == "II":
- self.i16, self.i32 = il16, il32
- self.o16, self.o32 = ol16, ol32
- else:
- raise SyntaxError("not a TIFF IFD")
- self.reset()
-
- def reset(self):
- self.tags = {}
- self.tagdata = {}
- self.next = None
-
- # dictionary API (sort of)
-
- def keys(self):
- return self.tagdata.keys() + self.tags.keys()
-
- def items(self):
- items = self.tags.items()
- for tag in self.tagdata.keys():
- items.append((tag, self[tag]))
- return items
-
- def __len__(self):
- return len(self.tagdata) + len(self.tags)
-
- def __getitem__(self, tag):
- try:
- return self.tags[tag]
- except KeyError:
- type, data = self.tagdata[tag] # unpack on the fly
- size, handler = self.load_dispatch[type]
- self.tags[tag] = data = handler(self, data)
- del self.tagdata[tag]
- return data
-
- def get(self, tag, default=None):
- try:
- return self[tag]
- except KeyError:
- return default
-
- def getscalar(self, tag, default=None):
- try:
- value = self[tag]
- if len(value) != 1:
- if tag == SAMPLEFORMAT:
- # work around broken (?) matrox library
- # (from Ted Wright, via Bob Klimek)
- raise KeyError # use default
- raise ValueError, "not a scalar"
- return value[0]
- except KeyError:
- if default is None:
- raise
- return default
-
- def has_key(self, tag):
- return self.tags.has_key(tag) or self.tagdata.has_key(tag)
-
- def __setitem__(self, tag, value):
- if type(value) is not type(()):
- value = (value,)
- self.tags[tag] = value
-
- # load primitives
-
- load_dispatch = {}
-
- def load_byte(self, data):
- l = []
- for i in range(len(data)):
- l.append(ord(data[i]))
- return tuple(l)
- load_dispatch[1] = (1, load_byte)
-
- def load_string(self, data):
- if data[-1:] == '\0':
- data = data[:-1]
- return data
- load_dispatch[2] = (1, load_string)
-
- def load_short(self, data):
- l = []
- for i in range(0, len(data), 2):
- l.append(self.i16(data, i))
- return tuple(l)
- load_dispatch[3] = (2, load_short)
-
- def load_long(self, data):
- l = []
- for i in range(0, len(data), 4):
- l.append(self.i32(data, i))
- return tuple(l)
- load_dispatch[4] = (4, load_long)
-
- def load_rational(self, data):
- l = []
- for i in range(0, len(data), 8):
- l.append((self.i32(data, i), self.i32(data, i+4)))
- return tuple(l)
- load_dispatch[5] = (8, load_rational)
-
- def load_float(self, data):
- a = array.array("f", data)
- if self.prefix != byteorder:
- a.byteswap()
- return tuple(a)
- load_dispatch[11] = (4, load_float)
-
- def load_double(self, data):
- a = array.array("d", data)
- if self.prefix != byteorder:
- a.byteswap()
- return tuple(a)
- load_dispatch[12] = (8, load_double)
-
- def load_undefined(self, data):
- # Untyped data
- return data
- load_dispatch[7] = (1, load_undefined)
-
- def load(self, fp):
- # load tag dictionary
-
- self.reset()
-
- i16 = self.i16
- i32 = self.i32
-
- for i in range(i16(fp.read(2))):
-
- ifd = fp.read(12)
-
- tag, typ = i16(ifd), i16(ifd, 2)
-
- if Image.DEBUG:
- import TiffTags
- tagname = TiffTags.TAGS.get(tag, "unknown")
- typname = TiffTags.TYPES.get(typ, "unknown")
- print "tag: %s (%d)" % (tagname, tag),
- print "- type: %s (%d)" % (typname, typ),
-
- try:
- dispatch = self.load_dispatch[typ]
- except KeyError:
- if Image.DEBUG:
- print "- unsupported type", typ
- continue # ignore unsupported type
-
- size, handler = dispatch
-
- size = size * i32(ifd, 4)
-
- # Get and expand tag value
- if size > 4:
- here = fp.tell()
- fp.seek(i32(ifd, 8))
- data = ImageFile._safe_read(fp, size)
- fp.seek(here)
- else:
- data = ifd[8:8+size]
-
- if len(data) != size:
- raise IOError, "not enough data"
-
- self.tagdata[tag] = typ, data
-
- if Image.DEBUG:
- if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK):
- print "- value: <table: %d bytes>" % size
- else:
- print "- value:", self[tag]
-
- self.next = i32(fp.read(4))
-
- # save primitives
-
- def save(self, fp):
-
- o16 = self.o16
- o32 = self.o32
-
- fp.write(o16(len(self.tags)))
-
- # always write in ascending tag order
- tags = self.tags.items()
- tags.sort()
-
- directory = []
- append = directory.append
-
- offset = fp.tell() + len(self.tags) * 12 + 4
-
- stripoffsets = None
-
- # pass 1: convert tags to binary format
- for tag, value in tags:
-
- if Image.DEBUG:
- import TiffTags
- tagname = TiffTags.TAGS.get(tag, "unknown")
- print "save: %s (%d)" % (tagname, tag),
- print "- value:", value
-
- if type(value[0]) is type(""):
- # string data
- typ = 2
- data = value = string.join(value, "\0") + "\0"
-
- else:
- # integer data
- if tag == STRIPOFFSETS:
- stripoffsets = len(directory)
- typ = 4 # to avoid catch-22
- elif tag in (X_RESOLUTION, Y_RESOLUTION):
- # identify rational data fields
- typ = 5
- else:
- typ = 3
- for v in value:
- if v >= 65536:
- typ = 4
- if typ == 3:
- data = string.join(map(o16, value), "")
- else:
- data = string.join(map(o32, value), "")
-
- # figure out if data fits into the directory
- if len(data) == 4:
- append((tag, typ, len(value), data, ""))
- elif len(data) < 4:
- append((tag, typ, len(value), data + (4-len(data))*"\0", ""))
- else:
- count = len(value)
- if typ == 5:
- count = count / 2 # adjust for rational data field
- append((tag, typ, count, o32(offset), data))
- offset = offset + len(data)
- if offset & 1:
- offset = offset + 1 # word padding
-
- # update strip offset data to point beyond auxiliary data
- if stripoffsets is not None:
- tag, typ, count, value, data = directory[stripoffsets]
- assert not data, "multistrip support not yet implemented"
- value = o32(self.i32(value) + offset)
- directory[stripoffsets] = tag, typ, count, value, data
-
- # pass 2: write directory to file
- for tag, typ, count, value, data in directory:
- if Image.DEBUG > 1:
- print tag, typ, count, repr(value), repr(data)
- fp.write(o16(tag) + o16(typ) + o32(count) + value)
- fp.write("\0\0\0\0") # end of directory
-
- # pass 3: write auxiliary data to file
- for tag, typ, count, value, data in directory:
- fp.write(data)
- if len(data) & 1:
- fp.write("\0")
-
- return offset
-
-##
-# Image plugin for TIFF files.
-
-class TiffImageFile(ImageFile.ImageFile):
-
- format = "TIFF"
- format_description = "Adobe TIFF"
-
- def _open(self):
- "Open the first image in a TIFF file"
-
- # Header
- ifh = self.fp.read(8)
-
- if ifh[:4] not in PREFIXES:
- raise SyntaxError, "not a TIFF file"
-
- # image file directory (tag dictionary)
- self.tag = self.ifd = ImageFileDirectory(ifh[:2])
-
- # setup frame pointers
- self.__first = self.__next = self.ifd.i32(ifh, 4)
- self.__frame = -1
- self.__fp = self.fp
-
- # and load the first frame
- self._seek(0)
-
- def seek(self, frame):
- "Select a given frame as current image"
-
- if frame < 0:
- frame = 0
- self._seek(frame)
-
- def tell(self):
- "Return the current frame number"
-
- return self._tell()
-
- def _seek(self, frame):
-
- self.fp = self.__fp
- if frame < self.__frame:
- # rewind file
- self.__frame = -1
- self.__next = self.__first
- while self.__frame < frame:
- if not self.__next:
- raise EOFError, "no more images in TIFF file"
- self.fp.seek(self.__next)
- self.tag.load(self.fp)
- self.__next = self.tag.next
- self.__frame = self.__frame + 1
- self._setup()
-
- def _tell(self):
-
- return self.__frame
-
- def _decoder(self, rawmode, layer):
- "Setup decoder contexts"
-
- args = None
- if rawmode == "RGB" and self._planar_configuration == 2:
- rawmode = rawmode[layer]
- compression = self._compression
- if compression == "raw":
- args = (rawmode, 0, 1)
- elif compression == "jpeg":
- args = rawmode, ""
- if self.tag.has_key(JPEGTABLES):
- # Hack to handle abbreviated JPEG headers
- self.tile_prefix = self.tag[JPEGTABLES]
- elif compression == "packbits":
- args = rawmode
- elif compression == "tiff_lzw":
- args = rawmode
- if self.tag.has_key(317):
- # Section 14: Differencing Predictor
- self.decoderconfig = (self.tag[PREDICTOR][0],)
-
- return args
-
- def _setup(self):
- "Setup this image object based on current tags"
-
- if self.tag.has_key(0xBC01):
- raise IOError, "Windows Media Photo files not yet supported"
-
- getscalar = self.tag.getscalar
-
- # extract relevant tags
- self._compression = COMPRESSION_INFO[getscalar(COMPRESSION, 1)]
- self._planar_configuration = getscalar(PLANAR_CONFIGURATION, 1)
-
- # photometric is a required tag, but not everyone is reading
- # the specification
- photo = getscalar(PHOTOMETRIC_INTERPRETATION, 0)
-
- fillorder = getscalar(FILLORDER, 1)
-
- if Image.DEBUG:
- print "*** Summary ***"
- print "- compression:", self._compression
- print "- photometric_interpretation:", photo
- print "- planar_configuration:", self._planar_configuration
- print "- fill_order:", fillorder
-
- # size
- xsize = getscalar(IMAGEWIDTH)
- ysize = getscalar(IMAGELENGTH)
- self.size = xsize, ysize
-
- if Image.DEBUG:
- print "- size:", self.size
-
- format = getscalar(SAMPLEFORMAT, 1)
-
- # mode: check photometric interpretation and bits per pixel
- key = (
- photo, format, fillorder,
- self.tag.get(BITSPERSAMPLE, (1,)),
- self.tag.get(EXTRASAMPLES, ())
- )
- if Image.DEBUG:
- print "format key:", key
- try:
- self.mode, rawmode = OPEN_INFO[key]
- except KeyError:
- if Image.DEBUG:
- print "- unsupported format"
- raise SyntaxError, "unknown pixel mode"
-
- if Image.DEBUG:
- print "- raw mode:", rawmode
- print "- pil mode:", self.mode
-
- self.info["compression"] = self._compression
-
- xdpi = getscalar(X_RESOLUTION, (1, 1))
- ydpi = getscalar(Y_RESOLUTION, (1, 1))
-
- if xdpi and ydpi and getscalar(RESOLUTION_UNIT, 1) == 1:
- xdpi = xdpi[0] / (xdpi[1] or 1)
- ydpi = ydpi[0] / (ydpi[1] or 1)
- self.info["dpi"] = xdpi, ydpi
-
- # build tile descriptors
- x = y = l = 0
- self.tile = []
- if self.tag.has_key(STRIPOFFSETS):
- # striped image
- h = getscalar(ROWSPERSTRIP, ysize)
- w = self.size[0]
- a = None
- for o in self.tag[STRIPOFFSETS]:
- if not a:
- a = self._decoder(rawmode, l)
- self.tile.append(
- (self._compression,
- (0, min(y, ysize), w, min(y+h, ysize)),
- o, a))
- y = y + h
- if y >= self.size[1]:
- x = y = 0
- l = l + 1
- a = None
- elif self.tag.has_key(324):
- # tiled image
- w = getscalar(322)
- h = getscalar(323)
- a = None
- for o in self.tag[324]:
- if not a:
- a = self._decoder(rawmode, l)
- # FIXME: this doesn't work if the image size
- # is not a multiple of the tile size...
- self.tile.append(
- (self._compression,
- (x, y, x+w, y+h),
- o, a))
- x = x + w
- if x >= self.size[0]:
- x, y = 0, y + h
- if y >= self.size[1]:
- x = y = 0
- l = l + 1
- a = None
- else:
- if Image.DEBUG:
- print "- unsupported data organization"
- raise SyntaxError("unknown data organization")
-
- # fixup palette descriptor
- if self.mode == "P":
- palette = map(lambda a: chr(a / 256), self.tag[COLORMAP])
- self.palette = ImagePalette.raw("RGB;L", string.join(palette, ""))
-
-#
-# --------------------------------------------------------------------
-# Write TIFF files
-
-# little endian is default
-
-SAVE_INFO = {
- # mode => rawmode, photometrics, sampleformat, bitspersample, extra
- "1": ("1", 1, 1, (1,), None),
- "L": ("L", 1, 1, (8,), None),
- "LA": ("LA", 1, 1, (8,8), 2),
- "P": ("P", 3, 1, (8,), None),
- "PA": ("PA", 3, 1, (8,8), 2),
- "I": ("I;32S", 1, 2, (32,), None),
- "I;16": ("I;16", 1, 1, (16,), None),
- "I;16S": ("I;16S", 1, 2, (16,), None),
- "F": ("F;32F", 1, 3, (32,), None),
- "RGB": ("RGB", 2, 1, (8,8,8), None),
- "RGBX": ("RGBX", 2, 1, (8,8,8,8), 0),
- "RGBA": ("RGBA", 2, 1, (8,8,8,8), 2),
- "CMYK": ("CMYK", 5, 1, (8,8,8,8), None),
- "YCbCr": ("YCbCr", 6, 1, (8,8,8), None),
- "LAB": ("LAB", 8, 1, (8,8,8), None),
-}
-
-def _cvt_res(value):
- # convert value to TIFF rational number -- (numerator, denominator)
- if type(value) in (type([]), type(())):
- assert(len(value) % 2 == 0)
- return value
- if type(value) == type(1):
- return (value, 1)
- value = float(value)
- return (int(value * 65536), 65536)
-
-def _save(im, fp, filename):
-
- try:
- rawmode, photo, format, bits, extra = SAVE_INFO[im.mode]
- except KeyError:
- raise IOError, "cannot write mode %s as TIFF" % im.mode
-
- ifd = ImageFileDirectory()
-
- # tiff header (write via IFD to get everything right)
- fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8))
-
- ifd[IMAGEWIDTH] = im.size[0]
- ifd[IMAGELENGTH] = im.size[1]
-
- # additions written by Greg Couch, gregc@cgl.ucsf.edu
- # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com
- if hasattr(im, 'tag'):
- # preserve tags from original TIFF image file
- for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION):
- if im.tag.tagdata.has_key(key):
- ifd[key] = im.tag.tagdata.get(key)
- if im.encoderinfo.has_key("description"):
- ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"]
- if im.encoderinfo.has_key("resolution"):
- ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \
- = _cvt_res(im.encoderinfo["resolution"])
- if im.encoderinfo.has_key("x resolution"):
- ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"])
- if im.encoderinfo.has_key("y resolution"):
- ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"])
- if im.encoderinfo.has_key("resolution unit"):
- unit = im.encoderinfo["resolution unit"]
- if unit == "inch":
- ifd[RESOLUTION_UNIT] = 2
- elif unit == "cm" or unit == "centimeter":
- ifd[RESOLUTION_UNIT] = 3
- else:
- ifd[RESOLUTION_UNIT] = 1
- if im.encoderinfo.has_key("software"):
- ifd[SOFTWARE] = im.encoderinfo["software"]
- if im.encoderinfo.has_key("date time"):
- ifd[DATE_TIME] = im.encoderinfo["date time"]
- if im.encoderinfo.has_key("artist"):
- ifd[ARTIST] = im.encoderinfo["artist"]
- if im.encoderinfo.has_key("copyright"):
- ifd[COPYRIGHT] = im.encoderinfo["copyright"]
-
- dpi = im.encoderinfo.get("dpi")
- if dpi:
- ifd[RESOLUTION_UNIT] = 1
- ifd[X_RESOLUTION] = _cvt_res(dpi[0])
- ifd[Y_RESOLUTION] = _cvt_res(dpi[1])
-
- if bits != (1,):
- ifd[BITSPERSAMPLE] = bits
- if len(bits) != 1:
- ifd[SAMPLESPERPIXEL] = len(bits)
- if extra is not None:
- ifd[EXTRASAMPLES] = extra
- if format != 1:
- ifd[SAMPLEFORMAT] = format
-
- ifd[PHOTOMETRIC_INTERPRETATION] = photo
-
- if im.mode == "P":
- lut = im.im.getpalette("RGB", "RGB;L")
- ifd[COLORMAP] = tuple(map(lambda v: ord(v) * 256, lut))
-
- # data orientation
- stride = len(bits) * ((im.size[0]*bits[0]+7)/8)
- ifd[ROWSPERSTRIP] = im.size[1]
- ifd[STRIPBYTECOUNTS] = stride * im.size[1]
- ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer
- ifd[COMPRESSION] = 1 # no compression
-
- offset = ifd.save(fp)
-
- ImageFile._save(im, fp, [
- ("raw", (0,0)+im.size, offset, (rawmode, stride, 1))
- ])
-
-#
-# --------------------------------------------------------------------
-# Register
-
-Image.register_open("TIFF", TiffImageFile, _accept)
-Image.register_save("TIFF", _save)
-
-Image.register_extension("TIFF", ".tif")
-Image.register_extension("TIFF", ".tiff")
-
-Image.register_mime("TIFF", "image/tiff")
diff --git a/PIL/TiffTags.py b/PIL/TiffTags.py
deleted file mode 100644
index 2795fc3..0000000
--- a/PIL/TiffTags.py
+++ /dev/null
@@ -1,200 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: TiffTags.py 2340 2005-03-25 08:05:37Z fredrik $
-#
-# TIFF tags
-#
-# This module provides clear-text names for various well-known
-# TIFF tags. the TIFF codec works just fine without it.
-#
-# Copyright (c) Secret Labs AB 1999.
-#
-# See the README file for information on usage and redistribution.
-#
-
-##
-# This module provides constants and clear-text names for various
-# well-known TIFF tags.
-##
-
-##
-# Map tag numbers (or tag number, tag value tuples) to tag names.
-
-TAGS = {
-
- 254: "NewSubfileType",
- 255: "SubfileType",
- 256: "ImageWidth",
- 257: "ImageLength",
- 258: "BitsPerSample",
-
- 259: "Compression",
- (259, 1): "Uncompressed",
- (259, 2): "CCITT 1d",
- (259, 3): "Group 3 Fax",
- (259, 4): "Group 4 Fax",
- (259, 5): "LZW",
- (259, 6): "JPEG",
- (259, 32773): "PackBits",
-
- 262: "PhotometricInterpretation",
- (262, 0): "WhiteIsZero",
- (262, 1): "BlackIsZero",
- (262, 2): "RGB",
- (262, 3): "RGB Palette",
- (262, 4): "Transparency Mask",
- (262, 5): "CMYK",
- (262, 6): "YCbCr",
- (262, 8): "CieLAB",
- (262, 32803): "CFA", # TIFF/EP, Adobe DNG
- (262, 32892): "LinearRaw", # Adobe DNG
-
- 263: "Thresholding",
- 264: "CellWidth",
- 265: "CellHeight",
- 266: "FillOrder",
- 269: "DocumentName",
-
- 270: "ImageDescription",
- 271: "Make",
- 272: "Model",
- 273: "StripOffsets",
- 274: "Orientation",
- 277: "SamplesPerPixel",
- 278: "RowsPerStrip",
- 279: "StripByteCounts",
-
- 280: "MinSampleValue",
- 281: "MaxSampleValue",
- 282: "XResolution",
- 283: "YResolution",
- 284: "PlanarConfiguration",
- (284, 1): "Contigous",
- (284, 2): "Separate",
-
- 285: "PageName",
- 286: "XPosition",
- 287: "YPosition",
- 288: "FreeOffsets",
- 289: "FreeByteCounts",
-
- 290: "GrayResponseUnit",
- 291: "GrayResponseCurve",
- 292: "T4Options",
- 293: "T6Options",
- 296: "ResolutionUnit",
- 297: "PageNumber",
-
- 301: "TransferFunction",
- 305: "Software",
- 306: "DateTime",
-
- 315: "Artist",
- 316: "HostComputer",
- 317: "Predictor",
- 318: "WhitePoint",
- 319: "PrimaryChromaticies",
-
- 320: "ColorMap",
- 321: "HalftoneHints",
- 322: "TileWidth",
- 323: "TileLength",
- 324: "TileOffsets",
- 325: "TileByteCounts",
-
- 332: "InkSet",
- 333: "InkNames",
- 334: "NumberOfInks",
- 336: "DotRange",
- 337: "TargetPrinter",
- 338: "ExtraSamples",
- 339: "SampleFormat",
-
- 340: "SMinSampleValue",
- 341: "SMaxSampleValue",
- 342: "TransferRange",
-
- 347: "JPEGTables",
-
- # obsolete JPEG tags
- 512: "JPEGProc",
- 513: "JPEGInterchangeFormat",
- 514: "JPEGInterchangeFormatLength",
- 515: "JPEGRestartInterval",
- 517: "JPEGLosslessPredictors",
- 518: "JPEGPointTransforms",
- 519: "JPEGQTables",
- 520: "JPEGDCTables",
- 521: "JPEGACTables",
-
- 529: "YCbCrCoefficients",
- 530: "YCbCrSubSampling",
- 531: "YCbCrPositioning",
- 532: "ReferenceBlackWhite",
-
- 33432: "Copyright",
-
- # various extensions (should check specs for "official" names)
- 33723: "IptcNaaInfo",
- 34377: "PhotoshopInfo",
-
- # Adobe DNG
- 50706: "DNGVersion",
- 50707: "DNGBackwardVersion",
- 50708: "UniqueCameraModel",
- 50709: "LocalizedCameraModel",
- 50710: "CFAPlaneColor",
- 50711: "CFALayout",
- 50712: "LinearizationTable",
- 50713: "BlackLevelRepeatDim",
- 50714: "BlackLevel",
- 50715: "BlackLevelDeltaH",
- 50716: "BlackLevelDeltaV",
- 50717: "WhiteLevel",
- 50718: "DefaultScale",
- 50741: "BestQualityScale",
- 50719: "DefaultCropOrigin",
- 50720: "DefaultCropSize",
- 50778: "CalibrationIlluminant1",
- 50779: "CalibrationIlluminant2",
- 50721: "ColorMatrix1",
- 50722: "ColorMatrix2",
- 50723: "CameraCalibration1",
- 50724: "CameraCalibration2",
- 50725: "ReductionMatrix1",
- 50726: "ReductionMatrix2",
- 50727: "AnalogBalance",
- 50728: "AsShotNeutral",
- 50729: "AsShotWhiteXY",
- 50730: "BaselineExposure",
- 50731: "BaselineNoise",
- 50732: "BaselineSharpness",
- 50733: "BayerGreenSplit",
- 50734: "LinearResponseLimit",
- 50735: "CameraSerialNumber",
- 50736: "LensInfo",
- 50737: "ChromaBlurRadius",
- 50738: "AntiAliasStrength",
- 50740: "DNGPrivateData",
- 50741: "MakerNoteSafety",
-}
-
-##
-# Map type numbers to type names.
-
-TYPES = {
-
- 1: "byte",
- 2: "ascii",
- 3: "short",
- 4: "long",
- 5: "rational",
- 6: "signed byte",
- 7: "undefined",
- 8: "signed short",
- 9: "signed long",
- 10: "signed rational",
- 11: "float",
- 12: "double",
-
-}
diff --git a/PIL/WalImageFile.py b/PIL/WalImageFile.py
deleted file mode 100644
index 34e7fc2..0000000
--- a/PIL/WalImageFile.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: WalImageFile.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# WAL file handling
-#
-# History:
-# 2003-04-23 fl created
-#
-# Copyright (c) 2003 by Fredrik Lundh.
-#
-# See the README file for information on usage and redistribution.
-#
-
-# NOTE: This format cannot be automatically recognized, so the reader
-# is not registered for use with Image.open(). To open a WEL file, use
-# the WalImageFile.open() function instead.
-
-# This reader is based on the specification available from:
-# http://www.flipcode.com/tutorials/tut_q2levels.shtml
-# and has been tested with a few sample files found using google.
-
-import Image
-
-def i32(c, o=0):
- return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24)
-
-##
-# Load texture from a Quake2 WAL texture file.
-# <p>
-# By default, a Quake2 standard palette is attached to the texture.
-# To override the palette, use the <b>putpalette</b> method.
-#
-# @param filename WAL file name, or an opened file handle.
-# @return An image instance.
-
-def open(filename):
- # FIXME: modify to return a WalImageFile instance instead of
- # plain Image object ?
-
- if hasattr(filename, "read"):
- fp = filename
- else:
- import __builtin__
- fp = __builtin__.open(filename, "rb")
-
- # read header fields
- header = fp.read(32+24+32+12)
- size = i32(header, 32), i32(header, 36)
- offset = i32(header, 40)
-
- # load pixel data
- fp.seek(offset)
-
- im = Image.fromstring("P", size, fp.read(size[0] * size[1]))
- im.putpalette(quake2palette)
-
- im.format = "WAL"
- im.format_description = "Quake2 Texture"
-
- # strings are null-terminated
- im.info["name"] = header[:32].split("\0", 1)[0]
- next_name = header[56:56+32].split("\0", 1)[0]
- if next_name:
- im.info["next_name"] = next_name
-
- return im
-
-
-quake2palette = (
- # default palette taken from piffo 0.93 by Hans Häggström
- "\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e"
- "\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f"
- "\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c"
- "\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b"
- "\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10"
- "\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07"
- "\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f"
- "\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16"
- "\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d"
- "\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31"
- "\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28"
- "\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07"
- "\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27"
- "\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b"
- "\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01"
- "\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21"
- "\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14"
- "\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07"
- "\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14"
- "\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f"
- "\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34"
- "\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d"
- "\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14"
- "\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01"
- "\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24"
- "\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10"
- "\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01"
- "\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27"
- "\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c"
- "\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a"
- "\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26"
- "\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d"
- "\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01"
- "\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20"
- "\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17"
- "\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07"
- "\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25"
- "\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c"
- "\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01"
- "\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23"
- "\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f"
- "\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b"
- "\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37"
- "\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b"
- "\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01"
- "\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10"
- "\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b"
- "\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20"
-)
-
-if __name__ == "__main__":
- im = open("../hacks/sample.wal")
- print im.info, im.mode, im.size
- im.save("../out.png")
diff --git a/PIL/WmfImagePlugin.py b/PIL/WmfImagePlugin.py
deleted file mode 100644
index 2191160..0000000
--- a/PIL/WmfImagePlugin.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#
-# The Python Imaging Library
-# $Id: WmfImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# WMF stub codec
-#
-# history:
-# 1996-12-14 fl Created
-# 2004-02-22 fl Turned into a stub driver
-# 2004-02-23 fl Added EMF support
-#
-# Copyright (c) Secret Labs AB 1997-2004. All rights reserved.
-# Copyright (c) Fredrik Lundh 1996.
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.2"
-
-import Image, ImageFile
-
-_handler = None
-
-##
-# Install application-specific WMF image handler.
-#
-# @param handler Handler object.
-
-def register_handler(handler):
- global _handler
- _handler = handler
-
-# --------------------------------------------------------------------
-
-def word(c, o=0):
- return ord(c[o]) + (ord(c[o+1])<<8)
-
-def short(c, o=0):
- v = ord(c[o]) + (ord(c[o+1])<<8)
- if v >= 32768:
- v = v - 65536
- return v
-
-def dword(c, o=0):
- return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24)
-
-def long(c, o=0):
- return dword(c, o)
-
-#
-# --------------------------------------------------------------------
-# Read WMF file
-
-def _accept(prefix):
- return (
- prefix[:6] == "\xd7\xcd\xc6\x9a\x00\x00" or
- prefix[:4] == "\x01\x00\x00\x00"
- )
-
-##
-# Image plugin for Windows metafiles.
-
-class WmfStubImageFile(ImageFile.StubImageFile):
-
- format = "WMF"
- format_description = "Windows Metafile"
-
- def _open(self):
-
- # check placable header
- s = self.fp.read(80)
-
- if s[:6] == "\xd7\xcd\xc6\x9a\x00\x00":
-
- # placeable windows metafile
-
- # get units per inch
- inch = word(s, 14)
-
- # get bounding box
- x0 = short(s, 6); y0 = short(s, 8)
- x1 = short(s, 10); y1 = short(s, 12)
-
- # normalize size to 72 dots per inch
- size = (x1 - x0) * 72 / inch, (y1 - y0) * 72 / inch
-
- self.info["wmf_bbox"] = x0, y0, x1, y1
-
- self.info["dpi"] = 72
-
- # print self.mode, self.size, self.info
-
- # sanity check (standard metafile header)
- if s[22:26] != "\x01\x00\t\x00":
- raise SyntaxError("Unsupported WMF file format")
-
- elif long(s) == 1 and s[40:44] == " EMF":
- # enhanced metafile
-
- # get bounding box
- x0 = long(s, 8); y0 = long(s, 12)
- x1 = long(s, 16); y1 = long(s, 20)
-
- # get frame (in 0.01 millimeter units)
- frame = long(s, 24), long(s, 28), long(s, 32), long(s, 36)
-
- # normalize size to 72 dots per inch
- size = x1 - x0, y1 - y0
-
- # calculate dots per inch from bbox and frame
- xdpi = 2540 * (x1 - y0) / (frame[2] - frame[0])
- ydpi = 2540 * (y1 - y0) / (frame[3] - frame[1])
-
- self.info["wmf_bbox"] = x0, y0, x1, y1
-
- if xdpi == ydpi:
- self.info["dpi"] = xdpi
- else:
- self.info["dpi"] = xdpi, ydpi
-
- else:
- raise SyntaxError("Unsupported file format")
-
- self.mode = "RGB"
- self.size = size
-
- loader = self._load()
- if loader:
- loader.open(self)
-
- def _load(self):
- return _handler
-
-
-def _save(im, fp, filename):
- if _handler is None or not hasattr("_handler", "save"):
- raise IOError("WMF save handler not installed")
- _handler.save(im, fp, filename)
-
-#
-# --------------------------------------------------------------------
-# Registry stuff
-
-Image.register_open(WmfStubImageFile.format, WmfStubImageFile, _accept)
-Image.register_save(WmfStubImageFile.format, _save)
-
-Image.register_extension(WmfStubImageFile.format, ".wmf")
-Image.register_extension(WmfStubImageFile.format, ".emf")
diff --git a/PIL/XVThumbImagePlugin.py b/PIL/XVThumbImagePlugin.py
deleted file mode 100644
index 4a9c0d6..0000000
--- a/PIL/XVThumbImagePlugin.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: XVThumbImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# XV Thumbnail file handler by Charles E. "Gene" Cash
-# (gcash@magicnet.net)
-#
-# see xvcolor.c and xvbrowse.c in the sources to John Bradley's XV,
-# available from ftp://ftp.cis.upenn.edu/pub/xv/
-#
-# history:
-# 98-08-15 cec created (b/w only)
-# 98-12-09 cec added color palette
-# 98-12-28 fl added to PIL (with only a few very minor modifications)
-#
-# To do:
-# FIXME: make save work (this requires quantization support)
-#
-
-__version__ = "0.1"
-
-import string
-import Image, ImageFile, ImagePalette
-
-# standard color palette for thumbnails (RGB332)
-PALETTE = ""
-for r in range(8):
- for g in range(8):
- for b in range(4):
- PALETTE = PALETTE + (chr((r*255)/7)+chr((g*255)/7)+chr((b*255)/3))
-
-##
-# Image plugin for XV thumbnail images.
-
-class XVThumbImageFile(ImageFile.ImageFile):
-
- format = "XVThumb"
- format_description = "XV thumbnail image"
-
- def _open(self):
-
- # check magic
- s = self.fp.read(6)
- if s != "P7 332":
- raise SyntaxError, "not an XV thumbnail file"
-
- # skip info comments
- while 1:
- s = string.strip(self.fp.readline())
- if s == "#END_OF_COMMENTS":
- break
-
- # read header line
- s = string.split(self.fp.readline())
-
- self.mode = "P"
- self.size = int(s[0]), int(s[1])
-
- self.palette = ImagePalette.raw("RGB", PALETTE)
-
- self.tile = [
- ("raw", (0, 0)+self.size,
- self.fp.tell(), (self.mode, 0, 1)
- )]
-
-# --------------------------------------------------------------------
-
-Image.register_open("XVThumb", XVThumbImageFile)
diff --git a/PIL/XbmImagePlugin.py b/PIL/XbmImagePlugin.py
deleted file mode 100644
index a1dccea..0000000
--- a/PIL/XbmImagePlugin.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: XbmImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# XBM File handling
-#
-# History:
-# 1995-09-08 fl Created
-# 1996-11-01 fl Added save support
-# 1997-07-07 fl Made header parser more tolerant
-# 1997-07-22 fl Fixed yet another parser bug
-# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4)
-# 2001-05-13 fl Added hotspot handling (based on code from Bernhard Herzog)
-# 2004-02-24 fl Allow some whitespace before first #define
-#
-# Copyright (c) 1997-2004 by Secret Labs AB
-# Copyright (c) 1996-1997 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-__version__ = "0.6"
-
-import re, string
-import Image, ImageFile
-
-# XBM header
-xbm_head = re.compile(
- "\s*#define[ \t]+[^_]*_width[ \t]+(?P<width>[0-9]+)[\r\n]+"
- "#define[ \t]+[^_]*_height[ \t]+(?P<height>[0-9]+)[\r\n]+"
- "(?P<hotspot>"
- "#define[ \t]+[^_]*_x_hot[ \t]+(?P<xhot>[0-9]+)[\r\n]+"
- "#define[ \t]+[^_]*_y_hot[ \t]+(?P<yhot>[0-9]+)[\r\n]+"
- ")?"
- "[\\000-\\377]*_bits\\[\\]"
-)
-
-def _accept(prefix):
- return string.lstrip(prefix)[:7] == "#define"
-
-##
-# Image plugin for X11 bitmaps.
-
-class XbmImageFile(ImageFile.ImageFile):
-
- format = "XBM"
- format_description = "X11 Bitmap"
-
- def _open(self):
-
- m = xbm_head.match(self.fp.read(512))
-
- if m:
-
- xsize = int(m.group("width"))
- ysize = int(m.group("height"))
-
- if m.group("hotspot"):
- self.info["hotspot"] = (
- int(m.group("xhot")), int(m.group("yhot"))
- )
-
- self.mode = "1"
- self.size = xsize, ysize
-
- self.tile = [("xbm", (0, 0)+self.size, m.end(), None)]
-
-
-def _save(im, fp, filename):
-
- if im.mode != "1":
- raise IOError, "cannot write mode %s as XBM" % im.mode
-
- fp.write("#define im_width %d\n" % im.size[0])
- fp.write("#define im_height %d\n" % im.size[1])
-
- hotspot = im.encoderinfo.get("hotspot")
- if hotspot:
- fp.write("#define im_x_hot %d\n" % hotspot[0])
- fp.write("#define im_y_hot %d\n" % hotspot[1])
-
- fp.write("static char im_bits[] = {\n")
-
- ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)])
-
- fp.write("};\n")
-
-
-Image.register_open("XBM", XbmImageFile, _accept)
-Image.register_save("XBM", _save)
-
-Image.register_extension("XBM", ".xbm")
-
-Image.register_mime("XBM", "image/xbm")
diff --git a/PIL/XpmImagePlugin.py b/PIL/XpmImagePlugin.py
deleted file mode 100644
index b8ac01f..0000000
--- a/PIL/XpmImagePlugin.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: XpmImagePlugin.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# XPM File handling
-#
-# History:
-# 1996-12-29 fl Created
-# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7)
-#
-# Copyright (c) Secret Labs AB 1997-2001.
-# Copyright (c) Fredrik Lundh 1996-2001.
-#
-# See the README file for information on usage and redistribution.
-#
-
-
-__version__ = "0.2"
-
-
-import re, string
-import Image, ImageFile, ImagePalette
-
-# XPM header
-xpm_head = re.compile("\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)")
-
-
-def _accept(prefix):
- return prefix[:9] == "/* XPM */"
-
-##
-# Image plugin for X11 pixel maps.
-
-class XpmImageFile(ImageFile.ImageFile):
-
- format = "XPM"
- format_description = "X11 Pixel Map"
-
- def _open(self):
-
- if not _accept(self.fp.read(9)):
- raise SyntaxError, "not an XPM file"
-
- # skip forward to next string
- while 1:
- s = self.fp.readline()
- if not s:
- raise SyntaxError, "broken XPM file"
- m = xpm_head.match(s)
- if m:
- break
-
- self.size = int(m.group(1)), int(m.group(2))
-
- pal = int(m.group(3))
- bpp = int(m.group(4))
-
- if pal > 256 or bpp != 1:
- raise ValueError, "cannot read this XPM file"
-
- #
- # load palette description
-
- palette = ["\0\0\0"] * 256
-
- for i in range(pal):
-
- s = self.fp.readline()
- if s[-2:] == '\r\n':
- s = s[:-2]
- elif s[-1:] in '\r\n':
- s = s[:-1]
-
- c = ord(s[1])
- s = string.split(s[2:-2])
-
- for i in range(0, len(s), 2):
-
- if s[i] == "c":
-
- # process colour key
- rgb = s[i+1]
- if rgb == "None":
- self.info["transparency"] = c
- elif rgb[0] == "#":
- # FIXME: handle colour names (see ImagePalette.py)
- rgb = string.atoi(rgb[1:], 16)
- palette[c] = chr((rgb >> 16) & 255) +\
- chr((rgb >> 8) & 255) +\
- chr(rgb & 255)
- else:
- # unknown colour
- raise ValueError, "cannot read this XPM file"
- break
-
- else:
-
- # missing colour key
- raise ValueError, "cannot read this XPM file"
-
- self.mode = "P"
- self.palette = ImagePalette.raw("RGB", string.join(palette, ""))
-
- self.tile = [("raw", (0, 0)+self.size, self.fp.tell(), ("P", 0, 1))]
-
- def load_read(self, bytes):
-
- #
- # load all image data in one chunk
-
- xsize, ysize = self.size
-
- s = [None] * ysize
-
- for i in range(ysize):
- s[i] = string.ljust(self.fp.readline()[1:xsize+1], xsize)
-
- self.fp = None
-
- return string.join(s, "")
-
-#
-# Registry
-
-Image.register_open("XPM", XpmImageFile, _accept)
-
-Image.register_extension("XPM", ".xpm")
-
-Image.register_mime("XPM", "image/xpm")
diff --git a/PIL/__init__.py b/PIL/__init__.py
deleted file mode 100644
index 3290883..0000000
--- a/PIL/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: __init__.py 2134 2004-10-06 08:55:20Z fredrik $
-#
-# package placeholder
-#
-# Copyright (c) 1999 by Secret Labs AB.
-#
-# See the README file for information on usage and redistribution.
-#
-
-# ;-)
diff --git a/activity/activity.info b/activity/activity.info
index 4ca109b..ad03094 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -4,5 +4,5 @@ license = GPLv2+
icon = activity-imageprocessor
exec = sugar-activity ImageProcessorActivity.ImageProcessorActivity
mime_types = image/bmp;image/gif;image/jpeg;image/png;image/tiff;image/svg+xml
-activity_version = 4
+activity_version = 6
bundle_id = org.laptop.ImageProcessorActivity
diff --git a/activity/activity.info.rtf b/activity/activity.info.rtf
deleted file mode 100644
index a393820..0000000
--- a/activity/activity.info.rtf
+++ /dev/null
Binary files differ
diff --git a/toolbar.py b/toolbar.py
index d08f886..2f71ba8 100644
--- a/toolbar.py
+++ b/toolbar.py
@@ -71,6 +71,11 @@ class ViewToolbar(gtk.Toolbar):
([])),
'paste': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
+
+ ([])),
+ 'original': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+
([])),
}
@@ -147,7 +152,15 @@ class ViewToolbar(gtk.Toolbar):
self.paste_button.connect('clicked', self.paste_cb)
self.insert(self.paste_button, -1)
self.paste_button.show()
+
+ self.original_button = ToolButton('original')
+ self.original_button.set_tooltip(_('original pic'))
+ self.original_button.connect('clicked', self.original_cb)
+ self.insert(self.original_button, -1)
+ self.original_button.show()
+ def original_cb(self, button):
+ self.emit('original')
def zoom_in_cb(self, button):
self.emit('zoom_in')