Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
AviFile.cpp
Go to the documentation of this file.
1 /* Project nGenEx
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: nGenEx.lib
6  FILE: AviFile.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  AviFile reader / writer
13 */
14 
15 
16 #include "MemDebug.h"
17 #include "AviFile.h"
18 
19 #include <vfw.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 
23 // +--------------------------------------------------------------------+
24 
25 void Print(const char* fmt, ...);
26 
27 // +--------------------------------------------------------------------+
28 
29 AviFile::AviFile(const char* fname)
30 : filename(fname), fps(0), play(true), pfile(0), ps(0), ps_comp(0),
31 nframe(0), nsamp(0), iserr(false), frame_size(0)
32 {
33  AVIFileInit();
34 }
35 
36 AviFile::AviFile(const char* fname, const Rect& r, int frame_rate)
37 : filename(fname), rect(r), fps(frame_rate), play(false), pfile(0),
38 ps(0), ps_comp(0), nframe(0), nsamp(0), iserr(false)
39 {
40  Print("\n\nAviFile(%s, w=%d, h=%d, f=%d FPS)\n", fname, r.w, r.h, fps);
41  frame_size = r.w * r.h * 3;
42 
43  AVIFileInit();
44  HRESULT hr = AVIFileOpen(&pfile, fname, OF_WRITE|OF_CREATE, 0);
45 
46  if (hr != AVIERR_OK) {
47  Print("AviFile - open failed. %08x\n", hr);
48  iserr = true;
49  return;
50  }
51 
52  Print("AviFile - open successful\n");
53 
54  AVISTREAMINFO strhdr;
55  ZeroMemory(&strhdr,sizeof(strhdr));
56 
57  strhdr.fccType = streamtypeVIDEO;
58  strhdr.fccHandler = 0;
59  strhdr.dwScale = 1000 / fps;
60  strhdr.dwRate = 1000;
61  strhdr.dwSuggestedBufferSize = frame_size;
62 
63  SetRect(&strhdr.rcFrame, 0, 0, r.w, r.h);
64 
65  hr = AVIFileCreateStream(pfile, &ps, &strhdr);
66 
67  if (hr != AVIERR_OK) {
68  Print("AviFile - create stream failed. %08x\n", hr);
69  iserr = true;
70  return;
71  }
72 
73  Print("AviFile - create stream successful\n");
74 
75  AVICOMPRESSOPTIONS opts;
76  ZeroMemory(&opts,sizeof(opts));
77  opts.fccType = streamtypeVIDEO;
78  //opts.fccHandler = mmioFOURCC('W','M','V','3');
79  opts.fccHandler = mmioFOURCC('D','I','B',' '); // (full frames)
80  opts.dwFlags = 8;
81 
82  hr = AVIMakeCompressedStream(&ps_comp, ps, &opts, 0);
83  if (hr != AVIERR_OK) {
84  Print("AviFile - compressed stream failed. %08x\n", hr);
85  iserr=true;
86  return;
87  }
88 
89  Print("AviFile - make compressed stream successful\n");
90 
91  BITMAPINFOHEADER bmih;
92  ZeroMemory(&bmih, sizeof(BITMAPINFOHEADER));
93 
94  bmih.biSize = sizeof(BITMAPINFOHEADER);
95  bmih.biBitCount = 24;
96  bmih.biCompression = BI_RGB;
97  bmih.biWidth = rect.w;
98  bmih.biHeight = rect.h;
99  bmih.biPlanes = 1;
100  bmih.biSizeImage = frame_size;
101 
102  hr = AVIStreamSetFormat(ps_comp, 0, &bmih, sizeof(BITMAPINFOHEADER));
103 
104  if (hr != AVIERR_OK) {
105  Print("AviFile - stream format failed. %08x\n", hr);
106  iserr=true;
107  return;
108  }
109 
110  Print("AviFile - stream format successful\n");
111 }
112 
114 {
115  if (!play) {
116  Print("*** Closing AVI file '%s' with %d frames\n", (const char*) filename, nframe);
117  }
118 
119  if (ps_comp) AVIStreamRelease(ps_comp);
120  if (ps) AVIStreamRelease(ps);
121  if (pfile) AVIFileRelease(pfile);
122 
123  AVIFileExit();
124 }
125 
126 // +--------------------------------------------------------------------+
127 //
128 // Note that AVI frames use DIB format - Y is inverted.
129 // So we need to flip the native bmp before sending to the
130 // file.
131 
132 HRESULT
134 {
135  HRESULT hr = E_FAIL;
136 
137  if (!iserr && !play && bmp.IsHighColor() && bmp.Width() == rect.w && bmp.Height() == rect.h) {
138  int w = bmp.Width();
139  int h = bmp.Height();
140  BYTE* buffer = new(__FILE__,__LINE__) BYTE[frame_size];
141  BYTE* dst = buffer;
142 
143  for (int y = 0; y < bmp.Height(); y++) {
144  Color* src = bmp.HiPixels() + (h - 1 - y) * w;
145 
146  for (int x = 0; x < bmp.Width(); x++) {
147  *dst++ = (BYTE) src->Blue();
148  *dst++ = (BYTE) src->Green();
149  *dst++ = (BYTE) src->Red();
150  src++;
151  }
152  }
153 
154 #pragma warning(suppress: 6001)
155  hr = AVIStreamWrite(ps_comp, nframe, 1, buffer, frame_size, AVIIF_KEYFRAME, 0, 0);
156 
157  if (SUCCEEDED(hr)) {
158  nframe++;
159  }
160  else {
161  Print("AVIStreamWriteFile failed. %08x\n", hr);
162  iserr = true;
163  }
164 
165  delete [] buffer;
166  }
167 
168  return hr;
169 }
170 
171 // +--------------------------------------------------------------------+
172 
173 HRESULT
174 AviFile::GetFrame(double seconds, Bitmap& bmp)
175 {
176  HRESULT hr = E_FAIL;
177  return hr;
178 }
179