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