1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup avi
22  *
23  * \section avi_about About the AVI module
24  *
25  * This is external code. It provides avi file import/export and
26  * conversions. It has been adapted to make use of Blender memory
27  * management functions, and because of this it needs module
28  * blenlib. You need to provide this lib when linking with libavi.a .
29  *
30  * \subsection avi_issues Known issues with AVI
31  *
32  * - avi uses #MEM_mallocN, #MEM_freeN from blenlib.
33  * - Not all functions that are used externally are properly
34  *   prototyped.
35  *
36  * This header has not been split, since it interleaves type defines
37  * and functions. You would need the types to be able to include the
38  * function headers anyway. And, after all, it is someone else's
39  * code. So we keep it like this.
40  */
41 
42 #pragma once
43 
44 #include "BLI_sys_types.h"
45 #include <stdio.h> /* for FILE */
46 
47 typedef struct _AviChunk {
48   int fcc;
49   int size;
50 } AviChunk;
51 
52 typedef struct _AviList {
53   int fcc;
54   int size;
55   int ids;
56 } AviList;
57 
58 typedef struct _AviMainHeader {
59   int fcc;
60   int size;
61   int MicroSecPerFrame; /* MicroSecPerFrame - timing between frames */
62   int MaxBytesPerSec;   /* MaxBytesPerSec - approx bps system must handle */
63   int PaddingGranularity;
64   int Flags;
65 
66   /** had idx1 chunk */
67 #define AVIF_HASINDEX 0x00000010
68   /** must use idx1 chunk to determine order */
69 #define AVIF_MUSTUSEINDEX 0x00000020
70   /** AVI file is interleaved */
71 #define AVIF_ISINTERLEAVED 0x00000100
72 #define AVIF_TRUSTCKTYPE 0x00000800
73   /** specially allocated used for capturing real time video */
74 #define AVIF_WASCAPTUREFILE 0x00010000
75   /** contains copyrighted data */
76 #define AVIF_COPYRIGHTED 0x00020000
77 
78   int TotalFrames;
79   int InitialFrames; /* InitialFrames - initial frame before interleaving */
80   int Streams;
81   int SuggestedBufferSize;
82   int Width;
83   int Height;
84   int Reserved[4];
85 } AviMainHeader;
86 
87 typedef struct _AviStreamHeader {
88   int fcc;
89   int size;
90   int Type;
91 #define AVIST_VIDEO FCC("vids")
92 #define AVIST_AUDIO FCC("auds")
93 #define AVIST_MIDI FCC("mids")
94 #define AVIST_TEXT FCC("txts")
95 
96   int Handler;
97   int Flags;
98 #define AVISF_DISABLED 0x00000001
99 #define AVISF_VIDEO_PALCHANGES 0x00010000
100 
101   short Priority;
102   short Language;
103   int InitialFrames;
104   int Scale;
105   int Rate;
106   int Start;
107   int Length;
108   int SuggestedBufferSize;
109   int Quality;
110   int SampleSize;
111   short left;
112   short top;
113   short right;
114   short bottom;
115 } AviStreamHeader;
116 
117 typedef struct _AviBitmapInfoHeader {
118   int fcc;
119   int size;
120   int Size;
121   int Width;
122   int Height;
123   short Planes;
124   short BitCount;
125   int Compression;
126   int SizeImage;
127   int XPelsPerMeter;
128   int YPelsPerMeter;
129   int ClrUsed;
130   int ClrImportant;
131 } AviBitmapInfoHeader;
132 
133 typedef struct _AviMJPEGUnknown {
134   int a;
135   int b;
136   int c;
137   int d;
138   int e;
139   int f;
140   int g;
141 } AviMJPEGUnknown;
142 
143 typedef struct _AviIndexEntry {
144   int ChunkId;
145   int Flags;
146 #define AVIIF_LIST 0x00000001
147 #define AVIIF_KEYFRAME 0x00000010
148 #define AVIIF_NO_TIME 0x00000100
149 #define AVIIF_COMPRESSOR 0x0FFF0000
150   int Offset;
151   int Size;
152 } AviIndexEntry;
153 
154 typedef struct _AviIndex {
155   int fcc;
156   int size;
157   AviIndexEntry *entrys;
158 } AviIndex;
159 
160 typedef enum {
161   /** The most basic of forms, 3 bytes per pixel, 1 per r, g, b. */
162   AVI_FORMAT_RGB24,
163   /** The second most basic of forms, 4 bytes per pixel, 1 per r, g, b, alpha. */
164   AVI_FORMAT_RGB32,
165   /** Same as above, but is in the weird AVI order (bottom to top, left to right). */
166   AVI_FORMAT_AVI_RGB,
167   /** Motion-JPEG. */
168   AVI_FORMAT_MJPEG,
169 } AviFormat;
170 
171 typedef struct _AviStreamRec {
172   AviStreamHeader sh;
173   void *sf;
174   int sf_size;
175   AviFormat format;
176 } AviStreamRec;
177 
178 typedef struct _AviMovie {
179   FILE *fp;
180 
181   int type;
182 #define AVI_MOVIE_READ 0
183 #define AVI_MOVIE_WRITE 1
184 
185   int64_t size;
186 
187   AviMainHeader *header;
188   AviStreamRec *streams;
189   AviIndexEntry *entries;
190   int index_entries;
191 
192   int64_t movi_offset;
193   int64_t read_offset;
194   int64_t *offset_table;
195 
196   /* Local data goes here */
197   int interlace;
198   int odd_fields;
199 } AviMovie;
200 
201 typedef enum {
202   AVI_ERROR_NONE = 0,
203   AVI_ERROR_COMPRESSION,
204   AVI_ERROR_OPEN,
205   AVI_ERROR_READING,
206   AVI_ERROR_WRITING,
207   AVI_ERROR_FORMAT,
208   AVI_ERROR_ALLOC,
209   AVI_ERROR_FOUND,
210   AVI_ERROR_OPTION,
211 } AviError;
212 
213 /* belongs to the option-setting function. */
214 typedef enum {
215   AVI_OPTION_WIDTH = 0,
216   AVI_OPTION_HEIGHT,
217   AVI_OPTION_QUALITY,
218   AVI_OPTION_FRAMERATE,
219 } AviOption;
220 
221 /* The offsets that will always stay the same in AVI files we
222  * write... used to seek around to the places where we need to write
223  * the sizes */
224 
225 #define AVI_RIFF_SOFF 4L
226 #define AVI_HDRL_SOFF 16L
227 
228 /**
229  * This is a sort of MAKE_ID thing. Used in imbuf :( It is used
230  * through options in the AVI header (AviStreamHeader). */
231 #define FCC(ch4) (ch4[0] | ch4[1] << 8 | ch4[2] << 16 | ch4[3] << 24)
232 
233 /**
234  * Test whether this is an avi-format.
235  */
236 bool AVI_is_avi(const char *name);
237 
238 /**
239  * Open a compressed file, decompress it into memory.
240  */
241 AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...);
242 
243 /**
244  * Finalize a compressed output stream.
245  */
246 AviError AVI_close_compress(AviMovie *movie);
247 
248 /**
249  * Choose a compression option for \<movie\>. Possible options are
250  * AVI_OPTION_TYPE_MAIN, AVI_OPTION_TYPE_STRH, AVI_OPTION_TYPE_STRF
251  */
252 AviError AVI_set_compress_option(
253     AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data);
254 /* Hmmm... there should be some explanation about what these mean */
255 /**
256  * Compression option, for use in avi_set_compress_option
257  */
258 #define AVI_OPTION_TYPE_MAIN 0
259 /**
260  * Compression option, for use in avi_set_compress_option
261  */
262 #define AVI_OPTION_TYPE_STRH 1
263 /**
264  * Compression option, for use in avi_set_compress_option
265  */
266 #define AVI_OPTION_TYPE_STRF 2
267 
268 /**
269  * Direct the streams \<avist_type\> to \<movie\>. Redirect \<stream_num\>
270  * streams.
271  */
272 int AVI_get_stream(AviMovie *movie, int avist_type, int stream_num);
273 
274 /**
275  * Open a movie stream from file.
276  */
277 AviError AVI_open_movie(const char *name, AviMovie *movie);
278 
279 /**
280  * Read a frame from a movie stream.
281  */
282 void *AVI_read_frame(AviMovie *movie, AviFormat format, int frame, int stream);
283 /**
284  * Close an open movie stream.
285  */
286 AviError AVI_close(AviMovie *movie);
287 
288 /**
289  * Write frames to a movie stream.
290  */
291 AviError AVI_write_frame(AviMovie *movie, int frame_num, ...);
292 
293 /**
294  * Unused but still external
295  */
296 AviError AVI_print_error(AviError error);
297