OLD | NEW |
---|---|
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 Loading... | |
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 |
54 | 55 |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 theta -= theta_offset; | 426 theta -= theta_offset; |
426 old_x = center_x + d * cos (theta); | 427 old_x = center_x + d * cos (theta); |
427 old_y = center_y + d * sin (theta); | 428 old_y = center_y + d * sin (theta); |
428 new_image->layout.as_pixels[x + y * width] = | 429 new_image->layout.as_pixels[x + y * width] = |
429 ply_image_interpolate (image, width, height, old_x, old_y); | 430 ply_image_interpolate (image, width, height, old_x, old_y); |
430 } | 431 } |
431 } | 432 } |
432 return new_image; | 433 return new_image; |
433 } | 434 } |
434 | 435 |
436 ply_image_t * | |
437 ply_image_from_file(const char *path) | |
438 { | |
439 int exit_code; | |
440 ply_image_t *image = ply_image_new (path); | |
441 | |
442 if (!ply_image_load (image)) | |
443 { | |
444 exit_code = errno; | |
445 perror (path); | |
446 exit (exit_code); | |
447 } | |
448 return image; | |
449 } | |
450 | |
435 #include "ply-frame-buffer.h" | 451 #include "ply-frame-buffer.h" |
436 | 452 |
437 #include <math.h> | 453 #include <math.h> |
438 #include <signal.h> | 454 #include <signal.h> |
439 #include <stdio.h> | 455 #include <stdio.h> |
440 #include <sys/ioctl.h> | 456 #include <sys/ioctl.h> |
441 #include <sys/time.h> | 457 #include <sys/time.h> |
442 #include <values.h> | 458 #include <values.h> |
443 | 459 |
444 #include <linux/kd.h> | 460 #include <linux/kd.h> |
445 | 461 |
462 const int frame_rate = 15; /* Animation frames per second */ | |
463 int bad_clock = 0; /* Set to 1 if the clock ever returns an error */ | |
464 | |
465 void | |
466 ply_frame_buffer_show_file_at_xy(ply_frame_buffer_t *buffer, const char *path, | |
467 long x, long y) | |
468 { | |
469 ply_image_t *image; | |
470 uint32_t *data; | |
471 long width, height; | |
472 ply_frame_buffer_area_t area; | |
473 | |
474 image = ply_image_from_file (path); | |
475 | |
476 data = ply_image_get_data (image); | |
477 width = ply_image_get_width (image); | |
478 height = ply_image_get_height (image); | |
479 | |
480 ply_frame_buffer_get_size (buffer, &area); | |
481 area.x = (area.width / 2) - (width / 2); // + x; | |
482 area.y = (area.height / 2) - (height / 2); // + y; | |
483 area.width = width; | |
484 area.height = height; | |
485 | |
486 ply_frame_buffer_fill (buffer, &area, x, y, data); | |
487 ply_image_free (image); | |
488 } | |
489 | |
490 /* | |
491 * Compute the difference in microseconds between two timevals. Return 0 if | |
492 * the clock is not reliable. Don't worry about overflows. | |
493 */ | |
494 int difference_nsec(struct timespec x, struct timespec y) | |
Daniel Erat
2010/12/14 02:18:05
why not return int64_t (and add some casts in the
| |
495 { | |
496 if (bad_clock) | |
497 { | |
498 return 0; | |
499 } | |
500 | |
501 return (x.tv_sec - y.tv_sec) * (1000 * 1000 * 1000) + x.tv_nsec - y.tv_nsec; | |
502 } | |
503 | |
504 | |
505 void gettime_check(struct timespec *ts) | |
506 { | |
507 int r = clock_gettime(CLOCK_MONOTONIC, ts); | |
508 if (r) | |
509 { | |
510 bad_clock = 1; | |
511 } | |
512 } | |
513 | |
514 | |
515 int usage(void) | |
516 { | |
517 fprintf(stderr, | |
518 "usage: ply-image --clear\n" | |
519 " ply-image <background> [<x-offset> <y-offset> " | |
520 "<frame-1> ... <frame-n>]"); | |
521 exit(1); | |
522 } | |
523 | |
446 | 524 |
447 int | 525 int |
448 main (int argc, | 526 main (int argc, |
449 char **argv) | 527 char **argv) |
450 { | 528 { |
451 ply_image_t *image = NULL; | 529 int exit_code = 0; |
530 int clear = 0; | |
531 int help = 0; | |
452 ply_frame_buffer_t *buffer; | 532 ply_frame_buffer_t *buffer; |
453 int exit_code; | 533 int i; |
454 ply_frame_buffer_area_t area; | 534 int xoff, yoff; |
455 uint32_t *data; | 535 char *endptr; |
456 long width, height; | |
457 | |
458 exit_code = 0; | |
459 | 536 |
460 // hide_cursor (); | 537 // hide_cursor (); |
461 | 538 |
462 if (argc != 2 || strcasecmp(argv[1], "-h") == 0 || strcasecmp(argv[1], "--help ") == 0) | 539 /* |
540 * Ad-hoc arg parsing, to keep the program small. | |
541 */ | |
542 | |
543 if (argc > 1) | |
463 { | 544 { |
464 perror ("usage: ply-image [--clear | <pngImageFile>]"); | 545 clear = strcasecmp (argv[1], "--clear") == 0; |
465 return 1; | 546 help = strcasecmp (argv[1], "--help") == 0 || |
547 strcasecmp (argv[1], "-h") == 0; | |
466 } | 548 } |
467 | 549 |
468 if (strcasecmp(argv[1], "--clear") != 0) | 550 if (help || argc == 1 || argc == 3 || argc == 4) |
469 { | 551 { |
470 image = ply_image_new (argv[1]); | 552 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 } | 553 } |
479 | 554 |
480 buffer = ply_frame_buffer_new (NULL); | 555 buffer = ply_frame_buffer_new (NULL); |
481 | 556 |
482 if (!ply_frame_buffer_open (buffer)) | 557 if (!ply_frame_buffer_open (buffer)) |
483 { | 558 { |
484 exit_code = errno; | 559 exit_code = errno; |
485 perror ("could not open framebuffer"); | 560 perror ("could not open framebuffer"); |
486 return exit_code; | 561 return exit_code; |
487 } | 562 } |
488 | 563 |
489 if (image == NULL) | 564 if (clear) |
490 { | 565 { |
491 ply_frame_buffer_clear (buffer); | 566 ply_frame_buffer_clear (buffer); |
492 } | 567 } |
493 else | 568 else |
494 { | 569 { |
495 data = ply_image_get_data (image); | 570 /* |
496 width = ply_image_get_width (image); | 571 * Display main image. |
497 height = ply_image_get_height (image); | 572 */ |
573 ply_frame_buffer_show_file_at_xy (buffer, argv[1], 0, 0); | |
498 | 574 |
499 ply_frame_buffer_get_size (buffer, &area); | 575 if (argc >= 4) |
500 area.x = (area.width / 2) - (width / 2); | 576 { |
501 area.y = (area.height / 2) - (height / 2); | 577 /* |
502 area.width = width; | 578 * Animate frames. |
503 area.height = height; | 579 */ |
580 struct timespec then, now; | |
504 | 581 |
505 ply_frame_buffer_fill (buffer, &area, 0, 0, data); | 582 xoff = strtol (argv[2], &endptr, 10); |
506 ply_image_free (image); | 583 if (endptr == argv[2] || *endptr != '\0') |
584 { | |
585 usage (); | |
586 } | |
587 yoff = strtol (argv[3], &endptr, 10); | |
588 if (endptr == argv[3] || *endptr != '\0') | |
589 { | |
590 usage (); | |
591 } | |
592 | |
593 gettime_check (&then); | |
594 for (i = 4; i < argc; i++) | |
595 { | |
596 struct timespec req; | |
597 int elapsed_nsec; | |
598 gettime_check (&now); | |
599 elapsed_nsec = difference_nsec (now, then); | |
600 req.tv_sec = 0; | |
601 req.tv_nsec = (1000 * 1000 * 1000) / frame_rate - elapsed_nsec; | |
Daniel Erat
2010/12/14 02:18:05
could you pull a variable like:
int64_t nsec_be
| |
602 if (req.tv_nsec > 0) | |
603 { | |
604 nanosleep (&req, NULL); | |
605 } | |
606 gettime_check (&then); | |
Daniel Erat
2010/12/14 02:18:05
it'd be cleaner/more accurate to copy 'now' into '
| |
607 ply_frame_buffer_show_file_at_xy (buffer, argv[i], xoff, yoff); | |
608 } | |
609 } | |
507 } | 610 } |
508 | 611 |
509 ply_frame_buffer_close (buffer); | 612 // Skip these to save time. |
510 ply_frame_buffer_free (buffer); | 613 // ply_frame_buffer_close (buffer); |
614 // ply_frame_buffer_free (buffer); | |
511 | 615 |
512 return exit_code; | 616 return exit_code; |
513 } | 617 } |
OLD | NEW |