Ignore generated files and input file
[cascardo/movie.git] / movie.c
1 /*
2  *  Copyright (C) 2008  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #define _GNU_SOURCE
20 #include <glib.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <ctype.h>
24 #include <math.h>
25
26 #include "point.h"
27
28 #define SWAP(x, y) do { \
29         x ^= y; y ^= x; x ^= y; \
30         } while (0)
31
32 void
33 InsertLine (GArray *points, Point *src, Point *dst)
34 {
35   Point rect;
36   int inc, err, thre, swap;
37   int x1, y1, x2, y2;
38   int x, y;
39   rect.name = NULL;
40   err = 0;
41   swap = 0;
42   x1 = src->x;
43   y1 = src->y;
44   x2 = dst->x;
45   y2 = dst->y;
46   inc = y2 - y1;
47   thre = x2 - x1;
48   if (ABS (inc) > ABS (thre))
49   {
50     SWAP (inc, thre);
51     SWAP (x1, y1);
52     SWAP (x2, y2);
53     swap = 1;
54   }
55   for (y = y1, x = x1; (x2 < x1) ? (x >= x2) : (x <= x2); (x2 < x1) ? x-- : x++)
56   {
57     rect.x = (swap ? y : x);
58     rect.y = (swap ? x : y);
59     g_array_append_val (points, rect);
60     err += ABS (inc);
61     if (err >= ABS (thre))
62     {
63       err -= ABS (thre);
64       y += (inc < 0) ? -1 : 1;
65     }
66   }
67 }
68
69 GArray *
70 ReadPoints (char *filename)
71 {
72   GArray *points;
73   FILE *file;
74   char *buffer;
75   char *next;
76   size_t len;
77   ssize_t r;
78   int i = 0;
79   Point last;
80   Point rect;
81   file = fopen (filename, "r");
82   points = g_array_new (FALSE, TRUE, sizeof (Point));
83   buffer = NULL;
84   len = 0;
85   rect.x = rect.y = 0;
86   rect.name = NULL;
87   last = rect;
88   while (!feof (file))
89   {
90     r = getline (&buffer, &len, file);
91     buffer[r - 1] = '\0';
92     rect.x = strtol (buffer, &next, 0);
93     rect.y = strtol (next+1, &next, 0);
94     strtol (next, &next, 0);
95     while (isspace (*next)) next++;
96     rect.name = g_strdup (next);
97     if (i > 0)
98       InsertLine (points, &last, &rect);
99     g_array_append_val (points, rect);
100     last = rect;
101     i++;
102   }
103   fclose (file);
104   return points;
105 }
106
107 GArray *
108 drop_dup_frames (GArray *points, int n)
109 {
110   GArray *frames;
111   Point *point;
112   Point *next;
113   int i;
114   int j;
115   int inc;
116   int thre;
117   int err;
118   inc = n;
119   frames = g_array_new (FALSE, TRUE, sizeof (Point));
120   for (i = 0; i < points->len;)
121     {
122       j = i + 1;
123       point = next = &(g_array_index (points, Point, j));
124       while (next->name == NULL && j < points->len)
125         {
126           j++;
127           next = &(g_array_index (points, Point, j));
128         }
129       thre = j - i;
130       err = 0;
131       g_array_append_val (frames, g_array_index (points, Point, i));
132       for (; i < j; i++)
133         {
134           err += inc;
135           while (err > thre)
136             {
137               err -= thre;
138               g_array_append_val (frames, g_array_index (points, Point, i));
139             }
140         }
141     }
142   return frames;
143 }
144
145 GArray *
146 get_scales (int n)
147 {
148   GArray *scales;
149   double scale;
150   double factor;
151   scales = g_array_new (FALSE, TRUE, sizeof (double));
152   factor = pow (4.0, 1.0/((double) n/2));
153   factor = 1.0/factor;
154   for (scale = 4.00; scale > 1.0 && scales->len < n/2; scale *= factor)
155     scales = g_array_append_val (scales, scale);
156   factor = 1.0/factor;
157   for (scale = 1.0; scale < 4.0 && scales->len < n; scale *= factor)
158     scales = g_array_append_val (scales, scale);
159   return scales;
160 }
161
162 void
163 rescale_points (GArray *points, GArray *scales)
164 {
165   Point *point;
166   double scale;
167   int i;
168   for (i = 0; i < points->len; i++)
169     {
170       point = &(g_array_index (points, Point, i));
171       scale = g_array_index (scales, double, (i % scales->len));
172       point->rx = scale;
173       point->ry = scale;
174       point->x *= point->rx;
175       point->y *= point->ry;
176     }
177 }