# -*- coding: utf-8 -*- # # libcaca Colour ASCII-Art library # Python language bindings # Copyright (c) 2010 Alex Foulon # All Rights Reserved # # This library is free software. It comes without any warranty, to # the extent permitted by applicable law. You can redistribute it # and/or modify it under the terms of the Do What the Fuck You Want # to Public License, Version 2, as published by Sam Hocevar. See # http://www.wtfpl.net/ for more details. # """ Libcaca Python bindings """ import ctypes from caca import _lib from caca.canvas import _Canvas class _DitherStruct(ctypes.Structure): pass class _Dither(object): """ Model for Dither object. """ def __init__(self): self._dither = None def from_param(self): """ Required by ctypes module to call object as parameter of a C function. """ return self._dither def __del__(self): if self._dither: self._free() def __str__(self): return "" def _free(self): """ Free a libcaca dither. """ _lib.caca_free_dither.argtypes = [_Dither] _lib.caca_free_dither.restype = ctypes.c_int return _lib.caca_free_dither(self) class Dither(_Dither): """ Dither object, methods are libcaca functions with caca_dither_t as first argument. """ def __init__(self, bpp, width, height, pitch, rmask, gmask, bmask, amask): """ Dither constructor bpp -- bitmap depth in bits per pixels width -- bitmap width in pixels height -- bitmap height in pixels pitch -- bitmap pitch in bytes rmask -- bitmask for red values gmask -- bitmask for green values bmask -- bitmask for blue values amask -- bitmask for alpha values """ _lib.caca_create_dither.argtypes = [ ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ] _lib.caca_create_dither.restype = ctypes.POINTER(_DitherStruct) self._dither = _lib.caca_create_dither(bpp, width, height, pitch, rmask, gmask, bmask, amask) if self._dither == 0: raise DitherError("Failed to create dither object") def set_palette(self, red, green, blue, alpha): """ Set the palette of an 8 bits per pixel bitmap. Values should be between 0 and 4095 (0xfff). red -- array of 256 red values green -- array of 256 green values blue -- array of 256 blue values alpha -- array of 256 alpha values """ raise DitherError("Not implemented") def set_brightness(self, brightness): """ Set the brightness of the dither object. brightness -- brightness value """ if isinstance(brightness, int): brightness = float(brightness) _lib.caca_set_dither_brightness.argtypes = [_Dither, ctypes.c_float] _lib.caca_set_dither_brightness.restype = ctypes.c_int return _lib.caca_set_dither_brightness(self, brightness) def get_brightness(self): """ Get the brightness of the dither object. """ _lib.caca_get_dither_brightness.argtypes = [_Dither] _lib.caca_get_dither_brightness.restype = ctypes.c_float return _lib.caca_get_dither_brightness(self) def set_gamma(self, gamma): """ Set the gamma of the dither object. A negative value causes colour inversion. gamma -- gamma value """ if isinstance(gamma, int): gamma = float(gamma) _lib.caca_set_dither_gamma.argtypes = [_Dither, ctypes.c_float] _lib.caca_set_dither_gamma.restype = ctypes.c_int return _lib.caca_set_dither_gamma(self, gamma) def get_gamma(self): """ Get the gamma of the dither object. """ _lib.caca_get_dither_gamma.argtypes = [_Dither] _lib.caca_get_dither_gamma.restype = ctypes.c_float return _lib.caca_get_dither_gamma(self) def set_contrast(self, contrast): """ Set the contrast of dither. contrast -- contrast value """ if isinstance(contrast, int): contrast = float(contrast) _lib.caca_set_dither_contrast.argtypes = [_Dither, ctypes.c_float] _lib.caca_set_dither_contrast.restype = ctypes.c_int return _lib.caca_set_dither_contrast(self, contrast) def get_contrast(self): """ Get the contrast of the dither object. """ _lib.caca_get_dither_contrast.argtypes = [_Dither] _lib.caca_get_dither_contrast.restype = ctypes.c_float return _lib.caca_get_dither_contrast(self) def set_antialias(self, value): """ Set dither antialiasing. value -- A string describing the antialiasing method that will be used for the dithering. + "none": no antialiasing + "prefilter" or "default": simple prefilter antialiasing. (default) """ _lib.caca_set_dither_antialias.argtypes = [_Dither, ctypes.c_char_p] _lib.caca_set_dither_antialias.restype = ctypes.c_int return _lib.caca_set_dither_antialias(self, value) def get_antialias(self): """ Return the dither's current antialiasing method. """ _lib.caca_get_dither_antialias.argtypes = [_Dither] _lib.caca_get_dither_antialias.restype = ctypes.c_char_p return _lib.caca_get_dither_antialias(self) def get_antialias_list(self): """ Get available antialiasing methods. """ lst = [] _lib.caca_get_dither_antialias_list.argtypes = [_Dither] _lib.caca_get_dither_antialias_list.restype = ctypes.POINTER(ctypes.c_char_p) for item in _lib.caca_get_dither_antialias_list(self): if item is not None and item != "": lst.append(item) else: #memory occurs otherwise break return lst def set_color(self, value): """ Choose colours used for dithering. value -- A string describing the colour set that will be used for the dithering. + "mono": use light gray on a black background + "gray": use white and two shades of gray on a black background + "8": use the 8 ANSI colours on a black background + "16": use the 16 ANSI colours on a black background + "fullgray": use black, white and two shades of gray for both the characters and the background + "full8": use the 8 ANSI colours for both the characters and the background + "full16" or "default": use the 16 ANSI colours for both the characters and the background (default) """ _lib.caca_set_dither_color.argtypes = [_Dither, ctypes.c_char_p] _lib.caca_set_dither_color.restype = ctypes.c_int return _lib.caca_set_dither_color(self, value) def get_color(self): """ Get current colour mode. """ _lib.caca_get_dither_color.argtypes = [_Dither] _lib.caca_get_dither_color.restype = ctypes.c_char_p return _lib.caca_get_dither_color(self) def get_color_list(self): """ Get available colour modes. """ lst = [] _lib.caca_get_dither_color_list.argtypes = [_Dither] _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p) for item in _lib.caca_get_dither_color_list(self): if item is not None and item != "": lst.append(item) else: #memory occurs otherwise break return lst def set_charset(self, value): """ Choose characters used for dithering. value -- A string describing the characters that need to be used for the dithering. + "ascii" or "default": use only ASCII characters (default). + "shades": use Unicode characters "U+2591 LIGHT SHADE", "U+2592 MEDIUM SHADE" and "U+2593 DARK SHADE". These characters are also present in the CP437 codepage available on DOS and VGA. + "blocks": use Unicode quarter-cell block combinations. These characters are only found in the Unicode set. """ _lib.caca_set_dither_charset.argtypes = [_Dither, ctypes.c_char_p] _lib.caca_set_dither_charset.restype = ctypes.c_int return _lib.caca_set_dither_charset(self, value) def get_charset(self): """ Get current character set. """ _lib.caca_get_dither_charset.argtypes = [_Dither] _lib.caca_get_dither_charset.restype = ctypes.c_char_p return _lib.caca_get_dither_charset(self) def get_charset_list(self): """ Get available dither character sets. """ lst = [] _lib.caca_get_dither_color_list.argtypes = [_Dither] _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p) for item in _lib.caca_get_dither_color_list(self): if item is not None and item != "": lst.append(item) else: #memory occurs otherwise break return lst def set_algorithm(self, value): """ Set dithering algorithm. value -- A string describing the algorithm that needs to be used for the dithering. + "none": no dithering is used, the nearest matching colour is used. + "ordered2": use a 2x2 Bayer matrix for dithering. + "ordered4": use a 4x4 Bayer matrix for dithering. + "ordered8": use a 8x8 Bayer matrix for dithering. + "random": use random dithering. + "fstein": use Floyd-Steinberg dithering (default). """ _lib.caca_set_dither_algorithm.argtypes = [_Dither, ctypes.c_char_p] _lib.caca_set_dither_algorithm.restype = ctypes.c_int return _lib.caca_set_dither_algorithm(self, value) def get_algorithm(self): """ Get dithering algorithms. """ _lib.caca_get_dither_algorithm.argtypes = [_Dither] _lib.caca_get_dither_algorithm.restype = ctypes.c_char_p return _lib.caca_get_dither_algorithm(self) def get_algorithm_list(self): """ Get dithering algorithms. """ lst = [] _lib.caca_get_dither_color_list.argtypes = [_Dither] _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p) for item in _lib.caca_get_dither_color_list(self): if item is not None and item != "": lst.append(item) else: #memory occurs otherwise break return lst def bitmap(self, canvas, x, y, width, height, pixels): """ Dither a bitmap on the canvas. canvas -- a handle to libcaca canvas x -- X coordinate of the upper-left corner of the drawing area y -- Y coordinate of the upper-left corner of the drawing area width -- width of the drawing area height -- height of the drawing area pixels -- bitmap's pixels """ _lib.caca_dither_bitmap.argtypes = [ _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, _Dither, ctypes.c_char_p ] _lib.caca_dither_bitmap.restype = ctypes.c_int return _lib.caca_dither_bitmap(canvas, x, y, width, height, self, pixels) class DitherError(Exception): pass