evas: add software YUY2 colorspace converter.

NOTE: will shortly learn how to write the corresponding shader and add it soon.


SVN revision: 61548
This commit is contained in:
Cedric BAIL 2011-07-21 10:36:05 +00:00
parent 0b7d33e3df
commit 5cbc6350ba
9 changed files with 102 additions and 12 deletions

View File

@ -457,10 +457,11 @@ typedef enum _Evas_Colorspace
{
EVAS_COLORSPACE_ARGB8888, /**< ARGB 32 bits per pixel, high-byte is Alpha, accessed 1 32bit word at a time */
/* these are not currently supported - but planned for the future */
EVAS_COLORSPACE_YCBCR422P601_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-601 specifications. The data poitned to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
EVAS_COLORSPACE_YCBCR422P709_PL,/**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data poitned to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
EVAS_COLORSPACE_YCBCR422P601_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-601 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
EVAS_COLORSPACE_YCBCR422P709_PL,/**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
EVAS_COLORSPACE_RGB565_A5P, /**< 16bit rgb565 + Alpha plane at end - 5 bits of the 8 being used per alpha byte */
EVAS_COLORSPACE_GRY8 /**< 8bit grayscale */
EVAS_COLORSPACE_GRY8, /**< 8bit grayscale */
EVAS_COLORSPACE_YCBCR422601_PL /**< YCbCr 4:2:2, ITU.BT-601 specifications. The data poitned to is just an array of row pointer, pointing to line of Y,Cb,Y,Cr bytes */
} Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */
/**

View File

@ -1048,7 +1048,8 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache,
Image_Entry *im;
if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
(cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(cspace == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
@ -1078,7 +1079,8 @@ evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, D
Image_Entry *im;
if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
(cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(cspace == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
@ -1108,7 +1110,8 @@ evas_cache_image_surface_alloc(Image_Entry *im, unsigned int w, unsigned int h)
Evas_Cache_Image *cache = im->cache;
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
_evas_cache_image_entry_surface_alloc(cache, im, w, h);
@ -1123,7 +1126,8 @@ evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
int error;
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
if ((im->w == w) && (im->h == h)) return im;

View File

@ -25,6 +25,7 @@ static void _evas_yv12torgb_altivec(unsigned char **yuv, unsigned char *rgb, int
static void _evas_yv12torgb_diz (unsigned char **yuv, unsigned char *rgb, int w, int h);
#endif
static void _evas_yv12torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
static void _evas_yuy2torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
#define CRV 104595
#define CBU 132251
@ -119,6 +120,8 @@ static unsigned char _clip_lut[1024];
#define CMP_CLIP(i) ((i&256)? (~(i>>10)) : i);
static int initted = 0;
#endif
void
@ -147,8 +150,6 @@ evas_common_convert_yuv_420p_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
else
{
#ifdef BUILD_C
static int initted = 0;
if (!initted) _evas_yuv_init();
initted = 1;
/* FIXME: diz may be faster sometimes */
@ -877,7 +878,7 @@ _evas_yv12torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
/* yuv to rgb */
y = _v1164[*yp2++];
*((DATA32 *) dp2) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
dp2 += 4;
}
/* jump down one line since we are doing 2 at once */
@ -887,5 +888,70 @@ _evas_yv12torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
#endif
}
void
evas_common_convert_yuv_422_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
{
#ifdef BUILD_C
if (!initted) _evas_yuv_init();
initted = 1;
_evas_yuy2torgb_raster(src, dst, w, h);
#endif
}
static void
_evas_yuy2torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
{
#ifdef BUILD_C
int xx, yy;
int y, u, v;
unsigned char *yp1, *yp2, *up, *vp;
unsigned char *dp1;
dp1 = rgb;
/* destination pointers */
for (yy = 0; yy < h; yy++)
{
/* plane pointers */
unsigned char *line;
line = yuv[yy];
yp1 = line + 0;
up = line + 1;
yp2 = line + 2;
vp = line + 3;
for (xx = 0; xx < w; xx += 2)
{
int vmu;
/* collect u & v for 2 pixels block */
u = *up;
v = *vp;
/* save lookups */
vmu = _v813[v] + _v391[u];
u = _v2018[u];
v = _v1596[v];
/* do the top 2 pixels of the 2x2 block which shared u & v */
/* yuv to rgb */
y = _v1164[*yp1];
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
dp1 += 4;
/* yuv to rgb */
y = _v1164[*yp2];
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
dp1 += 4;
yp1 += 4; yp2 += 4; up += 4; vp += 4;
}
}
#endif
}
#endif

View File

@ -3,6 +3,7 @@
EAPI void evas_common_convert_yuv_420p_601_rgba (DATA8 **src, DATA8 *dst, int w, int h);
EAPI void evas_common_convert_yuv_422_601_rgba(DATA8 **src, DATA8 *dst, int w, int h);
#endif /* _EVAS_CONVERT_YUV_H */

View File

@ -20,6 +20,7 @@ evas_common_rgba_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *imag
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
w &= ~0x1;
dst->cache_entry.w = w;
dst->cache_entry.h = h;
@ -51,6 +52,7 @@ evas_common_rgba_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA3
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
dst->cs.data = calloc(1, dst->cache_entry.h * sizeof(unsigned char*) * 2);
if (image_data && (dst->cs.data))
memcpy(dst->cs.data, image_data, dst->cache_entry.h * sizeof(unsigned char*) * 2);
@ -73,13 +75,15 @@ evas_common_rgba_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, u
RGBA_Image *im = (RGBA_Image *) ie_im;
if ((im->cache_entry.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->cache_entry.space == EVAS_COLORSPACE_YCBCR422P709_PL))
(im->cache_entry.space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(im->cache_entry.space == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
dst->flags = im->flags;
dst->cs.no_free = 0;
if ((im->cache_entry.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->cache_entry.space == EVAS_COLORSPACE_YCBCR422P709_PL))
(im->cache_entry.space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(im->cache_entry.space == EVAS_COLORSPACE_YCBCR422601_PL))
dst->cs.data = calloc(1, dst->cache_entry.h * sizeof(unsigned char *) * 2);
evas_common_image_colorspace_dirty(dst);
@ -104,6 +108,7 @@ evas_common_rgba_image_colorspace_set(Image_Entry* ie_dst, int cspace)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
if (dst->image.no_free)
{
ie_dst->allocated.w = 0;

View File

@ -588,6 +588,13 @@ evas_common_image_colorspace_normalize(RGBA_Image *im)
im->cache_entry.w, im->cache_entry.h);
#endif
break;
case EVAS_COLORSPACE_YCBCR422601_PL:
#ifdef BUILD_CONVERT_YUV
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);
#endif
break;
default:
break;
}

View File

@ -1332,6 +1332,7 @@ evas_engine_dfb_image_data_get(void *data __UNUSED__, void *image, int to_write,
}
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
/* XXX untested */
*image_data = im->cs.data;
break;
@ -1383,6 +1384,7 @@ evas_engine_dfb_image_data_put(void *data, void *image, DATA32* image_data)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
/* XXX untested */
if (image_data != im->cs.data)
{

View File

@ -433,6 +433,7 @@ eng_image_data_get(void *data __UNUSED__, void *image, int to_write, DATA32 **im
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
*image_data = im->cs.data;
break;
default:
@ -468,6 +469,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
if (image_data != im->cs.data)
{
if (im->cs.data)

View File

@ -451,6 +451,7 @@ evas_engine_sdl_image_data_get(void *data, void *image,
break;
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
*image_data = im->cs.data;
break;
default:
@ -487,6 +488,7 @@ evas_engine_sdl_image_data_put(void *data, void *image, DATA32* image_data)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
if (image_data != im->cs.data)
{
if (im->cs.data)