1 /*
2   Note 20020923 thammer:
3   movie.c should probably be rewritten to use stream.c.
4   If you are considering modifying movie.c, please discuss it
5   with coin@sim.no first.
6 
7  */
8 
9 #include <assert.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 #ifdef HAVE_CONFIG_H
14 #include <config.h>
15 #endif /* HAVE_CONFIG_H */
16 #include <simage.h>
17 #include <simage_private.h>
18 #include <string.h>
19 
20 #ifdef SIMAGE_MPEG2ENC_SUPPORT
21 #include "../mpeg2enc/api.h"
22 #endif /* SIMAGE_MPEG2ENC_SUPPORT */
23 
24 #ifdef SIMAGE_AVIENC_SUPPORT
25 #include "simage_avi.h"
26 #endif /* SIMAGE_AVIENC_SUPPORT */
27 
28 struct simage_movie_s {
29   char * filename;
30 
31   s_movie_open_func * open;
32   s_movie_create_func * create;
33   s_movie_get_func * get;
34   s_movie_put_func * put;
35   s_movie_close_func * close;
36 
37   s_params * params;
38 };
39 
40 struct simage_movie_importer {
41   s_movie_open_func * open;
42   s_movie_get_func * get;
43   s_movie_close_func * close;
44 
45   struct simage_movie_importer * next;
46 };
47 
48 struct simage_movie_exporter {
49   s_movie_create_func * create;
50   s_movie_put_func * put;
51   s_movie_close_func * close;
52 
53   struct simage_movie_exporter * next;
54 };
55 
56 // FIXME: convert access to these variables into the singleton
57 // pattern. 20010917 mortene.
58 static struct simage_movie_importer * importers;
59 static struct simage_movie_exporter * exporters;
60 
61 static void
add_internal_importers(void)62 add_internal_importers(void)
63 {
64   static int first = 1;
65   if (first) {
66     /* none yet */
67     first = 0;
68   }
69 }
70 
71 static void
add_internal_exporters(void)72 add_internal_exporters(void)
73 {
74   static int first = 1;
75   if (first) {
76 #ifdef SIMAGE_MPEG2ENC_SUPPORT
77     s_movie_exporter_add(mpeg2enc_movie_create,
78                          mpeg2enc_movie_put,
79                          mpeg2enc_movie_close);
80 #endif
81 #ifdef SIMAGE_AVIENC_SUPPORT
82     s_movie_exporter_add(avienc_movie_create,
83                          avienc_movie_put,
84                          avienc_movie_close);
85 #endif
86    first = 0;
87   }
88 }
89 
90 s_movie *
s_movie_open(const char * filename)91 s_movie_open(const char * filename)
92 {
93   struct simage_movie_importer * imp;
94   s_movie * movie = (s_movie*) malloc(sizeof(s_movie));
95   movie->params = NULL;
96   movie->filename = NULL;
97 
98   add_internal_importers();
99 
100   imp = importers;
101   while (imp) {
102     if (imp->open(filename, movie)) break;
103     imp = imp->next;
104   }
105   if (imp == NULL) {
106     free((void*)movie);
107     return NULL;
108   }
109 
110   movie->filename = (char*) malloc(strlen(filename)+1);
111   strcpy(movie->filename, filename);
112   movie->open = imp->open;
113   movie->get = imp->get;
114   movie->close = imp->close;
115 
116   return movie;
117 }
118 
119 s_movie *
s_movie_create(const char * filename,s_params * params)120 s_movie_create(const char * filename, s_params * params /* | NULL */)
121 {
122   struct simage_movie_exporter * exp;
123   s_movie * movie = (s_movie*) malloc(sizeof(s_movie));
124   movie->params = NULL;
125   movie->filename = NULL;
126 
127   add_internal_exporters();
128 
129   exp = exporters;
130   while (exp) {
131     if (exp->create(filename, movie, params)) break;
132     exp = exp->next;
133   }
134   if (exp == NULL) {
135     free((void*) movie);
136     return NULL;
137   }
138 
139   movie->filename = (char*) malloc(strlen(filename)+1);
140   movie->create = exp->create;
141   movie->put = exp->put;
142   movie->close = exp->close;
143   strcpy(movie->filename, filename);
144   return movie;
145 }
146 
147 s_image *
s_movie_get_image(s_movie * movie,s_image * prealloc,s_params * params)148 s_movie_get_image(s_movie * movie, s_image * prealloc, s_params * params)
149 {
150   return movie->get(movie, prealloc, params);
151 }
152 
153 int
s_movie_put_image(s_movie * movie,s_image * image,s_params * params)154 s_movie_put_image(s_movie * movie, s_image * image,
155                   s_params * params)
156 {
157   return movie->put(movie, image, params);
158 }
159 
160 void
s_movie_close(s_movie * movie)161 s_movie_close(s_movie * movie)
162 {
163   movie->close(movie);
164 }
165 
166 void
s_movie_destroy(s_movie * movie)167 s_movie_destroy(s_movie * movie)
168 {
169   if (movie->params) s_params_destroy(movie->params);
170   if (movie->filename) free((void*) movie->filename);
171   free((void*) movie);
172 }
173 
174 s_params *
s_movie_params(s_movie * movie)175 s_movie_params(s_movie * movie)
176 {
177   if (movie->params == NULL) {
178     movie->params = s_params_create();
179   }
180   return movie->params;
181 }
182 
183 void
s_movie_importer_add(s_movie_open_func * open,s_movie_get_func * get,s_movie_close_func * close)184 s_movie_importer_add(s_movie_open_func * open,
185                      s_movie_get_func * get,
186                      s_movie_close_func * close)
187 {
188   struct simage_movie_importer * last, * imp = importers;
189   last = NULL;
190   while (imp) {
191     last = imp;
192     imp = imp->next;
193   }
194   imp = (struct simage_movie_importer*) malloc(sizeof(struct simage_movie_importer));
195   imp->open = open;
196   imp->get = get;
197   imp->close = close;
198   imp->next = NULL;
199 
200   if (last == NULL) {
201     importers = imp;
202   }
203   else last->next = imp;
204 }
205 
206 void
s_movie_exporter_add(s_movie_create_func * create,s_movie_put_func * put,s_movie_close_func * close)207 s_movie_exporter_add(s_movie_create_func * create,
208                      s_movie_put_func * put,
209                      s_movie_close_func * close)
210 {
211   struct simage_movie_exporter * last, * exp = exporters;
212   last = NULL;
213   while (exp) {
214     last = exp;
215     exp = exp->next;
216   }
217   exp = (struct simage_movie_exporter*) malloc(sizeof(struct simage_movie_exporter));
218   exp->create = create;
219   exp->put = put;
220   exp->close = close;
221   exp->next = NULL;
222 
223   if (last == NULL) {
224     exporters = exp;
225   }
226   else last->next = exp;
227 }
228