gdk: support X11 LSBFirst 4-bpp images
This commit is contained in:
parent
5cd79214f3
commit
5d47a3743f
1 changed files with 247 additions and 5 deletions
252
gdk/gdkrgb.c
252
gdk/gdkrgb.c
|
|
@ -2826,6 +2826,90 @@ gdk_rgb_convert_4_pack (GdkRgbInfo *image_info, GdkImage *image,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
static void
|
||||
gdk_rgb_convert_4_pack_lsb (GdkRgbInfo *image_info, GdkImage *image,
|
||||
gint x0, gint y0, gint width, gint height,
|
||||
const guchar *buf, int rowstride,
|
||||
gint x_align, gint y_align,
|
||||
GdkRgbCmap *cmap)
|
||||
{
|
||||
int x, y, ix;
|
||||
gint bpl;
|
||||
guchar *obuf, *obptr;
|
||||
const guchar *bptr, *bp2;
|
||||
gint r, g, b;
|
||||
const guchar *dmp;
|
||||
gint dith;
|
||||
guchar *colorcube_d = image_info->colorcube_d;
|
||||
guchar pix0, pix1;
|
||||
|
||||
bptr = buf;
|
||||
bpl = image->bpl;
|
||||
obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1);
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
|
||||
bp2 = bptr;
|
||||
obptr = obuf;
|
||||
|
||||
x = 0;
|
||||
if (x0 & 1)
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
|
||||
ix = (((r + dith) & 0x100) >> 2) |
|
||||
(((g + 258 - dith) & 0x100) >> 5) |
|
||||
(((b + dith) & 0x100) >> 8);
|
||||
pix1 = (colorcube_d[ix]);
|
||||
*obptr = (*obptr & 0x0F) | (pix1 << 4);
|
||||
obptr++;
|
||||
x++;
|
||||
}
|
||||
while (x + 1 < width)
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
|
||||
ix = (((r + dith) & 0x100) >> 2) |
|
||||
(((g + 258 - dith) & 0x100) >> 5) |
|
||||
(((b + dith) & 0x100) >> 8);
|
||||
pix0 = (colorcube_d[ix]);
|
||||
x++;
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
|
||||
ix = (((r + dith) & 0x100) >> 2) |
|
||||
(((g + 258 - dith) & 0x100) >> 5) |
|
||||
(((b + dith) & 0x100) >> 8);
|
||||
pix1 = (colorcube_d[ix]);
|
||||
x++;
|
||||
}
|
||||
*obptr++ = (pix1 << 4) | pix0;
|
||||
}
|
||||
if (x < width)
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
|
||||
ix = (((r + dith) & 0x100) >> 2) |
|
||||
(((g + 258 - dith) & 0x100) >> 5) |
|
||||
(((b + dith) & 0x100) >> 8);
|
||||
pix0 = (colorcube_d[ix]);
|
||||
*obptr = (*obptr & 0xF0) | pix0;
|
||||
}
|
||||
bptr += rowstride;
|
||||
obuf += bpl;
|
||||
}
|
||||
}
|
||||
#endif /* GDK_WINDOWING_X11 */
|
||||
|
||||
/* This actually works for depths from 3 to 7 */
|
||||
static void
|
||||
gdk_rgb_convert_gray4 (GdkRgbInfo *image_info, GdkImage *image,
|
||||
|
|
@ -2874,7 +2958,7 @@ gdk_rgb_convert_gray4_pack (GdkRgbInfo *image_info, GdkImage *image,
|
|||
gint r, g, b;
|
||||
gint shift;
|
||||
guchar pix0, pix1;
|
||||
/* todo: this is hardcoded to big-endian. Make endian-agile. */
|
||||
/* Pixel 0 is stored in the high nibble. */
|
||||
|
||||
bptr = buf;
|
||||
bpl = image->bpl;
|
||||
|
|
@ -2920,6 +3004,67 @@ gdk_rgb_convert_gray4_pack (GdkRgbInfo *image_info, GdkImage *image,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
static void
|
||||
gdk_rgb_convert_gray4_pack_lsb (GdkRgbInfo *image_info, GdkImage *image,
|
||||
gint x0, gint y0, gint width, gint height,
|
||||
const guchar *buf, int rowstride,
|
||||
gint x_align, gint y_align, GdkRgbCmap *cmap)
|
||||
{
|
||||
int x, y;
|
||||
gint bpl;
|
||||
guchar *obuf, *obptr;
|
||||
const guchar *bptr, *bp2;
|
||||
gint r, g, b;
|
||||
gint shift;
|
||||
guchar pix0, pix1;
|
||||
/* X11 LSBFirst stores pixel 0 in the low nibble. */
|
||||
|
||||
bptr = buf;
|
||||
bpl = image->bpl;
|
||||
obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1);
|
||||
shift = 9 - image_info->visual->depth;
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
bp2 = bptr;
|
||||
obptr = obuf;
|
||||
|
||||
x = 0;
|
||||
if (x0 & 1)
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
pix1 = (g + ((b + r) >> 1)) >> shift;
|
||||
*obptr = (*obptr & 0x0F) | (pix1 << 4);
|
||||
obptr++;
|
||||
x++;
|
||||
}
|
||||
while (x < width)
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
pix0 = (g + ((b + r) >> 1)) >> shift;
|
||||
x++;
|
||||
if (x == width)
|
||||
pix1 = (*obptr & 0xF0) >> 4;
|
||||
else
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
pix1 = (g + ((b + r) >> 1)) >> shift;
|
||||
x++;
|
||||
}
|
||||
*obptr++ = (pix1 << 4) | pix0;
|
||||
}
|
||||
bptr += rowstride;
|
||||
obuf += bpl;
|
||||
}
|
||||
}
|
||||
#endif /* GDK_WINDOWING_X11 */
|
||||
|
||||
/* This actually works for depths from 3 to 7 */
|
||||
static void
|
||||
gdk_rgb_convert_gray4_d (GdkRgbInfo *image_info, GdkImage *image,
|
||||
|
|
@ -2976,7 +3121,7 @@ gdk_rgb_convert_gray4_d_pack (GdkRgbInfo *image_info, GdkImage *image,
|
|||
gint prec, right;
|
||||
gint gray;
|
||||
guchar pix0, pix1;
|
||||
/* todo: this is hardcoded to big-endian. Make endian-agile. */
|
||||
/* Pixel 0 is stored in the high nibble. */
|
||||
|
||||
bptr = buf;
|
||||
bpl = image->bpl;
|
||||
|
|
@ -3030,6 +3175,77 @@ gdk_rgb_convert_gray4_d_pack (GdkRgbInfo *image_info, GdkImage *image,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
static void
|
||||
gdk_rgb_convert_gray4_d_pack_lsb (GdkRgbInfo *image_info, GdkImage *image,
|
||||
gint x0, gint y0, gint width, gint height,
|
||||
const guchar *buf, int rowstride,
|
||||
gint x_align, gint y_align, GdkRgbCmap *cmap)
|
||||
{
|
||||
int x, y;
|
||||
gint bpl;
|
||||
guchar *obuf, *obptr;
|
||||
const guchar *bptr, *bp2;
|
||||
gint r, g, b;
|
||||
const guchar *dmp;
|
||||
gint prec, right;
|
||||
gint gray;
|
||||
guchar pix0, pix1;
|
||||
/* X11 LSBFirst stores pixel 0 in the low nibble. */
|
||||
|
||||
bptr = buf;
|
||||
bpl = image->bpl;
|
||||
obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1);
|
||||
prec = image_info->visual->depth;
|
||||
right = 8 - prec;
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
bp2 = bptr;
|
||||
obptr = obuf;
|
||||
dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
|
||||
|
||||
x = 0;
|
||||
if (x0 & 1)
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
gray = (g + ((b + r) >> 1)) >> 1;
|
||||
gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec;
|
||||
pix1 = (gray - (gray >> prec)) >> right;
|
||||
*obptr = (*obptr & 0x0F) | (pix1 << 4);
|
||||
obptr++;
|
||||
x++;
|
||||
}
|
||||
while (x < width)
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
gray = (g + ((b + r) >> 1)) >> 1;
|
||||
gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec;
|
||||
pix0 = (gray - (gray >> prec)) >> right;
|
||||
x++;
|
||||
if (x == width)
|
||||
pix1 = (*obptr & 0xF0) >> 4;
|
||||
else
|
||||
{
|
||||
r = *bp2++;
|
||||
g = *bp2++;
|
||||
b = *bp2++;
|
||||
gray = (g + ((b + r) >> 1)) >> 1;
|
||||
gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec;
|
||||
pix1 = (gray - (gray >> prec)) >> right;
|
||||
x++;
|
||||
}
|
||||
*obptr++ = (pix1 << 4) | pix0;
|
||||
}
|
||||
bptr += rowstride;
|
||||
obuf += bpl;
|
||||
}
|
||||
}
|
||||
#endif /* GDK_WINDOWING_X11 */
|
||||
|
||||
static void
|
||||
gdk_rgb_convert_1 (GdkRgbInfo *image_info, GdkImage *image,
|
||||
gint x0, gint y0, gint width, gint height,
|
||||
|
|
@ -3512,16 +3728,42 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
|
|||
{
|
||||
conv = gdk_rgb_convert_4;
|
||||
}
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
else if (bpp == 4 && depth <= 4 && depth >= 2 &&
|
||||
(vtype == GDK_VISUAL_STATIC_GRAY
|
||||
|| vtype == GDK_VISUAL_GRAYSCALE))
|
||||
(vtype == GDK_VISUAL_STATIC_GRAY
|
||||
|| vtype == GDK_VISUAL_GRAYSCALE))
|
||||
{
|
||||
if (byte_order == GDK_LSB_FIRST)
|
||||
{
|
||||
conv = gdk_rgb_convert_gray4_pack_lsb;
|
||||
conv_d = gdk_rgb_convert_gray4_d_pack_lsb;
|
||||
}
|
||||
else
|
||||
{
|
||||
conv = gdk_rgb_convert_gray4_pack;
|
||||
conv_d = gdk_rgb_convert_gray4_d_pack;
|
||||
}
|
||||
}
|
||||
#else
|
||||
else if (bpp == 4 && depth <= 4 && depth >= 2 &&
|
||||
(vtype == GDK_VISUAL_STATIC_GRAY
|
||||
|| vtype == GDK_VISUAL_GRAYSCALE))
|
||||
{
|
||||
conv = gdk_rgb_convert_gray4_pack;
|
||||
conv_d = gdk_rgb_convert_gray4_d_pack;
|
||||
}
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
else if (bpp == 4 && depth <= 4 && depth >= 2 &&
|
||||
vtype == GDK_VISUAL_STATIC_COLOR)
|
||||
vtype == GDK_VISUAL_STATIC_COLOR)
|
||||
conv = (byte_order == GDK_LSB_FIRST
|
||||
? gdk_rgb_convert_4_pack_lsb
|
||||
: gdk_rgb_convert_4_pack);
|
||||
#else
|
||||
else if (bpp == 4 && depth <= 4 && depth >= 2 &&
|
||||
vtype == GDK_VISUAL_STATIC_COLOR)
|
||||
conv = gdk_rgb_convert_4_pack;
|
||||
#endif
|
||||
|
||||
if (!conv)
|
||||
g_error ("Visual type=%d depth=%d, image bpp=%d, %s first\n"
|
||||
|
|
|
|||
Loading…
Reference in a new issue