[4398] | 1 | # -*- coding: utf-8 -*- |
---|
| 2 | # |
---|
| 3 | # libcaca Colour ASCII-Art library |
---|
| 4 | # Python language bindings |
---|
| 5 | # Copyright (c) 2010 Alex Foulon <alxf@lavabit.com> |
---|
| 6 | # All Rights Reserved |
---|
| 7 | # |
---|
| 8 | # This library is free software. It comes without any warranty, to |
---|
| 9 | # the extent permitted by applicable law. You can redistribute it |
---|
| 10 | # and/or modify it under the terms of the Do What The Fuck You Want |
---|
| 11 | # To Public License, Version 2, as published by Sam Hocevar. See |
---|
| 12 | # http://sam.zoy.org/wtfpl/COPYING for more details. |
---|
| 13 | # |
---|
| 14 | |
---|
| 15 | """ Libcaca Python bindings """ |
---|
| 16 | |
---|
| 17 | import ctypes |
---|
| 18 | |
---|
| 19 | from caca import _lib |
---|
[4705] | 20 | from caca.canvas import _Canvas |
---|
[4398] | 21 | |
---|
| 22 | class _Dither(object): |
---|
| 23 | """ Model for Dither object. |
---|
| 24 | """ |
---|
| 25 | def __init__(self): |
---|
| 26 | self._dither = 0 |
---|
| 27 | |
---|
| 28 | def from_param(self): |
---|
| 29 | """ Required by ctypes module to call object as parameter of |
---|
| 30 | a C function. |
---|
| 31 | """ |
---|
| 32 | return self._dither |
---|
| 33 | |
---|
| 34 | def __del__(self): |
---|
| 35 | if self._dither > 0: |
---|
| 36 | self._free() |
---|
| 37 | |
---|
| 38 | def __str__(self): |
---|
| 39 | return "<CacaDither>" |
---|
| 40 | |
---|
| 41 | def _free(self): |
---|
| 42 | """ Free a libcaca dither. |
---|
| 43 | """ |
---|
[4705] | 44 | _lib.caca_free_dither.argtypes = [_Dither] |
---|
| 45 | _lib.caca_free_dither.restype = ctypes.c_int |
---|
[4398] | 46 | |
---|
[4705] | 47 | return _lib.caca_free_dither(self) |
---|
[4398] | 48 | |
---|
| 49 | class Dither(_Dither): |
---|
| 50 | """ Dither object, methods are libcaca functions with caca_dither_t as first |
---|
| 51 | argument. |
---|
| 52 | """ |
---|
| 53 | def __init__(self, bpp, width, height, pitch, rmask, gmask, bmask, amask): |
---|
| 54 | """ Dither constructor |
---|
| 55 | |
---|
| 56 | bpp -- bitmap depth in bits per pixels |
---|
| 57 | width -- bitmap width in pixels |
---|
| 58 | height -- bitmap height in pixels |
---|
| 59 | pitch -- bitmap pitch in bytes |
---|
| 60 | rmask -- bitmask for red values |
---|
| 61 | gmask -- bitmask for green values |
---|
| 62 | bmask -- bitmask for blue values |
---|
| 63 | amask -- bitmask for alpha values |
---|
| 64 | """ |
---|
[4705] | 65 | _lib.caca_create_dither.argtypes = [ |
---|
| 66 | ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, |
---|
| 67 | ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, |
---|
| 68 | ] |
---|
[4398] | 69 | |
---|
[4705] | 70 | self._dither = _lib.caca_create_dither(bpp, width, height, pitch, |
---|
[4707] | 71 | rmask, gmask, bmask, amask) |
---|
[4705] | 72 | |
---|
| 73 | if self._dither == 0: |
---|
| 74 | raise DitherError, "Failed to create dither object" |
---|
| 75 | |
---|
| 76 | def set_palette(self, red, green, blue, alpha): |
---|
| 77 | """ Set the palette of an 8 bits per pixel bitmap. Values should be |
---|
| 78 | between 0 and 4095 (0xfff). |
---|
| 79 | |
---|
| 80 | red -- array of 256 red values |
---|
| 81 | green -- array of 256 green values |
---|
| 82 | blue -- array of 256 blue values |
---|
| 83 | alpha -- array of 256 alpha values |
---|
| 84 | """ |
---|
| 85 | raise DitherError, "Not implemented" |
---|
| 86 | |
---|
| 87 | def set_brightness(self, brightness): |
---|
| 88 | """ Set the brightness of the dither object. |
---|
| 89 | |
---|
| 90 | brightness -- brightness value |
---|
| 91 | """ |
---|
| 92 | if isinstance(brightness, int): |
---|
| 93 | brightness = float(brightness) |
---|
| 94 | |
---|
| 95 | _lib.caca_set_dither_brightness.argtypes = [_Dither, ctypes.c_float] |
---|
| 96 | _lib.caca_set_dither_brightness.restype = ctypes.c_int |
---|
| 97 | |
---|
| 98 | return _lib.caca_set_dither_brightness(self, brightness) |
---|
| 99 | |
---|
| 100 | def get_brightness(self): |
---|
| 101 | """ Get the brightness of the dither object. |
---|
| 102 | """ |
---|
| 103 | _lib.caca_get_dither_brightness.argtypes = [_Dither] |
---|
| 104 | _lib.caca_get_dither_brightness.restype = ctypes.c_float |
---|
| 105 | |
---|
| 106 | return _lib.caca_get_dither_brightness(self) |
---|
| 107 | |
---|
| 108 | def set_gamma(self, gamma): |
---|
| 109 | """ Set the gamma of the dither object. A negative value causes colour |
---|
| 110 | inversion. |
---|
| 111 | |
---|
| 112 | gamma -- gamma value |
---|
| 113 | """ |
---|
| 114 | if isinstance(gamma, int): |
---|
| 115 | gamma = float(gamma) |
---|
| 116 | |
---|
| 117 | _lib.caca_set_dither_gamma.argtypes = [_Dither, ctypes.c_float] |
---|
| 118 | _lib.caca_set_dither_gamma.restype = ctypes.c_int |
---|
| 119 | |
---|
| 120 | return _lib.caca_set_dither_gamma(self, gamma) |
---|
| 121 | |
---|
| 122 | def get_gamma(self): |
---|
| 123 | """ Get the gamma of the dither object. |
---|
| 124 | """ |
---|
| 125 | _lib.caca_get_dither_gamma.argtypes = [_Dither] |
---|
| 126 | _lib.caca_get_dither_gamma.restype = ctypes.c_float |
---|
| 127 | |
---|
| 128 | return _lib.caca_get_dither_gamma(self) |
---|
| 129 | |
---|
| 130 | def set_contrast(self, contrast): |
---|
| 131 | """ Set the contrast of dither. |
---|
| 132 | |
---|
| 133 | contrast -- contrast value |
---|
| 134 | """ |
---|
| 135 | if isinstance(contrast, int): |
---|
| 136 | contrast = float(contrast) |
---|
| 137 | |
---|
| 138 | _lib.caca_set_dither_contrast.argtypes = [_Dither, ctypes.c_float] |
---|
| 139 | _lib.caca_set_dither_contrast.restype = ctypes.c_int |
---|
| 140 | |
---|
| 141 | return _lib.caca_set_dither_contrast(self, contrast) |
---|
| 142 | |
---|
| 143 | def get_contrast(self): |
---|
| 144 | """ Get the contrast of the dither object. |
---|
| 145 | """ |
---|
| 146 | _lib.caca_get_dither_contrast.argtypes = [_Dither] |
---|
| 147 | _lib.caca_get_dither_contrast.restype = ctypes.c_float |
---|
| 148 | |
---|
| 149 | return _lib.caca_get_dither_contrast(self) |
---|
| 150 | |
---|
| 151 | def set_antialias(self, value): |
---|
| 152 | """ Set dither antialiasing. |
---|
| 153 | |
---|
| 154 | value -- A string describing the antialiasing method that will |
---|
| 155 | be used for the dithering. |
---|
| 156 | |
---|
| 157 | + "none": no antialiasing |
---|
| 158 | + "prefilter" or "default": simple prefilter antialiasing. (default) |
---|
| 159 | """ |
---|
| 160 | _lib.caca_set_dither_antialias.argtypes = [_Dither, ctypes.c_char_p] |
---|
| 161 | _lib.caca_set_dither_antialias.restype = ctypes.c_int |
---|
| 162 | |
---|
| 163 | return _lib.caca_set_dither_antialias(self, value) |
---|
| 164 | |
---|
| 165 | def get_antialias(self): |
---|
| 166 | """ Return the dither's current antialiasing method. |
---|
| 167 | """ |
---|
| 168 | _lib.caca_get_dither_antialias.argtypes = [_Dither] |
---|
| 169 | _lib.caca_get_dither_antialias.restype = ctypes.c_char_p |
---|
| 170 | |
---|
| 171 | return _lib.caca_get_dither_antialias(self) |
---|
| 172 | |
---|
| 173 | def get_antialias_list(self): |
---|
| 174 | """ Get available antialiasing methods. |
---|
| 175 | """ |
---|
| 176 | lst = [] |
---|
| 177 | |
---|
| 178 | _lib.caca_get_dither_antialias_list.argtypes = [_Dither] |
---|
| 179 | _lib.caca_get_dither_antialias_list.restype = ctypes.POINTER(ctypes.c_char_p) |
---|
| 180 | |
---|
| 181 | for item in _lib.caca_get_dither_antialias_list(self): |
---|
| 182 | if item is not None and item != "": |
---|
| 183 | lst.append(item) |
---|
| 184 | else: |
---|
| 185 | #memory occurs otherwise |
---|
| 186 | break |
---|
| 187 | |
---|
| 188 | return lst |
---|
| 189 | |
---|
| 190 | def set_color(self, value): |
---|
| 191 | """ Choose colours used for dithering. |
---|
| 192 | |
---|
| 193 | value -- A string describing the colour set that will be |
---|
| 194 | used for the dithering. |
---|
| 195 | |
---|
| 196 | + "mono": use light gray on a black background |
---|
| 197 | + "gray": use white and two shades of gray on a black background |
---|
| 198 | + "8": use the 8 ANSI colours on a black background |
---|
| 199 | + "16": use the 16 ANSI colours on a black background |
---|
| 200 | + "fullgray": use black, white and two shades of gray |
---|
| 201 | for both the characters and the background |
---|
| 202 | + "full8": use the 8 ANSI colours for both the characters and |
---|
| 203 | the background |
---|
| 204 | + "full16" or "default": use the 16 ANSI colours for both the |
---|
| 205 | characters and the background (default) |
---|
| 206 | """ |
---|
| 207 | _lib.caca_set_dither_color.argtypes = [_Dither, ctypes.c_char_p] |
---|
| 208 | _lib.caca_set_dither_color.restype = ctypes.c_int |
---|
| 209 | |
---|
| 210 | return _lib.caca_set_dither_color(self, value) |
---|
| 211 | |
---|
| 212 | def get_color(self): |
---|
| 213 | """ Get current colour mode. |
---|
| 214 | """ |
---|
| 215 | _lib.caca_get_dither_color.argtypes = [_Dither] |
---|
| 216 | _lib.caca_get_dither_color.restype = ctypes.c_char_p |
---|
| 217 | |
---|
| 218 | return _lib.caca_get_dither_color(self) |
---|
| 219 | |
---|
| 220 | def get_color_list(self): |
---|
| 221 | """ Get available colour modes. |
---|
| 222 | """ |
---|
| 223 | lst = [] |
---|
| 224 | |
---|
| 225 | _lib.caca_get_dither_color_list.argtypes = [_Dither] |
---|
| 226 | _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p) |
---|
| 227 | |
---|
| 228 | for item in _lib.caca_get_dither_color_list(self): |
---|
| 229 | if item is not None and item != "": |
---|
| 230 | lst.append(item) |
---|
| 231 | else: |
---|
| 232 | #memory occurs otherwise |
---|
| 233 | break |
---|
| 234 | |
---|
| 235 | return lst |
---|
| 236 | |
---|
| 237 | def set_charset(self, value): |
---|
| 238 | """ Choose characters used for dithering. |
---|
| 239 | |
---|
| 240 | value -- A string describing the characters that need to be |
---|
| 241 | used for the dithering. |
---|
| 242 | |
---|
| 243 | + "ascii" or "default": use only ASCII characters (default). |
---|
| 244 | + "shades": use Unicode characters "U+2591 LIGHT SHADE", |
---|
| 245 | "U+2592 MEDIUM SHADE" and "U+2593 DARK SHADE". These characters are |
---|
| 246 | also present in the CP437 codepage available on DOS and VGA. |
---|
| 247 | + "blocks": use Unicode quarter-cell block combinations. |
---|
| 248 | These characters are only found in the Unicode set. |
---|
| 249 | """ |
---|
| 250 | _lib.caca_set_dither_charset.argtypes = [_Dither, ctypes.c_char_p] |
---|
| 251 | _lib.caca_set_dither_charset.restype = ctypes.c_int |
---|
| 252 | |
---|
| 253 | return _lib.caca_set_dither_charset(self, value) |
---|
| 254 | |
---|
| 255 | def get_charset(self): |
---|
| 256 | """ Get current character set. |
---|
| 257 | """ |
---|
| 258 | _lib.caca_get_dither_charset.argtypes = [_Dither] |
---|
| 259 | _lib.caca_get_dither_charset.restype = ctypes.c_char_p |
---|
| 260 | |
---|
| 261 | return _lib.caca_get_dither_charset(self) |
---|
| 262 | |
---|
| 263 | def get_charset_list(self): |
---|
| 264 | """ Get available dither character sets. |
---|
| 265 | """ |
---|
| 266 | lst = [] |
---|
| 267 | |
---|
| 268 | _lib.caca_get_dither_color_list.argtypes = [_Dither] |
---|
| 269 | _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p) |
---|
| 270 | |
---|
| 271 | for item in _lib.caca_get_dither_color_list(self): |
---|
| 272 | if item is not None and item != "": |
---|
| 273 | lst.append(item) |
---|
| 274 | else: |
---|
| 275 | #memory occurs otherwise |
---|
| 276 | break |
---|
| 277 | |
---|
| 278 | return lst |
---|
| 279 | |
---|
| 280 | def set_algorithm(self, value): |
---|
| 281 | """ Set dithering algorithm. |
---|
| 282 | |
---|
| 283 | value -- A string describing the algorithm that needs to be |
---|
| 284 | used for the dithering. |
---|
| 285 | |
---|
| 286 | + "none": no dithering is used, the nearest matching colour is used. |
---|
| 287 | + "ordered2": use a 2x2 Bayer matrix for dithering. |
---|
| 288 | + "ordered4": use a 4x4 Bayer matrix for dithering. |
---|
| 289 | + "ordered8": use a 8x8 Bayer matrix for dithering. |
---|
| 290 | + "random": use random dithering. |
---|
| 291 | + "fstein": use Floyd-Steinberg dithering (default). |
---|
| 292 | """ |
---|
| 293 | _lib.caca_set_dither_algorithm.argtypes = [_Dither, ctypes.c_char_p] |
---|
| 294 | _lib.caca_set_dither_algorithm.restype = ctypes.c_int |
---|
| 295 | |
---|
| 296 | return _lib.caca_set_dither_algorithm(self, value) |
---|
| 297 | |
---|
| 298 | def get_algorithm(self): |
---|
| 299 | """ Get dithering algorithms. |
---|
| 300 | """ |
---|
| 301 | _lib.caca_get_dither_algorithm.argtypes = [_Dither] |
---|
| 302 | _lib.caca_get_dither_algorithm.restype = ctypes.c_char_p |
---|
| 303 | |
---|
| 304 | return _lib.caca_get_dither_algorithm(self) |
---|
| 305 | |
---|
| 306 | def get_algorithm_list(self): |
---|
| 307 | """ Get dithering algorithms. |
---|
| 308 | """ |
---|
| 309 | lst = [] |
---|
| 310 | |
---|
| 311 | _lib.caca_get_dither_color_list.argtypes = [_Dither] |
---|
| 312 | _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p) |
---|
| 313 | |
---|
| 314 | for item in _lib.caca_get_dither_color_list(self): |
---|
| 315 | if item is not None and item != "": |
---|
| 316 | lst.append(item) |
---|
| 317 | else: |
---|
| 318 | #memory occurs otherwise |
---|
| 319 | break |
---|
| 320 | |
---|
| 321 | return lst |
---|
| 322 | |
---|
| 323 | def bitmap(self, canvas, x, y, width, height, pixels): |
---|
| 324 | """ Dither a bitmap on the canvas. |
---|
| 325 | |
---|
| 326 | canvas -- a handle to libcaca canvas |
---|
| 327 | x -- X coordinate of the upper-left corner of the drawing area |
---|
| 328 | y -- Y coordinate of the upper-left corner of the drawing area |
---|
| 329 | width -- width of the drawing area |
---|
| 330 | height -- height of the drawing area |
---|
| 331 | pixels -- bitmap's pixels |
---|
| 332 | """ |
---|
| 333 | _lib.caca_dither_bitmap.argtypes = [ |
---|
| 334 | _Canvas, ctypes.c_int, ctypes.c_int, |
---|
| 335 | ctypes.c_int, ctypes.c_int, _Dither, |
---|
| 336 | ctypes.c_char_p |
---|
| 337 | ] |
---|
| 338 | _lib.caca_dither_bitmap.restype = ctypes.c_int |
---|
| 339 | |
---|
| 340 | return _lib.caca_dither_bitmap(canvas, x, y, width, height, self, pixels) |
---|
| 341 | |
---|
| 342 | class DitherError(Exception): |
---|
| 343 | pass |
---|
| 344 | |
---|