fix 24bpp rendering problem and pixel fetch problem found in qemu/kvm.

SVN revision: 81378
This commit is contained in:
Carsten Haitzler 2012-12-19 15:40:52 +00:00
parent 9f0e2fc7e8
commit 9e5266109d
8 changed files with 265 additions and 107 deletions

View File

@ -1,3 +1,12 @@
2012-12-20 Carsten Haitzler (The Rasterman)
* Fixed 24bpp issue with rendering in evas. It shows itself
only under qemu/kvm with the cirruse driver that I have found.
In this case the screen is really 24bpp packed and this case
just never comes up on any vaguely modern gfx system.
* Fixed 24bpp ximage convert back from 24bpp to 32bpp in
ecore-x. Only shows itself in qemu/kvm.
2012-12-18 Gustavo Sverzut Barbieri (k-s)
* Fixed many memory problems with ecore_evas_extn

View File

@ -249,8 +249,10 @@ ecore_x_image_is_argb32_get(Ecore_X_Image *im)
if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
(vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) &&
(im->depth >= 24) && (vis->red_mask == 0xff0000) &&
(vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff))
(im->bpp == 4) &&
(vis->red_mask == 0xff0000) &&
(vis->green_mask == 0x00ff00) &&
(vis->blue_mask == 0x0000ff))
{
#ifdef WORDS_BIGENDIAN
if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) return EINA_TRUE;
@ -287,6 +289,8 @@ ecore_x_image_to_argb_convert(void *src,
rgb565,
bgr565,
rgbx555,
rgb888,
bgr888,
argbx888,
abgrx888,
rgba888x,
@ -346,40 +350,56 @@ ecore_x_image_to_argb_convert(void *src,
else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
(vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR))
{
if ((vis->red_mask == 0x00ff0000) &&
(vis->green_mask == 0x0000ff00) &&
(vis->blue_mask == 0x000000ff))
mode = argbx888;
else if ((vis->red_mask == 0x000000ff) &&
if (sbpp == 24)
{
if ((vis->red_mask == 0x00ff0000) &&
(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;
(vis->blue_mask == 0x000000ff))
mode = rgb888;
else if ((vis->red_mask == 0x000000ff) &&
(vis->green_mask == 0x0000ff00) &&
(vis->blue_mask == 0x00ff0000))
mode = bgr888;
else
return EINA_FALSE;
}
else
return EINA_FALSE;
{
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++)
{
@ -461,6 +481,29 @@ ecore_x_image_to_argb_convert(void *src,
break;
case 24:
s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8));
switch (mode)
{
case rgb888:
while (dp < de)
{
*dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0];
s8 += 3; dp++;
}
break;
case bgr888:
while (dp < de)
{
*dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2];
s8 += 3; dp++;
}
break;
default:
return EINA_FALSE;
break;
}
break;
case 32:
s32 = ((unsigned int *)(((unsigned char *)src) +
((y + row) * sbpl))) + x;
@ -523,7 +566,6 @@ ecore_x_image_to_argb_convert(void *src,
break;
}
break;
break;
default:
return EINA_FALSE;

View File

@ -218,7 +218,9 @@ _ecore_x_image_shm_create(Ecore_X_Image *im)
im->bpp = 1;
else if (im->xim->bits_per_pixel <= 16)
im->bpp = 2;
else
else if (im->xim->bits_per_pixel <= 24)
im->bpp = 3;
else
im->bpp = 4;
}
@ -358,7 +360,7 @@ ecore_x_image_is_argb32_get(Ecore_X_Image *im)
if (!im->xim) _ecore_x_image_shm_create(im);
if (((vis->class == TrueColor) ||
(vis->class == DirectColor)) &&
(im->depth >= 24) &&
(im->bpp == 4) &&
(vis->red_mask == 0xff0000) &&
(vis->green_mask == 0x00ff00) &&
(vis->blue_mask == 0x0000ff))
@ -397,6 +399,8 @@ ecore_x_image_to_argb_convert(void *src,
rgb565,
bgr565,
rgbx555,
rgb888,
bgr888,
argbx888,
abgrx888,
rgba888x,
@ -439,40 +443,56 @@ ecore_x_image_to_argb_convert(void *src,
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) &&
if (sbpp == 24)
{
if ((vis->red_mask == 0x00ff0000) &&
(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;
(vis->blue_mask == 0x000000ff))
mode = rgb888;
else if ((vis->red_mask == 0x000000ff) &&
(vis->green_mask == 0x0000ff00) &&
(vis->blue_mask == 0x00ff0000))
mode = bgr888;
else
return EINA_FALSE;
}
else
return EINA_FALSE;
{
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++)
{
@ -553,6 +573,29 @@ ecore_x_image_to_argb_convert(void *src,
break;
case 24:
s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8));
switch (mode)
{
case rgb888:
while (dp < de)
{
*dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0];
s8 += 3; dp++;
}
break;
case bgr888:
while (dp < de)
{
*dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2];
s8 += 3; dp++;
}
break;
default:
return EINA_FALSE;
break;
}
break;
case 32:
s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
switch (mode)
@ -614,7 +657,6 @@ ecore_x_image_to_argb_convert(void *src,
break;
}
break;
break;
default:
return EINA_FALSE;

View File

@ -438,7 +438,7 @@ evas_common_convert_func_get(DATA8 *dest, int w, int h EINA_UNUSED, int depth, D
}
if (depth == 24)
{
if ((rmask == 0x00ff0000) && (gmask == 0x0000ff00) && (bmask == 0x000000ff))
if ((rmask == 0x000000ff) && (gmask == 0x0000ff00) && (bmask == 0x00ff0000))
{
if (rotation == 0)
return evas_common_convert_rgba_to_24bpp_rgb_888;
@ -448,7 +448,7 @@ evas_common_convert_func_get(DATA8 *dest, int w, int h EINA_UNUSED, int depth, D
if (rotation == 0)
return evas_common_convert_rgba_to_24bpp_rgb_666;
}
if ((rmask == 0x000000ff) && (gmask == 0x0000ff00) && (bmask == 0x00ff0000))
if ((rmask == 0x00ff0000) && (gmask == 0x0000ff00) && (bmask == 0x000000ff))
{
if (rotation == 0)
return evas_common_convert_rgba_to_24bpp_bgr_888;

View File

@ -22,7 +22,7 @@ evas_common_convert_rgba_to_24bpp_rgb_888(DATA32 *src, DATA8 *dst, int src_jump,
dst_ptr+=3;
}
src_ptr += src_jump;
dst_ptr += (dst_jump * 3);
dst_ptr += dst_jump;
}
return;
}
@ -53,7 +53,7 @@ evas_common_convert_rgba_to_24bpp_rgb_666(DATA32 *src, DATA8 *dst, int src_jump,
dst_ptr+=3;
}
src_ptr += src_jump;
dst_ptr += (dst_jump * 3);
dst_ptr += dst_jump;
}
return;
}
@ -79,7 +79,7 @@ evas_common_convert_rgba_to_24bpp_bgr_888(DATA32 *src, DATA8 *dst, int src_jump,
dst_ptr+=3;
}
src_ptr += src_jump;
dst_ptr += (dst_jump * 3);
dst_ptr += dst_jump;
}
return;
}

View File

@ -89,7 +89,7 @@ struct _Outbuf
Pixmap mask;
Visual *vis;
Colormap cmap;
int depth, shm;
int depth, imdepth, shm;
GC gc, gcm;
unsigned char swap : 1;
unsigned char bit_swap : 1;
@ -104,7 +104,7 @@ struct _Outbuf
xcb_pixmap_t mask;
xcb_visualtype_t *visual;
xcb_colormap_t cmap;
int depth, shm;
int depth, imdepth, shm;
xcb_gcontext_t gc, gcm;
unsigned char swap : 1;
unsigned char bit_swap : 1;

View File

@ -87,7 +87,8 @@ Outbuf *
evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha)
{
Outbuf *buf = NULL;
Gfx_Func_Convert func_conv= NULL;
Gfx_Func_Convert func_conv = NULL;
Xcb_Output_Buffer *xob;
const xcb_setup_t *setup;
if (!(buf = calloc(1, sizeof(Outbuf))))
@ -110,6 +111,27 @@ evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_co
buf->priv.destination_alpha = alpha;
buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen);
xob =
evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
buf->priv.x11.xcb.visual,
buf->priv.x11.xcb.depth,
1, 1, buf->priv.x11.xcb.shm,
NULL);
if (!xob) buf->priv.x11.xcb.shm = 0;
xob =
evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
buf->priv.x11.xcb.visual,
buf->priv.x11.xcb.depth,
1, 1, buf->priv.x11.xcb.shm,
NULL);
if (!xob)
{
free(buf);
return NULL;
}
buf->priv.x11.xcb.imdepth = evas_software_xcb_output_buffer_depth(xob);
evas_software_xcb_output_buffer_free(xob, EINA_FALSE);
eina_array_step_set(&buf->priv.onebuf_regions, sizeof(Eina_Array), 8);
#ifdef WORDS_BIGENDIAN
@ -287,8 +309,11 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
use_shm = buf->priv.x11.xcb.shm;
if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) &&
(buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff))
if ((buf->rot == 0) &&
(buf->priv.x11.xcb.imdepth == 32) &&
(buf->priv.mask.r == 0xff0000) &&
(buf->priv.mask.g == 0x00ff00) &&
(buf->priv.mask.b == 0x0000ff))
{
obr->xcbob =
evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
@ -427,8 +452,11 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
use_shm = buf->priv.x11.xcb.shm;
alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) &&
(buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff))
if ((buf->rot == 0) &&
(buf->priv.x11.xcb.imdepth == 32) &&
(buf->priv.mask.r == 0xff0000) &&
(buf->priv.mask.g == 0x00ff00) &&
(buf->priv.mask.b == 0x0000ff))
{
obr->xcbob =
_find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual,
@ -839,13 +867,35 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in
if (data != (unsigned char *)src_data)
{
if (buf->priv.pal)
func_conv(src_data, data, update->cache_entry.w - w,
(bpl / (buf->depth / 8)) - obr->w,
obr->w, obr->h, x, y, buf->priv.pal->lookup);
{
func_conv(src_data, data, update->cache_entry.w - w,
bpl - obr->w, obr->w, obr->h, x, y,
buf->priv.pal->lookup);
}
else
func_conv(src_data, data, update->cache_entry.w - w,
(bpl / (buf->depth / 8)) - obr->w,
obr->w, obr->h, x, y, NULL);
{
int pixelb = evas_software_xcb_output_buffer_depth(obr->xob) / 8;
int run;
int dstjump;
if (pixelb == 3)
{
run = obr->w * pixelb;
dstjump = bpl - run;
}
else if ((pixelb == 2) || (pixelb == 4))
{
run = obr->w;
dstjump = (bpl / pixelb) - run;
}
else
{
run = obr->w;
dstjump = bpl - run;
}
func_conv(src_data, data, update->cache_entry.w - w, dstjump,
obr->w, obr->h, x, y, NULL);
}
}
#if 1
#else
@ -1068,7 +1118,7 @@ _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int
return evas_software_xcb_output_buffer_new(conn, vis, depth, w, h,
shm, data);
lbytes = (((w + 31) / 32) * 4);
lbytes = (((w + 63) / 64) * 4);
if (depth > 1)
{
bpp = (depth / 8);
@ -1083,7 +1133,7 @@ _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int
int szdif = 0;
if ((xcbob2->xim->depth != depth) || (xcbob2->visual != vis) ||
(xcbob2->connection != conn)) continue;
(xcbob2->connection != conn) || (xcbob2->w != w)) continue;
szdif = (xcbob2->psize - sz);
if (szdif < 0) continue;
if (szdif == 0)
@ -1110,7 +1160,7 @@ have_xcbob:
_shmpool = eina_list_remove_list(_shmpool, xl);
xcbob->w = w;
xcbob->h = h;
xcbob->bpl = lbytes;
// xcbob->bpl = lbytes;
xcbob->xim->width = xcbob->w;
xcbob->xim->height = xcbob->h;
xcbob->xim->stride = xcbob->bpl;

View File

@ -52,7 +52,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
lbytes = (((w * bpp) + 3) / 4) * 4;
}
else
lbytes = ((w + 31) / 32) * 4;
lbytes = ((w + 63) / 64) * 4;
sz = lbytes * h;
SHMPOOL_LOCK();
EINA_LIST_FOREACH(shmpool, l, xob2)
@ -60,7 +60,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
int szdif;
if ((xob2->xim->depth != depth) || (xob2->visual != v) ||
(xob2->display != d))
(xob2->display != d) || (xob2->w != w))
continue;
szdif = xob2->psize - sz;
if (szdif < 0) continue;
@ -88,7 +88,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
shmpool = eina_list_remove_list(shmpool, xl);
xob->w = w;
xob->h = h;
xob->bpl = lbytes;
// xob->bpl = lbytes;
xob->xim->width = xob->w;
xob->xim->height = xob->h;
xob->xim->bytes_per_line = xob->bpl;
@ -224,7 +224,6 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
buf->priv.x11.xlib.vis,
buf->priv.x11.xlib.depth,
1, 1, buf->priv.x11.xlib.shm, NULL);
conv_func = NULL;
if (xob)
{
@ -341,7 +340,8 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
buf->priv.mask.b, PAL_MODE_NONE,
buf->rot);
}
evas_software_xlib_x_output_buffer_free(xob, 1);
buf->priv.x11.xlib.imdepth = evas_software_xlib_x_output_buffer_depth(xob);
evas_software_xlib_x_output_buffer_free(xob, 1);
if (!conv_func)
{
ERR("At depth: %i, RGB format mask: %08x %08x %08x, "
@ -410,6 +410,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
use_shm = buf->priv.x11.xlib.shm;
if ((buf->rot == 0) &&
(buf->priv.x11.xlib.imdepth == 32) &&
(buf->priv.mask.r == 0xff0000) &&
(buf->priv.mask.g == 0x00ff00) &&
(buf->priv.mask.b == 0x0000ff))
@ -565,6 +566,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
alpha = ((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha));
if ((buf->rot == 0) &&
(buf->priv.x11.xlib.imdepth == 32) &&
(buf->priv.mask.r == 0xff0000) &&
(buf->priv.mask.g == 0x00ff00) &&
(buf->priv.mask.b == 0x0000ff))
@ -1011,21 +1013,34 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
if (buf->priv.pal)
{
if (data != (unsigned char *)src_data)
conv_func(src_data, data,
update->cache_entry.w - w,
bpl /
((evas_software_xlib_x_output_buffer_depth(obr->xob) /
8)) - obr->w, obr->w, obr->h, x, y,
buf->priv.pal->lookup);
conv_func(src_data, data, update->cache_entry.w - w,
bpl - obr->w, obr->w, obr->h, x, y,
buf->priv.pal->lookup);
}
else
{
int pixelb = evas_software_xlib_x_output_buffer_depth(obr->xob) / 8;
int run;
int dstjump;
if (pixelb == 3)
{
run = obr->w * pixelb;
dstjump = bpl - run;
}
else if ((pixelb == 2) || (pixelb == 4))
{
run = obr->w;
dstjump = (bpl / pixelb) - run;
}
else
{
run = obr->w;
dstjump = bpl - run;
}
if (data != (unsigned char *)src_data)
conv_func(src_data, data,
update->cache_entry.w - w,
bpl /
((evas_software_xlib_x_output_buffer_depth(obr->xob) /
8)) - obr->w, obr->w, obr->h, x, y, NULL);
conv_func(src_data, data, update->cache_entry.w - w, dstjump,
obr->w, obr->h, x, y, NULL);
}
#if 1
#else