This source file includes following definitions.
- __imlib_RenderGetPixel
- __imlib_generic_render
- __imlib_RenderDisconnect
- __imlib_RenderImage
- __imlib_RenderImageSkewed
#include "common.h"
#ifdef BUILD_X11
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/XShm.h>
#include "colormod.h"
#include "image.h"
#include "scale.h"
#include "ximage.h"
#include "context.h"
#include "rgba.h"
#include "color.h"
#include "grab.h"
#include "blend.h"
#include "rend.h"
#include "rotate.h"
#define X_MAX_DIM 46340
#define LINESIZE 16
DATA32
__imlib_RenderGetPixel(Display * d, Drawable w, Visual * v, Colormap cm,
int depth, DATA8 r, DATA8 g, DATA8 b)
{
Context *ct;
ct = __imlib_GetContext(d, v, cm, depth);
if (ct->palette)
{
switch (ct->palette_type)
{
case 0:
return ct->palette[((r >> 0) & 0xe0) |
((g >> 3) & 0x1b) | ((b >> 6) & 0x02)];
break;
case 1:
return ct->palette[((r >> 0) & 0xe0) |
((g >> 3) & 0x1b) | ((b >> 6) & 0x02)];
break;
case 2:
return ct->palette[((r >> 0) & 0xe0) |
((g >> 3) & 0x1b) | ((b >> 6) & 0x02)];
break;
case 3:
return ct->palette[((r >> 0) & 0xe0) |
((g >> 3) & 0x1b) | ((b >> 6) & 0x02)];
break;
case 4:
return ct->palette[((r >> 0) & 0xe0) |
((g >> 3) & 0x1b) | ((b >> 6) & 0x02)];
break;
case 5:
return ct->palette[((r >> 0) & 0xe0) |
((g >> 3) & 0x1b) | ((b >> 6) & 0x02)];
break;
case 6:
return ct->palette[((r >> 0) & 0xe0) |
((g >> 3) & 0x1b) | ((b >> 6) & 0x02)];
break;
case 7:
return ct->palette[((int)(((double)r / 255) * 5.0) * 36) +
((int)(((double)g / 255) * 5.0) * 6) +
((int)(((double)b / 255) * 5.0))];
break;
default:
return 0;
}
}
else
{
unsigned int rm, gm, bm;
int i, rshift = 0, gshift = 0, bshift = 0;
DATA32 val;
rm = v->red_mask;
gm = v->green_mask;
bm = v->blue_mask;
if ((rm == 0xf800) && (gm == 0x7e0) && (bm == 0x1f))
{
return (((r << 8) & 0xf800) |
((g << 3) & 0x07e0) | ((b >> 3) & 0x001f));
}
if ((rm == 0xff0000) && (gm == 0xff00) && (bm == 0xff))
{
return (((r << 16) & 0xff0000) |
((g << 8) & 0x00ff00) | ((r) & 0x0000ff));
}
if ((rm == 0x7c00) && (gm == 0x3e0) && (bm == 0x1f))
{
return (((r << 7) & 0x7c00) |
((g << 2) & 0x03e0) | ((b >> 3) & 0x001f));
}
for (i = 31; i >= 0; i--)
{
if (rm >= (1 << i))
{
rshift = i - 7;
break;
}
}
for (i = 31; i >= 0; i--)
{
if (gm >= (1 << i))
{
gshift = i - 7;
break;
}
}
for (i = 31; i >= 0; i--)
{
if (bm >= (1 << i))
{
bshift = i - 7;
break;
}
}
if (rshift >= 0)
val = ((r << rshift) & rm);
else
val = ((r >> (-rshift)) & rm);
if (gshift >= 0)
val |= ((g << gshift) & gm);
else
val |= ((g >> (-gshift)) & gm);
if (bshift >= 0)
val |= ((b << bshift) & bm);
else
val |= ((b >> (-bshift)) & bm);
return val;
}
return 0;
}
static void
__imlib_generic_render(DATA32 * src, int jump, int w, int h, int dx, int dy,
XImage * xim, Visual * v, Context * ct)
{
unsigned int x, y, r, g, b, val, hh;
unsigned int rmask, gmask, bmask;
int i, rshift, gshift, bshift;
const DATA8 _dither_88[8][8] = {
{0, 32, 8, 40, 2, 34, 10, 42},
{48, 16, 56, 24, 50, 18, 58, 26},
{12, 44, 4, 36, 14, 46, 6, 38},
{60, 28, 52, 20, 62, 30, 54, 22},
{3, 35, 11, 43, 1, 33, 9, 41},
{51, 19, 59, 27, 49, 17, 57, 25},
{15, 47, 7, 39, 13, 45, 5, 37},
{63, 31, 55, 23, 61, 29, 53, 21}
};
if (xim->depth == 1)
{
hh = dy + h;
for (y = dy; y < hh; y++)
{
for (x = dx; x < w; x++)
{
r = R_VAL(src);
g = G_VAL(src);
b = B_VAL(src);
val = (R_VAL(src) + G_VAL(src) + B_VAL(src)) / 12;
if (val > _dither_88[x & 0x3][y & 0x3])
val = ct->palette[1];
else
val = ct->palette[0];
XPutPixel(xim, x, y, val);
src++;
}
}
return;
}
rmask = xim->red_mask;
gmask = xim->green_mask;
bmask = xim->blue_mask;
rshift = 0;
gshift = 0;
bshift = 0;
for (i = 31; i >= 0; i--)
{
if (rmask >= (1 << i))
{
rshift = i - 7;
break;
}
}
for (i = 31; i >= 0; i--)
{
if (gmask >= (1 << i))
{
gshift = i - 7;
break;
}
}
for (i = 31; i >= 0; i--)
{
if (bmask >= (1 << i))
{
bshift = i - 7;
break;
}
}
hh = dy + h;
for (y = dy; y < hh; y++)
{
for (x = dx; x < w; x++)
{
r = R_VAL(src);
if (rshift >= 0)
val = ((r << rshift) & rmask);
else
val = ((r >> (-rshift)) & rmask);
g = G_VAL(src);
if (gshift >= 0)
val |= ((g << gshift) & gmask);
else
val |= ((g >> (-gshift)) & gmask);
b = B_VAL(src);
if (bshift >= 0)
val |= ((b << bshift) & bmask);
else
val |= ((b >> (-bshift)) & bmask);
XPutPixel(xim, x, y, val);
src++;
}
}
}
static Display *disp = NULL;
static GC gc = NULL;
static GC gcm = NULL;
static int last_depth = 0;
void
__imlib_RenderDisconnect(Display * d)
{
if (d != disp)
return;
disp = NULL;
gc = gcm = NULL;
last_depth = 0;
}
void
__imlib_RenderImage(Display * d, ImlibImage * im,
Drawable w, Drawable m,
Visual * v, Colormap cm, int depth,
int sx, int sy, int sw, int sh,
int dx, int dy, int dw, int dh,
char antialias, char hiq, char blend, char dither_mask,
int mat, ImlibColorModifier * cmod, ImlibOp op)
{
XImage *xim = NULL, *mxim = NULL;
Context *ct;
DATA32 *buf = NULL, *pointer = NULL, *back = NULL;
int y, h, hh, jump;
XGCValues gcv;
ImlibScaleInfo *scaleinfo = NULL;
int psx, psy, psw, psh;
char shm = 0;
ImlibRGBAFunction rgbaer;
ImlibMaskFunction masker = NULL;
ImlibBlendFunction blender = NULL;
int do_mmx;
blender = __imlib_GetBlendFunction(op, 1, 0,
(!(im->flags & F_HAS_ALPHA)), NULL);
if ((dw == 0) || (dh == 0))
return;
if ((sw <= 0) || (sh <= 0))
return;
if ((abs(dw) > X_MAX_DIM) || (abs(dh) > X_MAX_DIM))
return;
psx = sx;
psy = sy;
psw = sw;
psh = sh;
CLIP(sx, sy, sw, sh, 0, 0, im->w, im->h);
if (psx != sx)
dx = (dx * sx) / psx;
if (psy != sy)
dy = (dy * sy) / psy;
if (psw != sw)
dw = (dw * sw) / psw;
if (psh != sh)
dh = (dh * sh) / psh;
if ((dw == 0) || (dh == 0))
return;
if ((sw <= 0) || (sh <= 0))
return;
if ((abs(dw) > X_MAX_DIM) || (abs(dh) > X_MAX_DIM))
return;
if (!((sw == dw) && (sh == dh)))
{
scaleinfo = __imlib_CalcScaleInfo(im, sw, sh, dw, dh, antialias);
if (!scaleinfo)
return;
}
dw = abs(dw);
dh = abs(dh);
ct = __imlib_GetContext(d, v, cm, depth);
__imlib_RGBASetupContext(ct);
if ((blend) && (IMAGE_HAS_ALPHA(im)))
{
back = malloc(dw * dh * sizeof(DATA32));
if (!__imlib_GrabDrawableToRGBA
(back, 0, 0, dw, dh, d, w, 0, v, cm, depth, dx, dy, dw, dh, 0, 1))
{
free(back);
back = NULL;
}
}
xim = __imlib_ProduceXImage(d, v, depth, dw, dh, &shm);
if (!xim)
{
__imlib_FreeScaleInfo(scaleinfo);
if (back)
free(back);
return;
}
if (m)
{
mxim = __imlib_ProduceXImage(d, v, 1, dw, dh, &shm);
if (!mxim)
{
__imlib_ConsumeXImage(d, xim);
__imlib_FreeScaleInfo(scaleinfo);
if (back)
free(back);
return;
}
memset(mxim->data, 0, mxim->bytes_per_line * mxim->height);
}
if (scaleinfo)
{
buf = malloc(dw * LINESIZE * sizeof(DATA32));
if (!buf)
{
__imlib_ConsumeXImage(d, xim);
if (m)
__imlib_ConsumeXImage(d, mxim);
__imlib_FreeScaleInfo(scaleinfo);
if (back)
free(back);
return;
}
}
h = dh;
rgbaer = __imlib_GetRGBAFunction(xim->bits_per_pixel,
v->red_mask, v->green_mask, v->blue_mask,
hiq, ct->palette_type);
if (m)
masker = __imlib_GetMaskFunction(dither_mask);
#ifdef DO_MMX_ASM
do_mmx = __imlib_get_cpuid() & CPUID_MMX;
#endif
for (y = 0; y < dh; y += LINESIZE)
{
hh = LINESIZE;
if (h < LINESIZE)
hh = h;
if (scaleinfo)
{
if (antialias)
{
#ifdef DO_MMX_ASM
if (do_mmx)
__imlib_Scale_mmx_AARGBA(scaleinfo, buf,
((sx * dw) / sw),
((sy * dh) / sh) + y,
0, 0, dw, hh, dw, im->w);
else
#endif
if (IMAGE_HAS_ALPHA(im))
__imlib_ScaleAARGBA(scaleinfo, buf, ((sx * dw) / sw),
((sy * dh) / sh) + y,
0, 0, dw, hh, dw, im->w);
else
__imlib_ScaleAARGB(scaleinfo, buf, ((sx * dw) / sw),
((sy * dh) / sh) + y,
0, 0, dw, hh, dw, im->w);
}
else
__imlib_ScaleSampleRGBA(scaleinfo, buf, ((sx * dw) / sw),
((sy * dh) / sh) + y, 0, 0, dw, hh, dw);
jump = 0;
pointer = buf;
if (cmod)
__imlib_DataCmodApply(buf, dw, hh, 0, NULL, cmod);
}
else
{
if (cmod)
{
if (!buf)
buf = malloc(im->w * LINESIZE * sizeof(DATA32));
if (!buf)
{
__imlib_ConsumeXImage(d, xim);
if (m)
__imlib_ConsumeXImage(d, mxim);
__imlib_FreeScaleInfo(scaleinfo);
if (back)
free(back);
return;
}
memcpy(buf, im->data + ((y + sy) * im->w),
im->w * hh * sizeof(DATA32));
__imlib_DataCmodApply(buf, im->w, hh, 0, NULL, cmod);
pointer = buf + sx;
jump = im->w - sw;
}
else
{
jump = im->w - sw;
pointer = im->data + ((y + sy) * im->w) + sx;
}
}
if (back)
{
blender(pointer, jump + dw, back + (y * dw), dw, dw, hh, NULL);
pointer = back + (y * dw);
jump = 0;
}
if (rgbaer)
rgbaer(pointer, jump,
((DATA8 *) xim->data) + (y * (xim->bytes_per_line)),
xim->bytes_per_line, dw, hh, dx, dy + y);
else
__imlib_generic_render(pointer, jump, dw, hh, 0, y, xim, v, ct);
if (m)
masker(pointer, jump,
((DATA8 *) mxim->data) + (y * (mxim->bytes_per_line)),
mxim->bytes_per_line, dw, hh, dx, dy + y, mat);
h -= LINESIZE;
}
if (buf)
free(buf);
if (scaleinfo)
__imlib_FreeScaleInfo(scaleinfo);
if (back)
free(back);
if ((gc) && ((last_depth != depth) || (disp != d)))
{
XFreeGC(disp, gc);
gc = 0;
}
if (!gc)
{
disp = d;
last_depth = depth;
gcv.graphics_exposures = False;
gc = XCreateGC(d, w, GCGraphicsExposures, &gcv);
}
if (m)
{
if ((gcm) && (disp != d))
{
XFreeGC(disp, gcm);
gcm = 0;
}
if (!gcm)
{
gcv.graphics_exposures = False;
gcm = XCreateGC(d, m, GCGraphicsExposures, &gcv);
}
if (shm)
XShmPutImage(d, m, gcm, mxim, 0, 0, dx, dy, dw, dh, False);
else
XPutImage(d, m, gcm, mxim, 0, 0, dx, dy, dw, dh);
}
if (shm)
XShmPutImage(d, w, gc, xim, 0, 0, dx, dy, dw, dh, False);
else
XPutImage(d, w, gc, xim, 0, 0, dx, dy, dw, dh);
if (shm)
XSync(d, False);
__imlib_ConsumeXImage(d, xim);
if (m)
__imlib_ConsumeXImage(d, mxim);
}
void
__imlib_RenderImageSkewed(Display * d, ImlibImage * im, Drawable w, Drawable m,
Visual * v, Colormap cm, int depth,
int sx, int sy, int sw, int sh, int dx, int dy,
int hsx, int hsy, int vsx, int vsy,
char antialias, char hiq, char blend,
char dither_mask, int mat, ImlibColorModifier * cmod,
ImlibOp op)
{
Context *ct;
int dx1, dy1, dx2, dy2, dw, dh, tsx, tsy;
ImlibImage *back;
dx1 = dx2 = dx;
dy1 = dy2 = dy;
if (hsx < 0)
dx1 += hsx;
else
dx2 += hsx;
if (hsy < 0)
dy1 += hsy;
else
dy2 += hsy;
tsx = vsx;
tsy = vsy;
if (!tsx && !tsy)
{
tsy = (hsx * im->h) / im->w;
tsx = -(hsy * im->h) / im->w;
}
if (tsx < 0)
dx1 += tsx;
else
dx2 += tsx;
if (tsy < 0)
dy1 += tsy;
else
dy2 += tsy;
if ((dx2 < 0) || (dy2 < 0))
return;
dw = dx2 - dx1;
dh = dy2 - dy1;
if ((dw <= 0) || (dh <= 0))
return;
if (dx1 < 0)
{
dw += dx1;
dx1 = 0;
}
if (dy1 < 0)
{
dh += dy1;
dy1 = 0;
}
ct = __imlib_GetContext(d, v, cm, depth);
back = __imlib_CreateImage(dw, dh, NULL);
back->data = calloc(dw * dh, sizeof(DATA32));
__imlib_GrabDrawableToRGBA(back->data, 0, 0, dw, dh, d, w, 0, v, cm,
depth, dx1, dy1, dw, dh, 0, 1);
__imlib_BlendImageToImageSkewed(im, back, antialias, 1, 0, sx, sy, sw, sh,
dx - dx1, dy - dy1, hsx, hsy, vsx, vsy,
cmod, op, 0, 0, 0, 0);
__imlib_RenderImage(d, back, w, m, v, cm, depth, 0, 0, dw, dh,
dx1, dy1, dw, dh, 0, hiq, 0, dither_mask, mat, 0,
OP_COPY);
__imlib_FreeImage(back);
}
#endif