diff options
Diffstat (limited to 'PIL/PsdImagePlugin.py')
-rw-r--r-- | PIL/PsdImagePlugin.py | 271 |
1 files changed, 0 insertions, 271 deletions
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") |