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