00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 #include <stdio.h>
00080 #include "all.h"
00081 #include "mtypes.h"
00082 #include "frames.h"
00083 #include "prototypes.h"
00084 #include "param.h"
00085 #include "readframe.h"
00086 #include "fsize.h"
00087 #include "rgbtoycc.h"
00088 #include "jpeg.h"
00089 
00090 
00091 #undef DCTSIZE2
00092 #include "jpeg/jpeglib.h"
00093 
00094 
00095 #define HEADER_SIZE 607   
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 void
00119   JMovie2JPEG(infilename,obase,start,end)
00120 char *infilename;       
00121 char *obase;             
00122 int start;              
00123 int end;                
00124 {
00125   FILE *inFile;                 
00126   FILE *outFile;                
00127   int fd, i;                    
00128   char ofname[256];             
00129   int Temp = 0, temp = 0;       
00130   int image_offset = 0;         
00131   
00132   int ver_no;                   
00133   int fps;                      
00134   int no_frames;                
00135   int bandwidth;                
00136   int qfactor;                  
00137   int mapsize;                  
00138   int audio_tracks;             
00139   int audiosize;                
00140   int *inoffsets;               
00141   int width;                    
00142   int height;                   
00143   int size;                     
00144   char op_code;                 
00145   char jpeg_size[4];            
00146   static char junk[1000];       
00147 
00148   
00149 
00150 
00151 
00152 
00153 
00154   static char inbuffer[300000] = {    
00155     0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46,  
00156     0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
00157     0x00, 0x01, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x11,  
00158     0x08, 0x00, 0xF0, 0x01, 0x40, 0x03, 0x01, 0x21,
00159     0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xFF,  
00160     0xDB, 0x00, 0x84, 0x00, 0x10, 0x0B, 0x0C, 0x0E,
00161     0x0C, 0x0A, 0x10, 0x0E, 0x0D, 0x0E, 0x12,  
00162     0x11, 0x10, 0x13, 0x18, 0x28, 0x1A, 0x18, 0x16,
00163     0x16, 0x18, 0x31, 0x23, 0x25, 0x1D, 0x28, 0x3A,  
00164     0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38, 0x37, 0x40,
00165     0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57, 0x45, 0x37,  
00166     0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F, 0x62, 0x67,
00167     0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79, 0x70, 0x64,  
00168     0x78, 0x5C, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12,
00169     0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A, 0x1A, 0x2F,  
00170     0x63, 0x42, 0x38, 0x42, 0x63, 0x63, 0x63, 0x63,
00171     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,  
00172     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,  
00173     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,  
00174     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,  
00175     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,  
00176     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0xFF, 0xC4,
00177     0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01,  
00178     0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
00179     0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,  
00180     0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
00181     0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04,  
00182     0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01,
00183     0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05,  
00184     0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
00185     0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,  
00186     0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1,
00187     0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09,   
00188     0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26,
00189     0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37,  
00190     0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47,
00191     0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,  
00192     0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
00193     0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,  
00194     0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87,
00195     0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,  
00196     0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
00197     0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,  
00198     0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
00199     0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,  
00200     0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
00201     0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8,  
00202     0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6,
00203     0xF7, 0xF8, 0xF9, 0xFA, 0x01, 0x00, 0x03, 0x01,  
00204     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00205     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,  
00206     0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
00207     0x0A, 0x0B, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04,  
00208     0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00,
00209     0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,  
00210     0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
00211     0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08,  
00212     0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23,
00213     0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1,   
00214     0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17,
00215     0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,  
00216     0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
00217     0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,  
00218     0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
00219     0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,  
00220     0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83,
00221     0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92,  
00222     0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
00223     0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9,  
00224     0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
00225     0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,  
00226     0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
00227     0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5,  
00228     0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4,
00229     0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xDA,  
00230     0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03,
00231     0x11, 0x00, 0x3F, 0x00  
00232 
00233     };
00234     
00235   if(start > end)
00236     {
00237       fprintf(stderr,"bad frame numbers\n");
00238       exit(1);
00239     }
00240     
00241   
00242   inFile = fopen(infilename, "rb");
00243   if (inFile == NULL) 
00244     {
00245       perror (infilename);
00246       exit (1);
00247     }
00248     
00249       
00250   fd = fileno(inFile);
00251     
00252   
00253   
00254 
00255   fseek (inFile, (8*sizeof(char)),0);
00256     
00257   if (fread (&ver_no,sizeof(int),1,inFile) != 1)
00258     {
00259       perror("Error in reading version");
00260       exit(1);
00261     }  
00262   if(ver_no != 2){
00263     perror("Unrecognized version - Quantization tables may be wrong\n");
00264   }
00265   if (fread (&(fps),sizeof(int),1,inFile) != 1)
00266     {
00267       perror("Error in reading fps");
00268       exit(1);
00269     }  
00270   if (fread (&(no_frames),sizeof(int),1,inFile) != 1)
00271     {
00272       perror("Error in reading no_frames");
00273       exit(1);
00274     }  
00275 
00276   inoffsets = (int *)malloc(no_frames*sizeof(int));
00277     
00278   if (fread (&(width),sizeof(int),1,inFile) != 1)
00279     {
00280       perror("Error in reading width");
00281       exit(1);
00282     }  
00283   
00284   inbuffer[27] = (char)(0xFF & (width >> 8));
00285   inbuffer[28] = (char)(0xFF & width);
00286  
00287   if (fread (&(height),sizeof(int), 1,inFile) != 1)
00288     {
00289       perror("Error in reading height");
00290       exit(1);
00291     }  
00292   
00293   inbuffer[25] = (char)(0xFF & (height >> 8));
00294   inbuffer[26] = (char)(0xFF & height);
00295     
00296   if (fread (&(bandwidth),sizeof(int),1,inFile) != 1)
00297     {
00298       perror("Error in reading bandwidth");
00299       exit(1);
00300     }  
00301     
00302   if (fread (&(qfactor),sizeof(int),1,inFile) != 1)
00303     {
00304       perror("Error in reading qfactor");
00305       exit(1);
00306     }  
00307   
00308 
00309     
00310   
00311   if(qfactor != 100){
00312     for(Temp=44;Temp<108;Temp++){
00313       temp= (inbuffer[Temp]*qfactor)/100;
00314       inbuffer[Temp] = (char)((temp<255) ? temp : 255);
00315     }
00316     for(Temp=109;Temp<173;Temp++){
00317       temp = (inbuffer[Temp]*qfactor)/100;
00318       inbuffer[Temp] = (char)((temp<255) ? temp : 255);
00319     }    
00320   }
00321   
00322   if (fread (&(mapsize),sizeof(int),1,inFile) != 1)
00323     {
00324       perror("Error in reading mapsize");
00325       exit(1);
00326     }  
00327   if (fread (&(image_offset),sizeof(int),1,inFile) != 1)
00328     {
00329       perror("Error in reading image offset");
00330       exit(1);
00331     }
00332   if (fread (&(audio_tracks),sizeof(int),1,inFile) != 1)
00333     {
00334       perror("Error in reading audio tracks");
00335       exit(1);
00336     }
00337     
00338   fread(junk,sizeof(int),1,inFile);
00339     
00340   if (fread (&(audiosize),sizeof(int),1,inFile) != 1)
00341     {
00342       perror("Error in reading audiosize");
00343       exit(1);
00344     }
00345     
00346   fseek (inFile,(image_offset),0);
00347     
00348 
00349   if(no_frames <= end)
00350     {
00351       end = no_frames - 1;
00352     }
00353     
00354 
00355   for(i=0;i<no_frames;i++) 
00356     {
00357       fread(&(inoffsets[i]),sizeof(int),1,inFile);
00358     } 
00359     
00360   rewind(inFile);
00361 
00362       
00363   for (i=start; i<=end ; i++) 
00364     {
00365       size = inoffsets[i]- inoffsets[i-1]- 5;
00366       lseek(fd, inoffsets[i-1],0); 
00367       read(fd, &(op_code), 1);
00368       while( op_code !=  0xffffffec)
00369         {
00370           read(fd,junk,audiosize);
00371           read(fd, &(op_code), 1);  
00372           size = size - audiosize ;
00373         } 
00374       read(fd,jpeg_size,4);
00375       read(fd,&(inbuffer[607]),(size));
00376       sprintf(ofname,"%s%d.jpg",obase,i);
00377       outFile = fopen(ofname, "wb");
00378       fwrite(inbuffer,(size+607),sizeof(char),outFile);
00379       fclose(outFile);        
00380     }
00381   free(inoffsets);
00382   fclose(inFile);
00383 }
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 void
00418 ReadJPEG(mf, fp)
00419     MpegFrame *mf;
00420     FILE *fp;
00421 {
00422 
00423   
00424 
00425 
00426   static struct jpeg_decompress_struct cinfo;
00427   struct jpeg_error_mgr jerr;
00428   
00429   JSAMPARRAY scanarray[3];
00430   int ci,cd,cp;
00431   JDIMENSION ncols[3];
00432   JDIMENSION nrows[3];
00433   jpeg_component_info *compptr;
00434   int buffer_height;
00435   int current_row[3];
00436   uint8 **orig[3];
00437   int h_samp[3],v_samp[3];
00438   int max_h_samp,max_v_samp;
00439   int temp_h, temp_v;
00440   int temp;
00441 
00442   
00443    cinfo.err = jpeg_std_error(&jerr);
00444 
00445   
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453   {
00454     static int first_stdin = 1;
00455     if( (fp != stdin) || first_stdin)
00456       {
00457         first_stdin = 0;
00458         
00459         jpeg_create_decompress(&cinfo);
00460         
00461         jpeg_stdio_src(&cinfo, fp);
00462       }
00463   }
00464   
00465   
00466   
00467   jpeg_stdio_src(&cinfo, fp);
00468   
00469   
00470   
00471   
00472   (void) jpeg_read_header(&cinfo, TRUE);
00473   
00474 
00475 
00476 
00477   
00478   
00479 #ifdef JPEG4
00480   cinfo.want_raw_output = TRUE;
00481 #else
00482   cinfo.raw_data_out = TRUE;
00483 #endif
00484   cinfo.out_color_space = JCS_YCbCr;
00485   
00486   
00487   jpeg_calc_output_dimensions(&cinfo);
00488   
00489   
00490   
00491   
00492   
00493   Fsize_Note(mf->id,(int)(cinfo.image_width),(int)(cinfo.image_height));
00494   
00495   
00496   Frame_AllocYCC(mf);      
00497   
00498   
00499 
00500   orig[0] = mf->orig_y;
00501   orig[1] = mf->orig_cb;
00502   orig[2] = mf->orig_cr;
00503   
00504   
00505 
00506   
00507   
00508   
00509   jpeg_start_decompress(&cinfo);
00510   
00511   
00512   
00513   
00514   for(cp=0,compptr = cinfo.comp_info;cp<cinfo.num_components;
00515       cp++,compptr++) {
00516     h_samp[cp] = compptr->h_samp_factor;
00517     v_samp[cp] = compptr->v_samp_factor;
00518   }
00519   
00520   temp_h = (h_samp[0]<h_samp[1]) ? h_samp[1] : h_samp[0];
00521   max_h_samp = (temp_h<h_samp[2]) ? h_samp[2]:temp_h;
00522   temp_v = (v_samp[0]<v_samp[1]) ? v_samp[1] : v_samp[0];
00523   max_v_samp = (temp_v<v_samp[2]) ? v_samp[2]:temp_v;
00524   
00525   
00526 #ifdef JPEG4
00527   buffer_height = 8;  
00528 #else
00529   buffer_height = cinfo.max_v_samp_factor * cinfo.min_DCT_scaled_size;
00530 #endif
00531   
00532   for(cp=0,compptr = cinfo.comp_info;cp<cinfo.num_components;
00533       cp++,compptr++) {
00534     ncols[cp] = (JDIMENSION)((cinfo.image_width*compptr->h_samp_factor)/
00535                              max_h_samp);
00536     
00537     nrows[cp] = (JDIMENSION)((buffer_height*compptr->v_samp_factor)/
00538                              max_v_samp);
00539     
00540     scanarray[cp] = (*cinfo.mem->alloc_sarray)
00541       ((j_common_ptr) &cinfo, JPOOL_IMAGE, ncols[cp], nrows[cp]);
00542     
00543   }
00544   
00545   
00546   
00547   
00548   
00549   
00550 
00551 
00552 
00553   while (cinfo.output_scanline < cinfo.output_height) {
00554 
00555 #ifdef JPEG4
00556     (void) jpeg_read_raw_scanlines(&cinfo, scanarray, buffer_height);
00557 #else
00558     (void) jpeg_read_raw_data(&cinfo, scanarray, buffer_height);
00559 #endif
00560 
00561 
00562     if((h_samp[0]==2)&&(h_samp[1]==1)&&(h_samp[2]==1)&&
00563        (v_samp[0]==2)&&(v_samp[1]==1)&&(v_samp[2]==1)){
00564       
00565     }else if((h_samp[0]==2)&&(h_samp[1]==1)&&(h_samp[2]==1)&&
00566              (v_samp[0]==1)&&(v_samp[1]==1)&&(v_samp[2]==1)){
00567       
00568       for(ci=1; ci<3; ci++){
00569         for(cp=0; cp<(buffer_height/2);cp=cp+1){
00570           for(cd=0;cd<ncols[ci];cd++){
00571             temp =((scanarray[ci][cp*2][cd]+scanarray[ci][(cp*2)+1][cd])/2);
00572             scanarray[ci][cp][cd] = (JSAMPLE)(temp);
00573           }
00574         }
00575       }
00576       
00577       if(cinfo.output_scanline==buffer_height){
00578         nrows[1] = nrows[1]/2;
00579         nrows[2] = nrows[2]/2;
00580         max_v_samp = 2;
00581         v_samp[0] = 2;
00582       }
00583     }else{
00584       fprintf(stderr, "Not a supported subsampling ratio\n");
00585       exit(1);
00586     }
00587     
00588     
00589     
00590     for(ci=0,compptr=cinfo.comp_info;ci<cinfo.num_components;
00591         ci++,compptr++){
00592       current_row[ci] =((cinfo.output_scanline - buffer_height)*
00593                         (v_samp[ci])/max_v_samp);  
00594       
00595       jcopy_sample_rows(scanarray[ci],0,(JSAMPARRAY)(orig[ci]),
00596                         current_row[ci],nrows[ci],ncols[ci]);
00597     }
00598     
00599   }  
00600   
00601   
00602   
00603   (void) jpeg_finish_decompress(&cinfo);
00604   
00605 
00606 
00607   
00608   
00609   
00610   
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618   if( fp == stdin) {
00619     static int no_from_stdin = 0;
00620     no_from_stdin++;
00621     
00622   }
00623   else {
00624     
00625     jpeg_destroy_decompress(&cinfo);
00626   }
00627 
00628   
00629 
00630 
00631 
00632 
00633   
00634   
00635   
00636 
00637 
00638 
00639 
00640 
00641   
00642   
00643 }
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673