]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/mediasource/netradiant-src/libs/picomodel/lwo/clip.c
Move all other sources in a separate subfolder
[voretournament/voretournament.git] / misc / mediasource / netradiant-src / libs / picomodel / lwo / clip.c
1 /*
2 ======================================================================
3 clip.c
4
5 Functions for LWO2 image references.
6
7 Ernie Wright  17 Sep 00
8 ====================================================================== */
9
10 #include "../picointernal.h"
11 #include "lwo2.h"
12
13
14 /*
15 ======================================================================
16 lwFreeClip()
17
18 Free memory used by an lwClip.
19 ====================================================================== */
20
21 void lwFreeClip( lwClip *clip )
22 {
23    if ( clip ) {
24       lwListFree( clip->ifilter, (void *) lwFreePlugin );
25       lwListFree( clip->pfilter, (void *) lwFreePlugin );
26
27       switch ( clip->type ) {
28           case ID_STIL:
29             _pico_free( clip->source.still.name);
30             break;
31
32           case ID_ISEQ:
33             _pico_free( clip->source.seq.prefix );
34             _pico_free( clip->source.seq.suffix );
35             break;
36
37           case ID_ANIM:
38             _pico_free( clip->source.anim.name );
39             _pico_free( clip->source.anim.server );
40             _pico_free( clip->source.anim.data );
41             break;
42
43           case ID_XREF:
44             _pico_free( clip->source.xref.string );
45             break;
46
47           case ID_STCC:
48             _pico_free( clip->source.cycle.name );
49             break;
50
51           default:
52             break;
53       }
54
55       _pico_free( clip );
56    }
57 }
58
59
60 /*
61 ======================================================================
62 lwGetClip()
63
64 Read image references from a CLIP chunk in an LWO2 file.
65 ====================================================================== */
66
67 lwClip *lwGetClip( picoMemStream_t *fp, int cksize )
68 {
69    lwClip *clip;
70    lwPlugin *filt;
71    unsigned int id;
72    unsigned short sz;
73    int pos, rlen;
74
75
76    /* allocate the Clip structure */
77
78    clip = _pico_calloc( 1, sizeof( lwClip ));
79    if ( !clip ) goto Fail;
80
81    clip->contrast.val = 1.0f;
82    clip->brightness.val = 1.0f;
83    clip->saturation.val = 1.0f;
84    clip->gamma.val = 1.0f;
85
86    /* remember where we started */
87
88    set_flen( 0 );
89    pos = _pico_memstream_tell( fp );
90
91    /* index */
92
93    clip->index = getI4( fp );
94
95    /* first subchunk header */
96
97    clip->type = getU4( fp );
98    sz = getU2( fp );
99    if ( 0 > get_flen() ) goto Fail;
100
101    sz += sz & 1;
102    set_flen( 0 );
103
104    switch ( clip->type ) {
105       case ID_STIL:
106          clip->source.still.name = getS0( fp );
107          break;
108
109       case ID_ISEQ:
110          clip->source.seq.digits  = getU1( fp );
111          clip->source.seq.flags   = getU1( fp );
112          clip->source.seq.offset  = getI2( fp );
113          getU2( fp );  /* not sure what this is yet */
114          clip->source.seq.start   = getI2( fp );
115          clip->source.seq.end     = getI2( fp );
116          clip->source.seq.prefix  = getS0( fp );
117          clip->source.seq.suffix  = getS0( fp );
118          break;
119
120       case ID_ANIM:
121          clip->source.anim.name   = getS0( fp );
122          clip->source.anim.server = getS0( fp );
123          rlen = get_flen();
124          clip->source.anim.data   = getbytes( fp, sz - rlen );
125          break;
126
127       case ID_XREF:
128          clip->source.xref.index  = getI4( fp );
129          clip->source.xref.string = getS0( fp );
130          break;
131
132       case ID_STCC:
133          clip->source.cycle.lo   = getI2( fp );
134          clip->source.cycle.hi   = getI2( fp );
135          clip->source.cycle.name = getS0( fp );
136          break;
137
138       default:
139          break;
140    }
141
142    /* error while reading current subchunk? */
143
144    rlen = get_flen();
145    if ( rlen < 0 || rlen > sz ) goto Fail;
146
147    /* skip unread parts of the current subchunk */
148
149    if ( rlen < sz )
150       _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
151
152    /* end of the CLIP chunk? */
153
154    rlen = _pico_memstream_tell( fp ) - pos;
155    if ( cksize < rlen ) goto Fail;
156    if ( cksize == rlen )
157       return clip;
158
159    /* process subchunks as they're encountered */
160
161    id = getU4( fp );
162    sz = getU2( fp );
163    if ( 0 > get_flen() ) goto Fail;
164
165    while ( 1 ) {
166       sz += sz & 1;
167       set_flen( 0 );
168
169       switch ( id ) {
170          case ID_TIME:
171             clip->start_time = getF4( fp );
172             clip->duration = getF4( fp );
173             clip->frame_rate = getF4( fp );
174             break;
175
176          case ID_CONT:
177             clip->contrast.val = getF4( fp );
178             clip->contrast.eindex = getVX( fp );
179             break;
180
181          case ID_BRIT:
182             clip->brightness.val = getF4( fp );
183             clip->brightness.eindex = getVX( fp );
184             break;
185
186          case ID_SATR:
187             clip->saturation.val = getF4( fp );
188             clip->saturation.eindex = getVX( fp );
189             break;
190
191          case ID_HUE:
192             clip->hue.val = getF4( fp );
193             clip->hue.eindex = getVX( fp );
194             break;
195
196          case ID_GAMM:
197             clip->gamma.val = getF4( fp );
198             clip->gamma.eindex = getVX( fp );
199             break;
200
201          case ID_NEGA:
202             clip->negative = getU2( fp );
203             break;
204
205          case ID_IFLT:
206          case ID_PFLT:
207             filt = _pico_calloc( 1, sizeof( lwPlugin ));
208             if ( !filt ) goto Fail;
209
210             filt->name = getS0( fp );
211             filt->flags = getU2( fp );
212             rlen = get_flen();
213             filt->data = getbytes( fp, sz - rlen );
214
215             if ( id == ID_IFLT ) {
216                lwListAdd( (void *) &clip->ifilter, filt );
217                clip->nifilters++;
218             }
219             else {
220                lwListAdd( (void *) &clip->pfilter, filt );
221                clip->npfilters++;
222             }
223             break;
224
225          default:
226             break;
227       }
228
229       /* error while reading current subchunk? */
230
231       rlen = get_flen();
232       if ( rlen < 0 || rlen > sz ) goto Fail;
233
234       /* skip unread parts of the current subchunk */
235
236       if ( rlen < sz )
237          _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
238
239       /* end of the CLIP chunk? */
240
241       rlen = _pico_memstream_tell( fp ) - pos;
242       if ( cksize < rlen ) goto Fail;
243       if ( cksize == rlen ) break;
244
245       /* get the next chunk header */
246
247       set_flen( 0 );
248       id = getU4( fp );
249       sz = getU2( fp );
250       if ( 6 != get_flen() ) goto Fail;
251    }
252
253    return clip;
254
255 Fail:
256    lwFreeClip( clip );
257    return NULL;
258 }
259
260
261 /*
262 ======================================================================
263 lwFindClip()
264
265 Returns an lwClip pointer, given a clip index.
266 ====================================================================== */
267
268 lwClip *lwFindClip( lwClip *list, int index )
269 {
270    lwClip *clip;
271
272    clip = list;
273    while ( clip ) {
274       if ( clip->index == index ) break;
275       clip = clip->next;
276    }
277    return clip;
278 }