Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

frame.c

Go to the documentation of this file.
00001 /*===========================================================================*
00002  * frame.c                                                                   *
00003  *                                                                           *
00004  *      basic frame procedures                                               *
00005  *                                                                           *
00006  * EXPORTED PROCEDURES:                                                      *
00007  *      Frame_Init                                                           *
00008  *      Frame_Exit                                                           *
00009  *      Frame_New                                                            *
00010  *      Frame_Free                                                           *
00011  *      Frame_AllocPPM                                                       *
00012  *      Frame_AllocBlocks                                                    *
00013  *      Frame_AllocYCC                                                       *
00014  *      Frame_AllocDecoded                                                   *
00015  *      Frame_AllocHalf                                                      *
00016  *      Frame_Resize                                                         * 
00017  *                                                                           *
00018  *===========================================================================*/
00019 
00020 /*
00021  * Copyright (c) 1995 The Regents of the University of California.
00022  * All rights reserved.
00023  *
00024  * Permission to use, copy, modify, and distribute this software and its
00025  * documentation for any purpose, without fee, and without written agreement is
00026  * hereby granted, provided that the above copyright notice and the following
00027  * two paragraphs appear in all copies of this software.
00028  *
00029  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
00030  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00031  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
00032  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00035  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00036  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00037  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
00038  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00039  */
00040 
00041 
00042 /*==============*
00043  * HEADER FILES *
00044  *==============*/
00045 
00046 #include "all.h"
00047 #include "mtypes.h"
00048 #include "frames.h"
00049 #include "frame.h"
00050 #include "fsize.h"
00051 #include "dct.h"
00052 
00053 /*===========*
00054  * CONSTANTS *
00055  *===========*/
00056 
00057 /* The maximum number of B-Frames allowed between reference frames. */
00058 #define  B_FRAME_RUN  16    
00059 
00060 /*==================*
00061  * GLOBAL VARIABLES *
00062  *==================*/
00063 
00064 MpegFrame      *frameMemory[B_FRAME_RUN+2];
00065 extern boolean stdinUsed;
00066 extern char    *framePattern;
00067 
00068 
00069 /*===============================*
00070  * INTERNAL PROCEDURE prototypes *
00071  *===============================*/
00072 
00073 static void FreeFrame _ANSI_ARGS_((MpegFrame * mf));
00074 static MpegFrame *GetUnusedFrame _ANSI_ARGS_((void));
00075 static void GetNumOfFrames _ANSI_ARGS_((int *numOfFrames));
00076 static void ResetFrame _ANSI_ARGS_((int fnumber, int type, MpegFrame *frame));
00077 static void Resize_Width _ANSI_ARGS_((MpegFrame *omfrw,MpegFrame *mfrw, int in_x,
00078        int in_y, int out_x));
00079 static void Resize_Height _ANSI_ARGS_((MpegFrame *omfrh,MpegFrame *mfrh,
00080        int in_x,
00081        int in_y,  int out_y));
00082 static void Resize_Array_Width _ANSI_ARGS_((uint8 **inarray,int in_x,
00083        int in_y,uint8 **outarray, int out_x));
00084 static void Resize_Array_Height _ANSI_ARGS_((uint8 **inarray,int in_x,
00085        int in_y,uint8 **outarray, int out_y));
00086 
00087 
00088 /*=====================*
00089  * EXPORTED PROCEDURES *
00090  *=====================*/
00091 
00092 /*===============================================================
00093  *
00094  * Frame_Resize                  by James Boucher
00095  *                Boston University Multimedia Communications Lab
00096  *  
00097  *     This function takes the mf input frame, read in READFrame(),
00098  * and resizes all the input component arrays to the output
00099  * dimensions specified in the parameter file as OUT_SIZE.
00100  * The new frame is returned with the omf pointer.  As well,
00101  * the values of Fsize_x and Fsize_y are adjusted.
00102  ***************************************************************/
00103 void
00104  Frame_Resize(omf,mf,insize_x,insize_y,outsize_x,outsize_y)
00105  MpegFrame *omf,*mf;
00106  int insize_x,insize_y,outsize_x,outsize_y;
00107 {
00108 MpegFrame *frameA;  /* intermediate frame */
00109 
00110 frameA = (MpegFrame *)malloc(sizeof(MpegFrame));
00111 
00112 if((insize_x != outsize_x)&&(insize_y != outsize_y)){
00113 Resize_Width(frameA,mf,insize_x,insize_y,outsize_x);
00114 Resize_Height(omf,frameA,outsize_x,insize_y,outsize_y);
00115 }else 
00116 if((insize_x ==outsize_x)&&(insize_y != outsize_y)){
00117 Resize_Height(omf,mf,insize_x,insize_y,outsize_y);
00118 } else
00119 if((insize_x !=outsize_x)&&(insize_y == outsize_y)){
00120 Resize_Width(omf,mf,insize_x,insize_y,outsize_x);
00121 }
00122 else{
00123   exit(1);
00124   }
00125 /* Free memory */
00126 free(frameA);
00127 free(mf);
00128 }
00129 /*========================================================
00130 * Resize_Width
00131 *======================================================*/
00132 static void  
00133 Resize_Width(omfrw,mfrw,in_x,in_y, out_x)
00134 MpegFrame *omfrw,*mfrw;
00135 int in_x,in_y, out_x;
00136 {
00137 register int y;
00138 int i;
00139 
00140 omfrw->orig_y = NULL;
00141 Fsize_x = out_x;
00142 /* Allocate new frame memory */
00143     omfrw->orig_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
00144     ERRCHK(omfrw->orig_y, "malloc");
00145     for (y = 0; y < Fsize_y; y++) {
00146         omfrw->orig_y[y] = (uint8 *) malloc(sizeof(uint8) * out_x);
00147         ERRCHK(omfrw->orig_y[y], "malloc");
00148     }
00149 
00150     omfrw->orig_cr = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
00151     ERRCHK(omfrw->orig_cr, "malloc");
00152     for (y = 0; y < Fsize_y / 2; y++) {
00153         omfrw->orig_cr[y] = (uint8 *) malloc(sizeof(int8) * out_x / 2);
00154         ERRCHK(omfrw->orig_cr[y], "malloc");
00155     }
00156 
00157     omfrw->orig_cb = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
00158     ERRCHK(omfrw->orig_cb, "malloc");
00159     for (y = 0; y < Fsize_y / 2; y++) {
00160         omfrw->orig_cb[y] = (uint8 *) malloc(sizeof(int8) * out_x / 2);
00161         ERRCHK(omfrw->orig_cb[y], "malloc");
00162     }
00163 
00164     if ( referenceFrame == ORIGINAL_FRAME ) {
00165         omfrw->ref_y = omfrw->orig_y;
00166         omfrw->ref_cr = omfrw->orig_cr;
00167         omfrw->ref_cb = omfrw->orig_cb;
00168     }
00169 
00170 /* resize each component array separately */
00171 Resize_Array_Width(mfrw->orig_y,in_x,in_y,omfrw->orig_y,out_x);
00172 Resize_Array_Width(mfrw->orig_cr,(in_x/2),(in_y/2),omfrw->orig_cr,(out_x/2));
00173 Resize_Array_Width(mfrw->orig_cb,(in_x/2),(in_y/2),omfrw->orig_cb,(out_x/2));
00174 
00175 /* Free old frame memory */
00176     if (mfrw->orig_y) {
00177         for (i = 0; i < in_y; i++) {
00178             free(mfrw->orig_y[i]);
00179         }
00180         free(mfrw->orig_y);
00181 
00182         for (i = 0; i < in_y / 2; i++) {
00183             free(mfrw->orig_cr[i]);
00184         }
00185         free(mfrw->orig_cr);
00186 
00187         for (i = 0; i < in_y / 2; i++) {
00188             free(mfrw->orig_cb[i]);
00189         }
00190         free(mfrw->orig_cb);
00191     }
00192 
00193 }
00194 
00195 /*=======================================================
00196 * Resize_Height
00197 *
00198 *   Resize Frame height up or down
00199 *=======================================================*/
00200 static  void
00201 Resize_Height(omfrh,mfrh,in_x,in_y,out_y)
00202 MpegFrame *omfrh,*mfrh;
00203 int in_x,in_y, out_y;
00204 {
00205 register int y; 
00206 int i;
00207 
00208 Fsize_y = out_y;
00209 
00210 /* Allocate new frame memory */
00211     omfrh->orig_y = (uint8 **) malloc(sizeof(uint8 *) * out_y);
00212     ERRCHK(omfrh->orig_y, "malloc");
00213     for (y = 0; y < out_y; y++) {
00214         omfrh->orig_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x);
00215         ERRCHK(omfrh->orig_y[y], "malloc");
00216     }
00217 
00218     omfrh->orig_cr = (uint8 **) malloc(sizeof(int8 *) * out_y / 2);
00219     ERRCHK(omfrh->orig_cr, "malloc");
00220     for (y = 0; y < out_y / 2; y++) {
00221         omfrh->orig_cr[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2);
00222         ERRCHK(omfrh->orig_cr[y], "malloc");
00223     }
00224 
00225     omfrh->orig_cb = (uint8 **) malloc(sizeof(int8 *) * out_y / 2);
00226     ERRCHK(omfrh->orig_cb, "malloc");
00227     for (y = 0; y < out_y / 2; y++) {
00228         omfrh->orig_cb[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2);
00229         ERRCHK(omfrh->orig_cb[y], "malloc");
00230     }
00231 
00232     if ( referenceFrame == ORIGINAL_FRAME ) {
00233         omfrh->ref_y = omfrh->orig_y;
00234         omfrh->ref_cr = omfrh->orig_cr;
00235         omfrh->ref_cb = omfrh->orig_cb;
00236     }
00237 
00238 /* resize component arrays separately */
00239 Resize_Array_Height(mfrh->orig_y,in_x,in_y,omfrh->orig_y,out_y);
00240 Resize_Array_Height(mfrh->orig_cr,(in_x/2),(in_y/2),omfrh->orig_cr,(out_y/2));
00241 Resize_Array_Height(mfrh->orig_cb,(in_x/2),(in_y/2),omfrh->orig_cb,(out_y/2));
00242 
00243 /* Free old frame memory */
00244     if (mfrh->orig_y) {
00245         for (i = 0; i < in_y; i++) {
00246             free(mfrh->orig_y[i]);
00247         }
00248         free(mfrh->orig_y);
00249 
00250         for (i = 0; i < in_y / 2; i++) {
00251             free(mfrh->orig_cr[i]);
00252         }
00253         free(mfrh->orig_cr);
00254 
00255         for (i = 0; i < in_y / 2; i++) {
00256             free(mfrh->orig_cb[i]);
00257         }
00258         free(mfrh->orig_cb);
00259     }
00260 
00261 }
00262 /*====================================================
00263 * Resize_Array_Width
00264 *    
00265 *   This function will resize any array width up
00266 * or down in size.  The algorithm is based on the
00267 * least common multiple approach more commonly
00268 * used in audio frequency adjustments.
00269 *=====================================================*/
00270 static void 
00271 Resize_Array_Width(inarray,in_x,in_y,outarray,out_x)
00272 uint8 **inarray;
00273 int in_x;
00274 int in_y;
00275 uint8 **outarray;
00276 int out_x;
00277 {
00278 int i,j; 
00279 int in_total;
00280 int out_total;
00281 uint8 *inptr;
00282 uint8 *outptr;
00283 uint8 pointA,pointB;
00284 /* double slope,diff; */
00285 
00286  for(i=0;i<in_y;i++){     /* For every row */
00287   inptr = &inarray[i][0];
00288   outptr = &outarray[i][0];
00289   in_total = 0;
00290   out_total = 0;
00291   for(j=0;j<out_x;j++){      /* For every output value */
00292     if(in_total == out_total){  
00293       *outptr = *inptr;
00294       outptr++;
00295       out_total=out_total+in_x;
00296       while(in_total < out_total){
00297         in_total = in_total + out_x;
00298         inptr++;
00299       }
00300       if(in_total > out_total){
00301         in_total = in_total - out_x;
00302         inptr--;
00303       }
00304     } else {  
00305       pointA = *inptr;
00306       inptr++;
00307       pointB = *inptr;
00308       inptr--;
00309 /*Interpolative solution */
00310 /*      slope = ((double)(pointB -pointA))/((double)(out_x));
00311       diff = (((double)(out_total - in_total)));
00312       if(diff < (out_x/2)){
00313       *outptr = (pointA + (uint8)(slope*diff));
00314     } else {
00315       *outptr = (pointB - (uint8)(slope*(((float)(out_x)) - diff)));
00316     } */
00317 /* Non-Interpolative solution */
00318     *outptr = *inptr;  
00319 
00320       outptr++;
00321       out_total=out_total+in_x;
00322       while(in_total < out_total){
00323         in_total = in_total + out_x;
00324         inptr++;
00325       }
00326       if(in_total > out_total){
00327         in_total = in_total - out_x;
00328         inptr--;
00329       }
00330     }  /* end if */
00331   }  /* end for each output value */
00332 
00333  }  /* end for each row */
00334 }  /* end main */
00335 /*==============================
00336 * Resize_Array_Height
00337 *
00338 *    Resize any array height larger or smaller.
00339 * Same as Resize_array_Width except pointer
00340 * manipulation must change.
00341 *===============================*/
00342 static void 
00343 Resize_Array_Height(inarray,in_x,in_y,outarray,out_y)
00344 uint8 **inarray;
00345 int in_x;
00346 int in_y;
00347 uint8 **outarray;
00348 int out_y;
00349 {
00350 int i,j,k; 
00351 int in_total;
00352 int out_total;
00353 uint8 pointA,pointB;
00354 double slope,diff;
00355 
00356  for(i=0;i<in_x;i++){    /* for each column */
00357   in_total = 0;
00358   out_total = 0;
00359   k = 0;
00360   for(j=0;j<out_y;j++){  /* for each output value */
00361     if(in_total == out_total){  
00362       outarray[j][i] = inarray[k][i];
00363       out_total=out_total+in_y;
00364       while(in_total < out_total){
00365         in_total = in_total + out_y;
00366         k++;
00367       }
00368       if(in_total > out_total){
00369         in_total = in_total - out_y;
00370         k--;
00371       }
00372     } else {  
00373  
00374       pointA = inarray[k][i];
00375       if(k != (in_y -1)){
00376       pointB = inarray[k+1][i];
00377       } else {
00378       pointB = pointA;
00379       }
00380 /* Interpolative case */
00381       slope = ((double)(pointB -pointA))/(double)(out_y);
00382       diff = (double)(out_total - in_total);
00383 /*      outarray[j][i] = (inarray[k][i] + (uint8)(slope*diff));
00384 */
00385 /* Non-Interpolative case */
00386     outarray[j][i] = inarray[k][i];
00387       out_total=out_total+in_y;
00388       while(in_total < out_total){
00389         in_total = in_total + out_y;
00390         k++;
00391       }
00392       if(in_total > out_total){
00393         in_total = in_total - out_y;
00394         k--;
00395       }
00396     } 
00397   }
00398  }
00399 
00400 }
00401 
00402 
00403 
00404 /*===========================================================================*
00405  *
00406  * Frame_Init
00407  *
00408  *      initializes the memory associated with all frames ever
00409  *      If the input is not coming in from stdin, only 3 frames are needed ;
00410  *      else, the program must create frames equal to the greatest distance
00411  *      between two reference frames to hold the B frames while it is parsing
00412  *      the input from stdin.
00413  *
00414  * RETURNS:     nothing
00415  *
00416  * SIDE EFFECTS:    frameMemory
00417  *
00418  *===========================================================================*/
00419 void
00420 Frame_Init()
00421 {
00422     register int idx;
00423     int numOfFrames = 0;
00424 
00425     GetNumOfFrames(&numOfFrames);
00426 
00427     for ( idx = 0; idx < numOfFrames; idx++ ) {
00428         frameMemory[idx] = (MpegFrame *) malloc(sizeof(MpegFrame));
00429         frameMemory[idx]->inUse = FALSE;
00430         frameMemory[idx]->ppm_data = NULL;
00431         frameMemory[idx]->rgb_data = NULL;
00432         frameMemory[idx]->orig_y = NULL;        /* if NULL, then orig_cr, orig_cb invalid */
00433         frameMemory[idx]->y_blocks = NULL; /* if NULL, then cr_blocks, cb_blocks invalid */
00434         frameMemory[idx]->decoded_y = NULL;     /* if NULL, then blah blah */
00435         frameMemory[idx]->halfX = NULL;
00436         frameMemory[idx]->next = NULL;
00437     }
00438 
00439 #ifdef BLEAH
00440 fprintf (stderr, "%d frames allocated.\n", numOfFrames);
00441 #endif
00442 }
00443 
00444 
00445 /*===========================================================================*
00446  *
00447  * Frame_Exit
00448  *
00449  *      frees the memory associated with frames
00450  *
00451  * RETURNS:     nothing
00452  *
00453  * SIDE EFFECTS:    frameMemory
00454  *
00455  *===========================================================================*/
00456 void
00457 Frame_Exit()
00458 {
00459     register int idx;
00460     int numOfFrames = 0;
00461 
00462     GetNumOfFrames(&numOfFrames);
00463 
00464     for ( idx = 0; idx < numOfFrames; idx++ ) {
00465         FreeFrame(frameMemory[idx]);
00466     }
00467 }
00468 
00469 
00470 /*===========================================================================*
00471  *
00472  * Frame_Free
00473  *
00474  *      frees the given frame -- allows it to be re-used
00475  *
00476  * RETURNS:     nothing
00477  *
00478  * SIDE EFFECTS:    none
00479  *
00480  *===========================================================================*/
00481 void
00482 Frame_Free(frame)
00483     MpegFrame *frame;
00484 {
00485     frame->inUse = FALSE;
00486 }
00487 
00488 
00489 /*===========================================================================*
00490  *
00491  * Frame_New
00492  *
00493  *      finds a frame that isn't currently being used and resets it
00494  *
00495  * RETURNS:     the frame
00496  *
00497  * SIDE EFFECTS:    none
00498  *
00499  *===========================================================================*/
00500 MpegFrame *
00501 Frame_New(id, type)
00502     int id;
00503     int type;
00504 {
00505     MpegFrame *frame;
00506 
00507     frame = GetUnusedFrame();
00508     ResetFrame(id, type, frame);
00509 
00510     return frame;
00511 }
00512 
00513 
00514 /*===========================================================================*
00515  *
00516  * Frame_AllocPPM
00517  *
00518  *      allocate memory for ppm data for the given frame, if required
00519  *
00520  * RETURNS:     nothing
00521  *
00522  * SIDE EFFECTS:    none
00523  *
00524  *===========================================================================*/
00525 void
00526 Frame_AllocPPM(frame)
00527     MpegFrame *frame;
00528 {
00529     register int y;
00530 
00531     if ( frame->ppm_data != NULL ) {    /* already allocated */
00532         return;
00533     }
00534 
00535     frame->ppm_data = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
00536     ERRCHK(frame->ppm_data, "malloc");
00537 
00538     for ( y = 0; y < Fsize_y; y++ ) {
00539         frame->ppm_data[y] = (uint8 *) malloc(3*sizeof(uint8) * Fsize_x);
00540         ERRCHK(frame->ppm_data[y], "malloc");
00541     }
00542 }
00543 
00544 
00545 /*===========================================================================*
00546  *
00547  * Frame_AllocBlocks
00548  *
00549  *      allocate memory for blocks for the given frame, if required
00550  *
00551  * RETURNS:     nothing
00552  *
00553  * SIDE EFFECTS:    none
00554  *
00555  *===========================================================================*/
00556 void
00557 Frame_AllocBlocks(frame)
00558     MpegFrame *frame;
00559 {
00560     int dctx, dcty;
00561     int i;
00562 
00563     if ( frame->y_blocks != NULL ) {        /* already allocated */
00564         return;
00565     }
00566 
00567     dctx = Fsize_x / DCTSIZE;
00568     dcty = Fsize_y / DCTSIZE;
00569 
00570     frame->y_blocks = (Block **) malloc(sizeof(Block *) * dcty);
00571     ERRCHK(frame->y_blocks, "malloc");
00572     for (i = 0; i < dcty; i++) {
00573         frame->y_blocks[i] = (Block *) malloc(sizeof(Block) * dctx);
00574         ERRCHK(frame->y_blocks[i], "malloc");
00575     }
00576 
00577     frame->cr_blocks = (Block **) malloc(sizeof(Block *) * (dcty >> 1));
00578     frame->cb_blocks = (Block **) malloc(sizeof(Block *) * (dcty >> 1));
00579     ERRCHK(frame->cr_blocks, "malloc");
00580     ERRCHK(frame->cb_blocks, "malloc");
00581     for (i = 0; i < (dcty >> 1); i++) {
00582         frame->cr_blocks[i] = (Block *) malloc(sizeof(Block) * (dctx >> 1));
00583         frame->cb_blocks[i] = (Block *) malloc(sizeof(Block) * (dctx >> 1));
00584         ERRCHK(frame->cr_blocks[i], "malloc");
00585         ERRCHK(frame->cb_blocks[i], "malloc");
00586     }
00587 }
00588 
00589 
00590 /*===========================================================================*
00591  *
00592  * Frame_AllocYCC
00593  *
00594  *      allocate memory for YCC info for the given frame, if required
00595  *
00596  * RETURNS:     nothing
00597  *
00598  * SIDE EFFECTS:    none
00599  *
00600  *===========================================================================*/
00601 void
00602 Frame_AllocYCC(frame)
00603     MpegFrame *frame;
00604 {
00605     register int y;
00606 
00607     if ( frame->orig_y != NULL ) {      /* already allocated */
00608         return /* nothing */ ;
00609     }
00610 
00611     DBG_PRINT(("ycc_calc:\n"));
00612     /*
00613      * first, allocate tons of memory
00614      */
00615     frame->orig_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
00616     ERRCHK(frame->orig_y, "malloc");
00617     for (y = 0; y < Fsize_y; y++) {
00618         frame->orig_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x);
00619         ERRCHK(frame->orig_y[y], "malloc");
00620     }
00621 
00622     frame->orig_cr = (uint8 **) malloc(sizeof(int8 *) * (Fsize_y >> 1));
00623     ERRCHK(frame->orig_cr, "malloc");
00624     for (y = 0; y < (Fsize_y >> 1); y++) {
00625         frame->orig_cr[y] = (uint8 *) malloc(sizeof(int8) * (Fsize_x >> 1));
00626         ERRCHK(frame->orig_cr[y], "malloc");
00627     }
00628 
00629     frame->orig_cb = (uint8 **) malloc(sizeof(int8 *) * (Fsize_y >> 1));
00630     ERRCHK(frame->orig_cb, "malloc");
00631     for (y = 0; y < (Fsize_y >> 1); y++) {
00632         frame->orig_cb[y] = (uint8 *) malloc(sizeof(int8) * (Fsize_x >> 1));
00633         ERRCHK(frame->orig_cb[y], "malloc");
00634     }
00635 
00636     if ( referenceFrame == ORIGINAL_FRAME ) {
00637         frame->ref_y = frame->orig_y;
00638         frame->ref_cr = frame->orig_cr;
00639         frame->ref_cb = frame->orig_cb;
00640     }
00641 }
00642 
00643 
00644 
00645 /*===========================================================================*
00646  *
00647  * Frame_AllocHalf
00648  *
00649  *      allocate memory for half-pixel values for the given frame, if required
00650  *
00651  * RETURNS:     nothing
00652  *
00653  * SIDE EFFECTS:    none
00654  *
00655  *===========================================================================*/
00656 void
00657 Frame_AllocHalf(frame)
00658     MpegFrame *frame;
00659 {
00660     register int y;
00661 
00662     if ( frame->halfX != NULL ) {
00663         return;
00664     }
00665 
00666         frame->halfX = (uint8 **) malloc(Fsize_y*sizeof(uint8 *));
00667         ERRCHK(frame->halfX, "malloc");
00668         frame->halfY = (uint8 **) malloc((Fsize_y-1)*sizeof(uint8 *));
00669         ERRCHK(frame->halfY, "malloc");
00670         frame->halfBoth = (uint8 **) malloc((Fsize_y-1)*sizeof(uint8 *));
00671         ERRCHK(frame->halfBoth, "malloc");
00672         for ( y = 0; y < Fsize_y; y++ ) {
00673             frame->halfX[y] = (uint8 *) malloc((Fsize_x-1)*sizeof(uint8));
00674             ERRCHK(frame->halfX[y], "malloc");
00675         }
00676         for ( y = 0; y < Fsize_y-1; y++ ) {
00677             frame->halfY[y] = (uint8 *) malloc(Fsize_x*sizeof(uint8));
00678             ERRCHK(frame->halfY[y], "malloc");
00679         }
00680         for ( y = 0; y < Fsize_y-1; y++ ) {
00681             frame->halfBoth[y] = (uint8 *) malloc((Fsize_x-1)*sizeof(uint8));
00682             ERRCHK(frame->halfBoth[y], "malloc");
00683         }
00684 }
00685 
00686 
00687 /*===========================================================================*
00688  *
00689  * Frame_AllocDecoded
00690  *
00691  *      allocate memory for decoded frame for the given frame, if required
00692  *      if makeReference == TRUE, then makes it reference frame
00693  * 
00694  * RETURNS:     nothing
00695  *
00696  * SIDE EFFECTS:    none
00697  *
00698  *===========================================================================*/
00699 void
00700 Frame_AllocDecoded(frame, makeReference)
00701     MpegFrame *frame;
00702     boolean makeReference;
00703 {
00704     register int y;
00705 
00706     if ( frame->decoded_y != NULL) {    /* already allocated */
00707         return;
00708     }
00709 
00710     /* allocate memory for decoded image */
00711     /* can probably reuse original image memory, but may decide to use
00712        it for some reason, so do it this way at least for now -- more
00713        flexible
00714      */
00715     frame->decoded_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
00716     ERRCHK(frame->decoded_y, "malloc");
00717     for (y = 0; y < Fsize_y; y++) {
00718         frame->decoded_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x);
00719         ERRCHK(frame->decoded_y[y], "malloc");
00720     }
00721 
00722     frame->decoded_cr = (uint8 **) malloc(sizeof(int8 *) * (Fsize_y >> 1));
00723     ERRCHK(frame->decoded_cr, "malloc");
00724     for (y = 0; y < (Fsize_y >> 1); y++) {
00725         frame->decoded_cr[y] = (uint8 *) malloc(sizeof(uint8) * (Fsize_x >> 1));
00726         ERRCHK(frame->decoded_cr[y], "malloc");
00727     }
00728 
00729     frame->decoded_cb = (uint8 **) malloc(sizeof(int8 *) * (Fsize_y >> 1));
00730     ERRCHK(frame->decoded_cb, "malloc");
00731     for (y = 0; y < (Fsize_y >> 1); y++) {
00732         frame->decoded_cb[y] = (uint8 *) malloc(sizeof(uint8) * (Fsize_x >> 1));
00733         ERRCHK(frame->decoded_cb[y], "malloc");
00734     }
00735 
00736     if ( makeReference ) {
00737         frame->ref_y = frame->decoded_y;
00738         frame->ref_cr = frame->decoded_cr;
00739         frame->ref_cb = frame->decoded_cb;
00740     }
00741 }
00742 
00743 
00744 /*=====================*
00745  * INTERNAL PROCEDURES *
00746  *=====================*/
00747 
00748 
00749 /*===========================================================================*
00750  *
00751  * GetUnusedFrame
00752  *
00753  *      return an unused frame
00754  *
00755  * RETURNS:     the frame
00756  *
00757  * SIDE EFFECTS:    none
00758  *
00759  *===========================================================================*/
00760 static MpegFrame *
00761 GetUnusedFrame()
00762 {
00763     register int idx;
00764     int numOfFrames;
00765 
00766     GetNumOfFrames(&numOfFrames);
00767 
00768     for ( idx = 0; idx < numOfFrames; idx++ ) {
00769         if ( ! frameMemory[idx]->inUse ) {
00770             frameMemory[idx]->inUse = TRUE;
00771             return frameMemory[idx];
00772         }
00773     }
00774 
00775     fprintf(stderr, "ERROR:  No unused frames!!!\n");
00776     fprintf(stderr, "        If you are using stdin for input, it is likely that you have too many\n");
00777     fprintf(stderr, "        B-frames between two reference frames.  See the man page for help.\n");
00778     exit(1);
00779 }
00780 
00781 
00782 /*===========================================================================*
00783  *
00784  * GetNumOfFrames
00785  *
00786  *      return the number of frames to allocate
00787  *
00788  * RETURNS:     nothing
00789  *
00790  * SIDE EFFECTS:    numOfFrames contains the number to allocate
00791  *
00792  *===========================================================================*/
00793 static void
00794 GetNumOfFrames(numOfFrames)
00795     int *numOfFrames;
00796 {
00797     int idx, bcount;
00798 
00799     if (stdinUsed) {
00800       for ( idx = 0, bcount = 0; idx < strlen(framePattern); idx++) {
00801 
00802         /* counts the maximum number of B frames between two reference
00803          * frames. 
00804          */
00805 
00806         switch( framePattern[idx] ) {
00807           case 'b': 
00808             bcount++;
00809             break;
00810           case 'i':
00811           case 'p':
00812             if (bcount > *numOfFrames) {
00813               *numOfFrames = bcount;
00814             }
00815             bcount = 0;
00816             break;
00817         }
00818 
00819         /* add 2 to hold the forward and past reference frames in addition
00820          * to the maximum number of B's 
00821          */
00822       }
00823 
00824       *numOfFrames += 2;
00825 
00826     } else {
00827       /* non-interactive, only 3 frames needed */
00828       *numOfFrames = 3;
00829     }
00830 }
00831 
00832 /*===========================================================================*
00833  *
00834  * ResetFrame
00835  *
00836  *      reset a frame to the given id and type
00837  *
00838  * RETURNS:     nothing
00839  *
00840  * SIDE EFFECTS:    none
00841  *
00842  *===========================================================================*/
00843 static void
00844 ResetFrame(id, type, frame)
00845     int id;
00846     int type;
00847     MpegFrame *frame;
00848 {
00849     switch (type) {
00850     case 'i':
00851         frame->type = TYPE_IFRAME;
00852         break;
00853     case 'p':
00854         frame->type = TYPE_PFRAME;
00855         break;
00856     case 'b':
00857         frame->type = TYPE_BFRAME;
00858         break;
00859     default:
00860         fprintf(stderr, "frame type %c: not supported\n", type);
00861         exit(1);
00862     }
00863 
00864     frame->id = id;
00865     frame->halfComputed = FALSE;
00866     frame->next = NULL;
00867 }
00868 
00869 
00870 /*===========================================================================*
00871  *
00872  * FreeFrame
00873  *
00874  *      frees the memory associated with the given frame
00875  *
00876  * RETURNS:     nothing
00877  *
00878  * SIDE EFFECTS:    none
00879  *
00880  *===========================================================================*/
00881 static void
00882 FreeFrame(frame)
00883     MpegFrame *frame;
00884 {
00885     int i;
00886 
00887     if (!frame) {
00888         return;
00889     }
00890 
00891     if ( frame->ppm_data ) {
00892         /* it may be a little bigger than Fsize_y, but that's fine for
00893            our purposes, since we aren't going to free until we exit anyway,
00894            so by the time we call this we won't care
00895          */
00896         pnm_freearray(frame->ppm_data, Fsize_y);
00897         frame->ppm_data = NULL;
00898     }
00899 
00900     if (frame->rgb_data) {
00901         pnm_freearray(frame->rgb_data, Fsize_y);
00902     }
00903     if (frame->orig_y) {
00904         for (i = 0; i < Fsize_y; i++) {
00905             free(frame->orig_y[i]);
00906         }
00907         free(frame->orig_y);
00908 
00909         for (i = 0; i < (Fsize_y >> 1); i++) {
00910             free(frame->orig_cr[i]);
00911         }
00912         free(frame->orig_cr);
00913 
00914         for (i = 0; i < (Fsize_y >> 1); i++) {
00915             free(frame->orig_cb[i]);
00916         }
00917         free(frame->orig_cb);
00918     }
00919     if ( frame->decoded_y ) {
00920         for (i = 0; i < Fsize_y; i++) {
00921             free(frame->decoded_y[i]);
00922         }
00923         free(frame->decoded_y);
00924 
00925         for (i = 0; i < (Fsize_y >> 1); i++) {
00926             free(frame->decoded_cr[i]);
00927         }
00928         free(frame->decoded_cr);
00929 
00930         for (i = 0; i < (Fsize_y >> 1); i++) {
00931             free(frame->decoded_cb[i]);
00932         }
00933         free(frame->decoded_cb);
00934     }
00935 
00936     if (frame->y_blocks) {
00937         for (i = 0; i < Fsize_y / DCTSIZE; i++) {
00938             free(frame->y_blocks[i]);
00939         }
00940         free(frame->y_blocks);
00941 
00942         for (i = 0; i < Fsize_y / (2 * DCTSIZE); i++) {
00943             free(frame->cr_blocks[i]);
00944         }
00945         free(frame->cr_blocks);
00946 
00947         for (i = 0; i < Fsize_y / (2 * DCTSIZE); i++) {
00948             free(frame->cb_blocks[i]);
00949         }
00950         free(frame->cb_blocks);
00951     }
00952     if ( frame->halfX ) {
00953         for ( i = 0; i < Fsize_y; i++ ) {
00954             free(frame->halfX[i]);
00955         }
00956         free(frame->halfX);
00957 
00958         for ( i = 0; i < Fsize_y-1; i++ ) {
00959             free(frame->halfY[i]);
00960         }
00961         free(frame->halfY);
00962 
00963         for ( i = 0; i < Fsize_y-1; i++ ) {
00964             free(frame->halfBoth[i]);
00965         }
00966         free(frame->halfBoth);
00967     }
00968 
00969         
00970     free(frame);
00971 }
00972 
00973 
 

Powered by Plone

This site conforms to the following standards: