Re: gdk_pixbuf_loader_write memory leak



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]