2 #ifdef SIMAGE_AVIENC_SUPPORT
30 #pragma comment(lib, "vfw32.lib")
41 static void avi_init_context(avi_encode_context *context)
43 context->pfile = NULL;
45 context->pscomp = NULL;
46 context->framenumber = 0;
51 static void avi_cleanup_context(avi_encode_context *context)
54 AVIStreamRelease(context->pscomp);
55 context->pscomp = NULL;
58 AVIStreamRelease(context->ps);
62 AVIFileRelease(context->pfile);
63 context->pfile = NULL;
70 avi_begin_encode(
const char *filename,
int width,
int height,
int fps,
const char *preferences_filename)
73 avi_encode_context *context;
78 AVICOMPRESSOPTIONS opts;
79 AVICOMPRESSOPTIONS * aopts[1];
83 int prefsReadFromFile;
85 if ( (width % 4 != 0) || (height % 4 != 0) )
88 context = (avi_encode_context *) malloc(
sizeof(avi_encode_context));
89 avi_init_context(context);
91 context->width = width;
92 context->height = height;
97 hr = AVIFileOpen(&context->pfile , filename, OF_WRITE | OF_CREATE, NULL);
98 if (hr != AVIERR_OK) {
99 avi_cleanup_context(context);
112 rowsize = (width * numbits + 31) / 32 * 4;
113 imagesize = rowsize * height;
115 memset(&strhdr, 0,
sizeof(strhdr));
116 strhdr.fccType = streamtypeVIDEO;
117 strhdr.fccHandler = 0;
120 strhdr.dwSuggestedBufferSize = imagesize;
121 strhdr.rcFrame.left = 0;
122 strhdr.rcFrame.top = 0;
123 strhdr.rcFrame.right = width;
124 strhdr.rcFrame.bottom = height;
127 hr = AVIFileCreateStream(context->pfile, &context->ps, &strhdr);
128 if (hr != AVIERR_OK) {
129 avi_cleanup_context(context);
135 memset(&opts, 0,
sizeof(opts));
137 prefsReadFromFile = 0;
138 if ( (preferences_filename != NULL) && (strlen(preferences_filename)>0) ) {
141 file = fopen(preferences_filename,
"rb");
144 ret = AVISaveOptions(NULL, ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE, 1, &context->ps, (LPAVICOMPRESSOPTIONS *) &aopts);
147 avi_cleanup_context(context);
152 file = fopen(preferences_filename,
"wb");
154 avi_cleanup_context(context);
160 size = fwrite(&opts,
sizeof(AVICOMPRESSOPTIONS), 1, file);
163 size = fwrite(&opts.cbFormat, 4, 1, file);
166 size = fwrite(opts.lpFormat, opts.cbFormat, 1, file);
169 size = fwrite(&opts.cbParms, 4, 1, file);
172 size = fwrite(opts.lpParms, opts.cbParms, 1, file);
177 file = fopen(preferences_filename,
"rb");
179 avi_cleanup_context(context);
185 size = fread(&opts,
sizeof(AVICOMPRESSOPTIONS), 1, file);
188 size = fread(&opts.cbFormat, 4, 1, file);
191 opts.lpFormat = (
void *) malloc(opts.cbFormat);
192 size = fread(opts.lpFormat, opts.cbFormat, 1, file);
195 size = fread(&opts.cbParms, 4, 1, file);
198 opts.lpParms = (
void *) malloc(opts.cbParms);
199 size = fread(opts.lpParms, opts.cbParms, 1, file);
203 prefsReadFromFile = 1;
207 ret = AVISaveOptions(NULL, ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE, 1, &context->ps, (LPAVICOMPRESSOPTIONS *) &aopts);
210 avi_cleanup_context(context);
216 hr = AVIMakeCompressedStream( &context->pscomp, context->ps, &opts, NULL);
217 if (hr != AVIERR_OK) {
218 avi_cleanup_context(context);
223 if (prefsReadFromFile)
229 opts.lpFormat = NULL;
234 AVISaveOptionsFree(1, (LPAVICOMPRESSOPTIONS *) &aopts);
237 memset(&bi, 0,
sizeof(BITMAPINFO));
239 bi.bmiHeader.biSize =
sizeof(BITMAPINFOHEADER) ;
240 bi.bmiHeader.biWidth = width ;
241 bi.bmiHeader.biHeight = height ;
242 bi.bmiHeader.biPlanes = 1 ;
243 bi.bmiHeader.biBitCount = numbits ;
244 bi.bmiHeader.biCompression = BI_RGB ;
245 bi.bmiHeader.biSizeImage = imagesize ;
246 bi.bmiHeader.biXPelsPerMeter = 0 ;
247 bi.bmiHeader.biYPelsPerMeter = 0 ;
248 bi.bmiHeader.biClrUsed = (numbits <= 8) ? 1 << numbits : 0;
249 bi.bmiHeader.biClrImportant = 0 ;
251 hr = AVIStreamSetFormat(context->pscomp, 0, &bi, bi.bmiHeader.biSize + bi.bmiHeader.biClrUsed *
sizeof(RGBQUAD));
253 if (hr != AVIERR_OK) {
254 avi_cleanup_context(context);
259 return (
void *)context;
281 avi_encode_context *context;
283 context = (avi_encode_context *)handle;
288 int x, y, r, nc, w, h;
293 for (y=0; y<h; y++) {
294 r = buf[x * nc + y * nc * w + 0];
295 buf[x * nc + y * nc * w + 0] = buf[x * nc + y * nc * w + 2];
296 buf[x * nc + y * nc * w + 2] = r;
300 hr = AVIStreamWrite(context->pscomp,
301 context->framenumber,
304 context->width * context->height * 3,
316 context->framenumber++;
328 avi_encode_context *context;
330 context = (avi_encode_context *)handle;
331 avi_cleanup_context(context);
int avi_encode_bitmap(void *handle, unsigned char *buf, int rgb2bgr)
int avi_end_encode(void *handle)
void * avi_begin_encode(const char *filename, int width, int height, int fps, const char *preferences_filename)