static void get_animation_size(GdkPixbufAnimation * animation, int *w, int *h, int *delay) { GList *frames; int iw, ih, n, i, d = -1; frames = gdk_pixbuf_animation_get_frames(animation); n = gdk_pixbuf_animation_get_num_frames(animation); *w = gdk_pixbuf_animation_get_width(animation); *h = gdk_pixbuf_animation_get_height(animation); for (i = 0; i < n; i++) { GdkPixbufFrame *frame; GdkPixbuf *pixbuf; int tmp; frame = (GdkPixbufFrame *) g_list_nth_data(frames, i); tmp = gdk_pixbuf_frame_get_delay_time(frame); if (tmp > d) d = tmp; pixbuf = gdk_pixbuf_frame_get_pixbuf(frame); iw = gdk_pixbuf_frame_get_x_offset(frame) + gdk_pixbuf_get_width(pixbuf); ih = gdk_pixbuf_frame_get_y_offset(frame) + gdk_pixbuf_get_height(pixbuf); if (iw > *w) *w = iw; if (ih > *h) *h = ih; } if (delay) *delay = d; }
int main (int argc, char **argv) { int i; int found_valid = FALSE; GdkPixbufAnimation *animation; gtk_init (&argc, &argv); gdk_rgb_set_verbose (TRUE); gdk_rgb_init (); gtk_widget_set_default_colormap (gdk_rgb_get_cmap ()); gtk_widget_set_default_visual (gdk_rgb_get_visual ()); { char *tbf_readlen = getenv("TBF_READLEN"); if(tbf_readlen) readlen = atoi(tbf_readlen); } { char *tbf_bps = getenv("TBF_KBPS"); guint bps; if (tbf_bps) { bps = atoi(tbf_bps); g_print ("Simulating %d kBytes/sec\n", bps); readlen = (bps*1024)/10; } } i = 1; if (argc == 1) { g_print ("USAGE: testanimation FILE1 ...\n"); return 0; } else { for (i = 1; i < argc; i++) { animation = gdk_pixbuf_animation_new_from_file (argv[i]); if (animation) { gint i = 0; GList *listptr; for (listptr = gdk_pixbuf_animation_get_frames (animation); listptr; listptr = listptr->next) { GdkPixbufFrame *frame; GdkPixbuf *pixbuf; gchar *title; frame = listptr->data; pixbuf = gdk_pixbuf_frame_get_pixbuf (frame); title = g_strdup_printf ("Frame %d", i); g_print ("Frame %d x:%d y:%d width:%d height:%d\n", i, gdk_pixbuf_frame_get_x_offset (frame), gdk_pixbuf_frame_get_y_offset (frame), gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); new_testrgb_window (pixbuf, title); g_free (title); i++; } found_valid = TRUE; } } #if 0 { GtkWidget* rgb_window = NULL; ProgressFileStatus status; GdkPixbufLoader *pixbuf_loader; pixbuf_loader = gdk_pixbuf_loader_new (); status.loader = pixbuf_loader; status.rgbwin = &rgb_window; status.buf = g_malloc (readlen); gtk_signal_connect(GTK_OBJECT(pixbuf_loader), "area_prepared", GTK_SIGNAL_FUNC(progressive_prepared_callback), &rgb_window); gtk_signal_connect(GTK_OBJECT(pixbuf_loader), "area_updated", GTK_SIGNAL_FUNC(progressive_updated_callback), &rgb_window); status.imagefile = fopen (argv[1], "r"); g_assert (status.imagefile != NULL); status.readlen = readlen; status.timeout = gtk_timeout_add(100, update_timeout, &status); } #endif } if (found_valid) gtk_main (); return 0; }
static int x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h) { struct x11_info *xi; #if defined(USE_IMLIB) ImlibImage *im; #elif defined(USE_IMLIB2) Imlib_Image im; #elif defined(USE_GDKPIXBUF) GdkPixbufAnimation *animation; GList *frames; int i, j, iw, ih, n, frame_num, delay, max_anim; double ratio_w, ratio_h; struct x11_image *ximg; Pixmap tmp_pixmap; #endif if (self == NULL) return 0; xi = (struct x11_info *)self->priv; if (xi == NULL) return 0; #if defined(USE_IMLIB) im = Imlib_load_image(xi->id, fname); if (!im) return 0; if (w <= 0) w = im->rgb_width; if (h <= 0) h = im->rgb_height; img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h, DefaultDepth(xi->display, 0)); if (!img->pixmap) return 0; XSetForeground(xi->display, xi->imageGC, xi->background_pixel); XFillRectangle(xi->display, (Pixmap) img->pixmap, xi->imageGC, 0, 0, w, h); Imlib_paste_image(xi->id, im, (Pixmap) img->pixmap, 0, 0, w, h); Imlib_kill_image(xi->id, im); #elif defined(USE_IMLIB2) im = imlib_load_image(fname); if (!im) return 0; imlib_context_set_image(im); if (w <= 0) w = imlib_image_get_width(); if (h <= 0) h = imlib_image_get_height(); img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h, DefaultDepth(xi->display, 0)); if (!img->pixmap) return 0; XSetForeground(xi->display, xi->imageGC, xi->background_pixel); XFillRectangle(xi->display, (Pixmap) img->pixmap, xi->imageGC, 0, 0, w, h); imlib_context_set_display(xi->display); imlib_context_set_visual(DefaultVisual(xi->display, 0)); imlib_context_set_colormap(DefaultColormap(xi->display, 0)); imlib_context_set_drawable((Drawable) img->pixmap); imlib_render_image_on_drawable_at_size(0, 0, w, h); imlib_free_image(); #elif defined(USE_GDKPIXBUF) max_anim = self->max_anim; animation = gdk_pixbuf_animation_new_from_file(fname); if (!animation) return 0; frames = gdk_pixbuf_animation_get_frames(animation); frame_num = n = gdk_pixbuf_animation_get_num_frames(animation); get_animation_size(animation, &iw, &ih, &delay); if (delay <= 0) max_anim = -1; if (max_anim < 0) { frame_num = (-max_anim > n) ? n : -max_anim; } else if (max_anim > 0) { frame_num = n = (max_anim > n) ? n : max_anim; } if (w < 1 || h < 1) { w = iw; h = ih; ratio_w = ratio_h = 1; } else { ratio_w = 1.0 * w / iw; ratio_h = 1.0 * h / ih; } tmp_pixmap = XCreatePixmap(xi->display, xi->parent, w, h, DefaultDepth(xi->display, 0)); XFillRectangle(xi->display, (Pixmap) tmp_pixmap, xi->imageGC, 0, 0, w, h); if (!tmp_pixmap) { gdk_pixbuf_animation_unref(animation); return 0; } ximg = x11_img_new(xi, w, h, frame_num); if (!ximg) { XFreePixmap(xi->display, tmp_pixmap); gdk_pixbuf_animation_unref(animation); return 0; } for (j = 0; j < n; j++) { GdkPixbufFrame *frame; GdkPixbuf *org_pixbuf, *pixbuf; int width, height, ofstx, ofsty; if (max_anim < 0) { i = (j - n + frame_num > 0) ? (j - n + frame_num) : 0; } else { i = j; } frame = (GdkPixbufFrame *) g_list_nth_data(frames, j); org_pixbuf = gdk_pixbuf_frame_get_pixbuf(frame); ofstx = gdk_pixbuf_frame_get_x_offset(frame); ofsty = gdk_pixbuf_frame_get_y_offset(frame); delay = gdk_pixbuf_frame_get_delay_time(frame); width = gdk_pixbuf_get_width(org_pixbuf); height = gdk_pixbuf_get_height(org_pixbuf); if (ofstx == 0 && ofsty == 0 && width == w && height == h) { pixbuf = resize_image(org_pixbuf, w, h); } else { pixbuf = resize_image(org_pixbuf, width * ratio_w, height * ratio_h); ofstx *= ratio_w; ofsty *= ratio_h; } width = gdk_pixbuf_get_width(pixbuf); height = gdk_pixbuf_get_height(pixbuf); if (delay > ximg->delay) ximg->delay = delay; XCopyArea(xi->display, tmp_pixmap, ximg->pixmap[i], xi->imageGC, 0, 0, w, h, 0, 0); gdk_pixbuf_xlib_render_to_drawable_alpha(pixbuf, (Drawable) ximg->pixmap[i], 0, 0, ofstx, ofsty, width, height, GDK_PIXBUF_ALPHA_BILEVEL, 1, XLIB_RGB_DITHER_NORMAL, 0, 0); switch (gdk_pixbuf_frame_get_action(frame)) { case GDK_PIXBUF_FRAME_RETAIN: XCopyArea(xi->display, ximg->pixmap[i], tmp_pixmap, xi->imageGC, 0, 0, w, h, 0, 0); break; case GDK_PIXBUF_FRAME_DISPOSE: break; case GDK_PIXBUF_FRAME_REVERT: XCopyArea(xi->display, ximg->pixmap[0], tmp_pixmap, xi->imageGC, 0, 0, w, h, 0, 0); break; default: XCopyArea(xi->display, ximg->pixmap[0], tmp_pixmap, xi->imageGC, 0, 0, w, h, 0, 0); break; } if (org_pixbuf != pixbuf) gdk_pixbuf_finalize(pixbuf); } XFreePixmap(xi->display, tmp_pixmap); gdk_pixbuf_animation_unref(animation); img->pixmap = ximg; #endif img->width = w; img->height = h; return 1; }