示例#1
0
void
vnr_tools_apply_embedded_orientation (GdkPixbufAnimation **anim)
{
    GdkPixbuf *pixbuf;
    GdkPixbuf *original;

    if(!gdk_pixbuf_animation_is_static_image (*anim))
        return;

    pixbuf = gdk_pixbuf_animation_get_static_image (*anim);
    original = pixbuf;
    pixbuf = gdk_pixbuf_apply_embedded_orientation(pixbuf);

    if(original == pixbuf)
    {
        g_object_unref(pixbuf);
        return;
    }

    GdkPixbufSimpleAnim *s_anim;

    s_anim = gdk_pixbuf_simple_anim_new (gdk_pixbuf_get_width(pixbuf),
                                         gdk_pixbuf_get_height(pixbuf),
                                         -1);
    gdk_pixbuf_simple_anim_add_frame(s_anim, pixbuf);

    g_object_unref(pixbuf);
    g_object_unref(*anim);

    *anim = GDK_PIXBUF_ANIMATION(s_anim);
}
示例#2
0
gboolean tilem_animation_save(TilemAnimation *anim,
                              const char *fname, const char *type,
                              char **option_keys, char **option_values,
                              GError **err)
{
	FILE *fp;
	char *dname;
	int errnum;
	GdkPixbuf *pb;
	gboolean status;
	byte palette[768];
	int i;

	g_return_val_if_fail(TILEM_IS_ANIMATION(anim), FALSE);
	g_return_val_if_fail(fname != NULL, FALSE);
	g_return_val_if_fail(type != NULL, FALSE);
	g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

	if (strcmp(type, "gif") != 0) {
		pb = gdk_pixbuf_animation_get_static_image
			(GDK_PIXBUF_ANIMATION(anim));
		status = gdk_pixbuf_savev(pb, fname, type,
		                          option_keys, option_values,
		                          err);
		return status;
	}

	fp = g_fopen(fname, "wb");
	if (!fp) {
		errnum = errno;
		dname = g_filename_display_name(fname);
		g_set_error(err, G_FILE_ERROR,
		            g_file_error_from_errno(errnum),
		            _("Failed to open '%s' for writing: %s"),
		            dname, g_strerror(errnum));
		g_free(dname);
		return FALSE;
	}

	for (i = 0; i < 256; i++) {
		palette[3 * i] = anim->palette[i] >> 16;
		palette[3 * i + 1] = anim->palette[i] >> 8;
		palette[3 * i + 2] = anim->palette[i];
	}

	tilem_animation_write_gif(anim, palette, 256, fp);

	if (fclose(fp)) {
		errnum = errno;
		dname = g_filename_display_name(fname);
		g_set_error(err, G_FILE_ERROR,
		            g_file_error_from_errno(errnum),
		            _("Error while closing '%s': %s"),
		            dname, g_strerror(errnum));
		g_free(dname);
		return FALSE;
	}

	return TRUE;
}
示例#3
0
static void
prepared_callback (GdkPixbufLoader *loader,
                   gpointer data)
{
    AniLoaderContext *context = (AniLoaderContext*)data;

#ifdef DEBUG_ANI
    g_print ("%d pixbuf prepared\n", context->pos);
#endif

    GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
    if (!pixbuf)
        return;

    if (gdk_pixbuf_get_width (pixbuf) > context->animation->width)
        context->animation->width = gdk_pixbuf_get_width (pixbuf);

    if (gdk_pixbuf_get_height (pixbuf) > context->animation->height)
        context->animation->height = gdk_pixbuf_get_height (pixbuf);

    if (context->title != NULL)
        gdk_pixbuf_set_option (pixbuf, "Title", context->title);

    if (context->author != NULL)
        gdk_pixbuf_set_option (pixbuf, "Author", context->author);

    g_object_ref (pixbuf);
    context->animation->pixbufs[context->pos] = pixbuf;

    if (context->pos == 0)
    {
        if (context->prepared_func)
            (* context->prepared_func) (pixbuf,
                                        GDK_PIXBUF_ANIMATION (context->animation),
                                        context->user_data);
    }
    else {
        /* FIXME - this is necessary for nice display of loading
           animations because GtkImage ignores
           gdk_pixbuf_animation_iter_on_currently_loading_frame()
           and always exposes the full frame */
        GdkPixbuf *last = context->animation->pixbufs[context->pos - 1];
        gint width = MIN (gdk_pixbuf_get_width (last), gdk_pixbuf_get_width (pixbuf));
        gint height = MIN (gdk_pixbuf_get_height (last), gdk_pixbuf_get_height (pixbuf));
        gdk_pixbuf_copy_area (last, 0, 0, width, height, pixbuf, 0, 0);
    }

    context->pos++;
}
示例#4
0
GdkPixbufAnimation*	
pgpug_animated_icon_compose_from_anim_list (GdkPixbufAnimation * anim,
					    ...)
{
     g_return_val_if_fail (anim != NULL, NULL);
     g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (anim), NULL);

     int width, height;
     width = gdk_pixbuf_animation_get_width (anim);
     height = gdk_pixbuf_animation_get_height (anim);
     g_return_val_if_fail (height == width, NULL);

     va_list anim_p;
     va_start (anim_p, anim);
     //get all animation into an array
     GPtrArray *anim_array = g_ptr_array_new (); 
     animation_param_entry* p_entry = g_malloc0 (sizeof (animation_param_entry));
     p_entry->anim = anim;
     g_ptr_array_add (anim_array, p_entry);
     
     gint anim_pos, param_num = 0;
     anim_pos = va_arg (anim_p, gint);

     while (anim_pos >= 0){
	  gpointer ptr = va_arg (anim_p, gpointer);
	  p_entry = g_malloc (sizeof (animation_param_entry));
	  param_num += 2;
	  if (!GDK_IS_PIXBUF_ANIMATION (ptr)) {
	       WARN_MSG ("pgpug_animated_icon_compose_from_anim_list: var_arg parameter %d expected GdkPixbufAnimation*", param_num);
	       break;
	  }

	  p_entry->anim = GDK_PIXBUF_ANIMATION (ptr);
	  p_entry->pos = anim_pos;

	  g_ptr_array_add (anim_array, p_entry);
	  anim_pos = va_arg (anim_p, gint);
     }
     va_end (anim_p);     

     GdkPixbufAnimation *result;
     result = compose_animation_from_array ((animation_param_entry**)anim_array->pdata, anim_array->len, width);

     g_ptr_array_foreach (anim_array, (GFunc)g_free, NULL);
     g_ptr_array_free (anim_array, TRUE);
     return result;
}
示例#5
0
static GdkPixbufAnimation*
compose_animation_from_array (animation_param_entry **anim_array, gint array_len, gint pix_size)
{
     GdkPixbufSimpleAnim *result = NULL;
     gint frames = 1, duration = 0,  duration_p, frames_p;
     /* calculate frames count as multiplication of all frames and duration as max */
     gint i;

     GTimeVal start_time = {0, 0};
     for (i = 0; i<array_len; i++){
	  /* initialize iterators for each animation*/
	  animation_param_entry *p_entry = anim_array[i];
	  
	  p_entry->iter = gdk_pixbuf_animation_get_iter (p_entry->anim, &start_time);
	  
	  frames_p = duration_p = 0;
	  pgpug_pixbuf_animation_get_detail (p_entry->anim, &frames_p, &duration_p);

	  duration = duration < duration_p ? duration_p : duration;
	  frames *= frames_p;
     }	  



     float fps = duration > 0 ? frames * 1000 / duration : 1;
     gint frame_change_time = duration / frames; 
     DEBG_MSG ("Fps: %f. frame change time :%dmsec", fps,frame_change_time);

     result = gdk_pixbuf_simple_anim_new (pix_size, pix_size, fps);
 
     gint elapsed_time = 0, frames_counter = 1;
     while (elapsed_time <= duration && frames_counter++ <= frames){

	  animation_param_entry *p_entry = anim_array[0];
	  GdkPixbuf *base_pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter));
	  g_time_val_add (&start_time, frame_change_time * 1000);
	  gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time);

	  for (i = 1; i < array_len; i++) {
	       
	       p_entry = anim_array[i];
	       GdkPixbuf *src_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter);
	       gint x_offset, y_offset, src_size;
	       src_size = gdk_pixbuf_get_width (src_pixbuf);

	       
	       pgpug_pixbuf_calculate_composition_offset (pix_size, src_size, p_entry->pos, &x_offset, &y_offset);

	       
	       gdk_pixbuf_composite (src_pixbuf, 
				     base_pixbuf,
				     x_offset, y_offset, 
				     src_size, src_size, 
				     x_offset, y_offset,
				     1.0f, 1.0f,
				     GDK_INTERP_BILINEAR, 255);
	       gboolean res;
	       res = gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time);
	       
	  }

	  gdk_pixbuf_simple_anim_add_frame (result, base_pixbuf);
	  elapsed_time += frame_change_time;
     }

     gdk_pixbuf_simple_anim_set_loop (result, TRUE);

     for (i=0;i<array_len;i++){
	  g_object_unref (anim_array[i]->iter);
     }

     return GDK_PIXBUF_ANIMATION (result);
}
示例#6
0
GdkPixbufAnimation*	
pgpug_animated_icon (PgpugPixEnum icon_id,
		     gint size)
{
     g_return_val_if_fail (icon_id < PIX_NUMBER, NULL);
     GdkPixbufSimpleAnim *result = NULL;
     PgpugPixEntry entry =  icon_entries_array [icon_id];

     /* assert that ids are in order */
     g_return_val_if_fail (entry.id == icon_id, NULL);

     GPtrArray *frames_array = g_ptr_array_new ();
     GtkIconTheme* theme;
     GdkPixbuf *pixbuf;
     GError *error = NULL, *error_anim = NULL;


     theme = gtk_icon_theme_get_default ();
     pixbuf = gtk_icon_theme_load_icon (theme, entry.name, size, 
					GTK_ICON_LOOKUP_FORCE_SIZE, &error);
     if (error == NULL && pixbuf != NULL) {
	  DEBG_MSG ("Loaded icon with name %s", entry.name);
	  //it's a static image
	  g_ptr_array_add (frames_array, (gpointer)pixbuf);
     }else{ 
	  //else try to get frame sequence
	  gchar *name_template = g_strconcat (entry.name, "%02d", NULL);
	  int i = 1;
	  do {
	       gchar *name = g_strdup_printf (name_template, i++);
	  
	       pixbuf = gtk_icon_theme_load_icon (theme, name, size, 
						  GTK_ICON_LOOKUP_FORCE_SIZE, &error_anim);
	       if (pixbuf != NULL){
		    DEBG_MSG ("Loaded animation frame with name %s, address %p", name, pixbuf);
		    g_ptr_array_add (frames_array, (gpointer)pixbuf);
	       }
	       g_free (name);
	  } while (error_anim == NULL && i < 100);

	  g_free (name_template);
     }

  
     if (frames_array->len != 0){
	  //construct animation
	  result = gdk_pixbuf_simple_anim_new (size, size, frames_array->len);
	  guint i;
	  for (i = 0;i < frames_array->len; i++)
	       gdk_pixbuf_simple_anim_add_frame (result, frames_array->pdata[i]);	       

     } else{
	  //we didn't find any images 
	  gchar **search_paths;
	  gint index;
	  gchar *search_path_str;
	  gtk_icon_theme_get_search_path (theme, &search_paths, &index);

	  search_path_str = g_strjoinv ("\n", search_paths);

	  WARN_MSG ("Icon with name \"%s\" can not be loaded.\n"
		   "Icon search paths are: \n%s\n"
		   "Error message: %s",
		   entry.name,
		   search_path_str, 
		   error->message);
	  g_strfreev (search_paths);
	  g_free (search_path_str);
     }

     g_ptr_array_foreach (frames_array, (GFunc)g_object_unref, NULL);
     g_ptr_array_free (frames_array, TRUE);
     if (error != NULL)	  	  g_error_free (error);
     if (error_anim != NULL)	  g_error_free (error_anim);

     return GDK_PIXBUF_ANIMATION (result);
}
示例#7
0
static gboolean
stop_load (GpBitmap *bitmap, GdipContext *context, GError **error)
{
  guint       n_frames = 1, i;
  GdkPixbufGdipAnim *animation = NULL;

  gdip_bitmap_get_n_frames (bitmap, &n_frames, TRUE);

  for (i = 0; i < n_frames; i++) {
    GdkPixbuf *pixbuf = NULL;
    GdkPixbufFrame *frame;
    guint frame_delay = 0;

    gdip_bitmap_select_frame (bitmap, i, TRUE);
    
    pixbuf = gdip_bitmap_to_pixbuf (bitmap, error);
    
    if (!pixbuf) {
      if (animation != NULL)
        g_object_unref (G_OBJECT (animation));

      GdipDisposeImage ((GpImage *)bitmap);
      destroy_gdipcontext (context);
      return FALSE;
    }
    
    if (animation == NULL) {
      guint n_loops = 1;

      animation = g_object_new (GDK_TYPE_PIXBUF_GDIP_ANIM, NULL);
      gdip_bitmap_get_n_loops (bitmap, &n_loops);
      animation->loop = n_loops;
    }

    frame = g_new (GdkPixbufFrame, 1);
    frame->pixbuf = pixbuf;

    gdip_bitmap_get_frame_delay (bitmap, &frame_delay);
  
    animation->n_frames++;
    animation->frames = g_list_append (animation->frames, frame);

    animation->width = gdk_pixbuf_get_width (pixbuf);
    animation->height = gdk_pixbuf_get_height (pixbuf);

    /* GIF delay is in hundredths, we want thousandths */
    frame->delay_time = frame_delay * 10;
    frame->elapsed = animation->total_time;
    
    /* Some GIFs apparently have delay time of 0,
     * that crashes everything so set it to "fast".
     * Also, timeouts less than 20 or so just lock up
     * the app or make the animation choppy, so fix them.
     */
    if (frame->delay_time < 20)
      frame->delay_time = 20; /* 20 = "fast" */

    animation->total_time += frame->delay_time;

    if (i == 0)
      emit_prepared (context, pixbuf, GDK_PIXBUF_ANIMATION (animation));

    emit_updated (context, pixbuf);
  }

  if (animation != NULL)
    g_object_unref (G_OBJECT (animation));

  GdipDisposeImage ((GpImage *)bitmap);
  destroy_gdipcontext (context);
  
  return TRUE;
}