00001 #include <stdio.h>
00002 #include <time.h>
00003 #include <string.h>
00004
00005 #include "qtime.h"
00006
00007 #define D(x)
00008 FILE *infile;
00009 FILE *outfile;
00010 const char hexStr[]="0123456789abcdef";
00011
00012
00013
00014
00015
00016
00017 char comStr[1024];
00018
00019 int width=1280;
00020 int height=1024;
00021 int nframes=100;
00022 int sample_dur=80;
00023 int samplesPerChunk=10;
00024 int framesize=80000;
00025 int timescale=600;
00026 int * sizes;
00027 D(FILE * dbg);
00028
00029 long headerSize=0;
00030
00031 void putBigEndian(unsigned long d, int l) {
00032 if (l>3) fputc((d >>24) & 0xff,outfile);
00033 if (l>2) fputc((d >>16) & 0xff,outfile);
00034 if (l>1) fputc((d >> 8) & 0xff,outfile);
00035 if (l>0) fputc((d ) & 0xff,outfile);
00036 }
00037
00038 int parse_special(void) {
00039
00040 time_t ltime;
00041 int n,j,l;
00042 char str[256];
00043 char c;
00044 int i=0;
00045 while (((c=fgetc(infile))!=0x20) && (c!=0x09) && (c!=0x0a) && (c!=0x0d) && (c!=0x0) && (i<255) && ( feof(infile) == 0 )) str[i++]=c;
00046 str[i]=0;
00047
00048 D(fprintf(dbg,"parse_special, str=!%s\n",str));
00049
00050 if (strcmp(str,"mdata")==0) {putBigEndian(headerSize, 4);return 0;}
00051 if (strcmp(str,"height")==0) {putBigEndian(height,2);return 0;}
00052 if (strcmp(str,"width")==0) {putBigEndian(width,2);return 0;}
00053 if (strcmp(str,"width")==0) {putBigEndian(width,2);return 0;}
00054 if (strcmp(str,"nframes")==0) {putBigEndian(nframes,4);return 0;}
00055 if (strcmp(str,"timescale")==0) {putBigEndian(timescale,4);return 0;}
00056 if (strcmp(str,"duration")==0) {putBigEndian(nframes*sample_dur,4);return 0;}
00057 if (strcmp(str,"frame_duration")==0) {putBigEndian(sample_dur,4);return 0;}
00058 if (strcmp(str,"samples_chunk")==0) {putBigEndian(samplesPerChunk, 4);return 0;}
00059 if (strcmp(str,"sample_sizes")==0) {
00060 if (sizes!=NULL) for (i=0;i<nframes;i++) putBigEndian(sizes[i],4);
00061 else for (i=0;i<nframes;i++) putBigEndian(framesize,4);
00062 return 0;
00063 }
00064 if (strcmp(str,"chunk_offsets")==0) {
00065 n= (nframes-1)/samplesPerChunk +1;
00066 putBigEndian(n,4);
00067 if (sizes!=NULL) {
00068 l=0;j=0;
00069 for (i=0; i<nframes;i++) {
00070 if (j==0) putBigEndian(headerSize+l,4);
00071 j++; if (j>=samplesPerChunk) j=0;
00072 l+=sizes[i];
00073 }
00074
00075 } else for (i=0;i<n;i++) putBigEndian(headerSize+framesize*samplesPerChunk*i,4);
00076 return 0;
00077 }
00078 if (strcmp(str,"data_size")==0) {
00079 if (sizes!=NULL) {
00080 l=0;
00081 for (i=0; i<nframes;i++) l+=sizes[i];
00082 putBigEndian(l,4);
00083 } else putBigEndian(nframes * framesize,4);
00084 return 0;
00085 }
00086 if (strcmp(str,"time")==0) {
00087 time (<ime);
00088 ltime+=2082801600;
00089 putBigEndian(ltime,4);return 0;}
00090 return -1;
00091
00092
00093
00094 }
00095 int parse (int top) {
00096 long out_start, out_end;
00097 char c;
00098 unsigned long d,l;
00099 char * cp;
00100 c=fgetc(infile);
00101 out_start=ftell (outfile);
00102
00103 D(fprintf(dbg,"parse(%x)\n",top));
00104
00105 if (!top) putBigEndian(0, 4);
00106 while (( feof(infile) == 0 ) && (c!='}')) {
00107
00108 if ((c!=' ') && (c!=0x9) && (c!=0xa) && (c!=0xd)) {
00109 if (c=='!') {
00110 if (parse_special()<0) return -1;
00111 }
00112
00113 else if (c=='{') {
00114 if (parse(0)<0) return -1;
00115
00116 } else if (c=='#') fgets( comStr, sizeof(comStr), infile);
00117 else if (c=='\'') {
00118 fgets ( comStr, sizeof(comStr), infile);
00119 if ((cp=strchr(comStr,0x0a))!=NULL) cp[0]=0;
00120 if ((cp=strchr(comStr,0x0d))!=NULL) cp[0]=0;
00121 if ((cp=strchr(comStr,'#'))!=NULL) cp[0]=0;
00122 cp=comStr+strlen(comStr)-1;
00123 while ((cp>comStr) && ((cp[0]==0x20) || (cp[0]==0x09))) cp--;
00124 cp[1]=0;
00125 fwrite (comStr,1, strlen(comStr),outfile);
00126
00127 D(fprintf(dbg,"writing string <%s>\n",comStr));
00128
00129 } else if (strchr(hexStr,c)) {
00130 d=0;
00131 l=1;
00132 do {
00133 d=(d<<4)+(strchr(hexStr,c)-hexStr);
00134 l++;
00135 } while (( feof(infile) == 0 ) && (l<=8) && (strchr(hexStr,(c=fgetc(infile)))) );
00136 l=(l)>>1;
00137 putBigEndian(d, l);
00138
00139 D(fprintf(dbg,"writing hex %lx, %lx bytes\n",d,l));
00140
00141
00142 } else if ((c=='}')){
00143 break;
00144
00145 } else {
00146 return -1;
00147 }
00148
00149 }
00150 c=fgetc(infile);
00151
00152 }
00153
00154
00155 if (!top) {
00156 out_end=ftell (outfile);
00157 fseek (outfile,out_start,SEEK_SET);
00158 putBigEndian((out_end-out_start), 4);
00159 fseek (outfile,out_end,SEEK_SET);
00160 }
00161 return 0;
00162 }
00163
00164
00165 int qtime (const char * inFileName,
00166 const char * outFileName,
00167 int i_width,
00168 int i_height,
00169 int i_nframes,
00170 int i_sample_dur,
00171 int i_samplesPerChunk,
00172 int i_framesize,
00173 int i_timescale,
00174 int * i_sizes
00175 ) {
00176 D(dbg=fopen ("/var/qtime_debug","w"));
00177
00178 D(fprintf(dbg,"inFileName=%s\n",inFileName));
00179 D(fprintf(dbg,"ioutFileName=%s\n",outFileName));
00180 D(fprintf(dbg,"i_width=0x%x\n",i_width));
00181 D(fprintf(dbg,"i_height=0x%x\n",i_height));
00182 D(fprintf(dbg,"i_nframes=0x%x\n",i_nframes));
00183 D(fprintf(dbg,"i_sample_dur=0x%x\n",i_sample_dur));
00184 D(fprintf(dbg,"i_samplesPerChunk=0x%x\n",i_samplesPerChunk));
00185 D(fprintf(dbg,"i_framesize=0x%x\n",i_framesize));
00186 D(fprintf(dbg,"i_timescale=0x%x\n",i_timescale));
00187 width= i_width;
00188 height= i_height;
00189 nframes= i_nframes;
00190 sample_dur= i_sample_dur;
00191 samplesPerChunk= i_samplesPerChunk;
00192 framesize= i_framesize;
00193 timescale= i_timescale;
00194 sizes= i_sizes;
00195 remove (outFileName);
00196
00197
00198 if ((infile= fopen (inFileName,"r"))==NULL) return -1;
00199 if ((outfile=fopen (outFileName,"wb+"))==NULL) return -1;
00200
00201 D(fprintf(dbg,"PASS I\n"));
00202
00203 while ( feof(infile) == 0 ) parse(1);
00204
00205 headerSize=ftell (outfile);
00206 fseek (outfile,0,SEEK_SET);
00207 fseek (infile, 0,SEEK_SET);
00208
00209 D(fprintf(dbg,"PASS II\n"));
00210 while ( feof(infile) == 0 ) parse(1);
00211
00212 fclose (infile);
00213 fclose (outfile);
00214 D(fclose (dbg));
00215 return 0;
00216 }
00217