diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
commit | 1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch) | |
tree | 64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/ppm/ppmtompeg/param.c | |
download | netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip |
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/ppm/ppmtompeg/param.c')
-rw-r--r-- | converter/ppm/ppmtompeg/param.c | 1077 |
1 files changed, 1077 insertions, 0 deletions
diff --git a/converter/ppm/ppmtompeg/param.c b/converter/ppm/ppmtompeg/param.c new file mode 100644 index 00000000..5ea69ab6 --- /dev/null +++ b/converter/ppm/ppmtompeg/param.c @@ -0,0 +1,1077 @@ +/*===========================================================================* + * param.c + * + * Procedures to read in parameter file + * + *===========================================================================*/ + +/* COPYRIGHT INFORMATION IS AT THE END OF THIS FILE */ + +#define _XOPEN_SOURCE 500 + /* This makes sure popen() is in stdio.h. In GNU libc 2.1.3, + _POSIX_C_SOURCE = 2 is sufficient, but on AIX 4.3, the higher level + _XOPEN_SOURCE is required. 2000.09.09 + + This also makes sure strdup() is in string.h. + */ +#define _BSD_SOURCE 1 + /* Make sure string.h defines strncasecmp */ + + +/*==============* + * HEADER FILES * + *==============*/ + +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#include "nstring.h" +#include "mallocvar.h" +#include "all.h" +#include "mtypes.h" +#include "mpeg.h" +#include "motion_search.h" +#include "prototypes.h" +#include "parallel.h" +#include "readframe.h" +#include "fsize.h" +#include "frames.h" +#include "jpeg.h" +#include "input.h" +#include "frametype.h" +#include "param.h" + +#include "rate.h" +#include "opts.h" + +/*===========* + * CONSTANTS * + *===========*/ + +#define INPUT_ENTRY_BLOCK_SIZE 128 + +#define FIRST_OPTION 0 +#define OPTION_GOP 0 +#define OPTION_PATTERN 1 +#define OPTION_PIXEL 2 +#define OPTION_PQSCALE 3 +#define OPTION_OUTPUT 4 +#define OPTION_RANGE 5 +#define OPTION_PSEARCH_ALG 6 +#define OPTION_IQSCALE 7 +#define OPTION_INPUT_DIR 8 +#define OPTION_INPUT_CONVERT 9 +#define OPTION_INPUT 10 +#define OPTION_BQSCALE 11 +#define OPTION_BASE_FORMAT 12 +#define OPTION_SPF 13 +#define OPTION_BSEARCH_ALG 14 +#define OPTION_REF_FRAME 15 +#define LAST_OPTION 15 + +/* put any non-required options after LAST_OPTION */ +#define OPTION_RESIZE 16 +#define OPTION_IO_CONVERT 17 +#define OPTION_SLAVE_CONVERT 18 +#define OPTION_IQTABLE 19 +#define OPTION_NIQTABLE 20 +#define OPTION_FRAME_RATE 21 +#define OPTION_ASPECT_RATIO 22 +#define OPTION_YUV_SIZE 23 +#define OPTION_SPECIFICS 24 +#define OPTION_DEFS_SPECIFICS 25 +#define OPTION_BUFFER_SIZE 26 +#define OPTION_BIT_RATE 27 +#define OPTION_USER_DATA 28 +#define OPTION_YUV_FORMAT 29 +#define OPTION_GAMMA 30 +#define OPTION_PARALLEL 31 +#define OPTION_FRAME_INPUT 32 +#define OPTION_GOP_INPUT 33 + +#define NUM_OPTIONS 33 + +/*==================* + * GLOBAL VARIABLES * + *==================*/ + +extern char currentPath[MAXPATHLEN]; +char outputFileName[256]; +int outputWidth, outputHeight; +char inputConversion[1024]; +char ioConversion[1024]; +char slaveConversion[1024]; +char yuvConversion[256]; +char specificsFile[256],specificsDefines[1024]=""; +boolean GammaCorrection=FALSE; +float GammaValue; +char userDataFileName[256]={0}; +boolean specificsOn = FALSE; +char currentGOPPath[MAXPATHLEN]; +char currentFramePath[MAXPATHLEN]; +boolean keepTempFiles; + +static const char * const optionText[LAST_OPTION+1] = { + "GOP_SIZE", "PATTERN", "PIXEL", "PQSCALE", + "OUTPUT", "RANGE", "PSEARCH_ALG", "IQSCALE", "INPUT_DIR", + "INPUT_CONVERT", "INPUT", "BQSCALE", "BASE_FILE_FORMAT", + "SLICES_PER_FRAME", "BSEARCH_ALG", "REFERENCE_FRAME"}; +static boolean optionSeen[NUM_OPTIONS+1]; + /* optionSeen[x] means we have seen option x in the parameter file we've + been reading. + */ + +int numMachines; +char machineName[MAX_MACHINES][256]; +char userName[MAX_MACHINES][256]; +char executable[MAX_MACHINES][1024]; +char remoteParamFile[MAX_MACHINES][1024]; +boolean remote[MAX_MACHINES]; +int mult_seq_headers = 0; /* 0 for none, N for header/N GOPs */ + + +/*===========================================================================* + * + * SkipSpacesTabs + * + * skip all spaces and tabs + * + * RETURNS: point to next character not a space or tab + * + * SIDE EFFECTS: none + * + *===========================================================================*/ +static const char * +SkipSpacesTabs(const char * const start) { + + const char * p; + + for (p = start; *p == ' ' || *p == '\t'; ++p); + + return p; +} + + + +/*===========================================================================* + * + * GetAspectRatio + * + * take a character string with the pixel aspect ratio + * and returns the correct aspect ratio code for use in the Sequence header + * + * RETURNS: aspect ratio code as per MPEG-I spec + * + * SIDE EFFECTS: none + * + *===========================================================================*/ +static int +GetAspectRatio(const char * const p) +{ + float ratio; + int ttRatio; + int retval; + + sscanf(p, "%f", &ratio); + ttRatio = (int)(0.5+ratio*10000.0); + + if ( ttRatio == 10000 ) retval = 1; + else if ( ttRatio == 6735 ) retval = 2; + else if ( ttRatio == 7031 ) retval = 3; + else if ( ttRatio == 7615 ) retval = 4; + else if ( ttRatio == 8055 ) retval = 5; + else if ( ttRatio == 8437 ) retval = 6; + else if ( ttRatio == 8935 ) retval = 7; + else if ( ttRatio == 9157 ) retval = 8; + else if ( ttRatio == 9815 ) retval = 9; + else if ( ttRatio == 10255 ) retval = 10; + else if ( ttRatio == 10695 ) retval = 11; + else if ( ttRatio == 10950 ) retval = 12; + else if ( ttRatio == 11575 ) retval = 13; + else if ( ttRatio == 12015 ) retval = 14; + else { + fprintf(stderr,"INVALID ASPECT RATIO: %s frames/sec\n", p); + exit(1); + } + return retval; +} + + + +/*===========================================================================* + * + * ReadMachineNames + * + * read a list of machine names for parallel execution + * + * RETURNS: nothing + * + * SIDE EFFECTS: machine info updated + * + *===========================================================================*/ +static void +ReadMachineNames(FILE * const fpointer) +{ + char input[256]; + const char *charPtr; + + while ( (fgets(input, 256, fpointer) != NULL) && + (strncmp(input, "END_PARALLEL", 12) != 0) ) { + if ( input[0] == '#' || input[0] == '\n') { + continue; + } + + if ( strncmp(input, "REMOTE", 6) == 0 ) { + charPtr = SkipSpacesTabs(&input[6]); + remote[numMachines] = TRUE; + + sscanf(charPtr, "%s %s %s %s", machineName[numMachines], + userName[numMachines], executable[numMachines], + remoteParamFile[numMachines]); + } else { + remote[numMachines] = FALSE; + + sscanf(input, "%s %s %s", machineName[numMachines], + userName[numMachines], executable[numMachines]); + } + + numMachines++; + } +} + + +/*===========================================================================* + * + * GetFrameRate + * + * take a character string with the input frame rate + * and return the correct frame rate code for use in the Sequence header + * + * RETURNS: frame rate code as per MPEG-I spec + * + * SIDE EFFECTS: none + * + *===========================================================================*/ +static int +GetFrameRate(const char * const p) +{ + float rate; + int thouRate; + int retval; + + sscanf(p, "%f", &rate); + thouRate = (int)(0.5+1000.0*rate); + + if ( thouRate == 23976 ) retval = 1; + else if ( thouRate == 24000 ) retval = 2; + else if ( thouRate == 25000 ) retval = 3; + else if ( thouRate == 29970 ) retval = 4; + else if ( thouRate == 30000 ) retval = 5; + else if ( thouRate == 50000 ) retval = 6; + else if ( thouRate == 59940 ) retval = 7; + else if ( thouRate == 60000 ) retval = 8; + else { + fprintf(stderr,"INVALID FRAME RATE: %s frames/sec\n", p); + exit(1); + } + return retval; +} + + + +static void +mergeInputSource(struct inputSource * const baseSourceP, + struct inputSource * const addedSourceP) { + + unsigned int i; + + baseSourceP->ifArraySize += addedSourceP->numInputFileEntries; + REALLOCARRAY_NOFAIL(baseSourceP->inputFileEntries, + baseSourceP->ifArraySize); + for (i = 0; i < addedSourceP->numInputFileEntries; ++i) + baseSourceP->inputFileEntries[baseSourceP->numInputFileEntries++] = + addedSourceP->inputFileEntries[i]; + + free(addedSourceP); + /* Note the space allocated for the *addedSourceP input file + entries themselves is still allocated, and used by + *baseSourceP. + */ +} + + + +/* Forward declaration for recursively called function */ +static void +ReadInputFileNames(FILE * const fpointer, + const char * const endInput, + struct inputSource * const inputSourceP); + +static void +expandBackTickLine(const char * const input, + struct inputSource * const inputSourceP) { + + FILE *fp; + char cmd[300]; + const char * start; + const char * end; + char cdcmd[110]; + + start = &input[1]; + end = &input[strlen(input)-1]; + + while (*end != '`') { + end--; + } + + end--; + + if (optionSeen[OPTION_INPUT_DIR]) + sprintf(cdcmd,"cd %s;",currentPath); + else + strcpy(cdcmd,""); + + { + char tmp[300]; + strncpy(tmp,start,end-start+1); + sprintf(cmd,"(%s %s)", cdcmd, tmp); + } + + fp = popen(cmd, "r"); + if (fp == NULL) { + pm_error("Unable to resolve backtick entry in input file list. " + "Could not open piped command: '%s'", cmd); + } else { + struct inputSource subInputSource; + ReadInputFileNames(fp, "HOPE-THIS_ISNT_A_FILENAME.xyz5555", + &subInputSource); + + mergeInputSource(inputSourceP, &subInputSource); + } +} + + + +static void +ReadInputFileNames(FILE * const fpointer, + const char * const endInput, + struct inputSource * const inputSourceP) { +/*---------------------------------------------------------------------------- + Read a list of input file names from the parameter file. Add + the information to *inputSourceP. + + If inputSourceP == NULL, read off the list, but ignore it. +-----------------------------------------------------------------------------*/ + char input[256]; + bool endStatementRead; + + /* read param file up through endInput statement. Each line until + endInput is a file specification. + */ + endStatementRead = FALSE; + + while (!endStatementRead) { + char * rc; + rc = fgets(input, sizeof(input), fpointer); + + if (feof(fpointer)) + pm_error("End of file before section end statement '%s'", + endInput); + else if (rc == NULL) + pm_error("Error reading file names from parameter file."); + else { + if (strncmp(input, endInput, strlen(endInput)) == 0) + endStatementRead = TRUE; + else if ((input[0] == '#') || (input[0] == '\n')) { + /* It's a comment or blank line. Ignore it */ + } else if (input[0] == '`' ) { + expandBackTickLine(input, inputSourceP); + } else { + /* get rid of trailing whitespace including newline */ + while (ISSPACE(input[strlen(input)-1])) + input[strlen(input)-1] = '\0'; + if (inputSourceP) + AddInputFiles(inputSourceP, input); + } + } + } +} + + + +static void +initOptionSeen(void) { + + unsigned int index; + + for (index = FIRST_OPTION; index < NUM_OPTIONS; ++index) + optionSeen[index] = FALSE; +} + + + +static void +verifyNoMissingEncodeFramesOption(void) { + if (!optionSeen[OPTION_GOP]) + pm_error("GOP_SIZE option missing"); + if (!optionSeen[OPTION_PATTERN]) + pm_error("PATTERN option missing"); + if (!optionSeen[OPTION_PIXEL]) + pm_error("PIXEL option missing"); + if (!optionSeen[OPTION_PQSCALE]) + pm_error("PQSCALE option missing"); + if (!optionSeen[OPTION_OUTPUT]) + pm_error("OUTPUT option missing"); + if (!optionSeen[OPTION_RANGE]) + pm_error("RANGE option missing"); + if (!optionSeen[OPTION_PSEARCH_ALG]) + pm_error("PSEARCH_ALG option missing"); + if (!optionSeen[OPTION_IQSCALE]) + pm_error("IQSCALE option missing"); + if (!optionSeen[OPTION_INPUT_DIR]) + pm_error("INPUT_DIR option missing"); + if (!optionSeen[OPTION_INPUT_CONVERT]) + pm_error("INPUT_CONVERT option missing"); + if (!optionSeen[OPTION_BQSCALE]) + pm_error("BQSCALE option missing"); + if (!optionSeen[OPTION_BASE_FORMAT]) + pm_error("BASE_FILE_FORMAT option missing"); + if (!optionSeen[OPTION_SPF]) + pm_error("SLICES_PER_FRAME option missing"); + if (!optionSeen[OPTION_BSEARCH_ALG]) + pm_error("BSEARCH_ALG option missing"); + if (!optionSeen[OPTION_REF_FRAME]) + pm_error("REFERENCE_FRAME option missing"); +} + + + +static void +verifyNoMissingCombineGopsOption(void) { + + if (!optionSeen[OPTION_GOP_INPUT]) + pm_error("GOP_INPUT option missing"); + if (!optionSeen[OPTION_YUV_SIZE]) + pm_error("YUV_SIZE option missing"); + if (!optionSeen[OPTION_OUTPUT]) + pm_error("OUTPUT option missing"); +} + + + +static void +verifyNoMissingCombineFramesOption(void) { + + if (!optionSeen[OPTION_GOP]) + pm_error("GOP_SIZE option missing"); + if (!optionSeen[OPTION_YUV_SIZE]) + pm_error("YUV_SIZE option missing"); + if (!optionSeen[OPTION_OUTPUT]) + pm_error("OUTPUT option missing"); +} + + + +static void +verifyNoMissingOption(int const function) { +/*---------------------------------------------------------------------------- + Verify that the parameter file contains every option it is supposed to. + Abort program if not. +-----------------------------------------------------------------------------*/ + switch(function) { + case ENCODE_FRAMES: + verifyNoMissingEncodeFramesOption(); + break; + case COMBINE_GOPS: + verifyNoMissingCombineGopsOption(); + break; + case COMBINE_FRAMES: + verifyNoMissingCombineFramesOption(); + break; + default: + pm_error("Internal error - impossible value for 'function': %d", + function); + } +} + + + +static void +processIqtable(FILE * const fpointer) { + + unsigned int row; + unsigned int col; + char input[256]; + + for (row = 0; row < 8; ++row) { + const char * charPtr; + + fgets(input, 256, fpointer); + charPtr = input; + if (8 != sscanf(charPtr,"%d %d %d %d %d %d %d %d", + &qtable[row*8+0], &qtable[row*8+1], + &qtable[row*8+2], &qtable[row*8+3], + &qtable[row*8+4], &qtable[row*8+5], + &qtable[row*8+6], &qtable[row*8+7])) { + pm_error("Line %d of IQTABLE doesn't have 8 elements!", + row); + } + for (col = 0; col < 8; ++col) { + if ((qtable[row*8+col]<1) || (qtable[row*8+col]>255)) { + pm_message( + "Warning: IQTable Element %1d,%1d (%d) " + "corrected to 1-255.", + row+1, col+1, qtable[row*8+col]); + qtable[row*8+col] = (qtable[row*8+col]<1)?1:255; + } + } + } + + if (qtable[0] != 8) { + pm_message("Warning: IQTable Element 1,1 reset to 8, " + "since it must be 8."); + qtable[0] = 8; + } + customQtable = qtable; +} + + + +static void +setInputSource(int const function, + struct inputSource ** const inputSourcePP, + struct inputSource * const inputSourceP, + struct inputSource * const gopInputSourceP, + struct inputSource * const frameInputSourceP) { +/*---------------------------------------------------------------------------- + Given three the three input sources described by the parameter + file, 'inputSourceP', 'gopInputSourceP', and 'frameInputSourceP', + return as *inputSourcePP the appropriate one of them for the + function 'function', and destroy the other two. +-----------------------------------------------------------------------------*/ + switch (function) { + case ENCODE_FRAMES: + *inputSourcePP = inputSourceP; + DestroyInputSource(gopInputSourceP); + DestroyInputSource(frameInputSourceP); + break; + case COMBINE_GOPS: + *inputSourcePP = gopInputSourceP; + DestroyInputSource(inputSourceP); + DestroyInputSource(frameInputSourceP); + break; + case COMBINE_FRAMES: + *inputSourcePP = frameInputSourceP; + DestroyInputSource(inputSourceP); + DestroyInputSource(gopInputSourceP); + break; + default: + pm_error("INTERNAL ERROR: invalid 'function' %d", function); + } +} + + + +/*=====================* + * EXPORTED PROCEDURES * + *=====================*/ + + + +static void +removeTrailingWhite(const char * const rawLine, + const char ** const editedLineP) { + + char * buffer; + char * p; + + buffer = strdup(rawLine); + + if (!buffer) + pm_error("Unable to get memory to process parameter file"); + + p = buffer + strlen(buffer) - 1; /* Point to last character */ + + /* Position p to just before the trailing white space (might be one + character before beginning of string!) + */ + while (p >= buffer && isspace(*p)) + --p; + + ++p; /* Move to first trailing whitespace character */ + + *p = '\0'; /* Chop off all the trailing whitespace */ + + *editedLineP = buffer; +} + + + +static void +readNiqTable(FILE * const fpointer) { + + unsigned int row; + for (row = 0; row < 8; ++row) { + char input[256]; + unsigned int col; + fgets(input, sizeof(input), fpointer); + if (8 != sscanf(input, "%d %d %d %d %d %d %d %d", + &niqtable[row*8+0], &niqtable[row*8+1], + &niqtable[row*8+2], &niqtable[row*8+3], + &niqtable[row*8+4], &niqtable[row*8+5], + &niqtable[row*8+6], &niqtable[row*8+7])) { + pm_error("Line %d of NIQTABLE doesn't have 8 elements!", + row); + } + for ( col = 0; col < 8; col++ ) { + if ((niqtable[row*8+col]<1) || (niqtable[row*8+col]>255)) { + pm_message( + "Warning: NIQTable Element %1d,%1d (%d) " + "corrected to 1-255.", + row + 1, col + 1, niqtable[row * 8 + col]); + niqtable[row * 8 + col] = (niqtable[row*8+col] < 1) ? 1 : 255; + } + } + } + + customNIQtable = niqtable; +} + + + +static void +processRanges(const char * const arg) { + + int numRanges; + int a, b; + + numRanges = sscanf(arg, "%d %d", &a, &b); + + if (numRanges == 2) + SetSearchRange(a, b); + else if (sscanf(arg, "%d [%d]", &a, &b) == 2) + SetSearchRange(a, b); + else + SetSearchRange(a, a); +} + + + +static void +processParamLine(char const input[], + FILE * const fpointer, + bool * const yuvUsedP, + struct inputSource * const inputSourceP, + struct inputSource * const frameInputSourceP, + struct inputSource * const gopInputSourceP, + struct params * const paramP) { + + switch(input[0]) { + case 'A': + if (STRNEQ(input, "ASPECT_RATIO", 12)) { + aspectRatio = GetAspectRatio(SkipSpacesTabs(&input[12])); + optionSeen[OPTION_ASPECT_RATIO] = TRUE; + } + break; + + case 'B': + if (STRNEQ(input, "BQSCALE", 7)) { + SetBQScale(atoi(SkipSpacesTabs(&input[7]))); + optionSeen[OPTION_BQSCALE] = TRUE; + } else if (STRNEQ(input, "BASE_FILE_FORMAT", 16)) { + const char * arg = SkipSpacesTabs(&input[16]); + SetFileFormat(arg); + if (STRNEQ(arg, "YUV", 3) || STREQ(arg, "Y")) + *yuvUsedP = TRUE; + optionSeen[OPTION_BASE_FORMAT] = TRUE; + } else if (STRNEQ(input, "BSEARCH_ALG", 11)) { + SetBSearchAlg(SkipSpacesTabs(&input[11])); + optionSeen[OPTION_BSEARCH_ALG] = TRUE; + } else if (STRNEQ(input, "BIT_RATE", 8)) { + setBitRate(SkipSpacesTabs(&input[8])); + optionSeen[OPTION_BIT_RATE] = TRUE; + } else if (STRNEQ(input, "BUFFER_SIZE", 11)) { + setBufferSize(SkipSpacesTabs(&input[11])); + optionSeen[OPTION_BUFFER_SIZE] = TRUE; + } + break; + + case 'C': + if (STRNEQ(input, "CDL_FILE", 8)) { + strcpy(specificsFile, SkipSpacesTabs(&input[8])); + specificsOn = TRUE; + optionSeen[OPTION_SPECIFICS] = TRUE; + } else if (STRNEQ(input, "CDL_DEFINES", 11)) { + strcpy(specificsDefines, SkipSpacesTabs(&input[11])); + optionSeen[OPTION_DEFS_SPECIFICS] = TRUE; + } + break; + + case 'F': + if (STRNEQ(input, "FRAME_INPUT_DIR", 15)) { + const char * const arg = SkipSpacesTabs(&input[15]); + if (STRNCASEEQ(arg, "stdin", 5)) + SetStdinInput(frameInputSourceP); + + strcpy(currentFramePath, arg); + } else if (STRNEQ(input, "FRAME_INPUT", 11)) { + ReadInputFileNames(fpointer, "FRAME_END_INPUT", + frameInputSourceP->stdinUsed ? + NULL : frameInputSourceP); + optionSeen[OPTION_FRAME_INPUT] = TRUE; + } else if (STRNEQ(input, "FORCE_I_ALIGN", 13)) { + forceIalign = TRUE; + } else if (STRNEQ(input, "FORCE_ENCODE_LAST_FRAME", 23)) { + /* NO-OP. We used to drop trailing B frames by default and you + needed this option to change the last frame to I so you could + encode all the frames. Now we just do that all the time. + Why wouldn't we? + */ + } else if (STRNEQ(input, "FRAME_RATE", 10)) { + frameRate = GetFrameRate(SkipSpacesTabs(&input[10])); + frameRateRounded = (int) VidRateNum[frameRate]; + if ((frameRate % 3) == 1) + frameRateInteger = FALSE; + optionSeen[OPTION_FRAME_RATE] = TRUE; + } + break; + + case 'G': + if (STRNEQ(input, "GOP_SIZE", 8)) { + SetGOPSize(atoi(SkipSpacesTabs(&input[8]))); + optionSeen[OPTION_GOP] = TRUE; + } else if (STRNEQ(input, "GOP_INPUT_DIR", 13)) { + const char * const arg = SkipSpacesTabs(&input[13]); + if (STRNCASEEQ(arg, "stdin", 5)) + SetStdinInput(gopInputSourceP); + + strcpy(currentGOPPath, arg); + } else if (STRNEQ(input, "GOP_INPUT", 9)) { + ReadInputFileNames(fpointer, "GOP_END_INPUT", + gopInputSourceP->stdinUsed ? + NULL : gopInputSourceP); + optionSeen[OPTION_GOP_INPUT] = TRUE; + } else if (STRNEQ(input, "GAMMA", 5)) { + GammaCorrection = TRUE; + sscanf(SkipSpacesTabs(&input[5]), "%f", &GammaValue); + optionSeen[OPTION_GAMMA] = TRUE; + } + break; + + case 'I': + if (STRNEQ(input, "IQSCALE", 7)) { + SetIQScale(atoi(SkipSpacesTabs(&input[7]))); + optionSeen[OPTION_IQSCALE] = TRUE; + } else if (STRNEQ(input, "INPUT_DIR", 9)) { + const char * const arg = SkipSpacesTabs(&input[9]); + if (STRNCASEEQ(arg, "stdin", 5)) + SetStdinInput(inputSourceP); + strcpy(currentPath, arg); + optionSeen[OPTION_INPUT_DIR] = TRUE; + } else if (STRNEQ(input, "INPUT_CONVERT", 13)) { + strcpy(inputConversion, SkipSpacesTabs(&input[13])); + optionSeen[OPTION_INPUT_CONVERT] = TRUE; + } else if (STREQ(input, "INPUT")) { + ReadInputFileNames(fpointer, "END_INPUT", + inputSourceP->stdinUsed ? + NULL : inputSourceP); + optionSeen[OPTION_INPUT] = TRUE; + } else if (STRNEQ(input, "IO_SERVER_CONVERT", 17)) { + strcpy(ioConversion, SkipSpacesTabs(&input[17])); + optionSeen[OPTION_IO_CONVERT] = TRUE; + } else if (STRNEQ(input, "IQTABLE", 7)) { + processIqtable(fpointer); + + optionSeen[OPTION_IQTABLE] = TRUE; + } + break; + + case 'K': + if (STRNEQ(input, "KEEP_TEMP_FILES", 15)) + keepTempFiles = TRUE; + break; + + case 'N': + if (STRNEQ(input, "NIQTABLE", 8)) { + readNiqTable(fpointer); + + optionSeen[OPTION_NIQTABLE] = TRUE; + } + break; + + case 'O': + if (STRNEQ(input, "OUTPUT", 6)) { + const char * const arg = SkipSpacesTabs(&input[6]); + if ( whichGOP == -1 ) + strcpy(outputFileName, arg); + else + sprintf(outputFileName, "%s.gop.%d", arg, whichGOP); + + optionSeen[OPTION_OUTPUT] = TRUE; + } + break; + + case 'P': + if (STRNEQ(input, "PATTERN", 7)) { + SetFramePattern(SkipSpacesTabs(&input[7])); + optionSeen[OPTION_PATTERN] = TRUE; + } else if (STRNEQ(input, "PIXEL", 5)) { + SetPixelSearch(SkipSpacesTabs(&input[5])); + optionSeen[OPTION_PIXEL] = TRUE; + } else if (STRNEQ(input, "PQSCALE", 7)) { + SetPQScale(atoi(SkipSpacesTabs(&input[7]))); + optionSeen[OPTION_PQSCALE] = TRUE; + } else if (STRNEQ(input, "PSEARCH_ALG", 11)) { + SetPSearchAlg(SkipSpacesTabs(&input[11])); + optionSeen[OPTION_PSEARCH_ALG] = TRUE; + } else if (STRNEQ(input, "PARALLEL_TEST_FRAMES", 20)) { + SetParallelPerfect(FALSE); + parallelTestFrames = atoi(SkipSpacesTabs(&input[20])); + } else if (STRNEQ(input, "PARALLEL_TIME_CHUNKS", 20)) { + SetParallelPerfect(FALSE); + parallelTimeChunks = atoi(SkipSpacesTabs(&input[20])); + } else if (STRNEQ(input, "PARALLEL_CHUNK_TAPER", 20)) { + SetParallelPerfect(FALSE); + parallelTimeChunks = -1; + } else if (STRNEQ(input, "PARALLEL_PERFECT", 16)) { + SetParallelPerfect(TRUE); + } else if (STRNEQ(input, "PARALLEL", 8)) { + ReadMachineNames(fpointer); + optionSeen[OPTION_PARALLEL] = TRUE; + } + break; + + case 'R': + if (STRNEQ(input, "RANGE", 5)) { + processRanges(SkipSpacesTabs(&input[5])); + optionSeen[OPTION_RANGE] = TRUE; + } else if (STRNEQ(input, "REFERENCE_FRAME", 15)) { + SetReferenceFrameType(SkipSpacesTabs(&input[15])); + optionSeen[OPTION_REF_FRAME] = TRUE; + } else if (STRNEQ(input, "RSH", 3)) { + SetRemoteShell(SkipSpacesTabs(&input[3])); + } else if (STRNEQ(input, "RESIZE", 6)) { + const char * const arg = SkipSpacesTabs(&input[6]); + sscanf(arg, "%dx%d", &outputWidth, &outputHeight); + outputWidth &= ~(DCTSIZE * 2 - 1); + outputHeight &= ~(DCTSIZE * 2 - 1); + optionSeen[OPTION_RESIZE] = TRUE; + } + break; + + case 'S': + if (STRNEQ(input, "SLICES_PER_FRAME", 16)) { + SetSlicesPerFrame(atoi(SkipSpacesTabs(&input[16]))); + optionSeen[OPTION_SPF] = TRUE; + } else if (STRNEQ(input, "SLAVE_CONVERT", 13)) { + strcpy(slaveConversion, SkipSpacesTabs(&input[13])); + optionSeen[OPTION_SLAVE_CONVERT] = TRUE; + } else if (STRNEQ(input, "SPECIFICS_FILE", 14)) { + strcpy(specificsFile, SkipSpacesTabs(&input[14])); + specificsOn = TRUE; + optionSeen[OPTION_SPECIFICS] = TRUE; + } else if (STRNEQ(input, "SPECIFICS_DEFINES", 16)) { + strcpy(specificsDefines, SkipSpacesTabs(&input[17])); + optionSeen[OPTION_DEFS_SPECIFICS] = TRUE; + } else if (STRNEQ(input, "SEQUENCE_SIZE", 13)) { + mult_seq_headers = atoi(SkipSpacesTabs(&input[13])); + } else if (STRNEQ(input, "SIZE", 4)) { + const char * const arg = SkipSpacesTabs(&input[4]); + sscanf(arg, "%dx%d", &yuvWidth, &yuvHeight); + realWidth = yuvWidth; + realHeight = yuvHeight; + Fsize_Validate(&yuvWidth, &yuvHeight); + optionSeen[OPTION_YUV_SIZE] = TRUE; + } + break; + + case 'T': + if (STRNEQ(input, "TUNE", 4)) { + tuneingOn = TRUE; + ParseTuneParam(SkipSpacesTabs(&input[4])); + } + break; + + case 'U': + if (STRNEQ(input, "USER_DATA", 9)) { + strcpy(userDataFileName, SkipSpacesTabs(&input[9])); + optionSeen[OPTION_USER_DATA] = TRUE; + } + break; + + case 'W': + if (STRNEQ(input, "WARN_UNDERFLOW", 14)) + paramP->warnUnderflow = TRUE; + if (STRNEQ(input, "WARN_OVERFLOW", 13)) + paramP->warnOverflow = TRUE; + break; + + case 'Y': + if (STRNEQ(input, "YUV_SIZE", 8)) { + const char * const arg = SkipSpacesTabs(&input[8]); + sscanf(arg, "%dx%d", &yuvWidth, &yuvHeight); + realWidth = yuvWidth; + realHeight = yuvHeight; + Fsize_Validate(&yuvWidth, &yuvHeight); + optionSeen[OPTION_YUV_SIZE] = TRUE; + } else if (STRNEQ(input, "Y_SIZE", 6)) { + const char * const arg = SkipSpacesTabs(&input[6]); + sscanf(arg, "%dx%d", &yuvWidth, &yuvHeight); + realWidth = yuvWidth; + realHeight = yuvHeight; + Fsize_Validate(&yuvWidth, &yuvHeight); + optionSeen[OPTION_YUV_SIZE] = TRUE; + } else if (STRNEQ(input, "YUV_FORMAT", 10)) { + strcpy(yuvConversion, SkipSpacesTabs(&input[10])); + optionSeen[OPTION_YUV_FORMAT] = TRUE; + } + break; + } +} + + + +/*===========================================================================* + * + * ReadParamFile + * + * read the parameter file + * function is ENCODE_FRAMES, COMBINE_GOPS, or COMBINE_FRAMES, and + * will slightly modify the procedure's behavior as to what it + * is looking for in the parameter file + * + * SIDE EFFECTS: sets parameters accordingly, as well as machine info for + * parallel execution and input file names + * + *===========================================================================*/ +void +ReadParamFile(const char * const fileName, + int const function, + struct params * const paramP) { + + FILE *fpointer; + char buffer[256]; + bool yuvUsed; + struct inputSource * inputSourceP; + /* Contents of INPUT section */ + struct inputSource * frameInputSourceP; + /* Contents of FRAME_INPUT section */ + struct inputSource * gopInputSourceP; + /* Contents of GOP_INPUT section */ + + fpointer = fopen(fileName, "r"); + if (fpointer == NULL) + pm_error("Error: Cannot open parameter file: %s", fileName); + + CreateInputSource(&inputSourceP); + CreateInputSource(&frameInputSourceP); + CreateInputSource(&gopInputSourceP); + + /* should set defaults */ + numMachines = 0; + sprintf(currentPath, "."); + sprintf(currentGOPPath, "."); + sprintf(currentFramePath, "."); + SetRemoteShell("rsh"); + keepTempFiles = FALSE; + paramP->warnOverflow = FALSE; + paramP->warnUnderflow = FALSE; + + initOptionSeen(); + + yuvUsed = FALSE; /* initial value */ + + while (fgets(buffer, 256, fpointer) != NULL) { + const char * input; + + removeTrailingWhite(buffer, &input); + + if (strlen(input) == 0) { + /* Ignore blank line */ + } else if (input[0] == '#') { + /* Ignore comment */ + } else + processParamLine(input, fpointer, &yuvUsed, + inputSourceP, frameInputSourceP, gopInputSourceP, + paramP); + /* May read additional lines from file */ + + strfree(input); + } + + fclose(fpointer); + + setInputSource(function, ¶mP->inputSourceP, + inputSourceP, gopInputSourceP, frameInputSourceP); + + verifyNoMissingOption(function); + + /* error checking */ + + if (!paramP->inputSourceP->stdinUsed && + paramP->inputSourceP->numInputFiles == 0) + pm_error("You have not specified any input. See the " + "INPUT_DIR, INPUT, GOP_INPUT_DIR, GOP_INPUT, " + "FRAME_INPUT_DIR, and FRAME_INPUT options"); + + if (yuvUsed) { + if (!optionSeen[OPTION_YUV_SIZE]) + pm_error("YUV format used but YUV_SIZE not given"); + + if (!optionSeen[OPTION_YUV_FORMAT]) { + strcpy (yuvConversion, "EYUV"); + pm_message("WARNING: YUV format not specified; " + "defaulting to Berkeley YUV (EYUV)"); + } + } + + if (paramP->inputSourceP->stdinUsed && optionSeen[OPTION_PARALLEL] ) + pm_error("stdin reading for parallel execution not enabled yet."); + + if (optionSeen[OPTION_PARALLEL] && !optionSeen[OPTION_YUV_SIZE]) + pm_error("Specify SIZE WxH for parallel encoding"); + + if (optionSeen[OPTION_IO_CONVERT] != optionSeen[OPTION_SLAVE_CONVERT]) + pm_error("Must have either both IO_SERVER_CONVERT and SLAVE_CONVERT " + "or neither"); + + if (optionSeen[OPTION_DEFS_SPECIFICS] && !optionSeen[OPTION_SPECIFICS]) + pm_error("Does not make sense to define Specifics file options, " + "but no specifics file!"); + + SetIOConvert(optionSeen[OPTION_IO_CONVERT]); + + SetResize(optionSeen[OPTION_RESIZE]); + + if (function == ENCODE_FRAMES) { + SetFCode(); + + if (psearchAlg == PSEARCH_TWOLEVEL) + SetPixelSearch("HALF"); + } +} + + +/* + * Copyright (c) 1995 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ |