]> Creatis software - gdcm.git/blob - src/gdcmMpeg.cxx
ENH: gdcm can now read and extract MPEG file
[gdcm.git] / src / gdcmMpeg.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmMpeg.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/10/27 19:05:36 $
7   Version:   $Revision: 1.6 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 #include "gdcmDebug.h"
19
20 #include <fstream>
21
22
23 typedef struct
24 {
25   std::ifstream InFd;
26 } istream;
27 extern "C" {
28 #define GLOBAL
29 #include "config.h"
30 #include "global.h"
31 }
32
33
34 off_t my_seek(istream *infile, off_t offset, int whence)
35 {
36   //return fseek(infile->InFd,offset, whence);
37   switch(whence)
38     {
39     case SEEK_SET:
40       infile->InFd.seekg(offset, std::ios::beg);
41       break;
42     case SEEK_END:
43       infile->InFd.seekg(offset, std::ios::end);
44       break;
45     case SEEK_CUR:
46       infile->InFd.seekg(offset, std::ios::cur);
47       break;
48     }
49   return infile->InFd.tellg();
50 }
51 ssize_t my_read(istream *infile, void *buf, size_t count)
52 {
53   //return fread(buf,1,count, infile->InFd);
54   infile->InFd.read((char*)buf, count);
55   return infile->InFd.gcount();
56 }
57
58 int my_close(istream *infile)
59 {
60   //return fclose(infile->InFd);
61   infile->InFd.close();
62   return 0;
63 }
64
65 namespace gdcm 
66 {
67 /**
68  * \brief   routine for MPEG decompression 
69  * @param fp pointer to an already open file descriptor 
70  *                      8 significant bits per pixel
71  * @param image_buffer to receive uncompressed pixels
72  * @param length length
73  * @return 1 on success, 0 on error
74  */
75 static int Headers();
76 static void DeInitialize_Decoder()
77 {
78   free(Clip-384); /* I love magic number */
79 }
80 static void Deinitialize_Sequence()
81 {
82   int i;
83
84   /* First cleanup the static buffer in store.c */
85   FreeStaticBuffer();
86
87   /* clear flags */
88   base.MPEG2_Flag=0;
89
90   for(i=0;i<3;i++)
91   {
92     free(backward_reference_frame[i]);
93     free(forward_reference_frame[i]);
94     free(auxframe[i]);
95
96     if (base.scalable_mode==SC_SPAT)
97     {
98      free(llframe0[i]);
99      free(llframe1[i]);
100     }
101   }
102
103   if (base.scalable_mode==SC_SPAT)
104     free(lltmp);
105
106 #ifdef DISPLAY
107   if (Output_Type==T_X11) 
108     Terminate_Display_Process();
109 #endif
110 }
111
112 /* mostly IMPLEMENTAION specific routines */
113 static void Initialize_Sequence()
114 {
115   int cc, size;
116   static int Table_6_20[3] = {6,8,12};
117
118   /* check scalability mode of enhancement layer */
119   if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
120     Error("unsupported scalability mode\n");
121
122   /* force MPEG-1 parameters for proper decoder behavior */
123   /* see ISO/IEC 13818-2 section D.9.14 */
124   if (!base.MPEG2_Flag)
125   {
126     progressive_sequence = 1;
127     progressive_frame = 1;
128     picture_structure = FRAME_PICTURE;
129     frame_pred_frame_dct = 1;
130     chroma_format = CHROMA420;
131     matrix_coefficients = 5;
132   }
133
134   /* round to nearest multiple of coded macroblocks */
135   /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
136   mb_width = (horizontal_size+15)/16;
137   mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
138                                         : (vertical_size+15)/16;
139
140   Coded_Picture_Width = 16*mb_width;
141   Coded_Picture_Height = 16*mb_height;
142
143   /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
144   Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
145                                            : Coded_Picture_Width>>1;
146   Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
147                                             : Coded_Picture_Height>>1;
148   
149   /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
150   block_count = Table_6_20[chroma_format-1];
151
152   for (cc=0; cc<3; cc++)
153   {
154     if (cc==0)
155       size = Coded_Picture_Width*Coded_Picture_Height;
156     else
157       size = Chroma_Width*Chroma_Height;
158
159     if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
160       Error("backward_reference_frame[] malloc failed\n");
161
162     if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
163       Error("forward_reference_frame[] malloc failed\n");
164
165     if (!(auxframe[cc] = (unsigned char *)malloc(size)))
166       Error("auxframe[] malloc failed\n");
167
168     if(Ersatz_Flag)
169       if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
170         Error("substitute_frame[] malloc failed\n");
171
172
173     if (base.scalable_mode==SC_SPAT)
174     {
175       /* this assumes lower layer is 4:2:0 */
176       if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
177         Error("llframe0 malloc failed\n");
178       if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
179         Error("llframe1 malloc failed\n");
180     }
181   }
182
183   /* SCALABILITY: Spatial */
184   if (base.scalable_mode==SC_SPAT)
185   {
186     if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
187       Error("lltmp malloc failed\n");
188   }
189
190 #ifdef DISPLAY
191   if (Output_Type==T_X11)
192   {
193     Initialize_Display_Process("");
194     Initialize_Dither_Matrix();
195   }
196 #endif /* DISPLAY */
197
198 }
199 static int video_sequence(int *Bitstream_Framenumber)
200 //int *Bitstream_Framenumber;
201 {
202   int Bitstream_Framenum;
203   int Sequence_Framenum;
204   int Return_Value;
205
206   Bitstream_Framenum = *Bitstream_Framenumber;
207   Sequence_Framenum=0;
208
209   Initialize_Sequence();
210
211   /* decode picture whose header has already been parsed in 
212      Decode_Bitstream() */
213
214
215   Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
216
217   /* update picture numbers */
218   if (!Second_Field)
219   {
220     Bitstream_Framenum++;
221     Sequence_Framenum++;
222   }
223
224   /* loop through the rest of the pictures in the sequence */
225   while ((Return_Value=Headers()))
226   {
227     Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
228
229     if (!Second_Field)
230     {
231       Bitstream_Framenum++;
232       Sequence_Framenum++;
233     }
234   }
235
236   /* put last frame */
237   if (Sequence_Framenum!=0)
238   {
239     Output_Last_Frame_of_Sequence(Bitstream_Framenum);
240   }
241
242   Deinitialize_Sequence();
243
244 #ifdef VERIFY
245     Clear_Verify_Headers();
246 #endif /* VERIFY */
247
248   *Bitstream_Framenumber = Bitstream_Framenum;
249   return(Return_Value);
250 }
251
252 static int Headers()
253 {
254   int ret;
255
256   ld = &base;
257   
258
259   /* return when end of sequence (0) or picture
260      header has been parsed (1) */
261
262   ret = Get_Hdr();
263
264
265   if (Two_Streams)
266   {
267     ld = &enhan;
268     if (Get_Hdr()!=ret && !Quiet_Flag)
269       fprintf(stderr,"streams out of sync\n");
270     ld = &base;
271   }
272
273   return ret;
274 }
275 static int Decode_Bitstream()
276 {
277   int ret;
278   int Bitstream_Framenum;
279
280   Bitstream_Framenum = 0;
281
282   for(;;)
283   {
284
285 #ifdef VERIFY
286     Clear_Verify_Headers();
287 #endif /* VERIFY */
288
289     ret = Headers();
290     
291     if(ret==1)
292     {
293       ret = video_sequence(&Bitstream_Framenum);
294     }
295     else
296       return(ret);
297   }
298
299 }
300
301
302 /* IMPLEMENTATION specific routines */
303 static void Initialize_Decoder()
304 {
305   int i;
306
307   /* Clip table */
308   if (!(Clip=(unsigned char *)malloc(1024)))
309     Error("Clip[] malloc failed\n");
310
311   Clip += 384;
312
313   for (i=-384; i<640; i++)
314     Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
315
316   /* IDCT */
317   if (Reference_IDCT_Flag)
318     Initialize_Reference_IDCT();
319   else
320     Initialize_Fast_IDCT();
321
322 }
323
324 /* option processing */
325 static void Process_Options(int argc, const char *argv[])
326 //int argc;                  /* argument count  */
327 //char *argv[];              /* argument vector */
328 {
329   int i, LastArg, NextArg;
330
331   /* at least one argument should be present */
332   if (argc<2)
333   {
334     printf("\n%s, %s\n",Version,Author);
335     printf("Usage:  mpeg2decode {options}\n"
336 "Options: -b  file  main bitstream (base or spatial enhancement layer)\n"
337 "         -cn file  conformance report (n: level)\n"
338 "         -e  file  enhancement layer bitstream (SNR or Data Partitioning)\n"
339 "         -f        store/display interlaced video in frame format\n"
340 "         -g        concatenated file format for substitution method (-x)\n"
341 "         -in file  information & statistics report  (n: level)\n"
342 "         -l  file  file name pattern for lower layer sequence\n");
343 printf("                   (for spatial scalability)\n"
344 "         -on file  output format (0:YUV 1:SIF 2:TGA 3:PPM 4:X11 5:X11HiQ)\n"
345 "         -q        disable warnings to stderr\n"
346 "         -r        use double precision reference IDCT\n"
347 "         -t        enable low level tracing to stdout\n"
348 "         -u  file  print user_data to stdio or file\n"
349 "         -vn       verbose output (n: level)\n"
350 "         -x  file  filename pattern of picture substitution sequence\n\n");
351 printf("File patterns:  for sequential filenames, \"printf\" style, e.g. rec%%d\n"
352 "                 or rec%%d%%c for fieldwise storage\n"
353 "Levels:        0:none 1:sequence 2:picture 3:slice 4:macroblock 5:block\n\n"
354 "Example:       mpeg2decode -b bitstream.mpg -f -r -o0 rec%%d\n"
355 "         \n");
356     exit(0);
357   }
358
359
360   Output_Type = -1;
361   i = 1;
362
363   /* command-line options are proceeded by '-' */
364
365   while(i < argc)
366   {
367     /* check if this is the last argument */
368     LastArg = ((argc-i)==1);
369
370     /* parse ahead to see if another flag immediately follows current
371        argument (this is used to tell if a filename is missing) */
372     if(!LastArg)
373       NextArg = (argv[i+1][0]=='-');
374     else
375       NextArg = 0;
376
377     /* second character, [1], after '-' is the switch */
378     if(argv[i][0]=='-')
379     {
380       switch(toupper(argv[i][1]))
381       {
382         /* third character. [2], is the value */
383       case 'B':
384         Main_Bitstream_Flag = 1;
385
386         if(NextArg || LastArg)
387         {
388           printf("ERROR: -b must be followed the main bitstream filename\n");
389         }
390         else
391           Main_Bitstream_Filename = argv[++i]; 
392
393         break;
394
395
396       case 'C':
397
398 #ifdef VERIFY
399         Verify_Flag = atoi(&argv[i][2]); 
400
401         if((Verify_Flag < NO_LAYER) || (Verify_Flag > ALL_LAYERS))
402         {
403           printf("ERROR: -c level (%d) out of range [%d,%d]\n",
404             Verify_Flag, NO_LAYER, ALL_LAYERS);
405           exit(ERROR);
406         }
407 #else  /* VERIFY */
408         printf("This program not compiled for Verify_Flag option\n");
409 #endif /* VERIFY */
410         break;
411
412       case 'E':
413         Two_Streams = 1; /* either Data Partitioning (DP) or SNR Scalability enhancment */
414                    
415         if(NextArg || LastArg)
416         {
417           printf("ERROR: -e must be followed by filename\n");
418           exit(ERROR);
419         }
420         else
421           Enhancement_Layer_Bitstream_Filename = argv[++i]; 
422
423         break;
424
425
426       case 'F':
427         Frame_Store_Flag = 1;
428         break;
429
430       case 'G':
431         Big_Picture_Flag = 1;
432         break;
433
434
435       case 'I':
436 #ifdef VERIFY
437         Stats_Flag = atoi(&argv[i][2]); 
438 #else /* VERIFY */
439         printf("WARNING: This program not compiled for -i option\n");
440 #endif /* VERIFY */     
441         break;
442     
443       case 'L':  /* spatial scalability flag */
444         Spatial_Flag = 1;
445
446        if(NextArg || LastArg)
447        {
448          printf("ERROR: -l must be followed by filename\n");
449          exit(ERROR);
450        }
451        else
452          Lower_Layer_Picture_Filename = argv[++i]; 
453
454         break;
455
456       case 'O':
457   
458         Output_Type = atoi(&argv[i][2]); 
459   
460         if((Output_Type==4) || (Output_Type==5))
461           Output_Picture_Filename = "";  /* no need of filename */
462         else if(NextArg || LastArg)  
463         {
464           printf("ERROR: -o must be followed by filename\n");
465           exit(ERROR);
466         }
467         else
468         /* filename is separated by space, so it becomes the next argument */
469           Output_Picture_Filename = argv[++i]; 
470
471 #ifdef DISPLAY
472         if (Output_Type==T_X11HIQ)
473         {
474           hiQdither = 1;
475           Output_Type=T_X11;
476         }
477 #endif /* DISPLAY */
478         break;
479
480       case 'Q':
481         Quiet_Flag = 1;
482         break;
483
484       case 'R':
485         Reference_IDCT_Flag = 1;
486         break;
487     
488       case 'T':
489 #ifdef TRACE
490         Trace_Flag = 1;
491 #else /* TRACE */
492         printf("WARNING: This program not compiled for -t option\n");
493 #endif /* TRACE */
494         break;
495
496       case 'U':
497         User_Data_Flag = 1;
498
499       case 'V':
500 #ifdef VERBOSE
501         Verbose_Flag = atoi(&argv[i][2]); 
502 #else /* VERBOSE */
503         printf("This program not compiled for -v option\n");
504 #endif /* VERBOSE */
505         break;
506
507
508       case 'X':
509         Ersatz_Flag = 1;
510
511        if(NextArg || LastArg)
512        {
513          printf("ERROR: -x must be followed by filename\n"); 
514          exit(ERROR);
515        }
516        else
517         Substitute_Picture_Filename = argv[++i]; 
518
519         break;
520
521
522
523       default:
524         fprintf(stderr,"undefined option -%c ignored. Exiting program\n", 
525           argv[i][1]);
526
527         exit(ERROR);
528     
529       } /* switch() */
530     } /* if argv[i][0] == '-' */
531     
532     i++;
533
534     /* check for bitstream filename argument (there must always be one, at the very end
535      of the command line arguments */
536
537   } /* while() */
538
539
540   /* options sense checking */
541
542   if(Main_Bitstream_Flag!=1)
543   {
544     printf("There must be a main bitstream specified (-b filename)\n");
545   }
546
547   /* force display process to show frame pictures */
548   if((Output_Type==4 || Output_Type==5) && Frame_Store_Flag)
549     Display_Progressive_Flag = 1;
550   else
551     Display_Progressive_Flag = 0;
552
553 #ifdef VERIFY
554   /* parse the bitstream, do not actually decode it completely */
555   
556
557 #if 0
558   if(Output_Type==-1)
559   {
560     Decode_Layer = Verify_Flag;
561     printf("FYI: Decoding bitstream elements up to: %s\n", 
562       Layer_Table[Decode_Layer]);
563   }
564   else
565 #endif
566     Decode_Layer = ALL_LAYERS;
567
568 #endif /* VERIFY */
569
570   /* no output type specified */
571   if(Output_Type==-1)
572   {
573     Output_Type = 9; 
574     Output_Picture_Filename = "";
575   }
576
577
578 #ifdef DISPLAY
579   if (Output_Type==T_X11)
580   {
581     if(Frame_Store_Flag)
582       Display_Progressive_Flag = 1;
583     else
584       Display_Progressive_Flag = 0;
585
586     Frame_Store_Flag = 1; /* to avoid calling dither() twice */
587   }
588 #endif
589
590
591 }
592
593 static void Clear_Options()
594 {
595   Verbose_Flag = 0;
596   Output_Type = 0;
597   Output_Picture_Filename = " ";
598   hiQdither  = 0;
599   Output_Type = 0;
600   Frame_Store_Flag = 0;
601   Spatial_Flag = 0;
602   Lower_Layer_Picture_Filename = " ";
603   Reference_IDCT_Flag = 0;
604   Trace_Flag = 0;
605   Quiet_Flag = 0;
606   Ersatz_Flag = 0;
607   Substitute_Picture_Filename  = " ";
608   Two_Streams = 0;
609   Enhancement_Layer_Bitstream_Filename = " ";
610   Big_Picture_Flag = 0;
611   Main_Bitstream_Flag = 0;
612   Main_Bitstream_Filename = " ";
613   Verify_Flag = 0;
614   Stats_Flag  = 0;
615   User_Data_Flag = 0; 
616 }
617 static void Print_Options()
618 {
619   
620   printf("Verbose_Flag                         = %d\n", Verbose_Flag);
621   printf("Output_Type                          = %d\n", Output_Type);
622   printf("Output_Picture_Filename              = %s\n", Output_Picture_Filename);
623   printf("hiQdither                            = %d\n", hiQdither);
624   printf("Output_Type                          = %d\n", Output_Type);
625   printf("Frame_Store_Flag                     = %d\n", Frame_Store_Flag);
626   printf("Spatial_Flag                         = %d\n", Spatial_Flag);
627   printf("Lower_Layer_Picture_Filename         = %s\n", Lower_Layer_Picture_Filename);
628   printf("Reference_IDCT_Flag                  = %d\n", Reference_IDCT_Flag);
629   printf("Trace_Flag                           = %d\n", Trace_Flag);
630   printf("Quiet_Flag                           = %d\n", Quiet_Flag);
631   printf("Ersatz_Flag                          = %d\n", Ersatz_Flag);
632   printf("Substitute_Picture_Filename          = %s\n", Substitute_Picture_Filename);
633   printf("Two_Streams                          = %d\n", Two_Streams);
634   printf("Enhancement_Layer_Bitstream_Filename = %s\n", Enhancement_Layer_Bitstream_Filename);
635   printf("Big_Picture_Flag                     = %d\n", Big_Picture_Flag);
636   printf("Main_Bitstream_Flag                  = %d\n", Main_Bitstream_Flag);
637   printf("Main_Bitstream_Filename              = %s\n", Main_Bitstream_Filename);
638   printf("Verify_Flag                          = %d\n", Verify_Flag);
639   printf("Stats_Flag                           = %d\n", Stats_Flag);
640   printf("User_Data_Flag                       = %d\n", User_Data_Flag);
641
642 }
643
644 bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t length)
645 {
646 #if 1
647   fp->read((char*)image_buffer, length);
648   std::ofstream out("/tmp/etiam.mpeg");
649   out.write((char*)image_buffer, length);
650   out.close();
651 #endif
652
653   int ret, code;
654   istream bos,eos;
655   /*base.open_stream = my_open;*/
656   base.seek_stream = my_seek;
657   base.read_stream = my_read;
658   base.close_stream = my_close;
659
660 //  Clear_Options();
661 //  int argc = 7;
662 //  const char *argv[] = {"mpeg2decode", "-b", "/tmp/etiam.mpeg", "-f", "-r", "-o3", "/tmp/rec%d"};
663 //
664 //  /* decode command line arguments */
665 //  Process_Options(argc,argv);
666 //  Print_Options();
667  
668   Verbose_Flag                         = 0;
669   Output_Type                          = 3;
670   Output_Picture_Filename              = "/tmp/rec%d";
671   hiQdither                            = 0;
672   Output_Type                          = 3;
673   Frame_Store_Flag                     = 1;
674   Spatial_Flag                         = 0;
675   Lower_Layer_Picture_Filename         = "";
676   Reference_IDCT_Flag                  = 1;
677   Trace_Flag                           = 0;
678   Quiet_Flag                           = 0;
679   Ersatz_Flag                          = 0;
680   Substitute_Picture_Filename          = "";
681   Two_Streams                          = 0;
682   Enhancement_Layer_Bitstream_Filename = "";
683   Big_Picture_Flag                     = 0;
684   Main_Bitstream_Flag                  = 1;
685   Main_Bitstream_Filename              = "/tmp/etiam.mpeg";
686   Verify_Flag                          = 0;
687   Stats_Flag                           = 0;
688   User_Data_Flag                       = 0;
689
690
691   ld = &base; /* select base layer context */
692
693   /* open MPEG base layer bitstream file(s) */
694   /* NOTE: this is either a base layer stream or a spatial enhancement stream */
695 /*  if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) */
696   /*base.Infile = ld->open_stream(Main_Bitstream_Filename);*/
697   base.Infile = &bos;
698 #ifdef FILESTAR
699   //base.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
700   base.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary | std::ios::in);
701 #else
702   base.Infile->InFd = open(Main_Bitstream_Filename,O_RDONLY|O_BINARY );
703 #endif
704   if( !base.Infile->InFd)
705   {
706     fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
707     exit(1);
708   }
709
710
711   if(base.Infile != 0)
712   {
713     Initialize_Buffer();
714
715     if(Show_Bits(8)==0x47)
716     {
717       sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
718       Error(Error_Text);
719     }
720
721     next_start_code();
722     code = Show_Bits(32);
723
724     switch(code)
725     {
726     case SEQUENCE_HEADER_CODE:
727       break;
728     case PACK_START_CODE:
729       System_Stream_Flag = 1;
730     case VIDEO_ELEMENTARY_STREAM:
731       System_Stream_Flag = 1;
732       break;
733     default:
734       sprintf(Error_Text,"Unable to recognize stream type\n");
735       Error(Error_Text);
736       break;
737     }
738
739     /*lseek(base.Infile, 0l, SEEK_SET);*/
740     ld->seek_stream(base.Infile,0l,SEEK_SET);
741     Initialize_Buffer(); 
742   }
743
744   if(base.Infile!=0)
745   {
746     /*lseek(base.Infile, 0l, SEEK_SET);*/
747     ld->seek_stream(base.Infile,0l,SEEK_SET);
748   }
749
750   Initialize_Buffer(); 
751
752   if(Two_Streams)
753   {
754     ld = &enhan; /* select enhancement layer context */
755
756     /*if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)*/
757     /*enhan.Infile = ld->open_stream(Enhancement_Layer_Bitstream_Filename);*/
758     enhan.Infile = &eos;
759 #ifdef FILESTAR
760     //enhan.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
761     enhan.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary|std::ios::in);
762 #else
763     enhan.Infile->InFd = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY);
764 #endif
765     if (enhan.Infile->InFd)
766     {
767       sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
768         Enhancement_Layer_Bitstream_Filename);
769
770       Error(Error_Text);
771     }
772
773     Initialize_Buffer();
774     ld = &base;
775   }
776
777   Initialize_Decoder();
778
779   ret = Decode_Bitstream();
780
781   /*close(base.Infile);*/
782   ld->close_stream(base.Infile);
783
784   if (Two_Streams)
785     /*close(enhan.Infile);*/
786     ld->close_stream(enhan.Infile);
787
788   DeInitialize_Decoder();
789
790   return ret;
791 }
792
793 } // end namespace gdcm