You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

350 lines
12 KiB

  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://www.wtfpl.net/ for more details.
  13. #
  14. """ Libcaca Python bindings """
  15. import ctypes
  16. from caca import _lib
  17. from caca.canvas import _Canvas
  18. class _DitherStruct(ctypes.Structure):
  19. pass
  20. class _Dither(object):
  21. """ Model for Dither object.
  22. """
  23. def __init__(self):
  24. self._dither = None
  25. def from_param(self):
  26. """ Required by ctypes module to call object as parameter of
  27. a C function.
  28. """
  29. return self._dither
  30. def __del__(self):
  31. if self._dither:
  32. self._free()
  33. def __str__(self):
  34. return "<CacaDither>"
  35. def _free(self):
  36. """ Free a libcaca dither.
  37. """
  38. _lib.caca_free_dither.argtypes = [_Dither]
  39. _lib.caca_free_dither.restype = ctypes.c_int
  40. return _lib.caca_free_dither(self)
  41. class Dither(_Dither):
  42. """ Dither object, methods are libcaca functions with caca_dither_t as first
  43. argument.
  44. """
  45. def __init__(self, bpp, width, height, pitch, rmask, gmask, bmask, amask):
  46. """ Dither constructor
  47. bpp -- bitmap depth in bits per pixels
  48. width -- bitmap width in pixels
  49. height -- bitmap height in pixels
  50. pitch -- bitmap pitch in bytes
  51. rmask -- bitmask for red values
  52. gmask -- bitmask for green values
  53. bmask -- bitmask for blue values
  54. amask -- bitmask for alpha values
  55. """
  56. _lib.caca_create_dither.argtypes = [
  57. ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
  58. ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint,
  59. ]
  60. _lib.caca_create_dither.restype = ctypes.POINTER(_DitherStruct)
  61. self._dither = _lib.caca_create_dither(bpp, width, height, pitch,
  62. rmask, gmask, bmask, amask)
  63. if self._dither == 0:
  64. raise DitherError("Failed to create dither object")
  65. def set_palette(self, red, green, blue, alpha):
  66. """ Set the palette of an 8 bits per pixel bitmap. Values should be
  67. between 0 and 4095 (0xfff).
  68. red -- array of 256 red values
  69. green -- array of 256 green values
  70. blue -- array of 256 blue values
  71. alpha -- array of 256 alpha values
  72. """
  73. raise DitherError("Not implemented")
  74. def set_brightness(self, brightness):
  75. """ Set the brightness of the dither object.
  76. brightness -- brightness value
  77. """
  78. if isinstance(brightness, int):
  79. brightness = float(brightness)
  80. _lib.caca_set_dither_brightness.argtypes = [_Dither, ctypes.c_float]
  81. _lib.caca_set_dither_brightness.restype = ctypes.c_int
  82. return _lib.caca_set_dither_brightness(self, brightness)
  83. def get_brightness(self):
  84. """ Get the brightness of the dither object.
  85. """
  86. _lib.caca_get_dither_brightness.argtypes = [_Dither]
  87. _lib.caca_get_dither_brightness.restype = ctypes.c_float
  88. return _lib.caca_get_dither_brightness(self)
  89. def set_gamma(self, gamma):
  90. """ Set the gamma of the dither object. A negative value causes colour
  91. inversion.
  92. gamma -- gamma value
  93. """
  94. if isinstance(gamma, int):
  95. gamma = float(gamma)
  96. _lib.caca_set_dither_gamma.argtypes = [_Dither, ctypes.c_float]
  97. _lib.caca_set_dither_gamma.restype = ctypes.c_int
  98. return _lib.caca_set_dither_gamma(self, gamma)
  99. def get_gamma(self):
  100. """ Get the gamma of the dither object.
  101. """
  102. _lib.caca_get_dither_gamma.argtypes = [_Dither]
  103. _lib.caca_get_dither_gamma.restype = ctypes.c_float
  104. return _lib.caca_get_dither_gamma(self)
  105. def set_contrast(self, contrast):
  106. """ Set the contrast of dither.
  107. contrast -- contrast value
  108. """
  109. if isinstance(contrast, int):
  110. contrast = float(contrast)
  111. _lib.caca_set_dither_contrast.argtypes = [_Dither, ctypes.c_float]
  112. _lib.caca_set_dither_contrast.restype = ctypes.c_int
  113. return _lib.caca_set_dither_contrast(self, contrast)
  114. def get_contrast(self):
  115. """ Get the contrast of the dither object.
  116. """
  117. _lib.caca_get_dither_contrast.argtypes = [_Dither]
  118. _lib.caca_get_dither_contrast.restype = ctypes.c_float
  119. return _lib.caca_get_dither_contrast(self)
  120. def set_antialias(self, value):
  121. """ Set dither antialiasing.
  122. value -- A string describing the antialiasing method that will
  123. be used for the dithering.
  124. + "none": no antialiasing
  125. + "prefilter" or "default": simple prefilter antialiasing. (default)
  126. """
  127. _lib.caca_set_dither_antialias.argtypes = [_Dither, ctypes.c_char_p]
  128. _lib.caca_set_dither_antialias.restype = ctypes.c_int
  129. return _lib.caca_set_dither_antialias(self, value)
  130. def get_antialias(self):
  131. """ Return the dither's current antialiasing method.
  132. """
  133. _lib.caca_get_dither_antialias.argtypes = [_Dither]
  134. _lib.caca_get_dither_antialias.restype = ctypes.c_char_p
  135. return _lib.caca_get_dither_antialias(self)
  136. def get_antialias_list(self):
  137. """ Get available antialiasing methods.
  138. """
  139. lst = []
  140. _lib.caca_get_dither_antialias_list.argtypes = [_Dither]
  141. _lib.caca_get_dither_antialias_list.restype = ctypes.POINTER(ctypes.c_char_p)
  142. for item in _lib.caca_get_dither_antialias_list(self):
  143. if item is not None and item != "":
  144. lst.append(item)
  145. else:
  146. #memory occurs otherwise
  147. break
  148. return lst
  149. def set_color(self, value):
  150. """ Choose colours used for dithering.
  151. value -- A string describing the colour set that will be
  152. used for the dithering.
  153. + "mono": use light gray on a black background
  154. + "gray": use white and two shades of gray on a black background
  155. + "8": use the 8 ANSI colours on a black background
  156. + "16": use the 16 ANSI colours on a black background
  157. + "fullgray": use black, white and two shades of gray
  158. for both the characters and the background
  159. + "full8": use the 8 ANSI colours for both the characters and
  160. the background
  161. + "full16" or "default": use the 16 ANSI colours for both the
  162. characters and the background (default)
  163. """
  164. _lib.caca_set_dither_color.argtypes = [_Dither, ctypes.c_char_p]
  165. _lib.caca_set_dither_color.restype = ctypes.c_int
  166. return _lib.caca_set_dither_color(self, value)
  167. def get_color(self):
  168. """ Get current colour mode.
  169. """
  170. _lib.caca_get_dither_color.argtypes = [_Dither]
  171. _lib.caca_get_dither_color.restype = ctypes.c_char_p
  172. return _lib.caca_get_dither_color(self)
  173. def get_color_list(self):
  174. """ Get available colour modes.
  175. """
  176. lst = []
  177. _lib.caca_get_dither_color_list.argtypes = [_Dither]
  178. _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p)
  179. for item in _lib.caca_get_dither_color_list(self):
  180. if item is not None and item != "":
  181. lst.append(item)
  182. else:
  183. #memory occurs otherwise
  184. break
  185. return lst
  186. def set_charset(self, value):
  187. """ Choose characters used for dithering.
  188. value -- A string describing the characters that need to be
  189. used for the dithering.
  190. + "ascii" or "default": use only ASCII characters (default).
  191. + "shades": use Unicode characters "U+2591 LIGHT SHADE",
  192. "U+2592 MEDIUM SHADE" and "U+2593 DARK SHADE". These characters are
  193. also present in the CP437 codepage available on DOS and VGA.
  194. + "blocks": use Unicode quarter-cell block combinations.
  195. These characters are only found in the Unicode set.
  196. """
  197. _lib.caca_set_dither_charset.argtypes = [_Dither, ctypes.c_char_p]
  198. _lib.caca_set_dither_charset.restype = ctypes.c_int
  199. return _lib.caca_set_dither_charset(self, value)
  200. def get_charset(self):
  201. """ Get current character set.
  202. """
  203. _lib.caca_get_dither_charset.argtypes = [_Dither]
  204. _lib.caca_get_dither_charset.restype = ctypes.c_char_p
  205. return _lib.caca_get_dither_charset(self)
  206. def get_charset_list(self):
  207. """ Get available dither character sets.
  208. """
  209. lst = []
  210. _lib.caca_get_dither_color_list.argtypes = [_Dither]
  211. _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p)
  212. for item in _lib.caca_get_dither_color_list(self):
  213. if item is not None and item != "":
  214. lst.append(item)
  215. else:
  216. #memory occurs otherwise
  217. break
  218. return lst
  219. def set_algorithm(self, value):
  220. """ Set dithering algorithm.
  221. value -- A string describing the algorithm that needs to be
  222. used for the dithering.
  223. + "none": no dithering is used, the nearest matching colour is used.
  224. + "ordered2": use a 2x2 Bayer matrix for dithering.
  225. + "ordered4": use a 4x4 Bayer matrix for dithering.
  226. + "ordered8": use a 8x8 Bayer matrix for dithering.
  227. + "random": use random dithering.
  228. + "fstein": use Floyd-Steinberg dithering (default).
  229. """
  230. _lib.caca_set_dither_algorithm.argtypes = [_Dither, ctypes.c_char_p]
  231. _lib.caca_set_dither_algorithm.restype = ctypes.c_int
  232. return _lib.caca_set_dither_algorithm(self, value)
  233. def get_algorithm(self):
  234. """ Get dithering algorithms.
  235. """
  236. _lib.caca_get_dither_algorithm.argtypes = [_Dither]
  237. _lib.caca_get_dither_algorithm.restype = ctypes.c_char_p
  238. return _lib.caca_get_dither_algorithm(self)
  239. def get_algorithm_list(self):
  240. """ Get dithering algorithms.
  241. """
  242. lst = []
  243. _lib.caca_get_dither_color_list.argtypes = [_Dither]
  244. _lib.caca_get_dither_color_list.restype = ctypes.POINTER(ctypes.c_char_p)
  245. for item in _lib.caca_get_dither_color_list(self):
  246. if item is not None and item != "":
  247. lst.append(item)
  248. else:
  249. #memory occurs otherwise
  250. break
  251. return lst
  252. def bitmap(self, canvas, x, y, width, height, pixels):
  253. """ Dither a bitmap on the canvas.
  254. canvas -- a handle to libcaca canvas
  255. x -- X coordinate of the upper-left corner of the drawing area
  256. y -- Y coordinate of the upper-left corner of the drawing area
  257. width -- width of the drawing area
  258. height -- height of the drawing area
  259. pixels -- bitmap's pixels
  260. """
  261. _lib.caca_dither_bitmap.argtypes = [
  262. _Canvas, ctypes.c_int, ctypes.c_int,
  263. ctypes.c_int, ctypes.c_int, _Dither,
  264. ctypes.c_char_p
  265. ]
  266. _lib.caca_dither_bitmap.restype = ctypes.c_int
  267. return _lib.caca_dither_bitmap(canvas, x, y, width, height, self, pixels)
  268. class DitherError(Exception):
  269. pass