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 _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))]
Esempio n. 3
0
    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))]
Esempio n. 4
0
def write(fieldname, input, timestep):

  "Transforms mm5 input to GIF file"

  field = input.get_field(fieldname, timestep)
  if (field == -1):
    return -1

  outdat = fieldname + `timestep`

  dim_ns = field['dim_ns']
  dim_ew = field['dim_ew']
  dim_z = field['dim_z']

  dim_k = dim_z

  arrfield = field['values']
  for k in xrange(dim_k):
    maxval = max(ravel(arrfield[k]))
    minval = min(ravel(arrfield[k]))
    rprec  = (maxval - minval) / 255.0
    arrfield[k] = (arrfield[k] - minval) / rprec

  arrfield = arrfield.astype(Int32)

  try:
    palette = ImagePalette.load('rgb.txt')
  except:
    print "Using System color palette."
    print "To use your own color palette, copy the file /disk1/utenti/giuliani/python_mm5/pillo/etc/rgb.txt"
    print "in this directory and modify as needed."
    palette = ImagePalette.load('/disk1/utenti/giuliani/python_mm5/pillo/etc/rgb.txt')

  for k in xrange(dim_k):
    outname = outdat + '_' + `k` + '.gif'
    try:
      img = Image.fromstring("I", (dim_ew, dim_ns), arrfield[k].tostring())
    except (ValueError, IOError), e:
      print "Cannot convert to GIF: ", e
      return -1
    img = img.transpose(Image.FLIP_LEFT_RIGHT)
    img = img.transpose(Image.ROTATE_180)
    img = img.convert("L")
    img = img.resize((dim_ew*8, dim_ns*8))
    img = img.filter(ImageFilter.SMOOTH_MORE)
    img.putpalette(palette)
    try:
      img.save(outname, "GIF")
    except IOError, e:
      print "Cannot write GIF file: ", e
      return -1
    def _open(self):

        # check magic
        s = self.fp.read(6)
        if s != "P7 332":
            raise SyntaxError, "not an XV thumbnail file"

        # Skip to beginning of next line
        self.fp.readline()

        # skip info comments
        while 1:
            s = self.fp.readline()
            if not s:
                raise SyntaxError, "Unexpected EOF reading XV thumbnail file"
            if s[0] != '#':
                break

        # parse header line (already read)
        s = string.split(s.strip())

        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))]
Esempio n. 6
0
    def _open(self):

        # check magic
        s = self.fp.read(6)
        if s != "P7 332":
            raise SyntaxError("not an XV thumbnail file")

        # Skip to beginning of next line
        self.fp.safereadline(512)

        # skip info comments
        while True:
            s = self.fp.safereadline(65536)
            if not s:
                raise SyntaxError("Unexpected EOF reading XV thumbnail file")
            if s[0] != '#':
                break

        # parse header line (already read)
        s = s.split()

        self.mode = "P"
        self.size = int(s[0]), int(s[1])

        self.palette = ImagePalette.raw_rgb332()

        self.tile = [
            ("raw", (0, 0)+self.size,
             self.fp.tell(), (self.mode, 0, 1)
             )]
    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
Esempio n. 8
0
    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)
             )]
Esempio n. 9
0
    def _open(self):

        # check magic
        s = self.fp.read(6)
        if s != "P7 332":
            raise SyntaxError("not an XV thumbnail file")

        # Skip to beginning of next line
        self.fp.safereadline(512)

        # skip info comments
        while True:
            s = self.fp.safereadline(65536)
            if not s:
                raise SyntaxError("Unexpected EOF reading XV thumbnail file")
            if s[0] != '#':
                break

        # parse header line (already read)
        s = s.split()

        self.mode = "P"
        self.size = int(s[0]), int(s[1])

        self.palette = ImagePalette.raw_rgb332()

        self.tile = [("raw", (0, 0) + self.size, self.fp.tell(), (self.mode, 0,
                                                                  1))]
Esempio n. 10
0
    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)
             )]
Esempio n. 11
0
    def chunk_PLTE(self, offset, nbytes):
        "PLTE -- palette data"

        s = self.fp.read(nbytes)
        if self.mode == "P":
            self.palette = ImagePalette.raw("RGB", s)
        return s
Esempio n. 12
0
    def _open(self):

        # check magic
        s = self.fp.read(6)
        if s != b"P7 332":
            raise SyntaxError("not an XV thumbnail file")

        # Skip to beginning of next line
        self.fp.readline()

        # skip info comments
        while True:
            s = self.fp.readline()
            if not s:
                raise SyntaxError("Unexpected EOF reading XV thumbnail file")
            if s[0] != b'#':
                break

        # parse header line (already read)
        s = s.strip().split()

        self.mode = "P"
        self.size = s[0], s[1]

        self.palette = ImagePalette.raw("RGB", PALETTE)

        self.tile = [("raw", (0, 0)+self.size, self.fp.tell(),
            (self.mode, 0, 1))]
Esempio n. 13
0
    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
Esempio n. 14
0
    def putpalette(self, data, rawmode="RGB"):
        "Put palette data into an image."

        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"
Esempio n. 15
0
    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
Esempio n. 16
0
 def __init__(self, mode='RGBA', size=(320, 240),
              background_color=(255, 255, 255)):
     Image.Image.__init__(self)
     if background_color == None:
         im = Image.core.new(mode, size)
     else:
         color_type = type(background_color).__name__
         if color_type == 'str' or color_type == 'unicode':
             background_color = ImageColor.getcolor(background_color, mode)
         im = Image.core.fill(mode, size, background_color)
     self.im = im
     self.mode = im.mode
     self.size = im.size
     if im.mode == 'P':
         self.palette = ImagePalette.ImagePalette()
Esempio n. 17
0
    def _open(self):

        # HEAD
        s = self.fp.read(128)
        magic = i16(s[4:6])
        if not (magic in [0xAF11, 0xAF12] and
                i16(s[14:16]) in [0, 3] and  # flags
                s[20:22] == '\x00\x00'):  # reserved
            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)
Esempio n. 18
0
    def _open(self):

        # HEAD
        s = self.fp.read(128)
        magic = i16(s[4:6])
        if not (magic in [0xAF11, 0xAF12] and i16(s[14:16]) in [0, 3]
                and  # flags
                s[20:22] == '\x00\x00'):  # reserved
            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 _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))]
Esempio n. 20
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
Esempio n. 21
0
    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))]
Esempio n. 22
0
    def _open(self):

        if not self.fp.read(8).startswith(_MAGIC):
            raise SyntaxError("not a PNG file")

        #
        # Parse headers up to the first IDAT chunk

        self.png = PngStream(self.fp)

        while True:

            #
            # get next chunk

            cid, pos, len = self.png.read()

            try:
                s = self.png.call(cid, pos, len)
            except EOFError:
                break

            if s is None:
                if Image.DEBUG:
                    print cid, pos, len, "(unknown)"
                s = self.fp.saferead(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.text = self.png.im_text # experimental
        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()
Esempio n. 23
0
    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 = [(a, a, a) for a in 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 = [bytes(r_g_b) for r_g_b in palette]
        self.palette = ImagePalette.raw("RGB", b"".join(palette))

        # set things up to decode first frame
        self.frame = -1
        self.__fp = self.fp

        self.seek(0)
Esempio n. 24
0
    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: bytes((r, g, b)), palette)
        self.palette = ImagePalette.raw("RGB", b"".join(palette))

        # set things up to decode first frame
        self.frame = -1
        self.__fp = self.fp

        self.seek(0)
Esempio n. 25
0
    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)]
Esempio n. 26
0
    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)]
Esempio n. 27
0
    def _bitmap(self, header = 0, offset = 0):

        if header:
            self.fp.seek(header)

        # CORE/INFO
        s = self.fp.read(4)
        s = s + self.fp.read(i32(s)-4)

        if len(s) == 12:

            # OS/2 1.0 CORE
            bits = i16(s[10:])
            self.size = i16(s[4:]), i16(s[6:])
            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:])
            self.info["compression"] = i32(s[16:])
            lutsize = 4
            colors = i32(s[32:])

        else:
            raise IOError, "Unknown BMP header type"

        if not colors:
            colors = 1 << bits

        # MODE
        try:
            self.mode, rawmode = BIT2MODE[bits]
        except KeyError:
            raise IOError, "Unsupported BMP pixel depth"

        # LUT
        if self.mode == "P":
            palette = []
            greyscale = 1
            if colors == 2:
                indices = (0, 255)
            else:
                indices = range(colors)
            for i in indices:
                rgb = self.fp.read(lutsize)[:3]
                if rgb != chr(i)*3:
                    greyscale = 0
                palette.append(rgb)
            if greyscale:
                if colors == 2:
                    self.mode = "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))]
Esempio n. 28
0
    def _setup(self):
        "Setup this image object based on current tags"

        if 0xBC01 in self.tag:
            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 = (self.tag.prefix, 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

        xres = getscalar(X_RESOLUTION, (1, 1))
        yres = getscalar(Y_RESOLUTION, (1, 1))

        if xres and yres:
            xres = xres[0] // (xres[1] or 1)
            yres = yres[0] // (yres[1] or 1)
            resunit = getscalar(RESOLUTION_UNIT, 1)
            if resunit == 2:  # dots per inch
                self.info["dpi"] = xres, yres
            elif resunit == 3:  # dots per centimeter. convert to dpi
                self.info["dpi"] = xres * 2.54, yres * 2.54
            else:  # No absolute unit of measurement
                self.info["resolution"] = xres, yres

        # build tile descriptors
        x = y = l = 0
        self.tile = []
        if STRIPOFFSETS in self.tag:
            # 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 TILEOFFSETS in self.tag:
            # tiled image
            w = getscalar(322)
            h = getscalar(323)
            a = None
            for o in self.tag[TILEOFFSETS]:
                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 = [chr(a // 256) for a in self.tag[COLORMAP]]
            self.palette = ImagePalette.raw("RGB;L", "".join(palette))
Esempio n. 29
0
    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 = (self.tag.byteorder, 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(TILEOFFSETS):
            # tiled image
            w = getscalar(322)
            h = getscalar(323)
            a = None
            for o in self.tag[TILEOFFSETS]:
                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":
            #seb
            try:
                palette = map(lambda a: chr(a // 256), self.tag[COLORMAP])
            except KeyError:
                pass  # seb HACK !! for some Zeiss LSM files
                palette = map(lambda a: chr(a // 256), range(256))
            self.palette = ImagePalette.raw("RGB;L", string.join(palette, ""))
    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 = (
            self.tag.prefix,
            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

        xres = getscalar(X_RESOLUTION, (1, 1))
        yres = getscalar(Y_RESOLUTION, (1, 1))

        if xres and yres:
            xres = xres[0] / (xres[1] or 1)
            yres = yres[0] / (yres[1] or 1)
            resunit = getscalar(RESOLUTION_UNIT, 1)
            if resunit == 2:  # dots per inch
                self.info["dpi"] = xres, yres
            elif resunit == 3:  # dots per centimeter. convert to dpi
                self.info["dpi"] = xres * 2.54, yres * 2.54
            else:  # No absolute unit of measurement
                self.info["resolution"] = xres, yres

        # build tile descriptors
        x = y = l = 0
        self.tile = []
        if self.tag.has_key(STRIPOFFSETS):
            # striped image
            offsets = self.tag[STRIPOFFSETS]
            h = getscalar(ROWSPERSTRIP, ysize)
            w = self.size[0]
            if self._compression in ["tiff_ccitt", "group3", "group4", "tiff_raw_16"]:
                if Image.DEBUG:
                    print "Activating g4 compression for whole file"

                # Decoder expects entire file as one tile.
                # There's a buffer size limit in load (64k)
                # so large g4 images will fail if we use that
                # function.
                #
                # Setup the one tile for the whole image, then
                # replace the existing load function with our
                # _load_libtiff function.

                self.load = self._load_libtiff

                # To be nice on memory footprint, if there's a
                # file descriptor, use that instead of reading
                # into a string in python.

                # libtiff closes the file descriptor, so pass in a dup.
                fp = hasattr(self.fp, "fileno") and os.dup(self.fp.fileno())

                # Offset in the tile tuple is 0, we go from 0,0 to
                # w,h, and we only do this once -- eds
                a = (rawmode, self._compression, fp)
                self.tile.append((self._compression, (0, 0, w, ysize), 0, a))
                a = None

            else:
                for i in range(len(offsets)):
                    a = self._decoder(rawmode, l, i)
                    self.tile.append((self._compression, (0, min(y, ysize), w, min(y + h, ysize)), offsets[i], a))
                    print "tiles: %s" % self.tile
                    y = y + h
                    if y >= self.size[1]:
                        x = y = 0
                        l = l + 1
                    a = None
        elif self.tag.has_key(TILEOFFSETS):
            # tiled image
            w = getscalar(322)
            h = getscalar(323)
            a = None
            for o in self.tag[TILEOFFSETS]:
                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, ""))
Esempio n. 31
0
    def _open(self):

        if not _accept(self.fp.read(9)):
            raise SyntaxError("not an XPM file")

        # skip forward to next string
        while True:
            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 = [b"\x00\x00\x00"] * 256

        for i in range(pal):

            s = self.fp.readline()
            if s[-2:] == b'\r\n':
                s = s[:-2]
            elif s[-1:] in b'\r\n':
                s = s[:-1]

            c = s[1]
            s = s[2:-2].split()

            for i in range(0, len(s), 2):

                if s[i] == b"c":

                    # process colour key
                    rgb = s[i+1]
                    if rgb == b"None":
                        self.info["transparency"] = c
                    elif rgb[0] == b"#":
                        # FIXME: handle colour names (see ImagePalette.py)
                        rgb = int(rgb[1:], 16)
                        palette[c] = bytes(((rgb >> 16) & 255, 
                                            (rgb >> 8) & 255,
                                            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", b''.join(palette))

        self.tile = [("raw", (0, 0)+self.size, self.fp.tell(), ("P", 0, 1))]
Esempio n. 32
0
    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
    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
            direction = -1

        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:])
            direction = -1
            if s[11] == '\xff':
                # upside-down storage
                self.size = self.size[0], 2**32 - self.size[1]
                direction = 0

        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),
                       direction))]

        self.info["compression"] = compression
Esempio n. 34
0
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))]
Esempio n. 35
0
    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 b"\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 == b"\r":
                continue

            if not s or s[0] == 0 or s[0] == 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:] == b'\r\n':
                s = s[:-2]
            elif s[-1:] == b'\n':
                s = s[:-1]

            try:
                m = split.match(s)
            except re.error as 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 = v.replace(b"*", b",")
                    v = tuple(map(number, v.split(b",")))
                    if len(v) == 1:
                        v = v[0]
                elif k == MODE:
                    v = v.decode('ascii')
                    if v in OPEN:
                        v, self.rawmode = OPEN[v]

                # Add to dictionary. Note that COMMENT tags are
                # combined into a list of strings.
                if k == COMMENT:
                    if k in self.info:
                        self.info[k].append(v)
                    else:
                        self.info[k] = [v]
                else:
                    self.info[k] = v

                if k in TAGS:
                    n = n + 1

            else:

                raise SyntaxError("Syntax error in IM header: " + str(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] != 26:
            s = self.fp.read(1)
        if not s:
            raise SyntaxError("File truncated")

        if LUT in self.info:
            # 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] != i:
                        linear = 0
                else:
                    greyscale = 0
            if self.mode == "L" or self.mode == "LA":
                if greyscale:
                    if not linear:
                        self.lut = list(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 = list(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))]
Esempio n. 36
0
    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))]
Esempio n. 37
0
    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 324 in self.tag:
            # 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 = [chr(a // 256) for a in self.tag[COLORMAP]]
            self.palette = ImagePalette.raw("RGB;L", "".join(palette))
    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 = (
            self.tag.prefix, 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

        xres = getscalar(X_RESOLUTION, (1, 1))
        yres = getscalar(Y_RESOLUTION, (1, 1))

        if xres and yres:
            xres = xres[0] / (xres[1] or 1)
            yres = yres[0] / (yres[1] or 1)
            resunit = getscalar(RESOLUTION_UNIT, 1)
            if resunit == 2: # dots per inch
                self.info["dpi"] = xres, yres
            elif resunit == 3: # dots per centimeter. convert to dpi
                self.info["dpi"] = xres * 2.54, yres * 2.54
            else: # No absolute unit of measurement
                self.info["resolution"] = xres, yres

        # 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(TILEOFFSETS):
            # tiled image
            w = getscalar(322)
            h = getscalar(323)
            a = None
            for o in self.tag[TILEOFFSETS]:
                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, ""))
Esempio n. 39
0
    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
            direction = -1

        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:])
            direction = -1
            if s[11] == b'\xff':
                # upside-down storage
                self.size = self.size[0], 2**32 - self.size[1]
                direction = 0

        else:
            raise IOError("Unsupported BMP header type ({0})".format(len(s)))

        if not colors:
            colors = 1 << bits

        # MODE
        try:
            self.mode, rawmode = BIT2MODE[bits]
        except KeyError:
            raise IOError("Unsupported BMP pixel depth ({0})".format(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 ({0})".format(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", "".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), direction))]

        self.info["compression"] = compression
    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))
                if id == 1039: # ICC profile
                    self.info["icc_profile"] = 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
Esempio n. 41
0
    def _open(self):

        # process header
        s = self.fp.read(18)

        id = s[0]

        colormaptype = s[1]
        imagetype = s[2]

        depth = s[16]

        flags = 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", b"\0" * 2 * start + self.fp.read(2 * size))
            elif mapdepth == 24:
                self.palette = ImagePalette.raw(
                    "BGR", b"\0" * 3 * start + self.fp.read(3 * size))
            elif mapdepth == 32:
                self.palette = ImagePalette.raw(
                    "BGRA", b"\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
Esempio n. 42
0
    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))]
Esempio n. 43
0
    def _setup(self):
        "Setup this image object based on current tags"

        # extract relevant tags
        self._compression = COMPRESSION_INFO[self.tag.getscalar(COMPRESSION, 1)]
        self._planar_configuration = self.tag.getscalar(PLANAR_CONFIGURATION, 1)

        # photometric is a required tag, but not everyone is reading
        # the specification
        photo = self.tag.getscalar(PHOTOMETRIC_INTERPRETATION, 0)

        if Image.DEBUG:
            print "*** Summary ***"
            print "- compression:", self._compression
            print "- photometric_interpretation:", photo
            print "- planar_configuration:", self._planar_configuration

        # size
        xsize = self.tag.getscalar(IMAGEWIDTH)
        ysize = self.tag.getscalar(IMAGELENGTH)
        self.size = xsize, ysize

        if Image.DEBUG:
            print "- size:", self.size

        format = self.tag.getscalar(SAMPLEFORMAT, 1)

        # mode: check photometric interpretation and bits per pixel
        key = (photo, format, 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

        # build tile descriptors
        x = y = l = 0
        self.tile = []
        if self.tag.has_key(STRIPOFFSETS):
            # striped image
            h = self.tag.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 = self.tag.getscalar(322)
            h = self.tag.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, ""))
Esempio n. 44
0
    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 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":
                        block = self.data()
                        if len(block) >= 3 and ord(block[0]) == 1:
                            self.info["loop"] = i16(block[1:3])
                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"