//
// yuvscan - a simple tool to scan a file containing YUV-video-data for valid chunks
// to be used to generate an index string for RawSource
// Ernst Peché - 2005
//

#include "string.h"
#include "stdio.h"
#include <io.h>
#include <stdlib.h>
#include <FCNTL.H>
#include <conio.h>

#define BUFLEN 0x10000	//filebuffer

int main(int argc, char* argv[])
{
	int ROUNDBY = 0x100;
	int ROUNDBYBYTES = 9;
	int TRIGGERLEN = 352*352;
	int THRESHOLD = 10;

	int infile;
	FILE * outfile;
	int lenread;
	
	__int64 i, i1;
	__int64 filelen;
	__int64 last_change;
	__int64 i_rounded;
	
	int winlen;
	int frame, framecount;

	char infilename[255];
	char outfilename[255];
	unsigned char * filebuf;//[BUFLEN-1];
	filebuf = new unsigned char [BUFLEN];

	bool state;
	bool last_state;

	if (argc>=2) {
		strcpy(infilename, argv[1]);
	} else {
//		strcpy(infilename, "d:\\avitest\\30s_pal_yuv_2ch_audio.mov");
//		strcpy(infilename, "d:\\avitest\\src6_ref__625.yuv");
//		strcpy(infilename, "d:\\avitest\\blue_sky.yuv");
//		strcpy(infilename, "d:\\avitest\\29frames.y4m");
		printf("No filename given. Usage: yuvscan.exe filename triggerlength threshold round_by_bytes");
		return -1;
	};
	if (argc>=3) sscanf(argv[2], "%d", &TRIGGERLEN);
	if (argc>=4) sscanf(argv[3], "%d", &THRESHOLD);
	if (argc>=5) sscanf(argv[4], "%d", &ROUNDBYBYTES);
	ROUNDBY = 1<<(ROUNDBYBYTES-1);

	strcpy(outfilename, "index.txt");

	infile = _open(infilename, _O_BINARY | _O_SEQUENTIAL | _O_RDONLY);
	if (infile == -1 ) {
		printf("Can't open input file!");
		return -2;	//file error
	}

	filelen = _filelength(infile);

	outfile = fopen(outfilename, "w");
	if (outfile == 0 ) {
		printf("Can't create output file!");
		return -2;	//file error
	}

	i = 0;
	i1 = 0;
	last_state = false;
	frame = 0;

	printf("Scanning %s for valid YUV-ranges\n", infilename);
	printf("framelength:%d,  threshold:%d,  rounded to %d bytes\n\n", TRIGGERLEN, THRESHOLD, ROUNDBY);
	printf("     start\t       end\t  length\tframes\t     indexstring\n");

	do 	{
		lenread = _read (infile, filebuf, BUFLEN);
		if (lenread<=0) break;

		printf("%10I64d \r", i);

		for (i1 = 0; i1<lenread; i1++) {
			if ((filebuf[i1] < (THRESHOLD)) || (filebuf[i1] > (255-THRESHOLD))) {
	            state = false;
			} else {
				state = true;
			}
			if (last_state != state) {
				if (last_state && !state) {
//valid --> not valid
					if ((i + i1 - last_change) > (TRIGGERLEN)) {
//long element found. i+i1 is at first illegal byte
	                    winlen = (int)(i + i1 - last_change);
						framecount = winlen / (TRIGGERLEN);
						i_rounded = (last_change + (ROUNDBY-1)) & (0xFFFFFFFFFFFFFFFF ^ (ROUNDBY-1));

						printf("%10I64d\t%10I64d\t%8d\t%2d\t%5d:%10I64d\n", last_change, i + i1 - 1, winlen, framecount, frame, i_rounded);
						fprintf(outfile, "%5d:%I64d\n", frame, i_rounded);
						
						frame = frame + framecount;
					}
					last_change = i + i1;
				} else {
//not valid --> valid
					last_change = i + i1;
				}
			}
            last_state = state;
        }
	    i = i + BUFLEN;
    } while (true);

	_close (infile);
	fclose(outfile);
	delete filebuf;
	printf("\nReady. Press any key...\n");
	_getch();

	return 0;
}
