void free(void* ptr) { chunk_header_t* chunk; chunk_header_t* next_chunk; chunk_header_t* prev_chunk; chunk_header_t* current_chunk; chunk_header_t** chunk_header; if (ptr) { chunk = (void*) ptr - 8; next_chunk = get_next_chunk(chunk); prev_chunk = get_prev_chunk(chunk); gHeapRemaining += chunk->size * 8; if (chunk == next_chunk || chunk == prev_chunk || get_prev_chunk(next_chunk) != chunk || get_next_chunk(prev_chunk) != chunk || chunk->prev_size & 1) { puts("Heap Error\n"); } chunk->prev_size |= 1; if ((chunk->prev_size << 30) < 0) { *prev_chunk->head = prev_chunk->next; if(prev_chunk->next) { prev_chunk->next->head = prev_chunk->head; } prev_chunk->size += chunk->size; chunk->size = 0; chunk->prev_size &= 3u; chunk = prev_chunk; } if ((next_chunk->prev_size << 31) < 0) { *next_chunk->head = next_chunk->next; if(next_chunk->next) { next_chunk->next->head = next_chunk->head; } chunk->size += next_chunk->size; next_chunk->size = 0; next_chunk->prev_size &= 3u; } next_chunk->prev_size |= 2; next_chunk->prev_size = (next_chunk->prev_size & 3) | (4 * chunk->size); chunk_header = &gHeapHeader[get_zone(chunk->size * 8)]; current_chunk = *chunk_header; chunk->head = chunk_header; chunk->next = current_chunk; if(current_chunk) { current_chunk->head = &chunk; } *chunk_header = chunk; } }
int get_mask(FILE *stream, int n, int size) { uint nexttag; Chunk_hdr nxt; Mapping *m = loadmtl->map[n]; if (m==NULL) { m = NewMapping(n,0); if (m==NULL) { MtlError(); return(0); } loadmtl->map[n] = m; } m->use = 1; while(size) { if(get_next_chunk(stream,&nxt)==0) return(0); nexttag = nxt.tag; #ifdef DBGLDMLI if (dbgldmli) printf(" get_MASK loop: nexttag = %X \n",nexttag); #endif if (!get_mapdata_chunk(stream,nexttag,&m->mask)) return(0); size-=nxt.size; } return(1); }
int get_map(FILE *stream, int n, int size) { uint nexttag; Chunk_hdr nxt; Mapping *m = loadmtl->map[n]; #ifdef DBGLDMLI if (dbgldmli) printf(" GET_MAP: n = %d\n",n); #endif if (m==NULL) { m = NewMapping(n,0); if (m==NULL) { MtlError(); return(0); } loadmtl->map[n] = m; } m->use = 1; while(size) { if(get_next_chunk(stream,&nxt)==0) return(0); nexttag = nxt.tag; switch(nexttag) { case INT_PERCENTAGE: case FLOAT_PERCENTAGE: if(get_mtlchunk(stream,NULL)==0) return(0); m->amt.pct = ipct; if (n==Nbump) m->amt.pct = (ipct<=20)?4*ipct:100; /* for old files */ #ifdef DBGLDMLI if (dbgldmli) printf(" get_map %d : pct: %d \n",n,ipct); #endif break; case MAT_BUMP_PERCENT: if(get_mtlchunk(stream,NULL)==0) return(0); m->amt.pct = ipct; /* for version 3+ files */ break; default: if (!get_mapdata_chunk(stream,nexttag,&m->map)) { #ifdef DBGLDMLI if (dbgldmli) printf(" Error in get_mapdata_chunk, nexttag = %X\n",nexttag); #endif MtlError(); return(0); } break; } size-=nxt.size; } #ifdef DBGLDMLI if (dbgldmli) printf(" EXIT GET_MAP: n = %d\n",n); #endif return(1); }
static Errcode load_fli_settings(char *path,Cmap *cmap) { Errcode err; Flifile flif; Chunkparse_data pd; (void)cmap; err = pj_fli_open(path, &flif, XREADONLY); if (err < Success) return err; init_chunkparse(&pd, flif.xf, FCID_PREFIX, sizeof(Fli_head), 0, 0); for (;;) { if (get_next_chunk(&pd)) { if (pd.type != FP_VSETTINGS) continue; err = load_settings_chunk(flif.xf, &pd.fchunk, pd.chunk_offset, NULL, NULL, TRUE, FALSE); break; } err = pd.error; if (err >= Success) err = Err_no_chunk; break; } pj_fli_close(&flif); return err; }
Errcode load_default_flidef(Vset_flidef *fdef) /* used by flisize menu to load the flidef fields in the buttons */ { Errcode err; Chunkparse_data pd; XFILE *xf; char path[PATH_SIZE]; make_file_path(vb.init_drawer,default_name,path); err = xffopen(path, &xf, XREADONLY); if (err < Success) return err; init_chunkparse(&pd, xf, VSETFILE_MAGIC, 0, sizeof(Fat_chunk), 0); while (get_next_chunk(&pd)) { if (pd.type == VSET_FLIDEF_ID) { if (pd.fchunk.version == VSET_FLIDEF_VERS) { pd.error = read_parsed_chunk(&pd,fdef,sizeof(*fdef)); fdef->id.size = sizeof(*fdef); /* keep host size the same */ } else pd.error = Err_version; goto done; } } if (pd.error >= Success) pd.error = Err_no_chunk; done: xffclose(&xf); return pd.error; }
static Errcode copy_flx_prefix(Flxfile *flx, Flifile *flif) /* copys or makes the appropriate prefix chunks from the tempflx to the output * flifile and sets the frame1_oset in the output filifile and leaves * the output file position at the start of the first frame chunk */ { Chunkparse_data pd; Errcode err; init_chunkparse(&pd,flx->fd,FCID_PREFIX,sizeof(Flx_head),0,0); while(get_next_chunk(&pd)) { switch(pd.type) { case FP_FLIPATH: /* ignore these */ case FP_FREE: break; case ROOT_CHUNK_TYPE: /* save old size */ if((err = copy_parsed_chunk(&pd, flif->fd)) < Success) goto error; /* install a settings chunk following prefix chunk */ if((err = write_fli_settings(flif->fd, FP_VSETTINGS)) < Success) { goto error; } break; default: if((err = copy_parsed_chunk(&pd, flif->fd)) < Success) goto error; break; } } if(pd.error < Success) { err = pd.error; goto error; } /* install prefix size write it and re-seek to end of prefix */ pd.fchunk.size = pj_tell(flif->fd) - sizeof(Fli_head); pd.fchunk.type = FCID_PREFIX; if((err = pj_writeoset(flif->fd,&pd.fchunk, sizeof(Fli_head),sizeof(Chunk_id))) < Success) { goto error; } /* back to end of file */ err = pj_seek(flif->fd,pd.fchunk.size+sizeof(Fli_head),JSEEK_START); error: return(err); }
/* Function: write_settings_chunk * * Writes out a settings chunk. Leaves file at start of chunk. */ static Errcode write_settings_chunk(XFILE *newxf, SHORT id_type, LONG offset, Cmap *cmap, Boolean for_fli_prefix) { Errcode err; Vsetfile vsf; Chunkparse_data pd; if((err = reopen_tsettings(&vsf)) < Success) return(err); if((err = tset_flush(&vsf,TRUE)) < Success) goto error; init_chunkparse(&pd, vsf.xf, VSETFILE_MAGIC, 0, sizeof(Fat_chunk), 0); while(get_next_chunk(&pd)) { switch(pd.type) { case VSET_FLIDEF_ID: if(for_fli_prefix) break; case VSET_PATHARRAY_ID: case (USHORT)ROOT_CHUNK_TYPE: case VSET_VS_ID: case VSET_SLOWVS_ID: copy_parsed_chunk(&pd, newxf); /* sets pd.error internally */ break; } } if((err = pd.error) < Success) goto error; if((!for_fli_prefix) && cmap) err = pj_write_palchunk(newxf, cmap, VSET_CMAP_ID); /* flush header chunk with final file size */ pd.fchunk.type = id_type; pd.fchunk.size = xfftell(newxf) - offset; err = xffwriteoset(newxf, &pd.fchunk.size, offset, sizeof(Chunk_id)); if (err < Success) goto error; err = pd.fchunk.size; error: close_vsetfile(&vsf); return(err); }
int main(int argc, const char *argv[]) { ALLEGRO_FILE *master, *slice; ALLEGRO_PATH *tmp_path; const char *first_string = "Hello, World!"; const char *second_string = "The quick brown fox jumps over the lazy dog."; char buffer[BUFFER_SIZE]; (void) argc, (void) argv; al_init(); master = al_make_temp_file("ex_file_slice_XXXX", &tmp_path); if (!master) { abort_example("Unable to create temporary file\n"); } /* Pack both strings into the master file. */ pack_object(master, first_string, strlen(first_string)); pack_object(master, second_string, strlen(second_string)); /* Seek back to the beginning of the file, as if we had just opened it */ al_fseek(master, 0, ALLEGRO_SEEK_SET); /* Loop through the main file, opening a slice for each object */ while ((slice = get_next_chunk(master))) { /* Note: While the slice is open, we must avoid using the master file! If you were dealing with packed images, this is where you would pass 'slice' to al_load_bitmap_f(). */ if (al_fsize(slice) < BUFFER_SIZE) { /* We could have used al_fgets(), but just to show that the file slice is constrained to the string object, we'll read the entire slice. */ al_fread(slice, buffer, al_fsize(slice)); buffer[al_fsize(slice)] = 0; printf("Chunk of size %d: '%s'\n", (int) al_fsize(slice), buffer); } /* The slice must be closed before the next slice is opened. Closing the slice will advanced the master file to the end of the slice. */ al_fclose(slice); } al_fclose(master); al_remove_filename(al_path_cstr(tmp_path, '/')); return 0; }
int get_mtlchunk(FILE *stream,void *data) { /* Grab a chunk from the file and process all its subsets */ Chunk_hdr chunk; Chunk_hdr nxt; uint thistag,nexttag; char *string; short *pshort; RDERR(&chunk,6); thistag=chunk.tag; #ifdef DBGLDMLI if (dbgldmli) printf(" get_mtlchunk: tag=%X, size=%d \n",thistag,chunk.size); #endif /* Update chunk size to account for header */ chunk.size-=6L; /* Find chunk type and go process it */ switch(thistag) { case MLIBMAGIC: while(chunk.size) { if(get_next_chunk(stream,&nxt)==0) return(0); nexttag=nxt.tag; switch(nexttag) { case MAT_ENTRY: loadmtl= &inmtl; /* Zero out data structure first */ init_mtl_struct(loadmtl); if(get_mtlchunk(stream,NULL)==0) return(0); if(put_lib_mtl(loadmtl)==0) return(0); break; default: if(skip_chunk(stream)==0){ MtlError(); return(0); } break; } chunk.size-=nxt.size; } break; case MAT_ENTRY: case MATMAGIC: while(chunk.size) { if(get_next_chunk(stream,&nxt)==0) return(0); nexttag=nxt.tag; switch(nexttag) { case MAT_NAME: strlimit=17; if(get_mtlchunk(stream,loadmtl->name)==0) return(0); #ifdef DBGLDMLI if (dbgldmli) printf(" **** Loading material : %s \n", loadmtl->name); #endif if(just_name) /* If all we need is the name, return */ return(1); break; case MAT_AMBIENT: if(get_mtlchunk(stream,&loadmtl->amb)==0) return(0); break; case MAT_DIFFUSE: if(get_mtlchunk(stream,&loadmtl->diff)==0) return(0); break; case MAT_SPECULAR: if(get_mtlchunk(stream,&loadmtl->spec)==0) return(0); break; case MAT_ACUBIC: { Mapping *m = loadmtl->map[Nrefl]; if (m==NULL) goto skip_mtl_chunk; if (get_mtlchunk(stream,&m->map.p.ref.acb)==0) return(0); } break; case MAT_SXP_TEXT_DATA: case MAT_SXP_TEXT2_DATA: case MAT_SXP_OPAC_DATA: case MAT_SXP_BUMP_DATA: case MAT_SXP_SPEC_DATA: case MAT_SXP_SELFI_DATA: case MAT_SXP_SHIN_DATA: case MAT_SXP_TEXT_MASKDATA: case MAT_SXP_TEXT2_MASKDATA: case MAT_SXP_OPAC_MASKDATA: case MAT_SXP_BUMP_MASKDATA: case MAT_SXP_SPEC_MASKDATA: case MAT_SXP_SELFI_MASKDATA: case MAT_SXP_SHIN_MASKDATA: case MAT_SXP_REFL_MASKDATA: if(get_mtlchunk(stream,NULL)==0) return(0); break; case MAT_TEXMAP: case MAT_TEX2MAP: case MAT_OPACMAP: case MAT_BUMPMAP: case MAT_SPECMAP: case MAT_SHINMAP: case MAT_SELFIMAP: case MAT_REFLMAP: case MAT_TEXMASK: case MAT_TEX2MASK: case MAT_OPACMASK: case MAT_BUMPMASK: case MAT_SPECMASK: case MAT_SHINMASK: case MAT_SELFIMASK: case MAT_REFLMASK: if(get_mtlchunk(stream,NULL)==0) return(0); break; case MAT_SHININESS: case MAT_SHIN2PCT: case MAT_TRANSPARENCY: case MAT_XPFALL: case MAT_REFBLUR: case MAT_SELF_ILPCT: case MAT_SHADING: case MAT_TWO_SIDE: case MAT_SUPERSMP: case MAT_SELF_ILLUM: case MAT_DECAL: case MAT_ADDITIVE: case MAT_WIRE: case MAT_FACEMAP: case MAT_XPFALLIN: case MAT_PHONGSOFT: case MAT_WIREABS: case MAT_USE_XPFALL: case MAT_USE_REFBLUR: case MAT_WIRESIZE: if(get_mtlchunk(stream,NULL)==0) return(0); break; case APP_DATA: if(get_mtlchunk(stream,&loadmtl->appdata)==0) return(0); break; default: skip_mtl_chunk: if(skip_chunk(stream)==0) { MtlError(); return(0); } break; } chunk.size-=nxt.size; } #ifdef DBGLDMLI if (dbgldmli) printf(" finished loading mtl %s, flags = %X\n", loadmtl->name, loadmtl->flags); #endif /* convert old data formats to new */ if (loadmtl->shading==REND_WIRE) { loadmtl->shading = REND_FLAT; loadmtl->flags |= MF_WIRE; loadmtl->flags |= MF_TWOSIDE; loadmtl->shininess=0; loadmtl->shin2pct=0; loadmtl->transparency=0; } if (loadmtl->xpfall<0.0) { loadmtl->flags|= MF_XPFALLIN; loadmtl->xpfall = -loadmtl->xpfall; } if (loadmtl->flags&MF_DECAL) { set_mtl_decal(loadmtl); loadmtl->flags &= ~MF_DECAL; } if (loadmtl->shin2pct==255) { float shin = (((float)(loadmtl->shininess))/100.0f); float atten = (float)sin(1.5707*shin); loadmtl->shin2pct = (int)((atten)*100.0f+0.5f); } break; case MAT_SXP_TEXT_DATA: GET_SXP(Ntex,0); break; case MAT_SXP_TEXT2_DATA: GET_SXP(Ntex2,0); break; case MAT_SXP_OPAC_DATA: GET_SXP(Nopac,0); break; case MAT_SXP_BUMP_DATA: GET_SXP(Nbump,0); break; case MAT_SXP_SPEC_DATA: GET_SXP(Nspec,0); break; case MAT_SXP_SELFI_DATA: GET_SXP(Nselfi,0); break; case MAT_SXP_SHIN_DATA: GET_SXP(Nshin,0); break; case MAT_SXP_TEXT_MASKDATA: GET_SXP(Ntex,1); break; case MAT_SXP_TEXT2_MASKDATA: GET_SXP(Ntex2,1); break; case MAT_SXP_OPAC_MASKDATA: GET_SXP(Nopac,1); break; case MAT_SXP_BUMP_MASKDATA: GET_SXP(Nbump,1); break; case MAT_SXP_SPEC_MASKDATA: GET_SXP(Nspec,1); break; case MAT_SXP_SELFI_MASKDATA: GET_SXP(Nselfi,1); break; case MAT_SXP_SHIN_MASKDATA: GET_SXP(Nshin,1); break; case MAT_SXP_REFL_MASKDATA: GET_SXP(Nrefl,1); break; case MAT_TEXMAP: GET_MAP(Ntex); break; case MAT_TEX2MAP: GET_MAP(Ntex2); break; case MAT_OPACMAP: GET_MAP(Nopac); break; case MAT_BUMPMAP: GET_MAP(Nbump); break; case MAT_SPECMAP: GET_MAP(Nspec); break; case MAT_SHINMAP: GET_MAP(Nshin); break; case MAT_SELFIMAP: GET_MAP(Nselfi); break; case MAT_REFLMAP: GET_MAP(Nrefl); break; case MAT_TEXMASK: GET_MASK(Ntex); break; case MAT_TEX2MASK: GET_MASK(Ntex2); break; case MAT_OPACMASK: GET_MASK(Nopac); break; case MAT_BUMPMASK: GET_MASK(Nbump); break; case MAT_SPECMASK: GET_MASK(Nspec); break; case MAT_SHINMASK: GET_MASK(Nshin); break; case MAT_SELFIMASK: GET_MASK(Nselfi); break; case MAT_REFLMASK: GET_MASK(Nrefl); break; case MAT_AMBIENT: case MAT_DIFFUSE: case MAT_SPECULAR: { int got_lin,got_gam; got_lin = got_gam = 0; while(chunk.size) { if(get_next_chunk(stream,&nxt)==0) return(0); nexttag=nxt.tag; switch(nexttag) { case COLOR_F: case COLOR_24: got_gam = 1; if(get_mtlchunk(stream,NULL)==0) return(0); break; case LIN_COLOR_24: got_lin = 1; if(get_mtlchunk(stream,NULL)==0) return(0); break; default: if(skip_chunk(stream)==0) { MtlError(); return(0); } break; } chunk.size-=nxt.size; } if (got_lin) { memcpy((char *)data,(char *)&LC24,sizeof(Color_24)); } else { if (!got_gam) { MtlError(); return(0); } if (gammaMgr.enable) { Color_24 gc; gc.r = gammaMgr.file_in_degamtab[C24.r]>>8; gc.g = gammaMgr.file_in_degamtab[C24.g]>>8; gc.b = gammaMgr.file_in_degamtab[C24.b]>>8; memcpy((char *)data,(char *)&gc,sizeof(Color_24)); } else { memcpy((char *)data,(char *)&C24,sizeof(Color_24)); } } }
Errcode pj_read_picbody(Jfile f,Pic_header *pic,Raster *cel, Cmap *cmap) /* from the file position just beyond the pic header will read a pic * into an Rcel it will truncate the pic if the cel is smaller and * center it otherwise */ { Errcode err; Chunkparse_data pd; if(pic->id.type == OPIC_MAGIC) { if(cmap) { if((err = pj_readoset(f,cmap->ctab,sizeof(Opic_header), COLORS*3)) < Success) { goto error; } pj_shift_cmap(cmap->ctab,cmap->ctab,COLORS*3); pj_cmap_load(cel,cmap); } return(read_pic_pixels(f,pic,cel,PIC_BYTEPIXELS, sizeof(Opic_header)+(COLORS*3), pic->width * pic->height )); } init_chunkparse(&pd,f,DONT_READ_ROOT,0,sizeof(Pic_header),pic->id.size); while(get_next_chunk(&pd)) { switch(pd.type) { case PIC_CMAP: if(!cmap) break; if((err = pj_read_palchunk(f,&pd.fchunk,cmap)) < Success) goto error; pj_cmap_load(cel,cmap); cmap = NULL; /* flag done */ break; case PIC_BITPIXELS: case PIC_BYTEPIXELS: if((err = read_pic_pixels(f,pic,cel,pd.type, pd.chunk_offset + sizeof(Chunk_id), pd.fchunk.size - sizeof(Chunk_id))) < Success) { goto error; } if(!cmap) goto done; default: break; } } if(pd.error < Success) goto error; if(cmap) /* no cmap chunk found and requested */ { pj_get_default_cmap(cmap); pj_cmap_load(cel,cmap); } done: error: return(err); }
/* Function: pj_read_picbody * * From the file position just beyond the pic header will read a pic * into an Rcel it will truncate the pic if the cel is smaller and * center it otherwise. */ Errcode pj_read_picbody(XFILE *xf, Pic_header *pic, Raster *cel, Cmap *cmap) { Errcode err = Err_nogood; Chunkparse_data pd; if(pic->id.type == OPIC_MAGIC) { if (cmap != NULL) { err = xffreadoset(xf, cmap->ctab, sizeof(Opic_header), COLORS*3); if (err < Success) goto error; pj_shift_cmap((const UBYTE *)cmap->ctab, (UBYTE *)cmap->ctab, COLORS*3); pj_cmap_load(cel,cmap); } return read_pic_pixels(xf, pic, cel, PIC_BYTEPIXELS, sizeof(Opic_header)+(COLORS*3), pic->width * pic->height); } init_chunkparse(&pd, xf, DONT_READ_ROOT, 0, sizeof(Pic_header), pic->id.size); while(get_next_chunk(&pd)) { switch(pd.type) { case PIC_CMAP: if(!cmap) break; err = pj_read_palchunk(xf,&pd.fchunk,cmap); if (err < Success) goto error; pj_cmap_load(cel,cmap); cmap = NULL; /* flag done */ break; case PIC_BITPIXELS: case PIC_BYTEPIXELS: err = read_pic_pixels(xf, pic, cel, pd.type, pd.chunk_offset + sizeof(Chunk_id), pd.fchunk.size - sizeof(Chunk_id)); if (err < Success) goto error; if(!cmap) goto done; default: break; } } if(pd.error < Success) { err = pd.error; goto error; } if(cmap) /* no cmap chunk found and requested */ { pj_get_default_cmap(cmap); pj_cmap_load(cel,cmap); } done: error: return(err); }
Errcode load_fli_fcel(char *flipath,char *tempname,char *celfli_name, Flicel **pfc) /* loads a fli file as a newly allocated flicel, if tempname is non-null * builds a temp fli from the fli or points a tempname file to the fli * if the tempname is NULL it will not build a temp file and will point the * ram cel to the fli even if the fli is on a removable device */ { Errcode err; Flifile flif; Flicel *fc; LONG chunksize; Chunkparse_data pd; Boolean make_flicopy; Boolean found_celdata; char device[DEV_NAME_LEN]; if((err = alloc_fcel(pfc)) < Success) return(err); fc = *pfc; if(tempname) { if(NULL == (fc->tpath = clone_string(tempname))) { err = Err_no_memory; goto error; } } clear_struct(&flif); if((err = get_path_device(flipath,device)) < Success) goto error; /* if allowed make sure cel fli file is not on removable drive */ make_flicopy = (tempname != NULL && celfli_name != NULL && !pj_is_fixed(device)); /* attempth to open fli requested as cel */ if (make_flicopy) { err = pj_fli_open(flipath, &flif, XREADONLY); if (err < Success) goto error; } else { err = pj_fli_open(flipath, &flif, XREADWRITE_OPEN); if (err < Success) goto error; /* we've got to have a valid update time ! */ if(flif.hdr.id.update_time == 0) { if((err = pj_i_flush_head(&flif)) < Success) goto error; } } found_celdata = FALSE; init_chunkparse(&pd, flif.xf, FCID_PREFIX, sizeof(Fli_head), 0, 0); while(get_next_chunk(&pd)) { if(pd.type == FP_CELDATA) { if(pd.fchunk.size == sizeof(Celdata)) { /* try to read it */ pd.error = read_parsed_chunk(&pd,&fc->cd,-1); found_celdata = TRUE; } break; } } if(pd.error < Success && pd.error != Err_no_chunk) { err = pd.error; goto error; } if(!found_celdata) { /* No positioning chunk found. Just put cel in upper left corner */ fc->cd.cent.x = flif.hdr.width>>1; fc->cd.cent.y = flif.hdr.height>>1; }
/* Function: load_settings_chunk * * This will load the global vsettings if there is no error and will * re-load the tsettings file with the input settings. It will load * the colour map even in some error cases, as it will the flidef. */ static Errcode load_settings_chunk(XFILE *xf, Fat_chunk *id, LONG offset, Vset_flidef *fdef, Cmap *cmap, Boolean load_mucolors, Boolean as_defaults) { Errcode err; Chunkparse_data pd; Tsettings_file *tset; Fat_chunk *buf; LONG recsize; Boolean load_inkstrengths; if(id->version != VSETCHUNK_VERSION) return(Err_version); if((tset = pj_malloc(sizeof(*tset))) == NULL) return(Err_no_memory); load_inkstrengths = !as_defaults; load_init_tsettings(tset); /* start out with defaults */ init_chunkparse(&pd, xf, DONT_READ_ROOT, offset, sizeof(Fat_chunk), id->size); while(get_next_chunk(&pd)) { switch(pd.type) { case VSET_FLIDEF_ID: if(!fdef) break; fdef->id = tset->fdef.id; buf = &(fdef->id); fdef = NULL; goto read_chunk; case VSET_VS_ID: buf = &(tset->vs.id); goto read_chunk; case VSET_SLOWVS_ID: if(!(load_inkstrengths || load_mucolors)) break; buf = &(tset->vslow.id); goto read_chunk; case VSET_PATHARRAY_ID: buf = &(tset->vsp.id); read_chunk: /* if the version is ok it will overlay or truncate to fit */ if(pd.fchunk.version != buf->version) goto version_error; recsize = buf->size; if((err = read_parsed_chunk(&pd,buf,recsize)) < Success) goto error; buf->size = recsize; /* OUR record should still * still have the same size NOT inputs */ break; case VSET_CMAP_ID: if (cmap) { err = pj_read_palchunk(pd.xf, &pd.fchunk, cmap); if (err < Success) goto error; cmap = NULL; } break; } } if((err = pd.error) < Success) goto error; if(as_defaults) chop_default_paths(&(tset->vsp)); if((err = write_gulp(tsettings_name,tset,sizeof(*tset))) < Success) goto error; if(load_mucolors) { memcpy(vconfg.mc_ideals,tset->vslow.mc_ideals, sizeof(vconfg.mc_ideals)); } if(load_inkstrengths) load_ink_strengths(tset->vslow.inkstrengths); if(fdef) *fdef = tset->fdef; if(cmap) { if(soft_yes_no_box("setting_cmap")) pj_get_default_cmap(cmap); } vs = tset->vs; goto done; version_error: err = Err_version; error: done: pj_freez(&tset); return(err); }
static GstFlowReturn gst_smfdec_chain (GstPad * pad, GstBuffer * data) { GstSmfdec *dec = GST_SMFDEC (gst_pad_get_parent (pad)); gint i, ticks; guint len, midi_len; /* we must be negotiated */ g_assert ( dec != NULL ); g_assert (dec->buf_denom > 0); gst_adapter_push (dec->adapter, GST_BUFFER (data)); if (dec->chunk.fourcc) { chunk_ensure (dec->adapter, &dec->chunk, 0); } while (dec->chunk.fourcc || get_next_chunk (dec->adapter, &dec->chunk)) { switch (dec->chunk.fourcc) { case GST_MAKE_FOURCC ('M', 'T', 'h', 'd'): if (dec->format) { GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("got a header chunk while already initialized")); goto error; } if (dec->chunk.length != 6) { GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("header chunk %d bytes long, not 6", (int) dec->chunk.length)); goto error; } if (!chunk_ensure (dec->adapter, &dec->chunk, 6)) goto out; /* we add one, so we can use 0 for uninitialized */ dec->format = GST_READ_UINT16_BE (dec->chunk.data) + 1; if (dec->format > 2) g_warning ("I have no clue if midi format %u works", dec->format - 1); dec->tracks_missing = GST_READ_UINT16_BE (dec->chunk.data + 2); //g_assert (dec->tracks_missing == 1); /* ignore the number of track atoms */ i = (gint16) GST_READ_UINT16_BE (dec->chunk.data + 4); if (i < 0) { GST_ELEMENT_ERROR (dec, STREAM, NOT_IMPLEMENTED, (NULL), ("can't handle smpte timing")); goto error; } else { dec->start = 0; dec->division = i; } chunk_flush (dec->adapter, &dec->chunk); break; case GST_MAKE_FOURCC ('M', 'T', 'r', 'k'): if (dec->format == 0) { GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("got a track chunk while not yet initialized")); goto error; } /* figure out if we have enough data */ ticks = gst_midi_data_parse_varlen (dec->chunk.data, dec->chunk.available, &len); if (ticks == -1) goto out; if (ticks == -2) { GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("invalid delta time value")); goto error; } midi_len = gst_midi_data_get_length (dec->chunk.data + len, dec->chunk.available - len, dec->status); if (midi_len == 0) goto out; /* we have enough data, process */ dec->ticks += ticks; //g_print ("got %u ticks, now %u\n", ticks, dec->ticks); if (dec->chunk.data[len] & 0x80) { dec->status = dec->chunk.data[len]; len++; midi_len--; } if (dec->status == 0xFF) { if (!gst_smfdec_meta_event (dec, dec->chunk.data + len, midi_len)) goto error; } else { gst_smfdec_buffer_append (dec, dec->status, dec->chunk.data + len, midi_len); } chunk_skip (dec->adapter, &dec->chunk, len + midi_len); if (dec->chunk.length == 0) chunk_clear (&dec->chunk); break; default: goto out; } } out: gst_object_unref(dec); return GST_FLOW_OK;; error: gst_smfdec_reset (dec); return GST_FLOW_ERROR; }