gdk: cache native indexed conversion tables
This commit is contained in:
parent
e947badaa4
commit
c3f11d2bf7
1 changed files with 180 additions and 52 deletions
236
gdk/gdkrgb.c
236
gdk/gdkrgb.c
|
|
@ -117,7 +117,7 @@ struct _GdkRgbCmapInfo
|
||||||
GdkRgbInfo *image_info;
|
GdkRgbInfo *image_info;
|
||||||
GdkRgbCmap *cmap;
|
GdkRgbCmap *cmap;
|
||||||
|
|
||||||
guchar lut[256]; /* For 8-bit modes */
|
guchar lut[1]; /* variable-sized private LUT */
|
||||||
};
|
};
|
||||||
|
|
||||||
static GdkRgbCmapInfo *gdk_rgb_cmap_get_info (GdkRgbCmap *cmap, GdkRgbInfo *image_info);
|
static GdkRgbCmapInfo *gdk_rgb_cmap_get_info (GdkRgbCmap *cmap, GdkRgbInfo *image_info);
|
||||||
|
|
@ -3445,29 +3445,22 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
|
||||||
const guchar *buf, gint rowstride,
|
const guchar *buf, gint rowstride,
|
||||||
gint x_align, gint y_align, GdkRgbCmap *cmap)
|
gint x_align, gint y_align, GdkRgbCmap *cmap)
|
||||||
{
|
{
|
||||||
union {
|
GdkRgbCmapInfo *cmap_info;
|
||||||
guint16 u16[256];
|
gint y;
|
||||||
guint32 u32[256];
|
|
||||||
} lut;
|
|
||||||
gint i, y;
|
|
||||||
gint bpl = image->bpl;
|
gint bpl = image->bpl;
|
||||||
const guchar *src = buf;
|
const guchar *src = buf;
|
||||||
guchar *dst = ((guchar *) image->mem) + y0 * bpl + x0 * image_info->bpp;
|
guchar *dst = ((guchar *) image->mem) +
|
||||||
|
y0 * bpl + x0 * image_info->bpp;
|
||||||
|
|
||||||
|
(void) x_align;
|
||||||
|
(void) y_align;
|
||||||
|
|
||||||
|
cmap_info = gdk_rgb_cmap_get_info (cmap, image_info);
|
||||||
|
g_assert (cmap_info != NULL);
|
||||||
|
|
||||||
if (image_info->bpp == 2)
|
if (image_info->bpp == 2)
|
||||||
{
|
{
|
||||||
guint is_565 = image_info->format == GDK_RGB_FORMAT_565;
|
const guint16 *lut = (const guint16 *) cmap_info->lut;
|
||||||
guint red_shift = 9 - is_565;
|
|
||||||
guint green_shift = 6 - is_565;
|
|
||||||
guint32 green_mask = 0x00f800 | (is_565 << 10);
|
|
||||||
|
|
||||||
for (i = 0; i < cmap->n_colors; i++)
|
|
||||||
{
|
|
||||||
guint32 rgb = cmap->colors[i];
|
|
||||||
lut.u16[i] = ((rgb & 0xf80000) >> red_shift) |
|
|
||||||
((rgb & green_mask) >> green_shift) |
|
|
||||||
((rgb & 0x0000f8) >> 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
|
@ -3476,7 +3469,7 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
|
||||||
gint x;
|
gint x;
|
||||||
|
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
q[x] = lut.u16[p[x]];
|
q[x] = lut[p[x]];
|
||||||
|
|
||||||
src += rowstride;
|
src += rowstride;
|
||||||
dst += bpl;
|
dst += bpl;
|
||||||
|
|
@ -3484,13 +3477,7 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gboolean little = image_info->format == GDK_RGB_FORMAT_0888;
|
const guint32 *lut = (const guint32 *) cmap_info->lut;
|
||||||
|
|
||||||
for (i = 0; i < cmap->n_colors; i++)
|
|
||||||
{
|
|
||||||
guint32 pixel = 0xff000000U | cmap->colors[i];
|
|
||||||
lut.u32[i] = little ? GUINT32_TO_LE (pixel) : GUINT32_TO_BE (pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
|
@ -3499,7 +3486,7 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
|
||||||
gint x;
|
gint x;
|
||||||
|
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
q[x] = lut.u32[p[x]];
|
q[x] = lut[p[x]];
|
||||||
|
|
||||||
src += rowstride;
|
src += rowstride;
|
||||||
dst += bpl;
|
dst += bpl;
|
||||||
|
|
@ -3508,6 +3495,61 @@ gdk_rgb_convert_indexed_lut (GdkRgbInfo *image_info, GdkImage *image,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFINE_GDK_RGB_INDEXED_888_CONVERTER(name, shift0, shift2) \
|
||||||
|
static void \
|
||||||
|
name (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) \
|
||||||
|
{ \
|
||||||
|
const guchar *src = buf; \
|
||||||
|
guchar *dst = ((guchar *) image->mem) + \
|
||||||
|
y0 * image->bpl + x0 * 3; \
|
||||||
|
gint x, y; \
|
||||||
|
\
|
||||||
|
(void) image_info; \
|
||||||
|
(void) x_align; \
|
||||||
|
(void) y_align; \
|
||||||
|
\
|
||||||
|
for (y = 0; y < height; y++) \
|
||||||
|
{ \
|
||||||
|
const guchar *p = src; \
|
||||||
|
guchar *q = dst; \
|
||||||
|
\
|
||||||
|
for (x = 0; x < width; x++) \
|
||||||
|
{ \
|
||||||
|
guint32 rgb = cmap->colors[p[x]]; \
|
||||||
|
\
|
||||||
|
q[0] = rgb >> (shift0); \
|
||||||
|
q[1] = rgb >> 8; \
|
||||||
|
q[2] = rgb >> (shift2); \
|
||||||
|
q += 3; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
src += rowstride; \
|
||||||
|
dst += image->bpl; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_GDK_RGB_INDEXED_888_CONVERTER (
|
||||||
|
gdk_rgb_convert_indexed_888_lsb,
|
||||||
|
0,
|
||||||
|
16)
|
||||||
|
|
||||||
|
DEFINE_GDK_RGB_INDEXED_888_CONVERTER (
|
||||||
|
gdk_rgb_convert_indexed_888_msb,
|
||||||
|
16,
|
||||||
|
0)
|
||||||
|
|
||||||
|
#undef DEFINE_GDK_RGB_INDEXED_888_CONVERTER
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_rgb_gray_to_stage (guchar *stage,
|
gdk_rgb_gray_to_stage (guchar *stage,
|
||||||
const guchar *buf, gint rowstride, gint width, gint height,
|
const guchar *buf, gint rowstride, gint width, gint height,
|
||||||
|
|
@ -4002,6 +4044,7 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
|
||||||
case GDK_RGB_FORMAT_555_BR:
|
case GDK_RGB_FORMAT_555_BR:
|
||||||
conv_gray = gdk_rgb_convert_gray_555_br;
|
conv_gray = gdk_rgb_convert_gray_555_br;
|
||||||
conv_gray_d = gdk_rgb_convert_gray_555_br;
|
conv_gray_d = gdk_rgb_convert_gray_555_br;
|
||||||
|
conv_indexed = gdk_rgb_convert_indexed_lut;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_RGB_FORMAT_565:
|
case GDK_RGB_FORMAT_565:
|
||||||
|
|
@ -4014,6 +4057,7 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
|
||||||
case GDK_RGB_FORMAT_565_BR:
|
case GDK_RGB_FORMAT_565_BR:
|
||||||
conv_gray = gdk_rgb_convert_gray_565_br;
|
conv_gray = gdk_rgb_convert_gray_565_br;
|
||||||
conv_gray_d = gdk_rgb_convert_gray_565_br;
|
conv_gray_d = gdk_rgb_convert_gray_565_br;
|
||||||
|
conv_indexed = gdk_rgb_convert_indexed_lut;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_RGB_FORMAT_0888:
|
case GDK_RGB_FORMAT_0888:
|
||||||
|
|
@ -4033,26 +4077,35 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_RGB_FORMAT_888_LSB:
|
case GDK_RGB_FORMAT_888_LSB:
|
||||||
|
conv_gray = gdk_rgb_convert_gray_888;
|
||||||
|
conv_gray_d = gdk_rgb_convert_gray_888;
|
||||||
|
conv_indexed = gdk_rgb_convert_indexed_888_lsb;
|
||||||
|
break;
|
||||||
|
|
||||||
case GDK_RGB_FORMAT_888_MSB:
|
case GDK_RGB_FORMAT_888_MSB:
|
||||||
conv_gray = gdk_rgb_convert_gray_888;
|
conv_gray = gdk_rgb_convert_gray_888;
|
||||||
conv_gray_d = gdk_rgb_convert_gray_888;
|
conv_gray_d = gdk_rgb_convert_gray_888;
|
||||||
|
conv_indexed = gdk_rgb_convert_indexed_888_msb;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_RGB_FORMAT_8880_BR:
|
case GDK_RGB_FORMAT_8880_BR:
|
||||||
conv_gray = gdk_rgb_convert_gray_8880_br;
|
conv_gray = gdk_rgb_convert_gray_8880_br;
|
||||||
conv_gray_d = gdk_rgb_convert_gray_8880_br;
|
conv_gray_d = gdk_rgb_convert_gray_8880_br;
|
||||||
|
conv_indexed = gdk_rgb_convert_indexed_lut;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_RGB_FORMAT_101010_R_LOW_LSB:
|
case GDK_RGB_FORMAT_101010_R_LOW_LSB:
|
||||||
case GDK_RGB_FORMAT_101010_B_LOW_LSB:
|
case GDK_RGB_FORMAT_101010_B_LOW_LSB:
|
||||||
conv_gray = gdk_rgb_convert_gray_101010_lsb;
|
conv_gray = gdk_rgb_convert_gray_101010_lsb;
|
||||||
conv_gray_d = gdk_rgb_convert_gray_101010_lsb;
|
conv_gray_d = gdk_rgb_convert_gray_101010_lsb;
|
||||||
|
conv_indexed = gdk_rgb_convert_indexed_lut;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_RGB_FORMAT_101010_R_LOW_MSB:
|
case GDK_RGB_FORMAT_101010_R_LOW_MSB:
|
||||||
case GDK_RGB_FORMAT_101010_B_LOW_MSB:
|
case GDK_RGB_FORMAT_101010_B_LOW_MSB:
|
||||||
conv_gray = gdk_rgb_convert_gray_101010_msb;
|
conv_gray = gdk_rgb_convert_gray_101010_msb;
|
||||||
conv_gray_d = gdk_rgb_convert_gray_101010_msb;
|
conv_gray_d = gdk_rgb_convert_gray_101010_msb;
|
||||||
|
conv_indexed = gdk_rgb_convert_indexed_lut;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -4968,48 +5021,123 @@ gdk_draw_gray_image (GdkDrawable *drawable,
|
||||||
|
|
||||||
static GdkRgbCmapInfo *
|
static GdkRgbCmapInfo *
|
||||||
gdk_rgb_cmap_get_info (GdkRgbCmap *cmap,
|
gdk_rgb_cmap_get_info (GdkRgbCmap *cmap,
|
||||||
GdkRgbInfo *image_info)
|
GdkRgbInfo *image_info)
|
||||||
{
|
{
|
||||||
GSList *tmp_list;
|
GSList *tmp_list;
|
||||||
GdkRgbCmapInfo *cmap_info;
|
GdkRgbCmapInfo *cmap_info;
|
||||||
int i, j;
|
gsize lut_bytes;
|
||||||
guint32 rgb;
|
gboolean lut8;
|
||||||
|
gint i;
|
||||||
|
|
||||||
/* We don't need a LUT for TrueColor or DirectColor visuals */
|
lut8 =
|
||||||
if (image_info->bpp != 1 ||
|
image_info->bpp == 1 &&
|
||||||
!(image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
|
(image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
|
||||||
image_info->visual->type == GDK_VISUAL_STATIC_COLOR ||
|
image_info->visual->type == GDK_VISUAL_STATIC_COLOR ||
|
||||||
image_info->visual->type == GDK_VISUAL_GRAYSCALE))
|
image_info->visual->type == GDK_VISUAL_GRAYSCALE);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
tmp_list = cmap->info_list;
|
if (lut8)
|
||||||
|
lut_bytes = 256;
|
||||||
while (tmp_list)
|
else
|
||||||
{
|
{
|
||||||
cmap_info = tmp_list->data;
|
switch (image_info->format)
|
||||||
if (cmap_info->image_info == image_info)
|
{
|
||||||
return cmap_info;
|
case GDK_RGB_FORMAT_565:
|
||||||
tmp_list = tmp_list->next;
|
case GDK_RGB_FORMAT_565_BR:
|
||||||
|
case GDK_RGB_FORMAT_555:
|
||||||
|
case GDK_RGB_FORMAT_555_BR:
|
||||||
|
lut_bytes = 256 * sizeof (guint16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_RGB_FORMAT_0888:
|
||||||
|
case GDK_RGB_FORMAT_0888_BR:
|
||||||
|
case GDK_RGB_FORMAT_8880_BR:
|
||||||
|
case GDK_RGB_FORMAT_101010_R_LOW_LSB:
|
||||||
|
case GDK_RGB_FORMAT_101010_B_LOW_LSB:
|
||||||
|
case GDK_RGB_FORMAT_101010_R_LOW_MSB:
|
||||||
|
case GDK_RGB_FORMAT_101010_B_LOW_MSB:
|
||||||
|
lut_bytes = 256 * sizeof (guint32);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmap_info = g_new (GdkRgbCmapInfo, 1);
|
for (tmp_list = cmap->info_list;
|
||||||
|
tmp_list;
|
||||||
|
tmp_list = tmp_list->next)
|
||||||
|
{
|
||||||
|
cmap_info = tmp_list->data;
|
||||||
|
|
||||||
|
if (cmap_info->image_info == image_info)
|
||||||
|
return cmap_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmap_info =
|
||||||
|
g_malloc (G_STRUCT_OFFSET (GdkRgbCmapInfo, lut) +
|
||||||
|
lut_bytes);
|
||||||
|
|
||||||
cmap_info->image_info = image_info;
|
cmap_info->image_info = image_info;
|
||||||
cmap_info->cmap = cmap;
|
cmap_info->cmap = cmap;
|
||||||
|
|
||||||
for (i = 0; i < cmap->n_colors; i++)
|
if (lut8)
|
||||||
{
|
{
|
||||||
rgb = cmap->colors[i];
|
for (i = 0; i < cmap->n_colors; i++)
|
||||||
j = ((rgb & 0xf00000) >> 12) |
|
{
|
||||||
((rgb & 0xf000) >> 8) |
|
guint32 rgb = cmap->colors[i];
|
||||||
((rgb & 0xf0) >> 4);
|
gint j;
|
||||||
|
|
||||||
|
j = ((rgb & 0xf00000) >> 12) |
|
||||||
|
((rgb & 0x00f000) >> 8) |
|
||||||
|
((rgb & 0x0000f0) >> 4);
|
||||||
|
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
g_print ("%d %x %x\n", i, j, image_info->colorcube[j]);
|
g_print ("%d %x %x\n",
|
||||||
|
i, j, image_info->colorcube[j]);
|
||||||
#endif
|
#endif
|
||||||
cmap_info->lut[i] = image_info->colorcube[j];
|
|
||||||
|
cmap_info->lut[i] =
|
||||||
|
image_info->colorcube[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GdkImage image;
|
||||||
|
guchar stage[256 * 3];
|
||||||
|
|
||||||
|
for (i = 0; i < cmap->n_colors; i++)
|
||||||
|
{
|
||||||
|
guint32 rgb = cmap->colors[i];
|
||||||
|
|
||||||
|
stage[i * 3 + 0] = rgb >> 16;
|
||||||
|
stage[i * 3 + 1] = rgb >> 8;
|
||||||
|
stage[i * 3 + 2] = rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&image, 0, sizeof (image));
|
||||||
|
|
||||||
|
image.mem = cmap_info->lut;
|
||||||
|
image.bpl = cmap->n_colors * image_info->bpp;
|
||||||
|
|
||||||
|
g_assert (image_info->conv != NULL);
|
||||||
|
|
||||||
|
image_info->conv (image_info,
|
||||||
|
&image,
|
||||||
|
0, 0,
|
||||||
|
cmap->n_colors, 1,
|
||||||
|
stage,
|
||||||
|
cmap->n_colors * 3,
|
||||||
|
0, 0,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmap->info_list = g_slist_prepend (cmap->info_list, cmap_info);
|
cmap->info_list =
|
||||||
image_info->cmap_info_list = g_slist_prepend (image_info->cmap_info_list, cmap_info);
|
g_slist_prepend (cmap->info_list,
|
||||||
|
cmap_info);
|
||||||
|
|
||||||
|
image_info->cmap_info_list =
|
||||||
|
g_slist_prepend (image_info->cmap_info_list,
|
||||||
|
cmap_info);
|
||||||
|
|
||||||
return cmap_info;
|
return cmap_info;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue