summaryrefslogtreecommitdiff
path: root/efl/ethumb
diff options
context:
space:
mode:
authorDave Andreoli <dave@gurumeditation.it>2016-01-03 16:48:13 +0100
committerDave Andreoli <dave@gurumeditation.it>2016-01-03 16:48:45 +0100
commit93d2c010025795923feff53317775910876bfd1d (patch)
tree4821d57fa9f31761a07a7bc8cbeb63cb0dc5dad9 /efl/ethumb
parente963e6d061103d9aaff9ef0187184417638cfbf6 (diff)
Implemented efl.Ethumb.Ethumb class.
With docs and an example EthumbClient will follow asap
Diffstat (limited to 'efl/ethumb')
-rw-r--r--efl/ethumb/__init__.py30
-rw-r--r--efl/ethumb/efl.ethumb.pyx603
2 files changed, 600 insertions, 33 deletions
diff --git a/efl/ethumb/__init__.py b/efl/ethumb/__init__.py
deleted file mode 100644
index d8d3e48..0000000
--- a/efl/ethumb/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
1# Copyright (C) 2009 by ProFUSION embedded systems
2#
3# This file is part of Python-Ethumb.
4#
5# Python-Ethumb is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2.1 of the License, or (at your option) any later version.
9#
10# Python-Ethumb is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this Python-Ethumb. If not, see <http://www.gnu.org/licenses/>.
17
18from c_ethumb import init, shutdown, PyEthumb
19
20ETHUMB_THUMB_NORMAL = 0
21ETHUMB_THUMB_LARGE = 1
22
23ETHUMB_THUMB_FDO = 0
24ETHUMB_THUMB_JPEG = 1
25ETHUMB_THUMB_EET = 2
26
27ETHUMB_THUMB_KEEP_ASPECT = 0
28ETHUMB_THUMB_IGNORE_ASPECT = 1
29ETHUMB_THUMB_CROP = 2
30
diff --git a/efl/ethumb/efl.ethumb.pyx b/efl/ethumb/efl.ethumb.pyx
index 573f811..d9f3d5b 100644
--- a/efl/ethumb/efl.ethumb.pyx
+++ b/efl/ethumb/efl.ethumb.pyx
@@ -15,19 +15,616 @@
15# You should have received a copy of the GNU Lesser General Public License 15# You should have received a copy of the GNU Lesser General Public License
16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>. 16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
17 17
18"""
19
20:mod:`efl.ethumb` Module
21########################
22
23
24Classes
25=======
26
27.. toctree::
28
29 class-ethumb.rst
30
31
32Enumerations
33============
34
35.. _Ethumb_Thumb_FDO_Size:
36
37Ethumb_Thumb_FDO_Size
38---------------------
39
40.. data:: ETHUMB_THUMB_NORMAL
41
42 128x128 as defined by FreeDesktop.Org standard
43
44.. data:: ETHUMB_THUMB_LARGE
45
46 256x256 as defined by FreeDesktop.Org standard
47
48
49.. _Ethumb_Thumb_Format:
50
51Ethumb_Thumb_Format
52-------------------
53
54.. data:: ETHUMB_THUMB_FDO
55
56 PNG as defined by FreeDesktop.Org standard.
57
58.. data:: ETHUMB_THUMB_JPEG
59
60 JPEGs are often smaller and faster to read/write.
61
62.. data:: ETHUMB_THUMB_EET
63
64 EFL's own storage system, supports key parameter.
65
66
67.. _Ethumb_Thumb_Aspect:
68
69Ethumb_Thumb_Aspect
70-------------------
71
72.. data:: ETHUMB_THUMB_KEEP_ASPECT
73
74 Keep original proportion between width and height
75
76.. data:: ETHUMB_THUMB_IGNORE_ASPECT
77
78 Ignore aspect and foce it to match thumbnail's width and height
79
80.. data:: ETHUMB_THUMB_CROP
81
82 keep aspect but crop (cut) the largest dimension
83
84
85.. _Ethumb_Thumb_Orientation:
86
87Ethumb_Thumb_Orientation
88------------------------
89
90.. data:: ETHUMB_THUMB_ORIENT_NONE
91
92 Keep orientation as pixel data is
93
94.. data:: ETHUMB_THUMB_ROTATE_90_CW
95
96 Rotate 90° clockwise
97
98.. data:: ETHUMB_THUMB_ROTATE_180
99
100 Rotate 180°
101
102.. data:: ETHUMB_THUMB_ROTATE_90_CCW
103
104 Rotate 90° counter-clockwise
105
106.. data:: ETHUMB_THUMB_FLIP_HORIZONTAL
107
108 Flip horizontally
109
110.. data:: ETHUMB_THUMB_FLIP_VERTICAL
111
112 Flip vertically
113
114.. data:: ETHUMB_THUMB_FLIP_TRANSPOSE
115
116 Transpose
117
118.. data:: ETHUMB_THUMB_FLIP_TRANSVERSE
119
120 Transverse
121
122.. data:: ETHUMB_THUMB_ORIENT_ORIGINAL
123
124 Use orientation from metadata (EXIF-only currently)
125
126
127Module level functions
128======================
129
130"""
131
132from libc.stdint cimport uintptr_t
133from cpython cimport Py_INCREF, Py_DECREF, PyUnicode_AsUTF8String
134
135from efl.eina cimport Eina_Bool
136from efl.utils.conversions cimport _ctouni
137from efl.c_ethumb cimport Ethumb as cEthumb, Ethumb_Thumb_FDO_Size, \
138 Ethumb_Thumb_Format, Ethumb_Thumb_Aspect, Ethumb_Thumb_Orientation, \
139 ethumb_init, ethumb_shutdown, \
140 ethumb_new, ethumb_free, ethumb_file_set, ethumb_file_get, ethumb_file_free, \
141 ethumb_thumb_path_set, ethumb_thumb_path_get, ethumb_exists, ethumb_generate, \
142 ethumb_frame_set, ethumb_frame_get, ethumb_thumb_dir_path_set, \
143 ethumb_thumb_dir_path_get, ethumb_thumb_category_set, \
144 ethumb_thumb_category_get, ethumb_thumb_fdo_set, ethumb_thumb_size_set, \
145 ethumb_thumb_size_get, ethumb_thumb_format_set, ethumb_thumb_format_get, \
146 ethumb_thumb_aspect_set, ethumb_thumb_aspect_get, ethumb_thumb_orientation_set, \
147 ethumb_thumb_orientation_get, ethumb_thumb_crop_align_set, \
148 ethumb_thumb_crop_align_get, ethumb_thumb_quality_set, ethumb_thumb_quality_get, \
149 ethumb_thumb_compress_set, ethumb_thumb_compress_get, \
150 ethumb_video_start_set, ethumb_video_start_get, ethumb_video_time_set, \
151 ethumb_video_time_get, ethumb_video_interval_set, ethumb_video_interval_get, \
152 ethumb_video_ntimes_set, ethumb_video_ntimes_get, ethumb_video_fps_set, \
153 ethumb_video_fps_get, ethumb_document_page_set, ethumb_document_page_get
154
18import atexit 155import atexit
156import traceback
157
158
159cdef void _generate_cb(void *data, cEthumb *e, Eina_Bool success) with gil:
160 obj = <object>data
161 (self, func, args, kargs) = obj
162 try:
163 func(self, bool(success), *args, **kargs)
164 except Exception:
165 traceback.print_exc()
166
167cdef void _generate_free_cb(void *data) with gil:
168 obj = <object>data
169 Py_DECREF(obj)
170
19 171
20def init(): 172def init():
173 """ Initialize the ethumb library.
174
175 .. note:: You never need to call this function, it is automatically called
176 on module import.
177
178 """
21 return ethumb_init() 179 return ethumb_init()
22 180
23def shutdown(): 181def shutdown():
182 """ Shutdown the ethumb library.
183
184 .. note:: You never need to call this function, it is automatically called
185 at exit.
186
187 """
24 ethumb_shutdown() 188 ethumb_shutdown()
25 189
26cdef class PyEthumb: 190
27 """Ethumb thumbnail generator""" 191cdef class Ethumb(object):
192 """ Ethumb thumbnail generator.
193
194 Use this class to generate thumbnails in the local process.
195
196 .. seealso:: :class:`~efl.ethumb_client.EthumbClient` to generate thumbnails
197 using a server (recommended).
198
199 """
200 def __cinit__(self):
201 self.obj = NULL
202
28 def __init__(self): 203 def __init__(self):
29 """Ethumb constructor.""" 204 """ Ethumb constructor. """
205 assert self.obj == NULL, "Object must be clean"
206 self.obj = ethumb_new()
207 if self.obj == NULL:
208 raise SystemError("Error creating the ethumb object.")
209
210 def __repr__(self):
211 return ("<%s object at %#x (file='%s', thumb='%s')>") % (
212 type(self).__name__, <uintptr_t><void *>self,
213 self.file[0], self.thumb_path[0])
214
215 def delete(self):
216 """ Delete the underlying C object.
217
218 .. note:: You MUST call this function when you don't need the object
219 anymore, as it will free all internal used resources.
220
221 """
222 ethumb_free(self.obj)
223
224 def file_free(self):
225 """ Reset the source file information. """
226 ethumb_file_free(self.obj)
227
228 def exists(self):
229 """ Test if the thumbnail already exists.
230
231 :return: ``True`` if thumbnail exists, ``False`` otherwise
232
233 """
234 return bool(ethumb_exists(self.obj))
235
236 def generate(self, func, *args, **kargs):
237 """ Generate the thumbnail.
238
239 Thumbnail generation is asynchronous and depend on ecore main
240 loop running. Given function will be called back with
241 generation status if True is returned by this call. If False
242 is returned, given function will not be called.
243
244 Existing thumbnails will be overwritten with this call. Check
245 if they already exist with :func:`exists` before calling.
246
247 :param func: function to call on generation completion, even
248 if failed or succeeded. Signature is::
249
250 func(Ethumb, success, *args, **kargs)
251
252 with success being ``True`` for successful generation or
253 ``False`` on failure.
254
255 :return: ``True`` on success and ``False`` on failure
256
257 :raise TypeError: if **func** is not callable.
258
259 """
260 cdef:
261 tuple func_data
262
263 if not callable(func):
264 raise TypeError("func must be callable")
265
266 func_data = (self, func, args, kargs)
267 if ethumb_generate(self.obj, _generate_cb, <void*>func_data,
268 _generate_free_cb) != 0:
269 Py_INCREF(func_data)
270 return True
271 else:
272 return False
273
274 ## source file properties
275 property file:
276 """ The file to thumbnail.
277
278 This is a tuple of 2 strings: ``path`` and ``key``.
279
280 ``path``: Is the file to use.
281
282 ``key``: If path allows storing multiple resources in a single file
283 (EET or Edje for instance), this is the name used to locate the right
284 resource inside the file.
285
286 For convenience you can also assign a single string value (``path``),
287 ignoring the key.
288
289 :type: **str** or (**str**, **str**)
290
291 :raise RuntimeError: on failure setting the property
292
293 """
294 def __set__(self, value):
295 if isinstance(value, tuple):
296 path, key = value
297 else:
298 path, key = value, None
299 if isinstance(path, unicode): path = PyUnicode_AsUTF8String(path)
300 if isinstance(key, unicode): key = PyUnicode_AsUTF8String(key)
301 if ethumb_file_set(self.obj,
302 <const char *>path if path is not None else NULL,
303 <const char *>key if key is not None else NULL) == 0:
304 raise RuntimeError("Cannot set file")
305
306 def __get__(self):
307 cdef:
308 const char *path
309 const char *key
310 ethumb_file_get(self.obj, &path, &key)
311 return (_ctouni(path), _ctouni(key))
312
313 property frame:
314 """ The optional edje file used to generate a frame around the thumbnail
315
316 This can be used to simulate frames (wood, polaroid, etc) in the
317 generated thumbnails.
318
319 :type: (**str**, **str**, **str**): (theme_file, group_name, swallow_name)
320
321 :raise RuntimeError: on failure setting the property
322
323 """
324 def __set__(self, tuple value):
325 theme, group, swallow = value
326 if isinstance(theme, unicode): theme = PyUnicode_AsUTF8String(theme)
327 if isinstance(group, unicode): group = PyUnicode_AsUTF8String(group)
328 if isinstance(swallow, unicode): swallow = PyUnicode_AsUTF8String(swallow)
329 if ethumb_frame_set(self.obj,
330 <const char *>theme if theme is not None else NULL,
331 <const char *>group if group is not None else NULL,
332 <const char *>swallow if swallow is not None else NULL) == 0:
333 raise RuntimeError("Cannot set frame")
334
335 def __get__(self):
336 cdef:
337 const char *theme
338 const char *group
339 const char *swallow
340 ethumb_frame_get(self.obj, &theme, &group, &swallow)
341 return tuple(_ctouni(theme), _ctouni(group), _ctouni(swallow))
342
343 # destination thumb properties
344 property thumb_path:
345 """ The complete path of the generated thumbnail.
346
347 This is a tuple of 2 strings: ``path`` and ``key``.
348
349 ``path``: Is the complete file path.
350
351 ``key``: If path allows storing multiple resources in a single file
352 (EET or Edje for instance), this is the name used to locate the right
353 resource inside the file.
354
355 For convenience you can also assign a single string value (``path``),
356 ignoring the key.
357
358 :type: **str** or (**str**, **str**)
359
360 """
361 def __set__(self, value):
362 if isinstance(value, tuple):
363 path, key = value
364 else:
365 path, key = value, None
366 if isinstance(path, unicode): path = PyUnicode_AsUTF8String(path)
367 if isinstance(key, unicode): key = PyUnicode_AsUTF8String(key)
368 ethumb_thumb_path_set(self.obj,
369 <const char *>path if path is not None else NULL,
370 <const char *>key if key is not None else NULL)
371
372 def __get__(self):
373 cdef:
374 const char *path
375 const char *key
376 ethumb_thumb_path_get(self.obj, &path, &key)
377 return (_ctouni(path), _ctouni(key))
378
379 property thumb_dir_path:
380 """ Destination folder for the thumbnails.
381
382 This is the base folder, a category folder is added to this path
383 as a sub directory. Default is ``~/.thumbnails``
384
385 :type: **str**
386
387 """
388 def __set__(self, path):
389 if isinstance(path, unicode): path = PyUnicode_AsUTF8String(path)
390 ethumb_thumb_dir_path_set(self.obj,
391 <const char *>path if path is not None else NULL)
392
393 def __get__(self):
394 cdef const char *path
395 path = ethumb_thumb_dir_path_get(self.obj)
396 return _ctouni(path)
397
398 property thumb_category:
399 """ The thumbnails category
400
401 Category sub directory to store thumbnail. Default is either "normal"
402 or "large" for FDO compliant thumbnails or
403 ``WIDTHxHEIGHT-ASPECT[-FRAMED]-FORMAT``. It can be a string or None to
404 use auto generated names.
405
406 :type: **str**
407
408 """
409 def __set__(self, cat):
410 if isinstance(cat, unicode): cat = PyUnicode_AsUTF8String(cat)
411 ethumb_thumb_category_set(self.obj,
412 <const char *>cat if cat is not None else NULL)
413
414 def __get__(self):
415 cdef const char *cat
416 cat = ethumb_thumb_category_get(self.obj)
417 return _ctouni(cat)
418
419 property thumb_fdo:
420 """ Set a standard FDO thumbnail size
421
422 This is a preset to provide freedesktop.org (fdo) standard
423 compliant thumbnails. That is, files are stored as JPEG under
424 ~/.thumbnails/SIZE, with size being either normal (128x128) or
425 large (256x256).
426
427 :type: :ref:`Ethumb_Thumb_FDO_Size` **writeonly**
428
429 """
430 def __set__(self, Ethumb_Thumb_FDO_Size value):
431 ethumb_thumb_fdo_set(self.obj, value)
432
433 property thumb_size:
434 """ The size of thumbnails.
435
436 :type: (int **width**, int **height**)
437
438 """
439 def __set__(self, tuple value):
440 w, h = value
441 ethumb_thumb_size_set(self.obj, w, h)
442
443 def __get__(self):
444 cdef:
445 int w
446 int h
447 ethumb_thumb_size_get(self.obj, &w, &h)
448 return tuple(w, h)
449
450 property thumb_format:
451 """ The fileformat for the thumbnails.
452
453 Thumbnails are compressed; possible formats are PNG, JPEG and EET.
454
455 :type: :ref:`Ethumb_Thumb_Format`
456
457 """
458 def __set__(self, Ethumb_Thumb_Format value):
459 ethumb_thumb_format_set(self.obj, value)
460
461 def __get__(self):
462 return ethumb_thumb_format_get(self.obj)
463
464 property thumb_aspect:
465 """ The aspect ratio policy.
466
467 When the source and thumbnail aspect ratios don't match, this policy
468 sets how to adapt from the former to the latter: resize keeping source
469 aspect ratio, resize ignoring it or crop.
470
471 :type: :ref:`Ethumb_Thumb_Aspect`
472
473 """
474 def __set__(self, Ethumb_Thumb_Aspect value):
475 ethumb_thumb_aspect_set(self.obj, value)
476
477 def __get__(self):
478 return ethumb_thumb_aspect_get(self.obj)
479
480 property thumb_orientation:
481 """ The thumbnail rotation or flip.
482
483 :type: :ref:`Ethumb_Thumb_Orientation`
484
485 """
486 def __set__(self, Ethumb_Thumb_Orientation value):
487 ethumb_thumb_orientation_set(self.obj, value)
488
489 def __get__(self):
490 return ethumb_thumb_orientation_get(self.obj)
491
492 property thumb_crop_align:
493 """ Crop alignment in use.
494
495 :param x: horizontal alignment. 0.0 means left side will be
496 visible or right side is being lost. 1.0 means right side
497 will be visible or left side is being lost. 0.5 means just
498 center is visible, both sides will be lost. Default is 0.5.
499 :param y: vertical alignment. 0.0 is top visible, 1.0 is
500 bottom visible, 0.5 is center visible. Default is 0.5
501
502 :type: (float **x**, float **y**)
503
504 """
505 def __set__(self, tuple value):
506 x, y = value
507 ethumb_thumb_crop_align_set(self.obj, x, y)
508
509 def __get__(self):
510 cdef:
511 float x
512 float y
513 ethumb_thumb_crop_align_get(self.obj, &x, &y)
514 return tuple(x, y)
515
516 property thumb_quality:
517 """ The thumbnail compression quality.
518
519 Value from 0 to 100, default is 80. The effect depends on the format
520 being used, PNG will not use it.
521
522 :type: int
523
524 """
525 def __set__(self, int value):
526 ethumb_thumb_quality_set(self.obj, value)
527
528 def __get__(self):
529 return ethumb_thumb_quality_get(self.obj)
530
531 property thumb_compress:
532 """ The thumbnail compression rate.
533
534 Value from 0 to 9, default is 9. The effect depends on the format being
535 used, JPEG will not use it.
536
537 :type: int
538
539 """
540 def __set__(self, int value):
541 ethumb_thumb_compress_set(self.obj, value)
542
543 def __get__(self):
544 return ethumb_thumb_compress_get(self.obj)
545
546 ## video related
547 property video_start:
548 """ The start point for video thumbnails.
549
550 :type: float (from 0.0 to 1.0)
551
552 """
553 def __set__(self, float value):
554 ethumb_video_start_set(self.obj, value)
555
556 def __get__(self):
557 return ethumb_video_start_get(self.obj)
558
559 property video_time:
560 """ The video time (duration) in seconds.
561
562 :type: float
563
564 """
565 def __set__(self, float value):
566 ethumb_video_time_set(self.obj, value)
567
568 def __get__(self):
569 return ethumb_video_time_get(self.obj)
570
571 property video_interval:
572 """ The video frame interval, in seconds.
573
574 This is useful for animated thumbnail and will define skip time before
575 going to the next frame.
576
577 .. note:: that video backends might not be able to
578 precisely skip that amount as it will depend on various
579 factors, including video encoding.
580
581 :type: float
582
583 """
584 def __set__(self, float value):
585 ethumb_video_interval_set(self.obj, value)
586
587 def __get__(self):
588 return ethumb_video_interval_get(self.obj)
589
590 property video_ntimes:
591 """ The number of times the video loops (if applicable).
592
593 :type: int
594
595 """
596 def __set__(self, int value):
597 ethumb_video_ntimes_set(self.obj, value)
598
599 def __get__(self):
600 return ethumb_video_ntimes_get(self.obj)
601
602 property video_fps:
603 """ The thumbnail framerate.
604
605 Default to 10.
606
607 :type: int
608
609 """
610 def __set__(self, int value):
611 ethumb_video_fps_set(self.obj, value)
612
613 def __get__(self):
614 return ethumb_video_fps_get(self.obj)
615
616 ## document
617 property document_page:
618 """ The page number to thumbnail in paged documents.
619
620 :type: int
621
622 """
623 def __set__(self, int value):
624 ethumb_document_page_set(self.obj, value)
30 625
626 def __get__(self):
627 return ethumb_document_page_get(self.obj)
31 628
32init() 629init()
33atexit.register(shutdown) 630atexit.register(shutdown)