X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fmovie.git;a=blobdiff_plain;f=movie.c;h=ec850ad59ae2b8357b96a691634c3b266ad40e8a;hp=f279449d03ee3ce1a1dfd9fc34da31fe2ccad2ab;hb=HEAD;hpb=2a9fb276c6db0dd6b2fd5764c45f0e589e3624f2 diff --git a/movie.c b/movie.c index f279449..ec850ad 100644 --- a/movie.c +++ b/movie.c @@ -16,131 +16,167 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define WIDTH 800 -#define HEIGHT 600 - +#define _GNU_SOURCE +#include #include #include -#include -#include +#include +#include + +#include "point.h" #define SWAP(x, y) do { \ x ^= y; y ^= x; x ^= y; \ } while (0) -#define ABS(x) ((x) < 0 ? -(x) : (x)) - -#define IS_CENTER(cx, cy, x, y) \ - ((x + WIDTH/2 == cx) && (y + HEIGHT/2 == cy)) - -SDL_Rect *points; -int psize; - void +InsertLine (GArray *points, Point *src, Point *dst) +{ + Point rect; + int inc, err, thre, swap; + int x1, y1, x2, y2; + int x, y; + rect.name = NULL; + err = 0; + swap = 0; + x1 = src->x; + y1 = src->y; + x2 = dst->x; + y2 = dst->y; + inc = y2 - y1; + thre = x2 - x1; + if (ABS (inc) > ABS (thre)) + { + SWAP (inc, thre); + SWAP (x1, y1); + SWAP (x2, y2); + swap = 1; + } + for (y = y1, x = x1; (x2 < x1) ? (x >= x2) : (x <= x2); (x2 < x1) ? x-- : x++) + { + rect.x = (swap ? y : x); + rect.y = (swap ? x : y); + g_array_append_val (points, rect); + err += ABS (inc); + if (err >= ABS (thre)) + { + err -= ABS (thre); + y += (inc < 0) ? -1 : 1; + } + } +} + +GArray * ReadPoints (char *filename) { + GArray *points; FILE *file; char *buffer; char *next; size_t len; - int i; + ssize_t r; + int i = 0; + Point last; + Point rect; file = fopen (filename, "r"); - fscanf (file, "%d\n", &psize); - points = malloc (sizeof (SDL_Rect) * psize); - if (points == NULL) - abort (); + if (file == NULL) + { + fprintf (stderr, "Could not open file %s\n", filename); + exit (1); + } + points = g_array_new (FALSE, TRUE, sizeof (Point)); buffer = NULL; len = 0; - for (i = 0; i < psize; i++) + rect.x = rect.y = 0; + rect.name = NULL; + last = rect; + while (!feof (file)) { - getline (&buffer, &len, file); - points[i].x = strtol (buffer, &next, 0); - points[i].y = strtol (next+1, NULL, 0); + r = getline (&buffer, &len, file); + buffer[r - 1] = '\0'; + rect.x = strtol (buffer, &next, 0); + rect.y = strtol (next+1, &next, 0); + strtol (next, &next, 0); + while (isspace (*next)) next++; + rect.name = g_strdup (next); + if (i > 0) + InsertLine (points, &last, &rect); + g_array_append_val (points, rect); + last = rect; + i++; } fclose (file); + return points; } -SDL_Rect * -GetNextPoint (void) +GArray * +drop_dup_frames (GArray *points, int n) { - static SDL_Rect rect = {0, 0, WIDTH, HEIGHT}; - static int cur = -1; - static int inc, err, thre, swap; - static int x1, y1, x2, y2; - static int x, y; - int next; - next = (cur + 1) % psize; - if (IS_CENTER (points[next].x, points[next].y, rect.x, rect.y) || cur == -1) - { - cur = next; - next = (cur + 1) % psize; - err = 0; - swap = 0; - x1 = points[cur].x; - y1 = points[cur].y; - x2 = points[next].x; - y2 = points[next].y; - inc = y2 - y1; - thre = x2 - x1; - if (ABS (inc) > ABS (thre)) + GArray *frames; + Point *point; + Point *next; + int i; + int j; + int inc; + int thre; + int err; + inc = n; + frames = g_array_new (FALSE, TRUE, sizeof (Point)); + for (i = 0; i < points->len;) { - SWAP (inc, thre); - SWAP (x1, y1); - SWAP (x2, y2); - swap = 1; + j = i + 1; + point = next = &(g_array_index (points, Point, j)); + while (next->name == NULL && j < points->len) + { + j++; + next = &(g_array_index (points, Point, j)); + } + thre = j - i; + err = 0; + g_array_append_val (frames, g_array_index (points, Point, i)); + for (; i < j; i++) + { + err += inc; + while (err > thre) + { + err -= thre; + g_array_append_val (frames, g_array_index (points, Point, i)); + } + } } - x = x1; - y = y1; - } - rect.x = (swap ? y : x) - WIDTH/2; - rect.y = (swap ? x : y) - HEIGHT/2; - (x2 < x1) ? x-- : x++; - err += ABS (inc); - if (err >= ABS (thre)) - { - err -= ABS (thre); - y += (inc < 0) ? -1 : 1; - } - return ▭ -} - -void -ShowPoint (SDL_Surface *screen, SDL_Surface *image, SDL_Rect *rect) -{ - SDL_BlitSurface (image, rect, screen, NULL); - SDL_UpdateRect (screen, 0, 0, 0, 0); + return frames; } -Uint32 -ShowNext (Uint32 interval, void *data) +GArray * +get_scales (int n) { - SDL_UserEvent event; - event.type = SDL_USEREVENT; - event.code = 0; - SDL_PushEvent ((SDL_Event *) &event); - return 33; + GArray *scales; + double scale; + double factor; + scales = g_array_new (FALSE, TRUE, sizeof (double)); + factor = pow (4.0, 1.0/((double) n/2)); + factor = 1.0/factor; + for (scale = 4.00; scale > 1.0 && scales->len < n/2; scale *= factor) + scales = g_array_append_val (scales, scale); + factor = 1.0/factor; + for (scale = 1.0; scale < 4.0 && scales->len < n; scale *= factor) + scales = g_array_append_val (scales, scale); + return scales; } -int -main (int argc, char **argv) +void +rescale_points (GArray *points, GArray *scales) { - SDL_Surface *screen; - SDL_Surface *image; - SDL_Event event; - ReadPoints ("pro-gnu"); - SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER); - screen = SDL_SetVideoMode (800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); - image = IMG_Load ("/home/cascardo/fotos/debconf.jpg"); - SDL_AddTimer (0, ShowNext, NULL); - while (SDL_WaitEvent (&event)) - { - if (event.type == SDL_KEYDOWN) - break; - else if (event.type == SDL_USEREVENT) - ShowPoint (screen, image, GetNextPoint ()); - } - SDL_FreeSurface (image); - SDL_Quit (); - free (points); - return 0; + Point *point; + double scale; + int i; + for (i = 0; i < points->len; i++) + { + point = &(g_array_index (points, Point, i)); + scale = g_array_index (scales, double, (i % scales->len)); + point->rx = scale; + point->ry = scale; + point->x *= point->rx; + point->y *= point->ry; + } }