2008-03-14 09:49:49 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h" /* so that EAPI in Eet.h is correctly defined */
|
|
|
|
#endif
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2013-08-28 01:16:48 -07:00
|
|
|
#ifdef HAVE_SYS_MMAN_H
|
|
|
|
# include <sys/mman.h>
|
|
|
|
#endif
|
|
|
|
|
2004-01-17 23:55:14 -08:00
|
|
|
#ifdef BUILD_LOADER_EET
|
2008-03-14 09:49:49 -07:00
|
|
|
# include <Eet.h>
|
2004-01-17 23:55:14 -08:00
|
|
|
#endif
|
|
|
|
|
2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2008-03-14 09:49:49 -07:00
|
|
|
#include "evas_private.h"
|
2008-07-19 11:32:32 -07:00
|
|
|
#include "evas_image_private.h"
|
2008-07-10 15:53:33 -07:00
|
|
|
#include "evas_convert_yuv.h"
|
2012-10-11 23:36:06 -07:00
|
|
|
//#include "evas_cs.h"
|
2008-03-14 09:49:49 -07:00
|
|
|
|
2004-05-02 01:41:11 -07:00
|
|
|
#ifdef HAVE_VALGRIND
|
2008-03-14 09:49:49 -07:00
|
|
|
# include <memcheck.h>
|
2004-05-02 01:41:11 -07:00
|
|
|
#endif
|
|
|
|
|
2012-02-08 04:08:41 -08:00
|
|
|
//#define SURFDBG 1
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
static Evas_Cache_Image * eci = NULL;
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
2012-11-27 10:23:25 -08:00
|
|
|
#define EVAS_CSERVE2_SCALE_CACHE_SIZE (4 * 1024 * 1024)
|
2012-05-03 14:01:31 -07:00
|
|
|
static Evas_Cache2 * eci2 = NULL;
|
|
|
|
#endif
|
2007-07-16 00:25:35 -07:00
|
|
|
static int reference = 0;
|
2015-08-17 19:27:17 -07:00
|
|
|
static int evas_image_no_mmap = -1;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
/* static RGBA_Image *evas_rgba_line_buffer = NULL; */
|
2005-12-03 01:27:53 -08:00
|
|
|
|
|
|
|
#define EVAS_RGBA_LINE_BUFFER_MIN_LEN 256
|
2006-09-30 03:18:37 -07:00
|
|
|
#define EVAS_RGBA_LINE_BUFFER_MAX_LEN 2048
|
2005-12-03 01:27:53 -08:00
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
/* static RGBA_Image *evas_alpha_line_buffer = NULL; */
|
2006-05-02 00:28:49 -07:00
|
|
|
|
|
|
|
#define EVAS_ALPHA_LINE_BUFFER_MIN_LEN 256
|
2006-09-30 03:18:37 -07:00
|
|
|
#define EVAS_ALPHA_LINE_BUFFER_MAX_LEN 2048
|
2006-05-02 00:28:49 -07:00
|
|
|
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
static Image_Entry *_evas_common_rgba_image_new(void);
|
|
|
|
static void _evas_common_rgba_image_delete(Image_Entry *ie);
|
|
|
|
|
2010-09-18 16:16:25 -07:00
|
|
|
static int _evas_common_rgba_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h);
|
2008-04-11 17:32:30 -07:00
|
|
|
static void _evas_common_rgba_image_surface_delete(Image_Entry *ie);
|
2008-06-03 02:09:39 -07:00
|
|
|
static DATA32 *_evas_common_rgba_image_surface_pixels(Image_Entry *ie);
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
static void _evas_common_rgba_image_unload(Image_Entry *im);
|
|
|
|
|
2010-09-18 16:16:25 -07:00
|
|
|
static void _evas_common_rgba_image_dirty_region(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
static int _evas_common_rgba_image_ram_usage(Image_Entry *ie);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
/* Only called when references > 0. Need to provide a fresh copie of im. */
|
|
|
|
/* The destination surface does have a surface, but no allocated pixel data. */
|
2008-04-11 17:32:30 -07:00
|
|
|
static int _evas_common_rgba_image_dirty(Image_Entry* dst, const Image_Entry* src);
|
|
|
|
|
2009-12-21 07:52:12 -08:00
|
|
|
#if 0
|
2008-04-11 17:32:30 -07:00
|
|
|
static void
|
|
|
|
_evas_common_rgba_image_debug(const char* context, Image_Entry *eim)
|
|
|
|
{
|
2009-10-22 08:22:22 -07:00
|
|
|
DBG("%p = [%s] {%s,%s} %i [%i|%i]", eim, context, eim->file, eim->key, eim->references, eim->w, eim->h);
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
2009-12-21 07:52:12 -08:00
|
|
|
#endif
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
static const Evas_Cache_Image_Func _evas_common_image_func =
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_common_rgba_image_new,
|
|
|
|
_evas_common_rgba_image_delete,
|
|
|
|
_evas_common_rgba_image_surface_alloc,
|
|
|
|
_evas_common_rgba_image_surface_delete,
|
2008-06-03 02:09:39 -07:00
|
|
|
_evas_common_rgba_image_surface_pixels,
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_common_load_rgba_image_module_from_file,
|
|
|
|
_evas_common_rgba_image_unload,
|
|
|
|
_evas_common_rgba_image_dirty_region,
|
|
|
|
_evas_common_rgba_image_dirty,
|
|
|
|
evas_common_rgba_image_size_set,
|
|
|
|
evas_common_rgba_image_from_copied_data,
|
|
|
|
evas_common_rgba_image_from_data,
|
|
|
|
evas_common_rgba_image_colorspace_set,
|
|
|
|
evas_common_load_rgba_image_data_from_file,
|
|
|
|
_evas_common_rgba_image_ram_usage,
|
|
|
|
/* _evas_common_rgba_image_debug */
|
|
|
|
NULL
|
2007-07-16 00:25:35 -07:00
|
|
|
};
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
static const Evas_Cache2_Image_Func _evas_common_image_func2 =
|
|
|
|
{
|
|
|
|
// _evas_common_rgba_image_new,
|
|
|
|
// _evas_common_rgba_image_delete,
|
|
|
|
_evas_common_rgba_image_surface_alloc,
|
|
|
|
_evas_common_rgba_image_surface_delete,
|
|
|
|
_evas_common_rgba_image_surface_pixels,
|
|
|
|
// evas_common_load_rgba_image_module_from_file,
|
|
|
|
// _evas_common_rgba_image_unload,
|
|
|
|
NULL, // _evas_common_rgba_image_dirty_region,
|
|
|
|
NULL, // _evas_common_rgba_image_dirty,
|
|
|
|
evas_common_rgba_image_size_set,
|
|
|
|
evas_common_rgba_image_from_copied_data,
|
|
|
|
evas_common_rgba_image_from_data,
|
|
|
|
NULL, // evas_common_rgba_image_colorspace_set,
|
|
|
|
// evas_common_load_rgba_image_data_from_file,
|
|
|
|
_evas_common_rgba_image_ram_usage,
|
|
|
|
/* _evas_common_rgba_image_debug */
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2016-03-22 21:33:08 -07:00
|
|
|
EAPI int
|
2014-06-30 01:13:51 -07:00
|
|
|
_evas_common_rgba_image_surface_size(unsigned int w, unsigned int h,
|
|
|
|
Evas_Colorspace cspace,
|
|
|
|
/* inout */ int *l, int *r, int *t, int *b)
|
2013-08-28 01:16:48 -07:00
|
|
|
{
|
2016-08-29 01:35:21 -07:00
|
|
|
#ifndef PAGE_SIZE
|
|
|
|
# define PAGE_SIZE (4 * 1024)
|
|
|
|
#endif
|
2014-01-05 05:44:50 -08:00
|
|
|
#define HUGE_PAGE_SIZE (2 * 1024 * 1024)
|
2014-01-03 00:53:51 -08:00
|
|
|
#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32))
|
2013-08-28 01:16:48 -07:00
|
|
|
# define ALIGN_TO_PAGE(Siz) (((Siz / PAGE_SIZE) + (Siz % PAGE_SIZE ? 1 : 0)) * PAGE_SIZE)
|
|
|
|
#else
|
|
|
|
# define ALIGN_TO_PAGE(Siz) Siz
|
|
|
|
#endif
|
2014-06-30 01:13:51 -07:00
|
|
|
|
|
|
|
int siz, block_size = 8;
|
|
|
|
Eina_Bool reset_borders = EINA_TRUE;
|
2013-08-28 01:16:48 -07:00
|
|
|
|
2015-08-17 19:27:17 -07:00
|
|
|
if (EINA_UNLIKELY(evas_image_no_mmap == -1))
|
|
|
|
{
|
|
|
|
const char *s = getenv("EVAS_IMAGE_NO_MMAP");
|
|
|
|
evas_image_no_mmap = s && (atoi(s));
|
|
|
|
if (evas_image_no_mmap)
|
|
|
|
WRN("EVAS_IMAGE_NO_MMAP is set, use this only for debugging purposes!");
|
|
|
|
}
|
|
|
|
|
2014-03-16 23:19:47 -07:00
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_GRY8: siz = w * h * sizeof(DATA8); break;
|
2014-03-20 18:48:04 -07:00
|
|
|
case EVAS_COLORSPACE_AGRY88: siz = w * h * sizeof(DATA16); break;
|
2014-06-30 01:13:51 -07:00
|
|
|
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
|
2014-06-29 23:10:07 -07:00
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
|
2014-07-07 04:14:02 -07:00
|
|
|
case EVAS_COLORSPACE_ETC1_ALPHA:
|
2014-06-30 01:13:51 -07:00
|
|
|
block_size = 16;
|
|
|
|
// fallthrough
|
2014-03-17 03:31:36 -07:00
|
|
|
case EVAS_COLORSPACE_ETC1:
|
2014-04-24 22:51:42 -07:00
|
|
|
case EVAS_COLORSPACE_RGB8_ETC2:
|
2014-06-29 23:10:07 -07:00
|
|
|
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
|
2014-06-30 01:13:51 -07:00
|
|
|
reset_borders = EINA_FALSE;
|
|
|
|
if (l && r && t && b)
|
|
|
|
{
|
|
|
|
w += *l + *r;
|
|
|
|
h += *t + *b;
|
|
|
|
}
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(!(w & 0x3) && !(h & 0x3), 0);
|
|
|
|
siz = (w >> 2) * (h >> 2) * block_size;
|
|
|
|
break;
|
2014-03-16 23:19:47 -07:00
|
|
|
default:
|
2014-04-02 00:40:59 -07:00
|
|
|
case EVAS_COLORSPACE_ARGB8888: siz = w * h * sizeof(DATA32); break;
|
2014-03-16 23:19:47 -07:00
|
|
|
}
|
2013-08-28 01:16:48 -07:00
|
|
|
|
2014-06-30 01:13:51 -07:00
|
|
|
if (reset_borders)
|
|
|
|
{
|
|
|
|
if (l) *l = 0;
|
|
|
|
if (r) *r = 0;
|
|
|
|
if (t) *t = 0;
|
|
|
|
if (b) *b = 0;
|
|
|
|
}
|
|
|
|
|
2015-08-17 19:27:17 -07:00
|
|
|
if ((siz < PAGE_SIZE) || evas_image_no_mmap)
|
|
|
|
return siz;
|
2013-08-28 01:16:48 -07:00
|
|
|
|
|
|
|
return ALIGN_TO_PAGE(siz);
|
|
|
|
|
|
|
|
#undef ALIGN_TO_PAGE
|
|
|
|
}
|
|
|
|
|
2016-09-02 01:55:33 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
_evas_common_rgba_image_plane_get(const RGBA_Image *im, int plane, Eina_Slice *slice)
|
|
|
|
{
|
2016-12-15 11:27:54 -08:00
|
|
|
unsigned char **csdata = NULL;
|
2016-09-02 01:55:33 -07:00
|
|
|
Evas_Colorspace cs;
|
2016-12-15 11:28:17 -08:00
|
|
|
size_t w, h;
|
2016-09-02 01:55:33 -07:00
|
|
|
|
|
|
|
if (!im || !slice) return EINA_FALSE;
|
|
|
|
cs = im->cache_entry.space;
|
|
|
|
w = im->cache_entry.w;
|
|
|
|
h = im->cache_entry.h;
|
|
|
|
|
|
|
|
switch (cs)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
|
|
|
if (!im->cs.data)
|
|
|
|
return EINA_FALSE;
|
|
|
|
csdata = im->cs.data;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (!im->image.data)
|
|
|
|
return EINA_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (cs)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
if (plane != 0) return EINA_FALSE;
|
|
|
|
slice->len = w * h * 4;
|
|
|
|
slice->mem = im->image.data;
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
|
|
|
if (plane != 0) return EINA_FALSE;
|
|
|
|
slice->len = w * h * 2;
|
|
|
|
slice->mem = im->image.data;
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
case EVAS_COLORSPACE_GRY8:
|
|
|
|
if (plane != 0) return EINA_FALSE;
|
|
|
|
slice->len = w * h;
|
|
|
|
slice->mem = im->image.data;
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
case EVAS_COLORSPACE_RGB565_A5P:
|
|
|
|
if (plane == 0)
|
|
|
|
{
|
|
|
|
slice->mem = im->image.data;
|
|
|
|
slice->len = w * h * 2;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (plane == 1)
|
|
|
|
{
|
|
|
|
slice->mem = im->image.data8 + (w * h * 2);
|
|
|
|
slice->len = w * h;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
2016-09-04 21:53:00 -07:00
|
|
|
// YUV, assume contiguous memory within a plane - padding ok
|
|
|
|
// 1 plane
|
2016-09-02 01:55:33 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
|
|
|
if (plane != 0) return EINA_FALSE;
|
|
|
|
slice->mem = csdata[0];
|
2016-12-15 11:28:17 -08:00
|
|
|
slice->len = (h > 1) ? ((csdata[1] - csdata[0]) * h * 2) : (w * 2);
|
2016-09-02 01:55:33 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
// 2 planes
|
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
|
|
|
if (plane == 0)
|
|
|
|
{
|
|
|
|
slice->mem = csdata[0];
|
2016-12-15 11:28:17 -08:00
|
|
|
slice->len = (h > 1) ? ((csdata[1] - csdata[0]) * h) : w;
|
2016-09-02 01:55:33 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (plane == 1)
|
|
|
|
{
|
|
|
|
slice->mem = csdata[h];
|
2016-12-15 11:28:17 -08:00
|
|
|
slice->len = (h > 1) ? ((csdata[h+1] - csdata[h]) * h / 2) : w / 2;
|
2016-09-02 01:55:33 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
// 3 planes
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
if (plane == 0)
|
|
|
|
{
|
|
|
|
slice->mem = csdata[0];
|
2016-12-15 11:28:17 -08:00
|
|
|
slice->len = (h > 1) ? ((csdata[1] - csdata[0]) * h) : w;
|
2016-09-02 01:55:33 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (plane == 1)
|
|
|
|
{
|
|
|
|
slice->mem = csdata[h];
|
2016-12-15 11:28:17 -08:00
|
|
|
slice->len = (h > 1) ? ((csdata[h+1] - csdata[h]) * h / 2) : w / 2;
|
2016-09-02 01:55:33 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (plane == 2)
|
|
|
|
{
|
2016-09-04 21:53:00 -07:00
|
|
|
slice->mem = csdata[h + h / 2];
|
2016-12-15 11:28:17 -08:00
|
|
|
slice->len = (h > 1) ? ((csdata[h+h/2+1] - csdata[h+h/2]) * h / 2) : w / 2;
|
2016-09-02 01:55:33 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
// ETC1/2 RGB, S3TC RGB
|
|
|
|
case EVAS_COLORSPACE_ETC1:
|
|
|
|
case EVAS_COLORSPACE_RGB8_ETC2:
|
|
|
|
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
|
|
|
|
if (plane != 0) return EINA_FALSE;
|
|
|
|
slice->mem = im->image.data;
|
|
|
|
slice->len = (w * h * 8) / 16;
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
// ETC2 ARGB, S3TC ARGB
|
|
|
|
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
|
|
|
|
if (plane != 0) return EINA_FALSE;
|
|
|
|
slice->mem = im->image.data;
|
|
|
|
slice->len = (w * h * 16) / 16;
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
// ETC1+Alpha
|
|
|
|
case EVAS_COLORSPACE_ETC1_ALPHA:
|
|
|
|
if (plane == 0)
|
|
|
|
{
|
|
|
|
slice->mem = im->image.data;
|
|
|
|
slice->len = (w * h * 8) / 16;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (plane == 1)
|
|
|
|
{
|
|
|
|
slice->mem = im->image.data8 + (w * h * 8) / 16;
|
|
|
|
slice->len = (w * h * 8) / 16;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-22 21:33:08 -07:00
|
|
|
EAPI int
|
|
|
|
_evas_common_rgba_image_data_offset(int rx, int ry, int rw, int rh, int plane, const RGBA_Image *im)
|
|
|
|
{
|
|
|
|
// note: no stride support
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(im, -1);
|
|
|
|
|
|
|
|
const Image_Entry *ie = &im->cache_entry;
|
|
|
|
|
|
|
|
if ((rx < 0) || (ry < 0) || (rw < 0) || (rh < 0))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (((rx + rw) > (int) ie->w) || ((ry + rh) > (int) ie->h))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
switch (ie->space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
return (ry * ie->w + rx) * 4;
|
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
|
|
|
return (ry * ie->w + rx) * 2;
|
|
|
|
case EVAS_COLORSPACE_GRY8:
|
|
|
|
return ry * ie->w + rx;
|
|
|
|
case EVAS_COLORSPACE_RGB565_A5P:
|
|
|
|
if (plane == 0)
|
|
|
|
return (ry * ie->w + rx) * 2;
|
|
|
|
else if (plane == 1)
|
|
|
|
return ry * ie->w + rx + (ie->w * ie->h) * 2;
|
|
|
|
else return -1;
|
|
|
|
|
|
|
|
// YUV
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
|
|
|
if ((rx & 1) || (rw & 1))
|
|
|
|
return -1;
|
|
|
|
if (plane == 0)
|
|
|
|
return ry * ie->w + rx;
|
|
|
|
else if (plane == 1)
|
|
|
|
return (ry * ie->w) / 2 + rx + ie->w * ie->h;
|
|
|
|
else return -1;
|
|
|
|
|
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
|
|
|
if ((rx & 1) || (ry & 1) || (rw & 1) || (rh & 1))
|
|
|
|
return -1;
|
|
|
|
if (plane == 0)
|
|
|
|
return ry * ie->w + rx;
|
|
|
|
else if (plane == 1)
|
|
|
|
return (ry * ie->w + rx) / 2 + ie->w * ie->h;
|
|
|
|
else return -1;
|
|
|
|
|
|
|
|
// ETC1/2 RGB, S3TC RGB
|
|
|
|
case EVAS_COLORSPACE_ETC1:
|
|
|
|
case EVAS_COLORSPACE_RGB8_ETC2:
|
|
|
|
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
|
|
|
|
if ((rx & 3) || (ry & 3) || (rw & 3) || (rh & 3))
|
|
|
|
return -1;
|
|
|
|
return (ry * ie->w + rx) * 8 / 16;
|
|
|
|
|
|
|
|
// ETC2 ARGB, S3TC ARGB
|
|
|
|
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
|
|
|
|
if ((rx & 3) || (ry & 3) || (rw & 3) || (rh & 3))
|
|
|
|
return -1;
|
|
|
|
return (ry * ie->w + rx) * 16 / 16;
|
|
|
|
|
|
|
|
// ETC1+Alpha
|
|
|
|
case EVAS_COLORSPACE_ETC1_ALPHA:
|
|
|
|
if ((rx & 3) || (ry & 3) || (rw & 3) || (rh & 3))
|
|
|
|
return -1;
|
|
|
|
if (plane == 0)
|
|
|
|
return (ry * ie->w + rx) * 8 / 16;
|
|
|
|
else if (plane == 1)
|
|
|
|
return (ry * ie->w + rx) * 8 / 16 + (ie->w * ie->h) * 8 / 16;
|
|
|
|
else return -1;
|
|
|
|
|
|
|
|
default:
|
|
|
|
CRI("unknown colorspace %d", ie->space);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-28 01:16:48 -07:00
|
|
|
static void *
|
2014-06-30 01:13:51 -07:00
|
|
|
_evas_common_rgba_image_surface_mmap(Image_Entry *ie, unsigned int w, unsigned int h,
|
|
|
|
/* inout */ int *pl, int *pr, int *pt, int *pb)
|
2013-08-28 01:16:48 -07:00
|
|
|
{
|
2014-04-02 00:40:59 -07:00
|
|
|
int siz;
|
2014-01-05 17:39:34 -08:00
|
|
|
#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32))
|
2014-01-05 05:44:50 -08:00
|
|
|
void *r = MAP_FAILED;
|
2014-01-05 17:39:34 -08:00
|
|
|
#endif
|
2013-08-28 01:16:48 -07:00
|
|
|
|
2014-06-30 01:13:51 -07:00
|
|
|
siz = _evas_common_rgba_image_surface_size(w, h, ie->space, pl, pr, pt, pb);
|
2013-08-28 01:16:48 -07:00
|
|
|
|
2014-01-03 00:53:51 -08:00
|
|
|
#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32))
|
2013-08-28 17:54:17 -07:00
|
|
|
#ifndef MAP_HUGETLB
|
|
|
|
# define MAP_HUGETLB 0
|
|
|
|
#endif
|
2014-04-02 00:40:59 -07:00
|
|
|
if (siz < 0)
|
|
|
|
return NULL;
|
2013-08-28 17:54:17 -07:00
|
|
|
|
2015-08-17 19:27:17 -07:00
|
|
|
if ((siz < PAGE_SIZE) || evas_image_no_mmap)
|
2013-08-28 01:16:48 -07:00
|
|
|
return malloc(siz);
|
|
|
|
|
2014-01-05 05:44:50 -08:00
|
|
|
if (siz > ((HUGE_PAGE_SIZE * 75) / 100))
|
2014-03-15 03:57:59 -07:00
|
|
|
r = mmap(NULL, siz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_HUGETLB, -1, 0);
|
2013-08-28 01:16:48 -07:00
|
|
|
if (r == MAP_FAILED)
|
2014-03-15 03:57:59 -07:00
|
|
|
r = mmap(NULL, siz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
2013-08-28 01:16:48 -07:00
|
|
|
if (r == MAP_FAILED)
|
|
|
|
r = NULL;
|
|
|
|
|
|
|
|
return r;
|
|
|
|
#else
|
|
|
|
return malloc(siz);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-10-30 00:41:32 -07:00
|
|
|
void
|
|
|
|
evas_common_rgba_image_surface_munmap(void *data, unsigned int w, unsigned int h, Evas_Colorspace cspace)
|
2013-08-28 01:16:48 -07:00
|
|
|
{
|
2014-04-02 00:40:59 -07:00
|
|
|
if (!data) return ;
|
2014-01-03 00:53:51 -08:00
|
|
|
#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32))
|
2013-08-28 01:16:48 -07:00
|
|
|
size_t siz;
|
|
|
|
|
2014-06-30 01:13:51 -07:00
|
|
|
siz = _evas_common_rgba_image_surface_size(w, h, cspace, NULL, NULL, NULL, NULL);
|
2015-08-17 19:27:17 -07:00
|
|
|
if ((siz < PAGE_SIZE) || evas_image_no_mmap)
|
2013-08-28 01:16:48 -07:00
|
|
|
free(data);
|
|
|
|
else
|
|
|
|
munmap(data, siz);
|
|
|
|
#else
|
2014-05-29 03:54:22 -07:00
|
|
|
(void)w;
|
|
|
|
(void)h;
|
|
|
|
(void)cspace;
|
2013-08-28 01:16:48 -07:00
|
|
|
free(data);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_image_init(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2007-07-16 00:25:35 -07:00
|
|
|
if (!eci)
|
|
|
|
eci = evas_cache_image_init(&_evas_common_image_func);
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (!eci2)
|
|
|
|
eci2 = evas_cache2_init(&_evas_common_image_func2);
|
|
|
|
#endif
|
2007-07-16 00:25:35 -07:00
|
|
|
reference++;
|
2009-10-22 08:22:22 -07:00
|
|
|
//// ERR("REF++=%i", reference);
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_scalecache_init();
|
2004-01-17 08:27:58 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2004-01-17 08:27:58 -08:00
|
|
|
evas_common_image_shutdown(void)
|
|
|
|
{
|
2007-07-16 00:25:35 -07:00
|
|
|
if (--reference == 0)
|
|
|
|
{
|
2007-07-22 09:25:24 -07:00
|
|
|
//// printf("REF--=%i\n", reference);
|
|
|
|
// DISABLE for now - something wrong with cache shutdown freeing things
|
|
|
|
// still in use - rage_thumb segv's now.
|
2008-07-19 10:40:52 -07:00
|
|
|
//
|
2007-07-22 09:25:24 -07:00
|
|
|
// actually - i think i see it. cache ref goes to 0 (and thus gets freed)
|
|
|
|
// because in eng_setup() when a buffer changes size it is FIRST freed
|
|
|
|
// THEN allocated again - thus brignhjing ref to 0 then back to 1 immediately
|
|
|
|
// where it should stay at 1. - see evas_engine.c in the buffer enigne for
|
|
|
|
// example. eng_output_free() is called BEFORE _output_setup(). although this
|
|
|
|
// is only a SIGNE of the problem. we can patch this up with either freeing
|
2008-07-19 10:40:52 -07:00
|
|
|
// after the setup (so we just pt a ref of 2 then back to 1), or just
|
2007-07-22 09:25:24 -07:00
|
|
|
// evas_common_image_init() at the start and evas_common_image_shutdown()
|
|
|
|
// after it all. really ref 0 should only be reached when no more canvases
|
|
|
|
// with no more objects exist anywhere.
|
2009-01-22 16:08:11 -08:00
|
|
|
|
|
|
|
// ENABLE IT AGAIN, hope it is fixed. Gustavo @ January 22nd, 2009.
|
|
|
|
evas_cache_image_shutdown(eci);
|
|
|
|
eci = NULL;
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
evas_cache2_shutdown(eci2);
|
|
|
|
eci2 = NULL;
|
|
|
|
#endif
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_scalecache_shutdown();
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2010-04-12 01:23:53 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_image_image_all_unload(void)
|
|
|
|
{
|
2010-12-03 01:36:17 -08:00
|
|
|
evas_common_rgba_image_scalecache_dump();
|
2010-04-12 01:23:53 -07:00
|
|
|
evas_cache_image_unload_all(eci);
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
static Image_Entry *
|
|
|
|
_evas_common_rgba_image_new(void)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
RGBA_Image *im;
|
|
|
|
|
|
|
|
im = calloc(1, sizeof(RGBA_Image));
|
|
|
|
if (!im) return NULL;
|
|
|
|
im->flags = RGBA_IMAGE_NOTHING;
|
2010-05-21 00:10:45 -07:00
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_rgba_image_scalecache_init(&im->cache_entry);
|
2011-12-23 03:50:29 -08:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
return &im->cache_entry;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_common_rgba_image_delete(Image_Entry *ie)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2011-04-20 23:21:51 -07:00
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2015-08-03 18:47:38 -07:00
|
|
|
evas_common_rgba_pending_unloads_remove(ie);
|
2009-03-26 18:48:58 -07:00
|
|
|
#ifdef BUILD_PIPE_RENDER
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_common_pipe_free(im);
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2013-05-07 23:37:37 -07:00
|
|
|
if (ie->loader_data)
|
|
|
|
{
|
|
|
|
Evas_Image_Load_Func *evas_image_load_func = NULL;
|
|
|
|
|
|
|
|
evas_image_load_func = ie->info.loader;
|
|
|
|
if (evas_image_load_func)
|
|
|
|
evas_image_load_func->file_close(ie->loader_data);
|
|
|
|
ie->loader_data = NULL;
|
|
|
|
}
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_rgba_image_scalecache_shutdown(&im->cache_entry);
|
2008-06-03 02:09:39 -07:00
|
|
|
if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module);
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (ie->data1)
|
|
|
|
ERR("Shouldn't reach this point since we are using cache2: '%s' '%s'",
|
|
|
|
ie->file, ie->key);
|
|
|
|
// if (ie->data1) evas_cserve2_image_free(ie);
|
|
|
|
#endif
|
2011-12-23 03:50:29 -08:00
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
if (ie->animated.frames)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
|
|
|
Image_Entry_Frame *frame;
|
2013-10-30 02:08:10 -07:00
|
|
|
|
|
|
|
EINA_LIST_FREE(ie->animated.frames, frame)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
2013-10-30 02:08:10 -07:00
|
|
|
if (frame->data) free(frame->data);
|
|
|
|
if (frame->info) free(frame->info);
|
|
|
|
free(frame);
|
2011-08-10 23:04:08 -07:00
|
|
|
}
|
|
|
|
}
|
2013-05-07 23:37:37 -07:00
|
|
|
if (ie->f && !ie->flags.given_mmap) eina_file_close(ie->f);
|
2012-02-08 03:22:09 -08:00
|
|
|
free(im);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2012-02-08 04:08:41 -08:00
|
|
|
static void
|
2015-07-07 05:29:31 -07:00
|
|
|
evas_common_rgba_image_unload_real(Image_Entry *ie)
|
2009-03-26 23:06:45 -07:00
|
|
|
{
|
|
|
|
RGBA_Image *im = (RGBA_Image *) ie;
|
|
|
|
|
|
|
|
ie->flags.loaded = 0;
|
|
|
|
|
|
|
|
if ((im->cs.data) && (im->image.data))
|
|
|
|
{
|
|
|
|
if (im->cs.data != im->image.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (im->cs.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
}
|
|
|
|
im->cs.data = NULL;
|
|
|
|
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (ie->data1)
|
|
|
|
{
|
|
|
|
ERR("Shouldn't reach this point since we are using cache2.");
|
|
|
|
// evas_cserve2_image_unload(ie);
|
|
|
|
// im->image.data = NULL;
|
|
|
|
// ie->allocated.w = 0;
|
|
|
|
// ie->allocated.h = 0;
|
|
|
|
// ie->flags.loaded = 0;
|
|
|
|
ie->flags.preload_done = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-03-26 23:06:45 -07:00
|
|
|
if (im->image.data && !im->image.no_free)
|
2012-02-08 04:08:41 -08:00
|
|
|
{
|
2015-10-30 00:41:32 -07:00
|
|
|
evas_common_rgba_image_surface_munmap(im->image.data,
|
|
|
|
ie->allocated.w, ie->allocated.h,
|
|
|
|
ie->space);
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surfs = eina_list_remove(surfs, ie);
|
|
|
|
#endif
|
|
|
|
}
|
2009-03-26 23:06:45 -07:00
|
|
|
im->image.data = NULL;
|
|
|
|
ie->allocated.w = 0;
|
|
|
|
ie->allocated.h = 0;
|
2010-12-14 02:22:06 -08:00
|
|
|
ie->flags.loaded = 0;
|
2010-12-18 01:59:50 -08:00
|
|
|
ie->flags.preload_done = 0;
|
2015-07-08 20:04:39 -07:00
|
|
|
ie->need_unload = 0;
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surf_debug();
|
|
|
|
#endif
|
2009-03-26 23:06:45 -07:00
|
|
|
}
|
|
|
|
|
2015-07-07 05:29:31 -07:00
|
|
|
static Eina_List *pending_unloads = NULL;
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_pending_unloads_cleanup(void)
|
|
|
|
{
|
|
|
|
Image_Entry *ie;
|
2015-07-16 04:07:39 -07:00
|
|
|
Eina_List *l;
|
|
|
|
Eina_List *l_next;
|
2015-07-07 05:29:31 -07:00
|
|
|
|
2015-07-16 04:07:39 -07:00
|
|
|
EINA_LIST_FOREACH_SAFE(pending_unloads, l, l_next, ie)
|
2015-07-07 05:29:31 -07:00
|
|
|
{
|
2015-07-16 04:07:39 -07:00
|
|
|
if ((ie->need_unload) && (!ie->preload) && (!ie->flags.preload_done))
|
|
|
|
{
|
|
|
|
evas_common_rgba_image_unload_real(ie);
|
|
|
|
pending_unloads = eina_list_remove_list(pending_unloads, l);
|
|
|
|
}
|
2015-07-07 05:29:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_pending_unloads_remove(Image_Entry *ie)
|
|
|
|
{
|
2015-07-24 07:21:55 -07:00
|
|
|
if (!ie->need_unload) return;
|
|
|
|
ie->need_unload = 0;
|
2015-07-07 05:29:31 -07:00
|
|
|
pending_unloads = eina_list_remove(pending_unloads, ie);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_image_free(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
if (ie->references > 0) return;
|
|
|
|
evas_common_rgba_pending_unloads_remove(ie);
|
|
|
|
_evas_common_rgba_image_surface_delete(ie);
|
|
|
|
_evas_common_rgba_image_delete(ie);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SURFDBG
|
|
|
|
static Eina_List *surfs = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
surf_debug(void)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Image_Entry *ie;
|
|
|
|
RGBA_Image *im;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
printf("----SURFS----\n");
|
|
|
|
EINA_LIST_FOREACH(surfs, l, ie)
|
|
|
|
{
|
|
|
|
im = ie;
|
|
|
|
printf("%i - %p - %ix%i [%s][%s]\n",
|
|
|
|
i, im->image.data, ie->allocated.w, ie->allocated.h,
|
|
|
|
ie->file, ie->key
|
|
|
|
);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_image_unload(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
if (!ie->flags.loaded) return;
|
|
|
|
if ((!ie->info.module) && (!ie->data1)) return;
|
|
|
|
if (!ie->file && !ie->f) return;
|
|
|
|
if ((evas_cache_async_frozen_get() == 0) &&
|
|
|
|
(ie->references > 0))
|
|
|
|
{
|
|
|
|
if (!ie->need_unload)
|
|
|
|
{
|
|
|
|
pending_unloads = eina_list_append(pending_unloads, ie);
|
|
|
|
ie->need_unload = 1;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2015-07-25 11:02:06 -07:00
|
|
|
if (!ie->need_unload) evas_common_rgba_image_unload_real(ie);
|
2015-07-07 05:29:31 -07:00
|
|
|
}
|
|
|
|
|
2011-04-22 04:47:14 -07:00
|
|
|
void
|
|
|
|
_evas_common_rgba_image_post_surface(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_PIXMAN
|
2011-12-23 03:50:29 -08:00
|
|
|
# ifdef PIXMAN_IMAGE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
2013-01-15 22:32:34 -08:00
|
|
|
int w, h;
|
2014-01-09 19:47:27 -08:00
|
|
|
|
|
|
|
if (!im->image.data) return;
|
2011-04-22 04:47:14 -07:00
|
|
|
if (im->pixman.im) pixman_image_unref(im->pixman.im);
|
2013-01-15 22:32:34 -08:00
|
|
|
w = ie->allocated.w;
|
|
|
|
h = ie->allocated.h;
|
|
|
|
if ((w <= 0) || (h <= 0))
|
|
|
|
{
|
|
|
|
w = im->cache_entry.w;
|
|
|
|
h = im->cache_entry.h;
|
|
|
|
}
|
2011-04-22 04:47:14 -07:00
|
|
|
if (im->cache_entry.flags.alpha)
|
|
|
|
{
|
|
|
|
im->pixman.im = pixman_image_create_bits
|
|
|
|
(
|
2011-12-23 03:50:29 -08:00
|
|
|
// FIXME: endianess determines this
|
2011-04-22 04:47:14 -07:00
|
|
|
PIXMAN_a8r8g8b8,
|
2011-12-23 03:50:29 -08:00
|
|
|
// PIXMAN_b8g8r8a8,
|
2013-01-15 22:32:34 -08:00
|
|
|
w, h, im->image.data, w * 4);
|
2011-04-22 04:47:14 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
im->pixman.im = pixman_image_create_bits
|
|
|
|
(
|
2011-12-23 03:50:29 -08:00
|
|
|
// FIXME: endianess determines this
|
2011-04-22 04:47:14 -07:00
|
|
|
PIXMAN_x8r8g8b8,
|
|
|
|
// PIXMAN_b8g8r8x8,
|
2013-01-15 22:32:34 -08:00
|
|
|
w, h, im->image.data, w * 4);
|
2011-04-22 04:47:14 -07:00
|
|
|
}
|
2011-12-23 03:50:29 -08:00
|
|
|
# else
|
2012-01-18 15:34:05 -08:00
|
|
|
(void)ie;
|
2011-12-23 03:50:29 -08:00
|
|
|
# endif
|
2011-04-22 04:47:14 -07:00
|
|
|
#else
|
2012-01-18 15:34:05 -08:00
|
|
|
(void)ie;
|
2011-04-22 04:47:14 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
static int
|
2010-09-18 16:16:25 -07:00
|
|
|
_evas_common_rgba_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2014-06-30 01:13:51 -07:00
|
|
|
RGBA_Image *im = (RGBA_Image *) ie;
|
|
|
|
int l = 0, r = 0, t = 0, b = 0;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (ie->data1) return 0;
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2008-05-06 04:20:29 -07:00
|
|
|
if (im->image.no_free) return 0;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2012-02-08 04:08:41 -08:00
|
|
|
if (im->image.data)
|
|
|
|
{
|
2015-10-30 00:41:32 -07:00
|
|
|
evas_common_rgba_image_surface_munmap(im->image.data,
|
|
|
|
ie->allocated.w, ie->allocated.h,
|
|
|
|
ie->space);
|
2014-04-02 00:40:59 -07:00
|
|
|
im->image.data = NULL;
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surfs = eina_list_remove(surfs, ie);
|
2014-03-16 23:19:47 -07:00
|
|
|
#endif
|
2012-02-08 04:08:41 -08:00
|
|
|
}
|
2014-04-02 00:40:59 -07:00
|
|
|
|
2014-06-30 01:13:51 -07:00
|
|
|
l = ie->borders.l;
|
|
|
|
r = ie->borders.r;
|
|
|
|
t = ie->borders.t;
|
|
|
|
b = ie->borders.b;
|
|
|
|
im->image.data = _evas_common_rgba_image_surface_mmap(ie, w, h, &l, &r, &t, &b);
|
2010-08-21 06:52:25 -07:00
|
|
|
if (!im->image.data) return -1;
|
2014-06-30 01:13:51 -07:00
|
|
|
ie->borders.l = l;
|
|
|
|
ie->borders.r = r;
|
|
|
|
ie->borders.t = t;
|
|
|
|
ie->borders.b = b;
|
|
|
|
ie->allocated.w = w + l + r;
|
|
|
|
ie->allocated.h = h + t + b;
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surfs = eina_list_append(surfs, ie);
|
2014-03-16 23:19:47 -07:00
|
|
|
#endif
|
2008-04-11 17:32:30 -07:00
|
|
|
#ifdef HAVE_VALGRIND
|
2014-04-02 00:40:59 -07:00
|
|
|
int siz = 0;
|
2014-06-30 01:13:51 -07:00
|
|
|
siz = _evas_common_rgba_image_surface_size(w, h, ie->space, &l, &r, &t, &b);
|
2008-07-19 10:40:52 -07:00
|
|
|
# ifdef VALGRIND_MAKE_READABLE
|
2014-04-02 00:40:59 -07:00
|
|
|
if (siz > 0) VALGRIND_MAKE_READABLE(im->image.data, siz);
|
2008-07-19 10:40:52 -07:00
|
|
|
# else
|
|
|
|
# ifdef VALGRIND_MAKE_MEM_DEFINED
|
2014-04-02 00:40:59 -07:00
|
|
|
if (siz > 0) VALGRIND_MAKE_MEM_DEFINED(im->image.data, siz);
|
2008-07-19 10:40:52 -07:00
|
|
|
# endif
|
2008-05-18 20:29:54 -07:00
|
|
|
# endif
|
2008-04-11 17:32:30 -07:00
|
|
|
#endif
|
2011-04-22 04:47:14 -07:00
|
|
|
_evas_common_rgba_image_post_surface(ie);
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surf_debug();
|
|
|
|
#endif
|
2008-04-11 17:32:30 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_common_rgba_image_surface_delete(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
RGBA_Image *im = (RGBA_Image *) ie;
|
|
|
|
|
2011-04-22 04:47:14 -07:00
|
|
|
#ifdef HAVE_PIXMAN
|
2013-01-16 14:32:39 -08:00
|
|
|
# ifdef PIXMAN_IMAGE
|
2011-04-22 04:47:14 -07:00
|
|
|
if (im->pixman.im)
|
|
|
|
{
|
|
|
|
pixman_image_unref(im->pixman.im);
|
|
|
|
im->pixman.im = NULL;
|
|
|
|
}
|
2013-01-16 14:32:39 -08:00
|
|
|
# endif
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2010-04-12 20:00:29 -07:00
|
|
|
if (ie->file)
|
2010-10-07 16:46:42 -07:00
|
|
|
DBG("unload: [%p] %s %s", ie, ie->file, ie->key);
|
2008-04-11 17:32:30 -07:00
|
|
|
if ((im->cs.data) && (im->image.data))
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
if (im->cs.data != im->image.data)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (im->cs.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
}
|
|
|
|
im->cs.data = NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
if (im->image.data && !im->image.no_free)
|
2012-02-08 04:08:41 -08:00
|
|
|
{
|
2015-10-30 00:41:32 -07:00
|
|
|
evas_common_rgba_image_surface_munmap(im->image.data,
|
|
|
|
ie->allocated.w, ie->allocated.h,
|
|
|
|
ie->space);
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surfs = eina_list_remove(surfs, ie);
|
2013-01-16 14:32:39 -08:00
|
|
|
#endif
|
2012-02-08 04:08:41 -08:00
|
|
|
}
|
2012-05-03 14:01:31 -07:00
|
|
|
// #ifdef EVAS_CSERVE2
|
|
|
|
// else if (ie->data1)
|
|
|
|
// ERR("Shouldn't reach this point since we are using cache2.");
|
|
|
|
// // evas_cserve2_image_free(ie);
|
|
|
|
// #endif
|
2011-08-10 23:04:08 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im->image.data = NULL;
|
2010-12-14 02:22:06 -08:00
|
|
|
ie->allocated.w = 0;
|
|
|
|
ie->allocated.h = 0;
|
|
|
|
ie->flags.preload_done = 0;
|
|
|
|
ie->flags.loaded = 0;
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surf_debug();
|
2013-01-16 14:32:39 -08:00
|
|
|
#endif
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-04-12 01:23:53 -07:00
|
|
|
_evas_common_rgba_image_unload(Image_Entry *im)
|
2008-04-11 17:32:30 -07:00
|
|
|
{
|
2010-10-07 16:46:42 -07:00
|
|
|
// DBG("unload: [%p] %s %s", im, im->file, im->key);
|
2010-08-18 08:11:07 -07:00
|
|
|
evas_common_rgba_image_scalecache_dirty(im);
|
2010-04-12 01:23:53 -07:00
|
|
|
evas_common_rgba_image_unload(im);
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
_evas_common_rgba_image_dirty_region(Image_Entry* ie, unsigned int x EINA_UNUSED, unsigned int y EINA_UNUSED, unsigned int w EINA_UNUSED, unsigned int h EINA_UNUSED)
|
2008-04-11 17:32:30 -07:00
|
|
|
{
|
2008-04-15 08:20:53 -07:00
|
|
|
RGBA_Image *im = (RGBA_Image *) ie;
|
|
|
|
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
// if (ie->data1) evas_cserve2_image_free(ie);
|
|
|
|
if (ie->data1) ERR("Shouldn't reach this point since we are using cache2.");
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2008-04-15 08:20:53 -07:00
|
|
|
im->flags |= RGBA_IMAGE_IS_DIRTY;
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Only called when references > 0. Need to provide a fresh copie of im. */
|
|
|
|
static int
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_common_rgba_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
RGBA_Image *dst = (RGBA_Image *) ie_dst;
|
|
|
|
RGBA_Image *src = (RGBA_Image *) ie_src;
|
|
|
|
|
2010-04-12 20:00:29 -07:00
|
|
|
evas_common_rgba_image_scalecache_dirty((Image_Entry *)ie_src);
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_rgba_image_scalecache_dirty(ie_dst);
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_load_data(&src->cache_entry);
|
2013-10-26 05:09:17 -07:00
|
|
|
if (!evas_cache_image_pixels(ie_dst))
|
2009-05-01 00:11:07 -07:00
|
|
|
{
|
2013-10-26 05:09:17 -07:00
|
|
|
if (_evas_common_rgba_image_surface_alloc(&dst->cache_entry,
|
|
|
|
src->cache_entry.w, src->cache_entry.h))
|
|
|
|
{
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
2013-10-26 05:09:17 -07:00
|
|
|
// if (ie_src->data1) evas_cserve2_image_free((Image_Entry*) ie_src);
|
|
|
|
if (ie_src->data1) ERR("Shouldn't reach this point since we are using cache2.");
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2013-10-26 05:09:17 -07:00
|
|
|
return 1;
|
|
|
|
}
|
2009-05-01 00:11:07 -07:00
|
|
|
}
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
2012-10-16 01:57:18 -07:00
|
|
|
// if (ie_src->data1) evas_cserve2_image_free((Image_Entry*) ie_src);
|
|
|
|
if (ie_src->data1) ERR("Shouldn't reach this point since we are using cache2.");
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2007-10-27 21:01:56 -07:00
|
|
|
evas_common_image_colorspace_normalize(src);
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_common_image_colorspace_normalize(dst);
|
2008-04-11 17:32:30 -07:00
|
|
|
/* evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */
|
|
|
|
/* evas_common_cpu_end_opt(); */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
static int
|
|
|
|
_evas_common_rgba_image_ram_usage(Image_Entry *ie)
|
|
|
|
{
|
2011-04-20 23:21:51 -07:00
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
|
|
|
int size = sizeof(struct _RGBA_Image);
|
2011-12-23 03:50:29 -08:00
|
|
|
|
2011-04-20 23:21:51 -07:00
|
|
|
if (ie->cache_key) size += strlen(ie->cache_key);
|
|
|
|
if (ie->file) size += strlen(ie->file);
|
|
|
|
if (ie->key) size += strlen(ie->key);
|
2011-12-23 03:50:29 -08:00
|
|
|
|
2009-05-01 00:11:07 -07:00
|
|
|
if (im->image.data)
|
|
|
|
{
|
2012-10-16 01:57:18 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
2009-05-01 00:11:07 -07:00
|
|
|
if ((!im->image.no_free) || (ie->data1))
|
|
|
|
#else
|
|
|
|
if ((!im->image.no_free))
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2009-05-01 00:11:07 -07:00
|
|
|
size += im->cache_entry.w * im->cache_entry.h * sizeof(DATA32);
|
|
|
|
}
|
2009-03-26 00:14:08 -07:00
|
|
|
size += evas_common_rgba_image_scalecache_usage_get(&im->cache_entry);
|
|
|
|
return size;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
static DATA32 *
|
|
|
|
_evas_common_rgba_image_surface_pixels(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
RGBA_Image *im = (RGBA_Image *) ie;
|
|
|
|
|
|
|
|
return im->image.data;
|
|
|
|
}
|
|
|
|
|
2005-01-27 02:05:41 -08:00
|
|
|
#if 0
|
2005-01-26 08:42:31 -08:00
|
|
|
void
|
|
|
|
evas_common_image_surface_alpha_tiles_calc(RGBA_Surface *is, int tsize)
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
DATA32 *ptr;
|
|
|
|
|
|
|
|
if (is->spans) return;
|
2008-06-03 02:09:39 -07:00
|
|
|
if (!is->im->cache_entry.flags.alpha) return;
|
2005-01-26 08:42:31 -08:00
|
|
|
/* FIXME: dont handle alpha only images yet */
|
2014-03-16 23:19:47 -07:00
|
|
|
if (is->im->space != EVAS_COLORSPACE_GRY8) return;
|
2005-01-26 08:42:31 -08:00
|
|
|
if (tsize < 0) tsize = 0;
|
|
|
|
is->spans = calloc(1, sizeof(RGBA_Image_Span *) * is->h);
|
|
|
|
if (!is->spans) return;
|
|
|
|
ptr = is->data;
|
|
|
|
for (y = 0; y < is->h; y++)
|
|
|
|
{
|
|
|
|
RGBA_Image_Span *sp;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-01-26 08:42:31 -08:00
|
|
|
sp = NULL;
|
|
|
|
for (x = 0; x < is->w; x++)
|
|
|
|
{
|
|
|
|
DATA8 a;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-01-26 08:42:31 -08:00
|
|
|
a = A_VAL(ptr);
|
|
|
|
if (sp)
|
|
|
|
{
|
|
|
|
if (a == 0)
|
|
|
|
{
|
2008-10-17 04:23:18 -07:00
|
|
|
is->spans[y] = eina_inlist_append(is->spans[y], sp);
|
2005-01-26 08:42:31 -08:00
|
|
|
sp = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sp->w++;
|
|
|
|
if ((sp->v == 2) && (a != 255)) sp->v = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (a == 255)
|
|
|
|
{
|
|
|
|
sp = calloc(1, sizeof(RGBA_Image_Span));
|
|
|
|
sp->x = x;
|
|
|
|
sp->w = 1;
|
|
|
|
sp->v = 2;
|
|
|
|
}
|
|
|
|
else if (a > 0)
|
|
|
|
{
|
|
|
|
sp = calloc(1, sizeof(RGBA_Image_Span));
|
|
|
|
sp->x = x;
|
|
|
|
sp->w = 1;
|
|
|
|
sp->v = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
if (sp)
|
|
|
|
{
|
2008-10-17 04:23:18 -07:00
|
|
|
is->spans[y] = eina_inlist_append(is->spans[y], sp);
|
2005-01-26 08:42:31 -08:00
|
|
|
sp = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
#endif
|
2005-01-26 08:42:31 -08:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
/* EAPI void */
|
|
|
|
/* evas_common_image_surface_dealloc(RGBA_Surface *is) */
|
|
|
|
/* { */
|
|
|
|
/* if ((is->data) && (!is->no_free)) */
|
|
|
|
/* { */
|
2008-07-19 10:40:52 -07:00
|
|
|
/* free(is->data); */
|
|
|
|
/* is->data = NULL; */
|
2008-04-11 17:32:30 -07:00
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
static RGBA_Image *
|
2010-09-18 16:16:25 -07:00
|
|
|
evas_common_image_create(unsigned int w, unsigned int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
RGBA_Image *im;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im = (RGBA_Image *) _evas_common_rgba_image_new();
|
2002-11-08 00:02:15 -08:00
|
|
|
if (!im) return NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
im->cache_entry.w = w;
|
|
|
|
im->cache_entry.h = h;
|
|
|
|
if (_evas_common_rgba_image_surface_alloc(&im->cache_entry, w, h))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_common_rgba_image_delete(&im->cache_entry);
|
|
|
|
return NULL;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
im->cache_entry.flags.cached = 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Image *
|
2010-09-18 16:16:25 -07:00
|
|
|
evas_common_image_alpha_create(unsigned int w, unsigned int h)
|
2006-05-02 00:28:49 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
RGBA_Image *im;
|
2006-05-02 00:28:49 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im = (RGBA_Image *) _evas_common_rgba_image_new();
|
2006-05-02 00:28:49 -07:00
|
|
|
if (!im) return NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
im->cache_entry.w = w;
|
|
|
|
im->cache_entry.h = h;
|
2009-03-27 07:11:27 -07:00
|
|
|
im->cache_entry.flags.alpha = 1;
|
2008-04-11 17:32:30 -07:00
|
|
|
if (_evas_common_rgba_image_surface_alloc(&im->cache_entry, w, h))
|
2006-05-02 00:28:49 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_common_rgba_image_delete(&im->cache_entry);
|
|
|
|
return NULL;
|
2006-05-02 00:28:49 -07:00
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
im->cache_entry.flags.cached = 0;
|
2006-05-02 00:28:49 -07:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
EAPI RGBA_Image *
|
2010-09-18 16:16:25 -07:00
|
|
|
evas_common_image_new(unsigned int w, unsigned int h, unsigned int alpha)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
|
|
|
if (alpha)
|
|
|
|
return evas_common_image_alpha_create(w, h);
|
|
|
|
return evas_common_image_create(w, h);
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
void
|
2006-12-17 07:48:52 -08:00
|
|
|
evas_common_image_colorspace_normalize(RGBA_Image *im)
|
|
|
|
{
|
2008-04-15 08:20:53 -07:00
|
|
|
if ((!im->cs.data) ||
|
2007-07-17 21:42:23 -07:00
|
|
|
((!im->cs.dirty) && (!(im->flags & RGBA_IMAGE_IS_DIRTY)))) return;
|
2008-04-11 17:32:30 -07:00
|
|
|
switch (im->cache_entry.space)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
2014-03-16 23:19:47 -07:00
|
|
|
case EVAS_COLORSPACE_GRY8:
|
2014-04-02 03:03:03 -07:00
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
2015-05-27 04:17:20 -07:00
|
|
|
if (im->image.data != im->cs.data)
|
|
|
|
{
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
// if (((Image_Entry *)im)->data1) evas_cserve2_image_free(&im->cache_entry);
|
|
|
|
if (((Image_Entry *)im)->data1) ERR("Shouldn't reach this point since we are using cache2.");
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2015-05-27 04:17:20 -07:00
|
|
|
if (!im->image.no_free)
|
2012-02-08 04:08:41 -08:00
|
|
|
{
|
2015-10-30 00:41:32 -07:00
|
|
|
evas_common_rgba_image_surface_munmap(im->image.data,
|
|
|
|
im->cache_entry.allocated.w,
|
|
|
|
im->cache_entry.allocated.h,
|
|
|
|
im->cache_entry.space);
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surfs = eina_list_remove(surfs, im);
|
2015-05-27 04:17:20 -07:00
|
|
|
#endif
|
2012-02-08 04:08:41 -08:00
|
|
|
((Image_Entry *)im)->allocated.w = 0;
|
|
|
|
((Image_Entry *)im)->allocated.h = 0;
|
|
|
|
}
|
2015-05-27 04:17:20 -07:00
|
|
|
im->image.data = im->cs.data;
|
|
|
|
im->cs.no_free = im->image.no_free;
|
|
|
|
}
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
2015-05-27 04:17:20 -07:00
|
|
|
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
|
|
|
|
evas_common_convert_yuv_422p_601_rgba(im->cs.data, (DATA8*) im->image.data,
|
|
|
|
im->cache_entry.w, im->cache_entry.h);
|
|
|
|
break;
|
2011-07-21 03:36:05 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
|
|
|
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
|
|
|
|
evas_common_convert_yuv_422_601_rgba(im->cs.data, (DATA8*) im->image.data,
|
|
|
|
im->cache_entry.w, im->cache_entry.h);
|
|
|
|
break;
|
2011-08-29 13:56:48 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
|
|
|
|
evas_common_convert_yuv_420_601_rgba(im->cs.data, (DATA8*) im->image.data,
|
|
|
|
im->cache_entry.w, im->cache_entry.h);
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
|
|
|
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
|
|
|
|
evas_common_convert_yuv_420T_601_rgba(im->cs.data, (DATA8*) im->image.data,
|
|
|
|
im->cache_entry.w, im->cache_entry.h);
|
|
|
|
break;
|
2015-05-27 04:17:20 -07:00
|
|
|
case EMILE_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
|
|
|
|
evas_common_convert_yuv_422p_709_rgba(im->cs.data, (DATA8*) im->image.data,
|
|
|
|
im->cache_entry.w, im->cache_entry.h);
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
default:
|
2015-05-27 04:17:20 -07:00
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
im->cs.dirty = 0;
|
2012-02-08 04:08:41 -08:00
|
|
|
#ifdef SURFDBG
|
|
|
|
surf_debug();
|
2015-05-27 04:17:20 -07:00
|
|
|
#endif
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_image_colorspace_dirty(RGBA_Image *im)
|
|
|
|
{
|
|
|
|
im->cs.dirty = 1;
|
2009-03-26 00:14:08 -07:00
|
|
|
evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
|
2012-05-13 23:56:22 -07:00
|
|
|
#ifdef HAVE_PIXMAN
|
|
|
|
# ifdef PIXMAN_IMAGE
|
|
|
|
if (im->pixman.im)
|
|
|
|
{
|
|
|
|
pixman_image_unref(im->pixman.im);
|
|
|
|
im->pixman.im = NULL;
|
|
|
|
}
|
|
|
|
_evas_common_rgba_image_post_surface((Image_Entry *)im);
|
|
|
|
# endif
|
|
|
|
#endif
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2010-09-18 16:16:25 -07:00
|
|
|
evas_common_image_set_cache(unsigned int size)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2010-08-21 06:52:25 -07:00
|
|
|
if (eci)
|
2008-12-01 18:33:09 -08:00
|
|
|
evas_cache_image_set(eci, size);
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (eci2)
|
2012-11-27 10:23:25 -08:00
|
|
|
evas_cache2_limit_set(eci2, size + EVAS_CSERVE2_SCALE_CACHE_SIZE);
|
2012-05-03 14:01:31 -07:00
|
|
|
#endif
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2007-12-13 21:57:16 -08:00
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI int
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_image_get_cache(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2007-07-16 00:25:35 -07:00
|
|
|
return evas_cache_image_get(eci);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Image *
|
2013-05-06 18:50:57 -07:00
|
|
|
evas_common_load_image_from_file(const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2010-08-21 06:52:25 -07:00
|
|
|
if (!file)
|
2009-12-22 15:11:57 -08:00
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return (RGBA_Image *) evas_cache_image_request(eci, file, key, lo, error);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2013-05-07 23:37:37 -07:00
|
|
|
EAPI RGBA_Image *
|
|
|
|
evas_common_load_image_from_mmap(Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error)
|
|
|
|
{
|
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return (RGBA_Image *) evas_cache_image_mmap_request(eci, f, key, lo, error);
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_common_image_cache_free(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_common_image_set_cache(0);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
EAPI Evas_Cache_Image*
|
|
|
|
evas_common_image_cache_get(void)
|
2005-12-03 01:27:53 -08:00
|
|
|
{
|
2007-07-16 00:25:35 -07:00
|
|
|
return eci;
|
2005-12-03 01:27:53 -08:00
|
|
|
}
|
|
|
|
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
EAPI Evas_Cache2*
|
|
|
|
evas_common_image_cache2_get(void)
|
|
|
|
{
|
|
|
|
return eci2;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-09-30 03:18:37 -07:00
|
|
|
EAPI RGBA_Image *
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_image_line_buffer_obtain(int len)
|
2005-11-30 00:45:20 -08:00
|
|
|
{
|
2005-12-03 01:27:53 -08:00
|
|
|
if (len < 1) return NULL;
|
|
|
|
if (len < EVAS_RGBA_LINE_BUFFER_MIN_LEN)
|
|
|
|
len = EVAS_RGBA_LINE_BUFFER_MIN_LEN;
|
2006-11-13 15:23:44 -08:00
|
|
|
return evas_common_image_create(len, 1);
|
2008-07-19 10:40:52 -07:00
|
|
|
/*
|
2005-12-03 01:27:53 -08:00
|
|
|
if (evas_rgba_line_buffer)
|
2005-11-30 00:45:20 -08:00
|
|
|
{
|
2005-12-03 01:27:53 -08:00
|
|
|
if (evas_rgba_line_buffer->image->w >= len)
|
|
|
|
return evas_rgba_line_buffer;
|
|
|
|
evas_rgba_line_buffer->image->data = (DATA32 *)realloc(evas_rgba_line_buffer->image->data, len * sizeof(DATA32));
|
|
|
|
if (!evas_rgba_line_buffer->image->data)
|
|
|
|
{
|
|
|
|
evas_common_image_free(evas_rgba_line_buffer);
|
|
|
|
evas_rgba_line_buffer = NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
evas_rgba_line_buffer->image->w = len;
|
|
|
|
return evas_rgba_line_buffer;
|
2005-11-30 00:45:20 -08:00
|
|
|
}
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_rgba_line_buffer = evas_common_image_create(len, 1);
|
|
|
|
if (!evas_rgba_line_buffer) return NULL;
|
|
|
|
return evas_rgba_line_buffer;
|
2006-11-13 15:23:44 -08:00
|
|
|
*/
|
2005-11-30 00:45:20 -08:00
|
|
|
}
|
|
|
|
|
2006-09-30 03:18:37 -07:00
|
|
|
EAPI void
|
2006-11-13 15:23:44 -08:00
|
|
|
evas_common_image_line_buffer_release(RGBA_Image *im)
|
2005-12-03 01:27:53 -08:00
|
|
|
{
|
2008-05-30 21:16:39 -07:00
|
|
|
_evas_common_rgba_image_delete(&im->cache_entry);
|
2008-07-19 10:40:52 -07:00
|
|
|
/*
|
2005-12-03 01:27:53 -08:00
|
|
|
if (!evas_rgba_line_buffer) return;
|
|
|
|
if (EVAS_RGBA_LINE_BUFFER_MAX_LEN < evas_rgba_line_buffer->image->w)
|
|
|
|
{
|
|
|
|
evas_rgba_line_buffer->image->w = EVAS_RGBA_LINE_BUFFER_MAX_LEN;
|
|
|
|
evas_rgba_line_buffer->image->data = (DATA32 *)realloc(evas_rgba_line_buffer->image->data,
|
|
|
|
evas_rgba_line_buffer->image->w * sizeof(DATA32));
|
|
|
|
if (!evas_rgba_line_buffer->image->data)
|
|
|
|
{
|
|
|
|
evas_common_image_free(evas_rgba_line_buffer);
|
|
|
|
evas_rgba_line_buffer = NULL;
|
|
|
|
}
|
|
|
|
}
|
2006-11-13 15:23:44 -08:00
|
|
|
*/
|
2005-12-03 01:27:53 -08:00
|
|
|
}
|
|
|
|
|
2006-09-30 03:18:37 -07:00
|
|
|
EAPI void
|
2006-11-13 15:23:44 -08:00
|
|
|
evas_common_image_line_buffer_free(RGBA_Image *im)
|
2005-12-03 01:27:53 -08:00
|
|
|
{
|
2008-05-30 21:16:39 -07:00
|
|
|
_evas_common_rgba_image_delete(&im->cache_entry);
|
2008-07-19 10:40:52 -07:00
|
|
|
/*
|
2005-12-03 01:27:53 -08:00
|
|
|
if (!evas_rgba_line_buffer) return;
|
|
|
|
evas_common_image_free(evas_rgba_line_buffer);
|
|
|
|
evas_rgba_line_buffer = NULL;
|
2006-11-13 15:23:44 -08:00
|
|
|
*/
|
2005-12-03 01:27:53 -08:00
|
|
|
}
|
2006-05-02 00:28:49 -07:00
|
|
|
|
2006-09-30 03:18:37 -07:00
|
|
|
EAPI RGBA_Image *
|
2006-05-02 00:28:49 -07:00
|
|
|
evas_common_image_alpha_line_buffer_obtain(int len)
|
|
|
|
{
|
|
|
|
if (len < 1) return NULL;
|
|
|
|
if (len < EVAS_ALPHA_LINE_BUFFER_MIN_LEN)
|
|
|
|
len = EVAS_ALPHA_LINE_BUFFER_MIN_LEN;
|
2006-11-13 15:23:44 -08:00
|
|
|
return evas_common_image_alpha_create(len, 1);
|
2008-07-19 10:40:52 -07:00
|
|
|
/*
|
2006-05-02 00:28:49 -07:00
|
|
|
if (evas_alpha_line_buffer)
|
|
|
|
{
|
|
|
|
if (evas_alpha_line_buffer->image->w >= len)
|
|
|
|
return evas_alpha_line_buffer;
|
|
|
|
evas_alpha_line_buffer->image->data = realloc(evas_alpha_line_buffer->image->data, len * sizeof(DATA8));
|
|
|
|
if (!evas_alpha_line_buffer->image->data)
|
|
|
|
{
|
|
|
|
evas_common_image_free(evas_alpha_line_buffer);
|
|
|
|
evas_alpha_line_buffer = NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
evas_alpha_line_buffer->image->w = len;
|
|
|
|
return evas_alpha_line_buffer;
|
|
|
|
}
|
|
|
|
evas_alpha_line_buffer = evas_common_image_alpha_create(len, 1);
|
|
|
|
return evas_alpha_line_buffer;
|
2006-11-13 15:23:44 -08:00
|
|
|
*/
|
2006-05-02 00:28:49 -07:00
|
|
|
}
|
|
|
|
|
2006-09-30 03:18:37 -07:00
|
|
|
EAPI void
|
2006-11-13 15:23:44 -08:00
|
|
|
evas_common_image_alpha_line_buffer_release(RGBA_Image *im)
|
2006-05-02 00:28:49 -07:00
|
|
|
{
|
2008-05-30 21:16:39 -07:00
|
|
|
_evas_common_rgba_image_delete(&im->cache_entry);
|
2008-07-19 10:40:52 -07:00
|
|
|
/*
|
2006-05-02 00:28:49 -07:00
|
|
|
if (!evas_alpha_line_buffer) return;
|
|
|
|
if (EVAS_ALPHA_LINE_BUFFER_MAX_LEN < evas_alpha_line_buffer->image->w)
|
|
|
|
{
|
|
|
|
evas_alpha_line_buffer->image->w = EVAS_ALPHA_LINE_BUFFER_MAX_LEN;
|
|
|
|
evas_alpha_line_buffer->image->data = realloc(evas_alpha_line_buffer->image->data,
|
|
|
|
evas_alpha_line_buffer->image->w * sizeof(DATA8));
|
|
|
|
if (!evas_alpha_line_buffer->image->data)
|
|
|
|
{
|
|
|
|
evas_common_image_free(evas_alpha_line_buffer);
|
|
|
|
evas_alpha_line_buffer = NULL;
|
|
|
|
}
|
|
|
|
}
|
2006-11-13 15:23:44 -08:00
|
|
|
*/
|
2006-05-02 00:28:49 -07:00
|
|
|
}
|
|
|
|
|
2006-09-30 03:18:37 -07:00
|
|
|
EAPI void
|
2008-06-03 02:09:39 -07:00
|
|
|
evas_common_image_premul(Image_Entry *ie)
|
2006-09-30 03:18:37 -07:00
|
|
|
{
|
|
|
|
DATA32 nas = 0;
|
|
|
|
|
2013-06-20 04:28:18 -07:00
|
|
|
if (!ie) return;
|
|
|
|
if (!evas_cache_image_pixels(ie)) return;
|
2008-06-03 02:09:39 -07:00
|
|
|
if (!ie->flags.alpha) return;
|
2006-09-30 03:18:37 -07:00
|
|
|
|
2014-03-20 19:53:57 -07:00
|
|
|
switch (ie->space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
nas = evas_common_convert_argb_premul(evas_cache_image_pixels(ie), ie->w * ie->h);
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
|
|
|
nas = evas_common_convert_ag_premul((void*) evas_cache_image_pixels(ie), ie->w * ie->h);
|
|
|
|
default: return;
|
|
|
|
}
|
2008-06-03 02:09:39 -07:00
|
|
|
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ie->w * ie->h))
|
|
|
|
ie->flags.alpha_sparse = 1;
|
2006-09-30 03:18:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2008-06-03 02:09:39 -07:00
|
|
|
evas_common_image_set_alpha_sparse(Image_Entry *ie)
|
2006-09-30 03:18:37 -07:00
|
|
|
{
|
|
|
|
DATA32 *s, *se;
|
|
|
|
DATA32 nas = 0;
|
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
if (!ie) return;
|
2013-06-20 04:28:18 -07:00
|
|
|
if (!evas_cache_image_pixels(ie)) return;
|
2008-06-03 02:09:39 -07:00
|
|
|
if (!ie->flags.alpha) return;
|
2006-09-30 03:18:37 -07:00
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
s = evas_cache_image_pixels(ie);
|
|
|
|
se = s + (ie->w * ie->h);
|
2006-09-30 03:18:37 -07:00
|
|
|
while (s < se)
|
|
|
|
{
|
|
|
|
DATA32 p = *s & 0xff000000;
|
|
|
|
|
|
|
|
if (!p || (p == 0xff000000))
|
|
|
|
nas++;
|
|
|
|
s++;
|
|
|
|
}
|
2008-06-03 02:09:39 -07:00
|
|
|
if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ie->w * ie->h))
|
|
|
|
ie->flags.alpha_sparse = 1;
|
2006-09-30 03:18:37 -07:00
|
|
|
}
|