aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common_16/evas_soft16_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/engines/common_16/evas_soft16_main.c')
-rw-r--r--libraries/evas/src/lib/engines/common_16/evas_soft16_main.c594
1 files changed, 594 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common_16/evas_soft16_main.c b/libraries/evas/src/lib/engines/common_16/evas_soft16_main.c
new file mode 100644
index 0000000..6028744
--- /dev/null
+++ b/libraries/evas/src/lib/engines/common_16/evas_soft16_main.c
@@ -0,0 +1,594 @@
1#include "evas_common_soft16.h"
2
3static Evas_Cache_Image *eci = NULL;
4static int reference = 0;
5
6static Image_Entry *_evas_common_soft16_image_new(void);
7static void _evas_common_soft16_image_delete(Image_Entry *ie);
8
9static int _evas_common_soft16_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h);
10static void _evas_common_soft16_image_surface_delete(Image_Entry *ie);
11static DATA32 *_evas_common_soft16_image_surface_pixels(Image_Entry *ie);
12
13static int _evas_common_load_soft16_image_from_file(Image_Entry *ie);
14static void _evas_common_soft16_image_unload(Image_Entry *ie);
15
16static void _evas_common_soft16_image_dirty_region(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
17static int _evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src);
18
19static int _evas_common_soft16_image_ram_usage(Image_Entry *ie);
20
21static int _evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, unsigned int w, unsigned int h);
22static int _evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
23static int _evas_common_soft16_image_from_data(Image_Entry* ie_dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
24static int _evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst, int cspace);
25
26static int _evas_common_load_soft16_image_data_from_file(Image_Entry *ie);
27
28/* static void */
29/* _evas_common_soft16_image_debug(const char* context, Image_Entry *eim) */
30/* { */
31/* DBG("[16] %p = [%s] {%s,%s} %i [%i|%i]", eim, context, eim->file, eim->key, eim->references, eim->w, eim->h); */
32/* } */
33
34static const Evas_Cache_Image_Func _evas_common_soft16_image_func =
35{
36 _evas_common_soft16_image_new,
37 _evas_common_soft16_image_delete,
38 _evas_common_soft16_image_surface_alloc,
39 _evas_common_soft16_image_surface_delete,
40 _evas_common_soft16_image_surface_pixels,
41 _evas_common_load_soft16_image_from_file,
42 _evas_common_soft16_image_unload,
43 _evas_common_soft16_image_dirty_region,
44 _evas_common_soft16_image_dirty,
45 _evas_common_soft16_image_size_set,
46 _evas_common_soft16_image_from_copied_data,
47 _evas_common_soft16_image_from_data,
48 _evas_common_soft16_image_colorspace_set,
49 _evas_common_load_soft16_image_data_from_file,
50 _evas_common_soft16_image_ram_usage,
51/* _evas_common_soft16_image_debug */
52 NULL
53};
54
55EAPI void
56evas_common_soft16_image_init(void)
57{
58 if (!eci)
59 eci = evas_cache_image_init(&_evas_common_soft16_image_func);
60 reference++;
61}
62
63EAPI void
64evas_common_soft16_image_shutdown(void)
65{
66 if (--reference == 0)
67 {
68// DISABLE for now - something wrong with cache shutdown freeing things
69// still in use - rage_thumb segv's now.
70//
71// actually - i think i see it. cache ref goes to 0 (and thus gets freed)
72// because in eng_setup() when a buffer changes size it is FIRST freed
73// THEN allocated again - thus brignhjing ref to 0 then back to 1 immediately
74// where it should stay at 1. - see evas_engine.c in the buffer enigne for
75// example. eng_output_free() is called BEFORE _output_setup(). although this
76// is only a SIGNE of the problem. we can patch this up with either freeing
77// after the setup (so we just pt a ref of 2 then back to 1), or just
78// evas_common_image_init() at the start and evas_common_image_shutdown()
79// after it all. really ref 0 should only be reached when no more canvases
80// with no more objects exist anywhere.
81
82// ENABLE IT AGAIN, hope it is fixed. Gustavo @ January 22nd, 2009.
83 evas_cache_image_shutdown(eci);
84 eci = NULL;
85 }
86}
87
88EAPI Evas_Cache_Image *
89evas_common_soft16_image_cache_get(void)
90{
91 return eci;
92}
93
94static Image_Entry *
95_evas_common_soft16_image_new(void)
96{
97 Soft16_Image *im;
98
99 im = calloc(1, sizeof(Soft16_Image));
100 if (!im) return NULL;
101
102 im->stride = -1;
103
104 return (Image_Entry *) im;
105}
106
107static void
108_evas_common_soft16_image_delete(Image_Entry *ie)
109{
110 memset(ie, 0xFF, sizeof (Soft16_Image));
111 free(ie);
112}
113
114static int
115_evas_common_soft16_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h)
116{
117 Soft16_Image *im = (Soft16_Image *) ie;
118
119 if (im->stride < 0) im->stride = _calc_stride(w);
120
121 im->pixels = realloc(im->pixels, IMG_BYTE_SIZE(im->stride, h, ie->flags.alpha));
122 if (!im->pixels) return -1;
123
124 if (ie->flags.alpha)
125 {
126 im->alpha = (DATA8 *)(im->pixels + (im->stride * h));
127 im->flags.free_alpha = 0;
128 }
129 im->flags.free_pixels = 1;
130
131 return 0;
132}
133
134static void
135_evas_common_soft16_image_surface_delete(Image_Entry *ie)
136{
137 Soft16_Image *im = (Soft16_Image *) ie;
138
139 if (im->flags.free_pixels)
140 free(im->pixels);
141 im->pixels = NULL;
142 im->flags.free_pixels = 0;
143
144 if (im->flags.free_alpha)
145 free(im->alpha);
146 im->alpha = NULL;
147 im->flags.free_alpha = 0;
148}
149
150static DATA32 *
151_evas_common_soft16_image_surface_pixels(Image_Entry *ie __UNUSED__)
152{
153 abort();
154
155 return NULL;
156}
157
158static int
159_evas_common_load_soft16_image_from_file(Image_Entry *ie)
160{
161 Soft16_Image *sim = (Soft16_Image *) ie;
162 RGBA_Image *im;
163 int error = 0;
164
165 im = (RGBA_Image *) evas_cache_image_request(evas_common_image_cache_get(), sim->cache_entry.file, sim->cache_entry.key, &sim->cache_entry.load_opts, &error);
166 sim->source = im;
167 if (!sim->source) return -1;
168
169 sim->cache_entry.w = sim->source->cache_entry.w;
170 sim->cache_entry.h = sim->source->cache_entry.h;
171 ie->flags.alpha = im->cache_entry.flags.alpha;
172 sim->cache_entry.info = im->cache_entry.info;
173 if (sim->stride < 0) sim->stride = _calc_stride(sim->cache_entry.w);
174
175 return 0;
176}
177
178static void
179_evas_common_soft16_image_unload(Image_Entry *ie __UNUSED__)
180{
181}
182
183static void
184_evas_common_soft16_image_dirty_region(Image_Entry *im __UNUSED__, unsigned int x __UNUSED__, unsigned int y __UNUSED__, unsigned int w __UNUSED__, unsigned int h __UNUSED__)
185{
186}
187
188static int
189_evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src)
190{
191 Soft16_Image *dst = (Soft16_Image *) ie_dst;
192 Soft16_Image *src = (Soft16_Image *) ie_src;
193
194 evas_cache_image_load_data(&src->cache_entry);
195 evas_cache_image_surface_alloc(&dst->cache_entry,
196 src->cache_entry.w, src->cache_entry.h);
197
198/* evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */
199
200 return 0;
201}
202
203static int
204_evas_common_soft16_image_ram_usage(Image_Entry *ie)
205{
206 Soft16_Image *im = (Soft16_Image *) ie;
207
208 if (im->pixels && im->flags.free_pixels)
209 return IMG_BYTE_SIZE(im->stride, im->cache_entry.h, ie->flags.alpha);
210 return 0;
211}
212
213static int
214_evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, unsigned int w __UNUSED__, unsigned int h __UNUSED__)
215{
216 Soft16_Image *dst = (Soft16_Image *) ie_dst;
217 Soft16_Image *im = (Soft16_Image *) ie_im;
218
219 dst->flags = im->flags;
220
221 return 0;
222}
223
224static int
225_evas_common_soft16_image_from_data(Image_Entry* ie_dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace __UNUSED__)
226{
227 Soft16_Image *im = (Soft16_Image *) ie_dst;
228
229 /* FIXME: handle colorspace */
230 ie_dst->w = w;
231 ie_dst->h = h;
232 ie_dst->flags.alpha = alpha;
233
234 im->flags.free_pixels = 0;
235 im->flags.free_alpha = 0;
236 if (im->stride < 0)
237 im->stride = _calc_stride(w);
238
239 /* FIXME: That's bad, the application must be aware of the engine internal. */
240 im->pixels = (DATA16 *) image_data;
241 if (ie_dst->flags.alpha)
242 im->alpha = (DATA8 *)(im->pixels + (im->stride * h));
243
244 return 0;
245}
246
247static int
248_evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, unsigned int w __UNUSED__, unsigned int h, DATA32 *image_data, int alpha __UNUSED__, int cspace __UNUSED__)
249{
250 Soft16_Image *im = (Soft16_Image *) ie_dst;
251
252 /* FIXME: handle colorspace */
253 if (image_data)
254 memcpy(im->pixels, image_data, IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
255 else
256 memset(im->pixels, 0, IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
257
258 return 0;
259}
260
261static int
262_evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst __UNUSED__, int cspace __UNUSED__)
263{
264 /* FIXME: handle colorspace */
265 return 0;
266}
267
268static int
269_evas_common_load_soft16_image_data_from_file(Image_Entry *ie)
270{
271 Soft16_Image *im = (Soft16_Image *) ie;
272
273 if (im->pixels) return 0;
274 if (!im->source) return -1;
275
276 evas_cache_image_load_data(&im->source->cache_entry);
277 if (im->source->image.data)
278 {
279 DATA32 *sp;
280
281 evas_cache_image_surface_alloc(&im->cache_entry,
282 im->source->cache_entry.w,
283 im->source->cache_entry.h);
284
285 sp = im->source->image.data;
286 if (im->alpha)
287 evas_common_soft16_image_convert_from_rgba(im, sp);
288 else
289 evas_common_soft16_image_convert_from_rgb(im, sp);
290 }
291 evas_cache_image_drop(&im->source->cache_entry);
292 im->cache_entry.info.module = NULL;
293 im->cache_entry.info.loader = NULL;
294 im->source = NULL;
295
296 return 0;
297}
298
299/* Soft16_Image * */
300/* evas_common_soft16_image_new(int w, int h, int stride, int have_alpha, DATA16 *pixels, */
301/* int copy) */
302/* { */
303/* Soft16_Image *im; */
304
305/* if (stride < 0) stride = _calc_stride(w); */
306
307/* im = evas_common_soft16_image_alloc(w, h, stride, have_alpha, copy); */
308/* if (!im) return NULL; */
309
310/* if (pixels) */
311/* { */
312/* if (copy) */
313/* memcpy(im->pixels, pixels, IMG_BYTE_SIZE(stride, h, have_alpha)); */
314/* else */
315/* { */
316/* im->pixels = pixels; */
317/* if (have_alpha) im->alpha = (DATA8 *)(im->pixels + (stride * h)); */
318/* } */
319/* } */
320/* return im; */
321/* } */
322
323static inline void
324_get_clip(const RGBA_Draw_Context *dc, const Soft16_Image *im,
325 Eina_Rectangle *clip)
326{
327 if (dc->clip.use)
328 {
329 EINA_RECTANGLE_SET(clip, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
330 if (clip->x < 0)
331 {
332 clip->w += clip->x;
333 clip->x = 0;
334 }
335 if (clip->y < 0)
336 {
337 clip->h += clip->y;
338 clip->y = 0;
339 }
340 if ((clip->x + clip->w) > (int)im->cache_entry.w) clip->w = im->cache_entry.w - clip->x;
341 if ((clip->y + clip->h) > (int)im->cache_entry.h) clip->h = im->cache_entry.h - clip->y;
342 }
343 else
344 {
345 EINA_RECTANGLE_SET(clip, 0, 0, im->cache_entry.w, im->cache_entry.h);
346 }
347}
348
349static inline int
350_is_empty_rectangle(const Eina_Rectangle *r)
351{
352 return (r->w < 1) || (r->h < 1);
353}
354
355static inline void
356_shrink(int *s_pos, int *s_size, int pos, int size)
357{
358 int d;
359
360 d = (*s_pos) - pos;
361 if (d < 0)
362 {
363 (*s_size) += d;
364 (*s_pos) = pos;
365 }
366
367 d = size + pos - (*s_pos);
368 if ((*s_size) > d)
369 (*s_size) = d;
370}
371
372static int
373_soft16_adjust_areas(Eina_Rectangle *src,
374 int src_max_x, int src_max_y,
375 Eina_Rectangle *dst,
376 int dst_max_x, int dst_max_y,
377 Eina_Rectangle *dst_clip)
378{
379 if (_is_empty_rectangle(src) ||
380 _is_empty_rectangle(dst) ||
381 _is_empty_rectangle(dst_clip))
382 return 0;
383
384 /* shrink clip */
385 _shrink(&dst_clip->x, &dst_clip->w, dst->x, dst->w);
386 _shrink(&dst_clip->y, &dst_clip->h, dst->y, dst->h);
387 if (_is_empty_rectangle(dst_clip)) return 0;
388
389 /* sanitise x */
390 if (src->x < 0)
391 {
392 dst->x -= (src->x * dst->w) / src->w;
393 dst->w += (src->x * dst->w) / src->w;
394 src->w += src->x;
395 src->x = 0;
396 }
397 if (src->x >= src_max_x) return 0;
398 if ((src->x + src->w) > src_max_x)
399 {
400 dst->w = (dst->w * (src_max_x - src->x)) / (src->w);
401 src->w = src_max_x - src->x;
402 }
403 if (dst->w <= 0) return 0;
404 if (src->w <= 0) return 0;
405 if (dst_clip->x < 0)
406 {
407 dst_clip->w += dst_clip->x;
408 dst_clip->x = 0;
409 }
410 if (dst_clip->w <= 0) return 0;
411 if (dst_clip->x >= dst_max_x) return 0;
412
413 _shrink(&dst_clip->x, &dst_clip->w, 0, dst_max_x);
414 if (dst_clip->w <= 0) return 0;
415
416 /* sanitise y */
417 if (src->y < 0)
418 {
419 dst->y -= (src->y * dst->h) / src->h;
420 dst->h += (src->y * dst->h) / src->h;
421 src->h += src->y;
422 src->y = 0;
423 }
424 if (src->y >= src_max_y) return 0;
425 if ((src->y + src->h) > src_max_y)
426 {
427 dst->h = (dst->h * (src_max_y - src->y)) / (src->h);
428 src->h = src_max_y - src->y;
429 }
430 if (dst->h <= 0) return 0;
431 if (src->h <= 0) return 0;
432 if (dst_clip->y < 0)
433 {
434 dst_clip->h += dst_clip->y;
435 dst_clip->y = 0;
436 }
437 if (dst_clip->h <= 0) return 0;
438 if (dst_clip->y >= dst_max_y) return 0;
439
440 _shrink(&dst_clip->y, &dst_clip->h, 0, dst_max_y);
441 if (dst_clip->h <= 0) return 0;
442
443 return 1;
444}
445
446static void
447_soft16_image_draw_sampled_int(Soft16_Image *src, Soft16_Image *dst,
448 RGBA_Draw_Context *dc,
449 Eina_Rectangle sr, Eina_Rectangle dr)
450{
451 Eina_Rectangle cr;
452
453 if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
454 return;
455 if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
456 return;
457
458 _get_clip(dc, dst, &cr);
459 if (!_soft16_adjust_areas(&sr, src->cache_entry.w, src->cache_entry.h, &dr, dst->cache_entry.w, dst->cache_entry.h, &cr))
460 return;
461
462 if ((dr.w == sr.w) && (dr.h == sr.h))
463 evas_common_soft16_image_draw_unscaled(src, dst, dc, sr, dr, cr);
464 else
465 evas_common_soft16_image_draw_scaled_sampled(src, dst, dc, sr, dr, cr);
466}
467
468EAPI void
469evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst,
470 RGBA_Draw_Context *dc,
471 int src_region_x, int src_region_y,
472 int src_region_w, int src_region_h,
473 int dst_region_x, int dst_region_y,
474 int dst_region_w, int dst_region_h,
475 int smooth __UNUSED__)
476{
477 Eina_Rectangle sr, dr;
478 Cutout_Rects *rects;
479 Cutout_Rect *r;
480 struct RGBA_Draw_Context_clip clip_bkp;
481 int i;
482
483 /* handle cutouts here! */
484 EINA_RECTANGLE_SET(&dr, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
485
486 if (_is_empty_rectangle(&dr)) return;
487 if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
488 return;
489
490 EINA_RECTANGLE_SET(&sr, src_region_x, src_region_y, src_region_w, src_region_h);
491
492 if (_is_empty_rectangle(&sr)) return;
493 if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
494 return;
495
496 /* no cutouts - cut right to the chase */
497 if (!dc->cutout.rects)
498 {
499 _soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
500 return;
501 }
502
503 /* save out clip info */
504 clip_bkp = dc->clip;
505 evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
506 evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
507 /* our clip is 0 size.. abort */
508 if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
509 {
510 dc->clip = clip_bkp;
511 return;
512 }
513 rects = evas_common_draw_context_apply_cutouts(dc);
514 for (i = 0; i < rects->active; i++)
515 {
516 r = rects->rects + i;
517 evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
518 _soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
519 }
520 evas_common_draw_context_apply_clear_cutouts(rects);
521 dc->clip = clip_bkp;
522}
523
524EAPI Soft16_Image *
525evas_common_soft16_image_alpha_set(Soft16_Image *im, int have_alpha)
526{
527 Soft16_Image *new_im;
528
529 if (im->cache_entry.flags.alpha == have_alpha) return im;
530
531 new_im = (Soft16_Image *) evas_cache_image_alone(&im->cache_entry);
532
533 new_im->cache_entry.flags.alpha = have_alpha;
534
535 if (im->cache_entry.w > 0
536 && im->cache_entry.h)
537 new_im = (Soft16_Image *) evas_cache_image_size_set(&new_im->cache_entry, im->cache_entry.w, im->cache_entry.h);
538
539 return new_im;
540}
541
542/* Soft16_Image * */
543/* evas_common_soft16_image_size_set(Soft16_Image *old_im, int w, int h) */
544/* { */
545/* Soft16_Image *new_im; */
546/* DATA16 *dp, *sp; */
547/* int i, cw, ch, ew; */
548
549/* if ((old_im->cache_entry.w == w) && (old_im->cache_entry.h == h)) return old_im; */
550
551/* new_im = evas_common_soft16_image_new(w, h, -1, old_im->flags.have_alpha, NULL, 1); */
552
553/* if (old_im->cache_entry.w < new_im->cache_entry.w) */
554/* cw = old_im->cache_entry.w; */
555/* else */
556/* cw = new_im->cache_entry.w; */
557
558/* ew = new_im->cache_entry.w - cw; */
559
560/* if (old_im->cache_entry.h < new_im->cache_entry.h) */
561/* ch = old_im->cache_entry.h; */
562/* else */
563/* ch = new_im->cache_entry.h; */
564
565/* dp = new_im->pixels; */
566/* sp = old_im->pixels; */
567/* for (i = 0; i < ch; i++) */
568/* { */
569/* memcpy(dp, sp, cw * sizeof(DATA16)); */
570/* if (ew > 0) memset(dp, 0, ew * sizeof(DATA16)); */
571
572/* dp += new_im->stride; */
573/* sp += old_im->stride; */
574/* } */
575
576/* if (old_im->flags.have_alpha) */
577/* { */
578/* DATA8 *dp, *sp; */
579
580/* dp = new_im->alpha; */
581/* sp = old_im->alpha; */
582/* for (i = 0; i < ch; i++) */
583/* { */
584/* memcpy(dp, sp, cw * sizeof(DATA8)); */
585/* if (ew > 0) memset(dp, 0, ew * sizeof(DATA8)); */
586
587/* dp += new_im->stride; */
588/* sp += old_im->stride; */
589/* } */
590/* } */
591
592/* evas_cache_image_drop(&old_im->cache_entry); */
593/* return new_im; */
594/* } */