# ---------------------------------------------------------------------------- # pyglet # Copyright (c) 2006-2008 Alex Holkner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of pyglet nor the names of its # contributors may be used to endorse or promote products # derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # ---------------------------------------------------------------------------- '''Collection of image encoders and decoders. Modules must subclass ImageDecoder and ImageEncoder for each method of decoding/encoding they support. Modules must also implement the two functions:: def get_decoders(): # Return a list of ImageDecoder instances or [] return [] def get_encoders(): # Return a list of ImageEncoder instances or [] return [] ''' __docformat__ = 'restructuredtext' __version__ = '$Id: $' import os.path _decoders = [] # List of registered ImageDecoders _decoder_extensions = {} # Map str -> list of matching ImageDecoders _decoder_animation_extensions = {} # Map str -> list of matching ImageDecoders _encoders = [] # List of registered ImageEncoders _encoder_extensions = {} # Map str -> list of matching ImageEncoders class ImageDecodeException(Exception): pass class ImageEncodeException(Exception): pass class ImageDecoder(object): def get_file_extensions(self): '''Return a list of accepted file extensions, e.g. ['.png', '.bmp'] Lower-case only. ''' return [] def get_animation_file_extensions(self): '''Return a list of accepted file extensions, e.g. ['.gif', '.flc'] Lower-case only. ''' return [] def decode(self, file, filename): '''Decode the given file object and return an instance of `Image`. Throws ImageDecodeException if there is an error. filename can be a file type hint. ''' raise NotImplementedError() def decode_animation(self, file, filename): '''Decode the given file object and return an instance of `Animation`. Throws ImageDecodeException if there is an error. filename can be a file type hint. ''' raise ImageDecodeException('This decoder cannot decode animations.') class ImageEncoder(object): def get_file_extensions(self): '''Return a list of accepted file extensions, e.g. ['.png', '.bmp'] Lower-case only. ''' return [] def encode(self, image, file, filename, options={}): '''Encode the given image to the given file. filename provides a hint to the file format desired. options are encoder-specific, and unknown options should be ignored or issue warnings. ''' raise NotImplementedError() def get_encoders(filename=None): '''Get an ordered list of encoders to attempt. filename can be used as a hint for the filetype. ''' encoders = [] if filename: extension = os.path.splitext(filename)[1].lower() encoders += _encoder_extensions.get(extension, []) encoders += [e for e in _encoders if e not in encoders] return encoders def get_decoders(filename=None): '''Get an ordered list of decoders to attempt. filename can be used as a hint for the filetype. ''' decoders = [] if filename: extension = os.path.splitext(filename)[1].lower() decoders += _decoder_extensions.get(extension, []) decoders += [e for e in _decoders if e not in decoders] return decoders def get_animation_decoders(filename=None): '''Get an ordered list of decoders to attempt. filename can be used as a hint for the filetype. ''' decoders = [] if filename: extension = os.path.splitext(filename)[1].lower() decoders += _decoder_animation_extensions.get(extension, []) decoders += [e for e in _decoders if e not in decoders] return decoders def add_decoders(module): '''Add a decoder module. The module must define `get_decoders`. Once added, the appropriate decoders defined in the codec will be returned by pyglet.image.codecs.get_decoders. ''' for decoder in module.get_decoders(): _decoders.append(decoder) for extension in decoder.get_file_extensions(): if extension not in _decoder_extensions: _decoder_extensions[extension] = [] _decoder_extensions[extension].append(decoder) for extension in decoder.get_animation_file_extensions(): if extension not in _decoder_animation_extensions: _decoder_animation_extensions[extension] = [] _decoder_animation_extensions[extension].append(decoder) def add_encoders(module): '''Add an encoder module. The module must define `get_encoders`. Once added, the appropriate encoders defined in the codec will be returned by pyglet.image.codecs.get_encoders. ''' for encoder in module.get_encoders(): _encoders.append(encoder) for extension in encoder.get_file_extensions(): if extension not in _encoder_extensions: _encoder_extensions[extension] = [] _encoder_extensions[extension].append(encoder) def add_default_image_codecs(): # Add the codecs we know about. These should be listed in order of # preference. This is called automatically by pyglet.image. # Compressed texture in DDS format try: from pyglet.image.codecs import dds add_encoders(dds) add_decoders(dds) except ImportError: pass # Mac OS X default: QuickTime try: import pyglet.image.codecs.quicktime add_encoders(quicktime) add_decoders(quicktime) except ImportError: pass # Windows XP default: GDI+ try: import pyglet.image.codecs.gdiplus add_encoders(gdiplus) add_decoders(gdiplus) except ImportError: pass # Linux default: GdkPixbuf 2.0 try: import pyglet.image.codecs.gdkpixbuf2 add_encoders(gdkpixbuf2) add_decoders(gdkpixbuf2) except ImportError: pass # Fallback: PIL try: import pyglet.image.codecs.pil add_encoders(pil) add_decoders(pil) except ImportError: pass # Fallback: PNG loader (slow) try: import pyglet.image.codecs.png add_encoders(png) add_decoders(png) except ImportError: pass # Fallback: BMP loader (slow) try: import pyglet.image.codecs.bmp add_encoders(bmp) add_decoders(bmp) except ImportError: pass