class WaveForm(RIFFForm): _chunk_types = { asbytes('fmt '): WaveFormatChunk, asbytes('data'): WaveDataChunk } def get_format_chunk(self): for chunk in self.get_chunks(): if isinstance(chunk, WaveFormatChunk): return chunk def get_data_chunk(self): for chunk in self.get_chunks(): if isinstance(chunk, WaveDataChunk): return chunk
def __init__(self, *args, **kwargs): super(RIFFType, self).__init__(*args, **kwargs) self.file.seek(self.offset) form = self.file.read(4) if form != asbytes('WAVE'): raise RIFFFormatException('Unsupported RIFF form "%s"' % form) self.form = WaveForm(self.file, self.offset + 4)
def _install_restore_mode_child(): global _mode_write_pipe global _restore_mode_child_installed if _restore_mode_child_installed: return # Parent communicates to child by sending "mode packets" through a pipe: mode_read_pipe, _mode_write_pipe = os.pipe() if os.fork() == 0: # Child process (watches for parent to die then restores video mode(s). os.close(_mode_write_pipe) # Set up SIGHUP to be the signal for when the parent dies. PR_SET_PDEATHSIG = 1 libc = ctypes.cdll.LoadLibrary('libc.so.6') libc.prctl.argtypes = (ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong) libc.prctl(PR_SET_PDEATHSIG, signal.SIGHUP, 0, 0, 0) # SIGHUP indicates the parent has died. The child lock is unlocked, it # stops reading from the mode packet pipe and restores video modes on # all displays/screens it knows about. def _sighup(signum, frame): parent_wait_lock.release() parent_wait_lock = threading.Lock() parent_wait_lock.acquire() signal.signal(signal.SIGHUP, _sighup) # Wait for parent to die and read packets from parent pipe packets = [] buffer = asbytes('') while parent_wait_lock.locked(): try: data = os.read(mode_read_pipe, ModePacket.size) buffer += data # Decode packets while len(buffer) >= ModePacket.size: packet = ModePacket.decode(buffer[:ModePacket.size]) packets.append(packet) buffer = buffer[ModePacket.size:] except OSError: pass # Interrupted system call for packet in packets: packet.set() os._exit(0) else: # Parent process. Clean up pipe then continue running program as # normal. Send mode packets through pipe as additional # displays/screens are mode switched. os.close(mode_read_pipe) _restore_mode_child_installed = True
def _install_restore_mode_child(): global _mode_write_pipe global _restore_mode_child_installed if _restore_mode_child_installed: return # Parent communicates to child by sending "mode packets" through a pipe: mode_read_pipe, _mode_write_pipe = os.pipe() if os.fork() == 0: # Child process (watches for parent to die then restores video mode(s). os.close(_mode_write_pipe) # Set up SIGHUP to be the signal for when the parent dies. PR_SET_PDEATHSIG = 1 libc = ctypes.cdll.LoadLibrary('libc.so.6') libc.prctl.argtypes = (ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong) libc.prctl(PR_SET_PDEATHSIG, signal.SIGHUP, 0, 0, 0) # SIGHUP indicates the parent has died. The child lock is unlocked, it # stops reading from the mode packet pipe and restores video modes on # all displays/screens it knows about. def _sighup(signum, frame): parent_wait_lock.release(); parent_wait_lock = threading.Lock(); parent_wait_lock.acquire() signal.signal(signal.SIGHUP, _sighup) # Wait for parent to die and read packets from parent pipe packets = [] buffer = asbytes('') while parent_wait_lock.locked(): try: data = os.read(mode_read_pipe, ModePacket.size) buffer += data # Decode packets while len(buffer) >= ModePacket.size: packet = ModePacket.decode(buffer[:ModePacket.size]) packets.append(packet) buffer = buffer[ModePacket.size:] except OSError: pass # Interrupted system call for packet in packets: packet.set() os._exit(0) else: # Parent process. Clean up pipe then continue running program as # normal. Send mode packets through pipe as additional # displays/screens are mode switched. os.close(mode_read_pipe) _restore_mode_child_installed = True
class RIFFFile(RIFFForm): _chunk_types = { asbytes('RIFF'): RIFFType, } def __init__(self, file): if not hasattr(file, 'seek'): file = BytesIO(file.read()) super(RIFFFile, self).__init__(file, 0) def get_wave_form(self): chunks = self.get_chunks() if len(chunks) == 1 and isinstance(chunks[0], RIFFType): return chunks[0].form
def read(self): """ Read a simple PNG file, return width, height, pixels and image metadata This function is a very early prototype with limited flexibility and excessive use of memory. """ signature = self.file.read(8) if (signature != struct.pack("8B", 137, 80, 78, 71, 13, 10, 26, 10)): raise Error("PNG file has invalid header") compressed = [] image_metadata = {} while True: try: tag, data = self.read_chunk() except ValueError, e: raise Error('Chunk error: ' + e.args[0]) # print >> sys.stderr, tag, len(data) if tag == asbytes('IHDR'): # http://www.w3.org/TR/PNG/#11IHDR (width, height, bits_per_sample, color_type, compression_method, filter_method, interlaced) = struct.unpack("!2I5B", data) bps = bits_per_sample // 8 if bps == 0: raise Error("unsupported pixel depth") if bps > 2 or bits_per_sample != (bps * 8): raise Error("invalid pixel depth") if color_type == 0: greyscale = True has_alpha = False planes = 1 elif color_type == 2: greyscale = False has_alpha = False planes = 3 elif color_type == 4: greyscale = True has_alpha = True planes = 2 elif color_type == 6: greyscale = False has_alpha = True planes = 4 else: raise Error("unknown PNG colour type %s" % color_type) if compression_method != 0: raise Error("unknown compression method") if filter_method != 0: raise Error("unknown filter method") self.bps = bps self.planes = planes self.psize = bps * planes self.width = width self.height = height self.row_bytes = width * self.psize elif tag == asbytes('IDAT'): # http://www.w3.org/TR/PNG/#11IDAT compressed.append(data) elif tag == asbytes('bKGD'): if greyscale: image_metadata["background"] = struct.unpack("!1H", data) else: image_metadata["background"] = struct.unpack("!3H", data) elif tag == asbytes('tRNS'): if greyscale: image_metadata["transparent"] = struct.unpack("!1H", data) else: image_metadata["transparent"] = struct.unpack("!3H", data) elif tag == asbytes('gAMA'): image_metadata["gamma"] = ( struct.unpack("!L", data)[0]) / 100000.0 elif tag == asbytes('IEND'): # http://www.w3.org/TR/PNG/#11IEND break
def decode(cls, data): display, screen, width, height, rate = \ struct.unpack(cls.format, data) return cls(display.strip(asbytes('\0')), screen, width, height, rate)
def read(self): """ Read a simple PNG file, return width, height, pixels and image metadata This function is a very early prototype with limited flexibility and excessive use of memory. """ signature = self.file.read(8) if (signature != struct.pack("8B", 137, 80, 78, 71, 13, 10, 26, 10)): raise Error("PNG file has invalid header") compressed = [] image_metadata = {} while True: try: tag, data = self.read_chunk() except ValueError, e: raise Error('Chunk error: ' + e.args[0]) # print >> sys.stderr, tag, len(data) if tag == asbytes('IHDR'): # http://www.w3.org/TR/PNG/#11IHDR (width, height, bits_per_sample, color_type, compression_method, filter_method, interlaced) = struct.unpack("!2I5B", data) bps = bits_per_sample // 8 if bps == 0: raise Error("unsupported pixel depth") if bps > 2 or bits_per_sample != (bps * 8): raise Error("invalid pixel depth") if color_type == 0: greyscale = True has_alpha = False planes = 1 elif color_type == 2: greyscale = False has_alpha = False planes = 3 elif color_type == 4: greyscale = True has_alpha = True planes = 2 elif color_type == 6: greyscale = False has_alpha = True planes = 4 else: raise Error("unknown PNG colour type %s" % color_type) if compression_method != 0: raise Error("unknown compression method") if filter_method != 0: raise Error("unknown filter method") self.bps = bps self.planes = planes self.psize = bps * planes self.width = width self.height = height self.row_bytes = width * self.psize elif tag == asbytes('IDAT'): # http://www.w3.org/TR/PNG/#11IDAT compressed.append(data) elif tag == asbytes('bKGD'): if greyscale: image_metadata["background"] = struct.unpack("!1H", data) else: image_metadata["background"] = struct.unpack("!3H", data) elif tag == asbytes('tRNS'): if greyscale: image_metadata["transparent"] = struct.unpack("!1H", data) else: image_metadata["transparent"] = struct.unpack("!3H", data) elif tag == asbytes('gAMA'): image_metadata["gamma"] = (struct.unpack("!L", data)[0]) / 100000.0 elif tag == asbytes('IEND'): # http://www.w3.org/TR/PNG/#11IEND break
class Reader: """ PNG decoder in pure Python. """ def __init__(self, _guess=None, **kw): """ Create a PNG decoder object. The constructor expects exactly one keyword argument. If you supply a positional argument instead, it will guess the input type. You can choose among the following arguments: filename - name of PNG input file file - object with a read() method pixels - array or string with PNG data """ if ((_guess is not None and len(kw) != 0) or (_guess is None and len(kw) != 1)): raise TypeError("Reader() takes exactly 1 argument") if _guess is not None: if isinstance(_guess, array): kw["pixels"] = _guess elif isinstance(_guess, str): kw["filename"] = _guess elif isinstance(_guess, file): kw["file"] = _guess if "filename" in kw: self.file = file(kw["filename"]) elif "file" in kw: self.file = kw["file"] elif "pixels" in kw: self.file = _readable(kw["pixels"]) else: raise TypeError("expecting filename, file or pixels array") def read_chunk(self): """ Read a PNG chunk from the input file, return tag name and data. """ # http://www.w3.org/TR/PNG/#5Chunk-layout try: data_bytes, tag = struct.unpack('!I4s', self.file.read(8)) except struct.error: raise ValueError('Chunk too short for header') data = self.file.read(data_bytes) if len(data) != data_bytes: raise ValueError('Chunk %s too short for required %i data octets' % (tag, data_bytes)) checksum = self.file.read(4) if len(checksum) != 4: raise ValueError('Chunk %s too short for checksum', tag) verify = zlib.crc32(tag) verify = zlib.crc32(data, verify) # Whether the output from zlib.crc32 is signed or not varies # according to hideous implementation details, see # http://bugs.python.org/issue1202 . # We coerce it to be positive here (in a way which works on # Python 2.3 and older). verify &= 2**32 - 1 verify = struct.pack('!I', verify) if checksum != verify: # print repr(checksum) (a, ) = struct.unpack('!I', checksum) (b, ) = struct.unpack('!I', verify) raise ValueError("Checksum error in %s chunk: 0x%X != 0x%X" % (tag, a, b)) return tag, data def _reconstruct_sub(self, offset, xstep, ystep): """ Reverse sub filter. """ pixels = self.pixels a_offset = offset offset += self.psize * xstep if xstep == 1: for index in range(self.psize, self.row_bytes): x = pixels[offset] a = pixels[a_offset] pixels[offset] = (x + a) & 0xff offset += 1 a_offset += 1 else: byte_step = self.psize * xstep for index in range(byte_step, self.row_bytes, byte_step): for i in range(self.psize): x = pixels[offset + i] a = pixels[a_offset + i] pixels[offset + i] = (x + a) & 0xff offset += self.psize * xstep a_offset += self.psize * xstep def _reconstruct_up(self, offset, xstep, ystep): """ Reverse up filter. """ pixels = self.pixels b_offset = offset - (self.row_bytes * ystep) if xstep == 1: for index in range(self.row_bytes): x = pixels[offset] b = pixels[b_offset] pixels[offset] = (x + b) & 0xff offset += 1 b_offset += 1 else: for index in range(0, self.row_bytes, xstep * self.psize): for i in range(self.psize): x = pixels[offset + i] b = pixels[b_offset + i] pixels[offset + i] = (x + b) & 0xff offset += self.psize * xstep b_offset += self.psize * xstep def _reconstruct_average(self, offset, xstep, ystep): """ Reverse average filter. """ pixels = self.pixels a_offset = offset - (self.psize * xstep) b_offset = offset - (self.row_bytes * ystep) if xstep == 1: for index in range(self.row_bytes): x = pixels[offset] if index < self.psize: a = 0 else: a = pixels[a_offset] if b_offset < 0: b = 0 else: b = pixels[b_offset] pixels[offset] = (x + ((a + b) >> 1)) & 0xff offset += 1 a_offset += 1 b_offset += 1 else: for index in range(0, self.row_bytes, self.psize * xstep): for i in range(self.psize): x = pixels[offset + i] if index < self.psize: a = 0 else: a = pixels[a_offset + i] if b_offset < 0: b = 0 else: b = pixels[b_offset + i] pixels[offset + i] = (x + ((a + b) >> 1)) & 0xff offset += self.psize * xstep a_offset += self.psize * xstep b_offset += self.psize * xstep def _reconstruct_paeth(self, offset, xstep, ystep): """ Reverse Paeth filter. """ pixels = self.pixels a_offset = offset - (self.psize * xstep) b_offset = offset - (self.row_bytes * ystep) c_offset = b_offset - (self.psize * xstep) # There's enough inside this loop that it's probably not worth # optimising for xstep == 1 for index in range(0, self.row_bytes, self.psize * xstep): for i in range(self.psize): x = pixels[offset + i] if index < self.psize: a = c = 0 b = pixels[b_offset + i] else: a = pixels[a_offset + i] b = pixels[b_offset + i] c = pixels[c_offset + i] p = a + b - c pa = abs(p - a) pb = abs(p - b) pc = abs(p - c) if pa <= pb and pa <= pc: pr = a elif pb <= pc: pr = b else: pr = c pixels[offset + i] = (x + pr) & 0xff offset += self.psize * xstep a_offset += self.psize * xstep b_offset += self.psize * xstep c_offset += self.psize * xstep # N.B. PNG files with 'up', 'average' or 'paeth' filters on the # first line of a pass are legal. The code above for 'average' # deals with this case explicitly. For up we map to the null # filter and for paeth we map to the sub filter. def reconstruct_line(self, filter_type, first_line, offset, xstep, ystep): # print >> sys.stderr, "Filter type %s, first_line=%s" % ( # filter_type, first_line) filter_type += (first_line << 8) if filter_type == 1 or filter_type == 0x101 or filter_type == 0x104: self._reconstruct_sub(offset, xstep, ystep) elif filter_type == 2: self._reconstruct_up(offset, xstep, ystep) elif filter_type == 3 or filter_type == 0x103: self._reconstruct_average(offset, xstep, ystep) elif filter_type == 4: self._reconstruct_paeth(offset, xstep, ystep) return def deinterlace(self, scanlines): # print >> sys.stderr, ("Reading interlaced, w=%s, r=%s, planes=%s," + # " bpp=%s") % (self.width, self.height, self.planes, self.bps) a = array('B') self.pixels = a # Make the array big enough temp = scanlines[0:self.width * self.height * self.psize] a.extend(temp) source_offset = 0 for xstart, ystart, xstep, ystep in _adam7: # print >> sys.stderr, "Adam7: start=%s,%s step=%s,%s" % ( # xstart, ystart, xstep, ystep) filter_first_line = 1 for y in range(ystart, self.height, ystep): if xstart >= self.width: continue filter_type = scanlines[source_offset] source_offset += 1 if xstep == 1: offset = y * self.row_bytes a[offset:offset+self.row_bytes] = \ scanlines[source_offset:source_offset + self.row_bytes] source_offset += self.row_bytes else: # Note we want the ceiling of (width - xstart) / xtep row_len = self.psize * ( (self.width - xstart + xstep - 1) / xstep) offset = y * self.row_bytes + xstart * self.psize end_offset = (y + 1) * self.row_bytes skip = self.psize * xstep for i in range(self.psize): a[offset+i:end_offset:skip] = \ scanlines[source_offset + i: source_offset + row_len: self.psize] source_offset += row_len if filter_type: self.reconstruct_line(filter_type, filter_first_line, offset, xstep, ystep) filter_first_line = 0 return a def read_flat(self, scanlines): a = array('B') self.pixels = a offset = 0 source_offset = 0 filter_first_line = 1 for y in range(self.height): filter_type = scanlines[source_offset] source_offset += 1 a.extend(scanlines[source_offset:source_offset + self.row_bytes]) if filter_type: self.reconstruct_line(filter_type, filter_first_line, offset, 1, 1) filter_first_line = 0 offset += self.row_bytes source_offset += self.row_bytes return a def read(self): """ Read a simple PNG file, return width, height, pixels and image metadata This function is a very early prototype with limited flexibility and excessive use of memory. """ signature = self.file.read(8) if (signature != struct.pack("8B", 137, 80, 78, 71, 13, 10, 26, 10)): raise Error("PNG file has invalid header") compressed = [] image_metadata = {} while True: try: tag, data = self.read_chunk() except ValueError, e: raise Error('Chunk error: ' + e.args[0]) # print >> sys.stderr, tag, len(data) if tag == asbytes('IHDR'): # http://www.w3.org/TR/PNG/#11IHDR (width, height, bits_per_sample, color_type, compression_method, filter_method, interlaced) = struct.unpack("!2I5B", data) bps = bits_per_sample // 8 if bps == 0: raise Error("unsupported pixel depth") if bps > 2 or bits_per_sample != (bps * 8): raise Error("invalid pixel depth") if color_type == 0: greyscale = True has_alpha = False planes = 1 elif color_type == 2: greyscale = False has_alpha = False planes = 3 elif color_type == 4: greyscale = True has_alpha = True planes = 2 elif color_type == 6: greyscale = False has_alpha = True planes = 4 else: raise Error("unknown PNG colour type %s" % color_type) if compression_method != 0: raise Error("unknown compression method") if filter_method != 0: raise Error("unknown filter method") self.bps = bps self.planes = planes self.psize = bps * planes self.width = width self.height = height self.row_bytes = width * self.psize elif tag == asbytes('IDAT'): # http://www.w3.org/TR/PNG/#11IDAT compressed.append(data) elif tag == asbytes('bKGD'): if greyscale: image_metadata["background"] = struct.unpack("!1H", data) else: image_metadata["background"] = struct.unpack("!3H", data) elif tag == asbytes('tRNS'): if greyscale: image_metadata["transparent"] = struct.unpack("!1H", data) else: image_metadata["transparent"] = struct.unpack("!3H", data) elif tag == asbytes('gAMA'): image_metadata["gamma"] = (struct.unpack("!L", data)[0]) / 100000.0 elif tag == asbytes('IEND'): # http://www.w3.org/TR/PNG/#11IEND break scanlines = array('B', zlib.decompress(asbytes('').join(compressed))) if interlaced: pixels = self.deinterlace(scanlines) else: pixels = self.read_flat(scanlines) image_metadata["greyscale"] = greyscale image_metadata["has_alpha"] = has_alpha image_metadata["bytes_per_sample"] = bps image_metadata["interlaced"] = interlaced return width, height, pixels, image_metadata
import fos.lib.pyglet.lib from fos.lib.pyglet.font import base from fos.lib.pyglet import image from fos.lib.pyglet.font.freetype_lib import * from fos.lib.pyglet.compat import asbytes # fontconfig library definitions fontconfig = fos.lib.pyglet.lib.load_library('fontconfig') FcResult = c_int fontconfig.FcPatternBuild.restype = c_void_p fontconfig.FcFontMatch.restype = c_void_p fontconfig.FcFreeTypeCharIndex.restype = c_uint FC_FAMILY = asbytes('family') FC_SIZE = asbytes('size') FC_SLANT = asbytes('slant') FC_WEIGHT = asbytes('weight') FC_FT_FACE = asbytes('ftface') FC_FILE = asbytes('file') FC_WEIGHT_REGULAR = 80 FC_WEIGHT_BOLD = 200 FC_SLANT_ROMAN = 0 FC_SLANT_ITALIC = 100 FT_STYLE_FLAG_ITALIC = 1 FT_STYLE_FLAG_BOLD = 2
def set(self): self._event.set() os.write(self._sync_file_write, asbytes('1'))