Example #1
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))]
Example #2
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))]
	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)
			 )]
Example #4
0
	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
Example #5
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.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))]
Example #6
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
Example #7
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
Example #8
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))]
Example #9
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))]
Example #10
0
	def _open(self):

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

		#
		# Parse headers up to the first IDAT chunk

		self.png = PngStream(self.fp)

		while 1:

			#
			# get next chunk

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

			try:
				s = self.png.call(cid, pos, len)
			except EOFError:
				break
			except AttributeError:
				if Image.DEBUG:
					print cid, pos, len, "(unknown)"
				s = ImageFile._safe_read(self.fp, len)

			self.png.crc(cid, s)

		#
		# Copy relevant attributes from the PngStream.  An alternative
		# would be to let the PngStream class modify these attributes
		# directly, but that introduces circular references which are
		# difficult to break if things go wrong in the decoder...
		# (believe me, I've tried ;-)

		self.mode = self.png.im_mode
		self.size = self.png.im_size
		self.info = self.png.im_info
		self.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()
Example #11
0
    def _open(self):

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

        #
        # Parse headers up to the first IDAT chunk

        self.png = PngStream(self.fp)

        while 1:

            #
            # get next chunk

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

            try:
                s = self.png.call(cid, pos, len)
            except EOFError:
                break
            except AttributeError:
                if Image.DEBUG:
                    print cid, pos, len, "(unknown)"
                s = ImageFile._safe_read(self.fp, len)

            self.png.crc(cid, s)

        #
        # Copy relevant attributes from the PngStream.  An alternative
        # would be to let the PngStream class modify these attributes
        # directly, but that introduces circular references which are
        # difficult to break if things go wrong in the decoder...
        # (believe me, I've tried ;-)

        self.mode = self.png.im_mode
        self.size = self.png.im_size
        self.info = self.png.im_info
        self.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()
Example #12
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): 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)
Example #13
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)]
Example #14
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] == '\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
Example #15
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))]
Example #16
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] == '\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
Example #17
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":
						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"
Example #18
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 (1, 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"

		self.info["orientation"] = 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
Example #19
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.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, ""))
Example #20
0
    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
Example #21
0
	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
Example #22
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 (1, 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"

        self.info["orientation"] = 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
Example #23
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))]
Example #24
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))]
Example #25
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.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, ""))