示例#1
0
/* Auxiliary function - look for frame that's currently loading. */
static void
update_currently_loaded_frame (FrameData* frame)
{
    int tmp_count;

    if (gdk_pixbuf_animation_iter_on_currently_loading_frame(frame->iter))
        return; /* frame is currently being loaded */
    /* clear old content of pixbuf */
    if (frame->pixbuf)
        g_object_unref (frame->pixbuf);
    frame->pixbuf = NULL;

    tmp_count = 0;
    do {
        int delay_time;

        if (++tmp_count > MAX_NUMBER_FRAMES) {
            /* protection against frames repeating */
            return;
        }

        delay_time = gdk_pixbuf_animation_iter_get_delay_time (frame->iter);
        if (delay_time < 0) {
            /* this is last frame in the animation */
            return;
        }
        g_time_val_add (&frame->time, delay_time * 1000);
        gdk_pixbuf_animation_iter_advance (frame->iter, &frame->time);
    } while (!gdk_pixbuf_animation_iter_on_currently_loading_frame (frame->iter));
    /* store current content of the frame */
    frame->pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (frame->iter));
}
示例#2
0
static GdkPixbuf *
_gdk_pixbuf_new_from_uri_at_scale (const char  *uri,
				   gint         size,
				   GError     **error)
{
    gboolean result;
    guchar buffer[LOAD_BUFFER_SIZE];
    gssize bytes_read;
    GdkPixbufLoader *loader = NULL;
    GdkPixbuf *pixbuf;	
    GdkPixbufAnimation *animation;
    GdkPixbufAnimationIter *iter;
    gboolean has_frame;
    SizePrepareContext info;
    GFile *file;
    GInputStream *input_stream;

    g_return_val_if_fail (uri != NULL, NULL);

    file = g_file_new_for_uri (uri);

    input_stream = G_INPUT_STREAM (g_file_read (file, NULL, error));
    if (input_stream == NULL) {
        g_object_unref (file);
        return NULL;
    }

    has_frame = FALSE;

    result = FALSE;
    while (!has_frame) {

	bytes_read = g_input_stream_read (input_stream,
					  buffer,
					  sizeof (buffer),
					  NULL,
					  error);
        if (bytes_read == -1) {
            break;
        }
	result = TRUE;
	if (bytes_read == 0) {
	    break;
	}

        if (loader == NULL) {
            loader = create_loader (file, buffer, bytes_read);
            if (1 <= size) {
              info.size = size;
              info.input_width = info.input_height = 0;
              g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
            }
            g_assert (loader != NULL);
        }

	if (!gdk_pixbuf_loader_write (loader,
				      (unsigned char *)buffer,
				      bytes_read,
				      error)) {
	    result = FALSE;
	    break;
	}

	animation = gdk_pixbuf_loader_get_animation (loader);
	if (animation) {
		iter = gdk_pixbuf_animation_get_iter (animation, NULL);
		if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) {
			has_frame = TRUE;
		}
		g_object_unref (iter);
	}
    }

    if (loader == NULL) {
        /* This can happen if the above loop was exited due to the
         * g_input_stream_read() call failing. */
        result = FALSE;
    } else if (*error != NULL) {
        gdk_pixbuf_loader_close (loader, NULL);
        result = FALSE;
    } else if (gdk_pixbuf_loader_close (loader, error) == FALSE) {
        if (!g_error_matches (*error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INCOMPLETE_ANIMATION))
          result = FALSE;
        else
          g_clear_error (error);
    }

    if (!result) {
        g_clear_object (&loader);
	g_input_stream_close (input_stream, NULL, NULL);
	g_object_unref (input_stream);
	g_object_unref (file);
	return NULL;
    }

    g_input_stream_close (input_stream, NULL, NULL);
    g_object_unref (input_stream);
    g_object_unref (file);

    pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
    if (pixbuf != NULL) {
	g_object_ref (G_OBJECT (pixbuf));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width",
			   GINT_TO_POINTER (info.input_width));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height",
			   GINT_TO_POINTER (info.input_height));
    }
    g_object_unref (G_OBJECT (loader));

    return pixbuf;
}
示例#3
0
/**
 * gnome_gdk_pixbuf_new_from_uri:
 * @uri: the uri of an image
 * @width: The width the image should have or -1 to not constrain the width
 * @height: The height the image should have or -1 to not constrain the height
 * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
 * 
 * Loads a GdkPixbuf from the image file @uri points to, scaling it to the
 * desired size. If you pass -1 for @width or @height then the value
 * specified in the file will be used.
 *
 * When preserving aspect ratio, if both height and width are set the size
 * is picked such that the scaled image fits in a width * height rectangle.
 * 
 * Return value: The loaded pixbuf, or NULL on error
 *
 * Since: 2.14
 **/
GdkPixbuf *
gnome_gdk_pixbuf_new_from_uri_at_scale (const char *uri,
					gint        width,
					gint        height,
					gboolean    preserve_aspect_ratio)
{
    GnomeVFSResult result;
    char buffer[LOAD_BUFFER_SIZE];
    GnomeVFSFileSize bytes_read;
    GdkPixbufLoader *loader;
    GdkPixbuf *pixbuf;	
    GdkPixbufAnimation *animation;
    GdkPixbufAnimationIter *iter;
    gboolean has_frame;
    SizePrepareContext info;
    GFile *file;
    GFileInputStream *file_input_stream;

    g_return_val_if_fail (uri != NULL, NULL);

    file = g_file_new_for_uri (uri);
    file_input_stream = g_file_read (file, NULL, NULL);
    if (file_input_stream == NULL) {
	g_object_unref (file);
	return NULL;
    }

    loader = gdk_pixbuf_loader_new ();
    if (1 <= width || 1 <= height) {
        info.width = width;
        info.height = height;
	info.input_width = info.input_height = 0;
        info.preserve_aspect_ratio = preserve_aspect_ratio;        
        g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
    }

    has_frame = FALSE;

    result = GNOME_VFS_ERROR_GENERIC;
    while (!has_frame) {

	bytes_read = g_input_stream_read (G_INPUT_STREAM (file_input_stream),
					  buffer,
					  sizeof (buffer),
					  NULL,
					  NULL);
	if (bytes_read == -1) {
	    break;
	}
	result = GNOME_VFS_OK;
	if (bytes_read == 0) {
	    break;
	}

	if (!gdk_pixbuf_loader_write (loader,
				      (unsigned char *)buffer,
				      bytes_read,
				      NULL)) {
	    result = GNOME_VFS_ERROR_WRONG_FORMAT;
	    break;
	}

	animation = gdk_pixbuf_loader_get_animation (loader);
	if (animation) {
		iter = gdk_pixbuf_animation_get_iter (animation, NULL);
		if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) {
			has_frame = TRUE;
		}
		g_object_unref (iter);
	}
    }

    gdk_pixbuf_loader_close (loader, NULL);
    
    if (result != GNOME_VFS_OK) {
	g_object_unref (G_OBJECT (loader));
	g_input_stream_close (G_INPUT_STREAM (file_input_stream), NULL, NULL);
	g_object_unref (file_input_stream);
	g_object_unref (file);
	return NULL;
    }

    g_input_stream_close (G_INPUT_STREAM (file_input_stream), NULL, NULL);
    g_object_unref (file_input_stream);
    g_object_unref (file);

    pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
    if (pixbuf != NULL) {
	g_object_ref (G_OBJECT (pixbuf));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width",
			   GINT_TO_POINTER (info.input_width));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height",
			   GINT_TO_POINTER (info.input_height));
    }
    g_object_unref (G_OBJECT (loader));

    return pixbuf;
}
static VALUE
rg_on_currently_loading_frame_p(VALUE self)
{
    return CBOOL2RVAL(gdk_pixbuf_animation_iter_on_currently_loading_frame(RVAL2ITR(self)));
}