Esempio n. 1
0
void PhoneLookup::outputNode( int node , int *n , char *tmpSepChars , int *tmpMonoInds )
{
   if ( node < 0 )
      return ;

   tmpSepChars[*n] = nodes[node].sepChar ;
   tmpMonoInds[*n] = nodes[node].monoInd ;
   (*n)++ ;
 
   if ( nodes[node].modelLookupInd >= 0 )
   {
      // we want to output this node.
      printf("%s",monoLookup->getString(tmpMonoInds[0])) ;
      for ( int i=1 ; i<(*n) ; i++ )
      {
         printf("%c%s" , tmpSepChars[i] , monoLookup->getString(tmpMonoInds[i]) ) ;
      }
      printf( " = %d(%d,%s)\n" , nodes[node].modelLookupInd , 
              modelInds[nodes[node].modelLookupInd] , modelStrs[nodes[node].modelLookupInd] ) ;
   }

   int next = nodes[node].firstChild ;
   while ( next >= 0 )
   {
      outputNode( next , n , tmpSepChars , tmpMonoInds ) ;
      next = nodes[next].nextSib ;
   }

   (*n)-- ;
}
Esempio n. 2
0
int main(int argc, char** args) {
    if (argc < 3 || argc > 4) {
        usage();
        return 1;
    }
    
    execname = args[0];
    char* input_filename = args[1];
    char* output_filename = "-";
    if (argc > 3) output_filename = args[3];
    
    FILE* output;
    if (strcmp(output_filename, "-") == 0)
        output = stdout;
    else
        output = fopen(output_filename, "w");
    if (output == NULL) {
        fprintf(stderr, "Could not open file for output '%s'\n", output_filename);
        return 1;
    }
    
    loadLua(args[2]);
    
    if (!openSOSI(input_filename)) {
        closeSOSI();
        return 1;
    }
    
    fprintf(output, "<?xml version=\"1.0\"?>\n"
        "<osm version=\"0.6\" upload=\"false\" generator=\"sosi2osm\">\n");
    
    while (nextSOSIObject()) {
        short type = getSOSIType();
        switch(type) {
        case L_HODE:
            handleHead();
            break;
        case L_FLATE:
            outputRelation(output);
            break;
        case L_PUNKT:
        case L_SYMBOL:
        case L_TEKST:
            outputNode(output);
            break;
        case L_KURVE:
        case L_LINJE:
        case L_BUEP:
            outputWay(output);
            break;
        }
    }
    
    fprintf(output, "</osm>\n");
    
    closeSOSI();
    fclose(output);
    
    return 0;
}
Esempio n. 3
0
bool Scene::output(const char *filename)
{
    FileStream stream(filename);
    if (!stream.openToWrite())
    {
        FBXSDK_printf("Fail to create %s.\n", filename);
        return false;
    }

    int depth = 0;

    if (m_camera != NULL)
    {
        stream.printf("<scene maincamera=\"%s\">\n", m_camera->attributes[0].second.Buffer());
    }
    else
    {
        stream.printf("<scene>\n");
    }

    outputNode(stream, m_root, ++depth);
    
    stream.printf("</scene>");

    return true;
}
Esempio n. 4
0
void Scene::outputNode(FileStream &stream, SceneNode *node, int depth)
{
    // The indent
    for (int i = 0; i < depth; ++i)
    {
        stream.printf("  ");
    }

    // Output the type and attributes;
    stream.printf("<%s ", node->type.Buffer());
    for (size_t i = 0; i < node->attributes.size(); i++)
    {
        stream.printf("%s=\"%s\" ", node->attributes[i].first.Buffer(),
                node->attributes[i].second.Buffer());
    }
    stream.printf(">\n");
    
    // Only output the geometry and material of root.
    if (depth > 1 && node->type == "drawable")
    {
        // Geometry
        for (int i = 0; i <= depth; ++i)
        {
            stream.printf("  ");
        }
        stream.printf("<geometry id=\"mesh/%s\" />\n", node->geometry.Lower().Buffer());
        
        // Texture
        // FIXME: more complex material
        for (int i = 0; i <= depth; ++i)
        {
            stream.printf("  ");
        }
        FbxString texName = node->texture;
        FbxString pngTexName = FbxPathUtils::ChangeExtension(texName, ".png");
        stream.printf("<material id=\"material/texture.pmt\" texture=\"texture/%s\" />\n", pngTexName.Buffer());
    }

    // Output children
    for (size_t i = 0; i < node->children.size(); i++)
    {
        SceneNode *child = node->children[i];
        outputNode(stream, child, depth + 1);
    }

    // The indent
    for (int i = 0; i < depth; ++i)
    {
        stream.printf("  ");
    }
    stream.printf("</%s>\n", node->type.Buffer());
}
void MaterialGeneratorNode::notifyNodeDisconnected( MaterialGeneratorNodeConnector* a, MaterialGeneratorNodeConnector* b )
{
    MaterialGeneratorNodeConnector* outputNode(a);
    MaterialGeneratorNodeConnector* inputNode(b);
    if (outputNode->getType() == eNodeGraphNodeConnectorType_Input)
    {
        outputNode = b;
        inputNode = a;
    }
    if (inputNode->getParent()->getParent() == this) // only operator when input node is this node (else calculations are done twice)
    {
        inputNode->setVar(he::ObjectHandle::unassigned);
        evaluate();
    }
}
Esempio n. 6
0
void PhoneLookup::outputText()
{
   char *tmpSepChars = new char[30] ;
   int *tmpMonoInds = new int[30] ;
   int n=0 ;
   
   printf("****** START PhoneLookup ******\n") ;
   printf("nSepChars=%d nPhones=%d nModelInds=%d nNodes=%d\n" , nSepChars , nPhones , 
          nModelInds , nNodes ) ;
   for ( int i=0 ; i<monoLookup->getNumMonophones() ; i++ )
   {
      n = 0 ;
      outputNode( firstLevelNodes[i] , &n , tmpSepChars , tmpMonoInds ) ;
   }

   printf("****** END PhoneLookup ******\n") ;
   delete [] tmpSepChars ;
   delete [] tmpMonoInds ;
}
Esempio n. 7
0
void MonophoneLookup::outputNode( int node , int *nChrs , char *chrs )
{
   if ( node < 0 )
      return ;

   chrs[(*nChrs)++] = nodes[node].chr ;
 
   if ( nodes[node].monophone >= 0 )
   {
      // we want to output this node.
      chrs[*nChrs] = '\0' ;
      printf("%s = %d\n" , chrs , nodes[node].monophone ) ;
   }

   int next = nodes[node].firstChild ;
   while ( next >= 0 )
   {
      outputNode( next , nChrs , chrs ) ;
      next = nodes[next].nextSib ;
   }

   (*nChrs)-- ;
}
Esempio n. 8
0
void MonophoneLookup::outputText()
{
   char *chrs = new char[30] ;
   int nChrs=0 , i ;
  
   printf("****** START MonophoneLookup ******\n") ;
   printf("nNodes=%d nNodesAlloc=%d nMonophones=%d nMonophoneStrsAlloc=%d\n" ,
           nNodes , nNodesAlloc , nMonophones , nMonophoneStrsAlloc ) ;
   printf("silMonoInd=%d pauseMonoInd=%d\n" , silMonoInd , pauseMonoInd ) ;
   printf("\nNodes Output\n-----------\n");
   for ( i=0 ; i<=MAX_CHAR ; i++ )
   {
      nChrs = 0 ;
      outputNode( firstLevelNodes[i] , &nChrs , chrs ) ;
   }
   printf("\nStrings Output\n-----------\n");
   for ( i=0 ; i<nMonophones ; i++ )
   {
      printf("%s\n" , monophoneStrs[i] ) ;
   }
   printf("****** END MonophoneLookup ******\n") ;

   delete [] chrs ;
}
Esempio n. 9
0
int wmain(int argc, wchar_t **argv) {
    if (_setmode(_fileno(stdout), _O_BINARY) == -1)
        fprintf(stderr, "Failed to set stdout to binary mode\n");
    SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else
int main(int argc, char **argv) {
#endif

    if (argc == 2) {
        if (nstring(argv[1]) == NSTRING("-version")) {
            if (!vsscript_init()) {
                fprintf(stderr, "Failed to initialize VapourSynth environment\n");
                return 1;
            }

            vsapi = vsscript_getVSApi();
            if (!vsapi) {
                fprintf(stderr, "Failed to get VapourSynth API pointer\n");
                vsscript_finalize();
                return 1;
            }

            VSCore *core = vsapi->createCore(0);
            if (!core) {
                fprintf(stderr, "Failed to create core\n");
                vsscript_finalize();
                return 1;
            }

            const VSCoreInfo *info = vsapi->getCoreInfo(core);
            printf("%s", info->versionString);
            vsapi->freeCore(core);
            return 0;
        }
    }

    if (argc < 3) {
        fprintf(stderr, "VSPipe usage:\n");
        fprintf(stderr, "Show version info: vspipe -version\n");
        fprintf(stderr, "Show script info: vspipe script.vpy - -info\n");
        fprintf(stderr, "Write to stdout: vspipe script.vpy - [options]\n");
        fprintf(stderr, "Write to file: vspipe script.vpy <outFile> [options]\n");
        fprintf(stderr, "Available options:\n");
        fprintf(stderr, "Select output index: -index N\n");
        fprintf(stderr, "Set number of concurrent frame requests: -requests N\n");
        fprintf(stderr, "Add YUV4MPEG headers: -y4m\n");
        fprintf(stderr, "Print progress to stderr: -progress\n");
        fprintf(stderr, "Show video info: -info (overrides other options)\n");
        return 1;
    }

    nstring outputFilename = argv[2];
    if (outputFilename == NSTRING("-")) {
        outFile = stdout;
    } else {
#ifdef VS_TARGET_OS_WINDOWS
        outFile = _wfopen(outputFilename.c_str(), L"wb");
#else
        outFile = fopen(outputFilename.c_str(), "wb");
#endif
        if (!outFile) {
            fprintf(stderr, "Failed to open output for writing\n");
            return 1;
        }
    }

    for (int arg = 3; arg < argc; arg++) {
        nstring argString = argv[arg];
        if (argString == NSTRING("-y4m")) {
            y4m = true;
        } else if (argString == NSTRING("-info")) {
            showInfo = true;
        } else if (argString == NSTRING("-index")) {
            bool ok = false;
            if (argc <= arg + 1) {
                fprintf(stderr, "No index number specified\n");
                return 1;
            }

            if (!nstringToInt(argv[arg + 1], outputIndex)) {
                fprintf(stderr, "Couldn't convert %s to an integer\n", nstringToUtf8(argv[arg + 1]).c_str());
                return 1;
            }
            arg++;
        } else if (argString == NSTRING("-requests")) {
            bool ok = false;
            if (argc <= arg + 1) {
                fprintf(stderr, "No request number specified\n");
                return 1;
            }
            if (!nstringToInt(argv[arg + 1], requests)) {
                fprintf(stderr, "Couldn't convert %s to an integer\n", nstringToUtf8(argv[arg + 1]).c_str());
                return 1;
            }
            arg++;
        } else if (argString == NSTRING("-progress")) {
            printFrameNumber = true;
        } else {
            fprintf(stderr, "Unknown argument: %s\n", nstringToUtf8(argString).c_str());
            return 1;
        }
    }

    if (!vsscript_init()) {
        fprintf(stderr, "Failed to initialize VapourSynth environment\n");
        return 1;
    }

    vsapi = vsscript_getVSApi();
    if (!vsapi) {
        fprintf(stderr, "Failed to get VapourSynth API pointer\n");
        vsscript_finalize();
        return 1;
    }

    std::chrono::time_point<std::chrono::high_resolution_clock> start(std::chrono::high_resolution_clock::now());

    if (vsscript_evaluateFile(&se,  nstringToUtf8(argv[1]).c_str(), efSetWorkingDir)) {
        fprintf(stderr, "Script evaluation failed:\n%s\n", vsscript_getError(se));
        vsscript_freeScript(se);
        vsscript_finalize();
        return 1;
    }

    node = vsscript_getOutput(se, outputIndex);
    if (!node) {
       fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n");
       vsscript_freeScript(se);
       vsscript_finalize();
       return 1;
    }

    bool error = false;
    const VSVideoInfo *vi = vsapi->getVideoInfo(node);

    if (showInfo) {
        fprintf(outFile, "Width: %d\n", vi->width);
        fprintf(outFile, "Height: %d\n", vi->height);
        fprintf(outFile, "Frames: %d\n", vi->numFrames);
        fprintf(outFile, "FPS: %" PRId64 "/%" PRId64 "\n", vi->fpsNum, vi->fpsDen);

        if (vi->format) {
            fprintf(outFile, "Format Name: %s\n", vi->format->name);
            fprintf(outFile, "Color Family: %s\n", colorFamilyToString(vi->format->colorFamily));
            fprintf(outFile, "Bits: %d\n", vi->format->bitsPerSample);
            fprintf(outFile, "SubSampling W: %d\n", vi->format->subSamplingW);
            fprintf(outFile, "SubSampling H: %d\n", vi->format->subSamplingH);
        } else {
            fprintf(outFile, "Format Name: Variable\n");
        }
    } else {
        if (!isConstantFormat(vi) || vi->numFrames == 0) {
            fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n");
            vsapi->freeNode(node);
            vsscript_freeScript(se);
            vsscript_finalize();
            return 1;
        }

        lastFpsReportTime = std::chrono::high_resolution_clock::now();
        error = outputNode();
    }

    fflush(outFile);
    std::chrono::time_point<std::chrono::high_resolution_clock> end(std::chrono::high_resolution_clock::now());
    std::chrono::duration<double> elapsedSeconds = end - start;
    fprintf(stderr, "Output %d frames in %.2f seconds (%.2f fps)\n", outputFrames, elapsedSeconds.count(), outputFrames / elapsedSeconds.count());
    vsapi->freeNode(node);
    vsscript_freeScript(se);
    vsscript_finalize();

    return error;
}
Esempio n. 10
0
void XMLParser::hierarchyToTerminal()
{
	int level = 0;
	bool error = false;
	if (xmlContents.length() == 0)
	{
		return;
	}
	std::stack<std::string> tagStack;
	unsigned int cursorLocA = 0;
	unsigned int cursorLocB = 0;
	std::string currentTag = "";
	do
	{
		try
		{
			cursorLocA = xmlContents.find("<", cursorLocB, 1);
			cursorLocB = xmlContents.find(">", cursorLocA, 1);
			if (cursorLocB == std::string::npos)
			{
				// end of file.
				break;
			}
			currentTag = xmlContents.substr(cursorLocA, (cursorLocB - cursorLocA) + 1);
			// First, carry on if tag is DTD or self closing
			if ((currentTag.substr(0, 2) == "<?") || (currentTag.substr(currentTag.length() - 2, 2) == "/>"))
			{
				outputNode(currentTag, level);
				continue;
			}
			if ((currentTag.substr(0, 1) == "<") && (currentTag.substr(0, 2) != "</"))
			{
				// open tag found
				tagStack.push(currentTag);
				outputNode(currentTag, level);
				level++;
			}
			if (currentTag.substr(0, 2) == "</")
			{
				// closing tag found
				if (currentTag.substr(2, currentTag.length() - 2) == tagStack.top().substr(1,
						tagStack.top().length() - 1))
				{
					// okay, they match. Pop off opening tag
					tagStack.pop();
					level--;
					outputNode(currentTag, level);
				}
				else
				{
					printf("Expected closing tag for %s, but found %s.", &tagStack.top()[0], &currentTag[0]);
					error = true;
				}
			}
		}
		catch (std::exception exc)
		{
			printf("An unknown error occurred.");
			error = true;
		}
	}
	while (!error);
	if (!error) // check no existing errors....
	{
		printf("%s lacks closing tag.", &tagStack.top()[0]);
	}
	for (unsigned int emptyStack = 0; emptyStack < tagStack.size(); emptyStack++)
	{
		tagStack.pop();
	}
	return; // almost okay, stack not empty though so a closing tag missing?
}
Esempio n. 11
0
/* This function is mutually recursive with outputNode() */
void outputXMLHelper (Node node)
{
    Node child;
    NameValue nv;
    int i;
    char tmpstr[255];

    switch (node->type)
    {
        case Heading:
            sprintf (tmpstr, "<heading level='%d'>", node->data.num);
            fb_write_to_buffer (tmpstr);
            outputNode (node); /* will not output the tag */
            fb_write_to_buffer ("</heading>");
            break;

        case TextToken:
            fb_write_to_buffer_escaped (node->data.str);
            break;

        case ExtensionToken:
            nv = node->data.nameval;
            sprintf (tmpstr, "<extension name='%s'>", nv->name);
            fb_write_to_buffer (tmpstr);
            fb_write_to_buffer_escaped (nv->value);
            fb_write_to_buffer ("</extension>");
            break;

        case Attribute:
            sprintf (tmpstr, "<attr name='%s'", node->data.attrdata->name);
            fb_write_to_buffer (tmpstr);
            if (node->data.attrdata->type == 0)
                fb_write_to_buffer (" isnull='yes'");
            fb_write_to_buffer (">");
            outputNode (node);
            fb_write_to_buffer ("</attr>");
            break;

        case List:
            fb_write_to_buffer (node->data.num == 1 ? "<list type='bullet'>"   :
                                node->data.num == 2 ? "<list type='numbered'>" :
                                node->data.num == 3 ? "<list type='indent'>" :
                                                      "<list>");
            outputNode (node);
            fb_write_to_buffer ("</list>");
            break;

        case LinkEtc:
            fb_write_to_buffer ("<link");
            if (node->data.num & 1) fb_write_to_buffer (" emptypipeatend='yes'");
            if (node->data.num & 2) fb_write_to_buffer (" forcedlink='yes'");
            fb_write_to_buffer (">");
            outputNode (node);
            fb_write_to_buffer ("</link>");
            break;

        default:
            outputNode (node);
            break;
    }
}
Esempio n. 12
0
int wmain(int argc, wchar_t **argv) {
#else
int main(int argc, char **argv) {
#endif

    if (argc < 3) {
        fprintf(stderr, "VSPipe usage:\n");
		fprintf(stderr, "Show script info: vspipe script.vpy - -info\n");
        fprintf(stderr, "Write to stdout: vspipe script.vpy - [options]\n");
        fprintf(stderr, "Write to file: vspipe script.vpy <outFile> [options]\n");
        fprintf(stderr, "Available options:\n");
		fprintf(stderr, "Select output index: -index N\n");
		fprintf(stderr, "Set number of concurrent frame requests: -requests N\n");
		fprintf(stderr, "Add YUV4MPEG headers: -y4m\n");
		fprintf(stderr, "Show video info: -info (overrides other options)\n");
        return 1;
    }

	QFile scriptFile(nativeToQString(argv[1]));
	if (!scriptFile.open(QIODevice::ReadOnly)) {
        fprintf(stderr, "Failed to to open script file for reading\n");
        return 1;
	}

	if (scriptFile.size() > 1024*1024*16) {
        fprintf(stderr, "Script files bigger than 16MB not allowed\n");
        return 1;
	}

    QByteArray scriptData = scriptFile.readAll();
	scriptFile.close();
    if (scriptData.isEmpty()) {
        fprintf(stderr, "Failed to read script file or file is empty\n");
        return 1;
    }

	QString outputFilename = nativeToQString(argv[2]);
	if (outputFilename == "-") {
		outFile = stdout;
	} else {
#ifdef VS_TARGET_OS_WINDOWS
		outFile = _wfopen(outputFilename.toStdWString().c_str(), L"wb");
#else
		outFile = fopen(outputFilename.toLocal8Bit(), "wb");
#endif
		if (!outFile) {
			fprintf(stderr, "Failed to open output for writing\n");
			return 1;
		}
	}

	for (int arg = 3; arg < argc; arg++) {
		QString argString = nativeToQString(argv[arg]);
		if (argString == "-y4m") {
			y4m = true;
		} else if (argString == "-info") {
			showInfo = true;
		} else if (argString == "-index") {
			bool ok = false;
			if (argc <= arg + 1) {
				fprintf(stderr, "No index number specified");
				return 1;
			}
			QString numString = nativeToQString(argv[arg+1]);
			outputIndex = numString.toInt(&ok);
			if (!ok) {
				fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData());
				return 1;
			}
			arg++;
		} else if (argString == "-requests") {
			bool ok = false;
			if (argc <= arg + 1) {
				fprintf(stderr, "No request number specified");
				return 1;
			}
			QString numString = nativeToQString(argv[arg+1]);
			requests = numString.toInt(&ok);
			if (!ok) {
				fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData());
				return 1;
			}
			arg++;
		} else {
			fprintf(stderr, "Unknown argument: %s\n", argString.toUtf8().constData());
			return 1;
		}
	}

    if (!vseval_init()) {
        fprintf(stderr, "Failed to initialize VapourSynth environment\n");
        return 1;
    }

    vsapi = vseval_getVSApi();
    if (!vsapi) {
        fprintf(stderr, "Failed to get VapourSynth API pointer\n");
        vseval_finalize();
        return 1;
    }

	if (vseval_evaluateScript(&se, scriptData.constData(), nativeToQString(argv[1]).toUtf8())) {
        fprintf(stderr, "Script evaluation failed:\n%s", vseval_getError(se));
        vseval_freeScript(se);
        vseval_finalize();
        return 1;
    }

    node = vseval_getOutput(se, outputIndex);
    if (!node) {
       fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n");
       vseval_freeScript(se);
       vseval_finalize();
       return 1;
    }

	bool error = false;
	const VSVideoInfo *vi = vsapi->getVideoInfo(node);

	if (showInfo) {
		fprintf(outFile, "Width: %d\n", vi->width);
		fprintf(outFile, "Height: %d\n", vi->height);
		fprintf(outFile, "Frames: %d\n", vi->numFrames);
		fprintf(outFile, "FPS: %" PRId64 "/%" PRId64 "\n", vi->fpsNum, vi->fpsDen);

		if (vi->format) {
			fprintf(outFile, "Format Name: %s\n", vi->format->name);
			fprintf(outFile, "Color Family: %s\n", colorFamilyToString(vi->format->colorFamily));
			fprintf(outFile, "Bits: %d\n", vi->format->bitsPerSample);
			fprintf(outFile, "SubSampling W: %d\n", vi->format->subSamplingW);
			fprintf(outFile, "SubSampling H: %d\n", vi->format->subSamplingH);
		} else {
			fprintf(outFile, "Format Name: Variable\n");
		}
	} else {
		if (!isConstantFormat(vi) || vi->numFrames == 0) {
			fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n");
			vsapi->freeNode(node);
			vseval_freeScript(se);
			vseval_finalize();
			return 1;
		}

		error = outputNode();
	}

	fflush(outFile);
    vsapi->freeNode(node);
    vseval_freeScript(se);
    vseval_finalize();

	return error;
}
Esempio n. 13
0
int wmain(int argc, wchar_t **argv) {
    if (_setmode(_fileno(stdout), _O_BINARY) == -1)
        fprintf(stderr, "Failed to set stdout to binary mode\n");
    SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else
int main(int argc, char **argv) {
#endif
    nstring outputFilename, scriptFilename;
    bool showHelp = false;
    std::map<std::string, std::string> scriptArgs;
    int startFrame = 0;

    for (int arg = 1; arg < argc; arg++) {
        nstring argString = argv[arg];
        if (argString == NSTRING("-v") || argString == NSTRING("--version")) {
            showVersion = true;
        } else if (argString == NSTRING("-y") || argString == NSTRING("--y4m")) {
            y4m = true;
        } else if (argString == NSTRING("-p") || argString == NSTRING("--progress")) {
            printFrameNumber = true;
        } else if (argString == NSTRING("-i") || argString == NSTRING("--info")) {
            showInfo = true;
        } else if (argString == NSTRING("-h") || argString == NSTRING("--help")) {
            showHelp = true;
        } else if (argString == NSTRING("-s") || argString == NSTRING("--start")) {
            if (argc <= arg + 1) {
                fprintf(stderr, "No start frame specified\n");
                return 1;
            }

            if (!nstringToInt(argv[arg + 1], startFrame)) {
                fprintf(stderr, "Couldn't convert %s to an integer (start)\n", nstringToUtf8(argv[arg + 1]).c_str());
                return 1;
            }

            if (startFrame < 0) {
                fprintf(stderr, "Negative start frame specified\n");
                return 1;
            }

            completedFrames = startFrame;
            outputFrames = startFrame;
            requestedFrames = startFrame;
            lastFpsReportFrame = startFrame;

            arg++;
        } else if (argString == NSTRING("-e") || argString == NSTRING("--end")) {
            if (argc <= arg + 1) {
                fprintf(stderr, "No end frame specified\n");
                return 1;
            }

            if (!nstringToInt(argv[arg + 1], totalFrames)) {
                fprintf(stderr, "Couldn't convert %s to an integer (end)\n", nstringToUtf8(argv[arg + 1]).c_str());
                return 1;
            }

            if (totalFrames < 0) {
                fprintf(stderr, "Negative end frame specified\n");
                return 1;
            }

            totalFrames++;
            arg++;
        } else if (argString == NSTRING("-o") || argString == NSTRING("--outputindex")) {
            if (argc <= arg + 1) {
                fprintf(stderr, "No output index specified\n");
                return 1;
            }

            if (!nstringToInt(argv[arg + 1], outputIndex)) {
                fprintf(stderr, "Couldn't convert %s to an integer (index)\n", nstringToUtf8(argv[arg + 1]).c_str());
                return 1;
            }
            arg++;
        } else if (argString == NSTRING("-r") || argString == NSTRING("--requests")) {
            if (argc <= arg + 1) {
                fprintf(stderr, "Number of requests not specified\n");
                return 1;
            }
            if (!nstringToInt(argv[arg + 1], requests)) {
                fprintf(stderr, "Couldn't convert %s to an integer (requests)\n", nstringToUtf8(argv[arg + 1]).c_str());
                return 1;
            }
            arg++;
        } else if (argString == NSTRING("-a") || argString == NSTRING("--arg")) {
            if (argc <= arg + 1) {
                fprintf(stderr, "No argument specified\n");
                return 1;
            }

            std::string aLine = nstringToUtf8(argv[arg + 1]).c_str();
            size_t equalsPos = aLine.find("=");
            if (equalsPos == std::string::npos) {
                fprintf(stderr, "No value specified for argument: %s\n", aLine.c_str());
                return 1;
            }

            scriptArgs[aLine.substr(0, equalsPos)] = aLine.substr(equalsPos + 1);

            arg++;
        } else if (scriptFilename.empty() && !argString.empty() && argString.substr(0, 1) != NSTRING("-")) {
            scriptFilename = argString;
        } else if (outputFilename.empty() && !argString.empty() && (argString == NSTRING("-") || (argString.substr(0, 1) != NSTRING("-")))) {
            outputFilename = argString;
        } else {
            fprintf(stderr, "Unknown argument: %s\n", nstringToUtf8(argString).c_str());
            return 1;
        }
    }

    if (showVersion && argc > 2) {
        fprintf(stderr, "Cannot combine version information with other options\n");
        return 1;
    } else if (showVersion) {
        return printVersion() ? 0 : 1;
    } else if (showHelp || argc <= 1) {
        printHelp();
        return 1;
    } else if (scriptFilename.empty()) {
        fprintf(stderr, "No script file specified\n");
        return 1;
    } else if (outputFilename.empty()) {
        fprintf(stderr, "No output file specified\n");
        return 1;
    }

    if (outputFilename == NSTRING("-")) {
        outFile = stdout;
    } else {
#ifdef VS_TARGET_OS_WINDOWS
        outFile = _wfopen(outputFilename.c_str(), L"wb");
#else
        outFile = fopen(outputFilename.c_str(), "wb");
#endif
        if (!outFile) {
            fprintf(stderr, "Failed to open output for writing\n");
            return 1;
        }
    }

    if (!vsscript_init()) {
        fprintf(stderr, "Failed to initialize VapourSynth environment\n");
        return 1;
    }

    vsapi = vsscript_getVSApi();
    if (!vsapi) {
        fprintf(stderr, "Failed to get VapourSynth API pointer\n");
        vsscript_finalize();
        return 1;
    }
    
    // Should always succeed
    if (vsscript_createScript(&se)) {
        fprintf(stderr, "Script environment initialization failed:\n%s\n", vsscript_getError(se));
        vsscript_freeScript(se);
        vsscript_finalize();
        return 1;
    }

    {
        VSMap *foldedArgs = vsapi->createMap();
        for (const auto &iter : scriptArgs)
            vsapi->propSetData(foldedArgs, iter.first.c_str(), iter.second.c_str(), static_cast<int>(iter.second.size()), paAppend);
        vsscript_setVariable(se, foldedArgs);
        vsapi->freeMap(foldedArgs);
    }

    start = std::chrono::high_resolution_clock::now();
    if (vsscript_evaluateFile(&se, nstringToUtf8(scriptFilename).c_str(), efSetWorkingDir)) {
        fprintf(stderr, "Script evaluation failed:\n%s\n", vsscript_getError(se));
        vsscript_freeScript(se);
        vsscript_finalize();
        return 1;
    }

    node = vsscript_getOutput(se, outputIndex);
    if (!node) {
       fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n");
       vsscript_freeScript(se);
       vsscript_finalize();
       return 1;
    }

    bool error = false;
    const VSVideoInfo *vi = vsapi->getVideoInfo(node);

    if (showInfo) {
        if (vi->width && vi->height) {
            fprintf(outFile, "Width: %d\n", vi->width);
            fprintf(outFile, "Height: %d\n", vi->height);
        } else {
            fprintf(outFile, "Width: Variable\n");
            fprintf(outFile, "Height: Variable\n");
        }
        if (vi->numFrames)
            fprintf(outFile, "Frames: %d\n", vi->numFrames);
        else
            fprintf(outFile, "Frames: Unknown\n");
        if (vi->fpsNum && vi->fpsDen)
            fprintf(outFile, "FPS: %" PRId64 "/%" PRId64 " (%.3f fps)\n", vi->fpsNum, vi->fpsDen, vi->fpsNum/(double)vi->fpsDen);
        else
            fprintf(outFile, "FPS: Variable\n");

        if (vi->format) {
            fprintf(outFile, "Format Name: %s\n", vi->format->name);
            fprintf(outFile, "Color Family: %s\n", colorFamilyToString(vi->format->colorFamily));
            fprintf(outFile, "Bits: %d\n", vi->format->bitsPerSample);
            fprintf(outFile, "SubSampling W: %d\n", vi->format->subSamplingW);
            fprintf(outFile, "SubSampling H: %d\n", vi->format->subSamplingH);
        } else {
            fprintf(outFile, "Format Name: Variable\n");
        }
    } else {
        const VSVideoInfo *vi = vsapi->getVideoInfo(node);
        if (totalFrames == -1)
            totalFrames = vi->numFrames;
        if ((vi->numFrames && vi->numFrames < totalFrames) || completedFrames >= totalFrames) {
            fprintf(stderr, "Invalid range of frames to output specified:\nfirst: %d\nlast: %d\nclip length: %d\nframes to output: %d\n", completedFrames, totalFrames, vi->numFrames, totalFrames - completedFrames);
            vsapi->freeNode(node);
            vsscript_freeScript(se);
            vsscript_finalize();
            return 1;
        }

        if (!isConstantFormat(vi) || !totalFrames) {
            fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n");
            vsapi->freeNode(node);
            vsscript_freeScript(se);
            vsscript_finalize();
            return 1;
        }

        lastFpsReportTime = std::chrono::high_resolution_clock::now();;
        error = outputNode();
    }

    fflush(outFile);

    if (!showInfo) {
        int totalFrames = outputFrames - startFrame;
        std::chrono::duration<double> elapsedSeconds = std::chrono::high_resolution_clock::now() - start;
        fprintf(stderr, "Output %d frames in %.2f seconds (%.2f fps)\n", totalFrames, elapsedSeconds.count(), totalFrames / elapsedSeconds.count());
    }
    vsapi->freeNode(node);
    vsscript_freeScript(se);
    vsscript_finalize();

    return error ? 1 : 0;
}