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