forked from AuroraMiddleware/gtk
Should now handle all formats, slow routine used where optimised
ones can't be. 1999-12-09 Michael Zucchi <zucchi@zedzone.mmc.com.au> * gdk-pixbuf/gdk-pixbuf-drawable.c (convert_real_slow): New function - should convert ANY visual/data format properly, but it aint fast. Used as a fallback when an optimised routine wont match. (rgbconvert): Do very specific tests on the data format to verify properly if the optimised version will do, otherwise use the fallback function for all other data formats.
This commit is contained in:
parent
6b23587aef
commit
757fc193c4
@ -4,6 +4,12 @@
|
||||
Filled in body of function.
|
||||
(rgbconvert): Added GdkColormap parameter, and to all conversion
|
||||
functions also.
|
||||
(convert_real_slow): New function - should convert ANY visual/data
|
||||
format properly, but it aint fast. Used as a fallback when an
|
||||
optimised routine wont match.
|
||||
(rgbconvert): Do very specific tests on the data format to verify
|
||||
properly if the optimised version will do, otherwise use the
|
||||
fallback function for all other data formats.
|
||||
|
||||
* gdk-pixbuf/Makefile.am: Re-enabled building of
|
||||
textpixbuf-drawable.
|
||||
|
@ -836,6 +836,69 @@ rgb888msb (GdkImage *image, art_u8 *pixels, int rowstride, GdkColormap *colormap
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This should work correctly with any display/any endianness, but will probably
|
||||
run quite slow
|
||||
*/
|
||||
static void
|
||||
convert_real_slow (GdkImage *image, art_u8 *pixels, int rowstride, GdkColormap *cmap, int alpha)
|
||||
{
|
||||
int xx, yy;
|
||||
int width, height;
|
||||
int bpl;
|
||||
unsigned char *srow = image->mem, *orow = pixels;
|
||||
unsigned char *s;
|
||||
unsigned char *o;
|
||||
guint32 pixel;
|
||||
GdkVisual *v;
|
||||
|
||||
width = image->width;
|
||||
height = image->height;
|
||||
bpl = image->bpl;
|
||||
v = gdk_colormap_get_visual(cmap);
|
||||
|
||||
d(printf("rgb mask/shift/prec = %x:%x:%x %d:%d:%d %d:%d:%d\n",
|
||||
v->red_mask, v->green_mask, v->blue_mask,
|
||||
v->red_shift, v->green_shift, v->blue_shift,
|
||||
v->red_prec, v->green_prec, v->blue_prec));
|
||||
|
||||
for (yy = 0; yy < height; yy++) {
|
||||
s = srow;
|
||||
o = orow;
|
||||
for (xx = 0; xx < width; xx++) {
|
||||
pixel = gdk_image_get_pixel(image, xx, yy);
|
||||
switch (v->type) {
|
||||
/* I assume this is right for static & greyscale's too? */
|
||||
case GDK_VISUAL_STATIC_GRAY:
|
||||
case GDK_VISUAL_GRAYSCALE:
|
||||
case GDK_VISUAL_STATIC_COLOR:
|
||||
case GDK_VISUAL_PSEUDO_COLOR:
|
||||
*o++ = cmap->colors[pixel].red;
|
||||
*o++ = cmap->colors[pixel].green;
|
||||
*o++ = cmap->colors[pixel].blue;
|
||||
break;
|
||||
case GDK_VISUAL_TRUE_COLOR:
|
||||
/* this is odd because it must sometimes shift left (otherwise
|
||||
i'd just shift >> *_shift - 8 + *_prec), so this logic
|
||||
should work for all bit sizes/shifts/etc */
|
||||
*o++ = ((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> 24;
|
||||
*o++ = ((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> 24;
|
||||
*o++ = ((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> 24;
|
||||
break;
|
||||
case GDK_VISUAL_DIRECT_COLOR:
|
||||
*o++ = cmap->colors[((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> 24].red;
|
||||
*o++ = cmap->colors[((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> 24].green;
|
||||
*o++ = cmap->colors[((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> 24].blue;
|
||||
break;
|
||||
}
|
||||
if (alpha)
|
||||
*o++ = 0xff;
|
||||
}
|
||||
srow += bpl;
|
||||
orow += rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (* cfunc) (GdkImage *image, art_u8 *pixels, int rowstride, GdkColormap *cmap);
|
||||
|
||||
static cfunc convert_map[] = {
|
||||
@ -848,39 +911,70 @@ static cfunc convert_map[] = {
|
||||
|
||||
/*
|
||||
perform actual conversion
|
||||
|
||||
If we can, try and use the optimised code versions, but as a default
|
||||
fallback, and always for direct colour, use the generic/slow but complete
|
||||
conversion function.
|
||||
*/
|
||||
static void
|
||||
rgbconvert (GdkImage *image, art_u8 *pixels, int rowstride, int alpha, GdkColormap *cmap)
|
||||
{
|
||||
int index = (image->byte_order == GDK_MSB_FIRST) | (alpha != 0) << 1;
|
||||
int bank=0;
|
||||
int bank=5; /* default fallback converter */
|
||||
GdkVisual *v = gdk_colormap_get_visual(cmap);
|
||||
|
||||
switch (image->depth) {
|
||||
d(printf("masks = %x:%x:%x\n", v->red_mask, v->green_mask, v->blue_mask));
|
||||
d(printf("image depth = %d, bpp = %d\n", image->depth, image->bpp));
|
||||
|
||||
switch (v->type) {
|
||||
/* I assume this is right for static & greyscale's too? */
|
||||
case GDK_VISUAL_STATIC_GRAY:
|
||||
case GDK_VISUAL_GRAYSCALE:
|
||||
case GDK_VISUAL_STATIC_COLOR:
|
||||
case GDK_VISUAL_PSEUDO_COLOR:
|
||||
switch (image->bpp) {
|
||||
case 1:
|
||||
bank = 0;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
bank = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case GDK_VISUAL_TRUE_COLOR:
|
||||
switch (image->depth) {
|
||||
case 15:
|
||||
if (v->red_mask == 0x7c00 && v->green_mask == 0x3e0 && v->blue_mask == 0x1f
|
||||
&& image->bpp == 16)
|
||||
bank = 2;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if (v->red_mask == 0xf800 && v->green_mask == 0x7e0 && v->blue_mask == 0x1f
|
||||
&& image->bpp == 16)
|
||||
bank = 3;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
if (v->red_mask == 0xff0000 && v->green_mask == 0xff00 && v->blue_mask == 0xff
|
||||
&& image->bpp == 32)
|
||||
bank = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GDK_VISUAL_DIRECT_COLOR:
|
||||
/* always use the slow version */
|
||||
break;
|
||||
}
|
||||
|
||||
d(printf("converting using conversion function in bank %d\n", bank));
|
||||
|
||||
if (bank==5) {
|
||||
convert_real_slow(image, pixels, rowstride, cmap, alpha);
|
||||
} else {
|
||||
index |= bank << 2;
|
||||
(* convert_map[index]) (image, pixels, rowstride, cmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Exported functions */
|
||||
|
Loading…
Reference in New Issue
Block a user