home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pypil112.zip / PIL-1.1.2.zip / Lib / site-packages / PIL / Image.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2001-12-25  |  36KB  |  967 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.2)
  3.  
  4. VERSION = '1.1.2'
  5.  
  6. class _imaging_not_installed:
  7.     
  8.     def __getattr__(self, id):
  9.         raise ImportError, 'The _imaging C module is not installed'
  10.  
  11.  
  12.  
  13. try:
  14.     import FixTk
  15. except ImportError:
  16.     pass
  17.  
  18.  
  19. try:
  20.     import _imaging
  21.     core = _imaging
  22.     del _imaging
  23. except ImportError:
  24.     core = _imaging_not_installed()
  25.  
  26. import ImagePalette
  27. import os
  28. import string
  29. import sys
  30. from types import IntType, StringType, TupleType
  31.  
  32. def isStringType(t):
  33.     return type(t) is StringType
  34.  
  35.  
  36. def isTupleType(t):
  37.     return type(t) is TupleType
  38.  
  39.  
  40. def isImageType(t):
  41.     return hasattr(t, 'im')
  42.  
  43.  
  44. def isDirectory(f):
  45.     if isStringType(f):
  46.         pass
  47.     return os.path.isdir(f)
  48.  
  49. from operator import isNumberType, isSequenceType
  50. DEBUG = 0
  51. NONE = 0
  52. FLIP_LEFT_RIGHT = 0
  53. FLIP_TOP_BOTTOM = 1
  54. ROTATE_90 = 2
  55. ROTATE_180 = 3
  56. ROTATE_270 = 4
  57. AFFINE = 0
  58. EXTENT = 1
  59. PERSPECTIVE = 2
  60. QUAD = 3
  61. MESH = 4
  62. NONE = 0
  63. NEAREST = 0
  64. ANTIALIAS = 1
  65. BILINEAR = 2
  66. BICUBIC = 3
  67. NONE = 0
  68. NEAREST = 0
  69. ORDERED = 1
  70. RASTERIZE = 2
  71. FLOYDSTEINBERG = 3
  72. WEB = 0
  73. ADAPTIVE = 1
  74. NORMAL = 0
  75. SEQUENCE = 1
  76. CONTAINER = 2
  77. ID = []
  78. OPEN = { }
  79. MIME = { }
  80. SAVE = { }
  81. EXTENSION = { }
  82. _MODEINFO = {
  83.     '1': ('L', 'L', ('1',)),
  84.     'L': ('L', 'L', ('L',)),
  85.     'I': ('L', 'I', ('I',)),
  86.     'F': ('L', 'F', ('F',)),
  87.     'P': ('RGB', 'L', ('P',)),
  88.     'RGB': ('RGB', 'L', ('R', 'G', 'B')),
  89.     'RGBX': ('RGB', 'L', ('R', 'G', 'B', 'X')),
  90.     'RGBA': ('RGB', 'L', ('R', 'G', 'B', 'A')),
  91.     'CMYK': ('RGB', 'L', ('C', 'M', 'Y', 'K')),
  92.     'YCbCr': ('RGB', 'L', ('Y', 'Cb', 'Cr')) }
  93. MODES = _MODEINFO.keys()
  94. MODES.sort()
  95.  
  96. def getmodebase(mode):
  97.     return _MODEINFO[mode][0]
  98.  
  99.  
  100. def getmodetype(mode):
  101.     return _MODEINFO[mode][1]
  102.  
  103.  
  104. def getmodebands(mode):
  105.     return len(_MODEINFO[mode][2])
  106.  
  107. _initialized = 0
  108.  
  109. def preinit():
  110.     '''Load standard file format drivers.'''
  111.     global _initialized
  112.     if _initialized >= 1:
  113.         return None
  114.     
  115.     for m in ('Bmp', 'Gif', 'Jpeg', 'Ppm', 'Png', 'Tiff'):
  116.         
  117.         try:
  118.             __import__('%sImagePlugin' % m, globals(), locals(), [])
  119.         except ImportError:
  120.             pass
  121.  
  122.     
  123.     _initialized = 1
  124.  
  125.  
  126. def init():
  127.     '''Load all file format drivers.'''
  128.     global _initialized
  129.     if _initialized >= 2:
  130.         return None
  131.     
  132.     visited = { }
  133.     directories = sys.path + [
  134.         os.path.dirname(__file__)]
  135.     for directory in filter(isDirectory, directories):
  136.         fullpath = os.path.abspath(directory)
  137.         if visited.has_key(fullpath):
  138.             continue
  139.         
  140.         for file in os.listdir(directory):
  141.             if file[-14:] == 'ImagePlugin.py':
  142.                 (f, e) = os.path.splitext(file)
  143.                 
  144.                 try:
  145.                     sys.path.insert(0, directory)
  146.                     
  147.                     try:
  148.                         __import__(f, globals(), locals(), [])
  149.                     finally:
  150.                         del sys.path[0]
  151.  
  152.                 except ImportError:
  153.                     if DEBUG:
  154.                         print 'Image: failed to import', f, ':', sys.exc_value
  155.                     
  156.                 except:
  157.                     DEBUG
  158.  
  159.             
  160.         
  161.         visited[fullpath] = None
  162.     
  163.     if OPEN or SAVE:
  164.         _initialized = 2
  165.     
  166.  
  167.  
  168. def _getdecoder(mode, decoder_name, args, extra = ()):
  169.     if args is None:
  170.         args = ()
  171.     elif type(args) != TupleType:
  172.         args = (args,)
  173.     
  174.     
  175.     try:
  176.         decoder = getattr(core, decoder_name + '_decoder')
  177.         return apply(decoder, (mode,) + args + extra)
  178.     except AttributeError:
  179.         raise IOError, 'decoder %s not available' % decoder_name
  180.  
  181.  
  182.  
  183. def _getencoder(mode, encoder_name, args, extra = ()):
  184.     if args is None:
  185.         args = ()
  186.     elif type(args) != TupleType:
  187.         args = (args,)
  188.     
  189.     
  190.     try:
  191.         encoder = getattr(core, encoder_name + '_encoder')
  192.         return apply(encoder, (mode,) + args + extra)
  193.     except AttributeError:
  194.         raise IOError, 'encoder %s not available' % encoder_name
  195.  
  196.  
  197.  
  198. class _E:
  199.     
  200.     def __init__(self, data):
  201.         self.data = data
  202.  
  203.     
  204.     def __coerce__(self, other):
  205.         return (self, _E(other))
  206.  
  207.     
  208.     def __add__(self, other):
  209.         return _E((self.data, '__add__', other.data))
  210.  
  211.     
  212.     def __mul__(self, other):
  213.         return _E((self.data, '__mul__', other.data))
  214.  
  215.  
  216.  
  217. def _getscaleoffset(expr):
  218.     stub = [
  219.         'stub']
  220.     data = expr(_E(stub)).data
  221.     
  222.     try:
  223.         (a, b, c) = data
  224.         if a is stub and b == '__mul__' and isNumberType(c):
  225.             return (c, 0.0)
  226.         
  227.         if a is stub and b == '__add__' and isNumberType(c):
  228.             return (1.0, c)
  229.     except TypeError:
  230.         pass
  231.  
  232.     
  233.     try:
  234.         (a, b, c) = ()
  235.         d = data
  236.         e = None
  237.         if a is stub and b == '__mul__' and isNumberType(c) and d == '__add__' and isNumberType(e):
  238.             return (c, e)
  239.     except TypeError:
  240.         pass
  241.  
  242.     raise ValueError, 'illegal expression'
  243.  
  244.  
  245. class Image:
  246.     format = None
  247.     format_description = None
  248.     
  249.     def __init__(self):
  250.         self.im = None
  251.         self.mode = ''
  252.         self.size = (0, 0)
  253.         self.palette = None
  254.         self.info = { }
  255.         self.category = NORMAL
  256.         self.readonly = 0
  257.  
  258.     
  259.     def _new(self, im):
  260.         new = Image()
  261.         new.im = im
  262.         new.mode = im.mode
  263.         new.size = im.size
  264.         new.palette = self.palette
  265.         
  266.         try:
  267.             new.info = self.info.copy()
  268.         except AttributeError:
  269.             new.info = { }
  270.             for k, v in self.info:
  271.                 new.info[k] = v
  272.             
  273.  
  274.         return new
  275.  
  276.     _makeself = _new
  277.     
  278.     def _copy(self):
  279.         self.load()
  280.         self.im = self.im.copy()
  281.         self.readonly = 0
  282.  
  283.     
  284.     def _dump(self, file = None, format = None):
  285.         import tempfile
  286.         if not file:
  287.             file = tempfile.mktemp()
  288.         
  289.         self.load()
  290.         if not format or format == 'PPM':
  291.             self.im.save_ppm(file)
  292.         else:
  293.             file = file + '.' + format
  294.             self.save(file, format)
  295.         return file
  296.  
  297.     
  298.     def tostring(self, encoder_name = 'raw', *args):
  299.         '''Return image as a binary string'''
  300.         if len(args) == 1 and isTupleType(args[0]):
  301.             args = args[0]
  302.         
  303.         if encoder_name == 'raw' and args == ():
  304.             args = self.mode
  305.         
  306.         self.load()
  307.         e = _getencoder(self.mode, encoder_name, args)
  308.         e.setimage(self.im)
  309.         data = []
  310.         while 1:
  311.             (l, s, d) = e.encode(65536)
  312.             data.append(d)
  313.             if s:
  314.                 break
  315.             
  316.         if s < 0:
  317.             raise RuntimeError, 'encoder error %d in tostring' % s
  318.         
  319.         return string.join(data, '')
  320.  
  321.     
  322.     def tobitmap(self, name = 'image'):
  323.         '''Return image as an XBM bitmap'''
  324.         self.load()
  325.         if self.mode != '1':
  326.             raise ValueError, 'not a bitmap'
  327.         
  328.         data = self.tostring('xbm')
  329.         return string.join([
  330.             '#define %s_width %d\n' % (name, self.size[0]),
  331.             '#define %s_height %d\n' % (name, self.size[1]),
  332.             'static char %s_bits[] = {\n' % name,
  333.             data,
  334.             '};'], '')
  335.  
  336.     
  337.     def fromstring(self, data, decoder_name = 'raw', *args):
  338.         '''Load data to image from binary string'''
  339.         if len(args) == 1 and isTupleType(args[0]):
  340.             args = args[0]
  341.         
  342.         if decoder_name == 'raw' and args == ():
  343.             args = self.mode
  344.         
  345.         d = _getdecoder(self.mode, decoder_name, args)
  346.         d.setimage(self.im)
  347.         s = d.decode(data)
  348.         if s[0] >= 0:
  349.             raise ValueError, 'not enough image data'
  350.         
  351.         if s[1] != 0:
  352.             raise ValueError, 'cannot decode image data'
  353.         
  354.  
  355.     
  356.     def load(self):
  357.         if self.im and self.palette and self.palette.rawmode:
  358.             self.im.putpalette(self.palette.rawmode, self.palette.data)
  359.             self.palette.mode = 'RGB'
  360.             self.palette.rawmode = None
  361.             if self.info.has_key('transparency'):
  362.                 self.im.putpalettealpha(self.info['transparency'], 0)
  363.                 self.palette.mode = 'RGBA'
  364.             
  365.         
  366.  
  367.     
  368.     def convert(self, mode = None, data = None, dither = None, palette = WEB, colors = 256):
  369.         '''Convert to other pixel format'''
  370.         if not mode:
  371.             if self.mode == 'P':
  372.                 self.load()
  373.                 if self.palette:
  374.                     mode = self.palette.mode
  375.                 else:
  376.                     mode = 'RGB'
  377.             else:
  378.                 return self.copy()
  379.         
  380.         self.load()
  381.         if data:
  382.             if mode not in ('L', 'RGB'):
  383.                 raise ValueError, 'illegal conversion'
  384.             
  385.             im = self.im.convert_matrix(mode, data)
  386.             return self._new(im)
  387.         
  388.         if mode == 'P' and palette == ADAPTIVE:
  389.             im = self.im.quantize(colors)
  390.             return self._new(im)
  391.         
  392.         if dither is None:
  393.             dither = FLOYDSTEINBERG
  394.         
  395.         
  396.         try:
  397.             im = self.im.convert(mode, dither)
  398.         except ValueError:
  399.             
  400.             try:
  401.                 im = self.im.convert(getmodebase(self.mode))
  402.                 im = im.convert(mode, dither)
  403.             except KeyError:
  404.                 raise ValueError, 'illegal conversion'
  405.  
  406.  
  407.         return self._new(im)
  408.  
  409.     
  410.     def quantize(self, colors = 256, method = 0, kmeans = 0):
  411.         self.load()
  412.         im = self.im.quantize(colors, method, kmeans)
  413.         return self._new(im)
  414.  
  415.     
  416.     def copy(self):
  417.         '''Copy raster data'''
  418.         self.load()
  419.         im = self.im.copy()
  420.         return self._new(im)
  421.  
  422.     
  423.     def crop(self, box = None):
  424.         '''Crop region from image'''
  425.         self.load()
  426.         if box is None:
  427.             return self.copy()
  428.         
  429.         return _ImageCrop(self, box)
  430.  
  431.     
  432.     def draft(self, mode, size):
  433.         '''Configure image decoder'''
  434.         pass
  435.  
  436.     
  437.     def filter(self, kernel):
  438.         '''Apply environment filter to image'''
  439.         if self.mode == 'P':
  440.             raise ValueError, 'cannot filter palette images'
  441.         
  442.         self.load()
  443.         id = kernel.id
  444.         if self.im.bands == 1:
  445.             return self._new(self.im.filter(id))
  446.         
  447.         ims = []
  448.         for c in range(self.im.bands):
  449.             ims.append(self._new(self.im.getband(c).filter(id)))
  450.         
  451.         return merge(self.mode, ims)
  452.  
  453.     
  454.     def getbands(self):
  455.         '''Get band names'''
  456.         return _MODEINFO[self.mode][2]
  457.  
  458.     
  459.     def getbbox(self):
  460.         '''Get bounding box of actual data (non-zero pixels) in image'''
  461.         self.load()
  462.         return self.im.getbbox()
  463.  
  464.     
  465.     def getdata(self, band = None):
  466.         '''Get image data as sequence object.'''
  467.         self.load()
  468.         if band is not None:
  469.             return self.im.getband(band)
  470.         
  471.         return self.im
  472.  
  473.     
  474.     def getextrema(self):
  475.         '''Get min/max value'''
  476.         self.load()
  477.         if self.im.bands > 1:
  478.             extrema = []
  479.             for i in range(self.im.bands):
  480.                 extrema.append(self.im.getband(i).getextrema())
  481.             
  482.             return tuple(extrema)
  483.         
  484.         return self.im.getextrema()
  485.  
  486.     
  487.     def getpixel(self, xy):
  488.         '''Get pixel value'''
  489.         self.load()
  490.         return self.im.getpixel(xy)
  491.  
  492.     
  493.     def getprojection(self):
  494.         '''Get projection to x and y axes'''
  495.         self.load()
  496.         (x, y) = self.im.getprojection()
  497.         return (map(ord, x), map(ord, y))
  498.  
  499.     
  500.     def histogram(self, mask = None, extrema = None):
  501.         '''Take histogram of image'''
  502.         self.load()
  503.         if mask:
  504.             mask.load()
  505.             return self.im.histogram((0, 0), mask.im)
  506.         
  507.         if self.mode in ('I', 'F'):
  508.             if extrema is None:
  509.                 extrema = self.getextrema()
  510.             
  511.             return self.im.histogram(extrema)
  512.         
  513.         return self.im.histogram()
  514.  
  515.     
  516.     def offset(self, xoffset, yoffset = None):
  517.         '''(deprecated) Offset image in horizontal and/or vertical direction'''
  518.         import ImageChops
  519.         return ImageChops.offset(self, xoffset, yoffset)
  520.  
  521.     
  522.     def paste(self, im, box = None, mask = None):
  523.         '''Paste other image into region'''
  524.         if box is None:
  525.             box = (0, 0) + self.size
  526.         
  527.         if len(box) == 2:
  528.             if isImageType(im):
  529.                 box = box + (box[0] + im.size[0], box[1] + im.size[1])
  530.             else:
  531.                 box = box + (box[0] + mask.size[0], box[1] + mask.size[1])
  532.         
  533.         if isImageType(im):
  534.             im.load()
  535.             if self.mode != im.mode:
  536.                 if self.mode != 'RGB' or im.mode not in ('RGBA', 'RGBa'):
  537.                     im = im.convert(self.mode)
  538.                 
  539.             
  540.             im = im.im
  541.         
  542.         self.load()
  543.         if self.readonly:
  544.             self._copy()
  545.         
  546.         if mask:
  547.             mask.load()
  548.             self.im.paste(im, box, mask.im)
  549.         else:
  550.             self.im.paste(im, box)
  551.  
  552.     
  553.     def point(self, lut, mode = None):
  554.         '''Map image through lookup table'''
  555.         if self.mode in ('I', 'F'):
  556.             (scale, offset) = _getscaleoffset(lut)
  557.             self.load()
  558.             im = self.im.point_transform(scale, offset)
  559.         else:
  560.             self.load()
  561.             if not isSequenceType(lut):
  562.                 lut = map(lut, range(256)) * self.im.bands
  563.             
  564.             im = self.im.point(lut, mode)
  565.         return self._new(im)
  566.  
  567.     
  568.     def putalpha(self, im):
  569.         '''Set alpha layer'''
  570.         if self.mode != 'RGBA' or im.mode not in ('1', 'L'):
  571.             raise ValueError, 'illegal image mode'
  572.         
  573.         im.load()
  574.         self.load()
  575.         if im.mode == '1':
  576.             im = im.convert('L')
  577.         
  578.         self.im.putband(im.im, 3)
  579.  
  580.     
  581.     def putdata(self, data, scale = 1.0, offset = 0.0):
  582.         '''Put data from a sequence object into an image.'''
  583.         self.load()
  584.         self.im.putdata(data, scale, offset)
  585.  
  586.     
  587.     def putpalette(self, data, rawmode = 'RGB'):
  588.         '''Put palette data into an image.'''
  589.         if self.mode not in ('L', 'P'):
  590.             raise ValueError, 'illegal image mode'
  591.         
  592.         if type(data) != StringType:
  593.             data = string.join(map(chr, data), '')
  594.         
  595.         self.mode = 'P'
  596.         self.palette = ImagePalette.raw(rawmode, data)
  597.         self.palette.mode = 'RGB'
  598.  
  599.     
  600.     def putpixel(self, xy, value):
  601.         '''Set pixel value'''
  602.         self.load()
  603.         return self.im.putpixel(xy, value)
  604.  
  605.     
  606.     def resize(self, size, resample = NEAREST):
  607.         '''Resize image'''
  608.         if resample not in (NEAREST, BILINEAR, BICUBIC, ANTIALIAS):
  609.             raise ValueError, 'unknown resampling filter'
  610.         
  611.         self.load()
  612.         if self.mode in ('1', 'P'):
  613.             resample = NEAREST
  614.         
  615.         if resample == ANTIALIAS:
  616.             (x0, y0) = self.size
  617.             (x1, y1) = size
  618.             
  619.             try:
  620.                 if x0 * y1 < x1 * y0:
  621.                     im = self.im.vstretch(x0, y1).hstretch(x1, y1)
  622.                 else:
  623.                     im = self.im.hstretch(x1, y0).vstretch(x1, y1)
  624.             except AttributeError:
  625.                 raise ValueError, 'unsupported resampling filter'
  626.  
  627.         else:
  628.             im = self.im.resize(size, resample)
  629.         return self._new(im)
  630.  
  631.     
  632.     def rotate(self, angle, resample = NEAREST):
  633.         '''Rotate image.  Angle given as degrees counter-clockwise.'''
  634.         if resample not in (NEAREST, BILINEAR, BICUBIC):
  635.             raise ValueError, 'unknown resampling filter'
  636.         
  637.         self.load()
  638.         if self.mode in ('1', 'P'):
  639.             resample = NEAREST
  640.         
  641.         return self._new(self.im.rotate(angle, resample))
  642.  
  643.     
  644.     def save(self, fp, format = None, **params):
  645.         '''Save image to file or stream'''
  646.         if isStringType(fp):
  647.             import __builtin__
  648.             filename = fp
  649.             fp = __builtin__.open(fp, 'wb')
  650.             close = 1
  651.         else:
  652.             filename = ''
  653.             close = 0
  654.         self.encoderinfo = params
  655.         self.encoderconfig = ()
  656.         self.load()
  657.         preinit()
  658.         ext = string.lower(os.path.splitext(filename)[1])
  659.         
  660.         try:
  661.             if not format:
  662.                 format = EXTENSION[ext]
  663.             
  664.             SAVE[string.upper(format)](self, fp, filename)
  665.         except KeyError:
  666.             v = None
  667.             init()
  668.             if not format:
  669.                 format = EXTENSION[ext]
  670.             
  671.             SAVE[string.upper(format)](self, fp, filename)
  672.  
  673.         if close:
  674.             fp.close()
  675.         
  676.  
  677.     
  678.     def seek(self, frame):
  679.         '''Seek to given frame in sequence file'''
  680.         if frame != 0:
  681.             raise EOFError
  682.         
  683.  
  684.     
  685.     def show(self, title = None, command = None):
  686.         '''Display image (for debug purposes only)'''
  687.         
  688.         try:
  689.             import ImageTk
  690.             ImageTk._show(self, title)
  691.         except:
  692.             _showxv(self, title, command)
  693.  
  694.  
  695.     
  696.     def split(self):
  697.         '''Split image into bands'''
  698.         ims = []
  699.         self.load()
  700.         for i in range(self.im.bands):
  701.             ims.append(self._new(self.im.getband(i)))
  702.         
  703.         return tuple(ims)
  704.  
  705.     
  706.     def tell(self):
  707.         '''Return current frame number'''
  708.         return 0
  709.  
  710.     
  711.     def thumbnail(self, size, resample = ANTIALIAS):
  712.         '''Create thumbnail representation (modifies image in place)'''
  713.         (x, y) = self.size
  714.         if x > size[0]:
  715.             y = y * size[0] / x
  716.             x = size[0]
  717.         
  718.         if y > size[1]:
  719.             x = x * size[1] / y
  720.             y = size[1]
  721.         
  722.         size = (x, y)
  723.         if size == self.size:
  724.             return None
  725.         
  726.         self.draft(None, size)
  727.         self.load()
  728.         
  729.         try:
  730.             im = self.resize(size, resample)
  731.         except ValueError:
  732.             if resample != ANTIALIAS:
  733.                 raise 
  734.             
  735.             im = self.resize(size, NEAREST)
  736.  
  737.         self.im = im.im
  738.         self.mode = im.mode
  739.         self.size = size
  740.         self.readonly = 0
  741.  
  742.     
  743.     def transform(self, size, method, data, resample = NEAREST, fill = 1):
  744.         '''Transform image'''
  745.         im = new(self.mode, size, None)
  746.         if method == MESH:
  747.             for box, quad in data:
  748.                 im._Image__transformer(box, self, QUAD, quad, resample, fill)
  749.             
  750.         else:
  751.             im._Image__transformer((0, 0) + size, self, method, data, resample, fill)
  752.         return im
  753.  
  754.     
  755.     def __transformer(self, box, image, method, data, resample = NEAREST, fill = 1):
  756.         '''Transform into current image'''
  757.         w = box[2] - box[0]
  758.         h = box[3] - box[1]
  759.         if method == AFFINE:
  760.             data = (data[2], data[0], data[1], data[5], data[3], data[4])
  761.         elif method == EXTENT:
  762.             (x0, y0, x1, y1) = data
  763.             xs = float(x1 - x0) / w
  764.             ys = float(y1 - y0) / h
  765.             method = AFFINE
  766.             data = (x0 + xs / 2, xs, 0, y0 + ys / 2, 0, ys)
  767.         elif method == QUAD:
  768.             nw = data[0:2]
  769.             sw = data[2:4]
  770.             se = data[4:6]
  771.             ne = data[6:8]
  772.             (x0, y0) = nw
  773.             As = 1.0 / w
  774.             At = 1.0 / h
  775.             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)
  776.         else:
  777.             raise ValueError, 'unknown transformation method'
  778.         if resample not in (NEAREST, BILINEAR, BICUBIC):
  779.             raise ValueError, 'unknown resampling filter'
  780.         
  781.         image.load()
  782.         self.load()
  783.         if image.mode in ('1', 'P'):
  784.             resample = NEAREST
  785.         
  786.         self.im.transform2(box, image.im, method, data, resample, fill)
  787.  
  788.     
  789.     def transpose(self, method):
  790.         '''Transpose image (flip or rotate in 90 degree steps)'''
  791.         self.load()
  792.         im = self.im.transpose(method)
  793.         return self._new(im)
  794.  
  795.  
  796.  
  797. class _ImageCrop(Image):
  798.     
  799.     def __init__(self, im, box):
  800.         Image.__init__(self)
  801.         self.mode = im.mode
  802.         self.size = (box[2] - box[0], box[3] - box[1])
  803.         self._ImageCrop__crop = box
  804.         self.im = im.im
  805.  
  806.     
  807.     def load(self):
  808.         if self._ImageCrop__crop:
  809.             self.im = self.im.crop(self._ImageCrop__crop)
  810.             self._ImageCrop__crop = None
  811.         
  812.  
  813.  
  814.  
  815. def _wedge():
  816.     '''Create greyscale wedge (for debugging only)'''
  817.     return Image()._new(core.wedge('L'))
  818.  
  819.  
  820. def new(mode, size, color = 0):
  821.     '''Create a new image'''
  822.     if color is None:
  823.         return Image()._new(core.new(mode, size))
  824.     
  825.     return Image()._new(core.fill(mode, size, color))
  826.  
  827.  
  828. def fromstring(mode, size, data, decoder_name = 'raw', *args):
  829.     '''Load image from string'''
  830.     if len(args) == 1 and isTupleType(args[0]):
  831.         args = args[0]
  832.     
  833.     if decoder_name == 'raw' and args == ():
  834.         args = mode
  835.     
  836.     im = new(mode, size)
  837.     im.fromstring(data, decoder_name, args)
  838.     return im
  839.  
  840.  
  841. def open(fp, mode = 'r'):
  842.     '''Open an image file, without loading the raster data'''
  843.     if mode != 'r':
  844.         raise ValueError, 'bad mode'
  845.     
  846.     if isStringType(fp):
  847.         import __builtin__
  848.         filename = fp
  849.         fp = __builtin__.open(fp, 'rb')
  850.     else:
  851.         filename = ''
  852.     prefix = fp.read(16)
  853.     preinit()
  854.     for i in ID:
  855.         
  856.         try:
  857.             (factory, accept) = OPEN[i]
  858.             if not accept or accept(prefix):
  859.                 fp.seek(0)
  860.                 return factory(fp, filename)
  861.         except (SyntaxError, IndexError, TypeError):
  862.             pass
  863.  
  864.     
  865.     init()
  866.     for i in ID:
  867.         
  868.         try:
  869.             (factory, accept) = OPEN[i]
  870.             if not accept or accept(prefix):
  871.                 fp.seek(0)
  872.                 return factory(fp, filename)
  873.         except (SyntaxError, IndexError, TypeError):
  874.             pass
  875.  
  876.     
  877.     raise IOError, 'cannot identify image file'
  878.  
  879.  
  880. def blend(im1, im2, alpha):
  881.     '''Interpolate between images.'''
  882.     if alpha <= 0.0:
  883.         return im1
  884.     elif alpha >= 1.0:
  885.         return im2
  886.     
  887.     im1.load()
  888.     im2.load()
  889.     return im1._new(core.blend(im1.im, im2.im, alpha))
  890.  
  891.  
  892. def composite(image1, image2, mask):
  893.     '''Create composite image by blending images using a transparency mask'''
  894.     image = image2.copy()
  895.     image.paste(image1, None, mask)
  896.     return image
  897.  
  898.  
  899. def eval(image, *args):
  900.     '''Evaluate image expression'''
  901.     return image.point(args[0])
  902.  
  903.  
  904. def merge(mode, bands):
  905.     '''Merge a set of single band images into a new multiband image.'''
  906.     if getmodebands(mode) != len(bands) or '*' in mode:
  907.         raise ValueError, 'wrong number of bands'
  908.     
  909.     for im in bands[1:]:
  910.         if im.mode != getmodetype(mode):
  911.             raise ValueError, 'mode mismatch'
  912.         
  913.         if im.size != bands[0].size:
  914.             raise ValueError, 'size mismatch'
  915.         
  916.     
  917.     im = core.new(mode, bands[0].size)
  918.     for i in range(getmodebands(mode)):
  919.         bands[i].load()
  920.         im.putband(bands[i].im, i)
  921.     
  922.     return bands[0]._new(im)
  923.  
  924.  
  925. def register_open(id, factory, accept = None):
  926.     id = string.upper(id)
  927.     ID.append(id)
  928.     OPEN[id] = (factory, accept)
  929.  
  930.  
  931. def register_mime(id, mimetype):
  932.     MIME[string.upper(id)] = mimetype
  933.  
  934.  
  935. def register_save(id, driver):
  936.     SAVE[string.upper(id)] = driver
  937.  
  938.  
  939. def register_extension(id, extension):
  940.     EXTENSION[string.lower(extension)] = string.upper(id)
  941.  
  942.  
  943. def _showxv(self, title = None, command = None):
  944.     if os.name == 'nt':
  945.         format = 'BMP'
  946.         if not command:
  947.             command = 'start'
  948.         
  949.     else:
  950.         format = None
  951.         if not command:
  952.             command = 'xv'
  953.             if title:
  954.                 command = command + ' -name "%s"' % title
  955.             
  956.         
  957.     base = getmodebase(self.mode)
  958.     if base != self.mode and self.mode != '1':
  959.         file = self.convert(base)._dump(format = format)
  960.     else:
  961.         file = self._dump(format = format)
  962.     if os.name == 'nt':
  963.         os.system('%s %s' % (command, file))
  964.     else:
  965.         os.system('(%s %s; rm -f %s)&' % (command, file, file))
  966.  
  967.