summaryrefslogtreecommitdiff
path: root/noncore/multimedia/camera/avi.c
Unidiff
Diffstat (limited to 'noncore/multimedia/camera/avi.c') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/camera/avi.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/noncore/multimedia/camera/avi.c b/noncore/multimedia/camera/avi.c
new file mode 100644
index 0000000..0c757c9
--- a/dev/null
+++ b/noncore/multimedia/camera/avi.c
@@ -0,0 +1,235 @@
1/**********************************************************************
2** Copyright (C) 2003 Michael 'Mickey' Lauer. All rights reserved.
3** Based on work from Andrew Tridgell and the jpegtoavi project
4**
5** This file is part of Opie Environment.
6**
7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file.
11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14**
15**********************************************************************/
16
17#include "avi.h"
18
19#include <string.h>
20#include <stdio.h>
21
22int nframes;
23int totalsize;
24unsigned int* sizes;
25
26void fprint_quartet(int fd, unsigned int i)
27{
28 char data[4];
29
30 data[0] = (char) i%0x100;
31 i /= 0x100;
32 data[1] = (char) i%0x100;
33 i /= 0x100;
34 data[2] = (char) i%0x100;
35 i /= 0x100;
36 data[3] = (char) i%0x100;
37
38 write( fd, &data, 4 );
39}
40
41// start writing an AVI file
42
43void avi_start(int fd, int frames)
44{
45 int ofs = sizeof(struct riff_head)+
46 sizeof(struct list_head)+
47 sizeof(struct avi_head)+
48 sizeof(struct list_head)+
49 sizeof(struct stream_head)+
50 sizeof(struct frame_head)+
51 sizeof(struct list_head)+
52 sizeof(struct dmlh_head)+
53 sizeof(struct list_head);
54
55 printf( "avi_start: frames = %d\n", frames );
56
57 lseek(fd, ofs, SEEK_SET);
58
59 nframes = 0;
60 totalsize = 0;
61
62 sizes = (unsigned int*) calloc( sizeof(unsigned int), frames ); // hold size of each frame
63}
64
65// add a jpeg frame to an AVI file
66void avi_add(int fd, u8 *buf, int size)
67{
68 struct db_head db = {"00db", 0};
69
70 printf( "avi_add: nframes = %d, totalsize = %d, size = %d\n", nframes, totalsize, size );
71
72 // overwrite JFIF type with AVI1
73 buf[6]='A';
74 buf[7]='V';
75 buf[8]='I';
76 buf[9]='1';
77
78 while( size%4 ) size++; // align 0 modulo 4*/
79 db.size = size;
80
81 write( fd, &db, sizeof(db) );
82 write( fd, buf, size );
83
84 sizes[nframes] = size;
85
86 nframes++;
87 totalsize += size; // total frame size
88}
89
90// finish writing the AVI file - filling in the header
91void avi_end(int fd, int width, int height, int fps)
92{
93 struct idx1_head idx = {"idx1", 16*nframes };
94 struct db_head db = {"00db", 0};
95 struct riff_head rh = { "RIFF", 0, "AVI "};
96 struct list_head lh1 = {"LIST", 0, "hdrl"};
97 struct avi_head ah;
98 struct list_head lh2 = {"LIST", 0, "strl"};
99 struct stream_head sh;
100 struct frame_head fh;
101 struct list_head lh3 = {"LIST", 0, "odml" };
102 struct dmlh_head dh = {"dmlh", 4, nframes };
103 struct list_head lh4 = {"LIST", 0, "movi"};
104 int i;
105 unsigned int offset = 4;
106
107 printf( "avi_end: nframes = %d, fps = %d\n", nframes, fps );
108
109 // write index
110
111 write(fd, &idx, sizeof(idx));
112
113 for ( i = 0; i < nframes; i++ )
114 {
115 write(fd, &db, 4 ); // only need the 00db
116 fprint_quartet( fd, 18 ); // ???
117 fprint_quartet( fd, offset );
118 fprint_quartet( fd, sizes[i] );
119 offset += sizes[i];
120 }
121
122 free( sizes );
123
124 bzero( &ah, sizeof(ah) );
125 strcpy(ah.avih, "avih");
126 ah.time = 1000000 / fps;
127 ah.maxbytespersec = 1000000.0*(totalsize/nframes)/ah.time;
128 ah.numstreams = 1;
129 ah.flags = AVIF_HASINDEX;
130 ah.width = width;
131 ah.height = height;
132
133 bzero(&sh, sizeof(sh));
134 strcpy(sh.strh, "strh");
135 strcpy(sh.vids, "vids");
136 strcpy(sh.codec, "MJPG");
137 sh.scale = ah.time;
138 sh.rate = 1000000;
139 sh.length = nframes;
140
141 bzero(&fh, sizeof(fh));
142 strcpy(fh.strf, "strf");
143 fh.width = width;
144 fh.height = height;
145 fh.planes = 1;
146 fh.bitcount = 24;
147 strcpy(fh.codec,"MJPG");
148 fh.unpackedsize = 3*width*height;
149
150 rh.size = sizeof(lh1)+sizeof(ah)+sizeof(lh2)+sizeof(sh)+
151 sizeof(fh)+sizeof(lh3)+sizeof(dh)+sizeof(lh4)+
152 nframes*sizeof(struct db_head)+
153 totalsize + sizeof(struct idx1_head)+ (16*nframes) +4; // FIXME:16 bytes per nframe // the '4' - what for???
154
155 lh1.size = 4+sizeof(ah)+sizeof(lh2)+sizeof(sh)+sizeof(fh)+sizeof(lh3)+sizeof(dh);
156 ah.size = sizeof(ah)-8;
157 lh2.size = 4+sizeof(sh)+sizeof(fh)+sizeof(lh3)+sizeof(dh); //4+sizeof(sh)+sizeof(fh);
158 sh.size = sizeof(sh)-8;
159 fh.size = sizeof(fh)-8;
160 fh.size2 = fh.size;
161 lh3.size = 4+sizeof(dh);
162 lh4.size = 4+ nframes*sizeof(struct db_head)+ totalsize;
163
164 lseek(fd, 0, SEEK_SET);
165
166 write(fd, &rh, sizeof(rh));
167 write(fd, &lh1, sizeof(lh1));
168 write(fd, &ah, sizeof(ah));
169 write(fd, &lh2, sizeof(lh2));
170 write(fd, &sh, sizeof(sh));
171 write(fd, &fh, sizeof(fh));
172 write(fd, &lh3, sizeof(lh3));
173 write(fd, &dh, sizeof(dh));
174 write(fd, &lh4, sizeof(lh4));
175}
176
177
178/* NOTE: This is not a general purpose routine - it is meant to only
179 cope with AVIs saved using the other functions in this file
180void avi_explode(char *fname)
181{
182 struct riff_head rh;
183 struct list_head lh1;
184 struct avi_head ah;
185 struct list_head lh2;
186 struct stream_head sh;
187 struct frame_head fh;
188 struct list_head lh3;
189 int hsize, qsize;
190 u16 *htables = jpeg_huffman_tables(&hsize);
191 u16 *qtables = jpeg_quantisation_tables(&qsize, image_quality);
192 int fd, i;
193
194 fd = open(fname,O_RDONLY);
195 if (fd == -1) {
196 perror(fname);
197 return;
198 }
199
200 read(fd, &rh, sizeof(rh));
201 read(fd, &lh1, sizeof(lh1));
202 read(fd, &ah, sizeof(ah));
203 read(fd, &lh2, sizeof(lh2));
204 read(fd, &sh, sizeof(sh));
205 read(fd, &fh, sizeof(fh));
206 read(fd, &lh3, sizeof(lh3));
207
208 for (i=0; ; i++) {
209 u8 buf[500*1024];
210 struct db_head db;
211 char fname[100];
212 int fd2;
213
214 if (read(fd, &db, sizeof(db)) != sizeof(db) ||
215 read(fd, buf, db.size) != db.size) break;
216
217 snprintf(fname, sizeof(fname)-1,"frame.%d", i);
218
219 fd2 = open(fname,O_WRONLY|O_CREAT, 0644);
220 if (fd2 == -1) {
221 perror(fname);
222 continue;
223 }
224 write(fd2, buf, 2);
225 write(fd2, qtables, qsize);
226 write(fd2, htables, hsize);
227 write(fd2, buf+2, db.size-2);
228 close(fd2);
229 }
230 close(fd);
231 printf("exploded %d frames\n", i);
232}
233
234*/
235