If picture does no exist, warn and exit
[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   if (file == NULL)
83     {
84       fprintf (stderr, "Could not open file %s\n", filename);
85       exit (1);
86     }
87   points = g_array_new (FALSE, TRUE, sizeof (Point));
88   buffer = NULL;
89   len = 0;
90   rect.x = rect.y = 0;
91   rect.name = NULL;
92   last = rect;
93   while (!feof (file))
94   {
95     r = getline (&buffer, &len, file);
96     buffer[r - 1] = '\0';
97     rect.x = strtol (buffer, &next, 0);
98     rect.y = strtol (next+1, &next, 0);
99     strtol (next, &next, 0);
100     while (isspace (*next)) next++;
101     rect.name = g_strdup (next);
102     if (i > 0)
103       InsertLine (points, &last, &rect);
104     g_array_append_val (points, rect);
105     last = rect;
106     i++;
107   }
108   fclose (file);
109   return points;
110 }
111
112 GArray *
113 drop_dup_frames (GArray *points, int n)
114 {
115   GArray *frames;
116   Point *point;
117   Point *next;
118   int i;
119   int j;
120   int inc;
121   int thre;
122   int err;
123   inc = n;
124   frames = g_array_new (FALSE, TRUE, sizeof (Point));
125   for (i = 0; i < points->len;)
126     {
127       j = i + 1;
128       point = next = &(g_array_index (points, Point, j));
129       while (next->name == NULL && j < points->len)
130         {
131           j++;
132           next = &(g_array_index (points, Point, j));
133         }
134       thre = j - i;
135       err = 0;
136       g_array_append_val (frames, g_array_index (points, Point, i));
137       for (; i < j; i++)
138         {
139           err += inc;
140           while (err > thre)
141             {
142               err -= thre;
143               g_array_append_val (frames, g_array_index (points, Point, i));
144             }
145         }
146     }
147   return frames;
148 }
149
150 GArray *
151 get_scales (int n)
152 {
153   GArray *scales;
154   double scale;
155   double factor;
156   scales = g_array_new (FALSE, TRUE, sizeof (double));
157   factor = pow (4.0, 1.0/((double) n/2));
158   factor = 1.0/factor;
159   for (scale = 4.00; scale > 1.0 && scales->len < n/2; scale *= factor)
160     scales = g_array_append_val (scales, scale);
161   factor = 1.0/factor;
162   for (scale = 1.0; scale < 4.0 && scales->len < n; scale *= factor)
163     scales = g_array_append_val (scales, scale);
164   return scales;
165 }
166
167 void
168 rescale_points (GArray *points, GArray *scales)
169 {
170   Point *point;
171   double scale;
172   int i;
173   for (i = 0; i < points->len; i++)
174     {
175       point = &(g_array_index (points, Point, i));
176       scale = g_array_index (scales, double, (i % scales->len));
177       point->rx = scale;
178       point->ry = scale;
179       point->x *= point->rx;
180       point->y *= point->ry;
181     }
182 }