Beispiel #1
0
int main (int argc, char **argv) {
    cpSpace *space = cpSpaceNew();
    cpSpaceSetGravity(space, cpv(0, GRAVITY));
    cpEnableSegmentToSegmentCollisions();
    
    cpShape *ground = cpSpaceAddShape(space, cpSegmentShapeNew(space->staticBody, cpv(0, 5), cpv(10, -5), 0));
    cpShapeSetFriction(ground, 0.3);
    
    cpBody *drawing = drawing_new(2, 7, 0);
    drawing = drawing_update(space, drawing, 3, 8);
    drawing = drawing_update(space, drawing, 3, 9);
    drawing = drawing_update(space, drawing, 2, 9);
    //cpBody *drawing = drawing_new(0, 0, 0);
    //drawing = drawing_update(space, drawing, 2, 0);
    //drawing = drawing_update(space, drawing, 2, 2);
    //drawing = drawing_update(space, drawing, 0, 2);
    print_positions(drawing);
    
    //drawing_activate(drawing);
    //print_positions(drawing);
    
    cpVect vel, pos;
    int i = 0;
    for(cpFloat time = 0; time < 2; time += TIMESTEP){
        pos = cpBodyGetPos(drawing);
        vel = cpBodyGetVel(drawing);
        
        printf( "Time = %2.2f Position = (%2.2f, %2.2f) Velocity = (%2.2f, %2.2f)\n",
            time, pos.x, pos.y, vel.x, vel.y);
        cpSpaceStep(space, TIMESTEP);
        
        i++;
        if (i == 20) {
            drawing_activate(space, drawing);
            print_positions(drawing);
        }
    }
    print_positions(drawing);
    
    free_body_full(drawing);
    cpShapeFree(ground);
    cpSpaceFree(space);
    return EXIT_SUCCESS;
}
Beispiel #2
0
int main(int argc, char *argv[])
{

    const char* optstring = ":ha:p:P:ld:D:";
    const struct option lopts[] = {
        {"help", no_argument, NULL, 'h'},
        {"appartient", required_argument, NULL, 'a'},
        {"positions", required_argument, NULL, 'p'},
        {"phrases", required_argument, NULL, 'P'},
        {"liste", no_argument, NULL, 'l'},
        {"prefixe", required_argument, NULL, 'd'},
        {"tofile", required_argument, NULL, 'D'},
        {NULL, no_argument, NULL, 0}
    };

    int val,index=-1;
    int last_val = val;
    char* last_optarg;


    while (EOF!=(val=getopt_long(argc,argv,optstring,lopts,&index))) {
        char msg[32];
        if (index==-1) sprintf(msg,"short option -%c",val);
        else sprintf(msg,"long option --%s",lopts[index].name);

        if(val == 'h') {
            print_help();
            exit(0);
        }
        last_val = val;
        last_optarg = optarg;
        #ifdef DEBUG
        printf("Option %c with opt %s recieved\n", val, optarg);
        #endif
        index=-1;
    }

    Cellule tab[N];
    int i = 0;
    for(; i<N; ++i) {
        tab[i].valeur = NULL;
        tab[i].suivant = NULL;
    }
    Liste alphab = NULL;
    if(argc == 1) {
        interactive_menu(tab, N, &alphab);
        exit(0);
    }

    if(optind < argc) {
        parse_file(tab, N, argv[optind], &alphab);
        if(last_val == 'a') {
            int res = belongs(last_optarg, tab, N);
            if(res)
                printf("Word %s is in file %s",last_optarg, argv[optind]);
            else
                printf("Word %s is not in file %s", last_optarg, argv[optind]);
        }
        else if(last_val == 'p') {
            print_positions(last_optarg, tab, N);
        }
        else if(last_val == 'P') {
            print_sentences_containing_word(last_optarg, argv[optind], tab, N);
        }
        else if(last_val == 'l') {
            print_alphabetical(alphab);
        }
        else if(last_val =='d') {
            print_all_from_prefix(last_optarg, alphab);
        }
        else if(last_val == 'D') {
            save_positions_to_file(last_optarg, alphab);
        }
    }
    else {
        fprintf(stderr, "Error: not enough arguments\n");
        print_help();
    }


    #ifdef DEBUG
    print_tab(tab, N);
    #endif


    for(i = 0; i<N; ++i)
        liste_free(tab[i].suivant, 0x3);
    liste_free(alphab, 0x0);

    return 0;
}
Beispiel #3
0
/**
 * This is the interactive menu. It is launched if the number of given args is == 1.
 * @param tab     the array containing the parsed data.
 * @param tab_len the length of the array
 * @param alphab  the pointer to the Liste which will contain the alphabetically-sorted data
 */
static void interactive_menu(Cellule* tab, int tab_len, Liste* alphab) {
    char choice = 0;
    char fname[256];
    char mot[32];
    printf("Index v%s - Menu interactif\n\n", version);
    printf("Entrez le nom du fichier à analyser: ");
    if(scanf("%s", fname) != 1) {
        fprintf(stderr, "Error while reading input\n");
        exit(1);
    }
    getchar(); /* removes the \n */
    FILE* tmp;
    if((tmp = fopen(fname, "r")) == NULL) {
        fprintf(stderr, "Error: file %s cannot be found.", fname);
        exit(1);
    }
    fclose(tmp);

    parse_file(tab, tab_len, fname, alphab);
    while(choice != 'q' && choice != EOF) {
        printf("Choix\n"
            "\n"
            "a - teste l'appartenance d'un mot au fichier\n"
            "p - affiche les positions de mot dans le fichier\n"
            "P - affiche les phrases contenant mot dans le fichier\n"
            "l - affiche l'intégralité ddes mots (triés) présents dans le texte\n"
            "d - affiche l'ensemble des mots du texte ayant pour préfixe mot\n"
            "D - sauvegarde dans un fichier la liste des mots, avec leurs positions\n"
            "q ou ctrl+d - quitter\n"
            "\n"
            "Que voulez vous faire?\n"
            );
        choice = getchar();
        if(choice != EOF)
            getchar(); /* removes the \n */
        #ifdef DEBUG
        printf("Choice: %c (%d)", choice, choice);
        #endif
        if(choice == 'a'){
            printf("Entrez le mot à rechercher: ");
            if(scanf("%s", mot) != 1) {
                fprintf(stderr, "Error while reading input\n");
                exit(1);
            }
            getchar(); /* removes the \n */
            if(belongs(mot, tab, tab_len)) {
                printf("%s appartient à %s\n", mot, fname);
            }
            else
                printf("%s n'appartient pas à %s\n", mot, fname);
        }
        else if(choice == 'p') {
            printf("Entrez le mot à rechercher: ");
            if(scanf("%s", mot) != 1) {
                fprintf(stderr, "Error while reading input\n");
                exit(1);
            }
            getchar(); /* removes the \n */
            print_positions(mot, tab, tab_len);
        }
        else if(choice == 'P') {
            printf("Entrez le mot à rechercher: ");
            if(scanf("%s", mot) != 1) {
                fprintf(stderr, "Error while reading input\n");
                exit(1);
            }
            getchar(); /* removes the \n */
            print_sentences_containing_word(mot, fname, tab, tab_len);
        }
        else if(choice == 'l') {
            print_alphabetical(*alphab);
        }
        else if(choice =='d') {
            printf("Entrez le mot à rechercher: ");
            if(scanf("%s", mot) != 1) {
                fprintf(stderr, "Error while reading input\n");
                exit(1);
            }
            getchar(); /* removes the \n */
            print_all_from_prefix(mot, *alphab);
        }
        else if(choice == 'D') {
            char fsave[256];
            printf("Entrez le nom de fichier dans lequel sauvegarder: ");
            if(scanf("%s", fname) != 1) {
                fprintf(stderr, "Error while reading input\n");
                exit(1);
            }
            getchar(); /* removes the \n */
            save_positions_to_file(fsave, *alphab);
        }
        else if(choice == 'q' || choice == EOF) {
            printf("Quit.\n");
        }
        else
            printf("Not a valid choice: %c\n", choice);

    }

}
Beispiel #4
0
unsigned long Read_VOD( char *theURL )
{ unsigned long N = 0;
  VODFiles *fp;
  FOFFSET jpgOffset, prev_Offset=0, prev_fpos, audioOffset;
  uint32_t VOBid;
  VOB_JPEG_Headers jH, prev_jH;
  VOB_Audio_Headers aH;
  int current_vmgi;
  int ok, nextFound;
  VMGIs vmgi;
  double tskipped = 0, audioDuration = 0;
  struct readtables {
	  int current_vmgi;
	  FOFFSET current_vmgiPos;
	  int VOB_Ns, vmgiAudioChunks, vmgiVideoFrames;
	  int frames;
	  int doubles;
  } *readtable, *rt;
  unsigned int readtableN = 0;
  char *mode = "rb";
  double frameRate;
  FILE *dumpFP = NULL;
  int pcloseDumpFP = 0, gotPipeSignal;
  size_t jpgFrameCount = 0, mp4FragCount = 0;
  char dirTemp[128] = "VODconverting-XXXXXX", *bURL = NULL;
  MPG4_Fragments mp4Frag;
  struct {
	  VOB_Dates StartDate;
	  VOB_Times StartTime;
	  int isSet;
#if defined(_MSC_VER) || defined(__MINGW32__)
	  struct _utimbuf ut;
#else
	  struct timeval t[2];
#endif
  } StartTimeStamp;
#if defined(_MSC_VER)
  POpenExProperties popProps;
#endif
#ifdef EXTRACTCHANNELVIEWS
  int ff;
  FILE *pfp[4] = {NULL, NULL, NULL, NULL};
#endif

	init_HRTime();
	HRTime_tic();
	if( (fp = open_VODFile( &FP, theURL, mode )) ){
		if( !validate_VODFile( fp, 0 ) ){
			fprintf( stderr, "Not a VOD file \"%s\"\n", theURL );
			close_VODFile(fp);
			return 0;
		}
		fprintf( stderr, "Opened VOD file \"%s\"\n", theURL );
#ifdef __APPLE_CC__
		fpBase = FP.theFile->_bf._base;
#endif
		readtable = (struct readtables*) calloc(1, sizeof(struct readtables));
		mkdtemp(dirTemp);
		bURL = strdup( basename(theURL) );
#if defined(WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
		strcat( dirTemp, "\\" );
#else
		strcat( dirTemp, "/" );
#endif
		fprintf( stderr, "@@\t average frequency: %gHz\n", (frameRate = VODFile_Find_averageRate(fp)) );
		CLEAR_MPG4_FRAGMENT(&mp4Frag);
		memset( &StartTimeStamp, 0, sizeof(StartTimeStamp) );
		VMGICHECK( Read_VMGI( fp ) ){
		  FOFFSET fpos;
			if( fp->hasMPG4 && !dumpFP ){
			   char command[1024];
#if defined(_MSC_VER) || defined(WIN32) || defined(__MINGW32__)
			   const char *mode = "wb";
#else
			   const char *mode = "w";
#endif
				snprintf( command, sizeof(command),
					    "ffmpeg -y -v 1 -i - -vcodec copy \"%s.%4d%02d%02d%02d%02d.mov\"",
						theURL,
						fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day,
						fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes );
	//			snprintf( command, sizeof(command), "cat > %s.fragments.mov -", theURL );
				fprintf( stderr, "Sending content to \"%s\"\n", command );
#if defined(_MSC_VER)
				popProps.commandShell = "ffmpeg.exe";
				popProps.shellCommandArg = NULL;
				popProps.runPriorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
				popProps.finishPriorityClass = HIGH_PRIORITY_CLASS;
				dumpFP = popenEx( command, mode, &popProps );
#else
				dumpFP = popen( command, mode );
#endif
				if( dumpFP ){
					SetupPipeSignalHandler(&gotPipeSignal);
					pcloseDumpFP = 1;
				}
#ifdef EXTRACTCHANNELVIEWS
				snprintf( command, sizeof(command),
					    "ffmpeg -y -v 1 -i - -vf crop=360:288:0:0 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera1.mov\"",
						theURL,
						fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day,
						fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes );
#ifdef _MSC_VER
				pfp[0] = popenEx( command, mode, &popProps );
#else
				pfp[0] = popen( command, mode );
#endif
				snprintf( command, sizeof(command),
					    "ffmpeg -y -v 1 -i - -vf crop=360:288:360:0 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera2.mov\"",
						theURL,
						fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day,
						fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes );
#ifdef _MSC_VER
				pfp[1] = popenEx( command, mode, &popProps );
#else
				pfp[1] = popen( command, mode );
#endif
				snprintf( command, sizeof(command),
					    "ffmpeg -y -v 1 -i - -vf crop=360:288:0:288 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera3.mov\"",
						theURL,
						fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day,
						fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes );
#ifdef _MSC_VER
				pfp[2] = popenEx( command, mode, &popProps );
#else
				pfp[2] = popen( command, mode );
#endif
				snprintf( command, sizeof(command),
					    "ffmpeg -y -v 1 -i - -vf crop=360:288:360:288 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera4.mov\"",
						theURL,
						fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day,
						fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes );
#ifdef _MSC_VER
				pfp[3] = popenEx( command, mode, &popProps );
#else
				pfp[3] = popen( command, mode );
#endif
#endif // EXTRACTCHANNELVIEWS
			}
			current_vmgi = fp->current_vmgi;
			if( !StartTimeStamp.isSet ){
				StartTimeStamp.StartDate = fp->vmgi.StartDate;
				StartTimeStamp.StartTime = fp->vmgi.StartTime;
				StartTimeStamp.isSet = 1;
#ifdef _MSC_VER
				{ struct tm tmm = {0};
					// Fill out the modified time structure
					// tm_hour is supposed to be in UTC, so we correct for the fact we're in Western continental Europe
					tmm.tm_hour = fp->vmgi.StartTime.hours - 1;
					// guess whether DST was in effect:
					tmm.tm_isdst = (fp->vmgi.StartDate.month > 3 && fp->vmgi.StartDate.month < 11)? 1 : 0;
					tmm.tm_min = fp->vmgi.StartTime.minutes;
					tmm.tm_sec = fp->vmgi.StartTime.seconds;
					tmm.tm_mday = fp->vmgi.StartDate.day;
					// tm_mon is 0 based
					tmm.tm_mon = fp->vmgi.StartDate.month - 1;
					// tm_year starts at 1900
					tmm.tm_year = fp->vmgi.StartDate.year - 1900;
					
					// Convert tm to time_t
					StartTimeStamp.ut.actime = StartTimeStamp.ut.modtime = mktime(&tmm);
				}
#endif
			}
			fprintf( stderr, "## VMGI #%d @ 0x%lx (%.3g%%), %d video, %u audio frames%s%s, %4d%02d%02d::%02d:%02d:%02d - %4d%02d%02d::%02d:%02d:%02d\n",
				fp->current_vmgi, (unsigned long) fp->current_vmgiPos,
				((double)fp->current_vmgiPos)/((double) fp->fileSize) * 100.0,
				fp->vmgiVideoFrames, fp->vmgiAudioChunks,
				(fp->vmgi.VOB_Ns != fp->vmgiVideoFrames+fp->vmgiAudioChunks)? " plus something else" : "",
				(fp->vmgi.InfoType==2)? ", GPS" : "",
				fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day,
				fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes, fp->vmgi.StartTime.seconds,
				fp->vmgi.EndDate.year, fp->vmgi.EndDate.month, fp->vmgi.EndDate.day,
				fp->vmgi.EndTime.hours, fp->vmgi.EndTime.minutes, fp->vmgi.EndTime.seconds
			);
			fflush( stderr );
			if( N == 0 ){
				fpos = FFTELL(fp->theFile);
				// we save fp->vmgi because Read_VOB_JPEG_Header_Scan_Next() can update this field to the file's next VMGI
				// when in fact we still want to print out information from the current one...
				vmgi = fp->vmgi;
			}
#ifdef USE_VMGI
			readtableN += 1;
			if( (readtable = (struct readtables*) realloc( readtable, readtableN*sizeof(struct readtables) )) ){
				rt = &readtable[readtableN-1];
				rt->current_vmgi = current_vmgi;
				rt->current_vmgiPos = fp->vmgiPos[current_vmgi];
				rt->VOB_Ns = fp->vmgi.VOB_Ns;
				rt->vmgiAudioChunks = fp->vmgiAudioChunks;
				rt->vmgiVideoFrames = fp->vmgiVideoFrames;
				rt->frames = rt->doubles = 0;
			}
			else{
				rt = NULL;
			}
			// fp and fp->vmgi are always up to date and never ahead of us.
			vmgi = fp->vmgi;
			fpos = FFTELL(fp->theFile);
			fp->readContent = 1;
			for( VOBid = 0; VOBid_Check(fp, VOBid, NULL); VOBid++ ){
				fflush(stdout);
				switch( VODFILE_VOB_TYPE(fp,VOBid) ){
					case VMGI_VOB_TYPE_VIDEO:
						if( (ok = Read_VOB_xPEG_Header( fp, VOBid, &jH, &jpgOffset, &nextFound, &mp4Frag, DUMP_JPGS /*&& (fp->vmgi.InfoType==2)*/ )) ){
							if( ok < 0  ){
								fputs( "((", stderr );
							}
							if( VOB_Header_isJPEG( (VOB_Headers_Common*)&jH ) ){
							  size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char);
							  char *tmpName = (char*) malloc(nameLen);
								if( tmpName ){
									snprintf( tmpName, nameLen, "%s%s.%04ld.jpg", dirTemp, bURL, fp->decodedFrames );
									if( dumpFP ){
										fclose(dumpFP);
									}
									if( (dumpFP = fopen(tmpName, "wb")) ){
										fwrite( fp->lastReadContent, sizeof(unsigned char),
											  fp->lastReadContentByteLength, dumpFP );
										fclose(dumpFP); dumpFP = NULL;
										jpgFrameCount += 1;
									}
									free(tmpName);
								}
								if( VOBid == 0 || VOBid == fp->vmgi.VOB_Ns - 1 ){
									fprintf( stderr, "jpeg image #%d at offset %ld; %hux%hu, %4d%02d%02d::%02d:%02d:%02d flags=%s\n",
										VOBid, (long) jpgOffset,
										jH.Width, jH.Height,
										jH.Date.year, jH.Date.month, jH.Date.day,
										jH.Time.hours, jH.Time.minutes, jH.Time.seconds,
										VOB_JPEG_Flags(&jH)
									);
									if( VOBid == 0 ){
										fputs( "...\n", stderr );
									}
								}
							}
							else if( VOB_Header_isMPG4( (VOB_Headers_Common*)&jH ) ){
								if( !dumpFP ){
								  size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char);
								  char *tmpName = (char*) malloc(nameLen);
									if( tmpName ){
										snprintf( tmpName, nameLen, "%s%s.fragments.mp4", dirTemp, bURL, fp->decodedFrames );
										dumpFP = fopen(tmpName, "wb");
										free(tmpName);
									}
								}
								if( dumpFP ){
									fwrite( fp->lastReadContent, sizeof(unsigned char),
										  fp->lastReadContentByteLength, dumpFP );
									if( gotPipeSignal ){
#ifdef _MSC_VER
										pcloseEx(dumpFP);
#else
										pclose(dumpFP);
#endif
										dumpFP = NULL;
										goto done;
									}
									mp4FragCount += 1;
								}
#ifdef EXTRACTCHANNELVIEWS
								for( ff = 0 ; ff < 4 ; ff++ ){
									if( pfp[ff] ){
										fwrite( fp->lastReadContent, sizeof(unsigned char),
											  fp->lastReadContentByteLength, pfp[ff] );
										if( gotPipeSignal ){
#ifdef _MSC_VER
											pcloseEx(pfp[ff]);
#else
											pclose(pfp[ff]);
#endif
											pfp[ff] = NULL;
											goto done;
										}
									}
								}
#endif
#ifndef NO_FFMPEGLIBS_DEPEND
								fprintf( stderr, "MPEG4 fragment #%d.%d at offset %ld(%ld), %d(%lu) bytes of %lu; %hux%hu, %4d%02d%02d::%02d:%02d:%02d flags=%s\n",
									VOBid, mp4Frag.current.frameNr,
									(long) jpgOffset, (long) jpgOffset - (long) mp4Frag.fileOffset,
									mp4Frag.current.byteLength, jH.Length - sizeof(jH), mp4Frag.byteLength,
									jH.Width, jH.Height,
									jH.Date.year, jH.Date.month, jH.Date.day,
									jH.Time.hours, jH.Time.minutes, jH.Time.seconds,
									VOB_JPEG_Flags(&jH)
								);
#else
								fprintf( stderr, "MPEG4 fragment #%d.%d @0x%lx, %lu bytes; %hux%hu, %4d%02d%02d::%02d:%02d:%02d flags=%s\n",
									VOBid, mp4Frag.current.frameNr,
									(long) jpgOffset, mp4Frag.byteLength,
									jH.Width, jH.Height,
									jH.Date.year, jH.Date.month, jH.Date.day,
									jH.Time.hours, jH.Time.minutes, jH.Time.seconds,
									VOB_JPEG_Flags(&jH)
								);
#endif
							}

							if( fp->hasGPS ){
								if( fp->gpsData.fieldsRead > 0 ){
									fprintf( stderr, "\tGPS NMEA Sentence %s[%d] ; speed=%g\n", 
										   fp->nmeaSentence, fp->gpsData.fieldsRead, fp->gpsData.speed
									);
								}
							}
							if( ok > 0 ){
								if( rt ){
									rt->frames += 1;
									if( jpgOffset == prev_Offset ){
										rt->doubles += 1;
									}
								}
								tskipped += print_positions( stdout, fp, &vmgi, N, &jH, &prev_jH, jpgOffset, &prev_Offset, &fpos, &prev_fpos );
								N += 1;
							}
						};
						break;
					case VMGI_VOB_TYPE_AUDIO:
						Find_Next_VOB_Audio_Header(fp, NULL, NULL, 1);
						fp->curPos += 1;
						break;
					default:
						break;
				}
				fflush(stderr);
			}
			fp->readContent = 0;
			if( strncmp( fp->vmgi.Id, "VOBX", 4 ) == 0 && fp->vmgi.VOB_Ns == 0 ){
				fprintf( stderr, "Encountered an empty VOBX instead of a VOBS - assuming end of recording!\n" );
				break;
			}
#else	// !USE_VMGI
			fp->readContent = 1;
			while( (ok = Read_VOB_xPEG_Header_Scan_Next( fp, &jH, &jpgOffset, &nextFound, &mp4Frag, DUMP_JPGS )) || nextFound ){
				if( current_vmgi != fp->current_vmgi || readtableN == 0 ){
					current_vmgi = fp->current_vmgi;
					readtableN += 1;
					fprintf( stderr, "## VMGI #%d @ 0x%lx (%.3g%%), %d video, %u audio frames%s%s, %4d%02d%02d::%02d:%02d:%02d - %4d%02d%02d::%02d:%02d:%02d\n",
						fp->current_vmgi, (unsigned long) fp->current_vmgiPos,
						((double)fp->current_vmgiPos)/((double) fp->fileSize) * 100.0,
						fp->vmgiVideoFrames, fp->vmgiAudioChunks,
						(fp->vmgi.VOB_Ns != fp->vmgiVideoFrames+fp->vmgiAudioChunks)? " plus something else" : "",
						(fp->vmgi.InfoType==2)? ", GPS" : "",
						fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day,
						fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes, fp->vmgi.StartTime.seconds,
						fp->vmgi.EndDate.year, fp->vmgi.EndDate.month, fp->vmgi.EndDate.day,
						fp->vmgi.EndTime.hours, fp->vmgi.EndTime.minutes, fp->vmgi.EndTime.seconds
					);
					fflush( stderr );
					if( (readtable = (struct readtables*) realloc( readtable, readtableN*sizeof(struct readtables) )) ){
						rt = &readtable[readtableN-1];
						rt->current_vmgi = current_vmgi;
						rt->current_vmgiPos = fp->vmgiPos[current_vmgi];
						rt->VOB_Ns = fp->vmgi.VOB_Ns;
						rt->vmgiAudioChunks = fp->vmgiAudioChunks;
						rt->vmgiVideoFrames = fp->vmgiVideoFrames;
						rt->frames = rt->doubles = 0;
					}
					else{
						rt = NULL;
					}
				}
				if( ok ){
					fflush(stdout);
					if( ok < 0 ){
						fputs( "((", stderr );
					}
					if( VOB_Header_isJPEG( (VOB_Headers_Common*)&jH ) ){
					  size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char);
					  char *tmpName = (char*) malloc(nameLen);
						if( tmpName ){
							snprintf( tmpName, nameLen, "%s%s.%04ld.jpg", dirTemp, bURL, fp->decodedFrames );
							if( dumpFP ){
								fclose(dumpFP);
							}
							if( (dumpFP = fopen(tmpName, "wb")) ){
								fwrite( fp->lastReadContent, sizeof(unsigned char),
									  fp->lastReadContentByteLength, dumpFP );
								fclose(dumpFP); dumpFP = NULL;
								jpgFrameCount += 1;
							}
							free(tmpName);
						}
						fprintf( stderr, "jpeg image #%d:%d at offset %lu; %hux%hu, %4d%02d%02d::%02d:%02d:%02d\n",
							fp->current_vmgi, fp->current_VOBDes, (unsigned long) jpgOffset,
							jH.Width, jH.Height,
							jH.Date.year, jH.Date.month, jH.Date.day,
							jH.Time.hours, jH.Time.minutes, jH.Time.seconds
						);
					}
					else if( VOB_Header_isMPG4( (VOB_Headers_Common*)&jH ) ){
						if( !dumpFP ){
						  size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char);
						  char *tmpName = (char*) malloc(nameLen);
							if( tmpName ){
								snprintf( tmpName, nameLen, "%s%s.fragments.mp4", dirTemp, bURL, fp->decodedFrames );
								dumpFP = fopen(tmpName, "wb");
								free(tmpName);
							}
						}
						if( dumpFP ){
							fwrite( fp->lastReadContent, sizeof(unsigned char),
								  fp->lastReadContentByteLength, dumpFP );
							mp4FragCount += 1;
						}
						fprintf( stderr, "MPEG4 fragment #%d:%d at offset %lu, %lu bytes; %hux%hu, %4d%02d%02d::%02d:%02d:%02d\n",
							fp->current_vmgi, fp->current_VOBDes, (unsigned long) jpgOffset, fp->lastReadContentByteLength,
							jH.Width, jH.Height,
							jH.Date.year, jH.Date.month, jH.Date.day,
							jH.Time.hours, jH.Time.minutes, jH.Time.seconds
						);
					}
					fflush( stderr );
					if( ok > 0 ){
						if( rt ){
							rt->frames += 1;
							if( jpgOffset == prev_Offset ){
								rt->doubles += 1;
							}
						}
						tskipped += print_positions( stdout, fp, &vmgi, N, &jH, &prev_jH, jpgOffset, &prev_Offset, &fpos, &prev_fpos );
						N += 1;
					}
				}
			}
			fp->readContent = 0;
#endif	// USE_VMGI
		}
done:
		// whether or not the scan of the file is complete is up to us to decide, though the routines in brigade.c
		// will set the flag if they encounter EOF.
		fp->scanComplete = 1;
		if( dumpFP ){
		  char fname[1024];
			if( pcloseDumpFP ){
				fflush(stdout);
				fprintf( stderr, "Waiting for ffmpeg to terminate..." ); fflush(stderr);
#ifdef _MSC_VER
				pcloseEx(dumpFP);
				fprintf( stderr, " took %g user and %g kernel seconds\n",
					   popProps.times.user, popProps.times.kernel );
#else
				pclose(dumpFP);
				fputs( "\n", stderr );
#endif
				snprintf( fname, sizeof(fname), "%s.%4d%02d%02d%02d%02d.mov",
					    theURL, StartTimeStamp.StartDate.year, StartTimeStamp.StartDate.month, StartTimeStamp.StartDate.day,
					    StartTimeStamp.StartTime.hours, StartTimeStamp.StartTime.minutes );
#ifdef _MSC_VER
				_utime( fname, &StartTimeStamp.ut );
#endif
			}
			else{
				fclose(dumpFP);
			}
			dumpFP = NULL;
		}
#ifdef EXTRACTCHANNELVIEWS
		for( ff = 0 ; ff < 4 ; ff++ ){
			if( pfp[ff] ){
#ifdef _MSC_VER
				pcloseEx(pfp[ff]);
#else
				pclose(pfp[ff]);
#endif
				pfp[ff] = NULL;
			}
		}
#endif
		if(0){
		  int aN = 0, pN = fp->NaudioPos;
		  extern int Find_All_VOB_Audio_Headers( VODFiles *fp );
			fprintf( stderr, "Doing an exhaustive scan for audio ... " );
			fflush(stderr);
			aN = Find_All_VOB_Audio_Headers(fp);
			if( aN != pN ){
				fprintf( stderr, " encountered %d chunks", aN );
			}
			fputs( "\n", stderr );
			rewind_VODFile(fp, NULL);
		}
		else{
			rewind_VODFile(fp, NULL);
		}
		if( fp ){
			fprintf( stderr, "Read %d VMGIs and encountered %d audio chunks while scanning for video frames\n",
				    fp->NvmgiPos, fp->NaudioPos
			);
		}
		else{
			fprintf( stderr, "Error reopening file after rewind (%s)\n", strerror(errno) );
		}
		if( fp && fp->NaudioPos ){
		  FILE *audioFP = NULL;
		  char *tmpName;
		  int tnl;
			if( (tmpName = (char*) malloc( (tnl = strlen(theURL)+32) * sizeof(char) )) ){
				snprintf( tmpName, tnl, "%s.au1", fp->theURL );
				audioFP = fopen( tmpName, "wb" );
				free(tmpName), tmpName = NULL;
			}
			for( VOBid = 0, audioDuration = 0 ; VOBid < fp->NaudioPos ; VOBid++ ){
			  uint32_t audioLength;
			  double duration, freq[] = { 8, 11025, 22050, 44100 };
				if( VOBid == 0 || fp->audioPos[VOBid] != fp->audioPos[VOBid-1] ){
					Read_VOB_Audio_Header_From_audioPos( fp, VOBid, &aH, &audioOffset, &audioLength, 1, audioFP );
					if( aH.Audio_Channel == 2 ){
						duration = audioLength / 2 / freq[aH.Audio_Rate];
					}
					else{
						duration = audioLength / freq[aH.Audio_Rate];
					}
					fprintf( stderr, "Audio chunk #%d: %lu bytes at 0x%lx; duration=%gs\n",
						    VOBid, audioLength, (unsigned long) audioOffset, duration
					);
					audioDuration += duration;
				}
			}
			if( audioFP ){
				fclose(audioFP);
			}
		}
		if( audioDuration ) {
			fprintf( stderr, "Total audio duration: %gs\n", audioDuration );
		}
		Finalise_MPG4_Fragment(&mp4Frag);
		close_VODFile(fp);
		fprintf( stderr, "Average skipped bytes per frame: %g\n", tskipped / N );
#ifdef DEBUG
		if( readtable ){
		  int i, AudioChunks = 0;
			for( i = 0; i< readtableN; i++){
				fprintf( stderr, "%03d VMGI #%d@0x%lu\tframes=%d\tVOB_Ns=%d,VideoFrames=%d,AudioChunks=%d",
					    i, readtable[i].current_vmgi, (unsigned long)readtable[i].current_vmgiPos,
					    readtable[i].frames, readtable[i].VOB_Ns, readtable[i].vmgiVideoFrames, readtable[i].vmgiAudioChunks
				);
				if( rt->doubles ){
					fprintf( stderr, "\tdoubles=%d", rt->doubles );
				}
				fputc( '\n', stderr );
				AudioChunks += readtable[i].vmgiAudioChunks;
			}
			free(readtable);
			readtable = NULL;
		}
#endif
		{ char command[1024];
			if( jpgFrameCount ){
				snprintf( command, sizeof(command),
					    "ffmpeg -y -r %g -i %s%s.%%04d.jpg -vcodec copy \"%s.%4d%02d%02d%02d%02d.mov\"",
					    frameRate, dirTemp, bURL,
					    theURL, StartTimeStamp.StartDate.year, StartTimeStamp.StartDate.month, StartTimeStamp.StartDate.day,
					    StartTimeStamp.StartTime.hours, StartTimeStamp.StartTime.minutes );
				system( command );
			}
//			if( mp4FragCount ){
//				snprintf( command, sizeof(command), "ffmpeg -y -i %s%s.fragments.mp4 -vcodec copy %s.converted.mov",
//					    dirTemp, bURL, theURL );
//				system( command );
//			}
#if defined(WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
			snprintf( command, sizeof(command), "rmdir /s /q %s", dirTemp );
#else
			snprintf( command, sizeof(command), "rm -rf %s", dirTemp );
#endif
			system(command);
			snprintf( command, sizeof(command), "%s.%4d%02d%02d%02d%02d.mov",
				    theURL, StartTimeStamp.StartDate.year, StartTimeStamp.StartDate.month, StartTimeStamp.StartDate.day,
				    StartTimeStamp.StartTime.hours, StartTimeStamp.StartTime.minutes );
#ifdef _MSC_VER
			_utime( command, &StartTimeStamp.ut );
#endif
			free(bURL);
		}
#ifdef USE_VMGI
		if( mp4Frag.valid ){
			fprintf( stderr, "Read %lu %gHz 1sec fragments from \"%s\" in %g sec (using VMGI info)\n",
				   N, frameRate, theURL, HRTime_toc() );
		}
		else{
			fprintf( stderr, "Read %lu frames from \"%s\" in %g sec (using VMGI info)\n", N, theURL, HRTime_toc() );
		}
#else
		fprintf( stderr, "Read %lu frames from \"%s\" in %g sec\n", N, theURL, HRTime_toc() );
#endif
	}
	else{