#include #include #include #include #include "wv.h" void wvReleaseEscher(escherstruct *item) { wvReleaseDggContainer(&item->dggcontainer); wvReleaseDgContainer(&item->dgcontainer); } void wvInitEscher(escherstruct *item) { wvInitDggContainer(&item->dggcontainer); wvInitDgContainer(&item->dgcontainer); } void wvGetEscher(escherstruct *item,U32 offset,U32 len,wvStream *fd,wvStream *delay) { U32 count=0; MSOFBH amsofbh; wvStream_goto(fd,offset); wvTrace(("offset %x, len %d\n",offset,len)); wvInitEscher(item); while (count < len) { count += wvGetMSOFBH(&amsofbh,fd); wvTrace(("count is %x,len is %x, next len is %x\n",count,len,amsofbh.cbLength)); wvTrace(("type is %x\n ",amsofbh.fbt)); switch(amsofbh.fbt) { case msofbtDggContainer: count += wvGetDggContainer(&item->dggcontainer,&amsofbh,fd,delay); break; case msofbtDgContainer: count += wvGetDgContainer(&item->dgcontainer,&amsofbh,fd); break; default: wvError(("Not a container, panic (%x)\n",amsofbh.fbt)); return; break; } } wvTrace(("offset %x, len %d (pos %x)\n",offset,len,wvStream_tell(fd))); } void wvReleaseDggContainer(DggContainer *item) { wvReleaseSplitMenuColors(&item->splitmenucolors); wvReleaseDgg(&item->dgg); wvReleaseBstoreContainer(&item->bstorecontainer); } void wvInitDggContainer(DggContainer *item) { wvInitSplitMenuColors(&item->splitmenucolors); wvInitDgg(&item->dgg); wvInitBstoreContainer(&item->bstorecontainer); } U32 wvGetDggContainer(DggContainer *item,MSOFBH *msofbh,wvStream *fd,wvStream *delay) { MSOFBH amsofbh; U32 count=0; while (count < msofbh->cbLength) { count += wvGetMSOFBH(&amsofbh,fd); wvTrace(("len is %x, type is %x, count %x,fullen %x\n",amsofbh.cbLength,amsofbh.fbt,count,msofbh->cbLength)); wvTrace(("type is %x\n ",amsofbh.fbt)); switch(amsofbh.fbt) { case msofbtDgg: count +=wvGetDgg(&item->dgg,&amsofbh,fd); break; case msofbtSplitMenuColors: count +=wvGetSplitMenuColors(&item->splitmenucolors,&amsofbh,fd); break; case msofbtBstoreContainer: count +=wvGetBstoreContainer(&item->bstorecontainer,&amsofbh,fd,delay); wvTrace(("type is %d (number is %d\n",item->bstorecontainer.blip[item->bstorecontainer.no_fbse-1].type,item->bstorecontainer.no_fbse)); break; default: count +=wvEatmsofbt(&amsofbh,fd); wvError(("Eating type 0x%x\n",amsofbh.fbt)); break; } } /* For some reason I appear to have an extra byte associated either with this or its wrapper, I will investigate further. */ read_8ubit(fd); count++; return(count); } void wvReleaseDgContainer (DgContainer * item) { U32 i; for (i = 0; i < item->no_spgrcontainer; i++) wvReleaseSpgrContainer (&(item->spgrcontainer[i])); wvFree (item->spgrcontainer); } void wvInitDgContainer (DgContainer * item) { item->no_spgrcontainer = 0; item->spgrcontainer=NULL; } void wvReleaseBstoreContainer(BstoreContainer *item) { U32 i; for (i=0;ino_fbse;i++) wvReleaseBlip(&item->blip[i]); wvFree(item->blip); } void wvInitBstoreContainer(BstoreContainer *item) { item->no_fbse=0; item->blip=NULL; } U32 wvGetBstoreContainer(BstoreContainer *item,MSOFBH *msofbh,wvStream *fd,wvStream *delay) { MSOFBH amsofbh; U32 count=0; while (count < msofbh->cbLength) { count += wvGetMSOFBH(&amsofbh,fd); wvTrace(("type is %x\n ",amsofbh.fbt)); switch(amsofbh.fbt) { case msofbtBSE: wvTrace(("Blip at %x\n",wvStream_tell(fd))); item->no_fbse++; item->blip = (Blip *)realloc(item->blip,sizeof(Blip)*item->no_fbse); count += wvGetBlip((&item->blip[item->no_fbse-1]),fd,delay); wvTrace(("type is %d (number is %d\n",item->blip[item->no_fbse-1].type,item->no_fbse)); break; default: count +=wvEatmsofbt(&amsofbh,fd); wvError(("Eating type 0x%x\n",amsofbh.fbt)); break; } } return(count); } U32 wvGetDgContainer(DgContainer *item,MSOFBH *msofbh,wvStream *fd) { MSOFBH amsofbh; U32 count=0; while (count < msofbh->cbLength) { count += wvGetMSOFBH(&amsofbh,fd); wvTrace(("len is %x, type is %x, count %x,fullen %x\n",amsofbh.cbLength,amsofbh.fbt,count,msofbh->cbLength)); wvTrace(("type is %x\n ",amsofbh.fbt)); switch(amsofbh.fbt) { case msofbtDg: count += wvGetFDG(&item->fdg,fd); break; case msofbtSpgrContainer: item->no_spgrcontainer++; item->spgrcontainer = (SpgrContainer *)realloc(item->spgrcontainer,sizeof(SpgrContainer)*item->no_spgrcontainer); count += wvGetSpgrContainer(&(item->spgrcontainer[item->no_spgrcontainer-1]),&amsofbh,fd); break; default: count +=wvEatmsofbt(&amsofbh,fd); wvError(("Eating type 0x%x\n",amsofbh.fbt)); break; } } return(count); } FSPContainer *wvFindSPID(SpgrContainer *item,S32 spid) { U32 i; FSPContainer *t; for(i=0;ino_spcontainer;i++) { /* FIXME: Cast below is to avoid compiler warnings, but having to have it could be a sign of something wrong. */ if (item->spcontainer[i].fsp.spid == (U32)spid) { wvTrace(("FOUND IT\n")); return(&(item->spcontainer[i])); } } for (i=0;ino_spgrcontainer;i++) { t = wvFindSPID(&(item->spgrcontainer[i]),spid); if (t) return(t); } return(NULL); } void wvReleaseSpgrContainer(SpgrContainer *item) { U32 i; for(i=0;ino_spcontainer;i++) wvReleaseFSPContainer(&(item->spcontainer[i])); wvFree(item->spcontainer); for(i=0;ino_spgrcontainer;i++) wvReleaseSpgrContainer(&(item->spgrcontainer[i])); wvFree(item->spgrcontainer); } U32 wvGetSpgrContainer(SpgrContainer *item,MSOFBH *msofbh,wvStream *fd) { MSOFBH amsofbh; U32 count=0; item->spgrcontainer=NULL; item->no_spgrcontainer=0; item->spcontainer=NULL; item->no_spcontainer=0; while (count < msofbh->cbLength) { count += wvGetMSOFBH(&amsofbh,fd); wvTrace(("len is %x, type is %x, count %x,fullen %x\n",amsofbh.cbLength,amsofbh.fbt,count,msofbh->cbLength)); wvTrace(("type is %x\n ",amsofbh.fbt)); switch(amsofbh.fbt) { case msofbtSpContainer: item->no_spcontainer++; item->spcontainer = realloc(item->spcontainer,sizeof(FSPContainer)*item->no_spcontainer); count += wvGetFSPContainer(&(item->spcontainer[item->no_spcontainer-1]),&amsofbh,fd); break; case msofbtSpgrContainer: item->no_spgrcontainer++; item->spgrcontainer = realloc(item->spgrcontainer,sizeof(SpgrContainer)*item->no_spgrcontainer); count += wvGetSpgrContainer(&(item->spgrcontainer[item->no_spgrcontainer-1]),&amsofbh,fd); break; default: count +=wvEatmsofbt(&amsofbh,fd); wvError(("Eating type 0x%x\n",amsofbh.fbt)); break; } } return(count); } U32 wvGetFDG(FDG *afdg,wvStream *fd) { afdg->csp = read_32ubit(fd); afdg->spidCur = read_32ubit(fd); wvTrace(("there are %d shapes here, the last is %x\n",afdg->csp,afdg->spidCur)); return(8); } void wvInitSplitMenuColors(SplitMenuColors *splitmenucolors) { splitmenucolors->noofcolors=0; splitmenucolors->colors=NULL; } void wvReleaseSplitMenuColors(SplitMenuColors *splitmenucolors) { wvFree(splitmenucolors->colors); } U32 wvGetSplitMenuColors(SplitMenuColors *splitmenucolors,MSOFBH *amsofbh,wvStream *fd) { U32 i=0; splitmenucolors->noofcolors = amsofbh->cbLength/4; if (splitmenucolors->noofcolors) { splitmenucolors->colors = (U32 *)malloc(sizeof(U32)*splitmenucolors->noofcolors); for(i=0;inoofcolors;i++) splitmenucolors->colors[i] = read_32ubit(fd); } return(i*4); } void wvReleaseDgg(Dgg *dgg) { wvFree(dgg->fidcl); } void wvInitDgg(Dgg *dgg) { dgg->fidcl=NULL; } U32 wvGetDgg(Dgg *dgg,MSOFBH *amsofbh,wvStream *fd) { U32 count=0; U32 no; U32 i; count+=wvGetFDGG(&dgg->fdgg,fd); if (dgg->fdgg.cidcl != 0) { wvTrace(("There are %d bytes left\n",amsofbh->cbLength-count)); no = (amsofbh->cbLength-count)/8; if (no != dgg->fdgg.cidcl) { wvWarning("Must be %d, not %d as specs, test algor gives %d\n",no,dgg->fdgg.cidcl,dgg->fdgg.cspSaved-dgg->fdgg.cidcl); } if (no) { dgg->fidcl = (FIDCL *)malloc(sizeof(FIDCL) * no); for(i=0;ifidcl[i]),fd); } } return(count); } U32 wvGetFIDCL(FIDCL *afidcl,wvStream *fd) { afidcl->dgid = read_32ubit(fd); afidcl->cspidCur = read_32ubit(fd); wvTrace(("dgid %d cspidCur %d\n",afidcl->dgid,afidcl->cspidCur)); return(8); } U32 wvGetFDGG(FDGG *afdgg,wvStream *fd) { afdgg->spidMax = read_32ubit(fd); afdgg->cidcl = read_32ubit(fd); afdgg->cspSaved = read_32ubit(fd); afdgg->cdgSaved = read_32ubit(fd); wvTrace(("spidMax %d cidcl %d cspSaved %d cdgSaved %d\n",afdgg->spidMax,afdgg->cidcl,afdgg->cspSaved, afdgg->cdgSaved )); return(16); } int wv0x08(Blip *blip,S32 spid,wvParseStruct *ps) { int ret=0; U32 i; escherstruct item; FSPContainer *answer=NULL; wvTrace(("spid is %x\n",spid)); wvGetEscher(&item,ps->fib.fcDggInfo,ps->fib.lcbDggInfo,ps->tablefd,ps->mainfd); for(i=0;ifopte) { while(answer->fopte[i].pid != 0) { if (answer->fopte[i].pid == 260) { wvTrace(("has a blip reference of %d\n",answer->fopte[i].op)); wvTrace(("no blips is %d\n",item.dggcontainer.bstorecontainer.no_fbse)); wvTrace(("type is %d (number is %d\n",item.dggcontainer.bstorecontainer.blip[item.dggcontainer.bstorecontainer.no_fbse-1].type,item.dggcontainer.bstorecontainer.no_fbse)); if (answer->fopte[i].op <= item.dggcontainer.bstorecontainer.no_fbse) { wvTrace(("Copied Blip\n")); wvCopyBlip(blip,&(item.dggcontainer.bstorecontainer.blip[answer->fopte[i].op-1])); wvTrace(("type is %d\n",blip->type)); ret = 1; break; } } i++; } } wvTrace(("spid is %x\n",spid)); wvReleaseEscher(&item); return(ret); } int wv0x01(Blip *blip,wvStream *fd,U32 len) { MSOFBH amsofbh; FSPContainer item; U32 count=0; char test[3]; int ret=0; if (fd == NULL) return(0); /* temp hack to test older included bmps in word 6 and 7, should be wrapped in a modern escher strucure before getting to here, and then handled as normal */ test[2] = '\0'; test[0] = read_8ubit(fd); test[1] = read_8ubit(fd); wvStream_rewind(fd); if (!(strcmp(test,"BM"))) { blip->blip.bitmap.m_pvBits = fd; blip->type=msoblipDIB; return(1); } while (count < len) { wvTrace(("count is %x,len is %x\n",count,len)); count += wvGetMSOFBH(&amsofbh,fd); wvTrace(("type is %x\n ",amsofbh.fbt)); switch(amsofbh.fbt) { case msofbtSpContainer: wvTrace(("Container at %x\n",wvStream_tell(fd))); count += wvGetFSPContainer(&item,&amsofbh,fd); wvReleaseFSPContainer(&item); break; case msofbtBSE: wvTrace(("Blip at %x\n",wvStream_tell(fd))); count += wvGetBlip(blip,fd,NULL); ret=1; break; default: wvError(("Not a shape container\n")); return(0); break; } } return(ret); } U32 wvGetFSP(FSP *fsp,wvStream *fd) { fsp->spid = read_32ubit(fd); wvTrace(("SPID is %x\n",fsp->spid)); fsp->grfPersistent = read_32ubit(fd); return(8); } U32 wvGetFSPGR(FSPGR *item,wvStream *fd) { /* It is supposed to be a RECT, but its only 4 long so... */ item->rcgBounds.left = read_32ubit(fd); item->rcgBounds.right = read_32ubit(fd); item->rcgBounds.top = read_32ubit(fd); item->rcgBounds.bottom = read_32ubit(fd); return(16); } void wvReleaseFSPContainer(FSPContainer *item) { wvReleaseClientTextbox(&item->clienttextbox); wvReleaseClientData(&item->clientdata); wvReleaseFOPTEArray(&item->fopte); } void wvInitFSPContainer(FSPContainer *item) { wvInitFOPTEArray(&item->fopte); wvInitClientData(&item->clientdata); wvInitClientTextbox(&item->clienttextbox); } U32 wvGetFSPContainer(FSPContainer *item,MSOFBH *msofbh,wvStream *fd) { MSOFBH amsofbh; U32 count=0; wvInitFSPContainer(item); while (count < msofbh->cbLength) { count += wvGetMSOFBH(&amsofbh,fd); wvTrace(("len is %x, type is %x, count %x,fullen %x\n",amsofbh.cbLength,amsofbh.fbt,count,msofbh->cbLength)); wvTrace(("type is %x\n ",amsofbh.fbt)); switch(amsofbh.fbt) { case msofbtSpgr: count += wvGetFSPGR(&item->fspgr,fd); break; case msofbtSp: wvTrace(("Getting an fsp\n")); count += wvGetFSP(&item->fsp,fd); break; case msofbtOPT: count += wvGetFOPTEArray(&item->fopte,&amsofbh,fd); break; case msofbtAnchor: case msofbtChildAnchor: case msofbtClientAnchor: count += wvGetFAnchor(&item->fanchor,fd); break; case msofbtClientData: count +=wvGetClientData(&item->clientdata,&amsofbh,fd); break; case msofbtClientTextbox: count +=wvGetClientTextbox(&item->clienttextbox,&amsofbh,fd); break; case msofbtTextbox: wvError(("unimp\n")); break; case msofbtOleObject: wvError(("unimp\n")); break; case msofbtDeletedPspl: wvError(("unimp\n")); break; default: count +=wvEatmsofbt(&amsofbh,fd); wvError(("Eating type 0x%x\n",amsofbh.fbt)); break; } } return(count); } void wvInitClientData(ClientData *item) { item->data=NULL; } void wvReleaseClientData(ClientData *item) { wvFree(item->data); } U32 wvGetClientData(ClientData *item,MSOFBH *msofbh,wvStream *fd) { U32 i; if (msofbh->cbLength) { item->data=(U8 *)malloc(msofbh->cbLength); for(i=0;icbLength;i++) item->data[i]=read_8ubit(fd); } else item->data=NULL; return(msofbh->cbLength); } U32 wvGetMSOFBH(MSOFBH *amsofbh,wvStream *fd) { U16 dtemp=0; dtemp=read_16ubit(fd); #ifdef PURIFY amsofbh->ver = 0; amsofbh->inst = 0; #endif amsofbh->ver = dtemp & 0x000F; amsofbh->inst = dtemp >> 4; amsofbh->fbt = read_16ubit(fd); amsofbh->cbLength = read_32ubit(fd); return(8); } U32 wvEatmsofbt(MSOFBH *amsofbh,wvStream *fd) { U32 i; for(i=0;icbLength;i++) read_8ubit(fd); return(amsofbh->cbLength); } void wvInitClientTextbox(ClientTextbox *item) { item->textid=NULL; } void wvReleaseClientTextbox(ClientTextbox *item) { wvFree(item->textid); } U32 wvGetClientTextbox(ClientTextbox *item,MSOFBH *amsofbh,wvStream *fd) { item->textid = (U32 *)malloc(amsofbh->cbLength); *item->textid = read_32ubit(fd); return(amsofbh->cbLength); }