summaryrefslogtreecommitdiff
path: root/noncore/multimedia/camera/lib/avi.c
Unidiff
Diffstat (limited to 'noncore/multimedia/camera/lib/avi.c') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/camera/lib/avi.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/noncore/multimedia/camera/lib/avi.c b/noncore/multimedia/camera/lib/avi.c
new file mode 100644
index 0000000..77aba33
--- a/dev/null
+++ b/noncore/multimedia/camera/lib/avi.c
@@ -0,0 +1,236 @@
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] + 8; //+8 (for the additional header)
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.nframes = nframes;
129 ah.numstreams = 1;
130 ah.flags = AVIF_HASINDEX;
131 ah.width = width;
132 ah.height = height;
133
134 bzero(&sh, sizeof(sh));
135 strcpy(sh.strh, "strh");
136 strcpy(sh.vids, "vids");
137 strcpy(sh.codec, "MJPG");
138 sh.scale = ah.time;
139 sh.rate = 1000000;
140 sh.length = nframes;
141
142 bzero(&fh, sizeof(fh));
143 strcpy(fh.strf, "strf");
144 fh.width = width;
145 fh.height = height;
146 fh.planes = 1;
147 fh.bitcount = 24;
148 strcpy(fh.codec,"MJPG");
149 fh.unpackedsize = 3*width*height;
150
151 rh.size = sizeof(lh1)+sizeof(ah)+sizeof(lh2)+sizeof(sh)+
152 sizeof(fh)+sizeof(lh3)+sizeof(dh)+sizeof(lh4)+
153 nframes*sizeof(struct db_head)+
154 totalsize + sizeof(struct idx1_head)+ (16*nframes) +4; // FIXME:16 bytes per nframe // the '4' - what for???
155
156 lh1.size = 4+sizeof(ah)+sizeof(lh2)+sizeof(sh)+sizeof(fh)+sizeof(lh3)+sizeof(dh);
157 ah.size = sizeof(ah)-8;
158 lh2.size = 4+sizeof(sh)+sizeof(fh)+sizeof(lh3)+sizeof(dh); //4+sizeof(sh)+sizeof(fh);
159 sh.size = sizeof(sh)-8;
160 fh.size = sizeof(fh)-8;
161 fh.size2 = fh.size;
162 lh3.size = 4+sizeof(dh);
163 lh4.size = 4+ nframes*sizeof(struct db_head)+ totalsize;
164
165 lseek(fd, 0, SEEK_SET);
166
167 write(fd, &rh, sizeof(rh));
168 write(fd, &lh1, sizeof(lh1));
169 write(fd, &ah, sizeof(ah));
170 write(fd, &lh2, sizeof(lh2));
171 write(fd, &sh, sizeof(sh));
172 write(fd, &fh, sizeof(fh));
173 write(fd, &lh3, sizeof(lh3));
174 write(fd, &dh, sizeof(dh));
175 write(fd, &lh4, sizeof(lh4));
176}
177
178
179/* NOTE: This is not a general purpose routine - it is meant to only
180 cope with AVIs saved using the other functions in this file
181void avi_explode(char *fname)
182{
183 struct riff_head rh;
184 struct list_head lh1;
185 struct avi_head ah;
186 struct list_head lh2;
187 struct stream_head sh;
188 struct frame_head fh;
189 struct list_head lh3;
190 int hsize, qsize;
191 u16 *htables = jpeg_huffman_tables(&hsize);
192 u16 *qtables = jpeg_quantisation_tables(&qsize, image_quality);
193 int fd, i;
194
195 fd = open(fname,O_RDONLY);
196 if (fd == -1) {
197 perror(fname);
198 return;
199 }
200
201 read(fd, &rh, sizeof(rh));
202 read(fd, &lh1, sizeof(lh1));
203 read(fd, &ah, sizeof(ah));
204 read(fd, &lh2, sizeof(lh2));
205 read(fd, &sh, sizeof(sh));
206 read(fd, &fh, sizeof(fh));
207 read(fd, &lh3, sizeof(lh3));
208
209 for (i=0; ; i++) {
210 u8 buf[500*1024];
211 struct db_head db;
212 char fname[100];
213 int fd2;
214
215 if (read(fd, &db, sizeof(db)) != sizeof(db) ||
216 read(fd, buf, db.size) != db.size) break;
217
218 snprintf(fname, sizeof(fname)-1,"frame.%d", i);
219
220 fd2 = open(fname,O_WRONLY|O_CREAT, 0644);
221 if (fd2 == -1) {
222 perror(fname);
223 continue;
224 }
225 write(fd2, buf, 2);
226 write(fd2, qtables, qsize);
227 write(fd2, htables, hsize);
228 write(fd2, buf+2, db.size-2);
229 close(fd2);
230 }
231 close(fd);
232 printf("exploded %d frames\n", i);
233}
234
235*/
236