forked from enlightenment/efl
evas: Implement support for external buffers
This brings support for the eo api for external buffers (like the old data_set / data_get). The new API now works with slices and planes. The internal code still relies on the old cs.data array for YUV color conversion. This makes the code a little bit too complex to my taste. Tested with expedite for RGBA and YUV 422 601 planar, both SW and GL engines (x11).
This commit is contained in:
parent
2f737e8f3b
commit
b2d92f2626
|
@ -639,34 +639,30 @@ _image_pixels_set(Evas_Object_Protected_Data *obj,
|
|||
}
|
||||
}
|
||||
|
||||
if (copy && !slice)
|
||||
if (!slice || !slice->mem)
|
||||
{
|
||||
// note: we release all planes at once
|
||||
if (o->engine_data)
|
||||
ENFN->image_free(ENDT, o->engine_data);
|
||||
o->engine_data = ENFN->image_new_from_copied_data(ENDT, w, h, NULL, o->cur->has_alpha, cspace);
|
||||
}
|
||||
else if (copy)
|
||||
{
|
||||
#warning TODO
|
||||
CRI("NOT IMPLEMENTED YET");
|
||||
//o->engine_data = ENFN->image_copy_slice(ENDT, o->engine_data, slice, w, h, stride, cspace, plane, o->cur->has_alpha)
|
||||
}
|
||||
else
|
||||
{
|
||||
#warning TODO
|
||||
CRI("NOT IMPLEMENTED YET");
|
||||
//o->engine_data = ENFN->image_set_slice(ENDT, o->engine_data, slice, w, h, stride, cspace, plane, o->cur->has_alpha);
|
||||
o->buffer_data_set = EINA_TRUE;
|
||||
o->engine_data = ENFN->image_data_slice_add(ENDT, o->engine_data,
|
||||
slice, copy, w, h, stride,
|
||||
cspace, plane, o->cur->has_alpha);
|
||||
}
|
||||
|
||||
if ((o->cur->image.w != w) || (o->cur->image.h != h))
|
||||
resized = EINA_TRUE;
|
||||
|
||||
if (!o->engine_data)
|
||||
{
|
||||
ERR("Failed to create internal image");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((o->cur->image.w != w) || (o->cur->image.h != h))
|
||||
resized = EINA_TRUE;
|
||||
|
||||
if (ENFN->image_scale_hint_set)
|
||||
ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint);
|
||||
|
||||
|
@ -698,6 +694,7 @@ end:
|
|||
if (resized)
|
||||
evas_object_inform_call_image_resize(obj->object);
|
||||
|
||||
efl_gfx_buffer_update_add(obj->object, 0, 0, w, h);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -246,12 +246,12 @@ _evas_common_rgba_image_plane_get(const RGBA_Image *im, int plane, Eina_Slice *s
|
|||
}
|
||||
return EINA_FALSE;
|
||||
|
||||
// YUV, assume contiguous memory within a plane (and no padding)
|
||||
// single interleaved plane
|
||||
// YUV, assume contiguous memory within a plane - padding ok
|
||||
// 1 plane
|
||||
case EVAS_COLORSPACE_YCBCR422601_PL:
|
||||
if (plane != 0) return EINA_FALSE;
|
||||
slice->mem = csdata[0];
|
||||
slice->len = (w * h * 3) / 2;
|
||||
slice->len = (h > 1) ? ((size_t) (csdata[1] - csdata[0]) * h * 2) : (w * 2);
|
||||
return EINA_TRUE;
|
||||
|
||||
// 2 planes
|
||||
|
@ -260,13 +260,13 @@ _evas_common_rgba_image_plane_get(const RGBA_Image *im, int plane, Eina_Slice *s
|
|||
if (plane == 0)
|
||||
{
|
||||
slice->mem = csdata[0];
|
||||
slice->len = w * h;
|
||||
slice->len = (h > 1) ? ((size_t) (csdata[1] - csdata[0]) * h) : w;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if (plane == 1)
|
||||
{
|
||||
slice->mem = csdata[h];
|
||||
slice->len = w * h / 4;
|
||||
slice->len = (h > 1) ? ((size_t) (csdata[h+1] - csdata[h]) * h / 2) : w / 2;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
|
@ -277,19 +277,19 @@ _evas_common_rgba_image_plane_get(const RGBA_Image *im, int plane, Eina_Slice *s
|
|||
if (plane == 0)
|
||||
{
|
||||
slice->mem = csdata[0];
|
||||
slice->len = w * h;
|
||||
slice->len = (h > 1) ? ((size_t) (csdata[1] - csdata[0]) * h) : w;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if (plane == 1)
|
||||
{
|
||||
slice->mem = csdata[h];
|
||||
slice->len = w * h / 4;
|
||||
slice->len = (h > 1) ? ((size_t) (csdata[h+1] - csdata[h]) * h / 2) : w / 2;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if (plane == 2)
|
||||
{
|
||||
slice->mem = csdata[2 * h];
|
||||
slice->len = w * h / 4;
|
||||
slice->mem = csdata[h + h / 2];
|
||||
slice->len = (h > 1) ? ((size_t) (csdata[h+h/2+1] - csdata[h+h/2]) * h / 2) : w / 2;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
|
|
|
@ -376,6 +376,8 @@ extern EAPI int _evas_log_dom_global;
|
|||
|
||||
#define TILE_CACHE_LINE_SIZE 64
|
||||
|
||||
#define RGBA_PLANE_MAX 3
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define UNROLL2(op...) op op
|
||||
|
@ -422,7 +424,6 @@ typedef struct _RGBA_Pipe RGBA_Pipe;
|
|||
typedef struct _RGBA_Pipe_Thread_Info RGBA_Pipe_Thread_Info;
|
||||
#endif
|
||||
typedef struct _RGBA_Image RGBA_Image;
|
||||
typedef struct _RGBA_Image_Span RGBA_Image_Span;
|
||||
typedef struct _RGBA_Draw_Context RGBA_Draw_Context;
|
||||
typedef struct _RGBA_Polygon_Point RGBA_Polygon_Point;
|
||||
typedef struct _RGBA_Map_Point RGBA_Map_Point;
|
||||
|
|
|
@ -1373,6 +1373,9 @@ struct _Evas_Func
|
|||
Eina_Bool (*image_data_unmap) (void *data, void *image, const Eina_Rw_Slice *slice);
|
||||
int (*image_data_maps_get) (void *data, const void *image, const Eina_Rw_Slice **slices);
|
||||
|
||||
/* new api for direct data set (not put) */
|
||||
void *(*image_data_slice_add) (void *data, void *image, const Eina_Slice *slice, Eina_Bool copy, int w, int h, int stride, Evas_Colorspace space, int plane, Eina_Bool alpha);
|
||||
|
||||
int (*image_native_init) (void *data, Evas_Native_Surface_Type type);
|
||||
void (*image_native_shutdown) (void *data, Evas_Native_Surface_Type type);
|
||||
void *(*image_native_set) (void *data, void *image, void *native);
|
||||
|
|
|
@ -360,13 +360,11 @@ evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, u
|
|||
break;
|
||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
||||
im->tex = NULL;
|
||||
im->cs.data = data;
|
||||
im->cs.no_free = 1;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
ERR("color space not supported: %d", cspace);
|
||||
break;
|
||||
}
|
||||
return im;
|
||||
|
@ -414,16 +412,13 @@ evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned i
|
|||
break;
|
||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
||||
im->tex = NULL;
|
||||
im->cs.no_free = 0;
|
||||
if (im->im->cache_entry.h > 0)
|
||||
im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
||||
if ((data) && (im->cs.data))
|
||||
memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
ERR("color space not supported: %d", cspace);
|
||||
break;
|
||||
}
|
||||
return im;
|
||||
|
|
|
@ -245,7 +245,8 @@ eng_image_file_colorspace_get(void *data EINA_UNUSED, void *image)
|
|||
}
|
||||
|
||||
static Eina_Bool
|
||||
eng_image_data_direct_get(void *data EINA_UNUSED, void *image, int plane, Eina_Slice *slice, Evas_Colorspace *cspace)
|
||||
eng_image_data_direct_get(void *data EINA_UNUSED, void *image, int plane,
|
||||
Eina_Slice *slice, Evas_Colorspace *cspace)
|
||||
{
|
||||
Evas_GL_Image *im = image;
|
||||
|
||||
|
@ -2897,6 +2898,201 @@ eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, const Eina
|
|||
return k;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_is_yuv(Efl_Gfx_Colorspace cspace)
|
||||
{
|
||||
switch (cspace)
|
||||
{
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR420TM12601_PL:
|
||||
return EINA_TRUE;
|
||||
|
||||
default:
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_data_slice_add(void *engdata, void *image,
|
||||
const Eina_Slice *slice, Eina_Bool copy,
|
||||
int w, int h, int stride, Evas_Colorspace cspace,
|
||||
int plane, Eina_Bool alpha)
|
||||
{
|
||||
const Eina_Bool use_cs = _is_yuv(cspace);
|
||||
const unsigned char **cs_data;
|
||||
Evas_GL_Image *im = image;
|
||||
int bpp = 0;
|
||||
|
||||
// Note: This code is not very robust by choice. It should NOT be used
|
||||
// in conjunction with data_put/data_get. Ever.
|
||||
// Assume w,h,cspace,alpha to be correct.
|
||||
// We still use cs.data for YUV.
|
||||
// 'image' may be NULL, in that case create a new one. Otherwise, it must
|
||||
// have been created by a previous call to this function.
|
||||
|
||||
if ((plane < 0) || (plane >= RGBA_PLANE_MAX)) goto fail;
|
||||
if (!slice || !slice->mem) goto fail;
|
||||
copy = !!copy;
|
||||
|
||||
// not implemented
|
||||
if (use_cs && copy)
|
||||
{
|
||||
// To implement this, we should switch the internals to slices first,
|
||||
// as this would give 3 planes rather than N rows of datas
|
||||
ERR("Evas can not copy YUV data (not implemented yet).");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (im && !im->im)
|
||||
{
|
||||
evas_gl_common_image_unref(im);
|
||||
im = NULL;
|
||||
}
|
||||
|
||||
// alloc
|
||||
if (!im)
|
||||
{
|
||||
switch (cspace)
|
||||
{
|
||||
case EFL_GFX_COLORSPACE_ARGB8888:
|
||||
case EFL_GFX_COLORSPACE_AGRY88:
|
||||
case EFL_GFX_COLORSPACE_GRY8:
|
||||
if (plane != 0) goto fail;
|
||||
if (copy)
|
||||
im = eng_image_new_from_copied_data(engdata, w, h, NULL, alpha, cspace);
|
||||
else
|
||||
im = eng_image_new_from_data(engdata, w, h, NULL, alpha, cspace);
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
||||
im = eng_image_new_from_data(engdata, w, h, NULL, alpha, cspace);
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: ETC, S3TC, YCBCR420TM12 (aka ST12 or tiled NV12)
|
||||
goto fail;
|
||||
}
|
||||
if (!im) goto fail;
|
||||
}
|
||||
|
||||
if (use_cs && (!im->cs.data || im->cs.no_free))
|
||||
{
|
||||
im->cs.data = calloc(1, h * sizeof(void *) * 2);
|
||||
if (!im->cs.data) goto fail;
|
||||
im->cs.no_free = EINA_FALSE;
|
||||
if (!im->im->cs.no_free) free(im->im->cs.data);
|
||||
im->im->cs.data = im->cs.data;
|
||||
im->im->cs.no_free = EINA_TRUE;
|
||||
}
|
||||
|
||||
// is this allocating image.data or cs.data?
|
||||
evas_gl_common_image_alloc_ensure(im);
|
||||
if (!im->im)
|
||||
goto fail;
|
||||
|
||||
// assign
|
||||
switch (cspace)
|
||||
{
|
||||
case EFL_GFX_COLORSPACE_ARGB8888:
|
||||
bpp = 4;
|
||||
case EFL_GFX_COLORSPACE_AGRY88:
|
||||
if (!bpp) bpp = 2;
|
||||
case EFL_GFX_COLORSPACE_GRY8:
|
||||
if (!bpp) bpp = 1;
|
||||
if (plane != 0) goto fail;
|
||||
if (!im->im->image.data) goto fail;
|
||||
if (!stride) stride = w * bpp;
|
||||
if (copy)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
const unsigned char *src = slice->bytes + h * stride;
|
||||
unsigned char *dst = im->im->image.data8 + bpp * w;
|
||||
memcpy(dst, src, w * bpp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stride != (bpp * w))
|
||||
{
|
||||
ERR("invalid stride for zero-copy data set");
|
||||
goto fail;
|
||||
}
|
||||
im->im->image.data = (DATA32 *) slice->mem;
|
||||
im->im->image.no_free = EINA_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
||||
/* YCbCr 4:2:2 Planar: Y rows, then the Cb, then Cr rows. */
|
||||
cs_data = im->cs.data;
|
||||
if (plane == 0)
|
||||
{
|
||||
if (!stride) stride = w;
|
||||
for (int y = 0; y < h; y++)
|
||||
cs_data[y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else if (plane == 1)
|
||||
{
|
||||
if (!stride) stride = w / 2;
|
||||
for (int y = 0; y < (h / 2); y++)
|
||||
cs_data[h + y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else if (plane == 2)
|
||||
{
|
||||
if (!stride) stride = w / 2;
|
||||
for (int y = 0; y < (h / 2); y++)
|
||||
cs_data[h + (h / 2) + y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else goto fail;
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
||||
/* YCbCr 4:2:2: lines of Y,Cb,Y,Cr bytes. */
|
||||
if (plane != 0) goto fail;
|
||||
if (!stride) stride = w * 2;
|
||||
cs_data = im->cs.data;
|
||||
for (int y = 0; y < h; y++)
|
||||
cs_data[y] = slice->bytes + (y * stride);
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
||||
/* YCbCr 4:2:0: Y rows, then the Cb,Cr rows. */
|
||||
if (!stride) stride = w;
|
||||
cs_data = im->cs.data;
|
||||
if (plane == 0)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
cs_data[y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else if (plane == 1)
|
||||
{
|
||||
for (int y = 0; y < (h / 2); y++)
|
||||
cs_data[h + y] = slice->bytes + (y * stride);
|
||||
}
|
||||
break;
|
||||
|
||||
// ETC, S3TC, YCBCR420TM12 (aka ST12 or tiled NV12)
|
||||
default:
|
||||
ERR("unsupported color space %d", cspace);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
||||
return im;
|
||||
|
||||
fail:
|
||||
if (im) eng_image_free(engdata, im);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
module_open(Evas_Module *em)
|
||||
{
|
||||
|
@ -2980,6 +3176,7 @@ module_open(Evas_Module *em)
|
|||
ORD(image_data_map);
|
||||
ORD(image_data_unmap);
|
||||
ORD(image_data_maps_get);
|
||||
ORD(image_data_slice_add);
|
||||
|
||||
ORD(font_cache_flush);
|
||||
ORD(font_cache_set);
|
||||
|
|
|
@ -1749,6 +1749,194 @@ eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, const Eina
|
|||
return k;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_is_yuv(Efl_Gfx_Colorspace cspace)
|
||||
{
|
||||
switch (cspace)
|
||||
{
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR420TM12601_PL:
|
||||
return EINA_TRUE;
|
||||
|
||||
default:
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_data_slice_add(void *engdata, void *image,
|
||||
const Eina_Slice *slice, Eina_Bool copy,
|
||||
int w, int h, int stride, Evas_Colorspace cspace,
|
||||
int plane, Eina_Bool alpha)
|
||||
{
|
||||
const Eina_Bool use_cs = _is_yuv(cspace);
|
||||
const unsigned char **cs_data;
|
||||
RGBA_Image *im = image;
|
||||
int bpp = 0;
|
||||
|
||||
// Note: This code is not very robust by choice. It should NOT be used
|
||||
// in conjunction with data_put/data_get. Ever.
|
||||
// Assume w,h,cspace,alpha to be correct.
|
||||
// We still use cs.data for YUV.
|
||||
// 'image' may be NULL, in that case create a new one. Otherwise, it must
|
||||
// have been created by a previous call to this function.
|
||||
|
||||
if ((plane < 0) || (plane >= RGBA_PLANE_MAX)) goto fail;
|
||||
if (!slice || !slice->mem) goto fail;
|
||||
copy = !!copy;
|
||||
|
||||
// not implemented
|
||||
if (use_cs && copy)
|
||||
{
|
||||
// To implement this, we should switch the internals to slices first,
|
||||
// as this would give 3 planes rather than N rows of datas
|
||||
ERR("Evas can not copy YUV data (not implemented yet).");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// alloc
|
||||
if (!im)
|
||||
{
|
||||
switch (cspace)
|
||||
{
|
||||
case EFL_GFX_COLORSPACE_ARGB8888:
|
||||
case EFL_GFX_COLORSPACE_AGRY88:
|
||||
case EFL_GFX_COLORSPACE_GRY8:
|
||||
if (plane != 0) goto fail;
|
||||
if (copy)
|
||||
im = eng_image_new_from_copied_data(engdata, w, h, NULL, alpha, cspace);
|
||||
else
|
||||
im = eng_image_new_from_data(engdata, w, h, NULL, alpha, cspace);
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
||||
// Use 'copied' to allocate the RGBA buffer
|
||||
im = eng_image_new_from_copied_data(engdata, w, h, NULL, alpha, cspace);
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: ETC, S3TC, YCBCR420TM12 (aka ST12 or tiled NV12)
|
||||
goto fail;
|
||||
}
|
||||
if (!im) goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
im = (RGBA_Image *) evas_cache_image_alone(&im->cache_entry);
|
||||
if (!im) goto fail;
|
||||
}
|
||||
|
||||
if (use_cs && (!im->cs.data || im->cs.no_free))
|
||||
{
|
||||
im->cs.data = calloc(1, h * sizeof(void *) * 2);
|
||||
if (!im->cs.data) goto fail;
|
||||
im->cs.no_free = EINA_FALSE;
|
||||
}
|
||||
|
||||
// assign
|
||||
switch (cspace)
|
||||
{
|
||||
case EFL_GFX_COLORSPACE_ARGB8888:
|
||||
bpp = 4;
|
||||
case EFL_GFX_COLORSPACE_AGRY88:
|
||||
if (!bpp) bpp = 2;
|
||||
case EFL_GFX_COLORSPACE_GRY8:
|
||||
if (!bpp) bpp = 1;
|
||||
if (plane != 0) goto fail;
|
||||
if (!stride) stride = w * bpp;
|
||||
if (copy)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
const unsigned char *src = slice->bytes + h * stride;
|
||||
unsigned char *dst = im->image.data8 + bpp * w;
|
||||
memcpy(dst, src, w * bpp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stride != (bpp * w))
|
||||
{
|
||||
ERR("invalid stride for zero-copy data set");
|
||||
goto fail;
|
||||
}
|
||||
im->image.data = (DATA32 *) slice->mem;
|
||||
im->image.no_free = EINA_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
||||
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
||||
/* YCbCr 4:2:2 Planar: Y rows, then the Cb, then Cr rows. */
|
||||
cs_data = im->cs.data;
|
||||
if (plane == 0)
|
||||
{
|
||||
if (!stride) stride = w;
|
||||
for (int y = 0; y < h; y++)
|
||||
cs_data[y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else if (plane == 1)
|
||||
{
|
||||
if (!stride) stride = w / 2;
|
||||
for (int y = 0; y < (h / 2); y++)
|
||||
cs_data[h + y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else if (plane == 2)
|
||||
{
|
||||
if (!stride) stride = w / 2;
|
||||
for (int y = 0; y < (h / 2); y++)
|
||||
cs_data[h + (h / 2) + y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else goto fail;
|
||||
evas_common_image_colorspace_dirty(im);
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
||||
/* YCbCr 4:2:2: lines of Y,Cb,Y,Cr bytes. */
|
||||
if (plane != 0) goto fail;
|
||||
if (!stride) stride = w * 2;
|
||||
cs_data = im->cs.data;
|
||||
for (int y = 0; y < h; y++)
|
||||
cs_data[y] = slice->bytes + (y * stride);
|
||||
evas_common_image_colorspace_dirty(im);
|
||||
break;
|
||||
|
||||
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
||||
/* YCbCr 4:2:0: Y rows, then the Cb,Cr rows. */
|
||||
if (!stride) stride = w;
|
||||
cs_data = im->cs.data;
|
||||
if (plane == 0)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
cs_data[y] = slice->bytes + (y * stride);
|
||||
}
|
||||
else if (plane == 1)
|
||||
{
|
||||
for (int y = 0; y < (h / 2); y++)
|
||||
cs_data[h + y] = slice->bytes + (y * stride);
|
||||
}
|
||||
evas_common_image_colorspace_dirty(im);
|
||||
break;
|
||||
|
||||
// ETC, S3TC, YCBCR420TM12 (aka ST12 or tiled NV12)
|
||||
default:
|
||||
ERR("unsupported color space %d", cspace);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return im;
|
||||
|
||||
fail:
|
||||
if (im) eng_image_free(engdata, im);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_image_flip_horizontal(DATA32 *pixels_out, const DATA32 *pixels_in,
|
||||
int iw, int ih)
|
||||
|
@ -4449,6 +4637,7 @@ static Evas_Func func =
|
|||
eng_image_data_map,
|
||||
eng_image_data_unmap,
|
||||
eng_image_data_maps_get,
|
||||
eng_image_data_slice_add,
|
||||
eng_image_native_init,
|
||||
eng_image_native_shutdown,
|
||||
eng_image_native_set,
|
||||
|
|
Loading…
Reference in New Issue