~ubuntu-branches/ubuntu/precise/gdk-pixbuf/precise-proposed

« back to all changes in this revision

Viewing changes to gdk-pixbuf/io-gif-animation.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2012-01-03 12:47:30 UTC
  • mfrom: (1.1.11)
  • Revision ID: package-import@ubuntu.com-20120103124730-ei8nfz2ujfxi5hrb
Tags: 2.25.0-0ubuntu1
* New upstream version
* debian/control.in: 
  - updated glib requirement
* debian/libgdk-pixbuf2.0-0.symbols:
  - list new symbols
* debian/rules:
  - use --with-x11

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "gdk-pixbuf-private.h"
29
29
#include "io-gif-animation.h"
30
30
 
31
 
static void gdk_pixbuf_gif_anim_class_init (GdkPixbufGifAnimClass *klass);
32
31
static void gdk_pixbuf_gif_anim_finalize   (GObject        *object);
33
32
 
34
33
static gboolean                gdk_pixbuf_gif_anim_is_static_image  (GdkPixbufAnimation *animation);
43
42
 
44
43
 
45
44
 
46
 
static gpointer parent_class;
 
45
G_DEFINE_TYPE (GdkPixbufGifAnim, gdk_pixbuf_gif_anim, GDK_TYPE_PIXBUF_ANIMATION);
47
46
 
48
 
GType
49
 
gdk_pixbuf_gif_anim_get_type (void)
 
47
static void
 
48
gdk_pixbuf_gif_anim_init (GdkPixbufGifAnim *anim)
50
49
{
51
 
        static GType object_type = 0;
52
 
 
53
 
        if (!object_type) {
54
 
                const GTypeInfo object_info = {
55
 
                        sizeof (GdkPixbufGifAnimClass),
56
 
                        (GBaseInitFunc) NULL,
57
 
                        (GBaseFinalizeFunc) NULL,
58
 
                        (GClassInitFunc) gdk_pixbuf_gif_anim_class_init,
59
 
                        NULL,           /* class_finalize */
60
 
                        NULL,           /* class_data */
61
 
                        sizeof (GdkPixbufGifAnim),
62
 
                        0,              /* n_preallocs */
63
 
                        (GInstanceInitFunc) NULL,
64
 
                };
65
 
                
66
 
                object_type = g_type_register_static (GDK_TYPE_PIXBUF_ANIMATION,
67
 
                                                      g_intern_static_string ("GdkPixbufGifAnim"),
68
 
                                                      &object_info, 0);
69
 
        }
70
 
        
71
 
        return object_type;
72
50
}
73
51
 
74
52
static void
76
54
{
77
55
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
78
56
        GdkPixbufAnimationClass *anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass);
79
 
        
80
 
        parent_class = g_type_class_peek_parent (klass);
81
 
        
 
57
 
82
58
        object_class->finalize = gdk_pixbuf_gif_anim_finalize;
83
59
 
84
60
        anim_class->is_static_image = gdk_pixbuf_gif_anim_is_static_image;
94
70
 
95
71
        GList *l;
96
72
        GdkPixbufFrame *frame;
97
 
        
 
73
 
98
74
        for (l = gif_anim->frames; l; l = l->next) {
99
75
                frame = l->data;
100
76
                g_object_unref (frame->pixbuf);
104
80
                        g_object_unref (frame->revert);
105
81
                g_free (frame);
106
82
        }
107
 
        
 
83
 
108
84
        g_list_free (gif_anim->frames);
109
 
        
110
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
 
85
 
 
86
        G_OBJECT_CLASS (gdk_pixbuf_gif_anim_parent_class)->finalize (object);
111
87
}
112
88
 
113
89
static gboolean
131
107
        if (gif_anim->frames == NULL)
132
108
                return NULL;
133
109
        else
134
 
                return GDK_PIXBUF (((GdkPixbufFrame*)gif_anim->frames->data)->pixbuf);        
 
110
                return GDK_PIXBUF (((GdkPixbufFrame*)gif_anim->frames->data)->pixbuf);
135
111
}
136
112
 
137
113
static void
161
137
iter_restart (GdkPixbufGifAnimIter *iter)
162
138
{
163
139
        iter_clear (iter);
164
 
  
 
140
 
165
141
        iter->current_frame = iter->gif_anim->frames;
166
142
}
167
143
 
176
152
        iter->gif_anim = GDK_PIXBUF_GIF_ANIM (anim);
177
153
 
178
154
        g_object_ref (iter->gif_anim);
179
 
        
 
155
 
180
156
        iter_restart (iter);
181
157
 
182
158
        iter->start_time = *start_time;
183
159
        iter->current_time = *start_time;
184
160
        iter->first_loop_slowness = 0;
185
 
        
 
161
 
186
162
        return GDK_PIXBUF_ANIMATION_ITER (iter);
187
163
}
188
164
 
189
165
 
190
166
 
191
 
static void gdk_pixbuf_gif_anim_iter_class_init (GdkPixbufGifAnimIterClass *klass);
192
167
static void gdk_pixbuf_gif_anim_iter_finalize   (GObject                   *object);
193
168
 
194
169
static int        gdk_pixbuf_gif_anim_iter_get_delay_time             (GdkPixbufAnimationIter *iter);
199
174
 
200
175
 
201
176
 
202
 
static gpointer iter_parent_class;
 
177
G_DEFINE_TYPE (GdkPixbufGifAnimIter, gdk_pixbuf_gif_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER);
203
178
 
204
 
GType
205
 
gdk_pixbuf_gif_anim_iter_get_type (void)
 
179
static void
 
180
gdk_pixbuf_gif_anim_iter_init (GdkPixbufGifAnimIter *iter)
206
181
{
207
 
        static GType object_type = 0;
208
 
 
209
 
        if (!object_type) {
210
 
                const GTypeInfo object_info = {
211
 
                        sizeof (GdkPixbufGifAnimIterClass),
212
 
                        (GBaseInitFunc) NULL,
213
 
                        (GBaseFinalizeFunc) NULL,
214
 
                        (GClassInitFunc) gdk_pixbuf_gif_anim_iter_class_init,
215
 
                        NULL,           /* class_finalize */
216
 
                        NULL,           /* class_data */
217
 
                        sizeof (GdkPixbufGifAnimIter),
218
 
                        0,              /* n_preallocs */
219
 
                        (GInstanceInitFunc) NULL,
220
 
                };
221
 
                
222
 
                object_type = g_type_register_static (GDK_TYPE_PIXBUF_ANIMATION_ITER,
223
 
                                                      g_intern_static_string ("GdkPixbufGifAnimIter"),
224
 
                                                      &object_info, 0);
225
 
        }
226
 
        
227
 
        return object_type;
228
182
}
229
183
 
230
184
static void
233
187
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
234
188
        GdkPixbufAnimationIterClass *anim_iter_class =
235
189
                GDK_PIXBUF_ANIMATION_ITER_CLASS (klass);
236
 
        
237
 
        iter_parent_class = g_type_class_peek_parent (klass);
238
 
        
 
190
 
239
191
        object_class->finalize = gdk_pixbuf_gif_anim_iter_finalize;
240
192
 
241
193
        anim_iter_class->get_delay_time = gdk_pixbuf_gif_anim_iter_get_delay_time;
252
204
        iter_clear (iter);
253
205
 
254
206
        g_object_unref (iter->gif_anim);
255
 
        
256
 
        G_OBJECT_CLASS (iter_parent_class)->finalize (object);
 
207
 
 
208
        G_OBJECT_CLASS (gdk_pixbuf_gif_anim_iter_parent_class)->finalize (object);
257
209
}
258
210
 
259
211
static gboolean
265
217
        gint loop;
266
218
        GList *tmp;
267
219
        GList *old;
268
 
        
 
220
 
269
221
        iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
270
 
        
 
222
 
271
223
        iter->current_time = *current_time;
272
224
 
273
225
        /* We use milliseconds for all times */
284
236
        }
285
237
 
286
238
        g_assert (iter->gif_anim->total_time > 0);
287
 
        
 
239
 
288
240
        /* See how many times we've already played the full animation,
289
241
         * and subtract time for that.
290
242
         */
308
260
        iter->position = elapsed;
309
261
 
310
262
        /* Now move to the proper frame */
311
 
        if (iter->gif_anim->loop == 0 || loop < iter->gif_anim->loop) 
 
263
        if (iter->gif_anim->loop == 0 || loop < iter->gif_anim->loop)
312
264
                tmp = iter->gif_anim->frames;
313
 
        else 
 
265
        else
314
266
                tmp = NULL;
315
267
        while (tmp != NULL) {
316
268
                GdkPixbufFrame *frame = tmp->data;
317
 
                
 
269
 
318
270
                if (iter->position >= frame->elapsed &&
319
271
                    iter->position < (frame->elapsed + frame->delay_time))
320
272
                        break;
321
 
                
 
273
 
322
274
                tmp = tmp->next;
323
275
        }
324
276
 
325
277
        old = iter->current_frame;
326
 
        
 
278
 
327
279
        iter->current_frame = tmp;
328
280
 
329
281
        return iter->current_frame != old;
334
286
{
335
287
        GdkPixbufFrame *frame;
336
288
        GdkPixbufGifAnimIter *iter;
337
 
  
 
289
 
338
290
        iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
339
291
 
340
292
        if (iter->current_frame) {
347
299
                         frame->delay_time,
348
300
                         frame->delay_time - (iter->position - frame->elapsed));
349
301
#endif
350
 
                
 
302
 
351
303
                return frame->delay_time - (iter->position - frame->elapsed);
352
 
        } else 
 
304
        } else
353
305
                return -1; /* show last frame forever */
354
306
}
355
307
 
356
308
void
357
309
gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
358
310
                                     GdkPixbufFrame   *frame)
359
 
{  
 
311
{
360
312
        GList *link;
361
313
        GList *tmp;
362
 
        
 
314
 
363
315
        link = g_list_find (gif_anim->frames, frame);
364
 
        
 
316
 
365
317
        if (frame->need_recomposite || frame->composited == NULL) {
366
318
                /* For now, to composite we start with the last
367
319
                 * composited frame and composite everything up to
372
324
                tmp = link;
373
325
                while (tmp != NULL) {
374
326
                        GdkPixbufFrame *f = tmp->data;
375
 
                        
 
327
 
376
328
                        if (f->need_recomposite) {
377
329
                                if (f->composited) {
378
330
                                        g_object_unref (f->composited);
382
334
 
383
335
                        if (f->composited != NULL)
384
336
                                break;
385
 
                        
 
337
 
386
338
                        tmp = tmp->prev;
387
339
                }
388
340
 
389
341
                /* Go forward, compositing all frames up to the current frame */
390
342
                if (tmp == NULL)
391
343
                        tmp = gif_anim->frames;
392
 
                
 
344
 
393
345
                while (tmp != NULL) {
394
346
                        GdkPixbufFrame *f = tmp->data;
395
347
                        gint clipped_width, clipped_height;
399
351
 
400
352
                        clipped_width = MIN (gif_anim->width - f->x_offset, gdk_pixbuf_get_width (f->pixbuf));
401
353
                        clipped_height = MIN (gif_anim->height - f->y_offset, gdk_pixbuf_get_height (f->pixbuf));
402
 
  
 
354
 
403
355
                        if (f->need_recomposite) {
404
356
                                if (f->composited) {
405
357
                                        g_object_unref (f->composited);
406
358
                                        f->composited = NULL;
407
359
                                }
408
360
                        }
409
 
                        
 
361
 
410
362
                        if (f->composited != NULL)
411
363
                                goto next;
412
364
 
424
376
                                        return;
425
377
 
426
378
                                /* alpha gets dumped if f->composited has no alpha */
427
 
                                
 
379
 
428
380
                                gdk_pixbuf_fill (f->composited,
429
381
                                                 (gif_anim->bg_red << 24) |
430
382
                                                 (gif_anim->bg_green << 16) |
441
393
                                                              1.0, 1.0,
442
394
                                                              GDK_INTERP_BILINEAR,
443
395
                                                              255);
444
 
                                
 
396
 
445
397
                                if (f->action == GDK_PIXBUF_FRAME_REVERT)
446
398
                                        g_warning ("First frame of GIF has bad dispose mode, GIF loader should not have loaded this image");
447
399
 
450
402
                                GdkPixbufFrame *prev_frame;
451
403
                                gint prev_clipped_width;
452
404
                                gint prev_clipped_height;
453
 
                                
 
405
 
454
406
                                prev_frame = tmp->prev->data;
455
407
 
456
408
                                prev_clipped_width = MIN (gif_anim->width - prev_frame->x_offset, gdk_pixbuf_get_width (prev_frame->pixbuf));
459
411
                                /* Init f->composited with what we should have after the previous
460
412
                                 * frame
461
413
                                 */
462
 
                                
 
414
 
463
415
                                if (prev_frame->action == GDK_PIXBUF_FRAME_RETAIN) {
464
416
                                        f->composited = gdk_pixbuf_copy (prev_frame->composited);
465
417
 
466
418
                                        if (f->composited == NULL)
467
419
                                                return;
468
 
                                        
 
420
 
469
421
                                } else if (prev_frame->action == GDK_PIXBUF_FRAME_DISPOSE) {
470
422
                                        f->composited = gdk_pixbuf_copy (prev_frame->composited);
471
423
 
484
436
 
485
437
                                                if (area == NULL)
486
438
                                                        return;
487
 
                                                
 
439
 
488
440
                                                gdk_pixbuf_fill (area,
489
441
                                                                 (gif_anim->bg_red << 24) |
490
442
                                                                 (gif_anim->bg_green << 16) |
491
443
                                                                 (gif_anim->bg_blue << 8));
492
 
                                                
 
444
 
493
445
                                                g_object_unref (area);
494
 
                                        }                                        
 
446
                                        }
495
447
                                } else if (prev_frame->action == GDK_PIXBUF_FRAME_REVERT) {
496
448
                                        f->composited = gdk_pixbuf_copy (prev_frame->composited);
497
449
 
518
470
                                        if (clipped_width > 0 && clipped_height > 0) {
519
471
                                                /* We need to save the contents before compositing */
520
472
                                                GdkPixbuf *area;
521
 
                                                
 
473
 
522
474
                                                area = gdk_pixbuf_new_subpixbuf (f->composited,
523
475
                                                                                 f->x_offset,
524
476
                                                                                 f->y_offset,
525
477
                                                                                 clipped_width,
526
478
                                                                                 clipped_height);
527
 
                                            
 
479
 
528
480
                                                if (area == NULL)
529
481
                                                        return;
530
 
                                                
 
482
 
531
483
                                                f->revert = gdk_pixbuf_copy (area);
532
484
 
533
485
                                                g_object_unref (area);
551
503
                                                              GDK_INTERP_NEAREST,
552
504
                                                              255);
553
505
                                }
554
 
                        
 
506
 
555
507
                                f->need_recomposite = FALSE;
556
508
                        }
557
 
                        
 
509
 
558
510
                next:
559
511
                        if (tmp == link)
560
512
                                break;
561
 
                        
 
513
 
562
514
                        tmp = tmp->next;
563
515
                }
564
516
        }
569
521
{
570
522
        GdkPixbufGifAnimIter *iter;
571
523
        GdkPixbufFrame *frame;
572
 
        
 
524
 
573
525
        iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
574
526
 
575
527
        frame = iter->current_frame ? iter->current_frame->data : g_list_last (iter->gif_anim->frames)->data;
583
535
                   gdk_pixbuf_get_width (frame->pixbuf),
584
536
                   gdk_pixbuf_get_height (frame->pixbuf));
585
537
#endif
586
 
        
 
538
 
587
539
        if (frame == NULL)
588
540
                return NULL;
589
541
 
590
542
        gdk_pixbuf_gif_anim_frame_composite (iter->gif_anim, frame);
591
 
        
 
543
 
592
544
        return frame->composited;
593
545
}
594
546
 
596
548
gdk_pixbuf_gif_anim_iter_on_currently_loading_frame (GdkPixbufAnimationIter *anim_iter)
597
549
{
598
550
        GdkPixbufGifAnimIter *iter;
599
 
  
 
551
 
600
552
        iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
601
553
 
602
 
        return iter->current_frame == NULL || iter->current_frame->next == NULL;  
 
554
        return iter->current_frame == NULL || iter->current_frame->next == NULL;
603
555
}