implement ecore_x_image to finish - put and convert done. actually no

need for convert from argb as that requires what evas already does
argb-> screen depth. use evas for that.



SVN revision: 52950
This commit is contained in:
Carsten Haitzler 2010-10-01 12:31:22 +00:00
parent 3966e2e027
commit a1cc721153
2 changed files with 290 additions and 37 deletions

View File

@ -2978,6 +2978,7 @@ EAPI Eina_Bool ecore_x_image_get(Ecore_X_Image *im,
int h);
EAPI void ecore_x_image_put(Ecore_X_Image *im,
Ecore_X_Drawable draw,
Ecore_X_GC gc,
int x,
int y,
int sx,
@ -2988,21 +2989,15 @@ EAPI void * ecore_x_image_data_get(Ecore_X_Image *im,
int *bpl,
int *rows,
int *bpp);
EAPI Eina_Bool ecore_x_image_is_argb32_get(Ecore_X_Image *im);
EAPI Eina_Bool ecore_x_image_to_argb_convert(void *src, int sbpp,
int sbpl, int srows,
int sbpl,
Ecore_X_Colormap c,
Ecore_X_Visual v,
int x, int y, int w, int h,
void *dst, int dbpp,
int dbpl, int drows,
int dx, int dy);
EAPI Eina_Bool ecore_x_image_from_argb_convert(void *src, int sbpp,
int sbpl, int srows,
Ecore_X_Colormap c,
Ecore_X_Visual v,
int x, int y, int w, int h,
void *dst, int dbpp,
int dbpl, int drows,
unsigned int *dst,
int dbpl,
int dx, int dy);
EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win);

View File

@ -215,9 +215,10 @@ ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw,
im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
im->xim->width = w;
im->xim->height = h;
XGrabServer(_ecore_x_disp);
if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
ret = EINA_FALSE;
XUngrabServer(_ecore_x_disp);
ecore_x_sync();
}
// unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
@ -270,38 +271,295 @@ ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw,
} /* ecore_x_image_get */
EAPI void
ecore_x_image_put(Ecore_X_Image *im __UNUSED__,
Ecore_X_Drawable draw __UNUSED__,
int x __UNUSED__,
int y __UNUSED__,
int sx __UNUSED__,
int sy __UNUSED__,
int w __UNUSED__,
int h __UNUSED__)
ecore_x_image_put(Ecore_X_Image *im,
Ecore_X_Drawable draw,
Ecore_X_GC gc,
int x,
int y,
int sx,
int sy,
int w,
int h)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
printf("ecore_x_image_put: unimplemented!\n");
Ecore_X_GC tgc = 0;
if (!gc)
{
XGCValues gcv;
memset(&gcv, 0, sizeof(gcv));
gcv.subwindow_mode = IncludeInferiors;
tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv);
gc = tgc;
}
if (!im->xim) _ecore_x_image_shm_create(im);
XShmPutImage(_ecore_x_disp, draw, gc, im->xim, sx, sy, x, y, w, h, False);
if (tgc) ecore_x_gc_free(tgc);
} /* ecore_x_image_put */
EAPI void *
ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!im->xim)
_ecore_x_image_shm_create(im);
if (!im->xim)
return NULL;
if (bpl)
*bpl = im->bpl;
if (rows)
*rows = im->rows;
if (bpp)
*bpp = im->bpp;
if (!im->xim) _ecore_x_image_shm_create(im);
if (!im->xim) return NULL;
if (bpl) *bpl = im->bpl;
if (rows) *rows = im->rows;
if (bpp) *bpp = im->bpp;
return im->data;
} /* ecore_x_image_data_get */
EAPI Eina_Bool
ecore_x_image_is_argb32_get(Ecore_X_Image *im)
{
Visual *vis = im->vis;
if (!im->xim) _ecore_x_image_shm_create(im);
if (((vis->class == TrueColor) ||
(vis->class == DirectColor)) &&
(im->depth >= 24) &&
(vis->red_mask == 0xff0000) &&
(vis->green_mask == 0x00ff00) &&
(vis->blue_mask == 0x0000ff))
{
#ifdef WORDS_BIGENDIAN
if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE;
#else
if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE;
#endif
}
return EINA_FALSE;
}
EAPI Eina_Bool
ecore_x_image_to_argb_convert(void *src, int sbpp,
int sbpl,
Ecore_X_Colormap c,
Ecore_X_Visual v,
int x, int y, int w, int h,
unsigned int *dst,
int dbpl,
int dx, int dy)
{
Visual *vis = v;
XColor *cols = NULL;
int n = 0, nret = 0, i, row;
unsigned int pal[256], r, g, b;
enum
{
rgbnone = 0,
rgb565,
bgr565,
rgbx555,
argbx888,
abgrx888,
rgba888x,
bgra888x,
argbx666
};
int mode = 0;
sbpp *= 8;
n = vis->map_entries;
if ((n <= 256) &&
((vis->class == PseudoColor) ||
(vis->class == StaticColor) ||
(vis->class == GrayScale) ||
(vis->class == StaticGray)))
{
if (!c) c = DefaultColormap(_ecore_x_disp,
DefaultScreen(_ecore_x_disp));
cols = alloca(n * sizeof(XColor));
for (i = 0; i < n; i++)
{
cols[i].pixel = i;
cols[i].flags = DoRed | DoGreen | DoBlue;
cols[i].red = 0;
cols[i].green = 0;
cols[i].blue = 0;
}
XQueryColors(_ecore_x_disp, c, cols, n);
for (i = 0; i < n; i++)
{
pal[i] = 0xff000000 |
((cols[i].red >> 8) << 16) |
((cols[i].green >> 8) << 8 ) |
((cols[i].blue >> 8) );
}
nret = n;
}
else if ((vis->class == TrueColor) ||
(vis->class == DirectColor))
{
if ((vis->red_mask == 0x00ff0000) &&
(vis->green_mask == 0x0000ff00) &&
(vis->blue_mask == 0x000000ff))
mode = argbx888;
else if ((vis->red_mask == 0x000000ff) &&
(vis->green_mask == 0x0000ff00) &&
(vis->blue_mask == 0x00ff0000))
mode = abgrx888;
else if ((vis->red_mask == 0xff000000) &&
(vis->green_mask == 0x00ff0000) &&
(vis->blue_mask == 0x0000ff00))
mode = rgba888x;
else if ((vis->red_mask == 0x0000ff00) &&
(vis->green_mask == 0x00ff0000) &&
(vis->blue_mask == 0xff000000))
mode = bgra888x;
else if ((vis->red_mask == 0x0003f000) &&
(vis->green_mask == 0x00000fc0) &&
(vis->blue_mask == 0x0000003f))
mode = argbx666;
else if ((vis->red_mask == 0x0000f800) &&
(vis->green_mask == 0x000007e0) &&
(vis->blue_mask == 0x0000001f))
mode = rgb565;
else if ((vis->red_mask == 0x0000001f) &&
(vis->green_mask == 0x000007e0) &&
(vis->blue_mask == 0x0000f800))
mode = bgr565;
else if ((vis->red_mask == 0x00007c00) &&
(vis->green_mask == 0x000003e0) &&
(vis->blue_mask == 0x0000001f))
mode = rgbx555;
else
return EINA_FALSE;
}
for (row = 0; row < h; row++)
{
unsigned char *s8;
unsigned short *s16;
unsigned int *s32;
unsigned int *dp, *de;
dp = ((unsigned int *)(((unsigned char *)dst) +
((dy + row) * dbpl))) + dx;
de = dp + w;
switch (sbpp)
{
case 8:
s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
if (nret > 0)
{
while (dp < de)
{
*dp = pal[*s8];
s8++; dp++;
}
}
else
return EINA_FALSE;
break;
case 16:
s16 = ((unsigned short *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
switch (mode)
{
case rgb565:
while (dp < de)
{
r = (*s16 & 0xf800) << 8;
g = (*s16 & 0x07e0) << 5;
b = (*s16 & 0x001f) << 3;
r |= (r >> 5) & 0xff0000;
g |= (g >> 6) & 0x00ff00;
b |= (b >> 5);
*dp = 0xff000000 | r | g | b;
s16++; dp++;
}
break;
case bgr565:
while (dp < de)
{
r = (*s16 & 0x001f) << 19;
g = (*s16 & 0x07e0) << 5;
b = (*s16 & 0xf800) >> 8;
r |= (r >> 5) & 0xff0000;
g |= (g >> 6) & 0x00ff00;
b |= (b >> 5);
*dp = 0xff000000 | r | g | b;
s16++; dp++;
}
break;
case rgbx555:
while (dp < de)
{
r = (*s16 & 0x7c00) << 9;
g = (*s16 & 0x03e0) << 6;
b = (*s16 & 0x001f) << 3;
r |= (r >> 5) & 0xff0000;
g |= (g >> 5) & 0x00ff00;
b |= (b >> 5);
*dp = 0xff000000 | r | g | b;
s16++; dp++;
}
break;
default:
return EINA_FALSE;
break;
}
break;
case 24:
case 32:
s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
switch (mode)
{
case argbx888:
while (dp < de)
{
*dp = 0xff000000 | *s32;
s32++; dp++;
}
break;
case abgrx888:
while (dp < de)
{
r = *s32 & 0x000000ff;
g = *s32 & 0x0000ff00;
b = *s32 & 0x00ff0000;
*dp = 0xff000000 | (r << 16) | (g) | (b >> 16);
s32++; dp++;
}
break;
case rgba888x:
while (dp < de)
{
*dp = 0xff000000 | (*s32 >> 8);
s32++; dp++;
}
break;
case bgra888x:
while (dp < de)
{
r = *s32 & 0x0000ff00;
g = *s32 & 0x00ff0000;
b = *s32 & 0xff000000;
*dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24);
s32++; dp++;
}
break;
case argbx666:
while (dp < de)
{
r = (*s32 & 0x3f000) << 6;
g = (*s32 & 0x00fc0) << 4;
b = (*s32 & 0x0003f) << 2;
r |= (r >> 6) & 0xff0000;
g |= (g >> 6) & 0x00ff00;
b |= (b >> 6);
*dp = 0xff000000 | r | g | b;
s32++; dp++;
}
break;
default:
return EINA_FALSE;
break;
}
break;
break;
default:
return EINA_FALSE;
break;
}
}
return EINA_TRUE;
}