Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Gtk+/Gnome Application Development
Prev Home Next

RGB Buffers

GDK's GdkRGB module allows you to copy a client-side buffer of image data to a drawable. If you need to manipulate images extensively, or copy image data to the server, this is the correct way to do it. You can't directly manipulate a GdkPixmap because a pixmap is a server-side object. Copying image data to the server with gdk_draw_point() would be unbelievably slow, since each point would require a server request (probably more than one, since you will need to change the GC for each point).

Internally, GdkRGB uses an object called GdkImage to rapidly copy image data to the server in a single request. This is still somewhat slow---sizeable data does have to be copied---but GdkRGB is highly tuned and uses shared memory if the client and server happen to be on the same machine. So it's the fastest way to perform this task, given the X architecture. It will also handle some tricky issues for you (such as adapting to the colormaps and visuals available on a given X server).

The GdkRGB functions are in a separate header, gdk/gdkrgb.h. Before using any GdkRGB functions, you must initialize the module with gdk_rgb_init() (Figure 24); this sets up the visual and colormap GdkRGB will use, and some internal data structures.

The drawable you intend to copy the RGB buffer to must use GdkRGB's visual and colormap. If the drawable is a part of a widget, the easiest way to ensure this is to push the GdkRGB visual and colormap when you create the widget:


  GtkWidget* widget;
  gtk_widget_push_visual(gdk_rgb_get_visual());
  gtk_widget_push_colormap(gdk_rgb_get_cmap());
  widget = gtk_whatever_new();
  gtk_widget_pop_visual();
  gtk_widget_pop_colormap();

The current version of GTK+ will be better-behaved if you do this when creating the toplevel window containing the drawable, instead of when creating the drawable itself. However, in principle you can do it for only the drawable.

GdkRGB understands several kinds of image data, including 24- and 32-bit RGB data, 8-bit grayscale, and 8-bit indexes into an array of RGB values (a client-side GdkRgbCmap). This section describes only the simplest, 24-bit RGB data; this kind of buffer is rendered with gdk_draw_rgb_image(). There are separate functions to render the other buffer types, but all of them work in essentially the same way.

A 24-bit RGB buffer is a one-dimensional array of bytes; every byte triplet makes up a pixel (byte 0 is red, byte 1 is green, byte 2 is blue). Three numbers describe the size of the array and the location of bytes within it:

  • The width is the number of pixels (byte triplets) per row of the image.

  • The height is the number of rows in the image.

  • The rowstride is the number of bytes between rows. That is, for a buffer with rowstride r, if row n starts at array index i row n+1 starts at array index i+r. The rowstride is not necessarily three times the buffer's width; GdkRGB is faster if both the source pointer and the rowstride are aligned to a 4-byte boundary. Specifying a rowstride allows you to use padding to achieve this.

The x, y, width, and height arguments to gdk_rgb_draw_image() define a region of the target drawable to copy the RGB buffer to. The RGB buffer must have at least width columns and height rows. Row 0, column 0 of the RGB buffer will be copied to point (x, y) on the drawable.

Dithering simulates a larger number of colors on displays with a limited palette. Dithering only matters on 8- and 16-bit displays; 24-bit displays do not have a limited palette. The dither argument is an enumerated type; it has three possible values:

  • GDK_RGB_DITHER_NONE specifies that no dithering will be done. It's appropriate for text or line drawings with few colors, but inappropriate for photographic images.

  • GDK_RGB_DITHER_NORMAL specifies dithering on 8-bit displays, but not 16-bit displays. This is usually the best quality/performance tradeoff.

  • GDK_RGB_DITHER_MAX specifies that dithering will always be done on 8- and 16-bit displays. The quality gain on 16-bit displays is probably not worth the speed penalty.

The gc argument to gdk_draw_rgb_image() is simply passed through to gdk_draw_image() (recall that GdkRGB uses GdkImage internally). The gc components that make sense are used (such as the clip mask, drawing function, and subwindow mode).

#include <gdk/gdkrgb.h>

void gdk_rgb_init(void);

GdkColormap* gdk_rgb_get_cmap(void);

GdkVisual* gdk_rgb_get_visual(void);

void gdk_draw_rgb_image(GdkDrawable* drawable, GdkGC* gc, gint x, gint y, gint width, gint height, GdkRGBDither dither, guchar* rgb_buf, gint rowstride);

Figure 24. GdkRGB

Gtk+/Gnome Application Development
Prev Home Next

 
 
  Published under free license. Design by Interspire