/************************************************************* Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved. PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research Group. If you use this software, you agree to the following: This program package is purely experimental, and is licensed "as is". Permission is granted to use, modify, and distribute this program without charge for any purpose, provided this license/ disclaimer notice appears in the copies. No warranty or maintenance is given, either expressed or implied. In no event shall the author(s) be liable to you or a third party for any special, incidental, consequential, or other damages, arising out of the use or inability to use the program for any purpose (or the loss of data), even if we have been advised of such possibilities. Any public reference or advertisement of this source code should refer to it as the Portable Video Research Group (PVRG) code, and not by any author(s) (or Stanford University) name. *************************************************************/ /* ************************************************************ io.c This is the IO/ motion frame stuff. It is derived from the JPEG io.c package, so it is somewhat unsuited for fixed-frame ratio fixed component number MPEG work. ************************************************************ */ /*LABEL io.c */ #include #include "globals.h" /*PUBLIC*/ extern void MakeFS(); extern void SuperSubCompensate(); extern void SubCompensate(); extern void AddCompensate(); extern void Sub2Compensate(); extern void Add2Compensate(); extern void MakeMask(); extern void ClearFS(); extern void InitFS(); extern void ReadFS(); extern void InstallIob(); extern void InstallFSIob(); extern void WriteFS(); extern void MoveTo(); extern int Bpos(); extern void ReadBlock(); extern void WriteBlock(); extern void PrintIob(); static void Get4Ptr(); static void Get2Ptr(); /*PRIVATE*/ extern IMAGE *CImage; extern FRAME *CFrame; extern FSTORE *CFStore; extern int FrameInterval; extern int FrameDistance; extern int MVDH; extern int MVDV; extern int MX; extern int MY; extern int NX; extern int NY; extern int Loud; extern int ImageType; int BlockWidth = BLOCKWIDTH; int BlockHeight = BLOCKHEIGHT; static int Mask[64]; static int Nask[64]; IOBUF *Iob; /*START*/ /*BFUNC MakeFS() constructs an IO structure and assorted book-keeping instructions for all components of the frame. EFUNC*/ void MakeFS(flag) int flag; { BEGIN("MakeFS"); int i; CFStore = MakeStructure(FSTORE); CFStore->NumberComponents=CFrame->NumberComponents; for(i=0;iNumberComponents;i++) { if (!(CFStore->Iob[i]=MakeStructure(IOBUF))) { WHEREAMI(); printf("Cannot make IO structure\n"); exit(ERROR_MEMORY); } CFStore->Iob[i]->flag = flag; CFStore->Iob[i]->hpos = 0; CFStore->Iob[i]->vpos = 0; CFStore->Iob[i]->hor = CFrame->hf[i]; CFStore->Iob[i]->ver = CFrame->vf[i]; CFStore->Iob[i]->width = CFrame->Width[i]; CFStore->Iob[i]->height = CFrame->Height[i]; CFStore->Iob[i]->mem = MakeMem(CFrame->Width[i], CFrame->Height[i]); } } /*BFUNC SuperSubCompensate(arrays,) ) subtracts off the compensation from three arrays; subtracts off the compensation from three arrays, forward compensation from the first, backward from the second, interpolated from the third. This is done with a corresponding portion of the memory in the forward and backward IO buffers. EFUNC*/ void SuperSubCompensate(fmcmatrix,bmcmatrix,imcmatrix,XIob,YIob) int *fmcmatrix; int *bmcmatrix; int *imcmatrix; IOBUF *XIob; IOBUF *YIob; { BEGIN("SuperSubCompensate"); int i,/*a,b,*/val; int *mask,*nask; MakeMask(MX, MY, Mask, XIob); MakeMask(NX, NY, Nask, YIob); /* Old stuff pre-SantaClara */ /* a = (16*(FrameInterval - FrameDistance) + FrameInterval/2)/FrameInterval; b = 16 - a; */ for(mask=Mask,nask=Nask,i=0;i<64;i++) { *fmcmatrix++ -= *mask; *bmcmatrix++ -= *nask; /* Old stuff pre-SantaClara */ /* val = a*(*mask++) + b *(*nask++); if (val > 0) {val = (val+8)/16;} else {val = (val-8)/16;} */ /* Should always be positive */ val = ((*mask++)+(*nask++)+1)>>1; *imcmatrix++ -= val; } } /*BFUNC Sub2Compensate() does a subtraction of the prediction from the current matrix with a corresponding portion of the memory in the forward and backward IO buffers. EFUNC*/ void Sub2Compensate(matrix,XIob,YIob) int *matrix; IOBUF *XIob; IOBUF *YIob; { BEGIN("Sub2Compensate"); int i,/*a,b,*/val; int *mask,*nask; MakeMask(MX, MY, Mask, XIob); MakeMask(NX, NY, Nask, YIob); /* Old stuff pre-SantaClara */ /* a = (16*(FrameInterval - FrameDistance) + FrameInterval/2)/FrameInterval; b = 16 - a; */ for(mask=Mask,nask=Nask,i=0;i<64;i++) { /* Old stuff pre-SantaClara */ /* val = a*(*mask++) + b *(*nask++); if (val > 0) {val = (val+8)/16;} else {val = (val-8)/16;} */ val = ((*mask++)+(*nask++)+1)>>1; *matrix++ -= val; } } /*BFUNC Add2Compensate() does an addition of the prediction from the current matrix with a corresponding portion of the memory in the forward and backward IO buffers. EFUNC*/ void Add2Compensate(matrix,XIob,YIob) int *matrix; IOBUF *XIob; IOBUF *YIob; { BEGIN("Add2Compensate"); int i,/*a,b,*/val; int *mask,*nask; MakeMask(MX, MY, Mask, XIob); MakeMask(NX, NY, Nask, YIob); /* Old stuff pre-SantaClara */ /* a = (16*(FrameInterval - FrameDistance) + FrameInterval/2)/FrameInterval; b = 16 - a; */ for(mask=Mask,nask=Nask,i=0;i<64;i++) { /* Old stuff pre-SantaClara */ /* val = a*(*mask++) + b *(*nask++); if (val > 0) {val = (val+8)/16;} else {val = (val-8)/16;} */ val = ((*mask++)+(*nask++)+1)>>1; *matrix += val; if (*matrix>255) {*matrix=255;} else if (*matrix<0){*matrix=0;} matrix++; } } /*BFUNC SubCompensate() does a subtraction of the prediction from the current matrix with a corresponding portion of the memory in the target IO buffer. EFUNC*/ void SubCompensate(matrix,XIob) int *matrix; IOBUF *XIob; { BEGIN("SubCompensate"); int i; int *mask; MakeMask(MX, MY, Mask, XIob); for(mask=Mask,i=0;i<64;i++) *matrix++ -= *mask++; } /*BFUNC AddCompensate() does an addition of the prediction from the current matrix with a corresponding portion of the memory in the target IO buffer. EFUNC*/ void AddCompensate(matrix,XIob) int *matrix; IOBUF *XIob; { BEGIN("AddCompensate"); int i; int *mask; MakeMask(MX, MY, Mask, XIob); for(mask=Mask,i=0;i<64;i++) { *matrix += *mask++; if (*matrix>255) {*matrix=255;} else if (*matrix<0){*matrix=0;} matrix++; } } void MakeMask(x,y,mask,XIob) int x; int y; int *mask; IOBUF *XIob; { BEGIN("MakeMask"); int i,j,rx,ry,dx,dy; unsigned char *aptr,*bptr,*cptr,*dptr; rx = x>>1; ry = y>>1; dx = x&1; dy = y&1; aptr = (((XIob->vpos * BlockHeight) + ry)*XIob->width) + (XIob->hpos * BlockWidth) + rx + XIob->mem->data; if (dx) { bptr = aptr + dx; if (dy) { cptr = aptr + XIob->width; dptr = cptr + dx; Get4Ptr(XIob->width,mask,aptr,bptr,cptr,dptr); } else { Get2Ptr(XIob->width,mask,aptr,bptr); } } else if (dy) { cptr = aptr + XIob->width; Get2Ptr(XIob->width,mask,aptr,cptr); } else { for(i=0;iwidth; } } } static void Get4Ptr(width,matrix,aptr,bptr,cptr,dptr) int width; int *matrix; unsigned char *aptr; unsigned char *bptr; unsigned char *cptr; unsigned char *dptr; { int i,j; for(i=0;i> 2); } aptr = aptr-BlockWidth+width; bptr = bptr-BlockWidth+width; cptr = cptr-BlockWidth+width; dptr = dptr-BlockWidth+width; } } static void Get2Ptr(width,matrix,aptr,bptr) int width; int *matrix; unsigned char *aptr; unsigned char *bptr; { int i,j; for(i=0;i> 1); } aptr = aptr-BlockWidth+width; bptr = bptr-BlockWidth+width; } } /*BFUNC CopyCFS2FS() copies all of the CFrame Iob's to a given frame store. EFUNC*/ void CopyCFS2FS(fs) FSTORE *fs; { BEGIN("CopyIob2FS"); int i; for(i=0;iNumberComponents;i++) CopyMem(CFStore->Iob[i]->mem,fs->Iob[i]->mem); } /*BFUNC ClearFS() clears the entire frame store passed into it. EFUNC*/ void ClearFS() { BEGIN("ClearFS"); int i; for(i=0;iNumberComponents;i++) ClearMem(CFStore->Iob[i]->mem); } /*BFUNC InitFS() initializes a frame store that is passed into it. It creates the IO structures and the memory structures. EFUNC*/ void InitFS() { BEGIN("InitFS"); int i; for(i=0;iNumberComponents;i++) { if (!(CFStore->Iob[i]=MakeStructure(IOBUF))) { WHEREAMI(); printf("Cannot create IO structure.\n"); exit(ERROR_MEMORY); } CFStore->Iob[i]->flag = 0; CFStore->Iob[i]->hpos = 0; CFStore->Iob[i]->vpos = 0; CFStore->Iob[i]->hor = CFrame->hf[i]; CFStore->Iob[i]->ver = CFrame->vf[i]; CFStore->Iob[i]->width = CFrame->Width[i]; CFStore->Iob[i]->height = CFrame->Height[i]; CFStore->Iob[i]->mem = MakeMem(CFrame->Width[i], CFrame->Height[i]); } } /*BFUNC ReadFS() loads the memory images from the filenames designated in the CFrame structure. EFUNC*/ void ReadFS() { BEGIN("ReadFS"); int i; for(i=0;iNumberComponents;i++) { if (CImage->PartialFrame) CFStore->Iob[i]->mem = LoadPartialMem(CFrame->ComponentFileName[i], CFrame->PWidth[i], CFrame->PHeight[i], CFrame->Width[i], CFrame->Height[i], CFStore->Iob[i]->mem); else CFStore->Iob[i]->mem = LoadMem(CFrame->ComponentFileName[i], CFrame->Width[i], CFrame->Height[i], CFStore->Iob[i]->mem); } } /*BFUNC InstallIob() installs a particular CFrame Iob as the target Iob. EFUNC*/ void InstallIob(index) int index; { BEGIN("InstallIob"); Iob = CFStore->Iob[index]; } void InstallFSIob(fs,index) FSTORE *fs; int index; { Iob = fs->Iob[index]; } /*BFUNC WriteFS() writes the frame store out. EFUNC*/ void WriteFS() { BEGIN("WriteIob"); int i; for(i=0;iNumberComponents;i++) { if (CImage->PartialFrame) SavePartialMem(CFrame->ComponentFileName[i], CFrame->PWidth[i], CFrame->PHeight[i], CFStore->Iob[i]->mem); else SaveMem(CFrame->ComponentFileName[i],CFStore->Iob[i]->mem); } } /*BFUNC MoveTo() moves the installed Iob to a given location designated by the horizontal and vertical offsets. EFUNC*/ void MoveTo(hp,vp,h,v) int hp; int vp; int h; int v; { BEGIN("MoveTo"); Iob->hpos = hp*Iob->hor + h; Iob->vpos = vp*Iob->ver + v; } /*BFUNC Bpos() returns the designated MDU number inside of the frame of the installed Iob given by the input gob, mdu, horizontal and vertical offset. It returns 0 on error. EFUNC*/ int Bpos(hp,vp,h,v) int hp; int vp; int h; int v; { BEGIN("Bpos"); return((vp*Iob->ver + v)*(Iob->width/BlockWidth) + (hp * Iob->hor + h)); } /*BFUNC ReadBlock() reads a block from the currently installed Iob into a designated matrix. EFUNC*/ void ReadBlock(store) int *store; { BEGIN("ReadBlock"); int i,j; unsigned char *loc; loc = Iob->vpos*Iob->width*BlockHeight + Iob->hpos*BlockWidth+Iob->mem->data; for(i=0;iwidth - BlockWidth; } if ((++Iob->hpos % Iob->hor)==0) { if ((++Iob->vpos % Iob->ver) == 0) { if (Iob->hpos < ((Iob->width - 1)/(BlockWidth*Iob->hor))*Iob->hor + 1) { Iob->vpos -= Iob->ver; } else {Iob->hpos = 0;} } else {Iob->hpos -= Iob->hor;} } } /*BFUNC WriteBlock() writes a input matrix as a block into the currently designated IOB structure. EFUNC*/ void WriteBlock(store) int *store; { int i,j; unsigned char *loc; loc = Iob->vpos*Iob->width*BlockHeight + Iob->hpos*BlockWidth+Iob->mem->data; for(i=0;iwidth - BlockWidth; } if ((++Iob->hpos % Iob->hor)==0) { if ((++Iob->vpos % Iob->ver) == 0) { if (Iob->hpos < ((Iob->width - 1)/(BlockWidth*Iob->hor))*Iob->hor + 1) { Iob->vpos -= Iob->ver; } else {Iob->hpos = 0;} } else {Iob->hpos -= Iob->hor;} } } /*BFUNC PrintIob() prints out the current Iob structure to the standard output device. EFUNC*/ void PrintIob() { printf("IOB: %x\n",Iob); if (Iob) { printf("hor: %d ver: %d width: %d height: %d\n", Iob->hor,Iob->ver,Iob->width,Iob->height); printf("flag: %d Memory Structure: %x\n",Iob->flag,Iob->mem); } } /*END*/