Re: gdk_pixbuf_loader_write memory leak
- From: Olexiy Avramchenko <olexiy irtech cn ua>
- To: milton soto <miltonpsoto yahoo com>
- Cc: gtk-app-devel-list gnome org
- Subject: Re: gdk_pixbuf_loader_write memory leak
- Date: Thu, 04 Dec 2003 09:48:53 +0200
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]