Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: src/ply-image.c

Issue 5819001: Add frame-by-frame animation. (Closed) Base URL: http://git.chromium.org/git/ply-image.git@master
Patch Set: Fix units in comment. Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ply-frame-buffer.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* ply-image.c - png file loader 1 /* ply-image.c - png file loader
2 * 2 *
3 * Copyright (C) 2006, 2007 Red Hat, Inc. 3 * Copyright (C) 2006, 2007 Red Hat, Inc.
4 * Copyright (C) 2003 University of Southern California 4 * Copyright (C) 2003 University of Southern California
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option) 8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version. 9 * any later version.
10 * 10 *
(...skipping 24 matching lines...) Expand all
35 #include <errno.h> 35 #include <errno.h>
36 #include <fcntl.h> 36 #include <fcntl.h>
37 #include <string.h> 37 #include <string.h>
38 #include <stdbool.h> 38 #include <stdbool.h>
39 #include <stdint.h> 39 #include <stdint.h>
40 #include <stdlib.h> 40 #include <stdlib.h>
41 #include <sys/ioctl.h> 41 #include <sys/ioctl.h>
42 #include <sys/mman.h> 42 #include <sys/mman.h>
43 #include <sys/stat.h> 43 #include <sys/stat.h>
44 #include <sys/types.h> 44 #include <sys/types.h>
45 #include <time.h>
45 #include <unistd.h> 46 #include <unistd.h>
46 #include <math.h> 47 #include <math.h>
47 48
48 #include <png.h> 49 #include <png.h>
49 50
50 #include <linux/fb.h> 51 #include <linux/fb.h>
51 52
52 #include "ply-utils.h" 53 #include "ply-utils.h"
53 54
55 #define BILLION (1000 * 1000 * 1000)
56
54 57
55 typedef union 58 typedef union
56 { 59 {
57 uint32_t *as_pixels; 60 uint32_t *as_pixels;
58 png_byte *as_png_bytes; 61 png_byte *as_png_bytes;
59 char *address; 62 char *address;
60 } ply_image_layout_t; 63 } ply_image_layout_t;
61 64
62 struct _ply_image 65 struct _ply_image
63 { 66 {
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 theta -= theta_offset; 428 theta -= theta_offset;
426 old_x = center_x + d * cos (theta); 429 old_x = center_x + d * cos (theta);
427 old_y = center_y + d * sin (theta); 430 old_y = center_y + d * sin (theta);
428 new_image->layout.as_pixels[x + y * width] = 431 new_image->layout.as_pixels[x + y * width] =
429 ply_image_interpolate (image, width, height, old_x, old_y); 432 ply_image_interpolate (image, width, height, old_x, old_y);
430 } 433 }
431 } 434 }
432 return new_image; 435 return new_image;
433 } 436 }
434 437
438 ply_image_t *
439 ply_image_from_file(const char *path)
440 {
441 int exit_code;
442 ply_image_t *image = ply_image_new (path);
443
444 if (!ply_image_load (image))
445 {
446 exit_code = errno;
447 perror (path);
448 exit (exit_code);
449 }
450 return image;
451 }
452
435 #include "ply-frame-buffer.h" 453 #include "ply-frame-buffer.h"
436 454
437 #include <math.h> 455 #include <math.h>
438 #include <signal.h> 456 #include <signal.h>
439 #include <stdio.h> 457 #include <stdio.h>
440 #include <sys/ioctl.h> 458 #include <sys/ioctl.h>
441 #include <sys/time.h> 459 #include <sys/time.h>
442 #include <values.h> 460 #include <values.h>
443 461
444 #include <linux/kd.h> 462 #include <linux/kd.h>
445 463
464 const int frame_rate = 20; /* Animation frames per second */
465 int bad_clock = 0; /* Set to 1 if the clock ever returns an error */
466
467 void
468 ply_frame_buffer_show_file_at_xy(ply_frame_buffer_t *buffer, const char *path,
469 long x, long y)
470 {
471 ply_image_t *image;
472 uint32_t *data;
473 long width, height;
474 ply_frame_buffer_area_t area;
475
476 image = ply_image_from_file (path);
477
478 data = ply_image_get_data (image);
479 width = ply_image_get_width (image);
480 height = ply_image_get_height (image);
481
482 ply_frame_buffer_get_size (buffer, &area);
483 area.x = (area.width / 2) - (width / 2); // + x;
484 area.y = (area.height / 2) - (height / 2); // + y;
485 area.width = width;
486 area.height = height;
487
488 ply_frame_buffer_fill (buffer, &area, x, y, data);
489 ply_image_free (image);
490 }
491
492 /*
493 * Compute the difference in nanoseconds between two timevals. Return 0 if the
494 * clock is not reliable.
495 */
496 int64_t difference_nsec(struct timespec x, struct timespec y)
497 {
498 int64_t z;
499
500 if (bad_clock)
501 {
502 return 0;
503 }
504
505 z = x.tv_sec - y.tv_sec;
506 z *= BILLION;
507 z += x.tv_nsec - y.tv_nsec;
508 return z;
509 }
510
511
512 void gettime_check(struct timespec *ts)
513 {
514 int r = clock_gettime(CLOCK_MONOTONIC, ts);
515 if (r)
516 {
517 bad_clock = 1;
518 }
519 }
520
521
522 int usage(void)
523 {
524 fprintf(stderr,
525 "usage: ply-image --clear\n"
526 " ply-image <background> [<x-offset> <y-offset> "
527 "<frame-1> ... <frame-n>]\n");
528 exit(1);
529 }
530
446 531
447 int 532 int
448 main (int argc, 533 main (int argc,
449 char **argv) 534 char **argv)
450 { 535 {
451 ply_image_t *image = NULL; 536 int exit_code = 0;
537 int clear = 0;
538 int help = 0;
452 ply_frame_buffer_t *buffer; 539 ply_frame_buffer_t *buffer;
453 int exit_code; 540 int i;
454 ply_frame_buffer_area_t area; 541 int xoff, yoff;
455 uint32_t *data; 542 char *endptr;
456 long width, height;
457
458 exit_code = 0;
459 543
460 // hide_cursor (); 544 // hide_cursor ();
461 545
462 if (argc != 2 || strcasecmp(argv[1], "-h") == 0 || strcasecmp(argv[1], "--help ") == 0) 546 /*
547 * Ad-hoc arg parsing, to keep the program small.
548 */
549
550 if (argc > 1)
463 { 551 {
464 perror ("usage: ply-image [--clear | <pngImageFile>]"); 552 clear = strcasecmp (argv[1], "--clear") == 0;
465 return 1; 553 help = strcasecmp (argv[1], "--help") == 0 ||
554 strcasecmp (argv[1], "-h") == 0;
466 } 555 }
467 556
468 if (strcasecmp(argv[1], "--clear") != 0) 557 if (help || argc == 1 || argc == 3 || argc == 4)
469 { 558 {
470 image = ply_image_new (argv[1]); 559 usage();
471
472 if (!ply_image_load (image))
473 {
474 exit_code = errno;
475 perror ("could not load image");
476 return exit_code;
477 }
478 } 560 }
479 561
480 buffer = ply_frame_buffer_new (NULL); 562 buffer = ply_frame_buffer_new (NULL);
481 563
482 if (!ply_frame_buffer_open (buffer)) 564 if (!ply_frame_buffer_open (buffer))
483 { 565 {
484 exit_code = errno; 566 exit_code = errno;
485 perror ("could not open framebuffer"); 567 perror ("could not open framebuffer");
486 return exit_code; 568 return exit_code;
487 } 569 }
488 570
489 if (image == NULL) 571 if (clear)
490 { 572 {
491 ply_frame_buffer_clear (buffer); 573 ply_frame_buffer_clear (buffer);
492 } 574 }
493 else 575 else
494 { 576 {
495 data = ply_image_get_data (image); 577 /*
496 width = ply_image_get_width (image); 578 * Display main image.
497 height = ply_image_get_height (image); 579 */
580 ply_frame_buffer_show_file_at_xy (buffer, argv[1], 0, 0);
498 581
499 ply_frame_buffer_get_size (buffer, &area); 582 if (argc >= 4)
500 area.x = (area.width / 2) - (width / 2); 583 {
501 area.y = (area.height / 2) - (height / 2); 584 /*
502 area.width = width; 585 * Animate frames.
503 area.height = height; 586 */
587 struct timespec then, now;
588 int64_t error_nsec;
589 int64_t interval_nsec;
504 590
505 ply_frame_buffer_fill (buffer, &area, 0, 0, data); 591 xoff = strtol (argv[2], &endptr, 10);
506 ply_image_free (image); 592 if (endptr == argv[2] || *endptr != '\0')
593 {
594 usage ();
595 }
596 yoff = strtol (argv[3], &endptr, 10);
597 if (endptr == argv[3] || *endptr != '\0')
598 {
599 usage ();
600 }
601
602 /*
603 * Begin animation.
604 *
605 * The first time around, we don't know how long it takes to draw a
606 * frame, so we assume it's instantaneous. After that, we assume
607 * that the drawing time for the previous cycle is a good estimate
608 * for the next cycle. Errors may be introduced by different frame
609 * size and complexity (PNG decoding).
610 */
611 error_nsec = 0;
612 interval_nsec = BILLION / frame_rate;
613 gettime_check (&now);
614
615 for (i = 4; i < argc; i++)
616 {
617 /*
618 * Before displaying the next frame, sleep for the inter-frame
619 * interval, adjusted by the error in the previous cycle.
620 * Positive error means the last cycle took longer than desired.
621 */
622 if (interval_nsec - error_nsec > 0)
623 {
624 struct timespec req;
625 req.tv_sec = (interval_nsec - error_nsec) / BILLION;
626 req.tv_nsec = (interval_nsec - error_nsec) % BILLION;
627 nanosleep (&req, NULL);
628 }
629 ply_frame_buffer_show_file_at_xy (buffer, argv[i], xoff, yoff);
630 then = now;
631 gettime_check (&now);
632 error_nsec = difference_nsec (now, then) - interval_nsec;
633 }
634 }
507 } 635 }
508 636
509 ply_frame_buffer_close (buffer); 637 // Skip these to save time.
510 ply_frame_buffer_free (buffer); 638 // ply_frame_buffer_close (buffer);
639 // ply_frame_buffer_free (buffer);
511 640
512 return exit_code; 641 return exit_code;
513 } 642 }
OLDNEW
« no previous file with comments | « src/ply-frame-buffer.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698