Re: gdk-pixbuf, loading jpeg from network and displaying
- From: acano systec com
- To: rothwell holly-springs nc us
- Cc: gtk-app-devel-list gnome org
- Subject: Re: gdk-pixbuf, loading jpeg from network and displaying
- Date: Fri, 22 Sep 2000 16:41:31 -0500
On Wed, 20 Sep 2000 23:39:02 -0400, Michael Rothwell <rothwell holly-springs nc us> wrote:
Hi,
I've been trying to find a way to load image data from memory and
display it. I will be fetching the data from the network, and ideally
would like to display it incrementally, but that's not necessary. THe
main thing is to be able to load a JPEG from a network data source and
display it in a GTK app. Anyone have some advice? Sample code?
Thanks!
-M
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Hopefully I haven't screwed this up too badly...
/*FIXME look into g_io stuff, instead of reading data in the idle function */
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk-pixbuf/gdk-pixbuf-loader.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT (80)
#define BUFFER_SIZE (1024 * 8)
typedef struct {
GdkPixbufLoader *loader;
GdkPixbuf *pixbuf;
int width;
int height;
GtkWidget *win;
GtkWidget *scrolled_window;
GtkWidget *drawing_area;
int socket_fd;
} WebImage;
static void error_quit (const gchar *error_msg)
{
g_print ("\nError: %s\n", error_msg);
exit (1);
}
/* cutting and pasting (from some BSD socket tutorial) a bunch of stuff
* I don't understand
*/
static int http_socket_new_with_file_request (const gchar *host_name,
const gchar *image_file)
{
int socket_fd, ret;
struct hostent *he;
struct sockaddr_in host_addr;
gchar *request_string;
he = gethostbyname (host_name);
if (he == NULL)
error_quit ("couldn't resolve host name");
socket_fd = socket (AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1)
error_quit ("couldn't create socket file descriptor");
host_addr.sin_family = AF_INET;
host_addr.sin_port = htons (PORT);
host_addr.sin_addr = *((struct in_addr *)he->h_addr);
ret = connect (socket_fd, (struct sockaddr *)&host_addr,
sizeof (struct sockaddr));
if (ret == -1)
error_quit ("couldn't connect");
request_string = g_strdup_printf ("GET %s\r\n", image_file);
ret = send (socket_fd, request_string, strlen (request_string), 0);
if (ret != strlen (request_string)) {
g_free (request_string);
error_quit ("couldn't send all of the request");
}
g_free (request_string);
return socket_fd;
}
/*FIXME make sure you don't read past the pixbuf image data
* (ex: drawing_area is bigger than the pixbuf being drawn).
* Doesn't matter here since drawing_area size was set to pixbuf size
*/
static gint drawing_area_expose_cb (GtkWidget *drawing_area,
GdkEventExpose *event,
gpointer data)
{
WebImage *web_image = (WebImage *) data;
if (gdk_pixbuf_get_has_alpha (web_image->pixbuf)) {
gdk_pixbuf_render_to_drawable_alpha (
web_image->pixbuf,
web_image->drawing_area->window,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height,
GDK_PIXBUF_ALPHA_FULL,
0, // alpha_threshold ?
GDK_RGB_DITHER_MAX,
0, 0);
}
else {
gdk_pixbuf_render_to_drawable (
web_image->pixbuf,
web_image->drawing_area->window,
web_image->drawing_area->style->black_gc,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height,
GDK_RGB_DITHER_MAX,
0, 0);
}
return FALSE;
}
static gint area_prepared_cb (GdkPixbuf *loader, gpointer data)
{
WebImage *web_image = (WebImage *) data;
web_image->pixbuf = gdk_pixbuf_loader_get_pixbuf (
GDK_PIXBUF_LOADER (loader));
web_image->width = gdk_pixbuf_get_width (web_image->pixbuf);
web_image->height = gdk_pixbuf_get_height (web_image->pixbuf);
web_image->win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (web_image->win), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
web_image->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_usize (web_image->scrolled_window, 500, 500);
gtk_container_add (GTK_CONTAINER (web_image->win),
web_image->scrolled_window);
web_image->drawing_area = gtk_drawing_area_new ();
gtk_signal_connect (GTK_OBJECT (web_image->drawing_area),
"expose_event",
GTK_SIGNAL_FUNC (drawing_area_expose_cb),
(gpointer) web_image);
gtk_scrolled_window_add_with_viewport (
GTK_SCROLLED_WINDOW (web_image->scrolled_window),
web_image->drawing_area);
gtk_drawing_area_size (GTK_DRAWING_AREA (web_image->drawing_area),
web_image->width,
web_image->height);
gtk_widget_show_all (web_image->win);
return FALSE;
}
/*FIXME need to check drawing_area and pixbuf sizes?
* see drawing_area_expose_cb()
*/
static gint area_updated_cb (GdkPixbuf *loader,
guint x, guint y,
guint width, guint height,
gpointer data)
{
WebImage *web_image = (WebImage *) data;
if (gdk_pixbuf_get_has_alpha (web_image->pixbuf)) {
gdk_pixbuf_render_to_drawable_alpha (
web_image->pixbuf,
web_image->drawing_area->window,
x, y,
x, y,
width, height,
GDK_PIXBUF_ALPHA_FULL,
0, // alpha_threshold ?
GDK_RGB_DITHER_MAX,
0, 0);
}
else {
gdk_pixbuf_render_to_drawable (
web_image->pixbuf,
web_image->drawing_area->window,
web_image->drawing_area->style->black_gc,
x, y,
x, y,
width, height,
GDK_RGB_DITHER_MAX,
0, 0);
}
return FALSE;
}
static gint recv_image_data (gpointer data)
{
WebImage *web_image = (WebImage *) data;
int num_bytes_received;
gchar buffer[BUFFER_SIZE];
num_bytes_received = recv (web_image->socket_fd,
buffer, BUFFER_SIZE,
0);
if (num_bytes_received <= 0) {
g_print ("all done?\n");
close (web_image->socket_fd);
gdk_pixbuf_loader_close (
GDK_PIXBUF_LOADER (web_image->loader));
return FALSE;
}
g_print ("writing %d bytes\n", num_bytes_received);
gdk_pixbuf_loader_write (GDK_PIXBUF_LOADER (web_image->loader),
buffer, num_bytes_received);
return TRUE;
}
int main (int argc, char *argv[])
{
WebImage web_image;
gchar *host_name, *image_file;
gtk_init (&argc, &argv);
gdk_rgb_init ();
if (argc < 3) {
g_print (
"usage: %s <hostname> <image>\n"
"example: %s www.gimp.org /icons/gimp_in_action1.jpeg\n",
argv[0], argv[0]);
host_name = "www.gimp.org";
image_file = "/icons/gimp_in_action1.jpeg";
}
else {
host_name = argv[1];
image_file = argv[2];
}
g_print ("\nhost_name: %s\nimage_file: %s\n", host_name, image_file);
web_image.socket_fd = http_socket_new_with_file_request (
host_name, image_file);
web_image.loader = gdk_pixbuf_loader_new ();
gtk_signal_connect (GTK_OBJECT (web_image.loader),
"area_prepared",
GTK_SIGNAL_FUNC (area_prepared_cb),
(gpointer) &web_image);
gtk_signal_connect (GTK_OBJECT (web_image.loader),
"area_updated",
GTK_SIGNAL_FUNC (area_updated_cb),
(gpointer) &web_image);
gtk_idle_add (recv_image_data, (gpointer) &web_image);
gtk_main ();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]