1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 //		QUIKTIME.H		QuickTime file access
20 //		Rex E. Bradford
21 
22 /*
23  * $Source: r:/prj/lib/src/afile/RCS/quiktime.h $
24  * $Revision: 1.4 $
25  * $Author: rex $
26  * $Date: 1994/10/04 20:31:57 $
27  * $Log: quiktime.h $
28  * Revision 1.4  1994/10/04  20:31:57  rex
29  * Added depth16 flag and macro to set it
30  *
31  * Revision 1.3  1994/09/30  16:57:34  rex
32  * Added stuff for writing quicktime movies
33  *
34  * Revision 1.2  1994/09/29  10:34:57  rex
35  * Put globals into a single struct, revamped prototypes, added writing
36  *
37  * Revision 1.1  1994/09/27  17:23:17  rex
38  * Initial revision
39  *
40  */
41 
42 #ifndef __QUIKTIME_H
43 #define __QUIKTIME_H
44 
45 #include <stdio.h>
46 
47 #ifndef __TYPES_H
48 #include "lg_types.h"
49 #endif
50 #ifndef __FIX_H
51 #include "fix.h"
52 #endif
53 #ifndef __2D_H
54 #include "2d.h"
55 #endif
56 
57 //	Data types
58 
59 typedef short fix8;     // 8.8 fixed-point number
60 typedef ulong QT_Ctype; // quicktime chunk type
61 
62 typedef struct {
63   ulong length;   // chunk length
64   QT_Ctype ctype; // chunk type
65 } QT_ChunkHdr;
66 
67 typedef struct {
68   ulong ctype;  // chunk type
69   uchar isleaf; // is leaf chunk, or are there subchunks
70 } QT_ChunkInfo;
71 
72 typedef struct {
73   uchar len;   // pascal strings start with length byte
74   char str[1]; // followed by string
75 } PStr;
76 
77 //	4-char chunk mnemonics
78 
79 #define MAKE4(c0, c1, c2, c3) ((((ulong)c0) << 24) | (((ulong)c1) << 16) | (((ulong)c2) << 8) | ((ulong)c3))
80 
81 #define QT_CLIP MAKE4('c', 'l', 'i', 'p')
82 #define QT_CRGN MAKE4('c', 'r', 'g', 'n')
83 #define QT_DINF MAKE4('d', 'i', 'n', 'f')
84 #define QT_DREF MAKE4('d', 'r', 'e', 'f')
85 #define QT_EDTS MAKE4('e', 'd', 't', 's')
86 #define QT_ELST MAKE4('e', 'l', 's', 't')
87 #define QT_HDLR MAKE4('h', 'd', 'l', 'r')
88 #define QT_KMAT MAKE4('k', 'm', 'a', 't')
89 #define QT_MATT MAKE4('m', 'a', 't', 't')
90 #define QT_MDAT MAKE4('m', 'd', 'a', 't')
91 #define QT_MDIA MAKE4('m', 'd', 'i', 'a')
92 #define QT_MDHD MAKE4('m', 'd', 'h', 'd')
93 #define QT_MINF MAKE4('m', 'i', 'n', 'f')
94 #define QT_MOOV MAKE4('m', 'o', 'o', 'v')
95 #define QT_MVHD MAKE4('m', 'v', 'h', 'd')
96 #define QT_SMHD MAKE4('s', 'm', 'h', 'd')
97 #define QT_STBL MAKE4('s', 't', 'b', 'l')
98 #define QT_STCO MAKE4('s', 't', 'c', 'o')
99 #define QT_STSC MAKE4('s', 't', 's', 'c')
100 #define QT_STSD MAKE4('s', 't', 's', 'd')
101 #define QT_STSH MAKE4('s', 't', 's', 'h')
102 #define QT_STSS MAKE4('s', 't', 's', 's')
103 #define QT_STSZ MAKE4('s', 't', 's', 'z')
104 #define QT_STTS MAKE4('s', 't', 't', 's')
105 #define QT_TKHD MAKE4('t', 'k', 'h', 'd')
106 #define QT_TRAK MAKE4('t', 'r', 'a', 'k')
107 #define QT_UDTA MAKE4('u', 'd', 't', 'a')
108 #define QT_VMHD MAKE4('v', 'm', 'h', 'd')
109 
110 //	Auxiliary structures
111 
112 // typedef struct {
113 //	uchar len;
114 //	uchar str[31];
115 //} Str31;
116 
117 typedef struct {
118   uchar version;
119   uchar flags[3];
120   ulong numEntries;
121 } QTS_STSD_Base;
122 
123 typedef struct {
124   ulong descSize;
125   ulong dataFormat;
126   uchar reserved1[6];
127   short dataRefIndex;
128   short version;
129   short revLevel;
130   ulong vendor;
131   short numChans;
132   short sampSize;
133   short compId;
134   short packetSize;
135   fix sampRate;
136 } QT_SoundDesc;
137 
138 typedef struct {
139   ulong descSize;
140   ulong dataFormat;
141   uchar reserved1[6];
142   short dataRefIndex;
143   short version;
144   short revLevel;
145   ulong vendor;
146   ulong temporalQuality;
147   ulong spatialQuality;
148   short width;
149   short height;
150   fix hRes;
151   fix vRes;
152   long dataSize;
153   short frameCount;
154   // Str31 name;
155   short depth;
156   short clutId;
157 } QT_ImageDesc;
158 
159 typedef struct {
160   ulong descSize;
161   ulong dataFormat;
162   // more stuff, but who cares?
163 } QT_TextDesc;
164 
165 typedef struct {
166   ulong trackDuration;
167   long mediaTime;
168   fix mediaRate;
169 } QT_EditList;
170 
171 typedef struct {
172   ulong count;
173   ulong duration;
174 } QT_Time2Samp;
175 
176 typedef struct {
177   ulong firstChunk;
178   ulong sampsPerChunk;
179   ulong sampDescId;
180 } QT_Samp2Chunk;
181 
182 typedef struct {
183   ulong frameDiffSampNum;
184   ulong syncSampNum;
185 } QT_ShadowSync;
186 
187 //	Chunk structures
188 
189 typedef struct {
190   uchar version;
191   uchar flags[3];
192   ulong numEntries;
193   QT_EditList editList[1];
194 } QTS_ELST;
195 
196 typedef struct {
197   uchar version;
198   uchar flags[3];
199   ulong compType;
200   ulong compSubtype;
201   ulong compManufacturer;
202   ulong compFlags;
203   ulong compFlagsMask;
204   PStr compName;
205 } QTS_HDLR;
206 
207 typedef struct {
208   uchar version;
209   uchar flags[3];
210   ulong createTime;
211   ulong modTime;
212   ulong timeScale;
213   ulong duration;
214   short language;
215   short quality;
216 } QTS_MDHD;
217 
218 typedef struct {
219   uchar version;
220   uchar flags[3];
221   ulong createTime;
222   ulong modTime;
223   ulong timeScale;
224   ulong duration;
225   fix preferredRate;
226   fix8 preferredVol;
227   uchar reserved[10];
228   fix matrix[9];
229   ulong previewTime;
230   ulong previewDur;
231   ulong posterTime;
232   ulong selTime;
233   ulong selDur;
234   ulong currTime;
235   ulong nextTrackId;
236 } QTS_MVHD;
237 
238 typedef struct {
239   uchar version;
240   uchar flags[3];
241   short balance;
242   short reserved;
243 } QTS_SMHD;
244 
245 typedef struct {
246   uchar version;
247   uchar flags[3];
248   ulong numEntries;
249   ulong offset[1];
250 } QTS_STCO;
251 
252 typedef struct {
253   uchar version;
254   uchar flags[3];
255   ulong numEntries;
256   QT_Samp2Chunk samp2chunk[1];
257 } QTS_STSC;
258 
259 typedef struct {
260   QTS_STSD_Base base;
261   union {
262     QT_SoundDesc sdesc;
263     QT_ImageDesc idesc;
264     QT_TextDesc tdesc;
265   };
266 } QTS_STSD;
267 
268 typedef struct {
269   uchar version;
270   uchar flags[3];
271   ulong numEntries;
272   QT_ShadowSync shadowSync[1];
273 } QTS_STSH;
274 
275 typedef struct {
276   uchar version;
277   uchar flags[3];
278   ulong numEntries;
279   ulong sample[1];
280 } QTS_STSS;
281 
282 typedef struct {
283   uchar version;
284   uchar flags[3];
285   ulong sampSize;
286   ulong numEntries;
287   ulong sampSizeTab[1];
288 } QTS_STSZ;
289 
290 typedef struct {
291   uchar version;
292   uchar flags[3];
293   ulong numEntries;
294   QT_Time2Samp time2samp[1];
295 } QTS_STTS;
296 
297 typedef struct {
298   uchar version;
299   uchar flags[3];
300   ulong createTime;
301   ulong modTime;
302   ulong trackId;
303   uchar reserved1[4];
304   ulong duration;
305   uchar reserved2[8];
306   short layer;
307   short altGroup;
308   fix8 volume;
309   uchar reserved3[2];
310   fix matrix[9];
311   fix trackWidth;
312   fix trackHeight;
313 } QTS_TKHD;
314 
315 typedef struct {
316   uchar version;
317   uchar flags[3];
318   short graphicsMode;
319   ushort opColor[3];
320 } QTS_VMHD;
321 
322 //	Quicktime movie structures for reading and writing whole movies
323 
324 typedef enum { TRACK_VIDEO, TRACK_AUDIO, TRACK_OTHER } TrackType;
325 
326 typedef struct {
327   QTS_TKHD qt_tkhd;  // track header (TKHD)
328   QTS_MDHD qt_mdhd;  // media header (MDHD)
329   QTS_STSD qt_stsd;  // sample descriptor (STSD)
330   QTS_STTS *qt_stts; // ptr to time->sample table (STTS)
331   QTS_STSC *qt_stsc; // ptr to sample->chunk table (STSC)
332   QTS_STSZ *qt_stsz; // ptr to sample size table (STSZ)
333   QTS_STCO *qt_stco; //	ptr to chunk->offset table (STCO)
334 
335   uchar *palette;          // 256-entry palette or NULL
336   ulong numSamps;          // number of samples
337   uchar *sampBuff;         // sample buffer (if NULL, then in file)
338   fix *sampTime;           // array of sample->time
339   ulong *sampSize;         // array of sample->size
340   ulong *sampOffset;       // array of sample->fileoffset
341   ulong audioBlockSize;    // # bytes per audio sample block
342   TrackType type;          // TRACK_XXX
343                            //	The following only used when writing movies
344   short numSamplesAlloced; // # sample entries allocated in buffs
345   fix *pSampleTime;        // ptr to array of sample times
346 } MovieTrack;
347 
348 typedef struct { // info about current track, have we gotten
349   uchar gotTKHD; // these important chunks? (TKHD, MDHD, STBL)
350   uchar gotMDHD;
351   uchar gotSTBL;
352 } MovieTrackStatus;
353 
354 #define QTM_MAX_TRACKS 8        // hey, what's in this thing anyway??
355 #define QTM_MAX_CHUNK_NESTING 8 // max nesting of subchunks
356 
357 typedef struct {
358   QTS_MVHD qt_mvhd;                        // global movie header
359   MovieTrack track[QTM_MAX_TRACKS];        // here are all my tracks!
360   MovieTrack *pVideoTrack;                 // ptr to single video track, or NULL if no video
361   MovieTrack *pAudioTrack;                 // ptr to audio track, or NULL if no audio
362   int numTracks;                           // number of tracks read into track[] array
363   int numAudioSamplesPerBlock;             // 4K if 11Khz, 8K if 22 Khz
364   ulong compTypeQT;                        // type of QuickTime VIDEO compression
365   short frameWidth;                        // frame width of video track
366   short frameHeight;                       // frame height of video track
367   uchar *pFrameCurr;                       // current frame in flat format
368   uchar *pFrameCompQT;                     // current frame in compressed format
369                                            //	The following used only when writing movies
370   long offsetStack[QTM_MAX_CHUNK_NESTING]; // stack of lengths to update
371   short indexOffsetStack;                  // current index into offset stack
372   uchar depth16;                           // convert to 16-bit depth when writing
373 } QTM;
374 
375 //	Prototypes: quiktime.c (reading movie for processing/conversion)
376 
377 void QuikReadMovie(QTM *pqtm, FILE *fpi);
378 void QuikFreeMovie(QTM *pqtm);
379 fix QuikComputeFrameRate(QTM *pqtm);
380 void *QuikGetVideoSample(QTM *pqtm, int isample, FILE *fpi, long *plength, uchar *pbmtype, fix *ptime);
381 void *QuikGetAudioSample(QTM *pqtm, int isample, long *plength, fix *ptime);
382 
383 //	Protoypes: quikwrite.c (writing movie)
384 
385 void QuikCreateMovie(QTM *pqtm, FILE *fp);
386 void QuikSetPal(QTM *pqtm, uchar *pal);
387 void QuikAddVideoSample(QTM *pqtm, FILE *fp, grs_bitmap *pbm, fix time);
388 void QuikWriteMovieAndClose(QTM *pqtm, FILE *fp);
389 
390 #define QuikSetDepth16(pqtm) ((pqtm)->depth16 = TRUE)
391 
392 //	Prototypes: quikconv.c (reading chunks for inspection/dumping)
393 
394 FILE *QuikOpenFile(char *filename);
395 uchar QuikReadChunkHdr(FILE *fp, QT_ChunkHdr *phdr);
396 void QuikSkipChunk(FILE *fp, QT_ChunkHdr *phdr);
397 uchar QuikReadChunk(FILE *fp, QT_ChunkHdr *phdr, void *buff, ulong bufflen);
398 void QuikWriteChunkHdr(FILE *fp, QT_ChunkHdr chunkHdr);
399 void QuikWriteChunkLength(FILE *fp, long length);
400 void QuikWriteChunk(FILE *fp, QT_Ctype ctype, void *data, ulong len);
401 QT_ChunkInfo *QuikFindChunkInfo(QT_ChunkHdr *phdr);
402 
403 #define Flip4(v) Flip4Func((ulong *)(v))
404 #define Flip2(v) Flip2Func((ushort *)(v))
405 
406 void Flip4Func(ulong *pval4);
407 void Flip2Func(ushort *pval2);
408 
409 //	Prototypes: quikprnt.c (printing chunks gotten via quikconv.c)
410 
411 void QuikPrintChunk(QT_ChunkHdr *phdr, void *buff, char *indent);
412 
413 #endif
414