- surf->color.rgb[ 0 ] = 0.78431f;
- surf->color.rgb[ 1 ] = 0.78431f;
- surf->color.rgb[ 2 ] = 0.78431f;
- surf->diffuse.val = 1.0f;
- surf->glossiness.val = 0.4f;
- surf->bump.val = 1.0f;
- surf->eta.val = 1.0f;
- surf->sideflags = 1;
-
- /* remember where we started */
-
- set_flen( 0 );
- pos = _pico_memstream_tell( fp );
-
- /* names */
-
- surf->name = getS0( fp );
- surf->srcname = getS0( fp );
-
- /* first subchunk header */
-
- id = getU4( fp );
- sz = getU2( fp );
- if ( 0 > get_flen() ) goto Fail;
-
- /* process subchunks as they're encountered */
-
- while ( 1 ) {
- sz += sz & 1;
- set_flen( 0 );
-
- switch ( id ) {
- case ID_COLR:
- surf->color.rgb[ 0 ] = getF4( fp );
- surf->color.rgb[ 1 ] = getF4( fp );
- surf->color.rgb[ 2 ] = getF4( fp );
- surf->color.eindex = getVX( fp );
- break;
-
- case ID_LUMI:
- surf->luminosity.val = getF4( fp );
- surf->luminosity.eindex = getVX( fp );
- break;
-
- case ID_DIFF:
- surf->diffuse.val = getF4( fp );
- surf->diffuse.eindex = getVX( fp );
- break;
-
- case ID_SPEC:
- surf->specularity.val = getF4( fp );
- surf->specularity.eindex = getVX( fp );
- break;
-
- case ID_GLOS:
- surf->glossiness.val = getF4( fp );
- surf->glossiness.eindex = getVX( fp );
- break;
-
- case ID_REFL:
- surf->reflection.val.val = getF4( fp );
- surf->reflection.val.eindex = getVX( fp );
- break;
-
- case ID_RFOP:
- surf->reflection.options = getU2( fp );
- break;
-
- case ID_RIMG:
- surf->reflection.cindex = getVX( fp );
- break;
-
- case ID_RSAN:
- surf->reflection.seam_angle = getF4( fp );
- break;
-
- case ID_TRAN:
- surf->transparency.val.val = getF4( fp );
- surf->transparency.val.eindex = getVX( fp );
- break;
-
- case ID_TROP:
- surf->transparency.options = getU2( fp );
- break;
-
- case ID_TIMG:
- surf->transparency.cindex = getVX( fp );
- break;
-
- case ID_RIND:
- surf->eta.val = getF4( fp );
- surf->eta.eindex = getVX( fp );
- break;
-
- case ID_TRNL:
- surf->translucency.val = getF4( fp );
- surf->translucency.eindex = getVX( fp );
- break;
-
- case ID_BUMP:
- surf->bump.val = getF4( fp );
- surf->bump.eindex = getVX( fp );
- break;
-
- case ID_SMAN:
- surf->smooth = getF4( fp );
- break;
-
- case ID_SIDE:
- surf->sideflags = getU2( fp );
- break;
-
- case ID_CLRH:
- surf->color_hilite.val = getF4( fp );
- surf->color_hilite.eindex = getVX( fp );
- break;
-
- case ID_CLRF:
- surf->color_filter.val = getF4( fp );
- surf->color_filter.eindex = getVX( fp );
- break;
-
- case ID_ADTR:
- surf->add_trans.val = getF4( fp );
- surf->add_trans.eindex = getVX( fp );
- break;
-
- case ID_SHRP:
- surf->dif_sharp.val = getF4( fp );
- surf->dif_sharp.eindex = getVX( fp );
- break;
-
- case ID_GVAL:
- surf->glow.val = getF4( fp );
- surf->glow.eindex = getVX( fp );
- break;
-
- case ID_LINE:
- surf->line.enabled = 1;
- if ( sz >= 2 ) surf->line.flags = getU2( fp );
- if ( sz >= 6 ) surf->line.size.val = getF4( fp );
- if ( sz >= 8 ) surf->line.size.eindex = getVX( fp );
- break;
-
- case ID_ALPH:
- surf->alpha_mode = getU2( fp );
- surf->alpha = getF4( fp );
- break;
-
- case ID_AVAL:
- surf->alpha = getF4( fp );
- break;
-
- case ID_BLOK:
- type = getU4( fp );
-
- switch ( type ) {
- case ID_IMAP:
- case ID_PROC:
- case ID_GRAD:
- tex = lwGetTexture( fp, sz - 4, type );
- if ( !tex ) goto Fail;
- if ( !add_texture( surf, tex ))
- lwFreeTexture( tex );
- set_flen( 4 + get_flen() );
- break;
- case ID_SHDR:
- shdr = lwGetShader( fp, sz - 4 );
- if ( !shdr ) goto Fail;
- lwListInsert( &surf->shader, shdr, compare_shaders );
- ++surf->nshaders;
- set_flen( 4 + get_flen() );
- break;
- }
- break;
-
- default:
- break;
- }
-
- /* error while reading current subchunk? */
-
- rlen = get_flen();
- if ( rlen < 0 || rlen > sz ) goto Fail;
-
- /* skip unread parts of the current subchunk */
-
- if ( rlen < sz )
- _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
-
- /* end of the SURF chunk? */
-
- if ( cksize <= _pico_memstream_tell( fp ) - pos )
- break;
-
- /* get the next subchunk header */
-
- set_flen( 0 );
- id = getU4( fp );
- sz = getU2( fp );
- if ( 6 != get_flen() ) goto Fail;
- }
-
- return surf;
+ /* allocate the Surface structure */
+
+ surf = _pico_calloc( 1, sizeof( lwSurface ) );
+ if ( !surf ) {
+ goto Fail;
+ }
+
+ /* non-zero defaults */
+
+ surf->color.rgb[ 0 ] = 0.78431f;
+ surf->color.rgb[ 1 ] = 0.78431f;
+ surf->color.rgb[ 2 ] = 0.78431f;
+ surf->diffuse.val = 1.0f;
+ surf->glossiness.val = 0.4f;
+ surf->bump.val = 1.0f;
+ surf->eta.val = 1.0f;
+ surf->sideflags = 1;
+
+ /* remember where we started */
+
+ set_flen( 0 );
+ pos = _pico_memstream_tell( fp );
+
+ /* names */
+
+ surf->name = getS0( fp );
+ surf->srcname = getS0( fp );
+
+ /* first subchunk header */
+
+ id = getU4( fp );
+ sz = getU2( fp );
+ if ( 0 > get_flen() ) {
+ goto Fail;
+ }
+
+ /* process subchunks as they're encountered */
+
+ while ( 1 ) {
+ sz += sz & 1;
+ set_flen( 0 );
+
+ switch ( id ) {
+ case ID_COLR:
+ surf->color.rgb[ 0 ] = getF4( fp );
+ surf->color.rgb[ 1 ] = getF4( fp );
+ surf->color.rgb[ 2 ] = getF4( fp );
+ surf->color.eindex = getVX( fp );
+ break;
+
+ case ID_LUMI:
+ surf->luminosity.val = getF4( fp );
+ surf->luminosity.eindex = getVX( fp );
+ break;
+
+ case ID_DIFF:
+ surf->diffuse.val = getF4( fp );
+ surf->diffuse.eindex = getVX( fp );
+ break;
+
+ case ID_SPEC:
+ surf->specularity.val = getF4( fp );
+ surf->specularity.eindex = getVX( fp );
+ break;
+
+ case ID_GLOS:
+ surf->glossiness.val = getF4( fp );
+ surf->glossiness.eindex = getVX( fp );
+ break;
+
+ case ID_REFL:
+ surf->reflection.val.val = getF4( fp );
+ surf->reflection.val.eindex = getVX( fp );
+ break;
+
+ case ID_RFOP:
+ surf->reflection.options = getU2( fp );
+ break;
+
+ case ID_RIMG:
+ surf->reflection.cindex = getVX( fp );
+ break;
+
+ case ID_RSAN:
+ surf->reflection.seam_angle = getF4( fp );
+ break;
+
+ case ID_TRAN:
+ surf->transparency.val.val = getF4( fp );
+ surf->transparency.val.eindex = getVX( fp );
+ break;
+
+ case ID_TROP:
+ surf->transparency.options = getU2( fp );
+ break;
+
+ case ID_TIMG:
+ surf->transparency.cindex = getVX( fp );
+ break;
+
+ case ID_RIND:
+ surf->eta.val = getF4( fp );
+ surf->eta.eindex = getVX( fp );
+ break;
+
+ case ID_TRNL:
+ surf->translucency.val = getF4( fp );
+ surf->translucency.eindex = getVX( fp );
+ break;
+
+ case ID_BUMP:
+ surf->bump.val = getF4( fp );
+ surf->bump.eindex = getVX( fp );
+ break;
+
+ case ID_SMAN:
+ surf->smooth = getF4( fp );
+ break;
+
+ case ID_SIDE:
+ surf->sideflags = getU2( fp );
+ break;
+
+ case ID_CLRH:
+ surf->color_hilite.val = getF4( fp );
+ surf->color_hilite.eindex = getVX( fp );
+ break;
+
+ case ID_CLRF:
+ surf->color_filter.val = getF4( fp );
+ surf->color_filter.eindex = getVX( fp );
+ break;
+
+ case ID_ADTR:
+ surf->add_trans.val = getF4( fp );
+ surf->add_trans.eindex = getVX( fp );
+ break;
+
+ case ID_SHRP:
+ surf->dif_sharp.val = getF4( fp );
+ surf->dif_sharp.eindex = getVX( fp );
+ break;
+
+ case ID_GVAL:
+ surf->glow.val = getF4( fp );
+ surf->glow.eindex = getVX( fp );
+ break;
+
+ case ID_LINE:
+ surf->line.enabled = 1;
+ if ( sz >= 2 ) {
+ surf->line.flags = getU2( fp );
+ }
+ if ( sz >= 6 ) {
+ surf->line.size.val = getF4( fp );
+ }
+ if ( sz >= 8 ) {
+ surf->line.size.eindex = getVX( fp );
+ }
+ break;
+
+ case ID_ALPH:
+ surf->alpha_mode = getU2( fp );
+ surf->alpha = getF4( fp );
+ break;
+
+ case ID_AVAL:
+ surf->alpha = getF4( fp );
+ break;
+
+ case ID_BLOK:
+ type = getU4( fp );
+
+ switch ( type ) {
+ case ID_IMAP:
+ case ID_PROC:
+ case ID_GRAD:
+ tex = lwGetTexture( fp, sz - 4, type );
+ if ( !tex ) {
+ goto Fail;
+ }
+ if ( !add_texture( surf, tex ) ) {
+ lwFreeTexture( tex );
+ }
+ set_flen( 4 + get_flen() );
+ break;
+ case ID_SHDR:
+ shdr = lwGetShader( fp, sz - 4 );
+ if ( !shdr ) {
+ goto Fail;
+ }
+ lwListInsert( &surf->shader, shdr, compare_shaders );
+ ++surf->nshaders;
+ set_flen( 4 + get_flen() );
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* error while reading current subchunk? */
+
+ rlen = get_flen();
+ if ( rlen < 0 || rlen > sz ) {
+ goto Fail;
+ }
+
+ /* skip unread parts of the current subchunk */
+
+ if ( rlen < sz ) {
+ _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
+ }
+
+ /* end of the SURF chunk? */
+
+ if ( cksize <= _pico_memstream_tell( fp ) - pos ) {
+ break;
+ }
+
+ /* get the next subchunk header */
+
+ set_flen( 0 );
+ id = getU4( fp );
+ sz = getU2( fp );
+ if ( 6 != get_flen() ) {
+ goto Fail;
+ }
+ }
+
+ return surf;