AVSValue ConditionalReader::ConvertType(const char* content, int line, IScriptEnvironment* env) { if (mode == MODE_UNKNOWN) ThrowLine("ConditionalReader: Type has not been defined. Line %d", line, env); int fields; switch (mode) { case MODE_INT: int ival; fields = sscanf(content, "%d", &ival); if (!fields) ThrowLine("ConditionalReader: Could not find an expected integer at line %d!", line, env); return AVSValue(ival); case MODE_FLOAT: float fval; fields = sscanf(content, "%e", &fval); if (!fields) ThrowLine("ConditionalReader: Could not find an expected float at line %d!", line, env); return AVSValue(fval); case MODE_BOOL: char bval [8]; fields = sscanf(content, "%7s", bval); if (!strcasecmp((const char*)bval, "true")) { return AVSValue(true); } else if (!strcasecmp((const char*)bval, "t")) { return AVSValue(true); } else if (!strcasecmp((const char*)bval, "yes")) { return AVSValue(true); } else if (!strcasecmp((const char*)bval, "false")) { return AVSValue(false); } else if (!strcasecmp((const char*)bval, "f")) { return AVSValue(false); } else if (!strcasecmp((const char*)bval, "no")) { return AVSValue(false); } ThrowLine("ConditionalReader: Boolean value was not true or false in line %d", line, env); } return AVSValue(0); }
AVSValue ConditionalReader::ConvertType(const char* content, int line, IScriptEnvironment* env) { if (mode == MODE_UNKNOWN) ThrowLine("ConditionalReader: Type has not been defined. Line %d", line, env); int fields; switch (mode) { case MODE_INT: int ival; fields = sscanf(content, "%d", &ival); if (fields != 1) ThrowLine("ConditionalReader: Could not find an expected integer at line %d!", line, env); return AVSValue(ival); case MODE_FLOAT: float fval; fields = sscanf(content, "%e", &fval); if (fields != 1) ThrowLine("ConditionalReader: Could not find an expected float at line %d!", line, env); return AVSValue(fval); case MODE_BOOL: char bval[8]; bval[0] = '\0'; fields = sscanf(content, "%7s", bval); bval[7] = '\0'; if (!lstrcmpi(bval, "true")) { return AVSValue(true); } else if (!lstrcmpi(bval, "t")) { return AVSValue(true); } else if (!lstrcmpi(bval, "yes")) { return AVSValue(true); } else if (!lstrcmp(bval, "1")) { return AVSValue(true); } else if (!lstrcmpi(bval, "false")) { return AVSValue(false); } else if (!lstrcmpi(bval, "f")) { return AVSValue(false); } else if (!lstrcmpi(bval, "no")) { return AVSValue(false); } else if (!lstrcmp(bval, "0")) { return AVSValue(false); } ThrowLine("ConditionalReader: Boolean value was not true or false in line %d", line, env); case MODE_STRING: StringCache *str; // Look for an existing duplicate for (str = stringcache; str; str = str->next ) { if (!lstrcmp(str->string, content)) break; } // Could not find one, add it if (!str) { str = new StringCache; str->string = _strdup(content); str->next = stringcache; stringcache = str; } return AVSValue(str->string); } return AVSValue(); }
ConditionalReader::ConditionalReader(PClip _child, const char* filename, const char _varname[], bool _show, IScriptEnvironment* env) : GenericVideoFilter(_child), show(_show), variableName(_varname), mode(MODE_UNKNOWN), offset(0), stringcache(0) { FILE * f; char *line = 0; int lines; if ((f = fopen(filename, "rb")) == NULL) env->ThrowError("ConditionalReader: Could not open file '%s'.", filename); lines = 0; try { while ((line = readline(f)) != NULL) { char *ptr; int fields; lines++; /* We skip spaces */ ptr = skipspaces(line); /* Skip coment lines or empty lines */ if(iscomment(ptr) || *ptr == '\0') { free(line); line = 0; continue; } if (mode == MODE_UNKNOWN) { // We have not recieved a mode - We expect type. char* keyword = ptr; ptr = findspace(ptr); if (*ptr) { *ptr++ = '\0'; if (!lstrcmpi(keyword, "type")) { /* We skip spaces */ char* type = skipspaces(ptr); ptr = findspace(type); *ptr = '\0'; if (!lstrcmpi(type, "int")) { mode = MODE_INT; intVal = new int[vi.num_frames]; } else if (!lstrcmpi(type, "float")) { mode = MODE_FLOAT; floatVal = new float[vi.num_frames]; } else if (!lstrcmpi(type, "bool")) { mode = MODE_BOOL; boolVal = new bool[vi.num_frames]; } else if (!lstrcmpi(type, "string")) { mode = MODE_STRING; stringVal = new const char*[vi.num_frames]; } else { ThrowLine("ConditionalReader: Unknown 'Type' specified in line %d", lines, env); }// end if compare type SetRange(0, vi.num_frames-1, AVSValue()); }// end if compare keyword }// end if fields } else { // We have a defined mode and allocated the values. char* keyword = ptr; char* type = findspace(keyword); if (*type) *type++ = '\0'; if (!lstrcmpi(keyword, "default")) { AVSValue def = ConvertType(type, lines, env); SetRange(0, vi.num_frames-1, def); } else if (!lstrcmpi(keyword, "offset")) { fields = sscanf(type, "%d", &offset); if (fields != 1) ThrowLine("ConditionalReader: Could not read Offset in line %d", lines, env); } else if (keyword[0] == 'R' || keyword[0] == 'r') { // Range int start; int stop; type = skipspaces(type); fields = sscanf(type, "%d", &start); type = findspace(type); type = skipspaces(type); fields += sscanf(type, "%d", &stop); type = findspace(type); if (!*type || fields != 2) ThrowLine("ConditionalReader: Could not read Range in line %d", lines, env); if (start > stop) ThrowLine("ConditionalReader: The Range start frame is after the end frame in line %d", lines, env); AVSValue set = ConvertType(type+1, lines, env); SetRange(start, stop, set); } else if (keyword[0] == 'I' || keyword[0] == 'i') { // Interpolate if (mode == MODE_BOOL) ThrowLine("ConditionalReader: Cannot Interpolate booleans in line %d", lines, env); if (mode == MODE_STRING) ThrowLine("ConditionalReader: Cannot Interpolate strings in line %d", lines, env); type = skipspaces(type); int start; int stop; char start_value[64]; char stop_value[64]; fields = sscanf(type, "%d %d %63s %63s", &start, &stop, start_value, stop_value); if (fields != 4) ThrowLine("ConditionalReader: Could not read Interpolation range in line %d", lines, env); if (start > stop) ThrowLine("ConditionalReader: The Interpolation start frame is after the end frame in line %d", lines, env); start_value[63] = '\0'; AVSValue set_start = ConvertType(start_value, lines, env); stop_value[63] = '\0'; AVSValue set_stop = ConvertType(stop_value, lines, env); const int range = stop-start; const double diff = (set_stop.AsFloat() - set_start.AsFloat()) / range; for (int i = 0; i<=range; i++) { const double n = i * diff + set_start.AsFloat(); SetFrame(i+start, (mode == MODE_FLOAT) ? AVSValue(n) : AVSValue((int)(n+0.5))); } } else { int cframe; fields = sscanf(keyword, "%d", &cframe); if (*type && fields == 1) { AVSValue set = ConvertType(type, lines, env); SetFrame(cframe, set); } else { ThrowLine("ConditionalReader: Do not understand line %d", lines, env); } } } // End we have defined type free(line); line = 0; }// end while still some file left to read. } catch (...) { if (line) free(line); fclose(f); CleanUp(); throw; } /* We are done with the file */ fclose(f); if (mode == MODE_UNKNOWN) env->ThrowError("ConditionalReader: Type was not defined!"); }
ConditionalReader::ConditionalReader(PClip _child, const char* filename, const char _varname[], bool _show, IScriptEnvironment* env) : GenericVideoFilter(_child), show(_show), variableName(_varname) { FILE * f; char *line; int lines; if ((f = fopen(filename, "rb")) == NULL) env->ThrowError("ConditionalReader: Could not open file '%s'.", filename); lines = 0; mode = MODE_UNKNOWN; while ((line = readline(f)) != NULL) { char *ptr; int fields; lines++; /* We skip spaces */ ptr = skipspaces(line); /* Skip coment lines or empty lines */ if(iscomment(ptr) || *ptr == '\0') { free(line); continue; } if (mode == MODE_UNKNOWN) { // We have not recieved a mode - We expect type. char keyword [1024]; char type [1024]; fields = sscanf(ptr,"%1023s %1023s", keyword, type); if (fields) { if (!strcasecmp((const char*)keyword, "type")) { if (!strcasecmp((const char*)type, "int")) { mode = MODE_INT; intVal = new int[vi.num_frames]; } else if (!strcasecmp((const char*)type, "float")) { mode = MODE_FLOAT; floatVal = new float[vi.num_frames]; } else if (!strcasecmp((const char*)type, "bool")) { mode = MODE_BOOL; boolVal = new bool[vi.num_frames]; } else { ThrowLine("ConditionalReader: Unknown 'type' specified in line %d", lines, env); }// end if compare type }// end if compare keyword }// end if fields } else { // We have a defined mode and allocated the values. char keyword [1024]; char type [1024]; fields = sscanf(ptr,"%1023s %1023s", keyword, type); if (!strcasecmp((const char*)keyword, "default")) { AVSValue def = ConvertType((const char*)type, lines, env); SetRange(0, vi.num_frames-1, def); free(line); continue; } // end if "default" if (ptr[0] == 'R' || ptr[0] == 'r') { // Range ptr++; ptr = skipspaces(ptr); int start; int stop; char value [64]; fields = sscanf(ptr, "%d %d %63s", &start, &stop, value); if (fields != 3) ThrowLine("ConditionalReader: Could not read range in line %d", lines, env); if (start > stop) ThrowLine("ConditionalReader: The start frame is after the end frame in line %d", lines, env); AVSValue set = ConvertType((const char*)value, lines, env); SetRange(start, stop, set); } else if (ptr[0] == 'I' || ptr[0] == 'i') { // Interpolate if (mode == MODE_BOOL) ThrowLine("ConditionalReader: Cannot interpolate booleans in line %d", lines, env); ptr++; ptr = skipspaces(ptr); int start; int stop; char start_value [64]; char stop_value [64]; fields = sscanf(ptr, "%d %d %63s %63s", &start, &stop, start_value, stop_value); if (fields != 4) ThrowLine("ConditionalReader: Could not read interpolation range in line %d", lines, env); if (start > stop) ThrowLine("ConditionalReader: The start frame is after the end frame in line %d", lines, env); AVSValue set_start = ConvertType((const char*)start_value, lines, env); AVSValue set_stop = ConvertType((const char*)stop_value, lines, env); int range = stop-start; double diff = set_stop.AsFloat() - set_start.AsFloat(); for (int i = 0; i<=range; i++) { double where = (double)(i)/(double)range; double n = where * diff + set_start.AsFloat(); SetFrame(i+start, (mode == MODE_FLOAT) ? AVSValue(n) : AVSValue((int) n)); } } else { char value [64]; int cframe; fields = sscanf(ptr, "%d %63s", &cframe, value); if (fields == 2) { AVSValue set = ConvertType((const char*)value, lines, env); SetFrame(cframe, set); } else { AVXLOG_INFO("ConditionalReader: Ignored line %d.\n", lines); } } } // End we have defined type free(line); }// end while still some file left to read. /* We are done with the file */ fclose(f); if (mode == MODE_UNKNOWN) env->ThrowError("ConditionalReader: Mode was not defined!"); }