1 /* EVAS - EFL Scene Graph
2  * Copyright (C) 2013 Enlightenment Developers:
3  *           Cedric Bail <cedric.bail@free.fr>
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  *    1. Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *    2. Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in the
14  *       documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 /**
28  * What does it means for you ?
29  *    Evas Loader is dynamically linked to Evas at run time. You can use anything
30  * you want here as long as the license of the module you add to your system matches
31  * the application you are using it in. Be aware that if you make a module that uses
32  * a GPL library, it may turn the license of your binary to GPL. Evas doesn't ship
33  * with any GPL modules.
34  */
35 
36 #ifndef _EVAS_LOADER_H
37 #define _EVAS_LOADER_H
38 
39 #include "Eina.h"
40 #include "Emile.h"
41 
42 #ifdef EAPI
43 # undef EAPI
44 #endif
45 
46 #ifdef _WIN32
47 # ifdef EFL_BUILD
48 #  ifdef DLL_EXPORT
49 #   define EAPI __declspec(dllexport)
50 #  else
51 #   define EAPI
52 #  endif
53 # else
54 #  define EAPI __declspec(dllimport)
55 # endif
56 #else
57 # ifdef __GNUC__
58 #  if __GNUC__ >= 4
59 #   define EAPI __attribute__ ((visibility("default")))
60 #  else
61 #   define EAPI
62 #  endif
63 # else
64 #  define EAPI
65 # endif
66 #endif
67 
68 #ifdef __cplusplus
69 extern "C" {
70 #endif
71 
72 /* the module api version */
73 #define EVAS_MODULE_API_VERSION 3
74 
75 /* the module types */
76 typedef enum _Evas_Module_Type
77 {
78    EVAS_MODULE_TYPE_ENGINE = 0,
79    EVAS_MODULE_TYPE_IMAGE_LOADER = 1,
80    EVAS_MODULE_TYPE_IMAGE_SAVER = 2,
81    EVAS_MODULE_TYPE_OBJECT = 3,
82    EVAS_MODULE_TYPE_VG_LOADER = 4,
83    EVAS_MODULE_TYPE_VG_SAVER = 5
84 } Evas_Module_Type;
85 
86 typedef struct _Evas_Module_Api    Evas_Module_Api;
87 typedef struct _Evas_Module        Evas_Module;
88 typedef struct _Evas_Module_Path   Evas_Module_Path;
89 typedef struct _Evas_Module_Engine Evas_Module_Engine;
90 typedef struct _Evas_Module_Public Evas_Module_Public;
91 
92 /* the module api structure, all modules should define this struct */
93 struct _Evas_Module_Api
94 {
95    int			version;
96    const char		*name;
97    const char		*author;
98 
99    struct
100      {
101 	int (*open)(Evas_Module *);
102 	void (*close)(Evas_Module *);
103      } func;
104 };
105 
106 /* the module structure */
107 struct _Evas_Module
108 {
109    const Evas_Module_Api *definition;
110 
111    void		*functions;	/* these are the functions exported by the module */
112    int           id_engine;	/* some internal data for the module i.e the id for engines */
113 
114    int           ref; /* how many refs */
115    int           last_used; /* the cycle count when it was last used */
116 
117    Eina_Lock     lock;
118 
119    unsigned char	loaded : 1;
120 };
121 
122 /**
123  * @addtogroup Evas_Image
124  * @{
125  */
126 
127 typedef struct _Evas_Image_Load_Opts  Evas_Image_Load_Opts;
128 
129 struct _Evas_Image_Load_Opts
130 {
131    Emile_Image_Load_Opts emile;
132    Eina_Bool             skip_head; // skip open of file and header load and
133                                     // defer this until a preload is done
134                                     // to allow for real async/threaded load
135 };
136 
137 typedef Emile_Image_Animated  Evas_Image_Animated;
138 typedef struct _Evas_Image_Property Evas_Image_Property;
139 
140 struct _Evas_Image_Property
141 {
142   Emile_Image_Property info;
143   // Stretch region are directly encoded the way Evas excpect them internally
144   // 8bits is used for each step. The lower bits indicate how long the stretch region
145   // span. Masking with 0x80 will be true if the region is stretchable. If false, it
146   // will be fixed size.
147   struct {
148      struct {
149         uint8_t *region;
150      } horizontal, vertical;
151   } stretch;
152   // Where inside the image are we supposed to overlay data
153   Eina_Rectangle content;
154   // need_data is set to True when to get accurate property, data need to be loaded
155   Eina_Bool need_data;
156 };
157 
158 typedef struct _Evas_Image_Load_Func Evas_Image_Load_Func;
159 
160 /**
161  * @brief Possible outcomes of a load operation
162  */
163 typedef enum
164 {
165    EVAS_LOAD_ERROR_NONE = 0,  /**< No error on load */
166    EVAS_LOAD_ERROR_GENERIC,  /**< A non-specific error occurred */
167    EVAS_LOAD_ERROR_DOES_NOT_EXIST,  /**< File (or file path) does not exist */
168    EVAS_LOAD_ERROR_PERMISSION_DENIED,	 /**< Permission denied to an existing file (or path) */
169    EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED,  /**< Allocation of resources failure prevented load */
170    EVAS_LOAD_ERROR_CORRUPT_FILE,  /**< File corrupt (but was detected as a known format) */
171    EVAS_LOAD_ERROR_UNKNOWN_FORMAT,  /**< File is not a known format */
172    EVAS_LOAD_ERROR_CANCELLED, /**< File loading has been cancelled */
173 } Evas_Load_Error;
174 
175 typedef Emile_Image_Animated_Loop_Hint Evas_Image_Animated_Loop_Hint;
176 
177 #define EVAS_IMAGE_ANIMATED_HINT_NONE EMILE_IMAGE_ANIMATED_HINT_NONE
178 #define EVAS_IMAGE_ANIMATED_HINT_LOOP EMILE_IMAGE_ANIMATED_HINT_LOOP
179 #define EVAS_IMAGE_ANIMATED_HINT_PINGPONG EMILE_IMAGE_ANIMATED_HINT_PINGPONG
180 
181 typedef Emile_Image_Scale_Hint Evas_Image_Scale_Hint; /**< How an image's data is to be treated by Evas, with regard to scaling cache */
182 
183 #define EVAS_IMAGE_SCALE_HINT_NONE EMILE_IMAGE_SCALE_HINT_NONE
184 #define EVAS_IMAGE_SCALE_HINT_DYNAMIC EMILE_IMAGE_SCALE_HINT_DYNAMIC
185 #define EVAS_IMAGE_SCALE_HINT_STATIC EMILE_IMAGE_SCALE_HINT_STATIC
186 
187 /**
188  * Colorspaces for pixel data supported by Evas
189  * @ingroup Evas_Object_Image
190  */
191 typedef Emile_Colorspace Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */
192 
193 #define EVAS_COLORSPACE_ARGB8888 EMILE_COLORSPACE_ARGB8888
194 #define EVAS_COLORSPACE_YCBCR422P601_PL EMILE_COLORSPACE_YCBCR422P601_PL
195 #define EVAS_COLORSPACE_YCBCR422P709_PL EMILE_COLORSPACE_YCBCR422P709_PL
196 #define EVAS_COLORSPACE_RGB565_A5P EMILE_COLORSPACE_RGB565_A5P
197 #define EVAS_COLORSPACE_GRY8 EMILE_COLORSPACE_GRY8
198 #define EVAS_COLORSPACE_YCBCR422601_PL EMILE_COLORSPACE_YCBCR422601_PL
199 #define EVAS_COLORSPACE_YCBCR420NV12601_PL EMILE_COLORSPACE_YCBCR420NV12601_PL
200 #define EVAS_COLORSPACE_YCBCR420TM12601_PL EMILE_COLORSPACE_YCBCR420TM12601_PL
201 #define EVAS_COLORSPACE_AGRY88 EMILE_COLORSPACE_AGRY88
202    // ETC1/2 support
203 #define EVAS_COLORSPACE_ETC1 EMILE_COLORSPACE_ETC1
204 #define EVAS_COLORSPACE_RGB8_ETC2 EMILE_COLORSPACE_RGB8_ETC2
205 #define EVAS_COLORSPACE_RGBA8_ETC2_EAC EMILE_COLORSPACE_RGBA8_ETC2_EAC
206 #define EVAS_COLORSPACE_ETC1_ALPHA EMILE_COLORSPACE_ETC1_ALPHA
207    // S3TC support
208 #define EVAS_COLORSPACE_RGB_S3TC_DXT1 EMILE_COLORSPACE_RGB_S3TC_DXT1
209 #define EVAS_COLORSPACE_RGBA_S3TC_DXT1 EMILE_COLORSPACE_RGBA_S3TC_DXT1
210 #define EVAS_COLORSPACE_RGBA_S3TC_DXT2 EMILE_COLORSPACE_RGBA_S3TC_DXT2
211 #define EVAS_COLORSPACE_RGBA_S3TC_DXT3 EMILE_COLORSPACE_RGBA_S3TC_DXT3
212 #define EVAS_COLORSPACE_RGBA_S3TC_DXT4 EMILE_COLORSPACE_RGBA_S3TC_DXT4
213 #define EVAS_COLORSPACE_RGBA_S3TC_DXT5 EMILE_COLORSPACE_RGBA_S3TC_DXT5
214 
215 #define EVAS_IMAGE_LOAD_VERSION 2
216 
217 struct _Evas_Image_Load_Func
218 {
219   int       version;
220   void     *(*file_open) (Eina_File *f, Eina_Stringshare *key,
221 			  Evas_Image_Load_Opts *opts,
222 			  Evas_Image_Animated *animated,
223 			  int *error);
224   void     (*file_close) (void *loader_data);
225 
226   Eina_Bool (*file_head) (void *loader_data,
227                           Evas_Image_Property *prop,
228                           int *error);
229   Eina_Bool (*file_head_with_data) (void *loader_data,
230                                     Evas_Image_Property *prop,
231                                     void *pixels, int *error);
232   Eina_Bool (*file_data) (void *loader_data,
233                           Evas_Image_Property *prop,
234                           void *pixels, int *error);
235   double    (*frame_duration) (void *loader_data,
236 			       int start, int frame_num);
237 
238   Eina_Bool threadable;
239   Eina_Bool do_region;
240 };
241 
242 EAPI Eina_Bool    evas_module_register   (const Evas_Module_Api *module, Evas_Module_Type type);
243 EAPI Eina_Bool    evas_module_unregister (const Evas_Module_Api *module, Evas_Module_Type type);
244 
245 EAPI Eina_Bool    evas_module_task_cancelled (void); /**< @since 1.19 */
246 
247 #define EVAS_MODULE_TASK_CHECK(Count, Mask, Error, Error_Handler)       \
248   do {                                                                  \
249      Count++;                                                           \
250      if ((Count & Mask) == Mask)                                        \
251        {                                                                \
252           Count = 0;                                                    \
253           if (evas_module_task_cancelled())                             \
254             {                                                           \
255                *Error = EVAS_LOAD_ERROR_CANCELLED;                 \
256                goto Error_Handler;                                      \
257             }                                                           \
258        }                                                                \
259   } while (0)
260 
261 #define EVAS_MODULE_DEFINE(Type, Tn, Name)		\
262   Eina_Bool evas_##Tn##_##Name##_init(void)		\
263   {							\
264      return evas_module_register(&evas_modapi, Type);	\
265   }							\
266   void evas_##Tn##_##Name##_shutdown(void)		\
267   {							\
268      evas_module_unregister(&evas_modapi, Type);	\
269   }
270 
271 #define EVAS_EINA_MODULE_DEFINE(Tn, Name)	\
272   EINA_MODULE_INIT(evas_##Tn##_##Name##_init);	\
273   EINA_MODULE_SHUTDOWN(evas_##Tn##_##Name##_shutdown);
274 
275 static inline Eina_Bool
evas_loader_helper_stretch_region_push(uint8_t ** region,uint8_t * offset,Eina_Bool stretchable)276 evas_loader_helper_stretch_region_push(uint8_t **region,
277                                        uint8_t *offset,
278                                        Eina_Bool stretchable)
279 {
280    uint32_t length = 0;
281    void *tmp;
282 
283    if (*offset == 0) return EINA_TRUE;
284 
285    while (*region && (*region)[length] != 0)
286      length++;
287 
288    // +1 for termination and +1 for the region being pushed
289    tmp = realloc(*region, sizeof (uint8_t) * (length + 2));
290    if (!tmp) return EINA_FALSE;
291 
292    *region = (uint8_t *) tmp;
293    (*region)[length] = (*offset) | (stretchable ? 0x80 : 0);
294    (*region)[length + 1] = 0;
295 
296    *offset = 0;
297 
298    return EINA_TRUE;
299 }
300 
301 /**
302  * @}
303  */
304 
305 #ifdef __cplusplus
306 }
307 #endif
308 
309 #undef EAPI
310 #define EAPI
311 
312 #endif
313