All pastes #429598 Raw Edit

Stuff

public text v1 · immutable
·published 2007-04-08 09:39 UTC
rendered paste body
#include <stdio.h>
#include <string.h>

#define SIZEWMAX 800 //It honors the image size tags. These are safety limits.
#define SIZEHMAX 600
#define MAXVALMAX 255 //maxvalmax must be 255 or less since we aren't supporting 16 bit yet.


/*

slomo -- converts pnm stream of interlaced video to twice the number of progressive frames
         by turning each field into it's own frame. Provides nice slowmotion from interlaced.
v0.00

by Jesse Gordon -- jesseg (at) nikola (dawt) com -- 4/8/2007

Compile with gcc slomo.c -o slomo

Use like:

playdv input.dv --dump-frames - |./slomo | encodedv - > out.dv


slomo.c should recover from corrupted streams as well as possible, 
including some garbage at the end of frames (as long as that garbage
doesn't contain P6\n !!)

First it examins the input byte by byte until it finds a P6\n
Then it reads one text line. If it starts out with two 
numbers of the apropriate width and height
for the picture , then it reads the next text line. If the first 
two numbers are out of range, it goes back to scanning for P6\n
If the first two numbers are seemingly valid, then it reads another text line.
If it starts with a number which is a valid maxvalue, then it goes on
to read in width*height*3 raw bytes. If the maxvalue was invalid, then it
goes back to scanning for P6\n
Note that when reading the headers, comments starting with # are ignored
and can be placed anywhere between the P6 line and the maxval line.

Assuming all of the header checked out, then, as I said before,
width*height*3 bytes are read in from stdin, and saved in three 2-D arrays
(one for each color.)

If they all get read in without hitting EOF, then they are processed
and spat back out stdout in the form of two frames each, with half 
of them being shifted up 1 pixel to remove vertical jitter.
If EOF is reached part way through the reading of a frame,
that frame is discarded and not sent to the output. 

*/

int main(void)
{

	int l,i;
	unsigned char ts[1055]; //temp string.
	unsigned char keeprun,mode,msg;
	unsigned int sizew,sizeh,maxval;
	unsigned int tslen,framecounter;
	unsigned char slomo=1;
	unsigned char ubuffr[SIZEWMAX][SIZEHMAX];
	unsigned char ubuffg[SIZEWMAX][SIZEHMAX];
	unsigned char ubuffb[SIZEWMAX][SIZEHMAX];

	unsigned char lbuffr[SIZEWMAX][SIZEHMAX];
	unsigned char lbuffg[SIZEWMAX][SIZEHMAX];
	unsigned char lbuffb[SIZEWMAX][SIZEHMAX];

//	unsigned char buffr[SIZEWMAX][SIZEHMAX];
//	unsigned char buffg[SIZEWMAX][SIZEHMAX];
//	unsigned char buffb[SIZEWMAX][SIZEHMAX];

	unsigned int dc,lc; //dot counter and line counter.
	unsigned int fl; //Field Line 
	int r,g,b;


	while(feof(stdin)==0)
	{

		i=0;while(i<1044){ts[i]=0;i++;}  //Okay, first, we scan byte at a time 
		keeprun=1;			// for P6\n.
		msg=0;
		while((keeprun)&&(feof(stdin)==0))
		{
			fprintf(stderr,".");
			l=fgetc(stdin);
			i=4;
			while(i>0)
			{
				ts[i]=ts[i-1]; //fifo.. or somethng. backwards.
				i--;
			}
			ts[0]=l;
			if(strncmp("\n6P",ts,3)==0) //Remember, it needs to be backwards.
			{
				//fprintf(stderr,"[%s]\n",ts);
				fprintf(stderr,"Found P6 for frame %d!\n",framecounter);
				keeprun=0;
				msg=1; //Tell the next step that this one was sucessful.
			}
		}
		fprintf(stderr,"\n");

		if(msg>0) //if the last step was successful..
		{
			keeprun=1;
			msg=1;
			mode=0;
			while((keeprun)&&(feof(stdin)==0))
			{
				fgets(ts,1033,stdin);
				tslen=strlen(ts);
				if(ts[0]!='#') //If it's not a comment.
				{
					if(tslen<20)
					{
						if(mode==0)
						{
							sscanf(ts,"%d %d",&sizew,&sizeh);
							fprintf(stderr,"sizew=%d, sizeh=%d\n",sizew,sizeh);
							if((sizew<1)||(sizew>SIZEWMAX)||(sizeh<1)||(sizeh>SIZEHMAX))
							{
								msg=0; //tell next section that this part failed.
								keeprun=0;
								fprintf(stderr,"Error: sizew and sizeh were out of range or invalid.\n");
							}
						}
						if(mode==1)
						{
							sscanf(ts,"%d",&maxval);
							fprintf(stderr,"maxval=%d\n",maxval);
							if((maxval<1)||(maxval>MAXVALMAX))
							{
								msg=0; //tell next section that this part failed.
								keeprun=0;
								fprintf(stderr,"Error: maxval is out of range or invalid.\n");
							}
						}
						mode++;
						if(mode>1){keeprun=0;}
					}else{keeprun=0;msg=0;} //invalid parameter, don't even bother.
	
	
				}else{fprintf(stderr,"P6 Comment: %s\n",ts);}
			}
		}

		if(msg)
		{
			fprintf(stderr,"Now reading in the image data..\n");
			msg=1;
			keeprun=1;
			lc=0;
			dc=0;
			i=0;
			while(keeprun)
			{
				if(feof(stdin)==0)
				{
					fl=(lc>>1);

					if(lc&1) //If it's an odd line, it's a lower field.
					{
						lbuffr[dc][fl]=fgetc(stdin);
						lbuffg[dc][fl]=fgetc(stdin);
						lbuffb[dc][fl]=fgetc(stdin);
					}
					else
					{
						ubuffr[dc][fl]=fgetc(stdin);
						ubuffg[dc][fl]=fgetc(stdin);
						ubuffb[dc][fl]=fgetc(stdin);
					}

					i++;
					dc++;
					if(dc>=sizew){dc=0;lc++;/*printf("\n");*/}
					if(lc>=sizeh){keeprun=0;}
				}
				else
				{
					fprintf(stderr,"Note: EOF at line %d, pixel %d in frame %d. Dropping it because it's incomplete.\n",lc,dc,framecounter);
					msg=0; //tell the next process that this frame is damaged.
					keeprun=0;
				}
			}
		}
		if(msg)
		{
			//Process and print out our frame here.

			if(slomo)
			{
				printf("P6\n#From Bottom Top Field\n%d %d\n%d\n",sizew,sizeh,maxval);
				keeprun=1;
				lc=0;
				dc=0;
				i=0;
				while(keeprun)
				{
					fl=(lc>>1);
					r=lbuffr[dc][fl];
					g=lbuffg[dc][fl];
					b=lbuffb[dc][fl];
	
					if(r<0){r=0;}if(r>255){r=255;}
					if(g<0){g=0;}if(g>255){g=255;}
					if(b<0){b=0;}if(b>255){b=255;}
					printf("%c%c%c",r,g,b);
					i++;
					dc++;
					if(dc>=sizew){dc=0;lc++;/*printf("\n");*/}
					if(lc>=sizeh){keeprun=0;}
				}

				printf("P6\n#From Top Field\n%d %d\n%d\n",sizew,sizeh,maxval);
				keeprun=1;
				lc=1; //This moves the second frame up one pixel. (1 vs 0)
				dc=0;
				i=0;
				while(keeprun)
				{
					fl=(lc>>1);
					r=ubuffr[dc][fl];
					g=ubuffg[dc][fl];
					b=ubuffb[dc][fl];
	
					if(r<0){r=0;}if(r>255){r=255;}
					if(g<0){g=0;}if(g>255){g=255;}
					if(b<0){b=0;}if(b>255){b=255;}
					printf("%c%c%c",r,g,b);
					i++;
					dc++;
					if(dc>=sizew){dc=0;lc++;/*printf("\n");*/}
					if(lc>=sizeh){keeprun=0;}
				}
				dc=0;
				while(dc<sizew) //Lets make up for the missing line..
				{
					r=ubuffr[dc][fl];
					g=ubuffg[dc][fl];
					b=ubuffb[dc][fl];
	
					if(r<0){r=0;}if(r>255){r=255;}
					if(g<0){g=0;}if(g>255){g=255;}
					if(b<0){b=0;}if(b>255){b=255;}
					printf("%c%c%c",r,g,b);
					dc++;
				}

			}
			else
			{

				printf("P6\n#Interlaced\n%d %d\n%d\n",sizew,sizeh,maxval);
				keeprun=1;
				lc=0;
				dc=0;
				i=0;
				while(keeprun)
				{
					fl=(lc>>1);

					if(lc&1) //If it's an odd line, it's a lower field.
					{
						r=lbuffr[dc][fl];
						g=lbuffg[dc][fl];
						b=lbuffb[dc][fl];
					}
					else
					{
						r=ubuffr[dc][fl];
						g=ubuffg[dc][fl];
						b=ubuffb[dc][fl];
					}
	
					if(r<0){r=0;}if(r>255){r=255;}
					if(g<0){g=0;}if(g>255){g=255;}
					if(b<0){b=0;}if(b>255){b=255;}
					printf("%c%c%c",r,g,b);
					i++;
					dc++;
					if(dc>=sizew){dc=0;lc++;/*printf("\n");*/}
					if(lc>=sizeh){keeprun=0;}
				}

			}

		}

	framecounter++;
	}
	return 0;
}