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  

readframe.c

Go to the documentation of this file.
00001 /*===========================================================================*
00002  * readframe.c                                                               *
00003  *                                                                           *
00004  *      procedures to read in frames                                         *
00005  *                                                                           *
00006  * EXPORTED PROCEDURES:                                                      *
00007  *      ReadFrame                                                            *
00008  *      SetFileType                                                          *
00009  *      SetFileFormat                                                        *
00010  *                                                                           *
00011  *===========================================================================*/
00012 
00013 /*
00014  * Copyright (c) 1995 The Regents of the University of California.
00015  * All rights reserved.
00016  *
00017  * Permission to use, copy, modify, and distribute this software and its
00018  * documentation for any purpose, without fee, and without written agreement is
00019  * hereby granted, provided that the above copyright notice and the following
00020  * two paragraphs appear in all copies of this software.
00021  *
00022  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
00023  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00024  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
00025  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00028  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00029  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00030  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
00031  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00032  */
00033 
00034 /*  
00035  *  $Header: /misc/elrond0/share/cvs/AFNI/src/mpeg_encodedir/readframe.c,v 1.5 2004/04/02 15:12:41 rwcox Exp $
00036  *  $Log: readframe.c,v $
00037  *  Revision 1.5  2004/04/02 15:12:41  rwcox
00038  *  Cput
00039  *
00040  *  Revision 1.4  2004/02/05 21:32:22  rwcox
00041  *  Cput
00042  *
00043  *  Revision 1.3  2003/12/23 13:50:08  rwcox
00044  *  Cput
00045  *
00046  *  Revision 1.2  2003/12/03 14:46:14  rwcox
00047  *  Cput
00048  *
00049  *  Revision 1.1  2001/12/17 16:11:55  rwcox
00050  *  Cadd
00051  *
00052  *  Revision 1.27  1995/08/14 22:31:40  smoot
00053  *  reads training info from PPms now (needed for piping reads)
00054  *
00055  *  Revision 1.26  1995/08/07 21:48:36  smoot
00056  *  better error reporting, JPG == JPEG now
00057  *
00058  *  Revision 1.25  1995/06/12 20:30:12  smoot
00059  *  added popen for OS2
00060  *
00061  * Revision 1.24  1995/06/08  20:34:36  smoot
00062  * added "b"'s to fopen calls to make MSDOS happy
00063  *
00064  * Revision 1.23  1995/05/03  10:16:01  smoot
00065  * minor compile bug with static f
00066  *
00067  * Revision 1.22  1995/05/02  22:00:12  smoot
00068  * added TUNEing, setting near-black values to black
00069  *
00070  * Revision 1.21  1995/03/27  21:00:01  eyhung
00071  * fixed bug with some long jpeg names
00072  *
00073  * Revision 1.20  1995/02/02  01:05:54  eyhung
00074  * Fixed aAdded error checking for stdin
00075  *
00076  * Revision 1.19  1995/02/01  05:01:12  eyhung
00077  * Removed troubleshooting printf
00078  *
00079  * Revision 1.18  1995/01/31  21:08:16  eyhung
00080  * Improved YUV_FORMAT strings with better algorithm
00081  *
00082  * Revision 1.17  1995/01/27  23:34:09  eyhung
00083  * Removed temporary JPEG files created by JMOVIE input
00084  *
00085  * Revision 1.16  1995/01/27  21:57:43  eyhung
00086  * Added case for reading original JMOVIES
00087  *
00088  * Revision 1.14  1995/01/24  23:47:51  eyhung
00089  * Confusion with Abekas format fixed : all other YUV revisions are wrong
00090  *
00091  * Revision 1.13  1995/01/20  00:02:30  smoot
00092  * added gamma correction
00093  *
00094  * Revision 1.12  1995/01/19  23:09:21  eyhung
00095  * Changed copyrights
00096  *
00097  * Revision 1.11  1995/01/17  22:23:07  aswan
00098  * AbekasYUV chrominance implementation fixed
00099  *
00100  * Revision 1.10  1995/01/17  21:26:25  smoot
00101  * Tore our average on Abekus/Phillips reconstruct
00102  *
00103  * Revision 1.9  1995/01/17  08:22:34  eyhung
00104  * Debugging of ReadAYUV
00105  *
00106  * Revision 1.8  1995/01/16  13:18:24  eyhung
00107  * Interlaced YUV format (e.g. Abekas) support added (slightly buggy)
00108  *
00109  * Revision 1.7  1995/01/16  06:58:23  eyhung
00110  * Added skeleton of ReadAYUV (for Abekas YUV files)
00111  *
00112  * Revision 1.6  1995/01/13  23:22:23  smoot
00113  * Added ReadY, so we can make black&white movies (how artsy!)
00114  *
00115  * Revision 1.5  1994/12/16  00:20:40  smoot
00116  * Now errors out on too small an input file
00117  *
00118  * Revision 1.4  1994/11/12  02:11:59  keving
00119  * nothing
00120  *
00121  * Revision 1.3  1994/03/15  00:27:11  keving
00122  * nothing
00123  *
00124  * Revision 1.2  1993/12/22  19:19:01  keving
00125  * nothing
00126  *
00127  * Revision 1.1  1993/07/22  22:23:43  keving
00128  * nothing
00129  *
00130  */
00131 
00132 
00133 /*==============*
00134  * HEADER FILES *
00135  *==============*/
00136 
00137 #include "all.h"
00138 #include <time.h>
00139 #include <errno.h>
00140 #include <ctype.h>
00141 #include <string.h>
00142 #include <unistd.h>
00143 #include "mtypes.h"
00144 #include "frames.h"
00145 #include "prototypes.h"
00146 #include "parallel.h"
00147 #include "param.h"
00148 #include "readframe.h"
00149 #include "fsize.h"
00150 #include "rgbtoycc.h"
00151 #include "jpeg.h"
00152 #include "opts.h"
00153 
00154 #define PPM_READ_STATE_MAGIC    0
00155 #define PPM_READ_STATE_WIDTH    1
00156 #define PPM_READ_STATE_HEIGHT   2
00157 #define PPM_READ_STATE_MAXVAL   3
00158 #define PPM_READ_STATE_DONE     4
00159 
00160 
00161 /*==================*
00162  * STATIC VARIABLES *
00163  *==================*/
00164 
00165 static int  fileType = BASE_FILE_TYPE;
00166 struct YuvLine {
00167         uint8   data[3072];
00168         uint8   y[1024];
00169         int8    cr[1024];
00170         int8    cb[1024];
00171 };
00172 
00173 
00174 /*==================*
00175  * Portability      *
00176  *==================*/
00177 #ifdef __OS2__
00178   #define popen _popen
00179 #endif
00180    
00181 
00182 /*==================*
00183  * Global VARIABLES *
00184  *==================*/
00185 
00186 extern boolean GammaCorrection;
00187 extern float GammaValue;
00188 extern int outputWidth,outputHeight;
00189 boolean resizeFrame;
00190 char *CurrFile;
00191 
00192 /*===============================*
00193  * INTERNAL PROCEDURE prototypes *
00194  *===============================*/
00195 
00196 static char *ScanNextString _ANSI_ARGS_((char *inputLine, char *string));
00197 static void ReadPNM _ANSI_ARGS_((FILE * fp, MpegFrame * mf));
00198 static boolean  ReadPPM _ANSI_ARGS_((MpegFrame *mf, FILE *fpointer));
00199 static void ReadEYUV _ANSI_ARGS_((MpegFrame * mf, FILE *fpointer,
00200                                  int width, int height));
00201 static void ReadAYUV _ANSI_ARGS_((MpegFrame * mf, FILE *fpointer,
00202                                  int width, int height));
00203 static void SeparateLine _ANSI_ARGS_((FILE *fpointer, struct YuvLine *lineptr,
00204                                      int width));
00205 static void ReadY _ANSI_ARGS_((MpegFrame * mf, FILE *fpointer,
00206                                  int width, int height));
00207 static void ReadSub4 _ANSI_ARGS_((MpegFrame * mf, FILE *fpointer,
00208                                   int width, int height));
00209 static void DoGamma  _ANSI_ARGS_((MpegFrame *mf, int width, int height));
00210 
00211 static void DoKillDim _ANSI_ARGS_((MpegFrame *mf, int w, int h));
00212 
00213 #define safe_fread(ptr,sz,len,fileptr)                           \
00214     if ((safe_read_count=fread(ptr,sz,len,fileptr))!=sz*len) {   \
00215       fprintf(stderr,"Input file too small! (%s)\n",CurrFile);   \
00216       exit(1);}                                                  \
00217 
00218 /*=====================*
00219  * EXPORTED PROCEDURES *
00220  *=====================*/
00221 
00222 
00223 
00224 void    SetResize(set)
00225     boolean     set;
00226 {
00227     resizeFrame = set;
00228 }
00229 
00230 
00231 
00232 /*===========================================================================*
00233  *
00234  * ReadFrame
00235  *
00236  *      reads the given frame, performing conversion as necessary
00237  *      if addPath = TRUE, then must add the current path before the
00238  *      file name
00239  *
00240  * RETURNS:     frame modified
00241  *
00242  * SIDE EFFECTS:    none
00243  *
00244  *===========================================================================*/
00245 void
00246 ReadFrame(frame, fileName, conversion, addPath)
00247     MpegFrame *frame;
00248     char *fileName;
00249     char *conversion;
00250     boolean addPath;
00251 {
00252     FILE    *ifp;
00253     char    command[1024];
00254     char    fullFileName[1024];
00255     MpegFrame    tempFrame;
00256     MpegFrame    *framePtr;
00257 #ifdef BLEAH
00258     static int32    readDiskTime = 0;
00259     int32    diskStartTime, diskEndTime;
00260 
00261 time(&diskStartTime);
00262 #endif
00263 
00264     if ( resizeFrame ) {
00265       tempFrame.inUse = FALSE;
00266       tempFrame.ppm_data = NULL;
00267       tempFrame.rgb_data = NULL;
00268       tempFrame.orig_y = NULL;
00269       tempFrame.y_blocks = NULL;
00270       tempFrame.decoded_y = NULL;
00271       tempFrame.halfX = NULL;
00272       framePtr = &tempFrame;
00273     } else {
00274       framePtr = frame;
00275     }
00276 
00277     if ( addPath ) {
00278       sprintf(fullFileName, "%s/%s", currentPath, fileName);
00279     } else {
00280       sprintf(fullFileName, "%s", fileName);
00281     }
00282 
00283     CurrFile = fullFileName;
00284 
00285 #ifdef BLEAH
00286     if ( ! childProcess ) {
00287     fprintf(stdout, "+++++READING Frame %d  (type %d):  %s\n", framePtr->id,
00288             framePtr->type, fullFileName);
00289     }
00290 #endif
00291 
00292     if ( fileType == ANY_FILE_TYPE ) {
00293     char *convertPtr, *commandPtr, *charPtr;
00294 
00295       if ( stdinUsed ) {
00296         fprintf(stderr, "ERROR : cannot use stdin with INPUT_CONVERT.\n");
00297         exit(1);
00298       }
00299 
00300       /* replace every occurrence of '*' with fullFileName */
00301       convertPtr = conversion;
00302       commandPtr = command;
00303       while ( *convertPtr != '\0' ) {
00304         while ( (*convertPtr != '\0') && (*convertPtr != '*') ) {
00305           *commandPtr = *convertPtr;
00306           commandPtr++;
00307           convertPtr++;
00308         }
00309 
00310         if ( *convertPtr == '*' ) {
00311           /* copy fullFileName */
00312           charPtr = fullFileName;
00313           while ( *charPtr != '\0' ) {
00314             *commandPtr = *charPtr;
00315             commandPtr++;
00316             charPtr++;
00317           }
00318 
00319           convertPtr++;   /* go past '*' */
00320         }
00321       }
00322       *commandPtr = '\0';
00323 
00324       if ( (ifp = popen(command, "r")) == NULL ) {
00325         fprintf(stderr, "ERROR:  Couldn't execute input conversion command:\n");
00326         fprintf(stderr, "\t%s\n", command);
00327         fprintf(stderr, "errno = %d\n", errno);
00328         if ( ioServer ) {
00329           fprintf(stderr, "IO SERVER:  EXITING!!!\n");
00330         } else {
00331           fprintf(stderr, "SLAVE EXITING!!!\n");
00332         }
00333         exit(1);
00334       }
00335     } else if (stdinUsed) {
00336       ifp = stdin;
00337     } else if ( (ifp = fopen(fullFileName, "rb")) == NULL ) {
00338       fprintf(stderr, "ERROR:  Couldn't open input file %s\n",
00339               fullFileName);
00340       exit(1);
00341     }
00342 
00343     switch(baseFormat) {
00344     case YUV_FILE_TYPE:
00345 
00346         /* Encoder YUV */
00347         if ((strncmp (yuvConversion, "EYUV", 4) == 0) ||
00348             (strncmp (yuvConversion, "UCB", 3) == 0) ) 
00349         {
00350             ReadEYUV(framePtr, ifp, realWidth, realHeight);
00351         }
00352 
00353         /* Abekas-type (interlaced) YUV */
00354         else {
00355             ReadAYUV(framePtr, ifp, realWidth, realHeight);
00356         }
00357 
00358         break;
00359     case Y_FILE_TYPE:
00360         ReadY(framePtr, ifp, realWidth, realHeight);
00361         break;
00362     case PPM_FILE_TYPE:
00363         if ( ! ReadPPM(framePtr, ifp) ) {
00364         fprintf(stderr, "Error reading PPM input file!!! (%s)\n", CurrFile);
00365         exit(1);
00366         }
00367         PPMtoYUV(framePtr);
00368         break;
00369     case PNM_FILE_TYPE:
00370         ReadPNM(ifp, framePtr);
00371         PNMtoYUV(framePtr);
00372         break;
00373     case SUB4_FILE_TYPE:
00374         ReadSub4(framePtr, ifp, yuvWidth, yuvHeight);
00375         break;
00376     case JPEG_FILE_TYPE:
00377     case JMOVIE_FILE_TYPE:
00378         ReadJPEG(framePtr, ifp);
00379         break;
00380     default:
00381         break;
00382     }
00383 
00384     if (! stdinUsed) {
00385       if ( fileType == ANY_FILE_TYPE ) {
00386         int errorcode;
00387         if ( (errorcode = pclose(ifp)) != 0) {
00388           fprintf(stderr, "WARNING:  Pclose reported error (%d)\n", errorcode);
00389         }
00390       } else {
00391         fclose(ifp);
00392       }
00393     }
00394     
00395     if ( baseFormat == JMOVIE_FILE_TYPE ) {
00396       remove(fullFileName);
00397     }
00398 
00399     if ( resizeFrame ) {
00400       Frame_Resize(frame, &tempFrame, Fsize_x, Fsize_y, outputWidth, outputHeight);
00401     }
00402 
00403 #ifdef BLEAH
00404 time(&diskEndTime);
00405 
00406 readDiskTime += (diskEndTime-diskStartTime);
00407 
00408 fprintf(stdout, "cumulative disk read time:  %d seconds\n", readDiskTime);
00409 #endif
00410 
00411     if ( GammaCorrection ) {
00412       DoGamma(frame, Fsize_x, Fsize_y);
00413     }
00414 
00415     if ( kill_dim ) {
00416       DoKillDim(frame, Fsize_x, Fsize_y);
00417     }
00418 
00419     MotionSearchPreComputation(frame);
00420 }
00421 
00422 
00423 /*===========================================================================*
00424  *
00425  * SetFileType
00426  *
00427  *      set the file type to be either a base type (no conversion), or
00428  *      any type (conversion required)
00429  *
00430  * RETURNS:     nothing
00431  *
00432  * SIDE EFFECTS:    fileType
00433  *
00434  *===========================================================================*/
00435 void
00436 SetFileType(conversion)
00437     char *conversion;
00438 {
00439     if ( strcmp(conversion, "*") == 0 ) {
00440         fileType = BASE_FILE_TYPE;
00441     } else {
00442         fileType = ANY_FILE_TYPE;
00443     }
00444 }
00445 
00446 
00447 /*===========================================================================*
00448  *
00449  * SetFileFormat
00450  *
00451  *      set the file format (PPM, PNM, YUV, JPEG)
00452  *
00453  * RETURNS:     nothing
00454  *
00455  * SIDE EFFECTS:    baseFormat
00456  *
00457  *===========================================================================*/
00458 void
00459 SetFileFormat(format)
00460     char *format;
00461 {
00462     if ( strcmp(format, "PPM") == 0 ) {
00463         baseFormat = PPM_FILE_TYPE;
00464     } else if ( strcmp(format, "YUV") == 0 ) {
00465         baseFormat = YUV_FILE_TYPE;
00466     } else if ( strcmp(format, "Y") == 0 ) {
00467         baseFormat = Y_FILE_TYPE;
00468     } else if ( strcmp(format, "PNM") == 0 ) {
00469         baseFormat = PNM_FILE_TYPE;
00470     } else if (( strcmp(format, "JPEG") == 0 ) || ( strcmp(format, "JPG") == 0 )) {
00471         baseFormat = JPEG_FILE_TYPE;
00472     } else if ( strcmp(format, "JMOVIE") == 0 ) {
00473         baseFormat = JMOVIE_FILE_TYPE;
00474     } else if ( strcmp(format, "SUB4") == 0 ) {
00475         baseFormat = SUB4_FILE_TYPE;
00476     } else {
00477         fprintf(stderr, "ERROR:  Invalid file format:  %s\n", format);
00478         exit(1);
00479     }
00480 }
00481 
00482 
00483 /*===========================================================================*
00484  *
00485  * ReadPNM
00486  *
00487  *      read a PNM file
00488  *
00489  * RETURNS:     mf modified
00490  *
00491  * SIDE EFFECTS:    none
00492  *
00493  *===========================================================================*/
00494 static void
00495 ReadPNM(fp, mf)
00496     FILE *fp;
00497     MpegFrame *mf;
00498 {
00499     int x, y;
00500     xelval maxval;
00501     int format;
00502 
00503     if (mf->rgb_data) {
00504         pnm_freearray(mf->rgb_data, Fsize_y);
00505     }
00506     mf->rgb_data = pnm_readpnm(fp, &x, &y, &maxval, &format);
00507     ERRCHK(mf, "pnm_readpnm");
00508 
00509     if (format != PPM_FORMAT) {
00510         if (maxval < 255) {
00511             pnm_promoteformat(mf->rgb_data, x, y, maxval, format, 255, PPM_FORMAT);
00512             maxval = 255;
00513         } else {
00514             pnm_promoteformat(mf->rgb_data, x, y, maxval, format, maxval, PPM_FORMAT);
00515         }
00516     }
00517     if (maxval < 255) {
00518         pnm_promoteformat(mf->rgb_data, x, y, maxval, format, 255, format);
00519         maxval = 255;
00520     }
00521     /*
00522      * if this is the first frame read, set the global frame size
00523      */
00524     Fsize_Note(mf->id, x, y);
00525 
00526     mf->rgb_maxval = maxval;
00527     mf->rgb_format = PPM_FORMAT;
00528 }
00529 
00530 
00531 
00532 /*===========================================================================*
00533  *
00534  * ReadIOConvert
00535  *
00536  *      do conversion; return a pointer to the appropriate file
00537  *
00538  * RETURNS:     pointer to the appropriate file
00539  *
00540  * SIDE EFFECTS:    none
00541  *
00542  *===========================================================================*/
00543 FILE *
00544 ReadIOConvert(fileName)
00545     char *fileName;
00546 {
00547     FILE        *ifp;
00548     char        command[1024];
00549     char        fullFileName[1024];
00550     char *convertPtr, *commandPtr, *charPtr;
00551 
00552     sprintf(fullFileName, "%s/%s", currentPath, fileName);
00553 
00554 #ifdef BLEAH
00555     if ( ! childProcess ) {
00556         fprintf(stdout, "+++++READING (IO CONVERT) Frame %d  (type %d):  %s\n", frame->id,
00557                 frame->type, fullFileName); }
00558 #endif
00559 
00560     if ( strcmp(ioConversion, "*") == 0 ) {
00561       char buff[1024];
00562       ifp = fopen(fullFileName, "rb");
00563       sprintf(buff,"fopen \"%s\"",fullFileName);
00564       ERRCHK(ifp, buff);
00565       return ifp;
00566     }
00567 
00568     /* replace every occurrence of '*' with fullFileName */
00569     convertPtr = ioConversion;
00570     commandPtr = command;
00571     while ( *convertPtr != '\0' ) {
00572         while ( (*convertPtr != '\0') && (*convertPtr != '*') ) {
00573             *commandPtr = *convertPtr;
00574             commandPtr++;
00575             convertPtr++;
00576         }
00577 
00578         if ( *convertPtr == '*' ) {
00579             /* copy fullFileName */
00580             charPtr = fullFileName;
00581             while ( *charPtr != '\0' ) {
00582                 *commandPtr = *charPtr;
00583                 commandPtr++;
00584                 charPtr++;
00585             }
00586 
00587             convertPtr++;   /* go past '*' */
00588         }
00589     }
00590     *commandPtr = '\0';
00591 
00592     if ( (ifp = popen(command, "r")) == NULL ) {
00593         fprintf(stderr, "ERROR:  Couldn't execute input conversion command:\n");
00594         fprintf(stderr, "\t%s\n", command);
00595         fprintf(stderr, "errno = %d\n", errno);
00596         if ( ioServer ) {
00597             fprintf(stderr, "IO SERVER:  EXITING!!!\n");
00598         } else {
00599             fprintf(stderr, "SLAVE EXITING!!!\n");
00600         }
00601         exit(1);
00602     }
00603 
00604     return ifp;
00605 }
00606 
00607 
00608 
00609 /*===========================================================================*
00610  *
00611  * ReadPPM
00612  *
00613  *      read a PPM file
00614  *
00615  * RETURNS:     TRUE if successful; FALSE otherwise; mf modified
00616  *
00617  * SIDE EFFECTS:    none
00618  *
00619  *===========================================================================*/
00620 static boolean
00621 ReadPPM(mf, fpointer)
00622     MpegFrame *mf;
00623     FILE *fpointer;
00624 {
00625     char    inputBuffer[71];
00626     char    string[71];
00627     char    *inputLine;
00628     int     height = 0, width = 0, maxVal=255;
00629     uint8   junk[4096];
00630     register int y;
00631     int     state;
00632     int     safe_read_count;
00633 
00634     state = PPM_READ_STATE_MAGIC;
00635 
00636     while ( state != PPM_READ_STATE_DONE ) {
00637         if ( fgets(inputBuffer, 71, fpointer) == NULL ) {
00638             return FALSE;
00639         }
00640         
00641         inputLine = inputBuffer;
00642  
00643         if ( inputLine[0] == '#' ) {
00644             continue;
00645         }
00646 
00647         if ( inputLine[strlen(inputLine)-1] != '\n' ) {
00648             return FALSE;
00649         }
00650 
00651         switch(state) {
00652             case PPM_READ_STATE_MAGIC:
00653                 if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) {
00654                     return FALSE;
00655                 }
00656 
00657                 if ( strcmp(string, "P6") != 0 ) {
00658                     return FALSE;
00659                 }
00660                 state = PPM_READ_STATE_WIDTH;
00661                 /* no break */
00662             case PPM_READ_STATE_WIDTH:
00663                 if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) {
00664                     if ( inputLine == inputBuffer ) {
00665                         return FALSE;
00666                     } else {
00667                         break;
00668                     }
00669                 }
00670 
00671                 width = atoi(string);
00672 
00673                 state = PPM_READ_STATE_HEIGHT;
00674 
00675                 /* no break */
00676             case PPM_READ_STATE_HEIGHT:
00677                 if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) {
00678                     if ( inputLine == inputBuffer ) {
00679                         return FALSE;
00680                     } else {
00681                         break;
00682                     }
00683                 }
00684 
00685                 height = atoi(string);
00686 
00687                 state = PPM_READ_STATE_MAXVAL;
00688 
00689                 /* no break */
00690             case PPM_READ_STATE_MAXVAL:
00691                 if ( (inputLine = ScanNextString(inputLine, string)) == NULL ) {
00692                     if ( inputLine == inputBuffer ) {
00693                         return FALSE;
00694                     } else {
00695                         break;
00696                     }
00697                 }
00698 
00699                 maxVal = atoi(string);
00700 
00701                 state = PPM_READ_STATE_DONE;
00702                 break;
00703         } /* end of switch */
00704     }
00705 
00706     Fsize_Note(mf->id, width, height);
00707 
00708     mf->rgb_maxval = maxVal;
00709 
00710     Frame_AllocPPM(mf);
00711 
00712     for ( y = 0; y < Fsize_y; y++ ) {
00713         safe_fread(mf->ppm_data[y], sizeof(char), 3*Fsize_x, fpointer);
00714 
00715         /* read the leftover stuff on the right side */
00716         safe_fread(junk, sizeof(char), 3*(width-Fsize_x), fpointer);
00717     }
00718 
00719     /* read the leftover stuff to prevent broken pipe */
00720     for ( y=Fsize_y; y<height; ++y ) {
00721       safe_fread(junk, sizeof(char), 3*Fsize_x, fpointer);
00722     }
00723     return TRUE;
00724 }
00725 
00726 
00727 /*===========================================================================*
00728  *
00729  * ReadEYUV
00730  *
00731  *      read a Encoder-YUV file (concatenated Y, U, and V)
00732  *
00733  * RETURNS:     mf modified
00734  *
00735  * SIDE EFFECTS:    none
00736  *
00737  *===========================================================================*/
00738 static void
00739 ReadEYUV(mf, fpointer, width, height)
00740     MpegFrame *mf;
00741     FILE *fpointer;
00742     int width;
00743     int height;
00744 {
00745     register int y;
00746     uint8   junk[4096];
00747     int     safe_read_count;
00748 
00749     Fsize_Note(mf->id, width, height);
00750 
00751     Frame_AllocYCC(mf);
00752 
00753     for (y = 0; y < Fsize_y; y++) {                     /* Y */
00754         safe_fread(mf->orig_y[y], 1, Fsize_x, fpointer);
00755 
00756         /* read the leftover stuff on the right side */
00757         if ( width != Fsize_x ) {
00758             safe_fread(junk, 1, width-Fsize_x, fpointer);
00759         }
00760     }
00761 
00762     /* read the leftover stuff on the bottom */
00763     for (y = Fsize_y; y < height; y++) {
00764         safe_fread(junk, 1, width, fpointer);
00765     }
00766 
00767     for (y = 0; y < (Fsize_y >> 1); y++) {                      /* U */
00768         safe_fread(mf->orig_cb[y], 1, Fsize_x >> 1, fpointer);
00769 
00770         /* read the leftover stuff on the right side */
00771         if ( width != Fsize_x ) {
00772             safe_fread(junk, 1, (width-Fsize_x)>>1, fpointer);
00773         }
00774     }
00775 
00776     /* read the leftover stuff on the bottom */
00777     for (y = (Fsize_y >> 1); y < (height >> 1); y++) {
00778         safe_fread(junk, 1, width>>1, fpointer);
00779     }
00780 
00781     for (y = 0; y < (Fsize_y >> 1); y++) {                      /* V */
00782         safe_fread(mf->orig_cr[y], 1, Fsize_x >> 1, fpointer);
00783 
00784         /* read the leftover stuff on the right side */
00785         if ( width != Fsize_x ) {
00786             safe_fread(junk, 1, (width-Fsize_x)>>1, fpointer);
00787         }
00788     }
00789 
00790     /* ignore leftover stuff on the bottom */
00791 }
00792 
00793 /*===========================================================================*
00794  *
00795  * ReadAYUV
00796  *
00797  *      read an Abekas-YUV file
00798  *
00799  * RETURNS:     mf modified
00800  *
00801  * SIDE EFFECTS:    none
00802  *
00803  *===========================================================================*/
00804 static void
00805 ReadAYUV(mf, fpointer, width, height)
00806     MpegFrame *mf;
00807     FILE *fpointer;
00808     int width;
00809     int height;
00810 {
00811     register int x, y;
00812     struct  YuvLine line1, line2;
00813     uint8   junk[4096];
00814     int8    *cbptr, *crptr;
00815     int     safe_read_count;
00816 
00817     Fsize_Note(mf->id, width, height);
00818 
00819     Frame_AllocYCC(mf);
00820 
00821     for (y = 0; y < Fsize_y; y += 2) {
00822         SeparateLine(fpointer, &line1, width);
00823         SeparateLine(fpointer, &line2, width);
00824 
00825         /* Copy the Y values for each line to the frame */
00826         for (x = 0; x < Fsize_x; x++) {
00827             mf->orig_y[y][x]   = line1.y[x];
00828             mf->orig_y[y+1][x] = line2.y[x];
00829         }
00830 
00831         cbptr = &(mf->orig_cb[y>>1][0]);
00832         crptr = &(mf->orig_cr[y>>1][0]);
00833 
00834         /* One U and one V for each two pixels horizontal as well */
00835         /* Toss the second line of Cr/Cb info, averaging was worse,
00836            so just subsample */
00837         for (x = 0; x < (Fsize_x >> 1); x ++) {
00838             cbptr[x] =  line1.cb[x];
00839             crptr[x] =  line1.cr[x];
00840 
00841         }
00842     }
00843 
00844     /* read the leftover stuff on the bottom */
00845     for (y = Fsize_y; y < height; y++) {
00846         safe_fread(junk, 1, width<<1, fpointer);
00847     }
00848 
00849 }
00850 
00851 /*===========================================================================*
00852  *
00853  * SeparateLine
00854  *
00855  *      Separates one line of pixels into Y, U, and V components
00856  *
00857  * RETURNS:     lineptr modified
00858  *
00859  * SIDE EFFECTS:    none
00860  *
00861  *===========================================================================*/
00862 static void
00863 SeparateLine(fpointer, lineptr, width)
00864     FILE *fpointer;
00865     struct YuvLine *lineptr;
00866     int width;
00867 {
00868     uint8   junk[4096];
00869     int8    *crptr, *cbptr;
00870     uint8   *yptr;
00871     int     num, length;
00872     int     safe_read_count;
00873 
00874 
00875     /* Sets the deinterlacing pattern */
00876 
00877         /* shorthand for UYVY */
00878     if (strncmp(yuvConversion, "ABEKAS", 6) == 0) {
00879         strcpy(yuvConversion, "UYVY");
00880 
00881         /* shorthand for YUYV */
00882     } else if (strncmp(yuvConversion, "PHILLIPS", 8) == 0) {
00883         strcpy(yuvConversion, "YUYV");
00884     }
00885 
00886     length = strlen (yuvConversion);
00887 
00888     if ((length % 2) != 0) {
00889         fprintf (stderr, "ERROR : YUV_FORMAT must represent two pixels, hence must be even in length.\n");
00890         exit(1);
00891     }
00892 
00893     /* each line in 4:2:2 chroma format takes 2X bytes to represent X pixels.
00894      * each line in 4:4:4 chroma format takes 3X bytes to represent X pixels.
00895      * Therefore, half of the length of the YUV_FORMAT represents 1 pixel.
00896      */
00897     safe_fread(lineptr->data, 1, Fsize_x*(length>>1), fpointer);
00898 
00899     /* read the leftover stuff on the right side */
00900     if ( width != Fsize_x ) {
00901         safe_fread(junk, 1, (width-Fsize_x)*(length>>1), fpointer);
00902     }
00903 
00904     crptr = &(lineptr->cr[0]);
00905     cbptr = &(lineptr->cb[0]);
00906     yptr = &(lineptr->y[0]);
00907 
00908     for (num = 0; num < (Fsize_x*(length>>1)); num++) {
00909         switch (yuvConversion[num % length]) {
00910         case 'U':
00911         case 'u':
00912             *(cbptr++) = (lineptr->data[num]);
00913             break;
00914         case 'V':
00915         case 'v':
00916             *(crptr++) = (lineptr->data[num]);
00917             break;
00918         case 'Y':
00919         case 'y':
00920             *(yptr++) = (lineptr->data[num]);
00921             break;
00922         default:
00923             fprintf(stderr, "ERROR: YUV_FORMAT must be one of the following:\n");
00924             fprintf(stderr, "       ABEKAS\n");
00925             fprintf(stderr, "       EYUV\n");
00926             fprintf(stderr, "       PHILLIPS\n");
00927             fprintf(stderr, "       UCB\n");
00928             fprintf(stderr, "       or any even-length string consisting of the letters U, V, and Y.\n");
00929             exit(1);
00930         }
00931         
00932     }
00933 
00934 }
00935 
00936 
00937 /*===========================================================================*
00938  *
00939  * ReadY
00940  *
00941  *      read a Y file
00942  *
00943  * RETURNS:     mf modified
00944  *
00945  * SIDE EFFECTS:    none
00946  *
00947  *===========================================================================*/
00948 static void
00949 ReadY(mf, fpointer, width, height)
00950     MpegFrame *mf;
00951     FILE *fpointer;
00952     int width;
00953     int height;
00954 {
00955     register int y;
00956     uint8   junk[4096];
00957     int     safe_read_count;
00958 
00959     Fsize_Note(mf->id, width, height);
00960 
00961     Frame_AllocYCC(mf);
00962 
00963     for (y = 0; y < Fsize_y; y++) {                     /* Y */
00964         safe_fread(mf->orig_y[y], 1, Fsize_x, fpointer);
00965 
00966         /* read the leftover stuff on the right side */
00967         if ( width != Fsize_x ) {
00968             safe_fread(junk, 1, width-Fsize_x, fpointer);
00969         }
00970     }
00971 
00972     /* read the leftover stuff on the bottom */
00973     for (y = Fsize_y; y < height; y++) {
00974         safe_fread(junk, 1, width, fpointer);
00975     }
00976     
00977     for (y = 0 ; y < (Fsize_y >> 1); y++) {
00978       memset(mf->orig_cb[y], 128, (Fsize_x>>1));
00979       memset(mf->orig_cr[y], 128, (Fsize_x>>1));
00980     }
00981 }
00982 
00983 
00984 /*===========================================================================*
00985  *
00986  * ReadSub4
00987  *
00988  *      read a YUV file (subsampled even further by 4:1 ratio)
00989  *
00990  * RETURNS:     mf modified
00991  *
00992  * SIDE EFFECTS:    none
00993  *
00994  *===========================================================================*/
00995 static void
00996 ReadSub4(mf, fpointer, width, height)
00997     MpegFrame *mf;
00998     FILE *fpointer;
00999     int width;
01000     int height;
01001 {
01002     register int y;
01003     register int x;
01004     uint8   buffer[1024];
01005     int     safe_read_count;
01006 
01007     Fsize_Note(mf->id, width, height);
01008 
01009     Frame_AllocYCC(mf);
01010 
01011     for (y = 0; y < (height>>1); y++) {                 /* Y */
01012         safe_fread(buffer, 1, width>>1, fpointer);
01013         for ( x = 0; x < (width>>1); x++ ) {
01014             mf->orig_y[2*y][2*x] = buffer[x];
01015             mf->orig_y[2*y][2*x+1] = buffer[x];
01016             mf->orig_y[2*y+1][2*x] = buffer[x];
01017             mf->orig_y[2*y+1][2*x+1] = buffer[x];
01018         }
01019     }
01020 
01021     for (y = 0; y < (height >> 2); y++) {                       /* U */
01022         safe_fread(buffer, 1, width>>2, fpointer);
01023         for ( x = 0; x < (width>>2); x++ ) {
01024             mf->orig_cb[2*y][2*x] = buffer[x];
01025             mf->orig_cb[2*y][2*x+1] = buffer[x];
01026             mf->orig_cb[2*y+1][2*x] = buffer[x];
01027             mf->orig_cb[2*y+1][2*x+1] = buffer[x];
01028         }
01029     }
01030 
01031     for (y = 0; y < (height >> 2); y++) {                       /* V */
01032         safe_fread(buffer, 1, width>>2, fpointer);
01033         for ( x = 0; x < (width>>2); x++ ) {
01034             mf->orig_cr[2*y][2*x] = buffer[x];
01035             mf->orig_cr[2*y][2*x+1] = buffer[x];
01036             mf->orig_cr[2*y+1][2*x] = buffer[x];
01037             mf->orig_cr[2*y+1][2*x+1] = buffer[x];
01038         }
01039     }
01040 }
01041 
01042 
01043 /*=====================*
01044  * INTERNAL PROCEDURES *
01045  *=====================*/
01046 
01047 /*===========================================================================*
01048  *
01049  * ScanNextString
01050  *
01051  *      read a string from a input line, ignoring whitespace
01052  *
01053  * RETURNS:     pointer to position in input line after string
01054  *              NULL if all whitespace
01055  *              puts string in 'string'
01056  *
01057  * SIDE EFFECTS:    file stream munched a bit
01058  *
01059  *===========================================================================*/
01060 static char *
01061 ScanNextString(inputLine, string)
01062     char *inputLine;
01063     char *string;
01064 {
01065     /* skip whitespace */
01066     while ( isspace(*inputLine) && (*inputLine != '\n') ) {
01067         inputLine++;
01068     }
01069 
01070     if ( *inputLine == '\n' ) {
01071         return NULL;
01072     }
01073 
01074     while ( (! isspace(*inputLine)) && (*inputLine != '\n') ) {
01075         *string = *inputLine;
01076         string++;
01077         inputLine++;
01078     }
01079 
01080     *string = '\0';
01081 
01082     return inputLine;
01083 }
01084 
01085 /*===========================================================================*
01086  *
01087  * DoGamma
01088  *
01089  *      Gamma Correct the Lum values
01090  *
01091  * RETURNS:     nothing
01092  *
01093  * SIDE EFFECTS:    Raises Y values to power gamma.
01094  *
01095  *===========================================================================*/
01096 static void
01097 DoGamma(mf, w, h)
01098 MpegFrame *mf;
01099 int w,h;
01100 {
01101   static int GammaVal[256];
01102   static boolean init_done=FALSE;
01103   int i,j;
01104 
01105   if (!init_done) {
01106     for(i=0; i<256; i++) 
01107       GammaVal[i]=(unsigned char) (pow(((double) i)/255.0,GammaValue)*255.0+0.5);
01108     init_done=TRUE;
01109   }
01110 
01111   for (i=0; i< h; i++) {  /* For each line */
01112     for (j=0; j<w; j++) { /* For each Y value */
01113       mf->orig_y[i][j] = GammaVal[mf->orig_y[i][j]];
01114     }}
01115 }
01116 
01117 
01118 
01119 
01120 /*===========================================================================*
01121  *
01122  * DoKillDim
01123  *
01124  *      Applies an input filter to small Y values.
01125  *
01126  * RETURNS:     nothing
01127  *
01128  * SIDE EFFECTS:    Changes Y values:
01129  *
01130  *  Output    |                 /
01131               |                /
01132               |               /
01133               |              !
01134               |             /
01135               |            !
01136               |           /
01137               |          -
01138               |        /
01139               |      --
01140               |     /
01141               |   --
01142               | /
01143               ------------------------
01144                         ^ kill_dim_break
01145                              ^kill_dim_end
01146               kill_dim_slope gives the slope (y = kill_dim_slope * x +0)
01147               from 0 to kill_dim_break                      
01148  *
01149  *===========================================================================*/
01150 
01151 static void
01152 DoKillDim(mf, w, h)
01153 MpegFrame *mf;
01154 int w,h;
01155 {
01156   static boolean init_done=FALSE;
01157   static unsigned char mapper[256];
01158   register int i,j;
01159   double slope, intercept;
01160 
01161   slope = (kill_dim_end - kill_dim_break*kill_dim_slope)*1.0 /
01162     (kill_dim_end - kill_dim_break);
01163   intercept = kill_dim_end * (1.0-slope);
01164 
01165   if (!init_done) {
01166     for(i=0; i<256; i++) {
01167       if (i >= kill_dim_end) {
01168         mapper[i] = (char) i;
01169       } else if (i >= kill_dim_break) {
01170         mapper[i] = (char) (slope*i + intercept);
01171       } else { /* i <= kill_dim_break */
01172         mapper[i] = (char) floor(i*kill_dim_slope + 0.49999);
01173       }
01174     }
01175     init_done = TRUE;
01176   }
01177 
01178   for (i=0;  i < h;  i++) {  /* For each line */
01179     for (j=0;   j < w;   j++) { /* For each Y value */
01180       mf->orig_y[i][j] = mapper[mf->orig_y[i][j]];
01181     }}
01182 }
 

Powered by Plone

This site conforms to the following standards: