예제 #1
0
def getdata(im, offset = (0, 0), **params):
	"""Return a list of strings representing this image.
	   The first string is a local image header, the rest contains
	   encoded image data."""

	class collector:
		data = []
		def write(self, data):
			self.data.append(data)

	im.load() # make sure raster data is available

	fp = collector()

	try:
		im.encoderinfo = params

		# local image header
		fp.write("," +
				 o16(offset[0]) +	   # offset
				 o16(offset[1]) +
				 o16(im.size[0]) +	  # size
				 o16(im.size[1]) +
				 chr(0) +			   # flags
				 chr(8))				# bits

		ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])])

		fp.write("\0") # end of image data

	finally:
		del im.encoderinfo

	return fp.data
예제 #2
0
def _save(im, fp, filename):

    if im.mode != "1":
        raise IOError, "cannot write mode %s as MSP" % im.mode

    # create MSP header
    header = [0] * 16

    header[0], header[1] = i16("Da"), i16("nM")  # version 1
    header[2], header[3] = im.size
    header[4], header[5] = 1, 1
    header[6], header[7] = 1, 1
    header[8], header[9] = im.size

    sum = 0
    for h in header:
        sum = sum ^ h
    header[12] = sum  # FIXME: is this the right field?

    # header
    for h in header:
        fp.write(o16(h))

    # image body
    ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 32, ("1", 0, 1))])
예제 #3
0
def _save(im, fp, filename, check=0):

    try:
        rawmode, bits, colormaptype, imagetype = SAVE[im.mode]
    except KeyError:
        raise IOError("cannot write mode %s as TGA" % im.mode)

    if check:
        return check

    if colormaptype:
        colormapfirst, colormaplength, colormapentry = 0, 256, 24
    else:
        colormapfirst, colormaplength, colormapentry = 0, 0, 0

    if im.mode == "RGBA":
        flags = 8
    else:
        flags = 0

    orientation = im.info.get("orientation", -1)
    if orientation > 0:
        flags = flags | 0x20

    fp.write("\000" + chr(colormaptype) + chr(imagetype) + o16(colormapfirst) +
             o16(colormaplength) + chr(colormapentry) + o16(0) + o16(0) +
             o16(im.size[0]) + o16(im.size[1]) + chr(bits) + chr(flags))

    if colormaptype:
        fp.write(im.im.getpalette("RGB", "BGR"))

    ImageFile._save(im, fp,
                    [("raw", (0, 0) + im.size, 0, (rawmode, 0, orientation))])
예제 #4
0
def _save(im, fp, filename):

    if im.mode != "1":
        raise IOError, "cannot write mode %s as MSP" % im.mode

        # create MSP header
    header = [0] * 16

    header[0], header[1] = i16("Da"), i16("nM")  # version 1
    header[2], header[3] = im.size
    header[4], header[5] = 1, 1
    header[6], header[7] = 1, 1
    header[8], header[9] = im.size

    sum = 0
    for h in header:
        sum = sum ^ h
    header[12] = sum  # FIXME: is this the right field?

    # header
    for h in header:
        fp.write(o16(h))

        # image body
    ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 32, ("1", 0, 1))])
예제 #5
0
def _save(im, fp, filename, check=0):

    try:
        type, rawmode = SAVE[im.mode]
    except KeyError:
        raise ValueError, "Cannot save %s images as IM" % im.mode

    try:
        frames = im.encoderinfo["frames"]
    except KeyError:
        frames = 1

    if check:
        return check

    fp.write("Image type: %s image\r\n" % type)
    if filename:
        fp.write("Name: %s\r\n" % filename)
    fp.write("Image size (x*y): %d*%d\r\n" % im.size)
    fp.write("File size (no of images): %d\r\n" % frames)
    if im.mode == "P":
        fp.write("Lut: 1\r\n")
    fp.write("\000" * (511 - fp.tell()) + "\032")
    if im.mode == "P":
        fp.write(im.im.getpalette("RGB", "RGB;L"))  # 768 bytes
    ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, -1))])
예제 #6
0
def _save(im, fp, filename):

	try:
		rawmode = RAWMODE[im.mode]
	except KeyError:
		raise IOError("cannot write mode %s as JPEG" % im.mode)

	info = im.encoderinfo

	dpi = info.get("dpi", (0, 0))

	subsampling = info.get("subsampling", -1)
	if subsampling == "4:4:4":
		subsampling = 0
	elif subsampling == "4:2:2":
		subsampling = 1
	elif subsampling == "4:1:1":
		subsampling = 2

	extra = ""

	icc_profile = info.get("icc_profile")
	if icc_profile:
		ICC_OVERHEAD_LEN = 14
		MAX_BYTES_IN_MARKER = 65533
		MAX_DATA_BYTES_IN_MARKER = MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN
		markers = []
		while icc_profile:
			markers.append(icc_profile[:MAX_DATA_BYTES_IN_MARKER])
			icc_profile = icc_profile[MAX_DATA_BYTES_IN_MARKER:]
		i = 1
		for marker in markers:
			size = struct.pack(">H", 2 + ICC_OVERHEAD_LEN + len(marker))
			extra = extra + ("\xFF\xE2" + size + "ICC_PROFILE\0" + chr(i) + chr(len(markers)) + marker)
			i = i + 1

	# get keyword arguments
	im.encoderconfig = (
		info.get("quality", 0),
		# "progressive" is the official name, but older documentation
		# says "progression"
		# FIXME: issue a warning if the wrong form is used (post-1.1.7)
		info.has_key("progressive") or info.has_key("progression"),
		info.get("smooth", 0),
		info.has_key("optimize"),
		info.get("streamtype", 0),
		dpi[0], dpi[1],
		subsampling,
		extra,
		)

	ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
예제 #7
0
def _save(im, fp, filename):
    if im.mode == "1":
        rawmode, head = "1;I", "P4"
    elif im.mode == "L":
        rawmode, head = "L", "P5"
    elif im.mode == "RGB":
        rawmode, head = "RGB", "P6"
    elif im.mode == "RGBA":
        rawmode, head = "RGB", "P6"
    else:
        raise IOError, "cannot write mode %s as PPM" % im.mode
    fp.write(head + "\n%d %d\n" % im.size)
    if head != "P4":
        fp.write("255\n")
    ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))])
예제 #8
0
def _save(im, fp, filename):
	if im.mode == "1":
		rawmode, head = "1;I", "P4"
	elif im.mode == "L":
		rawmode, head = "L", "P5"
	elif im.mode == "RGB":
		rawmode, head = "RGB", "P6"
	elif im.mode == "RGBA":
		rawmode, head = "RGB", "P6"
	else:
		raise IOError, "cannot write mode %s as PPM" % im.mode
	fp.write(head + "\n%d %d\n" % im.size)
	if head != "P4":
		fp.write("255\n")
	ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))])
예제 #9
0
	def chunk_PLTE(self, pos, len):

		# palette
		s = ImageFile._safe_read(self.fp, len)
		if self.im_mode == "P":
			self.im_palette = "RGB", s
		return s
예제 #10
0
    def chunk_PLTE(self, pos, len):

        # palette
        s = ImageFile._safe_read(self.fp, len)
        if self.im_mode == "P":
            self.im_palette = "RGB", s
        return s
예제 #11
0
def _save(im, fp, filename, check=0):

    try:
        rawmode, bits, colors = SAVE[im.mode]
    except KeyError:
        raise IOError("cannot write mode %s as BMP" % im.mode)

    if check:
        return check

    stride = ((im.size[0] * bits + 7) / 8 + 3) & (~3)
    header = 40  # or 64 for OS/2 version 2
    offset = 14 + header + colors * 4
    image = stride * im.size[1]

    # bitmap header
    fp.write("BM" +  # file type (magic)
             o32(offset + image) +  # file size
             o32(0) +  # reserved
             o32(offset))  # image data offset

    # bitmap info header
    fp.write(
        o32(header) +  # info header size
        o32(im.size[0]) +  # width
        o32(im.size[1]) +  # height
        o16(1) +  # planes
        o16(bits) +  # depth
        o32(0) +  # compression (0=uncompressed)
        o32(image) +  # size of bitmap
        o32(1) + o32(1) +  # resolution
        o32(colors) +  # colors used
        o32(colors))  # colors important

    fp.write("\000" * (header - 40))  # padding (for OS/2 format)

    if im.mode == "1":
        for i in (0, 255):
            fp.write(chr(i) * 4)
    elif im.mode == "L":
        for i in range(256):
            fp.write(chr(i) * 4)
    elif im.mode == "P":
        fp.write(im.im.getpalette("RGB", "BGRX"))

    ImageFile._save(im, fp,
                    [("raw", (0, 0) + im.size, 0, (rawmode, stride, -1))])
예제 #12
0
def _save(im, fp, filename, check=0):

	try:
		rawmode, bits, colors = SAVE[im.mode]
	except KeyError:
		raise IOError("cannot write mode %s as BMP" % im.mode)

	if check:
		return check

	stride = ((im.size[0]*bits+7)/8+3)&(~3)
	header = 40 # or 64 for OS/2 version 2
	offset = 14 + header + colors * 4
	image  = stride * im.size[1]

	# bitmap header
	fp.write("BM" +					 # file type (magic)
			 o32(offset+image) +		# file size
			 o32(0) +				   # reserved
			 o32(offset))			   # image data offset

	# bitmap info header
	fp.write(o32(header) +			  # info header size
			 o32(im.size[0]) +		  # width
			 o32(im.size[1]) +		  # height
			 o16(1) +				   # planes
			 o16(bits) +				# depth
			 o32(0) +				   # compression (0=uncompressed)
			 o32(image) +			   # size of bitmap
			 o32(1) + o32(1) +		  # resolution
			 o32(colors) +			  # colors used
			 o32(colors))			   # colors important

	fp.write("\000" * (header - 40))	# padding (for OS/2 format)

	if im.mode == "1":
		for i in (0, 255):
			fp.write(chr(i) * 4)
	elif im.mode == "L":
		for i in range(256):
			fp.write(chr(i) * 4)
	elif im.mode == "P":
		fp.write(im.im.getpalette("RGB", "BGRX"))

	ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, stride, -1))])
예제 #13
0
def _save(im, fp, filename):

    if im.mode != "1":
        raise IOError, "cannot write mode %s as XBM" % im.mode

    fp.write("#define im_width %d\n" % im.size[0])
    fp.write("#define im_height %d\n" % im.size[1])

    hotspot = im.encoderinfo.get("hotspot")
    if hotspot:
        fp.write("#define im_x_hot %d\n" % hotspot[0])
        fp.write("#define im_y_hot %d\n" % hotspot[1])

    fp.write("static char im_bits[] = {\n")

    ImageFile._save(im, fp, [("xbm", (0, 0) + im.size, 0, None)])

    fp.write("};\n")
예제 #14
0
def _save(im, fp, filename):

	if im.mode != "1":
		raise IOError, "cannot write mode %s as XBM" % im.mode

	fp.write("#define im_width %d\n" % im.size[0])
	fp.write("#define im_height %d\n" % im.size[1])

	hotspot = im.encoderinfo.get("hotspot")
	if hotspot:
		fp.write("#define im_x_hot %d\n" % hotspot[0])
		fp.write("#define im_y_hot %d\n" % hotspot[1])

	fp.write("static char im_bits[] = {\n")

	ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)])

	fp.write("};\n")
예제 #15
0
def COM(self, marker):
	#
	# Comment marker.  Store these in the APP dictionary.

	n = i16(self.fp.read(2))-2
	s = ImageFile._safe_read(self.fp, n)

	self.app["COM"] = s # compatibility
	self.applist.append(("COM", s))
예제 #16
0
def APP(self, marker):
	#
	# Application marker.  Store these in the APP dictionary.
	# Also look for well-known application markers.

	n = i16(self.fp.read(2))-2
	s = ImageFile._safe_read(self.fp, n)

	app = "APP%d" % (marker&15)

	self.app[app] = s # compatibility
	self.applist.append((app, s))

	if marker == 0xFFE0 and s[:4] == "JFIF":
		# extract JFIF information
		self.info["jfif"] = version = i16(s, 5) # version
		self.info["jfif_version"] = divmod(version, 256)
		# extract JFIF properties
		try:
			jfif_unit = ord(s[7])
			jfif_density = i16(s, 8), i16(s, 10)
		except:
			pass
		else:
			if jfif_unit == 1:
				self.info["dpi"] = jfif_density
			self.info["jfif_unit"] = jfif_unit
			self.info["jfif_density"] = jfif_density
	elif marker == 0xFFE1 and s[:5] == "Exif\0":
		# extract Exif information (incomplete)
		self.info["exif"] = s # FIXME: value will change
	elif marker == 0xFFE2 and s[:5] == "FPXR\0":
		# extract FlashPix information (incomplete)
		self.info["flashpix"] = s # FIXME: value will change
	elif marker == 0xFFE2 and s[:12] == "ICC_PROFILE\0":
		# Since an ICC profile can be larger than the maximum size of
		# a JPEG marker (64K), we need provisions to split it into
		# multiple markers. The format defined by the ICC specifies
		# one or more APP2 markers containing the following data:
		#   Identifying string	  ASCII "ICC_PROFILE\0"  (12 bytes)
		#   Marker sequence number  1, 2, etc (1 byte)
		#   Number of markers	   Total of APP2's used (1 byte)
		#   Profile data			(remainder of APP2 data)
		# Decoders should use the marker sequence numbers to
		# reassemble the profile, rather than assuming that the APP2
		# markers appear in the correct sequence.
		self.icclist.append(s)
	elif marker == 0xFFEE and s[:5] == "Adobe":
		self.info["adobe"] = i16(s, 5)
		# extract Adobe custom properties
		try:
			adobe_transform = ord(s[1])
		except:
			pass
		else:
			self.info["adobe_transform"] = adobe_transform
예제 #17
0
def _save(im, fp, filename, check=0):

	try:
		version, bits, planes, rawmode = SAVE[im.mode]
	except KeyError:
		raise ValueError, "Cannot save %s images as PCX" % im.mode

	if check:
		return check

	# bytes per plane
	stride = (im.size[0] * bits + 7) / 8

	# under windows, we could determine the current screen size with
	# "Image.core.display_mode()[1]", but I think that's overkill...

	screen = im.size

	dpi = 100, 100

	# PCX header
	fp.write(
		chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) +
		o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) +
		o16(dpi[1]) + chr(0)*24 + chr(255)*24 + chr(0) + chr(planes) +
		o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) +
		chr(0)*54
		)

	assert fp.tell() == 128

	ImageFile._save(im, fp, [("pcx", (0,0)+im.size, 0,
							  (rawmode, bits*planes))])

	if im.mode == "P":
		# colour palette
		fp.write(chr(12))
		fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes
	elif im.mode == "L":
		# greyscale palette
		fp.write(chr(12))
		for i in range(256):
			fp.write(chr(i)*3)
예제 #18
0
def _save(im, fp, filename):
	if im.mode[0] != "F":
		im = im.convert('F')

	hdr = makeSpiderHeader(im)
	if len(hdr) < 256:
		raise IOError, "Error creating Spider header"

	# write the SPIDER header
	try:
		fp = open(filename, 'wb')
	except:
		raise IOError, "Unable to open %s for writing" % filename
	fp.writelines(hdr)

	rawmode = "F;32NF"  #32-bit native floating point
	ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode,0,1))])

	fp.close()
예제 #19
0
def _save(im, fp, filename):
    if im.mode[0] != "F":
        im = im.convert('F')

    hdr = makeSpiderHeader(im)
    if len(hdr) < 256:
        raise IOError, "Error creating Spider header"

    # write the SPIDER header
    try:
        fp = open(filename, 'wb')
    except:
        raise IOError, "Unable to open %s for writing" % filename
    fp.writelines(hdr)

    rawmode = "F;32NF"  #32-bit native floating point
    ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))])

    fp.close()
예제 #20
0
    def load(self, fp):
        # load tag dictionary

        self.reset()

        i16 = self.i16
        i32 = self.i32

        for i in range(i16(fp.read(2))):

            ifd = fp.read(12)

            tag, typ = i16(ifd), i16(ifd, 2)

            if Image.DEBUG:
                import TiffTags
                tagname = TiffTags.TAGS.get(tag, "unknown")
                typname = TiffTags.TYPES.get(typ, "unknown")
                print "tag: %s (%d)" % (tagname, tag),
                print "- type: %s (%d)" % (typname, typ),

            try:
                dispatch = self.load_dispatch[typ]
            except KeyError:
                if Image.DEBUG:
                    print "- unsupported type", typ
                continue  # ignore unsupported type

            size, handler = dispatch

            size = size * i32(ifd, 4)

            # Get and expand tag value
            if size > 4:
                here = fp.tell()
                fp.seek(i32(ifd, 8))
                data = ImageFile._safe_read(fp, size)
                fp.seek(here)
            else:
                data = ifd[8:8 + size]

            if len(data) != size:
                raise IOError, "not enough data"

            self.tagdata[tag] = typ, data
            self.tagtype[tag] = typ

            if Image.DEBUG:
                if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK,
                           ICCPROFILE, XMP):
                    print "- value: <table: %d bytes>" % size
                else:
                    print "- value:", self[tag]

        self.next = i32(fp.read(4))
예제 #21
0
	def chunk_tEXt(self, pos, len):

		# text
		s = ImageFile._safe_read(self.fp, len)
		try:
			k, v = string.split(s, "\0", 1)
		except ValueError:
			k = s; v = "" # fallback for broken tEXt tags
		if k:
			self.im_info[k] = self.im_text[k] = v
		return s
예제 #22
0
	def chunk_zTXt(self, pos, len):

		# compressed text
		s = ImageFile._safe_read(self.fp, len)
		k, v = string.split(s, "\0", 1)
		comp_method = ord(v[0])
		if comp_method != 0:
			raise SyntaxError("Unknown compression method %s in zTXt chunk" % comp_method)
		import zlib
		self.im_info[k] = self.im_text[k] = zlib.decompress(v[1:])
		return s
예제 #23
0
	def load(self, fp):
		# load tag dictionary

		self.reset()

		i16 = self.i16
		i32 = self.i32

		for i in range(i16(fp.read(2))):

			ifd = fp.read(12)

			tag, typ = i16(ifd), i16(ifd, 2)

			if Image.DEBUG:
				import TiffTags
				tagname = TiffTags.TAGS.get(tag, "unknown")
				typname = TiffTags.TYPES.get(typ, "unknown")
				print "tag: %s (%d)" % (tagname, tag),
				print "- type: %s (%d)" % (typname, typ),

			try:
				dispatch = self.load_dispatch[typ]
			except KeyError:
				if Image.DEBUG:
					print "- unsupported type", typ
				continue # ignore unsupported type

			size, handler = dispatch

			size = size * i32(ifd, 4)

			# Get and expand tag value
			if size > 4:
				here = fp.tell()
				fp.seek(i32(ifd, 8))
				data = ImageFile._safe_read(fp, size)
				fp.seek(here)
			else:
				data = ifd[8:8+size]

			if len(data) != size:
				raise IOError, "not enough data"

			self.tagdata[tag] = typ, data
			self.tagtype[tag] = typ

			if Image.DEBUG:
				if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP):
					print "- value: <table: %d bytes>" % size
				else:
					print "- value:", self[tag]

		self.next = i32(fp.read(4))
예제 #24
0
def _save(im, fp, filename, check=0):

    try:
        version, bits, planes, rawmode = SAVE[im.mode]
    except KeyError:
        raise ValueError, "Cannot save %s images as PCX" % im.mode

    if check:
        return check

    # bytes per plane
    stride = (im.size[0] * bits + 7) / 8

    # under windows, we could determine the current screen size with
    # "Image.core.display_mode()[1]", but I think that's overkill...

    screen = im.size

    dpi = 100, 100

    # PCX header
    fp.write(
        chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) + o16(0) +
        o16(im.size[0] - 1) + o16(im.size[1] - 1) + o16(dpi[0]) + o16(dpi[1]) +
        chr(0) * 24 + chr(255) * 24 + chr(0) + chr(planes) + o16(stride) +
        o16(1) + o16(screen[0]) + o16(screen[1]) + chr(0) * 54)

    assert fp.tell() == 128

    ImageFile._save(im, fp,
                    [("pcx", (0, 0) + im.size, 0, (rawmode, bits * planes))])

    if im.mode == "P":
        # colour palette
        fp.write(chr(12))
        fp.write(im.im.getpalette("RGB", "RGB"))  # 768 bytes
    elif im.mode == "L":
        # greyscale palette
        fp.write(chr(12))
        for i in range(256):
            fp.write(chr(i) * 3)
예제 #25
0
def _save(im, fp, filename, check=0):

	try:
		rawmode, bits, colormaptype, imagetype = SAVE[im.mode]
	except KeyError:
		raise IOError("cannot write mode %s as TGA" % im.mode)

	if check:
		return check

	if colormaptype:
		colormapfirst, colormaplength, colormapentry = 0, 256, 24
	else:
		colormapfirst, colormaplength, colormapentry = 0, 0, 0

	if im.mode == "RGBA":
		flags = 8
	else:
		flags = 0

	orientation = im.info.get("orientation", -1)
	if orientation > 0:
		flags = flags | 0x20

	fp.write("\000" +
			 chr(colormaptype) +
			 chr(imagetype) +
			 o16(colormapfirst) +
			 o16(colormaplength) +
			 chr(colormapentry) +
			 o16(0) +
			 o16(0) +
			 o16(im.size[0]) +
			 o16(im.size[1]) +
			 chr(bits) +
			 chr(flags))

	if colormaptype:
		fp.write(im.im.getpalette("RGB", "BGR"))

	ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, orientation))])
예제 #26
0
	def chunk_pHYs(self, pos, len):

		# pixels per unit
		s = ImageFile._safe_read(self.fp, len)
		px, py = i32(s), i32(s[4:])
		unit = ord(s[8])
		if unit == 1: # meter
			dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5)
			self.im_info["dpi"] = dpi
		elif unit == 0:
			self.im_info["aspect"] = px, py
		return s
예제 #27
0
    def chunk_tEXt(self, pos, len):

        # text
        s = ImageFile._safe_read(self.fp, len)
        try:
            k, v = string.split(s, "\0", 1)
        except ValueError:
            k = s
            v = ""  # fallback for broken tEXt tags
        if k:
            self.im_info[k] = self.im_text[k] = v
        return s
예제 #28
0
    def chunk_pHYs(self, pos, len):

        # pixels per unit
        s = ImageFile._safe_read(self.fp, len)
        px, py = i32(s), i32(s[4:])
        unit = ord(s[8])
        if unit == 1:  # meter
            dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5)
            self.im_info["dpi"] = dpi
        elif unit == 0:
            self.im_info["aspect"] = px, py
        return s
예제 #29
0
    def chunk_zTXt(self, pos, len):

        # compressed text
        s = ImageFile._safe_read(self.fp, len)
        k, v = string.split(s, "\0", 1)
        comp_method = ord(v[0])
        if comp_method != 0:
            raise SyntaxError("Unknown compression method %s in zTXt chunk" %
                              comp_method)
        import zlib
        self.im_info[k] = self.im_text[k] = zlib.decompress(v[1:])
        return s
예제 #30
0
    def chunk_tRNS(self, pos, len):

        # transparency
        s = ImageFile._safe_read(self.fp, len)
        if self.im_mode == "P":
            i = string.find(s, chr(0))
            if i >= 0:
                self.im_info["transparency"] = i
        elif self.im_mode == "L":
            self.im_info["transparency"] = i16(s)
        elif self.im_mode == "RGB":
            self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:])
        return s
예제 #31
0
	def chunk_tRNS(self, pos, len):

		# transparency
		s = ImageFile._safe_read(self.fp, len)
		if self.im_mode == "P":
			i = string.find(s, chr(0))
			if i >= 0:
				self.im_info["transparency"] = i
		elif self.im_mode == "L":
			self.im_info["transparency"] = i16(s)
		elif self.im_mode == "RGB":
			self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:])
		return s
예제 #32
0
    def chunk_IHDR(self, pos, len):

        # image header
        s = ImageFile._safe_read(self.fp, len)
        self.im_size = i32(s), i32(s[4:])
        try:
            self.im_mode, self.im_rawmode = _MODES[(ord(s[8]), ord(s[9]))]
        except:
            pass
        if ord(s[12]):
            self.im_info["interlace"] = 1
        if ord(s[11]):
            raise SyntaxError, "unknown filter category"
        return s
예제 #33
0
	def chunk_IHDR(self, pos, len):

		# image header
		s = ImageFile._safe_read(self.fp, len)
		self.im_size = i32(s), i32(s[4:])
		try:
			self.im_mode, self.im_rawmode = _MODES[(ord(s[8]), ord(s[9]))]
		except:
			pass
		if ord(s[12]):
			self.im_info["interlace"] = 1
		if ord(s[11]):
			raise SyntaxError, "unknown filter category"
		return s
예제 #34
0
	def verify(self, endchunk = "IEND"):

		# Simple approach; just calculate checksum for all remaining
		# blocks.  Must be called directly after open.

		cids = []

		while 1:
			cid, pos, len = self.read()
			if cid == endchunk:
				break
			self.crc(cid, ImageFile._safe_read(self.fp, len))
			cids.append(cid)

		return cids
예제 #35
0
    def verify(self, endchunk="IEND"):

        # Simple approach; just calculate checksum for all remaining
        # blocks.  Must be called directly after open.

        cids = []

        while 1:
            cid, pos, len = self.read()
            if cid == endchunk:
                break
            self.crc(cid, ImageFile._safe_read(self.fp, len))
            cids.append(cid)

        return cids
예제 #36
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()
예제 #37
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()
예제 #38
0
def SOF(self, marker):
	#
	# Start of frame marker.  Defines the size and mode of the
	# image.  JPEG is colour blind, so we use some simple
	# heuristics to map the number of layers to an appropriate
	# mode.  Note that this could be made a bit brighter, by
	# looking for JFIF and Adobe APP markers.

	n = i16(self.fp.read(2))-2
	s = ImageFile._safe_read(self.fp, n)
	self.size = i16(s[3:]), i16(s[1:])

	self.bits = ord(s[0])
	if self.bits != 8:
		raise SyntaxError("cannot handle %d-bit layers" % self.bits)

	self.layers = ord(s[5])
	if self.layers == 1:
		self.mode = "L"
	elif self.layers == 3:
		self.mode = "RGB"
	elif self.layers == 4:
		self.mode = "CMYK"
	else:
		raise SyntaxError("cannot handle %d-layer images" % self.layers)

	if marker in [0xFFC2, 0xFFC6, 0xFFCA, 0xFFCE]:
		self.info["progressive"] = self.info["progression"] = 1

	if self.icclist:
		# fixup icc profile
		self.icclist.sort() # sort by sequence number
		if ord(self.icclist[0][13]) == len(self.icclist):
			profile = []
			for p in self.icclist:
				profile.append(p[14:])
			icc_profile = string.join(profile, "")
		else:
			icc_profile = None # wrong number of fragments
		self.info["icc_profile"] = icc_profile
		self.icclist = None

	for i in range(6, len(s), 3):
		t = s[i:i+3]
		# 4-tuples: id, vsamp, hsamp, qtable
		self.layer.append((t[0], ord(t[1])/16, ord(t[1])&15, ord(t[2])))
예제 #39
0
def DQT(self, marker):
	#
	# Define quantization table.  Support baseline 8-bit tables
	# only.  Note that there might be more than one table in
	# each marker.

	# FIXME: The quantization tables can be used to estimate the
	# compression quality.

	n = i16(self.fp.read(2))-2
	s = ImageFile._safe_read(self.fp, n)
	while len(s):
		if len(s) < 65:
			raise SyntaxError("bad quantization table marker")
		v = ord(s[0])
		if v/16 == 0:
			self.quantization[v&15] = array.array("b", s[1:65])
			s = s[65:]
		else:
			return # FIXME: add code to read 16-bit tables!
예제 #40
0
	def chunk_iCCP(self, pos, len):

		# ICC profile
		s = ImageFile._safe_read(self.fp, len)
		# according to PNG spec, the iCCP chunk contains:
		# Profile name  1-79 bytes (character string)
		# Null separator		1 byte (null character)
		# Compression method	1 byte (0)
		# Compressed profile	n bytes (zlib with deflate compression)
		i = string.find(s, chr(0))
		if Image.DEBUG:
			print "iCCP profile name", s[:i]
			print "Compression method", ord(s[i])
		comp_method = ord(s[i])
		if comp_method != 0:
			raise SyntaxError("Unknown compression method %s in iCCP chunk" % comp_method)
		try:
			icc_profile = zlib.decompress(s[i+2:])
		except zlib.error:
			icc_profile = None # FIXME
		self.im_info["icc_profile"] = icc_profile
		return s
예제 #41
0
    def chunk_iCCP(self, pos, len):

        # ICC profile
        s = ImageFile._safe_read(self.fp, len)
        # according to PNG spec, the iCCP chunk contains:
        # Profile name  1-79 bytes (character string)
        # Null separator		1 byte (null character)
        # Compression method	1 byte (0)
        # Compressed profile	n bytes (zlib with deflate compression)
        i = string.find(s, chr(0))
        if Image.DEBUG:
            print "iCCP profile name", s[:i]
            print "Compression method", ord(s[i])
        comp_method = ord(s[i])
        if comp_method != 0:
            raise SyntaxError("Unknown compression method %s in iCCP chunk" %
                              comp_method)
        try:
            icc_profile = zlib.decompress(s[i + 2:])
        except zlib.error:
            icc_profile = None  # FIXME
        self.im_info["icc_profile"] = icc_profile
        return s
예제 #42
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
예제 #43
0
def Skip(self, marker):
	n = i16(self.fp.read(2))-2
	ImageFile._safe_read(self.fp, n)
예제 #44
0
def _save(im, fp, filename):

	if _imaging_gif:
		# call external driver
		try:
			_imaging_gif.save(im, fp, filename)
			return
		except IOError:
			pass # write uncompressed file

	try:
		rawmode = RAWMODE[im.mode]
		imOut = im
	except KeyError:
		# convert on the fly (EXPERIMENTAL -- I'm not sure PIL
		# should automatically convert images on save...)
		if Image.getmodebase(im.mode) == "RGB":
			imOut = im.convert("P")
			rawmode = "P"
		else:
			imOut = im.convert("L")
			rawmode = "L"

	# header
	for s in getheader(imOut, im.encoderinfo):
		fp.write(s)

	flags = 0

	try:
		interlace = im.encoderinfo["interlace"]
	except KeyError:
		interlace = 1

	# workaround for @PIL153
	if min(im.size) < 16:
		interlace = 0

	if interlace:
		flags = flags | 64

	try:
		transparency = im.encoderinfo["transparency"]
	except KeyError:
		pass
	else:
		# transparency extension block
		fp.write("!" +
				 chr(249) +			 # extension intro
				 chr(4) +			   # length
				 chr(1) +			   # transparency info present
				 o16(0) +			   # duration
				 chr(int(transparency)) # transparency index
				 + chr(0))

	# local image header
	fp.write("," +
			 o16(0) + o16(0) +		  # bounding box
			 o16(im.size[0]) +		  # size
			 o16(im.size[1]) +
			 chr(flags) +			   # flags
			 chr(8))					# bits

	imOut.encoderconfig = (8, interlace)

	ImageFile._save(imOut, fp, [("gif", (0,0)+im.size, 0, rawmode)])

	fp.write("\0") # end of image data

	fp.write(";") # end of file

	try:
		fp.flush()
	except: pass
예제 #45
0
def _save(im, fp, filename):
    resolution = im.encoderinfo.get("resolution", 72.0)

    #
    # make sure image data is available
    im.load()

    xref = [0] * (5 + 1)  # placeholders

    fp.write("%PDF-1.2\n")
    fp.write("% created by PIL PDF driver " + __version__ + "\n")

    #
    # Get image characteristics

    width, height = im.size

    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)
    # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports
    # Flatedecode (zip compression).

    bits = 8
    params = None

    if im.mode == "1":
        filter = "/ASCIIHexDecode"
        colorspace = "/DeviceGray"
        procset = "/ImageB"  # grayscale
        bits = 1
    elif im.mode == "L":
        filter = "/DCTDecode"
        # params = "<< /Predictor 15 /Columns %d >>" % (width-2)
        colorspace = "/DeviceGray"
        procset = "/ImageB"  # grayscale
    elif im.mode == "P":
        filter = "/ASCIIHexDecode"
        colorspace = "[ /Indexed /DeviceRGB 255 <"
        palette = im.im.getpalette("RGB")
        for i in range(256):
            r = ord(palette[i * 3])
            g = ord(palette[i * 3 + 1])
            b = ord(palette[i * 3 + 2])
            colorspace = colorspace + "%02x%02x%02x " % (r, g, b)
        colorspace = colorspace + "> ]"
        procset = "/ImageI"  # indexed color
    elif im.mode == "RGB":
        filter = "/DCTDecode"
        colorspace = "/DeviceRGB"
        procset = "/ImageC"  # color images
    elif im.mode == "CMYK":
        filter = "/DCTDecode"
        colorspace = "/DeviceCMYK"
        procset = "/ImageC"  # color images
    else:
        raise ValueError("cannot save mode %s" % im.mode)

    #
    # catalogue

    xref[1] = fp.tell()
    _obj(fp, 1, Type="/Catalog", Pages="2 0 R")
    _endobj(fp)

    #
    # pages

    xref[2] = fp.tell()
    _obj(fp, 2, Type="/Pages", Count=1, Kids="[4 0 R]")
    _endobj(fp)

    #
    # image

    op = StringIO.StringIO()

    if filter == "/ASCIIHexDecode":
        if bits == 1:
            # FIXME: the hex encoder doesn't support packed 1-bit
            # images; do things the hard way...
            data = im.tostring("raw", "1")
            im = Image.new("L", (len(data), 1), None)
            im.putdata(data)
        ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, im.mode)])
    elif filter == "/DCTDecode":
        ImageFile._save(im, op, [("jpeg", (0, 0) + im.size, 0, im.mode)])
    elif filter == "/FlateDecode":
        ImageFile._save(im, op, [("zip", (0, 0) + im.size, 0, im.mode)])
    elif filter == "/RunLengthDecode":
        ImageFile._save(im, op, [("packbits", (0, 0) + im.size, 0, im.mode)])
    else:
        raise ValueError("unsupported PDF filter (%s)" % filter)

    xref[3] = fp.tell()
    _obj(
        fp,
        3,
        Type="/XObject",
        Subtype="/Image",
        Width=width,  # * 72.0 / resolution,
        Height=height,  # * 72.0 / resolution,
        Length=len(op.getvalue()),
        Filter=filter,
        BitsPerComponent=bits,
        DecodeParams=params,
        ColorSpace=colorspace)

    fp.write("stream\n")
    fp.write(op.getvalue())
    fp.write("\nendstream\n")

    _endobj(fp)

    #
    # page

    xref[4] = fp.tell()
    _obj(fp, 4)
    fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\
       "/Resources <<\n/ProcSet [ /PDF %s ]\n"\
       "/XObject << /image 3 0 R >>\n>>\n"\
       "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\
       (procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution)))
    _endobj(fp)

    #
    # page contents

    op = StringIO.StringIO()

    op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" %
             (int(width * 72.0 / resolution), int(height * 72.0 / resolution)))

    xref[5] = fp.tell()
    _obj(fp, 5, Length=len(op.getvalue()))

    fp.write("stream\n")
    fp.write(op.getvalue())
    fp.write("\nendstream\n")

    _endobj(fp)

    #
    # trailer
    startxref = fp.tell()
    fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref))
    for x in xref[1:]:
        fp.write("%010d 00000 n \n" % x)
    fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref))
    fp.write("startxref\n%d\n%%%%EOF\n" % startxref)
    fp.flush()
예제 #46
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
예제 #47
0
def _save(im, fp, filename):
	resolution = im.encoderinfo.get("resolution", 72.0)

	#
	# make sure image data is available
	im.load()

	xref = [0]*(5+1) # placeholders

	fp.write("%PDF-1.2\n")
	fp.write("% created by PIL PDF driver " + __version__ + "\n")

	#
	# Get image characteristics

	width, height = im.size

	# FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)
	# or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports
	# Flatedecode (zip compression).

	bits = 8
	params = None

	if im.mode == "1":
		filter = "/ASCIIHexDecode"
		colorspace = "/DeviceGray"
		procset = "/ImageB" # grayscale
		bits = 1
	elif im.mode == "L":
		filter = "/DCTDecode"
		# params = "<< /Predictor 15 /Columns %d >>" % (width-2)
		colorspace = "/DeviceGray"
		procset = "/ImageB" # grayscale
	elif im.mode == "P":
		filter = "/ASCIIHexDecode"
		colorspace = "[ /Indexed /DeviceRGB 255 <"
		palette = im.im.getpalette("RGB")
		for i in range(256):
			r = ord(palette[i*3])
			g = ord(palette[i*3+1])
			b = ord(palette[i*3+2])
			colorspace = colorspace + "%02x%02x%02x " % (r, g, b)
		colorspace = colorspace + "> ]"
		procset = "/ImageI" # indexed color
	elif im.mode == "RGB":
		filter = "/DCTDecode"
		colorspace = "/DeviceRGB"
		procset = "/ImageC" # color images
	elif im.mode == "CMYK":
		filter = "/DCTDecode"
		colorspace = "/DeviceCMYK"
		procset = "/ImageC" # color images
	else:
		raise ValueError("cannot save mode %s" % im.mode)

	#
	# catalogue

	xref[1] = fp.tell()
	_obj(fp, 1, Type = "/Catalog",
				Pages = "2 0 R")
	_endobj(fp)

	#
	# pages

	xref[2] = fp.tell()
	_obj(fp, 2, Type = "/Pages",
				Count = 1,
				Kids = "[4 0 R]")
	_endobj(fp)

	#
	# image

	op = StringIO.StringIO()

	if filter == "/ASCIIHexDecode":
		if bits == 1:
			# FIXME: the hex encoder doesn't support packed 1-bit
			# images; do things the hard way...
			data = im.tostring("raw", "1")
			im = Image.new("L", (len(data), 1), None)
			im.putdata(data)
		ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, im.mode)])
	elif filter == "/DCTDecode":
		ImageFile._save(im, op, [("jpeg", (0,0)+im.size, 0, im.mode)])
	elif filter == "/FlateDecode":
		ImageFile._save(im, op, [("zip", (0,0)+im.size, 0, im.mode)])
	elif filter == "/RunLengthDecode":
		ImageFile._save(im, op, [("packbits", (0,0)+im.size, 0, im.mode)])
	else:
		raise ValueError("unsupported PDF filter (%s)" % filter)

	xref[3] = fp.tell()
	_obj(fp, 3, Type = "/XObject",
				Subtype = "/Image",
				Width = width, # * 72.0 / resolution,
				Height = height, # * 72.0 / resolution,
				Length = len(op.getvalue()),
				Filter = filter,
				BitsPerComponent = bits,
				DecodeParams = params,
				ColorSpace = colorspace)

	fp.write("stream\n")
	fp.write(op.getvalue())
	fp.write("\nendstream\n")

	_endobj(fp)

	#
	# page

	xref[4] = fp.tell()
	_obj(fp, 4)
	fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\
			 "/Resources <<\n/ProcSet [ /PDF %s ]\n"\
			 "/XObject << /image 3 0 R >>\n>>\n"\
			 "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\
			 (procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution)))
	_endobj(fp)

	#
	# page contents

	op = StringIO.StringIO()

	op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution)))

	xref[5] = fp.tell()
	_obj(fp, 5, Length = len(op.getvalue()))

	fp.write("stream\n")
	fp.write(op.getvalue())
	fp.write("\nendstream\n")

	_endobj(fp)

	#
	# trailer
	startxref = fp.tell()
	fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref))
	for x in xref[1:]:
		fp.write("%010d 00000 n \n" % x)
	fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref))
	fp.write("startxref\n%d\n%%%%EOF\n" % startxref)
	fp.flush()
예제 #48
0
def _save(im, fp, filename):

	try:
		rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode]
	except KeyError:
		raise IOError, "cannot write mode %s as TIFF" % im.mode

	ifd = ImageFileDirectory(prefix)

	# -- multi-page -- skip TIFF header on subsequent pages
	if fp.tell() == 0:
		# tiff header (write via IFD to get everything right)
		# PIL always starts the first IFD at offset 8
		fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8))

	ifd[IMAGEWIDTH] = im.size[0]
	ifd[IMAGELENGTH] = im.size[1]

	# additions written by Greg Couch, [email protected]
	# inspired by image-sig posting from Kevin Cazabon, [email protected]
	if hasattr(im, 'tag'):
		# preserve tags from original TIFF image file
		for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION):
			if im.tag.tagdata.has_key(key):
				ifd[key] = im.tag.tagdata.get(key)
		# preserve some more tags from original TIFF image file
		# -- 2008-06-06 Florian Hoech
		ifd.tagtype = im.tag.tagtype
		for key in (IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, XMP):
			if im.tag.has_key(key):
				ifd[key] = im.tag[key]
		# preserve ICC profile (should also work when saving other formats
		# which support profiles as TIFF) -- 2008-06-06 Florian Hoech
		if im.info.has_key("icc_profile"):
			ifd[ICCPROFILE] = im.info["icc_profile"]
	if im.encoderinfo.has_key("description"):
		ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"]
	if im.encoderinfo.has_key("resolution"):
		ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \
								= _cvt_res(im.encoderinfo["resolution"])
	if im.encoderinfo.has_key("x resolution"):
		ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"])
	if im.encoderinfo.has_key("y resolution"):
		ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"])
	if im.encoderinfo.has_key("resolution unit"):
		unit = im.encoderinfo["resolution unit"]
		if unit == "inch":
			ifd[RESOLUTION_UNIT] = 2
		elif unit == "cm" or unit == "centimeter":
			ifd[RESOLUTION_UNIT] = 3
		else:
			ifd[RESOLUTION_UNIT] = 1
	if im.encoderinfo.has_key("software"):
		ifd[SOFTWARE] = im.encoderinfo["software"]
	if im.encoderinfo.has_key("date time"):
		ifd[DATE_TIME] = im.encoderinfo["date time"]
	if im.encoderinfo.has_key("artist"):
		ifd[ARTIST] = im.encoderinfo["artist"]
	if im.encoderinfo.has_key("copyright"):
		ifd[COPYRIGHT] = im.encoderinfo["copyright"]

	dpi = im.encoderinfo.get("dpi")
	if dpi:
		ifd[RESOLUTION_UNIT] = 2
		ifd[X_RESOLUTION] = _cvt_res(dpi[0])
		ifd[Y_RESOLUTION] = _cvt_res(dpi[1])

	if bits != (1,):
		ifd[BITSPERSAMPLE] = bits
		if len(bits) != 1:
			ifd[SAMPLESPERPIXEL] = len(bits)
	if extra is not None:
		ifd[EXTRASAMPLES] = extra
	if format != 1:
		ifd[SAMPLEFORMAT] = format

	ifd[PHOTOMETRIC_INTERPRETATION] = photo

	if im.mode == "P":
		lut = im.im.getpalette("RGB", "RGB;L")
		ifd[COLORMAP] = tuple(map(lambda v: ord(v) * 256, lut))

	# data orientation
	stride = len(bits) * ((im.size[0]*bits[0]+7)/8)
	ifd[ROWSPERSTRIP] = im.size[1]
	ifd[STRIPBYTECOUNTS] = stride * im.size[1]
	ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer
	ifd[COMPRESSION] = 1 # no compression

	offset = ifd.save(fp)

	ImageFile._save(im, fp, [
		("raw", (0,0)+im.size, offset, (rawmode, stride, 1))
		])


	# -- helper for multi-page save --
	if im.encoderinfo.has_key("_debug_multipage"):
		#just to access o32 and o16 (using correct byte order)
		im._debug_multipage = ifd
예제 #49
0
def _save(im, fp, filename, chunk=putchunk, check=0):
    # save an image to disk (called by the save method)

    mode = im.mode

    if mode == "P":

        #
        # attempt to minimize storage requirements for palette images

        if im.encoderinfo.has_key("bits"):

            # number of bits specified by user
            n = 1 << im.encoderinfo["bits"]

        else:

            # check palette contents
            n = 256  # FIXME

        if n <= 2:
            bits = 1
        elif n <= 4:
            bits = 2
        elif n <= 16:
            bits = 4
        else:
            bits = 8

        if bits != 8:
            mode = "%s;%d" % (mode, bits)

    # encoder options
    if im.encoderinfo.has_key("dictionary"):
        dictionary = im.encoderinfo["dictionary"]
    else:
        dictionary = ""

    im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary)

    # get the corresponding PNG mode
    try:
        rawmode, mode = _OUTMODES[mode]
    except KeyError:
        raise IOError, "cannot write mode %s as PNG" % mode

    if check:
        return check

    #
    # write minimal PNG file

    fp.write(_MAGIC)

    chunk(
        fp,
        "IHDR",
        o32(im.size[0]),
        o32(im.size[1]),  #  0: size
        mode,  #  8: depth/type
        chr(0),  # 10: compression
        chr(0),  # 11: filter category
        chr(0))  # 12: interlace flag

    if im.mode == "P":
        chunk(fp, "PLTE", im.im.getpalette("RGB"))

    if im.encoderinfo.has_key("transparency"):
        if im.mode == "P":
            transparency = max(0, min(255, im.encoderinfo["transparency"]))
            chunk(fp, "tRNS", chr(255) * transparency + chr(0))
        elif im.mode == "L":
            transparency = max(0, min(65535, im.encoderinfo["transparency"]))
            chunk(fp, "tRNS", o16(transparency))
        elif im.mode == "RGB":
            red, green, blue = im.encoderinfo["transparency"]
            chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue))
        else:
            raise IOError("cannot use transparency for this mode")

    if 0:
        # FIXME: to be supported some day
        chunk(fp, "gAMA", o32(int(gamma * 100000.0)))

    dpi = im.encoderinfo.get("dpi")
    if dpi:
        chunk(fp, "pHYs", o32(int(dpi[0] / 0.0254 + 0.5)),
              o32(int(dpi[1] / 0.0254 + 0.5)), chr(1))

    info = im.encoderinfo.get("pnginfo")
    if info:
        for cid, data in info.chunks:
            chunk(fp, cid, data)

    # ICC profile writing support -- 2008-06-06 Florian Hoech
    if im.info.has_key("icc_profile"):
        # ICC profile
        # according to PNG spec, the iCCP chunk contains:
        # Profile name  1-79 bytes (character string)
        # Null separator		1 byte (null character)
        # Compression method	1 byte (0)
        # Compressed profile	n bytes (zlib with deflate compression)
        try:
            import ICCProfile
            p = ICCProfile.ICCProfile(im.info["icc_profile"])
            name = p.tags.desc.get(
                "ASCII",
                p.tags.desc.get(
                    "Unicode",
                    p.tags.desc.get(
                        "Macintosh",
                        p.tags.desc.get("en",
                                        {}).get("US", "ICC Profile")))).encode(
                                            "latin1", "replace")[:79]
        except ImportError:
            name = "ICC Profile"
        data = name + "\0\0" + zlib.compress(im.info["icc_profile"])
        chunk(fp, "iCCP", data)

    ImageFile._save(im, _idat(fp, chunk),
                    [("zip", (0, 0) + im.size, 0, rawmode)])

    chunk(fp, "IEND", "")

    try:
        fp.flush()
    except:
        pass
예제 #50
0
def _save(im, fp, filename, check=0):

    if im.mode == "P":

        # we assume this is a color Palm image with the standard colormap,
        # unless the "info" dict has a "custom-colormap" field

        rawmode = "P"
        bpp = 8
        version = 1

    elif im.mode == "L" and im.encoderinfo.has_key(
            "bpp") and im.encoderinfo["bpp"] in (1, 2, 4):

        # this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because
        # Palm does greyscale from white (0) to black (1)
        bpp = im.encoderinfo["bpp"]
        im = im.point(lambda x, shift=8 - bpp, maxval=(1 << bpp) - 1: maxval -
                      (x >> shift))
        # we ignore the palette here
        im.mode = "P"
        rawmode = "P;" + str(bpp)
        version = 1

    elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2,
                                                                          4):

        # here we assume that even though the inherent mode is 8-bit grayscale, only
        # the lower bpp bits are significant.  We invert them to match the Palm.
        bpp = im.info["bpp"]
        im = im.point(lambda x, maxval=(1 << bpp) - 1: maxval - (x & maxval))
        # we ignore the palette here
        im.mode = "P"
        rawmode = "P;" + str(bpp)
        version = 1

    elif im.mode == "1":

        # monochrome -- write it inverted, as is the Palm standard
        rawmode = "1;I"
        bpp = 1
        version = 0

    else:

        raise IOError, "cannot write mode %s as Palm" % im.mode

    if check:
        return check

    #
    # make sure image data is available
    im.load()

    # write header

    cols = im.size[0]
    rows = im.size[1]

    rowbytes = ((cols + (16 / bpp - 1)) / (16 / bpp)) * 2
    transparent_index = 0
    compression_type = _COMPRESSION_TYPES["none"]

    flags = 0
    if im.mode == "P" and im.info.has_key("custom-colormap"):
        flags = flags & _FLAGS["custom-colormap"]
        colormapsize = 4 * 256 + 2
        colormapmode = im.palette.mode
        colormap = im.getdata().getpalette()
    else:
        colormapsize = 0

    if im.info.has_key("offset"):
        offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4
    else:
        offset = 0

    fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags))
    fp.write(chr(bpp))
    fp.write(chr(version))
    fp.write(o16b(offset))
    fp.write(chr(transparent_index))
    fp.write(chr(compression_type))
    fp.write(o16b(0))  # reserved by Palm

    # now write colormap if necessary

    if colormapsize > 0:
        fp.write(o16b(256))
        for i in range(256):
            fp.write(chr(i))
            if colormapmode == 'RGB':
                fp.write(
                    chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) +
                    chr(colormap[3 * i + 2]))
            elif colormapmode == 'RGBA':
                fp.write(
                    chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) +
                    chr(colormap[4 * i + 2]))

    # now convert data to raw form
    ImageFile._save(im, fp,
                    [("raw", (0, 0) + im.size, 0, (rawmode, rowbytes, 1))])

    fp.flush()
예제 #51
0
	def chunk_gAMA(self, pos, len):

		# gamma setting
		s = ImageFile._safe_read(self.fp, len)
		self.im_info["gamma"] = i32(s) / 100000.0
		return s
예제 #52
0
def _save(im, fp, filename, chunk=putchunk, check=0):
	# save an image to disk (called by the save method)

	mode = im.mode

	if mode == "P":

		#
		# attempt to minimize storage requirements for palette images

		if im.encoderinfo.has_key("bits"):

			# number of bits specified by user
			n = 1 << im.encoderinfo["bits"]

		else:

			# check palette contents
			n = 256 # FIXME

		if n <= 2:
			bits = 1
		elif n <= 4:
			bits = 2
		elif n <= 16:
			bits = 4
		else:
			bits = 8

		if bits != 8:
			mode = "%s;%d" % (mode, bits)

	# encoder options
	if im.encoderinfo.has_key("dictionary"):
		dictionary = im.encoderinfo["dictionary"]
	else:
		dictionary = ""

	im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary)

	# get the corresponding PNG mode
	try:
		rawmode, mode = _OUTMODES[mode]
	except KeyError:
		raise IOError, "cannot write mode %s as PNG" % mode

	if check:
		return check

	#
	# write minimal PNG file

	fp.write(_MAGIC)

	chunk(fp, "IHDR",
		  o32(im.size[0]), o32(im.size[1]),	 #  0: size
		  mode,								 #  8: depth/type
		  chr(0),							   # 10: compression
		  chr(0),							   # 11: filter category
		  chr(0))							   # 12: interlace flag

	if im.mode == "P":
		chunk(fp, "PLTE", im.im.getpalette("RGB"))

	if im.encoderinfo.has_key("transparency"):
		if im.mode == "P":
			transparency = max(0, min(255, im.encoderinfo["transparency"]))
			chunk(fp, "tRNS", chr(255) * transparency + chr(0))
		elif im.mode == "L":
			transparency = max(0, min(65535, im.encoderinfo["transparency"]))
			chunk(fp, "tRNS", o16(transparency))
		elif im.mode == "RGB":
			red, green, blue = im.encoderinfo["transparency"]
			chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue))
		else:
			raise IOError("cannot use transparency for this mode")

	if 0:
		# FIXME: to be supported some day
		chunk(fp, "gAMA", o32(int(gamma * 100000.0)))

	dpi = im.encoderinfo.get("dpi")
	if dpi:
		chunk(fp, "pHYs",
			  o32(int(dpi[0] / 0.0254 + 0.5)),
			  o32(int(dpi[1] / 0.0254 + 0.5)),
			  chr(1))

	info = im.encoderinfo.get("pnginfo")
	if info:
		for cid, data in info.chunks:
			chunk(fp, cid, data)

	# ICC profile writing support -- 2008-06-06 Florian Hoech
	if im.info.has_key("icc_profile"):
		# ICC profile
		# according to PNG spec, the iCCP chunk contains:
		# Profile name  1-79 bytes (character string)
		# Null separator		1 byte (null character)
		# Compression method	1 byte (0)
		# Compressed profile	n bytes (zlib with deflate compression)
		try:
			import ICCProfile
			p = ICCProfile.ICCProfile(im.info["icc_profile"])
			name = p.tags.desc.get("ASCII", p.tags.desc.get("Unicode", p.tags.desc.get("Macintosh", p.tags.desc.get("en", {}).get("US", "ICC Profile")))).encode("latin1", "replace")[:79]
		except ImportError:
			name = "ICC Profile"
		data = name + "\0\0" + zlib.compress(im.info["icc_profile"])
		chunk(fp, "iCCP", data)

	ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)])

	chunk(fp, "IEND", "")

	try:
		fp.flush()
	except:
		pass