Re: gdk_pixbuf_loader_write memory leak



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;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]