Re: gdk_pixbuf_loader_write memory leak
- From: milton soto <miltonpsoto yahoo com>
- To: Olexiy Avramchenko <olexiy irtech cn ua>
- Cc: gtk-app-devel-list gnome org
- Subject: Re: gdk_pixbuf_loader_write memory leak
- Date: Thu, 4 Dec 2003 20:37:06 -0800 (PST)
Hi
I?m Sorry please disregard my last email.
I changed my coded according to your first suggestion, and it?s
working.
Thank You
I lost track of the main issue because I was so angry with not being
able to display a simple jpeg image onto a GTK/GDK display.
Let me explain:
There are two issues
For the pass six months I have been running a program (that I wrote in
GTK) that displays the raw gray camera images sent over a network. This
is all working okay, its not 100% perfect, because the display
occasional flickers and moving objects have a hazy look. I also have a
test site directly connected to the camera (no network) that display
the same flickering and hazy images, so the network is not the problem.
It?s not the camera because the camera can capture 30 to 3000 frames
per second and I checked it all out with the camera manufacture. It?s
not the computer/video card because I could display a full two hour DVD
movie over the network with no delays, flickers or haziness. So the
only thing left is GTK.
The following paragraph from
http://developer.gnome.org/doc/books/WGA/graphics.html#AEN686
describe the same problem I?m having.
One of the most common uses for pixmaps is double buffering, in which
the application uses a pixmap as an intermediary drawing buffer to
smooth out the drawing process (see Figure 10.3). A complex graphic
might require a long series of drawing commands to complete. Each time
the window is reexposed, the client normally has to reexecute the
same drawing commands. If the client is displaying over a slow
connection, or if the rendering process takes too long, the graphic
flickers as the display updates in real time. On the other hand, if
the client renders to an off-screen pixmap, it doesn't matter how long
the process takes. The client can update the pixmap at its leisure,
whenever the graphic changes. When the X server needs to refresh the
on-screen image, the client can tell it to copy the graphic from the
pixmap drawable to the window drawable. Since both of these resources
reside on the X server, this will be a fast operation.
But it doesn?t show you how to do this and the GTK book I have doesn?t
explain this procedure at all.
So my first issue is to eliminate the flickering and haziness from the
GTK display.
The second issue is I need to do it using jpeg images, because I need
the compression.
Can GTK handle it, or do I have to find a different method of
displaying the images.
Any suggestions or examples would be appreciated
Thank You
Milt
--- Olexiy Avramchenko <olexiy irtech cn ua> wrote:
milton soto wrote:
<...>
If you can send me a small example or point me to a web page
that has an example on how to do the steps you suggested, I
would gladly appreciated.
YOUR STEPS
You just need to convert your raw pixels to GdkRGB and display it.
This way example attached (compile with smth like 'gcc -Wall
`pkg-config
--cflags --libs gtk+-2.0` gray-image.c -o gray-image').
The faster (but it works with local X server only) way is:
1. Create shared pixmap.
2. Allocate all pixels (create relation raw pixel -> actual display
pixel).
3. Fill pixmap.
4. Put it on screen.
5. Go to 3.
I'll post this later.
Olexiy
/*
An example (pretty simple) of GDK RGB gray image usage.
Use and enjoy.
*/
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
typedef struct __gray_image_stuff
{
guchar *buffer;
gint width;
gint height;
guchar start_pixel;
guint idle_handle;
GtkWidget *area;
} GRAY_IMAGE_STUFF;
/*
Simple frame calculation (on idle) - we'll show moving border and
binary 8-bit frame counter.
*/
static gboolean create_frame(GRAY_IMAGE_STUFF *image)
{
guint i;
guchar pixel;
pixel = image->start_pixel;
for (i=1;i<image->width-2;i++)
image->buffer[image->width + i] = pixel++;
for (i=1;i<image->height-1;i++)
image->buffer[image->width - 2 + i*image->width] = pixel++;
for (i=image->width-2;i>1;i--)
image->buffer[image->width*(image->height-2) + i] = pixel++;
for (i=image->height-2;i>1;i--)
image->buffer[1 + i*image->width] = pixel++;
for (i=0;i<8;i++) {
gint x,y;
pixel = image->start_pixel&(1<<i)?0x88:0x00;
for (x=0;x<8;x++)
for (y=0;y<8;y++)
image->buffer[8+(7-i)*16+x + (8+y)*image->width] = pixel;
}
image->start_pixel++;
gtk_widget_queue_draw(image->area);
return TRUE;
}
/*
This handles the resizing of drawing area, pretty simple - we just
reallocate the gray buffer.
Your code may use fixed-size area, or some logic when reallocating.
*/
static gboolean area_configure(GtkWidget *area, GdkEventConfigure
*event, GRAY_IMAGE_STUFF *image)
{
g_free(image->buffer);
image->width = event->width;
image->height = event->height;
image->buffer = g_malloc0(image->width*image->height);
if (!image->idle_handle)
image->idle_handle = gtk_idle_add((GtkFunction)create_frame,
image);
return TRUE;
}
/*
Expose handler responsible of showing the parts of image buffer on
screen.
Without it you may see strange artifacts when dragging another
window over your app.
*/
static gboolean area_expose(GtkWidget *area, GdkEventExpose *event,
GRAY_IMAGE_STUFF *image)
{
gint i, size;
GdkRectangle *rects;
gdk_region_get_rectangles(event->region, &rects, &size);
for (i=0;i<size;i++)
gdk_draw_gray_image(
area->window,
area->style->black_gc,
rects[i].x, rects[i].y,
rects[i].width, rects[i].height,
GDK_RGB_DITHER_NONE,
(gpointer)image->buffer+(rects[i].y*image->width+rects[i].x),
image->width
);
g_free(rects);
return TRUE;
}
int main(int argc, char **argv)
{
GtkWidget *window;
GtkWidget *area;
static GRAY_IMAGE_STUFF image;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(window), 2);
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit),
NULL);
area = gtk_drawing_area_new();
memset(&image, 0, sizeof(image));
image.area = area;
gtk_widget_set_double_buffered(area, FALSE); /* it's already
double-buffered */
gtk_widget_set_size_request(area, 640,480);
gtk_container_add(GTK_CONTAINER(window), area);
g_signal_connect(area, "configure-event",
G_CALLBACK(area_configure), &image);
g_signal_connect(area, "expose-event", G_CALLBACK(area_expose),
&image);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
__________________________________
Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]