1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2 
3 /*
4  * GImageView
5  * Copyright (C) 2001-2002 Takuro Ashie
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * $Id: gimv_anim.c,v 1.17 2004/06/17 06:37:26 makeinu Exp $
22  */
23 
24 #include "gimv_anim.h"
25 
26 #ifdef HAVE_GDK_PIXBUF
27 #  include <gdk-pixbuf/gdk-pixbuf.h>
28 #elif defined (HAVE_GDK_IMLIB)
29 #  include <gdk_imlib.h>
30 #endif
31 
32 
33 static void gimv_anim_class_init    (GimvAnimClass *klass);
34 static void gimv_anim_init          (GimvAnim      *anim);
35 static void gimv_anim_destroy       (GtkObject     *object);
36 
37 
38 static GimvImageClass *parent_class = NULL;
39 
40 
41 GtkType
gimv_anim_get_type(void)42 gimv_anim_get_type (void)
43 {
44    static GtkType gimv_anim_type = 0;
45 
46    if (!gimv_anim_type) {
47       static const GtkTypeInfo gimv_anim_info = {
48          "GimvAnim",
49          sizeof (GimvAnim),
50          sizeof (GimvAnimClass),
51          (GtkClassInitFunc) gimv_anim_class_init,
52          (GtkObjectInitFunc) gimv_anim_init,
53          NULL,
54          NULL,
55          (GtkClassInitFunc) NULL,
56       };
57 
58       gimv_anim_type = gtk_type_unique (gimv_image_get_type (),
59                                         &gimv_anim_info);
60    }
61 
62    return gimv_anim_type;
63 }
64 
65 
66 static void
gimv_anim_class_init(GimvAnimClass * klass)67 gimv_anim_class_init (GimvAnimClass *klass)
68 {
69    GtkObjectClass *object_class;
70 
71    object_class = (GtkObjectClass *) klass;
72    parent_class = gtk_type_class (gimv_image_get_type ());
73 
74    object_class->destroy  = gimv_anim_destroy;
75 }
76 
77 
78 static void
gimv_anim_init(GimvAnim * anim)79 gimv_anim_init (GimvAnim *anim)
80 {
81    anim->anim = NULL;
82    anim->current_frame_idx = -1;
83    anim->table = NULL;
84 }
85 
86 
87 static void
gimv_anim_destroy(GtkObject * object)88 gimv_anim_destroy (GtkObject *object)
89 {
90    GimvAnim *anim;
91 
92    g_return_if_fail (GIMV_IS_ANIM (object));
93 
94    anim = GIMV_ANIM (object);
95 
96    g_return_if_fail (anim->table);
97    g_return_if_fail (anim->table->delete);
98 
99    if (anim->anim && anim->table && anim->table->delete) {
100       anim->table->delete (anim);
101       anim->anim  = NULL;
102    }
103    anim->table = NULL;
104 
105    if (GTK_OBJECT_CLASS (parent_class)->destroy)
106       (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
107 }
108 
109 
110 GimvAnim *
gimv_anim_new(void)111 gimv_anim_new (void)
112 {
113    GimvAnim *anim = GIMV_ANIM (gtk_type_new (GIMV_TYPE_ANIM));
114    return anim;
115 }
116 
117 
118 gint
gimv_anim_get_length(GimvAnim * anim)119 gimv_anim_get_length (GimvAnim *anim)
120 {
121    g_return_val_if_fail (anim, -1);
122    g_return_val_if_fail (anim->table, -1);
123 
124    if (anim->table->get_length)
125       return anim->table->get_length (anim);
126 
127    return -1;
128 }
129 
130 
131 gint
gimv_anim_iterate(GimvAnim * anim)132 gimv_anim_iterate (GimvAnim *anim)
133 {
134    g_return_val_if_fail (anim, -1);
135    g_return_val_if_fail (anim->table, -1);
136    g_return_val_if_fail (anim->table->iterate, -1);
137 
138    return anim->table->iterate (anim);
139 }
140 
141 
142 gboolean
gimv_anim_seek(GimvAnim * anim,gint idx)143 gimv_anim_seek (GimvAnim *anim, gint idx)
144 {
145    g_return_val_if_fail (anim, FALSE);
146    g_return_val_if_fail (anim->table, FALSE);
147 
148    if (anim->table->seek)
149       return anim->table->seek (anim, idx);
150 
151    return FALSE;
152 }
153 
154 
155 gint
gimv_anim_get_interval(GimvAnim * anim)156 gimv_anim_get_interval (GimvAnim *anim)
157 {
158    g_return_val_if_fail (anim, -1);
159    g_return_val_if_fail (anim->table, -1);
160    g_return_val_if_fail (anim->table->get_interval, -1);
161 
162    return anim->table->get_interval (anim);
163 }
164 
165 
166 #if HAVE_GDK_PIXBUF
167 static void
free_rgb_buffer(guchar * pixels,gpointer data)168 free_rgb_buffer (guchar *pixels, gpointer data)
169 {
170    g_free(pixels);
171 }
172 #endif /* HAVE_GDK_PIXBUF */
173 
174 gboolean
gimv_anim_update_frame(GimvAnim * anim,guchar * frame,gint width,gint height,gboolean has_alpha)175 gimv_anim_update_frame (GimvAnim *anim,
176                         guchar   *frame,
177                         gint      width,
178                         gint      height,
179                         gboolean  has_alpha)
180 {
181    GimvImage *image = (GimvImage *) anim;
182 
183    g_return_val_if_fail (anim, FALSE);
184 
185 #if HAVE_GDK_PIXBUF
186    {
187       gint bytes = 3;
188 
189       if (has_alpha)
190          bytes = 4;
191 
192       if (image->image)
193          gdk_pixbuf_unref (image->image);
194 
195       image->image = gdk_pixbuf_new_from_data (frame, GDK_COLORSPACE_RGB, FALSE, 8,
196                                                width, height, bytes * width,
197                                                free_rgb_buffer, NULL);
198    }
199 #elif defined (HAVE_GDK_IMLIB)
200    if (image->image)
201       gdk_imlib_kill_image (image->image);
202 
203    image->image = gdk_imlib_create_image_from_data (frame, NULL, width, height);
204    g_free (frame);
205 #endif /* HAVE_GDK_PIXBUF */
206 
207    if (image->image)
208       return TRUE;
209    else
210       return FALSE;
211 }
212