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

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]