diff --git a/ChangeLog b/ChangeLog index 39c307eeee..0691ca573b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +1998-08-19 Raph Levien + + * gdk/gdkrgb.c: fixed some bugs in the 565_d mode, and added a + 4bpp static_color mode (for vga displays). Also fixed a '64' value + in the dither matrix, which was causing one pixel out of 16k to be + dithered wrong. + + * gtk/gtkpreview.{c,h}: Changed it to work with GdkRgb, gutting + most of the contents. This is an API change - any apps that relied + on the internal structure of GtkPreview will need some change - + most notably in the use of reserved colors. The Gimp needed + changes in this regard. + Wed Aug 19 00:11:14 1998 Tim Janik * gtk/gtkmain.c (gtk_init): allow argument parsing in gtk without diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 39c307eeee..0691ca573b 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,16 @@ +1998-08-19 Raph Levien + + * gdk/gdkrgb.c: fixed some bugs in the 565_d mode, and added a + 4bpp static_color mode (for vga displays). Also fixed a '64' value + in the dither matrix, which was causing one pixel out of 16k to be + dithered wrong. + + * gtk/gtkpreview.{c,h}: Changed it to work with GdkRgb, gutting + most of the contents. This is an API change - any apps that relied + on the internal structure of GtkPreview will need some change - + most notably in the use of reserved colors. The Gimp needed + changes in this regard. + Wed Aug 19 00:11:14 1998 Tim Janik * gtk/gtkmain.c (gtk_init): allow argument parsing in gtk without diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 39c307eeee..0691ca573b 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,16 @@ +1998-08-19 Raph Levien + + * gdk/gdkrgb.c: fixed some bugs in the 565_d mode, and added a + 4bpp static_color mode (for vga displays). Also fixed a '64' value + in the dither matrix, which was causing one pixel out of 16k to be + dithered wrong. + + * gtk/gtkpreview.{c,h}: Changed it to work with GdkRgb, gutting + most of the contents. This is an API change - any apps that relied + on the internal structure of GtkPreview will need some change - + most notably in the use of reserved colors. The Gimp needed + changes in this regard. + Wed Aug 19 00:11:14 1998 Tim Janik * gtk/gtkmain.c (gtk_init): allow argument parsing in gtk without diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 39c307eeee..0691ca573b 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,16 @@ +1998-08-19 Raph Levien + + * gdk/gdkrgb.c: fixed some bugs in the 565_d mode, and added a + 4bpp static_color mode (for vga displays). Also fixed a '64' value + in the dither matrix, which was causing one pixel out of 16k to be + dithered wrong. + + * gtk/gtkpreview.{c,h}: Changed it to work with GdkRgb, gutting + most of the contents. This is an API change - any apps that relied + on the internal structure of GtkPreview will need some change - + most notably in the use of reserved colors. The Gimp needed + changes in this regard. + Wed Aug 19 00:11:14 1998 Tim Janik * gtk/gtkmain.c (gtk_init): allow argument parsing in gtk without diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 39c307eeee..0691ca573b 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,16 @@ +1998-08-19 Raph Levien + + * gdk/gdkrgb.c: fixed some bugs in the 565_d mode, and added a + 4bpp static_color mode (for vga displays). Also fixed a '64' value + in the dither matrix, which was causing one pixel out of 16k to be + dithered wrong. + + * gtk/gtkpreview.{c,h}: Changed it to work with GdkRgb, gutting + most of the contents. This is an API change - any apps that relied + on the internal structure of GtkPreview will need some change - + most notably in the use of reserved colors. The Gimp needed + changes in this regard. + Wed Aug 19 00:11:14 1998 Tim Janik * gtk/gtkmain.c (gtk_init): allow argument parsing in gtk without diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 39c307eeee..0691ca573b 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,16 @@ +1998-08-19 Raph Levien + + * gdk/gdkrgb.c: fixed some bugs in the 565_d mode, and added a + 4bpp static_color mode (for vga displays). Also fixed a '64' value + in the dither matrix, which was causing one pixel out of 16k to be + dithered wrong. + + * gtk/gtkpreview.{c,h}: Changed it to work with GdkRgb, gutting + most of the contents. This is an API change - any apps that relied + on the internal structure of GtkPreview will need some change - + most notably in the use of reserved colors. The Gimp needed + changes in this regard. + Wed Aug 19 00:11:14 1998 Tim Janik * gtk/gtkmain.c (gtk_init): allow argument parsing in gtk without diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 39c307eeee..0691ca573b 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,16 @@ +1998-08-19 Raph Levien + + * gdk/gdkrgb.c: fixed some bugs in the 565_d mode, and added a + 4bpp static_color mode (for vga displays). Also fixed a '64' value + in the dither matrix, which was causing one pixel out of 16k to be + dithered wrong. + + * gtk/gtkpreview.{c,h}: Changed it to work with GdkRgb, gutting + most of the contents. This is an API change - any apps that relied + on the internal structure of GtkPreview will need some change - + most notably in the use of reserved colors. The Gimp needed + changes in this regard. + Wed Aug 19 00:11:14 1998 Tim Janik * gtk/gtkmain.c (gtk_init): allow argument parsing in gtk without diff --git a/gdk/gdkrgb.c b/gdk/gdkrgb.c index 644e6060fe..f884b8af4f 100644 --- a/gdk/gdkrgb.c +++ b/gdk/gdkrgb.c @@ -18,9 +18,9 @@ */ /* For more information on GdkRgb, see http://www.levien.com/gdkrgb/ - + Raph Levien -*/ + */ #include #include @@ -64,39 +64,39 @@ struct _GdkRgbInfo { GdkVisual *visual; GdkColormap *cmap; - + gulong *color_pixels; gulong *gray_pixels; gulong *reserved_pixels; - + guint nred_shades; guint ngreen_shades; guint nblue_shades; guint ngray_shades; guint nreserved; - + guint bpp; gint cmap_alloced; gdouble gamma; - + /* Generally, the stage buffer is used to convert 32bit RGB, gray, and indexed images into 24 bit packed RGB. */ guchar *stage_buf; - + GdkRgbCmap *gray_cmap; - + gboolean dith_default; - + /* Convert functions */ GdkRgbConvFunc conv; GdkRgbConvFunc conv_d; - + GdkRgbConvFunc conv_32; GdkRgbConvFunc conv_32_d; - + GdkRgbConvFunc conv_gray; GdkRgbConvFunc conv_gray_d; - + GdkRgbConvFunc conv_indexed; GdkRgbConvFunc conv_indexed_d; }; @@ -123,9 +123,9 @@ gdk_rgb_cmap_fail (const char *msg, GdkColormap *cmap, gulong *pixels) gulong free_pixels[256]; gint n_free; gint i; - + #ifdef VERBOSE - g_message ("%s", msg); + g_print ("%s", msg); #endif n_free = 0; for (i = 0; i < 256; i++) @@ -141,7 +141,7 @@ gdk_rgb_make_colorcube (gulong *pixels, gint nr, gint ng, gint nb) { guchar rt[16], gt[16], bt[16]; gint i; - + colorcube = g_new (guchar, 4096); for (i = 0; i < 16; i++) { @@ -149,12 +149,12 @@ gdk_rgb_make_colorcube (gulong *pixels, gint nr, gint ng, gint nb) gt[i] = nb * ((i * 17 * (ng - 1) + 128) >> 8); bt[i] = ((i * 17 * (nb - 1) + 128) >> 8); } - + for (i = 0; i < 4096; i++) { colorcube[i] = pixels[rt[i >> 8] + gt[(i >> 4) & 0x0f] + bt[i & 0x0f]]; #ifdef VERBOSE - g_message ("%03x %02x %x %x %x", i, colorcube[i], rt[i >> 8], gt[(i >> 4) & 0x0f], bt[i & 0x0f]); + g_print ("%03x %02x %x %x %x\n", i, colorcube[i], rt[i >> 8], gt[(i >> 4) & 0x0f], bt[i & 0x0f]); #endif } } @@ -165,7 +165,7 @@ gdk_rgb_make_colorcube_d (gulong *pixels, gint nr, gint ng, gint nb) { gint r, g, b; gint i; - + colorcube_d = g_new (guchar, 512); for (i = 0; i < 512; i++) { @@ -193,53 +193,53 @@ gdk_rgb_try_colormap (gint nr, gint ng, gint nb) gint colors_needed; gint idx; gint best[256]; - + if (nr * ng * nb < gdk_rgb_min_colors) return FALSE; - + if (image_info->cmap_alloced) cmap = image_info->cmap; else cmap = gdk_colormap_get_system (); - + colors_needed = nr * ng * nb; for (i = 0; i < 256; i++) { best[i] = 192; pixels[i] = 256; } - + #ifndef GAMMA if (!gdk_rgb_install_cmap) - /* find color cube colors that are already present */ - for (i = 0; i < MIN (256, cmap->size); i++) - { - r = cmap->colors[i].red >> 8; - g = cmap->colors[i].green >> 8; - b = cmap->colors[i].blue >> 8; - ri = (r * (nr - 1) + 128) >> 8; - gi = (g * (ng - 1) + 128) >> 8; - bi = (b * (nb - 1) + 128) >> 8; - r0 = ri * 255 / (nr - 1); - g0 = gi * 255 / (ng - 1); - b0 = bi * 255 / (nb - 1); - idx = ((ri * nr) + gi) * nb + bi; - d2 = (r - r0) * (r - r0) + (g - g0) * (g - g0) + (b - b0) * (b - b0); - if (d2 < best[idx]) { - if (pixels[idx] < 256) - gdk_colors_free (cmap, pixels + idx, 1, 0); - else - colors_needed--; - color = cmap->colors[i]; - if (!gdk_color_alloc (cmap, &color)) - return gdk_rgb_cmap_fail ("error allocating system color", - cmap, pixels); - pixels[idx] = color.pixel; /* which is almost certainly i */ - best[idx] = d2; - } + /* find color cube colors that are already present */ + for (i = 0; i < MIN (256, cmap->size); i++) + { + r = cmap->colors[i].red >> 8; + g = cmap->colors[i].green >> 8; + b = cmap->colors[i].blue >> 8; + ri = (r * (nr - 1) + 128) >> 8; + gi = (g * (ng - 1) + 128) >> 8; + bi = (b * (nb - 1) + 128) >> 8; + r0 = ri * 255 / (nr - 1); + g0 = gi * 255 / (ng - 1); + b0 = bi * 255 / (nb - 1); + idx = ((ri * nr) + gi) * nb + bi; + d2 = (r - r0) * (r - r0) + (g - g0) * (g - g0) + (b - b0) * (b - b0); + if (d2 < best[idx]) { + if (pixels[idx] < 256) + gdk_colors_free (cmap, pixels + idx, 1, 0); + else + colors_needed--; + color = cmap->colors[i]; + if (!gdk_color_alloc (cmap, &color)) + return gdk_rgb_cmap_fail ("error allocating system color\n", + cmap, pixels); + pixels[idx] = color.pixel; /* which is almost certainly i */ + best[idx] = d2; } + } #endif - + if (colors_needed) { if (!gdk_colors_alloc (cmap, 0, NULL, 0, junk, colors_needed)) @@ -247,14 +247,14 @@ gdk_rgb_try_colormap (gint nr, gint ng, gint nb) char tmp_str[80]; sprintf (tmp_str, - "%d %d %d colormap failed (in gdk_colors_alloc)", + "%d %d %d colormap failed (in gdk_colors_alloc)\n", nr, ng, nb); return gdk_rgb_cmap_fail (tmp_str, cmap, pixels); } - + gdk_colors_free (cmap, junk, colors_needed, 0); } - + for (r = 0, i = 0; r < nr; r++) for (g = 0; g < ng; g++) for (b = 0; b < nb; b++, i++) @@ -264,18 +264,19 @@ gdk_rgb_try_colormap (gint nr, gint ng, gint nb) color.red = r * 65535 / (nr - 1); color.green = g * 65535 / (ng - 1); color.blue = b * 65535 / (nb - 1); - + #ifdef GAMMA color.red = 65535 * pow (color.red / 65535.0, 0.5); color.green = 65535 * pow (color.green / 65535.0, 0.5); color.blue = 65535 * pow (color.blue / 65535.0, 0.5); #endif - + + /* This should be a raw XAllocColor call */ if (!gdk_color_alloc (cmap, &color)) { char tmp_str[80]; - - sprintf (tmp_str, "%d %d %d colormap failed", + + sprintf (tmp_str, "%d %d %d colormap failed\n", nr, ng, nb); return gdk_rgb_cmap_fail (tmp_str, cmap, pixels); @@ -283,10 +284,10 @@ gdk_rgb_try_colormap (gint nr, gint ng, gint nb) pixels[i] = color.pixel; } #ifdef VERBOSE - g_message ("%d: %lx", i, pixels[i]); + g_print ("%d: %lx\n", i, pixels[i]); #endif } - + image_info->nred_shades = nr; image_info->ngreen_shades = ng; image_info->nblue_shades = nb; @@ -300,7 +301,7 @@ static gboolean gdk_rgb_do_colormaps (void) { const gint sizes[][3] = { - /* { 6, 7, 6 }, */ + /* { 6, 7, 6 }, */ { 6, 6, 6 }, { 6, 6, 5 }, { 6, 6, 4 }, @@ -313,13 +314,38 @@ gdk_rgb_do_colormaps (void) }; const gint n_sizes = sizeof(sizes) / (3 * sizeof(gint)); gint i; - + for (i = 0; i < n_sizes; i++) if (gdk_rgb_try_colormap (sizes[i][0], sizes[i][1], sizes[i][2])) return TRUE; return FALSE; } +/* Make a 2 x 2 x 2 colorcube */ +static void +gdk_rgb_colorcube_222 (void) +{ + int i; + GdkColor color; + GdkColormap *cmap; + + if (image_info->cmap_alloced) + cmap = image_info->cmap; + else + cmap = gdk_colormap_get_system (); + + colorcube_d = g_new (guchar, 512); + + for (i = 0; i < 8; i++) + { + color.red = ((i & 4) >> 2) * 65535; + color.green = ((i & 2) >> 1) * 65535; + color.blue = (i & 1) * 65535; + gdk_color_alloc (cmap, &color); + colorcube_d[((i & 4) << 4) | ((i & 2) << 2) | (i & 1)] = color.pixel; + } +} + void gdk_rgb_set_verbose (gboolean verbose) { @@ -339,16 +365,16 @@ gdk_rgb_set_min_colors (gint min_colors) } /* Return a "score" based on the following criteria (in hex): - + x000 is the quality - 1 is 1bpp, 2 is 4bpp, - 4 is 8bpp, - 7 is 15bpp truecolor, 8 is 16bpp truecolor, - 9 is 24bpp truecolor. + 4 is 8bpp, + 7 is 15bpp truecolor, 8 is 16bpp truecolor, + 9 is 24bpp truecolor. 0x00 is the speed - 1 is the normal case, - 2 means faster than normal + 2 means faster than normal 00x0 gets a point for being the system visual 000x gets a point for being pseudocolor - + A caveat: in the 8bpp modes, being the system visual seems to be quite important. Thus, all of the 8bpp modes should be ranked at the same speed. @@ -366,8 +392,8 @@ gdk_rgb_score_visual (GdkVisual *visual) "true color", "direct color", }; - - + + quality = 0; speed = 1; sys = 0; @@ -386,10 +412,15 @@ gdk_rgb_score_visual (GdkVisual *visual) else if (visual->depth == 8) quality = 4; } - else if (visual->type == GDK_VISUAL_PSEUDO_COLOR) + else if (visual->type == GDK_VISUAL_PSEUDO_COLOR || + visual->type == GDK_VISUAL_STATIC_COLOR) { if (visual->depth == 8) quality = 4; + else if (visual->depth == 4) + quality = 2; + else if (visual->depth == 1) + quality = 1; } else if (visual->type == GDK_VISUAL_STATIC_GRAY #ifdef ENABLE_GRAYSCALE @@ -404,25 +435,25 @@ gdk_rgb_score_visual (GdkVisual *visual) else if (visual->depth == 1) quality = 1; } - + if (quality == 0) return 0; - + sys = (visual == gdk_visual_get_system ()); - + pseudo = (visual->type == GDK_VISUAL_PSEUDO_COLOR); - + if (gdk_rgb_verbose) - g_message ("Visual 0x%x, type = %s, depth = %d, %x:%x:%x%s; score=%x", - (gint)(((GdkVisualPrivate *)visual)->xvisual->visualid), - visual_names[visual->type], - visual->depth, - visual->red_mask, - visual->green_mask, - visual->blue_mask, - sys ? " (system)" : "", - (quality << 12) | (speed << 8) | (sys << 4) | pseudo); - + g_print ("Visual 0x%x, type = %s, depth = %d, %x:%x:%x%s; score=%x\n", + (gint)(((GdkVisualPrivate *)visual)->xvisual->visualid), + visual_names[visual->type], + visual->depth, + visual->red_mask, + visual->green_mask, + visual->blue_mask, + sys ? " (system)" : "", + (quality << 12) | (speed << 8) | (sys << 4) | pseudo); + return (quality << 12) | (speed << 8) | (sys << 4) | pseudo; } @@ -432,9 +463,9 @@ gdk_rgb_choose_visual (void) GList *visuals; guint32 score, best_score; GdkVisual *visual, *best_visual; - + visuals = gdk_list_visuals (); - + best_visual = visuals->data; best_score = gdk_rgb_score_visual (best_visual); visuals = visuals->next; @@ -449,7 +480,7 @@ gdk_rgb_choose_visual (void) } visuals = visuals->next; } - + image_info->visual = best_visual; } @@ -463,7 +494,7 @@ gdk_rgb_set_gray_cmap (GdkColormap *cmap) gint status; gulong pixels[256]; gint r, g, b, gray; - + for (i = 0; i < 256; i++) { color.pixel = i; @@ -473,16 +504,16 @@ gdk_rgb_set_gray_cmap (GdkColormap *cmap) status = gdk_color_alloc (cmap, &color); pixels[i] = color.pixel; #ifdef VERBOSE - g_message ("allocating pixel %d, %x %x %x, result %d", - color.pixel, color.red, color.green, color.blue, status); + g_print ("allocating pixel %d, %x %x %x, result %d\n", + color.pixel, color.red, color.green, color.blue, status); #endif } - + /* Now, we make fake colorcubes - we ultimately just use the pseudocolor methods. */ - + colorcube = g_new (guchar, 4096); - + for (i = 0; i < 4096; i++) { r = (i >> 4) & 0xf0; @@ -501,7 +532,7 @@ gdk_rgb_init (void) { gint i; gint byte_order[1] = { 1 }; - + /* check endian sanity */ #ifdef WORDS_BIGENDIAN if (((char *)byte_order)[0] == 1) @@ -510,33 +541,37 @@ gdk_rgb_init (void) if (((char *)byte_order)[0] != 1) g_error ("gdk_rgb_init: WORDS_BIGENDIAN is not defined, but this is a little endian machine.\n\n"); #endif - + if (image_info == NULL) { image_info = g_new0 (GdkRgbInfo, 1); - + image_info->visual = NULL; image_info->cmap = NULL; - + image_info->color_pixels = NULL; image_info->gray_pixels = NULL; image_info->reserved_pixels = NULL; - + image_info->nred_shades = 6; image_info->ngreen_shades = 6; image_info->nblue_shades = 4; image_info->ngray_shades = 24; image_info->nreserved = 0; - + image_info->bpp = 0; image_info->cmap_alloced = FALSE; image_info->gamma = 1.0; - + image_info->stage_buf = NULL; - + gdk_rgb_choose_visual (); - - if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR) + + if (image_info->visual->depth == 4) + { + gdk_rgb_colorcube_222 (); + } + else if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR) { if (gdk_rgb_install_cmap || image_info->visual != gdk_visual_get_system ()) @@ -551,13 +586,13 @@ gdk_rgb_init (void) gdk_rgb_do_colormaps (); } if (gdk_rgb_verbose) - g_message ("color cube: %d x %d x %d", - image_info->nred_shades, - image_info->ngreen_shades, - image_info->nblue_shades); - + g_print ("color cube: %d x %d x %d\n", + image_info->nred_shades, + image_info->ngreen_shades, + image_info->nblue_shades); + if (!image_info->cmap_alloced) - image_info->cmap = gdk_colormap_get_system (); + image_info->cmap = gdk_colormap_get_system (); } #ifdef ENABLE_GRAYSCALE else if (image_info->visual->type == GDK_VISUAL_GRAYSCALE) @@ -565,7 +600,7 @@ gdk_rgb_init (void) image_info->cmap = gdk_colormap_new (image_info->visual, FALSE); gdk_rgb_set_gray_cmap (image_info->cmap); image_info->cmap_alloced = TRUE; - } + } #endif else { @@ -579,16 +614,16 @@ gdk_rgb_init (void) image_info->cmap_alloced = TRUE; } } - + for (i = 0; i < N_IMAGES; i++) static_image[i] = gdk_image_new (GDK_IMAGE_FASTEST, image_info->visual, IMAGE_WIDTH, IMAGE_HEIGHT); - + image_info->bpp = static_image[0]->bpp; - + gdk_rgb_select_conv (static_image[0]); - + } } @@ -597,36 +632,41 @@ gulong gdk_rgb_xpixel_from_rgb (guint32 rgb) { gulong pixel; - + if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR) pixel = colorcube[((rgb & 0xf00000) >> 12) | ((rgb & 0xf000) >> 8) | ((rgb & 0xf0) >> 4)]; + else if (image_info->visual->depth == 4 && + image_info->visual->type == GDK_VISUAL_STATIC_COLOR) + { + pixel = colorcube_d[((rgb & 0x800000) >> 17) | + ((rgb & 0x8000) >> 12) | + ((rgb & 0x80) >> 7)]; + } else { #ifdef VERBOSE - g_message ("shift, prec: r %d %d g %d %d b %d %d", - image_info->visual->red_shift, - image_info->visual->red_prec, - image_info->visual->green_shift, - image_info->visual->green_prec, - image_info->visual->blue_shift, - image_info->visual->blue_prec); + g_print ("shift, prec: r %d %d g %d %d b %d %d\n", + image_info->visual->red_shift, + image_info->visual->red_prec, + image_info->visual->green_shift, + image_info->visual->green_prec, + image_info->visual->blue_shift, + image_info->visual->blue_prec); #endif - + pixel = (((((rgb & 0xff0000) >> 16) >> (8 - image_info->visual->red_prec)) << image_info->visual->red_shift) + - ((((rgb & 0xff00) >> 8) >> + ((((rgb & 0xff00) >> 8) >> (8 - image_info->visual->green_prec)) << image_info->visual->green_shift) + (((rgb & 0xff) >> (8 - image_info->visual->blue_prec)) << image_info->visual->blue_shift)); - - ; } - + return pixel; } @@ -634,7 +674,7 @@ void gdk_rgb_gc_set_foreground (GdkGC *gc, guint32 rgb) { GdkColor color; - + color.pixel = gdk_rgb_xpixel_from_rgb (rgb); gdk_gc_set_foreground (gc, &color); } @@ -643,7 +683,7 @@ void gdk_rgb_gc_set_background (GdkGC *gc, guint32 rgb) { GdkColor color; - + color.pixel = gdk_rgb_xpixel_from_rgb (rgb); gdk_gc_set_background (gc, &color); } @@ -664,7 +704,7 @@ gdk_rgb_convert_8 (GdkImage *image, guchar *obuf, *obptr; guchar *bptr, *bp2; gint r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0; @@ -672,7 +712,7 @@ gdk_rgb_convert_8 (GdkImage *image, { bp2 = bptr; obptr = obuf; - if (width < 8 || (((unsigned long)obuf | (unsigned long) bp2) & 3)) + if (((unsigned long)obuf | (unsigned long) bp2) & 3) { for (x = 0; x < width; x++) { @@ -692,7 +732,7 @@ gdk_rgb_convert_8 (GdkImage *image, guint32 r1b0g0r0; guint32 g2r2b1g1; guint32 b3g3r3b2; - + r1b0g0r0 = ((guint32 *)bp2)[0]; g2r2b1g1 = ((guint32 *)bp2)[1]; b3g3r3b2 = ((guint32 *)bp2)[2]; @@ -739,7 +779,7 @@ gdk_rgb_convert_8 (GdkImage *image, guchar *obuf, *obptr; guchar *bptr, *bp2; gint r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0; @@ -877,7 +917,7 @@ static guchar DM[128][128] = { 46, 2, 56, 11, 41, 1, 49, 6, 27, 47, 2, 48, 5, 32, 37, 3, 13, 19, 32, 1, 55, 28, 60, 17, 43, 59, 32, 20, 49, 16, 55, 23, 14, 46, 2, 36, 6, 30, 20, 49, 12, 47, 35, 14, 21, 60, 29, 14, 35, 24, 46, 1, 56, 29, 53, 8, 33, 23, 56, 1, 35, 46, 20, 39, 26, 4, 53, 28, 17, 38, 60, 34, 48, 9, 55, 15, 46, 7, 41, 31, 60, 24, 16, 36, 1, 59, 19, 52, 35, 6, 55, 11, 59, 33, 7, 57, 4, 29, 48, 1, 19, 26, 37, 30, 18, 63, 37, 6, 59, 1, 40, 24, 56, 33, 46, 22, 35, 7, 24, 53, 39, 5, 26, 45, 55, 18, 62, 7 }, { 20, 60, 29, 34, 20, 62, 33, 52, 10, 36, 13, 60, 41, 21, 50, 27, 56, 49, 8, 51, 21, 45, 11, 48, 8, 23, 53, 3, 29, 44, 5, 52, 9, 32, 50, 17, 43, 56, 3, 38, 24, 10, 62, 25, 51, 9, 33, 49, 61, 7, 30, 62, 22, 19, 2, 42, 63, 5, 49, 18, 60, 15, 52, 7, 43, 56, 23, 50, 5, 50, 2, 20, 41, 30, 1, 52, 22, 61, 14, 26, 3, 43, 53, 7, 47, 28, 11, 14, 23, 58, 33, 25, 47, 13, 50, 17, 40, 54, 34, 60, 41, 6, 59, 14, 50, 7, 25, 55, 20, 42, 51, 8, 27, 4, 16, 60, 28, 50, 44, 3, 22, 49, 63, 12, 33, 1, 43, 31 }, { 36, 5, 46, 8, 44, 24, 13, 39, 25, 57, 31, 18, 8, 52, 10, 45, 6, 30, 36, 24, 63, 4, 33, 26, 57, 40, 15, 56, 37, 12, 40, 25, 37, 58, 11, 63, 21, 45, 16, 60, 31, 53, 18, 33, 3, 45, 23, 0, 20, 54, 40, 15, 50, 38, 60, 16, 25, 42, 29, 38, 7, 41, 25, 62, 18, 33, 8, 35, 42, 16, 32, 56, 12, 39, 59, 19, 34, 9, 49, 38, 57, 12, 21, 50, 14, 40, 61, 44, 50, 9, 49, 19, 3, 29, 35, 62, 12, 24, 7, 18, 52, 32, 10, 46, 21, 41, 32, 11, 36, 29, 14, 34, 60, 38, 54, 11, 41, 14, 19, 57, 32, 16, 7, 41, 51, 25, 14, 57 }, - { 53, 18, 26, 50, 15, 58, 4, 63, 17, 43, 7, 40, 61, 35, 15, 41, 23, 60, 16, 38, 14, 42, 19, 50, 0, 31, 10, 46, 27, 63, 18, 60, 0, 20, 29, 39, 8, 26, 37, 5, 42, 0, 44, 39, 57, 17, 58, 41, 28, 37, 4, 32, 9, 44, 12, 31, 54, 10, 59, 14, 27, 53, 12, 36, 0, 47, 13, 64, 21, 58, 10, 24, 50, 27, 4, 26, 44, 53, 31, 0, 18, 42, 29, 33, 57, 4, 32, 26, 0, 38, 16, 61, 41, 53, 20, 0, 42, 44, 49, 27, 10, 56, 39, 0, 57, 15, 53, 49, 3, 61, 22, 47, 17, 5, 49, 26, 2, 63, 39, 10, 47, 27, 37, 23, 4, 59, 38, 10 }, + { 53, 18, 26, 50, 15, 58, 4, 63, 17, 43, 7, 40, 61, 35, 15, 41, 23, 60, 16, 38, 14, 42, 19, 50, 0, 31, 10, 46, 27, 63, 18, 60, 0, 20, 29, 39, 8, 26, 37, 5, 42, 0, 44, 39, 57, 17, 58, 41, 28, 37, 4, 32, 9, 44, 12, 31, 54, 10, 59, 14, 27, 53, 12, 36, 0, 47, 13, 63, 21, 58, 10, 24, 50, 27, 4, 26, 44, 53, 31, 0, 18, 42, 29, 33, 57, 4, 32, 26, 0, 38, 16, 61, 41, 53, 20, 0, 42, 44, 49, 27, 10, 56, 39, 0, 57, 15, 53, 49, 3, 61, 22, 47, 17, 5, 49, 26, 2, 63, 39, 10, 47, 27, 37, 23, 4, 59, 38, 10 }, { 23, 39, 61, 3, 37, 28, 48, 31, 0, 34, 51, 23, 2, 26, 58, 0, 53, 11, 46, 1, 57, 29, 52, 14, 37, 61, 21, 35, 2, 49, 7, 34, 47, 55, 4, 33, 54, 13, 58, 52, 19, 50, 22, 7, 13, 29, 36, 11, 51, 17, 60, 25, 55, 4, 34, 51, 0, 35, 20, 48, 32, 3, 51, 30, 59, 28, 40, 3, 46, 29, 54, 43, 7, 62, 47, 11, 39, 4, 23, 46, 55, 8, 63, 5, 25, 37, 18, 46, 21, 56, 31, 5, 36, 8, 45, 58, 26, 15, 2, 36, 47, 21, 29, 44, 25, 34, 3, 27, 43, 10, 52, 0, 45, 30, 24, 36, 43, 18, 34, 59, 0, 52, 61, 15, 44, 19, 30, 49 }, { 0, 27, 12, 43, 54, 9, 22, 53, 21, 46, 15, 55, 29, 47, 20, 33, 39, 28, 59, 35, 9, 44, 5, 24, 47, 7, 52, 17, 56, 22, 30, 42, 14, 26, 45, 18, 49, 1, 24, 34, 11, 27, 55, 32, 61, 47, 2, 56, 6, 44, 13, 47, 36, 27, 58, 22, 16, 47, 40, 4, 57, 38, 21, 45, 16, 9, 56, 26, 11, 38, 0, 22, 36, 17, 33, 57, 16, 30, 62, 15, 35, 40, 20, 45, 59, 10, 54, 8, 63, 13, 52, 27, 22, 57, 28, 12, 32, 51, 55, 22, 63, 4, 16, 54, 12, 62, 45, 19, 58, 13, 32, 40, 20, 56, 7, 57, 9, 54, 6, 29, 42, 21, 8, 55, 35, 47, 6, 41 }, { 56, 33, 58, 32, 19, 35, 42, 6, 59, 11, 38, 5, 49, 12, 62, 7, 52, 17, 5, 25, 54, 20, 61, 31, 54, 27, 41, 11, 44, 5, 59, 12, 36, 51, 10, 61, 28, 41, 48, 9, 43, 63, 5, 40, 20, 8, 49, 26, 34, 21, 58, 1, 18, 45, 7, 39, 61, 26, 8, 50, 23, 10, 63, 5, 55, 37, 19, 49, 52, 15, 59, 47, 13, 54, 1, 25, 42, 58, 10, 48, 3, 27, 50, 1, 17, 48, 34, 41, 16, 40, 2, 45, 10, 39, 17, 61, 5, 38, 19, 9, 41, 31, 60, 38, 5, 23, 36, 8, 30, 55, 24, 63, 12, 48, 14, 51, 31, 20, 45, 25, 12, 50, 32, 2, 28, 11, 62, 14 }, @@ -910,13 +950,13 @@ static guchar DM[128][128] = #define DM_HEIGHT 8 static guchar DM[8][8] = { - { 0, 32, 8, 40, 2, 34, 10, 42 }, + { 0, 32, 8, 40, 2, 34, 10, 42 }, { 48, 16, 56, 24, 50, 18, 58, 26 }, - { 12, 44, 4, 36, 14, 46, 6, 38 }, + { 12, 44, 4, 36, 14, 46, 6, 38 }, { 60, 28, 52, 20, 62, 30, 54, 22 }, - { 3, 35, 11, 43, 1, 33, 9, 41 }, + { 3, 35, 11, 43, 1, 33, 9, 41 }, { 51, 19, 59, 27, 49, 17, 57, 25 }, - { 15, 47, 7, 39, 13, 45, 5, 37 }, + { 15, 47, 7, 39, 13, 45, 5, 37 }, { 63, 31, 55, 23, 61, 29, 53, 21 } }; #endif @@ -928,7 +968,7 @@ gdk_rgb_preprocess_dm_565 (void) { int i; guint32 dith; - + if (DM_565 == NULL) { DM_565 = g_new (guint32, DM_WIDTH * DM_HEIGHT); @@ -937,7 +977,7 @@ gdk_rgb_preprocess_dm_565 (void) dith = DM[0][i] >> 3; DM_565[i] = (dith << 20) | dith | (((7 - dith) >> 1) << 10); #ifdef VERBOSE - g_message ("%i %x %x", i, dith, DM_565[i]); + g_print ("%i %x %x\n", i, dith, DM_565[i]); #endif } } @@ -956,7 +996,7 @@ gdk_rgb_convert_8_d666 (GdkImage *image, gint r, g, b; guchar *dmp; gint dith; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0; @@ -997,7 +1037,7 @@ gdk_rgb_convert_8_d (GdkImage *image, guchar *dmp; gint dith; gint rs, gs, bs; - + bptr = buf; bpl = image->bpl; rs = image_info->nred_shades - 1; @@ -1038,7 +1078,7 @@ gdk_rgb_convert_8_indexed (GdkImage *image, guchar *bptr, *bp2; guchar c; guchar *lut; - + lut = cmap->lut; bptr = buf; bpl = image->bpl; @@ -1069,7 +1109,7 @@ gdk_rgb_convert_gray8 (GdkImage *image, guchar *obuf, *obptr; guchar *bptr, *bp2; gint r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0; @@ -1100,7 +1140,7 @@ gdk_rgb_convert_gray8_gray (GdkImage *image, gint bpl; guchar *obuf; guchar *bptr; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0; @@ -1121,7 +1161,7 @@ gdk_rgb_convert_gray8_gray (GdkImage *image, This assumes native byte ordering - what should really be done is to check whether static_image->byte_order is consistent with the _ENDIAN config flag, and if not, use a different function. - + This one is even faster than the one below - its inner loop loads 3 words (i.e. 4 24-bit pixels), does a lot of shifting and masking, then writes 2 words. */ @@ -1136,7 +1176,7 @@ gdk_rgb_convert_565 (GdkImage *image, gint bpl; guchar *bptr, *bp2; guchar r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; @@ -1144,7 +1184,7 @@ gdk_rgb_convert_565 (GdkImage *image, { bp2 = bptr; obptr = obuf; - if (width < 8 || (((unsigned long)obuf | (unsigned long) bp2) & 3)) + if (((unsigned long)obuf | (unsigned long) bp2) & 3) { for (x = 0; x < width; x++) { @@ -1164,7 +1204,7 @@ gdk_rgb_convert_565 (GdkImage *image, guint32 r1b0g0r0; guint32 g2r2b1g1; guint32 b3g3r3b2; - + r1b0g0r0 = ((guint32 *)bp2)[0]; g2r2b1g1 = ((guint32 *)bp2)[1]; b3g3r3b2 = ((guint32 *)bp2)[2]; @@ -1205,19 +1245,19 @@ gdk_rgb_convert_565 (GdkImage *image, This assumes native byte ordering - what should really be done is to check whether static_image->byte_order is consistent with the _ENDIAN config flag, and if not, use a different function. - + This routine is faster than the one included with Gtk 1.0 for a number of reasons: - + 1. Shifting instead of lookup tables (less memory traffic). - + 2. Much less register pressure, especially because shifts are in the code. - + 3. A memcpy is avoided (i.e. the transfer function). - + 4. On big-endian architectures, byte swapping is avoided. - + That said, it wouldn't be hard to make it even faster - just make an inner loop that reads 3 words (i.e. 4 24-bit pixels), does a lot of shifting and masking, then writes 2 words. @@ -1233,7 +1273,7 @@ gdk_rgb_convert_565 (GdkImage *image, gint bpl; guchar *bptr, *bp2; guchar r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; @@ -1267,7 +1307,7 @@ gdk_rgb_convert_565_gray (GdkImage *image, gint bpl; guchar *bptr, *bp2; guchar g; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; @@ -1275,7 +1315,7 @@ gdk_rgb_convert_565_gray (GdkImage *image, { bp2 = bptr; obptr = obuf; - if (width < 8 || (((unsigned long)obuf | (unsigned long) bp2) & 3)) + if (((unsigned long)obuf | (unsigned long) bp2) & 3) { for (x = 0; x < width; x++) { @@ -1291,7 +1331,7 @@ gdk_rgb_convert_565_gray (GdkImage *image, for (x = 0; x < width - 3; x += 4) { guint32 g3g2g1g0; - + g3g2g1g0 = ((guint32 *)bp2)[0]; ((guint32 *)obptr)[0] = ((g3g2g1g0 & 0xf8) << 8) | @@ -1335,7 +1375,7 @@ gdk_rgb_convert_565_gray (GdkImage *image, gint bpl; guchar *bptr, *bp2; guchar g; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; @@ -1366,7 +1406,7 @@ gdk_rgb_convert_565_br (GdkImage *image, gint bpl; guchar *bptr, *bp2; guchar r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; @@ -1380,7 +1420,7 @@ gdk_rgb_convert_565_br (GdkImage *image, b = *bp2++; /* final word is: g4 g3 g2 b7 b6 b5 b4 b3 r7 r6 r5 r4 r3 g7 g6 g5 - */ + */ ((unsigned short *)obuf)[x] = (r & 0xf8) | ((g & 0xe0) >> 5) | ((g & 0x1c) << 11) | @@ -1396,16 +1436,16 @@ gdk_rgb_convert_565_br (GdkImage *image, #ifdef HAIRY_CONVERT_565 static void gdk_rgb_convert_565_d (GdkImage *image, - gint x0, gint y0, gint width, gint height, - guchar *buf, int rowstride, - gint x_align, gint y_align, GdkRgbCmap *cmap) + gint x0, gint y0, gint width, gint height, + guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) { /* Now this is what I'd call some highly tuned code! */ int x, y; guchar *obuf, *obptr; gint bpl; guchar *bptr, *bp2; - + width += x_align; height += y_align; @@ -1417,7 +1457,7 @@ gdk_rgb_convert_565_d (GdkImage *image, guint32 *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT); bp2 = bptr; obptr = obuf; - if (width < 8 || (((unsigned long)obuf | (unsigned long) bp2) & 3)) + if (((unsigned long)obuf | (unsigned long) bp2) & 3) { for (x = x_align; x < width; x++) { @@ -1428,8 +1468,8 @@ gdk_rgb_convert_565_d (GdkImage *image, rgb += 0x10040100 - ((rgb & 0x1e0001e0) >> 5) - ((rgb & 0x00070000) >> 6); - - ((unsigned short *)obuf)[0] = + + ((unsigned short *)obptr)[0] = ((rgb & 0x0f800000) >> 12) | ((rgb & 0x0003f000) >> 7) | ((rgb & 0x000000f8) >> 3); @@ -1444,7 +1484,7 @@ gdk_rgb_convert_565_d (GdkImage *image, guint32 g2r2b1g1; guint32 b3g3r3b2; guint32 rgb02, rgb13; - + r1b0g0r0 = ((guint32 *)bp2)[0]; g2r2b1g1 = ((guint32 *)bp2)[1]; b3g3r3b2 = ((guint32 *)bp2)[2]; @@ -1506,8 +1546,8 @@ gdk_rgb_convert_565_d (GdkImage *image, rgb += 0x10040100 - ((rgb & 0x1e0001e0) >> 5) - ((rgb & 0x00070000) >> 6); - - ((unsigned short *)obuf)[0] = + + ((unsigned short *)obptr)[0] = ((rgb & 0x0f800000) >> 12) | ((rgb & 0x0003f000) >> 7) | ((rgb & 0x000000f8) >> 3); @@ -1521,43 +1561,43 @@ gdk_rgb_convert_565_d (GdkImage *image, #else static void gdk_rgb_convert_565_d (GdkImage *image, - gint x0, gint y0, gint width, gint height, - guchar *buf, int rowstride, - gint x_align, gint y_align, GdkRgbCmap *cmap) + gint x0, gint y0, gint width, gint height, + guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) { int x, y; guchar *obuf; gint bpl; guchar *bptr; - + width += x_align; height += y_align; bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + (x0 - x_align) * 2; - + for (y = y_align; y < height; y++) { guint32 *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT); guchar *bp2 = bptr; - + for (x = x_align; x < width; x++) - { - gint32 rgb = *bp2++ << 20; - rgb += *bp2++ << 10; - rgb += *bp2++; + { + gint32 rgb = *bp2++ << 20; + rgb += *bp2++ << 10; + rgb += *bp2++; rgb += dmp[x & (DM_WIDTH - 1)]; - rgb += 0x10040100 - - ((rgb & 0x1e0001e0) >> 5) - - ((rgb & 0x00070000) >> 6); - - ((unsigned short *)obuf)[x] = - ((rgb & 0x0f800000) >> 12) | - ((rgb & 0x0003f000) >> 7) | - ((rgb & 0x000000f8) >> 3); - } - + rgb += 0x10040100 + - ((rgb & 0x1e0001e0) >> 5) + - ((rgb & 0x00070000) >> 6); + + ((unsigned short *)obuf)[x] = + ((rgb & 0x0f800000) >> 12) | + ((rgb & 0x0003f000) >> 7) | + ((rgb & 0x000000f8) >> 3); + } + bptr += rowstride; obuf += bpl; } @@ -1575,7 +1615,7 @@ gdk_rgb_convert_555 (GdkImage *image, gint bpl; guchar *bptr, *bp2; guchar r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; @@ -1607,7 +1647,7 @@ gdk_rgb_convert_555_br (GdkImage *image, gint bpl; guchar *bptr, *bp2; guchar r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; @@ -1621,7 +1661,7 @@ gdk_rgb_convert_555_br (GdkImage *image, b = *bp2++; /* final word is: g5 g4 g3 b7 b6 b5 b4 b3 0 r7 r6 r5 r4 r3 g7 g6 - */ + */ ((unsigned short *)obuf)[x] = ((r & 0xf8) >> 1) | ((g & 0xc0) >> 6) | ((g & 0x18) << 10) | @@ -1642,7 +1682,7 @@ gdk_rgb_convert_888_msb (GdkImage *image, guchar *obuf; gint bpl; guchar *bptr; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3; @@ -1671,7 +1711,7 @@ gdk_rgb_convert_888_lsb (GdkImage *image, gint bpl; guchar *bptr, *bp2; int r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3; @@ -1679,7 +1719,7 @@ gdk_rgb_convert_888_lsb (GdkImage *image, { bp2 = bptr; obptr = obuf; - if (width < 8 || (((unsigned long)obuf | (unsigned long) bp2) & 3)) + if (((unsigned long)obuf | (unsigned long) bp2) & 3) { for (x = 0; x < width; x++) { @@ -1699,7 +1739,7 @@ gdk_rgb_convert_888_lsb (GdkImage *image, guint32 r1b0g0r0; guint32 g2r2b1g1; guint32 b3g3r3b2; - + r1b0g0r0 = ((guint32 *)bp2)[0]; g2r2b1g1 = ((guint32 *)bp2)[1]; b3g3r3b2 = ((guint32 *)bp2)[2]; @@ -1745,7 +1785,7 @@ gdk_rgb_convert_888_lsb (GdkImage *image, gint bpl; guchar *bptr, *bp2; int r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3; @@ -1781,7 +1821,7 @@ gdk_rgb_convert_0888 (GdkImage *image, gint bpl; guchar *bptr, *bp2; int r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4; @@ -1812,7 +1852,7 @@ gdk_rgb_convert_0888_br (GdkImage *image, gint bpl; guchar *bptr, *bp2; int r, g, b; - + bptr = buf; bpl = image->bpl; obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4; @@ -1852,7 +1892,7 @@ gdk_rgb_convert_truecolor_lsb (GdkImage *image, gint bpp; guint32 pixel; gint i; - + r_right = 8 - image_info->visual->red_prec; r_left = image_info->visual->red_shift; g_right = 8 - image_info->visual->green_prec; @@ -1908,7 +1948,7 @@ gdk_rgb_convert_truecolor_lsb_d (GdkImage *image, gint dith; gint r1, g1, b1; guchar *dmp; - + r_right = 8 - image_info->visual->red_prec; r_left = image_info->visual->red_shift; r_prec = image_info->visual->red_prec; @@ -1969,7 +2009,7 @@ gdk_rgb_convert_truecolor_msb (GdkImage *image, gint bpp; guint32 pixel; gint shift, shift_init; - + r_right = 8 - image_info->visual->red_prec; r_left = image_info->visual->red_shift; g_right = 8 - image_info->visual->green_prec; @@ -2025,7 +2065,7 @@ gdk_rgb_convert_truecolor_msb_d (GdkImage *image, gint dith; gint r1, g1, b1; guchar *dmp; - + r_right = 8 - image_info->visual->red_prec; r_left = image_info->visual->red_shift; r_prec = image_info->visual->red_prec; @@ -2068,6 +2108,70 @@ gdk_rgb_convert_truecolor_msb_d (GdkImage *image, } } +#define IMAGE_8BPP +static void +gdk_rgb_convert_4 (GdkImage *image, + gint x0, gint y0, gint width, gint height, + guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + guchar *bptr, *bp2; + gint r, g, b; + guchar *dmp; + gint dith; + guchar pix0, pix1; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + bp2 = bptr; + obptr = obuf; +#ifdef IMAGE_8BPP + for (x = 0; x < width; x += 1) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3; + obptr[0] = colorcube_d[(((r + dith) & 0x100) >> 2) | + (((g + 258 - dith) & 0x100) >> 5) | + (((b + dith) & 0x100) >> 8)]; + obptr++; + } +#else + for (x = 0; x < width; x += 2) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3; + pix0 = colorcube_d[(((r + dith) & 0x100) >> 2) | + (((g + dith) & 0x100) >> 5) | + (((b + dith) & 0x100) >> 8)]; + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) | 3; + pix1 = colorcube_d[(((r + dith) & 0x100) >> 2) | + (((g + dith) & 0x100) >> 5) | + (((b + dith) & 0x100) >> 8)]; + obptr[0] = (pix0 << 4) | pix1; + obptr++; + } +#endif + bptr += rowstride; + obuf += bpl; + } +} + + /* Returns a pointer to the stage buffer. */ static guchar * gdk_rgb_ensure_stage (void) @@ -2084,7 +2188,7 @@ gdk_rgb_32_to_stage (guchar *buf, gint rowstride, gint width, gint height) gint x, y; guchar *pi_start, *po_start; guchar *pi, *po; - + pi_start = buf; po_start = gdk_rgb_ensure_stage (); for (y = 0; y < height; y++) @@ -2112,7 +2216,7 @@ gdk_rgb_convert_32_generic (GdkImage *image, gint x_align, gint y_align, GdkRgbCmap *cmap) { gdk_rgb_32_to_stage (buf, rowstride, width, height); - + (*image_info->conv) (image, x0, y0, width, height, image_info->stage_buf, STAGE_ROWSTRIDE, x_align, y_align, cmap); @@ -2127,7 +2231,7 @@ gdk_rgb_convert_32_generic_d (GdkImage *image, gint x_align, gint y_align, GdkRgbCmap *cmap) { gdk_rgb_32_to_stage (buf, rowstride, width, height); - + (*image_info->conv_d) (image, x0, y0, width, height, image_info->stage_buf, STAGE_ROWSTRIDE, x_align, y_align, cmap); @@ -2141,7 +2245,7 @@ gdk_rgb_gray_to_stage (guchar *buf, gint rowstride, gint width, gint height) guchar *pi_start, *po_start; guchar *pi, *po; guchar gray; - + pi_start = buf; po_start = gdk_rgb_ensure_stage (); for (y = 0; y < height; y++) @@ -2169,7 +2273,7 @@ gdk_rgb_convert_gray_generic (GdkImage *image, gint x_align, gint y_align, GdkRgbCmap *cmap) { gdk_rgb_gray_to_stage (buf, rowstride, width, height); - + (*image_info->conv) (image, x0, y0, width, height, image_info->stage_buf, STAGE_ROWSTRIDE, x_align, y_align, cmap); @@ -2182,7 +2286,7 @@ gdk_rgb_convert_gray_generic_d (GdkImage *image, gint x_align, gint y_align, GdkRgbCmap *cmap) { gdk_rgb_gray_to_stage (buf, rowstride, width, height); - + (*image_info->conv_d) (image, x0, y0, width, height, image_info->stage_buf, STAGE_ROWSTRIDE, x_align, y_align, cmap); @@ -2203,9 +2307,9 @@ gdk_rgb_convert_gray_cmap (GdkImage *image, #if 0 static void gdk_rgb_convert_gray_cmap_d (GdkImage *image, - gint x0, gint y0, gint width, gint height, - guchar *buf, gint rowstride, - gint x_align, gint y_align, GdkRgbCmap *cmap) + gint x0, gint y0, gint width, gint height, + guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) { (*image_info->conv_indexed_d) (image, x0, y0, width, height, buf, rowstride, @@ -2222,7 +2326,7 @@ gdk_rgb_indexed_to_stage (guchar *buf, gint rowstride, gint width, gint height, guchar *pi_start, *po_start; guchar *pi, *po; gint rgb; - + pi_start = buf; po_start = gdk_rgb_ensure_stage (); for (y = 0; y < height; y++) @@ -2250,7 +2354,7 @@ gdk_rgb_convert_indexed_generic (GdkImage *image, gint x_align, gint y_align, GdkRgbCmap *cmap) { gdk_rgb_indexed_to_stage (buf, rowstride, width, height, cmap); - + (*image_info->conv) (image, x0, y0, width, height, image_info->stage_buf, STAGE_ROWSTRIDE, x_align, y_align, cmap); @@ -2264,7 +2368,7 @@ gdk_rgb_convert_indexed_generic_d (GdkImage *image, GdkRgbCmap *cmap) { gdk_rgb_indexed_to_stage (buf, rowstride, width, height, cmap); - + (*image_info->conv_d) (image, x0, y0, width, height, image_info->stage_buf, STAGE_ROWSTRIDE, x_align, y_align, cmap); @@ -2283,40 +2387,40 @@ gdk_rgb_select_conv (GdkImage *image) GdkRgbConvFunc conv_32, conv_32_d; GdkRgbConvFunc conv_gray, conv_gray_d; GdkRgbConvFunc conv_indexed, conv_indexed_d; - + depth = image_info->visual->depth; bpp = image->bpp; - + byte_order = image->byte_order; - + #ifdef WORDS_BIGENDIAN byterev = (byte_order == GDK_LSB_FIRST); #else byterev = (byte_order == GDK_MSB_FIRST); #endif - + vtype = image_info->visual->type; if (vtype == GDK_VISUAL_DIRECT_COLOR) vtype = GDK_VISUAL_TRUE_COLOR; - + red_mask = image_info->visual->red_mask; green_mask = image_info->visual->green_mask; blue_mask = image_info->visual->blue_mask; - + conv = NULL; conv_d = NULL; - + conv_32 = gdk_rgb_convert_32_generic; conv_32_d = gdk_rgb_convert_32_generic_d; - + conv_gray = gdk_rgb_convert_gray_generic; conv_gray_d = gdk_rgb_convert_gray_generic_d; - + conv_indexed = gdk_rgb_convert_indexed_generic; conv_indexed_d = gdk_rgb_convert_indexed_generic_d; - + image_info->dith_default = FALSE; - + if (bpp == 2 && depth == 16 && !byterev && red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f) { @@ -2327,19 +2431,19 @@ gdk_rgb_select_conv (GdkImage *image) } else if (bpp == 2 && depth == 16 && vtype == GDK_VISUAL_TRUE_COLOR && byterev && - red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f) + red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f) conv = gdk_rgb_convert_565_br; - + else if (bpp == 2 && depth == 15 && vtype == GDK_VISUAL_TRUE_COLOR && !byterev && - red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f) + red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f) conv = gdk_rgb_convert_555; - + else if (bpp == 2 && depth == 15 && vtype == GDK_VISUAL_TRUE_COLOR && byterev && - red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f) + red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f) conv = gdk_rgb_convert_555_br; - + /* I'm not 100% sure about the 24bpp tests */ else if (bpp == 3 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_LSB_FIRST && @@ -2357,7 +2461,7 @@ gdk_rgb_select_conv (GdkImage *image) vtype == GDK_VISUAL_TRUE_COLOR && byterev && red_mask == 0xff0000 && green_mask == 0xff00 && blue_mask == 0xff) conv = gdk_rgb_convert_0888_br; - + else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_LSB_FIRST) { conv = gdk_rgb_convert_truecolor_lsb; @@ -2397,19 +2501,23 @@ gdk_rgb_select_conv (GdkImage *image) conv = gdk_rgb_convert_gray8; conv_gray = gdk_rgb_convert_gray8_gray; } - + else if (depth == 4) + { + conv = gdk_rgb_convert_4; + } + if (conv_d == NULL) conv_d = conv; - + image_info->conv = conv; image_info->conv_d = conv_d; - + image_info->conv_32 = conv_32; image_info->conv_32_d = conv_32_d; - + image_info->conv_gray = conv_gray; image_info->conv_gray_d = conv_gray_d; - + image_info->conv_indexed = conv_indexed; image_info->conv_indexed_d = conv_indexed_d; } @@ -2441,7 +2549,7 @@ gdk_rgb_alloc_scratch_image (void) gdk_flush (); #endif #ifdef VERBOSE - g_message ("flush, %d puts since last flush", sincelast); + g_print ("flush, %d puts since last flush\n", sincelast); sincelast = 0; #endif static_image_idx = 0; @@ -2458,8 +2566,8 @@ gdk_rgb_alloc_scratch (gint width, gint height, gint *x0, gint *y0) { GdkImage *image; gint idx; - - + + if (width >= (IMAGE_WIDTH >> 1)) { if (height >= (IMAGE_HEIGHT >> 1)) @@ -2519,7 +2627,7 @@ gdk_rgb_alloc_scratch (gint width, gint height, gint *x0, gint *y0) } image = static_image[idx]; #ifdef VERBOSE - g_message ("index %d, x %d, y %d (%d x %d)", idx, *x0, *y0, width, height); + g_print ("index %d, x %d, y %d (%d x %d)\n", idx, *x0, *y0, width, height); sincelast++; #endif return image; @@ -2543,7 +2651,7 @@ gdk_draw_rgb_image_core (GdkDrawable *drawable, GdkImage *image; gint width1, height1; guchar *buf_ptr; - + for (y0 = 0; y0 < height; y0 += IMAGE_HEIGHT) { height1 = MIN (height - y0, IMAGE_HEIGHT); @@ -2551,12 +2659,12 @@ gdk_draw_rgb_image_core (GdkDrawable *drawable, { width1 = MIN (width - x0, IMAGE_WIDTH); buf_ptr = buf + y0 * rowstride + x0 * pixstride; - + image = gdk_rgb_alloc_scratch (width1, height1, &xs0, &ys0); - + conv (image, xs0, ys0, width1, height1, buf_ptr, rowstride, x + x0, y + y0, cmap); - + #ifndef DONT_ACTUALLY_DRAW gdk_draw_image (drawable, gc, image, xs0, ys0, x + x0, y + y0, width1, height1); @@ -2613,9 +2721,9 @@ gdk_rgb_make_gray_cmap (GdkRgbInfo *info) { guint32 rgb[256]; gint i; - + for (i = 0; i < 256; i++) - rgb[i] = (i << 16) | (i << 8) | i; + rgb[i] = (i << 16) | (i << 8) | i; info->gray_cmap = gdk_rgb_cmap_new (rgb, 256); } @@ -2653,7 +2761,7 @@ gdk_rgb_cmap_new (guint32 *colors, gint n_colors) GdkRgbCmap *cmap; int i, j; guint32 rgb; - + g_return_val_if_fail (n_colors >= 0, NULL); g_return_val_if_fail (n_colors <= 256, NULL); cmap = g_new (GdkRgbCmap, 1); @@ -2665,10 +2773,10 @@ gdk_rgb_cmap_new (guint32 *colors, gint n_colors) { rgb = colors[i]; j = ((rgb & 0xf00000) >> 12) | - ((rgb & 0xf000) >> 8) | - ((rgb & 0xf0) >> 4); + ((rgb & 0xf000) >> 8) | + ((rgb & 0xf0) >> 4); #ifdef VERBOSE - g_message ("%d %x %x %d", i, j, colorcube[j]); + g_print ("%d %x %x %d\n", i, j, colorcube[j]); #endif cmap->lut[i] = colorcube[j]; } diff --git a/gtk/gtkpreview.c b/gtk/gtkpreview.c index 9dc9b2973c..6490fca6da 100644 --- a/gtk/gtkpreview.c +++ b/gtk/gtkpreview.c @@ -22,26 +22,12 @@ #include #include #include "gdk/gdkx.h" +#include "gdk/gdkrgb.h" #include "gtkpreview.h" #include "gtksignal.h" -#define IMAGE_SIZE 256 #define PREVIEW_CLASS(w) GTK_PREVIEW_CLASS (GTK_OBJECT (w)->klass) -#define COLOR_COMPOSE(r,g,b) (lookup_red[r] | lookup_green[g] | lookup_blue[b]) - - -typedef struct _GtkPreviewProp GtkPreviewProp; -typedef void (*GtkTransferFunc) (guchar *dest, guchar *src, gint count); - -struct _GtkPreviewProp -{ - guint16 ref_count; - guint16 nred_shades; - guint16 ngreen_shades; - guint16 nblue_shades; - guint16 ngray_shades; -}; static void gtk_preview_class_init (GtkPreviewClass *klass); @@ -51,77 +37,10 @@ static void gtk_preview_realize (GtkWidget *widget); static gint gtk_preview_expose (GtkWidget *widget, GdkEventExpose *event); static void gtk_preview_make_buffer (GtkPreview *preview); -static void gtk_preview_get_visuals (GtkPreviewClass *klass); -static void gtk_preview_get_cmaps (GtkPreviewClass *klass); -static void gtk_preview_dither_init (GtkPreviewClass *klass); -static void gtk_fill_lookup_array (gulong *array, - int depth, - int shift, - int prec); -static void gtk_trim_cmap (GtkPreviewClass *klass); -static void gtk_create_8_bit (GtkPreviewClass *klass); - -static void gtk_color_8 (guchar *src, - guchar *data, - gint x, - gint y, - gulong width); -static void gtk_color_16 (guchar *src, - guchar *data, - gulong width); -static void gtk_color_24 (guchar *src, - guchar *data, - gulong width); -static void gtk_grayscale_8 (guchar *src, - guchar *data, - gint x, - gint y, - gulong width); -static void gtk_grayscale_16 (guchar *src, - guchar *data, - gulong width); -static void gtk_grayscale_24 (guchar *src, - guchar *data, - gulong width); - -static gint gtk_get_preview_prop (guint *nred, - guint *nblue, - guint *ngreen, - guint *ngray); -static void gtk_set_preview_prop (guint nred, - guint ngreen, - guint nblue, - guint ngray); - -/* transfer functions: - * destination byte order/source bpp/destination bpp - */ -static void gtk_lsbmsb_1_1 (guchar *dest, - guchar *src, - gint count); -static void gtk_lsb_2_2 (guchar *dest, - guchar *src, - gint count); -static void gtk_msb_2_2 (guchar *dest, - guchar *src, - gint count); -static void gtk_lsb_3_3 (guchar *dest, - guchar *src, - gint count); -static void gtk_msb_3_3 (guchar *dest, - guchar *src, - gint count); -static void gtk_lsb_3_4 (guchar *dest, - guchar *src, - gint count); -static void gtk_msb_3_4 (guchar *dest, - guchar *src, - gint count); - +static void gtk_fill_lookup_array (guchar *array); static GtkWidgetClass *parent_class = NULL; static GtkPreviewClass *preview_class = NULL; -static GtkPreviewInfo *preview_info = NULL; static gint install_cmap = FALSE; @@ -167,113 +86,22 @@ gtk_preview_class_init (GtkPreviewClass *klass) widget_class->realize = gtk_preview_realize; widget_class->expose_event = gtk_preview_expose; - if (preview_info) - klass->info = *preview_info; - else - { - klass->info.visual = NULL; - klass->info.cmap = NULL; + klass->info.visual = NULL; + klass->info.cmap = NULL; - klass->info.color_pixels = NULL; - klass->info.gray_pixels = NULL; - klass->info.reserved_pixels = NULL; + klass->info.lookup = NULL; - klass->info.lookup_red = NULL; - klass->info.lookup_green = NULL; - klass->info.lookup_blue = NULL; + klass->info.gamma = 1.0; - klass->info.dither_red = NULL; - klass->info.dither_green = NULL; - klass->info.dither_blue = NULL; - klass->info.dither_gray = NULL; - klass->info.dither_matrix = NULL; - - klass->info.nred_shades = 6; - klass->info.ngreen_shades = 6; - klass->info.nblue_shades = 4; - klass->info.ngray_shades = 24; - klass->info.nreserved = 0; - - klass->info.bpp = 0; - klass->info.cmap_alloced = FALSE; - klass->info.gamma = 1.0; - } - - klass->image = NULL; - - gtk_preview_get_visuals (klass); - gtk_preview_get_cmaps (klass); - gtk_preview_dither_init (klass); + gdk_rgb_init (); + klass->info.cmap = gdk_rgb_get_cmap (); + klass->info.visual = gdk_rgb_get_visual (); } void gtk_preview_reset (void) { - GtkPreviewInfo *info; - - if (!preview_class || !preview_info) - return; - - info = &preview_class->info; - - gtk_preview_uninit(); - - if (info->color_pixels) - { - gdk_colors_free (info->cmap, - info->color_pixels, - info->nred_shades * - info->ngreen_shades * - info->nblue_shades, - 0); - - gdk_colors_free (info->cmap, - info->gray_pixels, - info->ngray_shades, 0); - - g_free (info->color_pixels); - g_free (info->gray_pixels); - } - - if (info->reserved_pixels) - { - gdk_colors_free (info->cmap, - info->reserved_pixels, - info->nreserved, 0); - g_free (info->reserved_pixels); - } - - if (info->cmap && info->cmap_alloced) - gdk_colormap_unref (info->cmap); - - if (info->lookup_red) - { - g_free (info->lookup_red); - g_free (info->lookup_green); - g_free (info->lookup_blue); - } - - if (info->dither_matrix) - { - int i, j; - - for (i= 0 ; i < 8 ; i++) - { - for (j = 0; j < 8 ; j++) - g_free (info->dither_matrix[i][j]); - g_free (info->dither_matrix[i]); - } - g_free (info->dither_matrix); - g_free (info->dither_red); - g_free (info->dither_green); - g_free (info->dither_blue); - } - - preview_class->info = *preview_info; - - gtk_preview_get_visuals (preview_class); - gtk_preview_get_cmaps (preview_class); - gtk_preview_dither_init (preview_class); + /* unimplemented */ } static void @@ -290,34 +118,8 @@ gtk_preview_init (GtkPreview *preview) void gtk_preview_uninit (void) { - GtkPreviewProp *prop; - GdkAtom property; - /* FIXME: need to grab the server here to prevent a race condition */ - - if (preview_class && !install_cmap && preview_class->info.visual && - (preview_class->info.visual->type != GDK_VISUAL_TRUE_COLOR) && - (preview_class->info.visual->type != GDK_VISUAL_DIRECT_COLOR)) - { - property = gdk_atom_intern ("GTK_PREVIEW_INFO", FALSE); - - if (gdk_property_get (NULL, property, property, - 0, sizeof (GtkPreviewProp), FALSE, - NULL, NULL, NULL, (guchar**) &prop)) - { - prop->ref_count = prop->ref_count - 1; - if (prop->ref_count == 0) - { - gdk_property_delete (NULL, property); - } - else - { - gdk_property_change (NULL, property, property, 16, - GDK_PROP_MODE_REPLACE, - (guchar*) prop, 5); - } - } - } + /* unimplemented */ } GtkWidget* @@ -328,6 +130,13 @@ gtk_preview_new (GtkPreviewType type) preview = gtk_type_new (gtk_preview_get_type ()); preview->type = type; + if (type == GTK_PREVIEW_COLOR) + preview->bpp = 3; + else + preview->bpp = 1; + + preview->dither = GDK_RGB_DITHER_NORMAL; + return GTK_WIDGET (preview); } @@ -363,17 +172,10 @@ gtk_preview_put (GtkPreview *preview, gint height) { GtkWidget *widget; - GdkImage *image; GdkRectangle r1, r2, r3; - GtkTransferFunc transfer_func; - guchar *image_mem; - guchar *src, *dest; - gint x, xe, x2; - gint y, ye, y2; - guint dest_rowstride; - guint src_bpp; - guint dest_bpp; - gint i; + guchar *src; + guint bpp; + guint rowstride; g_return_if_fail (preview != NULL); g_return_if_fail (GTK_IS_PREVIEW (preview)); @@ -397,106 +199,32 @@ gtk_preview_put (GtkPreview *preview, if (!gdk_rectangle_intersect (&r1, &r2, &r3)) return; - x2 = r3.x + r3.width; - y2 = r3.y + r3.height; + bpp = preview->bpp; + rowstride = preview->rowstride; - if (!preview_class->image) - preview_class->image = gdk_image_new (GDK_IMAGE_FASTEST, - preview_class->info.visual, - IMAGE_SIZE, IMAGE_SIZE); - image = preview_class->image; - src_bpp = preview_class->info.bpp; + src = preview->buffer + r3.y * rowstride + r3.x * bpp; - image_mem = image->mem; - dest_bpp = image->bpp; - dest_rowstride = image->bpl; - - transfer_func = NULL; - - switch (dest_bpp) - { - case 1: - switch (src_bpp) - { - case 1: - transfer_func = gtk_lsbmsb_1_1; - break; - } - break; - case 2: - switch (src_bpp) - { - case 2: - if (image->byte_order == GDK_MSB_FIRST) - transfer_func = gtk_msb_2_2; - else - transfer_func = gtk_lsb_2_2; - break; - case 3: - break; - } - break; - case 3: - switch (src_bpp) - { - case 3: - if (image->byte_order == GDK_MSB_FIRST) - transfer_func = gtk_msb_3_3; - else - transfer_func = gtk_lsb_3_3; - break; - } - break; - case 4: - switch (src_bpp) - { - case 3: - if (image->byte_order == GDK_MSB_FIRST) - transfer_func = gtk_msb_3_4; - else - transfer_func = gtk_lsb_3_4; - break; - } - break; - } - - if (!transfer_func) - { - g_warning ("unsupported byte order/src bpp/dest bpp combination: %s:%d:%d", - (image->byte_order == GDK_MSB_FIRST) ? "msb" : "lsb", src_bpp, dest_bpp); - return; - } - - for (y = r3.y; y < y2; y += IMAGE_SIZE) - { - for (x = r3.x; x < x2; x += IMAGE_SIZE) - { - xe = x + IMAGE_SIZE; - if (xe > x2) - xe = x2; - - ye = y + IMAGE_SIZE; - if (ye > y2) - ye = y2; - - for (i = y; i < ye; i++) - { - src = preview->buffer + (((gulong) (i - r1.y) * (gulong) preview->buffer_width) + - (x - r1.x)) * (gulong) src_bpp; - dest = image_mem + ((gulong) (i - y) * dest_rowstride); - - if (xe > x) - (* transfer_func) (dest, src, xe - x); - } - - gdk_draw_image (window, gc, - image, 0, 0, - destx + (r3.x - srcx) + (x - r3.x), - desty + (r3.y - srcy) + (y - r3.y), - xe - x, ye - y); - gdk_flush (); - } - } + if (preview->type == GTK_PREVIEW_COLOR) + gdk_draw_rgb_image (window, + gc, + destx + (r3.x - srcx), + desty + (r3.y - srcy), + r3.width, + r3.height, + preview->dither, + src, + rowstride); + else + gdk_draw_gray_image (window, + gc, + destx + (r3.x - srcx), + desty + (r3.y - srcy), + r3.width, + r3.height, + preview->dither, + src, + rowstride); + } void @@ -507,46 +235,7 @@ gtk_preview_put_row (GtkPreview *preview, gint y, gint w) { - g_return_if_fail (preview != NULL); - g_return_if_fail (GTK_IS_PREVIEW (preview)); - g_return_if_fail (src != NULL); - g_return_if_fail (dest != NULL); - - switch (preview->type) - { - case GTK_PREVIEW_COLOR: - switch (preview_class->info.visual->depth) - { - case 8: - gtk_color_8 (src, dest, x, y, w); - break; - case 15: - case 16: - gtk_color_16 (src, dest, w); - break; - case 24: - case 32: - gtk_color_24 (src, dest, w); - break; - } - break; - case GTK_PREVIEW_GRAYSCALE: - switch (preview_class->info.visual->depth) - { - case 8: - gtk_grayscale_8 (src, dest, x, y, w); - break; - case 15: - case 16: - gtk_grayscale_16 (src, dest, w); - break; - case 24: - case 32: - gtk_grayscale_24 (src, dest, w); - break; - } - break; - } + g_warning ("gtk_preview_put_row not implemented (deprecated)\n"); } void @@ -556,13 +245,17 @@ gtk_preview_draw_row (GtkPreview *preview, gint y, gint w) { - guchar *dest; + guint bpp; + guint rowstride; g_return_if_fail (preview != NULL); g_return_if_fail (GTK_IS_PREVIEW (preview)); g_return_if_fail (data != NULL); g_return_if_fail (preview_class->info.visual != NULL); + bpp = (preview->type == GTK_PREVIEW_COLOR ? 3 : 1); + rowstride = (preview->buffer_width * bpp + 3) & -4; + if ((w <= 0) || (y < 0)) return; @@ -570,49 +263,33 @@ gtk_preview_draw_row (GtkPreview *preview, gtk_preview_make_buffer (preview); - if (y >= preview->buffer_height) + if (x + w > preview->buffer_width) return; - switch (preview->type) + if (y + 1 > preview->buffer_height) + return; + + if (preview_class->info.gamma == 1.0) + memcpy (preview->buffer + y * rowstride + x * bpp, data, w * bpp); + else { - case GTK_PREVIEW_COLOR: - switch (preview_class->info.visual->depth) + guint i, size; + guchar *src, *dst; + guchar *lookup; + + if (preview_class->info.lookup != NULL) + lookup = preview_class->info.lookup; + else { - case 8: - dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x); - gtk_color_8 (data, dest, x, y, w); - break; - case 15: - case 16: - dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 2; - gtk_color_16 (data, dest, w); - break; - case 24: - case 32: - dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 3; - gtk_color_24 (data, dest, w); - break; + preview_class->info.lookup = g_new (guchar, 256); + gtk_fill_lookup_array (preview_class->info.lookup); + lookup = preview_class->info.lookup; } - break; - case GTK_PREVIEW_GRAYSCALE: - switch (preview_class->info.visual->depth) - { - case 8: - dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x); - gtk_grayscale_8 (data, dest, x, y, w); - break; - case 15: - case 16: - dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 2; - gtk_grayscale_16 (data, dest, w); - break; - case 24: - case 32: - dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 3; - gtk_grayscale_24 (data, dest, w); - break; - } - break; + size = w * bpp; + src = data; + dst = preview->buffer + y * rowstride + x * bpp; + for (i = 0; i < size; i++) + *dst++ = lookup[*src++]; } } @@ -629,16 +306,18 @@ gtk_preview_set_expand (GtkPreview *preview, void gtk_preview_set_gamma (double _gamma) { - if (!preview_info) - { - preview_info = g_new0 (GtkPreviewInfo, 1); - preview_info->nred_shades = 6; - preview_info->ngreen_shades = 6; - preview_info->nblue_shades = 4; - preview_info->ngray_shades = 24; - } + if (!preview_class) + preview_class = gtk_type_class (gtk_preview_get_type ()); - preview_info->gamma = _gamma; + if (preview_class->info.gamma != _gamma) + { + preview_class->info.gamma = _gamma; + if (preview_class->info.lookup != NULL) + { + g_free (preview_class->info.lookup); + preview_class->info.lookup = NULL; + } + } } void @@ -647,31 +326,28 @@ gtk_preview_set_color_cube (guint nred_shades, guint nblue_shades, guint ngray_shades) { - if (!preview_info) - { - preview_info = g_new0 (GtkPreviewInfo, 1); - preview_info->gamma = 1.0; - } - - preview_info->nred_shades = nred_shades; - preview_info->ngreen_shades = ngreen_shades; - preview_info->nblue_shades = nblue_shades; - preview_info->ngray_shades = ngray_shades; + /* unimplemented */ } void gtk_preview_set_install_cmap (gint _install_cmap) { + /* effectively unimplemented */ install_cmap = _install_cmap; } void gtk_preview_set_reserved (gint nreserved) { - if (!preview_info) - preview_info = g_new0 (GtkPreviewInfo, 1); - preview_info->nreserved = nreserved; + /* unimplemented */ +} + +void +gtk_preview_set_dither (GtkPreview *preview, + GdkRgbDither dither) +{ + preview->dither = dither; } GdkVisual* @@ -811,837 +487,28 @@ gtk_preview_make_buffer (GtkPreview *preview) preview->buffer_width = width; preview->buffer_height = height; + preview->rowstride = (preview->buffer_width * preview->bpp + 3) & -4; preview->buffer = g_new0 (guchar, - preview->buffer_width * preview->buffer_height * - preview_class->info.bpp); + preview->rowstride); } } +/* This will be useful for implementing gamma. */ static void -gtk_preview_get_visuals (GtkPreviewClass *klass) -{ - static GdkVisualType types[] = - { - GDK_VISUAL_TRUE_COLOR, - GDK_VISUAL_DIRECT_COLOR, - GDK_VISUAL_TRUE_COLOR, - GDK_VISUAL_DIRECT_COLOR, - GDK_VISUAL_TRUE_COLOR, - GDK_VISUAL_DIRECT_COLOR, - GDK_VISUAL_TRUE_COLOR, - GDK_VISUAL_DIRECT_COLOR, - GDK_VISUAL_PSEUDO_COLOR, - GDK_VISUAL_STATIC_COLOR, - GDK_VISUAL_STATIC_GRAY - }; - static gint depths[] = { 24, 24, 32, 32, 16, 16, 15, 15, 8, 4, 1 }; - static gint nvisual_types = sizeof (types) / sizeof (types[0]); - - int i; - - g_return_if_fail (klass != NULL); - - if (!klass->info.visual) - for (i = 0; i < nvisual_types; i++) - if ((klass->info.visual = gdk_visual_get_best_with_both (depths[i], types[i]))) - { - if ((klass->info.visual->type == GDK_VISUAL_TRUE_COLOR) || - (klass->info.visual->type == GDK_VISUAL_DIRECT_COLOR)) - { - klass->info.lookup_red = g_new (gulong, 256); - klass->info.lookup_green = g_new (gulong, 256); - klass->info.lookup_blue = g_new (gulong, 256); - - gtk_fill_lookup_array (klass->info.lookup_red, - klass->info.visual->depth, - klass->info.visual->red_shift, - 8 - klass->info.visual->red_prec); - gtk_fill_lookup_array (klass->info.lookup_green, - klass->info.visual->depth, - klass->info.visual->green_shift, - 8 - klass->info.visual->green_prec); - gtk_fill_lookup_array (klass->info.lookup_blue, - klass->info.visual->depth, - klass->info.visual->blue_shift, - 8 - klass->info.visual->blue_prec); - } - break; - } - - if (!klass->info.visual) - { - g_warning ("unable to find a suitable visual for color image display.\n"); - return; - } - - /* If we are _not_ running with an installed cmap, we must run - * with the system visual. Otherwise, we let GDK pick the visual, - * and it makes some effort to pick a non-default visual, which - * will hopefully provide minimum color flashing. - */ - if ((klass->info.visual->depth == gdk_visual_get_system()->depth) && - (klass->info.visual->type == gdk_visual_get_system()->type) && - !install_cmap) - { - klass->info.visual = gdk_visual_get_system(); - } - - switch (klass->info.visual->depth) - { - case 1: - case 4: - case 8: - klass->info.bpp = 1; - break; - case 15: - case 16: - klass->info.bpp = 2; - break; - case 24: - case 32: - klass->info.bpp = 3; - break; - } -} - -static void -gtk_preview_get_cmaps (GtkPreviewClass *klass) -{ - g_return_if_fail (klass != NULL); - g_return_if_fail (klass->info.visual != NULL); - - if ((klass->info.visual->type != GDK_VISUAL_TRUE_COLOR) && - (klass->info.visual->type != GDK_VISUAL_DIRECT_COLOR)) - { - if (install_cmap) - { - klass->info.cmap = gdk_colormap_new (klass->info.visual, FALSE); - klass->info.cmap_alloced = install_cmap; - - gtk_trim_cmap (klass); - gtk_create_8_bit (klass); - } - else - { - guint nred; - guint ngreen; - guint nblue; - guint ngray; - gint set_prop; - - klass->info.cmap = gdk_colormap_get_system (); - - set_prop = TRUE; - if (gtk_get_preview_prop (&nred, &ngreen, &nblue, &ngray)) - { - set_prop = FALSE; - - klass->info.nred_shades = nred; - klass->info.ngreen_shades = ngreen; - klass->info.nblue_shades = nblue; - klass->info.ngray_shades = ngray; - - if (klass->info.nreserved) - { - klass->info.reserved_pixels = g_new (gulong, klass->info.nreserved); - if (!gdk_colors_alloc (klass->info.cmap, 0, NULL, 0, - klass->info.reserved_pixels, - klass->info.nreserved)) - { - g_free (klass->info.reserved_pixels); - klass->info.reserved_pixels = NULL; - } - } - } - else - { - gtk_trim_cmap (klass); - } - - gtk_create_8_bit (klass); - - if (set_prop) - gtk_set_preview_prop (klass->info.nred_shades, - klass->info.ngreen_shades, - klass->info.nblue_shades, - klass->info.ngray_shades); - } - } - else - { - if (klass->info.visual == gdk_visual_get_system ()) - klass->info.cmap = gdk_colormap_get_system (); - else - { - klass->info.cmap = gdk_colormap_new (klass->info.visual, FALSE); - klass->info.cmap_alloced = TRUE; - } - - klass->info.nred_shades = 0; - klass->info.ngreen_shades = 0; - klass->info.nblue_shades = 0; - klass->info.ngray_shades = 0; - } -} - -static void -gtk_preview_dither_init (GtkPreviewClass *klass) -{ - int i, j, k; - unsigned char low_shade, high_shade; - unsigned short index; - long red_mult, green_mult; - double red_matrix_width; - double green_matrix_width; - double blue_matrix_width; - double gray_matrix_width; - double red_colors_per_shade; - double green_colors_per_shade; - double blue_colors_per_shade; - double gray_colors_per_shade; - gulong *gray_pixels; - gint shades_r, shades_g, shades_b, shades_gray; - GtkDitherInfo *red_ordered_dither; - GtkDitherInfo *green_ordered_dither; - GtkDitherInfo *blue_ordered_dither; - GtkDitherInfo *gray_ordered_dither; - guchar ***dither_matrix; - guchar DM[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 (!klass->info.visual || klass->info.visual->type != GDK_VISUAL_PSEUDO_COLOR) - return; - - shades_r = klass->info.nred_shades; - shades_g = klass->info.ngreen_shades; - shades_b = klass->info.nblue_shades; - shades_gray = klass->info.ngray_shades; - - red_mult = shades_g * shades_b; - green_mult = shades_b; - - red_colors_per_shade = 255.0 / (shades_r - 1); - red_matrix_width = red_colors_per_shade / 64; - - green_colors_per_shade = 255.0 / (shades_g - 1); - green_matrix_width = green_colors_per_shade / 64; - - blue_colors_per_shade = 255.0 / (shades_b - 1); - blue_matrix_width = blue_colors_per_shade / 64; - - gray_colors_per_shade = 255.0 / (shades_gray - 1); - gray_matrix_width = gray_colors_per_shade / 64; - - /* alloc the ordered dither arrays for accelerated dithering */ - - klass->info.dither_red = g_new (GtkDitherInfo, 256); - klass->info.dither_green = g_new (GtkDitherInfo, 256); - klass->info.dither_blue = g_new (GtkDitherInfo, 256); - klass->info.dither_gray = g_new (GtkDitherInfo, 256); - - red_ordered_dither = klass->info.dither_red; - green_ordered_dither = klass->info.dither_green; - blue_ordered_dither = klass->info.dither_blue; - gray_ordered_dither = klass->info.dither_gray; - - dither_matrix = g_new (guchar**, 8); - for (i = 0; i < 8; i++) - { - dither_matrix[i] = g_new (guchar*, 8); - for (j = 0; j < 8; j++) - dither_matrix[i][j] = g_new (guchar, 65); - } - - klass->info.dither_matrix = dither_matrix; - - /* setup the ordered_dither_matrices */ - - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) - for (k = 0; k <= 64; k++) - dither_matrix[i][j][k] = (DM[i][j] < k) ? 1 : 0; - - /* setup arrays containing three bytes of information for red, green, & blue */ - /* the arrays contain : - * 1st byte: low end shade value - * 2nd byte: high end shade value - * 3rd & 4th bytes: ordered dither matrix index - */ - - gray_pixels = klass->info.gray_pixels; - - for (i = 0; i < 256; i++) - { - - /* setup the red information */ - { - low_shade = (unsigned char) (i / red_colors_per_shade); - if (low_shade == (shades_r - 1)) - low_shade--; - high_shade = low_shade + 1; - - index = (unsigned short) - (((double) i - low_shade * red_colors_per_shade) / - red_matrix_width); - - low_shade *= red_mult; - high_shade *= red_mult; - - red_ordered_dither[i].s[1] = index; - red_ordered_dither[i].c[0] = low_shade; - red_ordered_dither[i].c[1] = high_shade; - } - - - /* setup the green information */ - { - low_shade = (unsigned char) (i / green_colors_per_shade); - if (low_shade == (shades_g - 1)) - low_shade--; - high_shade = low_shade + 1; - - index = (unsigned short) - (((double) i - low_shade * green_colors_per_shade) / - green_matrix_width); - - low_shade *= green_mult; - high_shade *= green_mult; - - green_ordered_dither[i].s[1] = index; - green_ordered_dither[i].c[0] = low_shade; - green_ordered_dither[i].c[1] = high_shade; - } - - - /* setup the blue information */ - { - low_shade = (unsigned char) (i / blue_colors_per_shade); - if (low_shade == (shades_b - 1)) - low_shade--; - high_shade = low_shade + 1; - - index = (unsigned short) - (((double) i - low_shade * blue_colors_per_shade) / - blue_matrix_width); - - blue_ordered_dither[i].s[1] = index; - blue_ordered_dither[i].c[0] = low_shade; - blue_ordered_dither[i].c[1] = high_shade; - } - - - /* setup the gray information */ - { - low_shade = (unsigned char) (i / gray_colors_per_shade); - if (low_shade == (shades_gray - 1)) - low_shade--; - high_shade = low_shade + 1; - - index = (unsigned short) - (((double) i - low_shade * gray_colors_per_shade) / - gray_matrix_width); - - gray_ordered_dither[i].s[1] = index; - gray_ordered_dither[i].c[0] = gray_pixels[low_shade]; - gray_ordered_dither[i].c[1] = gray_pixels[high_shade]; - } - } -} - -static void -gtk_fill_lookup_array (gulong *array, - int depth, - int shift, - int prec) +gtk_fill_lookup_array (guchar *array) { double one_over_gamma; double ind; int val; int i; - if (preview_class->info.gamma != 0.0) - one_over_gamma = 1.0 / preview_class->info.gamma; - else - one_over_gamma = 1.0; + one_over_gamma = 1.0 / preview_class->info.gamma; for (i = 0; i < 256; i++) { - if (one_over_gamma == 1.0) - array[i] = ((i >> prec) << shift); - else - { - ind = (double) i / 255.0; - val = (int) (255 * pow (ind, one_over_gamma)); - array[i] = ((val >> prec) << shift); - } - } -} - -static void -gtk_trim_cmap (GtkPreviewClass *klass) -{ - gulong pixels[256]; - guint nred; - guint ngreen; - guint nblue; - guint ngray; - guint nreserved; - guint total; - guint tmp; - gint success; - - nred = klass->info.nred_shades; - ngreen = klass->info.ngreen_shades; - nblue = klass->info.nblue_shades; - ngray = klass->info.ngray_shades; - nreserved = klass->info.nreserved; - - success = FALSE; - while (!success) - { - total = nred * ngreen * nblue + ngray + nreserved; - - if (total <= 256) - { - if ((nred < 2) || (ngreen < 2) || (nblue < 2) || (ngray < 2)) - success = TRUE; - else - { - success = gdk_colors_alloc (klass->info.cmap, 0, NULL, 0, pixels, total); - if (success) - { - if (nreserved > 0) - { - klass->info.reserved_pixels = g_new (gulong, nreserved); - memcpy (klass->info.reserved_pixels, pixels, sizeof (gulong) * nreserved); - gdk_colors_free (klass->info.cmap, &pixels[nreserved], - total - nreserved, 0); - } - else - { - gdk_colors_free (klass->info.cmap, pixels, total, 0); - } - } - } - } - - if (!success) - { - if ((nblue >= nred) && (nblue >= ngreen)) - nblue = nblue - 1; - else if ((nred >= ngreen) && (nred >= nblue)) - nred = nred - 1; - else - { - tmp = log ((gdouble)ngray) / log (2.0); - - if (ngreen >= tmp) - ngreen = ngreen - 1; - else - ngray -= 1; - } - } - } - - if ((nred < 2) || (ngreen < 2) || (nblue < 2) || (ngray < 2)) - { - g_message ("Unable to allocate sufficient colormap entries."); - g_message ("Try exiting other color intensive applications."); - return; - } - - /* If any of the shade values has changed, issue a warning */ - if ((nred != klass->info.nred_shades) || - (ngreen != klass->info.ngreen_shades) || - (nblue != klass->info.nblue_shades) || - (ngray != klass->info.ngray_shades)) - { - g_message ("Not enough colors to satisfy requested color cube."); - g_message ("Reduced color cube shades from"); - g_message ("[%d of Red, %d of Green, %d of Blue, %d of Gray] ==> [%d of Red, %d of Green, %d of Blue, %d of Gray]\n", - klass->info.nred_shades, klass->info.ngreen_shades, - klass->info.nblue_shades, klass->info.ngray_shades, - nred, ngreen, nblue, ngray); - } - - klass->info.nred_shades = nred; - klass->info.ngreen_shades = ngreen; - klass->info.nblue_shades = nblue; - klass->info.ngray_shades = ngray; -} - -static void -gtk_create_8_bit (GtkPreviewClass *klass) -{ - unsigned int r, g, b; - unsigned int rv, gv, bv; - unsigned int dr, dg, db, dgray; - GdkColor color; - gulong *pixels; - double one_over_gamma; - int i; - - if (!klass->info.color_pixels) - klass->info.color_pixels = g_new (gulong, 256); - - if (!klass->info.gray_pixels) - klass->info.gray_pixels = g_new (gulong, 256); - - if (klass->info.gamma != 0.0) - one_over_gamma = 1.0 / klass->info.gamma; - else - one_over_gamma = 1.0; - - dr = klass->info.nred_shades - 1; - dg = klass->info.ngreen_shades - 1; - db = klass->info.nblue_shades - 1; - dgray = klass->info.ngray_shades - 1; - - pixels = klass->info.color_pixels; - - for (r = 0, i = 0; r <= dr; r++) - for (g = 0; g <= dg; g++) - for (b = 0; b <= db; b++, i++) - { - rv = (unsigned int) ((r * klass->info.visual->colormap_size) / dr); - gv = (unsigned int) ((g * klass->info.visual->colormap_size) / dg); - bv = (unsigned int) ((b * klass->info.visual->colormap_size) / db); - color.red = ((int) (255 * pow ((double) rv / 256.0, one_over_gamma))) * 257; - color.green = ((int) (255 * pow ((double) gv / 256.0, one_over_gamma))) * 257; - color.blue = ((int) (255 * pow ((double) bv / 256.0, one_over_gamma))) * 257; - - if (!gdk_color_alloc (klass->info.cmap, &color)) - { - g_error ("could not initialize 8-bit combined colormap"); - return; - } - - pixels[i] = color.pixel; - } - - - pixels = klass->info.gray_pixels; - - for (i = 0; i < (int) klass->info.ngray_shades; i++) - { - color.red = (i * klass->info.visual->colormap_size) / dgray; - color.red = ((int) (255 * pow ((double) color.red / 256.0, one_over_gamma))) * 257; - color.green = color.red; - color.blue = color.red; - - if (!gdk_color_alloc (klass->info.cmap, &color)) - { - g_error ("could not initialize 8-bit combined colormap"); - return; - } - - pixels[i] = color.pixel; - } -} - - -static void -gtk_color_8 (guchar *src, - guchar *dest, - gint x, - gint y, - gulong width) -{ - gulong *colors; - GtkDitherInfo *dither_red; - GtkDitherInfo *dither_green; - GtkDitherInfo *dither_blue; - GtkDitherInfo r, g, b; - guchar **dither_matrix; - guchar *matrix; - - colors = preview_class->info.color_pixels; - dither_red = preview_class->info.dither_red; - dither_green = preview_class->info.dither_green; - dither_blue = preview_class->info.dither_blue; - dither_matrix = preview_class->info.dither_matrix[y & 0x7]; - - while (width--) - { - r = dither_red[src[0]]; - g = dither_green[src[1]]; - b = dither_blue[src[2]]; - src += 3; - - matrix = dither_matrix[x++ & 0x7]; - *dest++ = colors[(r.c[matrix[r.s[1]]] + - g.c[matrix[g.s[1]]] + - b.c[matrix[b.s[1]]])]; - } -} - -static void -gtk_color_16 (guchar *src, - guchar *dest, - gulong width) -{ - gulong *lookup_red; - gulong *lookup_green; - gulong *lookup_blue; - gulong val; - - lookup_red = preview_class->info.lookup_red; - lookup_green = preview_class->info.lookup_green; - lookup_blue = preview_class->info.lookup_blue; - - while (width--) - { - val = COLOR_COMPOSE (src[0], src[1], src[2]); - dest[0] = val; - dest[1] = val >> 8; - dest += 2; - src += 3; - } -} - -static void -gtk_color_24 (guchar *src, - guchar *dest, - gulong width) -{ - gulong *lookup_red; - gulong *lookup_green; - gulong *lookup_blue; - gulong val; - - lookup_red = preview_class->info.lookup_red; - lookup_green = preview_class->info.lookup_green; - lookup_blue = preview_class->info.lookup_blue; - - while (width--) - { - val = COLOR_COMPOSE (src[0], src[1], src[2]); - dest[0] = val; - dest[1] = val >> 8; - dest[2] = val >> 16; - dest += 3; - src += 3; - } -} - -static void -gtk_grayscale_8 (guchar *src, - guchar *dest, - gint x, - gint y, - gulong width) -{ - GtkDitherInfo *dither_gray; - GtkDitherInfo gray; - guchar **dither_matrix; - guchar *matrix; - - dither_gray = preview_class->info.dither_gray; - dither_matrix = preview_class->info.dither_matrix[y & 0x7]; - - while (width--) - { - gray = dither_gray[*src++]; - matrix = dither_matrix[x++ & 0x7]; - *dest++ = gray.c[matrix[gray.s[1]]]; - } -} - -static void -gtk_grayscale_16 (guchar *src, - guchar *dest, - gulong width) -{ - gulong *lookup_red; - gulong *lookup_green; - gulong *lookup_blue; - gulong val; - - lookup_red = preview_class->info.lookup_red; - lookup_green = preview_class->info.lookup_green; - lookup_blue = preview_class->info.lookup_blue; - - while (width--) - { - val = COLOR_COMPOSE (*src, *src, *src); - dest[0] = val; - dest[1] = val >> 8; - dest += 2; - src += 1; - } -} - -static void -gtk_grayscale_24 (guchar *src, - guchar *dest, - gulong width) -{ - gulong *lookup_red; - gulong *lookup_green; - gulong *lookup_blue; - gulong val; - - lookup_red = preview_class->info.lookup_red; - lookup_green = preview_class->info.lookup_green; - lookup_blue = preview_class->info.lookup_blue; - - while (width--) - { - val = COLOR_COMPOSE (*src, *src, *src); - dest[0] = val; - dest[1] = val >> 8; - dest[2] = val >> 16; - dest += 3; - src += 1; - } -} - - -static gint -gtk_get_preview_prop (guint *nred, - guint *ngreen, - guint *nblue, - guint *ngray) -{ - GtkPreviewProp *prop; - GdkAtom property; - - /* FIXME: need to grab the server here to prevent a race condition */ - - property = gdk_atom_intern ("GTK_PREVIEW_INFO", FALSE); - - if (gdk_property_get (NULL, property, property, - 0, sizeof (GtkPreviewProp), FALSE, - NULL, NULL, NULL, (guchar**) &prop)) - { - *nred = prop->nred_shades; - *ngreen = prop->ngreen_shades; - *nblue = prop->nblue_shades; - *ngray = prop->ngray_shades; - - prop->ref_count = prop->ref_count + 1; - gdk_property_change (NULL, property, property, 16, - GDK_PROP_MODE_REPLACE, - (guchar*) prop, 5); - - return TRUE; - } - - return FALSE; -} - -static void -gtk_set_preview_prop (guint nred, - guint ngreen, - guint nblue, - guint ngray) -{ - GtkPreviewProp prop; - GdkAtom property; - - property = gdk_atom_intern ("GTK_PREVIEW_INFO", FALSE); - - prop.ref_count = 1; - prop.nred_shades = nred; - prop.ngreen_shades = ngreen; - prop.nblue_shades = nblue; - prop.ngray_shades = ngray; - - gdk_property_change (NULL, property, property, 16, - GDK_PROP_MODE_REPLACE, - (guchar*) &prop, 5); -} - - -static void -gtk_lsbmsb_1_1 (guchar *dest, - guchar *src, - gint count) -{ - memcpy (dest, src, count); -} - -static void -gtk_lsb_2_2 (guchar *dest, - guchar *src, - gint count) -{ - memcpy (dest, src, count * 2); -} - -static void -gtk_msb_2_2 (guchar *dest, - guchar *src, - gint count) -{ - while (count--) - { - dest[0] = src[1]; - dest[1] = src[0]; - dest += 2; - src += 2; - } -} - -static void -gtk_lsb_3_3 (guchar *dest, - guchar *src, - gint count) -{ - memcpy (dest, src, count * 3); -} - -static void -gtk_msb_3_3 (guchar *dest, - guchar *src, - gint count) -{ - while (count--) - { - dest[0] = src[2]; - dest[1] = src[1]; - dest[2] = src[0]; - dest += 3; - src += 3; - } -} - -static void -gtk_lsb_3_4 (guchar *dest, - guchar *src, - gint count) -{ - while (count--) - { - dest[0] = src[0]; - dest[1] = src[1]; - dest[2] = src[2]; - dest += 4; - src += 3; - } -} - -static void -gtk_msb_3_4 (guchar *dest, - guchar *src, - gint count) -{ - while (count--) - { - dest[1] = src[2]; - dest[2] = src[1]; - dest[3] = src[0]; - dest += 4; - src += 3; + ind = (double) i / 255.0; + val = (int) (255 * pow (ind, one_over_gamma)); + array[i] = val; } } diff --git a/gtk/gtkpreview.h b/gtk/gtkpreview.h index 71da9b4f16..252569b30e 100644 --- a/gtk/gtkpreview.h +++ b/gtk/gtkpreview.h @@ -46,6 +46,11 @@ struct _GtkPreview guint16 buffer_width; guint16 buffer_height; + guint16 bpp; + guint16 rowstride; + + GdkRgbDither dither; + guint type : 1; guint expand : 1; }; @@ -55,28 +60,8 @@ struct _GtkPreviewInfo GdkVisual *visual; GdkColormap *cmap; - gulong *color_pixels; - gulong *gray_pixels; - gulong *reserved_pixels; + guchar *lookup; - gulong *lookup_red; - gulong *lookup_green; - gulong *lookup_blue; - - GtkDitherInfo *dither_red; - GtkDitherInfo *dither_green; - GtkDitherInfo *dither_blue; - GtkDitherInfo *dither_gray; - guchar ***dither_matrix; - - guint nred_shades; - guint ngreen_shades; - guint nblue_shades; - guint ngray_shades; - guint nreserved; - - guint bpp; - gint cmap_alloced; gdouble gamma; }; @@ -92,7 +77,6 @@ struct _GtkPreviewClass GtkPreviewInfo info; - GdkImage *image; }; @@ -111,6 +95,7 @@ void gtk_preview_put (GtkPreview *preview, gint desty, gint width, gint height); +/* gtk_preview_put_row is broken */ void gtk_preview_put_row (GtkPreview *preview, guchar *src, guchar *dest, @@ -132,6 +117,8 @@ void gtk_preview_set_color_cube (guint nred_shades, guint ngray_shades); void gtk_preview_set_install_cmap (gint install_cmap); void gtk_preview_set_reserved (gint nreserved); +void gtk_preview_set_dither (GtkPreview *preview, + GdkRgbDither dither); GdkVisual* gtk_preview_get_visual (void); GdkColormap* gtk_preview_get_cmap (void); GtkPreviewInfo* gtk_preview_get_info (void);