1 #include "evas_common_soft16.h"
3 static Evas_Cache_Image *eci = NULL;
4 static int reference = 0;
6 static Image_Entry *_evas_common_soft16_image_new(void);
7 static void _evas_common_soft16_image_delete(Image_Entry *ie);
9 static int _evas_common_soft16_image_surface_alloc(Image_Entry *ie, int w, int h);
10 static void _evas_common_soft16_image_surface_delete(Image_Entry *ie);
11 static DATA32 *_evas_common_soft16_image_surface_pixels(Image_Entry *ie);
13 static int _evas_common_load_soft16_image_from_file(Image_Entry *ie);
14 static void _evas_common_soft16_image_unload(Image_Entry *ie);
16 static void _evas_common_soft16_image_dirty_region(Image_Entry *im, int x, int y, int w, int h);
17 static int _evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src);
19 static int _evas_common_soft16_image_ram_usage(Image_Entry *ie);
21 static int _evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, int w, int h);
22 static int _evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace);
23 static int _evas_common_soft16_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace);
24 static int _evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst, int cspace);
26 static int _evas_common_load_soft16_image_data_from_file(Image_Entry *ie);
29 _evas_common_soft16_image_debug(const char* context, Image_Entry *eim)
31 fprintf(stderr, "[16] %p = [%s] {%s,%s} %i [%i|%i]\n", eim, context, eim->file, eim->key, eim->references, eim->w, eim->h);
34 static const Evas_Cache_Image_Func _evas_common_soft16_image_func =
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 */
56 evas_common_soft16_image_init(void)
59 eci = evas_cache_image_init(&_evas_common_soft16_image_func);
64 evas_common_soft16_image_shutdown(void)
68 // DISABLE for now - something wrong with cache shutdown freeing things
69 // still in use - rage_thumb segv's now.
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 // evas_cache_image_shutdown(eci);
86 EAPI Evas_Cache_Image *
87 evas_common_soft16_image_cache_get(void)
93 _evas_common_soft16_image_new(void)
97 im = calloc(1, sizeof(Soft16_Image));
102 return (Image_Entry *) im;
106 _evas_common_soft16_image_delete(Image_Entry *ie)
108 memset(ie, 0xFF, sizeof (Soft16_Image));
113 _evas_common_soft16_image_surface_alloc(Image_Entry *ie, int w, int h)
115 Soft16_Image *im = (Soft16_Image *) ie;
117 if (im->stride < 0) im->stride = _calc_stride(w);
119 im->pixels = realloc(im->pixels, IMG_BYTE_SIZE(im->stride, h, ie->flags.alpha));
120 if (!im->pixels) return -1;
124 im->alpha = (DATA8 *)(im->pixels + (im->stride * h));
125 im->flags.free_alpha = 0;
127 im->flags.free_pixels = 1;
133 _evas_common_soft16_image_surface_delete(Image_Entry *ie)
135 Soft16_Image *im = (Soft16_Image *) ie;
137 if (im->flags.free_pixels)
140 im->flags.free_pixels = 0;
142 if (im->flags.free_alpha)
145 im->flags.free_alpha = 0;
149 _evas_common_soft16_image_surface_pixels(Image_Entry *ie)
157 _evas_common_load_soft16_image_from_file(Image_Entry *ie)
159 Soft16_Image *sim = (Soft16_Image *) ie;
163 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);
165 if (!sim->source) return -1;
167 sim->cache_entry.w = sim->source->cache_entry.w;
168 sim->cache_entry.h = sim->source->cache_entry.h;
169 ie->flags.alpha = im->cache_entry.flags.alpha;
170 if (sim->stride < 0) sim->stride = _calc_stride(sim->cache_entry.w);
176 _evas_common_soft16_image_unload(Image_Entry *ie)
181 _evas_common_soft16_image_dirty_region(Image_Entry *im, int x, int y, int w, int h)
186 _evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src)
188 Soft16_Image *dst = (Soft16_Image *) ie_dst;
189 Soft16_Image *src = (Soft16_Image *) ie_src;
191 evas_cache_image_load_data(&src->cache_entry);
192 evas_cache_image_surface_alloc(&dst->cache_entry,
193 src->cache_entry.w, src->cache_entry.h);
195 /* evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */
201 _evas_common_soft16_image_ram_usage(Image_Entry *ie)
203 Soft16_Image *im = (Soft16_Image *) ie;
205 if (im->pixels && im->flags.free_pixels)
206 return IMG_BYTE_SIZE(im->stride, im->cache_entry.h, ie->flags.alpha);
211 _evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, int w, int h)
213 Soft16_Image *dst = (Soft16_Image *) ie_dst;
214 Soft16_Image *im = (Soft16_Image *) ie_im;
216 dst->flags = im->flags;
222 _evas_common_soft16_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace)
224 Soft16_Image *im = (Soft16_Image *) ie_dst;
226 /* FIXME: handle colorspace */
229 ie_dst->flags.alpha = alpha;
231 im->flags.free_pixels = 0;
232 im->flags.free_alpha = 0;
234 /* FIXME: That's bad, the application must be aware of the engine internal. */
235 im->pixels = (DATA16 *) image_data;
236 if (ie_dst->flags.alpha)
237 im->alpha = (DATA8 *)(im->pixels + (im->stride * h));
243 _evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace)
245 Soft16_Image *im = (Soft16_Image *) ie_dst;
247 /* FIXME: handle colorspace */
249 memcpy(im->pixels, image_data, IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
251 memset(im->pixels, 0, IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
257 _evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst, int cspace)
259 /* FIXME: handle colorspace */
264 _evas_common_load_soft16_image_data_from_file(Image_Entry *ie)
266 Soft16_Image *im = (Soft16_Image *) ie;
268 if (im->pixels) return 0;
269 if (!im->source) return -1;
271 evas_cache_image_load_data(&im->source->cache_entry);
272 if (im->source->image.data)
276 evas_cache_image_surface_alloc(&im->cache_entry,
277 im->source->cache_entry.w,
278 im->source->cache_entry.h);
280 sp = im->source->image.data;
282 soft16_image_convert_from_rgba(im, sp);
284 soft16_image_convert_from_rgb(im, sp);
286 evas_cache_image_drop(&im->source->cache_entry);
293 /* soft16_image_new(int w, int h, int stride, int have_alpha, DATA16 *pixels, */
296 /* Soft16_Image *im; */
298 /* if (stride < 0) stride = _calc_stride(w); */
300 /* im = soft16_image_alloc(w, h, stride, have_alpha, copy); */
301 /* if (!im) return NULL; */
306 /* memcpy(im->pixels, pixels, IMG_BYTE_SIZE(stride, h, have_alpha)); */
309 /* im->pixels = pixels; */
310 /* if (have_alpha) im->alpha = (DATA8 *)(im->pixels + (stride * h)); */
317 _get_clip(const RGBA_Draw_Context *dc, const Soft16_Image *im,
318 Evas_Rectangle *clip)
322 clip->x = dc->clip.x;
323 clip->y = dc->clip.y;
324 clip->w = dc->clip.w;
325 clip->h = dc->clip.h;
336 if ((clip->x + clip->w) > im->cache_entry.w) clip->w = im->cache_entry.w - clip->x;
337 if ((clip->y + clip->h) > im->cache_entry.h) clip->h = im->cache_entry.h - clip->y;
343 clip->w = im->cache_entry.w;
344 clip->h = im->cache_entry.h;
349 _is_empty_rectangle(const Evas_Rectangle *r)
351 return (r->w < 1) || (r->h < 1);
355 _shrink(int *s_pos, int *s_size, int pos, int size)
366 d = size + pos - (*s_pos);
372 _soft16_adjust_areas(Evas_Rectangle *src,
373 int src_max_x, int src_max_y,
375 int dst_max_x, int dst_max_y,
376 Evas_Rectangle *dst_clip)
378 if (_is_empty_rectangle(src) ||
379 _is_empty_rectangle(dst) ||
380 _is_empty_rectangle(dst_clip))
384 _shrink(&dst_clip->x, &dst_clip->w, dst->x, dst->w);
385 _shrink(&dst_clip->y, &dst_clip->h, dst->y, dst->h);
386 if (_is_empty_rectangle(dst_clip)) return 0;
391 dst->x -= (src->x * dst->w) / src->w;
392 dst->w += (src->x * dst->w) / src->w;
396 if (src->x >= src_max_x) return 0;
397 if ((src->x + src->w) > src_max_x)
399 dst->w = (dst->w * (src_max_x - src->x)) / (src->w);
400 src->w = src_max_x - src->x;
402 if (dst->w <= 0) return 0;
403 if (src->w <= 0) return 0;
406 dst_clip->w += dst_clip->x;
409 if (dst_clip->w <= 0) return 0;
410 if (dst_clip->x >= dst_max_x) return 0;
412 _shrink(&dst_clip->x, &dst_clip->w, 0, dst_max_x);
413 if (dst_clip->w <= 0) return 0;
418 dst->y -= (src->y * dst->h) / src->h;
419 dst->h += (src->y * dst->h) / src->h;
423 if (src->y >= src_max_y) return 0;
424 if ((src->y + src->h) > src_max_y)
426 dst->h = (dst->h * (src_max_y - src->y)) / (src->h);
427 src->h = src_max_y - src->y;
429 if (dst->h <= 0) return 0;
430 if (src->h <= 0) return 0;
433 dst_clip->h += dst_clip->y;
436 if (dst_clip->h <= 0) return 0;
437 if (dst_clip->y >= dst_max_y) return 0;
439 _shrink(&dst_clip->y, &dst_clip->h, 0, dst_max_y);
440 if (dst_clip->h <= 0) return 0;
446 _soft16_image_draw_sampled_int(Soft16_Image *src, Soft16_Image *dst,
447 RGBA_Draw_Context *dc,
448 Evas_Rectangle sr, Evas_Rectangle dr)
452 if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
454 if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
457 _get_clip(dc, dst, &cr);
458 if (!_soft16_adjust_areas(&sr, src->cache_entry.w, src->cache_entry.h, &dr, dst->cache_entry.w, dst->cache_entry.h, &cr))
461 if ((dr.w == sr.w) && (dr.h == sr.h))
462 soft16_image_draw_unscaled(src, dst, dc, sr, dr, cr);
464 soft16_image_draw_scaled_sampled(src, dst, dc, sr, dr, cr);
468 soft16_image_draw(Soft16_Image *src, Soft16_Image *dst,
469 RGBA_Draw_Context *dc,
470 int src_region_x, int src_region_y,
471 int src_region_w, int src_region_h,
472 int dst_region_x, int dst_region_y,
473 int dst_region_w, int dst_region_h,
476 Evas_Rectangle sr, dr;
479 struct RGBA_Draw_Context_clip clip_bkp;
482 /* handle cutouts here! */
488 if (_is_empty_rectangle(&dr)) return;
489 if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
497 if (_is_empty_rectangle(&sr)) return;
498 if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
501 /* no cutouts - cut right to the chase */
502 if (!dc->cutout.rects)
504 _soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
508 /* save out clip info */
510 evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
511 evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
512 /* our clip is 0 size.. abort */
513 if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
518 rects = evas_common_draw_context_apply_cutouts(dc);
519 for (i = 0; i < rects->active; i++)
521 r = rects->rects + i;
522 evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
523 _soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
525 evas_common_draw_context_apply_clear_cutouts(rects);
530 soft16_image_alpha_set(Soft16_Image *im, int have_alpha)
532 Soft16_Image *new_im;
534 if (im->cache_entry.flags.alpha == have_alpha) return im;
536 new_im = (Soft16_Image *) evas_cache_image_alone(&im->cache_entry);
538 new_im->cache_entry.flags.alpha = have_alpha;
540 if (im->cache_entry.w > 0
541 && im->cache_entry.h)
542 new_im = (Soft16_Image *) evas_cache_image_size_set(&new_im->cache_entry, im->cache_entry.w, im->cache_entry.h);
548 /* soft16_image_size_set(Soft16_Image *old_im, int w, int h) */
550 /* Soft16_Image *new_im; */
551 /* DATA16 *dp, *sp; */
552 /* int i, cw, ch, ew; */
554 /* if ((old_im->cache_entry.w == w) && (old_im->cache_entry.h == h)) return old_im; */
556 /* new_im = soft16_image_new(w, h, -1, old_im->flags.have_alpha, NULL, 1); */
558 /* if (old_im->cache_entry.w < new_im->cache_entry.w) */
559 /* cw = old_im->cache_entry.w; */
561 /* cw = new_im->cache_entry.w; */
563 /* ew = new_im->cache_entry.w - cw; */
565 /* if (old_im->cache_entry.h < new_im->cache_entry.h) */
566 /* ch = old_im->cache_entry.h; */
568 /* ch = new_im->cache_entry.h; */
570 /* dp = new_im->pixels; */
571 /* sp = old_im->pixels; */
572 /* for (i = 0; i < ch; i++) */
574 /* memcpy(dp, sp, cw * sizeof(DATA16)); */
575 /* if (ew > 0) memset(dp, 0, ew * sizeof(DATA16)); */
577 /* dp += new_im->stride; */
578 /* sp += old_im->stride; */
581 /* if (old_im->flags.have_alpha) */
583 /* DATA8 *dp, *sp; */
585 /* dp = new_im->alpha; */
586 /* sp = old_im->alpha; */
587 /* for (i = 0; i < ch; i++) */
589 /* memcpy(dp, sp, cw * sizeof(DATA8)); */
590 /* if (ew > 0) memset(dp, 0, ew * sizeof(DATA8)); */
592 /* dp += new_im->stride; */
593 /* sp += old_im->stride; */
597 /* evas_cache_image_drop(&old_im->cache_entry); */