X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmMpeg.cxx;h=fc31f6e4a783319ec53915be6888ab4833ac5fb0;hb=224876ca6cbe71952f2a1d66d9853eca7745d3a0;hp=4eee68ae03ebe35467be2456f9056eadcd4b36ba;hpb=33e0626ee829c06cee6f6dda37f7f720c6c9b311;p=gdcm.git diff --git a/src/gdcmMpeg.cxx b/src/gdcmMpeg.cxx index 4eee68ae..fc31f6e4 100644 --- a/src/gdcmMpeg.cxx +++ b/src/gdcmMpeg.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmMpeg.cxx,v $ Language: C++ - Date: $Date: 2005/10/27 20:08:29 $ - Version: $Revision: 1.8 $ + Date: $Date: 2007/09/17 12:20:01 $ + Version: $Revision: 1.14 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -18,110 +18,62 @@ #include "gdcmDebug.h" #include - - -typedef struct -{ - std::ifstream *InFd; -} istream; +#include +#include +#include +#include extern "C" { #define GLOBAL #include "config.h" #include "global.h" -} +/* private prototypes */ +static int video_sequence _ANSI_ARGS_((int *framenum)); +static int Decode_Bitstream _ANSI_ARGS_((void)); +static int Headers _ANSI_ARGS_((void)); +static void Initialize_Sequence _ANSI_ARGS_((void)); +static void Initialize_Decoder _ANSI_ARGS_((void)); +static void Deinitialize_Sequence _ANSI_ARGS_((void)); +//static void Process_Options _ANSI_ARGS_((int argc, char *argv[])); -off_t my_seek(istream *infile, off_t offset, int whence) -{ - //return fseek(infile->InFd,offset, whence); - switch(whence) - { - case SEEK_SET: - infile->InFd->seekg(offset, std::ios::beg); - break; - case SEEK_END: - infile->InFd->seekg(offset, std::ios::end); - break; - case SEEK_CUR: - infile->InFd->seekg(offset, std::ios::cur); - break; - } - return infile->InFd->tellg(); -} -ssize_t my_read(istream *infile, void *buf, size_t count) -{ - //return fread(buf,1,count, infile->InFd); - infile->InFd->read((char*)buf, count); - return infile->InFd->gcount(); -} - -int my_close(istream *infile) -{ - //return fclose(infile->InFd); - infile->InFd->close(); - return 0; -} - -namespace gdcm -{ -/** - * \brief routine for MPEG decompression - * @param fp pointer to an already open file descriptor - * 8 significant bits per pixel - * @param image_buffer to receive uncompressed pixels - * @param length length - * @return 1 on success, 0 on error - */ -static int Headers(); -static void DeInitialize_Decoder() -{ - free(Clip-384); /* I love magic number */ -} -static void Deinitialize_Sequence() +/* IMPLEMENTATION specific routines */ +static void Initialize_Decoder() { int i; - /* First cleanup the static buffer in store.c */ - FreeStaticBuffer(); - - /* clear flags */ - base.MPEG2_Flag=0; + /* Clip table */ + if ( !(Clip=(unsigned char *)malloc(1024)) ) + Error("Clip[] malloc failed\n"); - for(i=0;i<3;i++) - { - free(backward_reference_frame[i]); - free(forward_reference_frame[i]); - free(auxframe[i]); + Clip += 384; - if (base.scalable_mode==SC_SPAT) - { - free(llframe0[i]); - free(llframe1[i]); - } - } + for (i=-384; i<640; i++) + Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i); - if (base.scalable_mode==SC_SPAT) - free(lltmp); + /* IDCT */ + if ( Reference_IDCT_Flag ) + Initialize_Reference_IDCT(); + else + Initialize_Fast_IDCT(); -#ifdef DISPLAY - if (Output_Type==T_X11) - Terminate_Display_Process(); -#endif } -/* mostly IMPLEMENTAION specific routines */ +/* mostly IMPLEMENTATION specific routines */ static void Initialize_Sequence() { int cc, size; static int Table_6_20[3] = {6,8,12}; /* check scalability mode of enhancement layer */ - if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP)) - Error("unsupported scalability mode\n"); - + if ( Two_Streams && (enhan.scalable_mode!=SC_SNR) + && + (base.scalable_mode!=SC_DP) ) + { + Error("unsupported scalability mode\n"); + } /* force MPEG-1 parameters for proper decoder behavior */ /* see ISO/IEC 13818-2 section D.9.14 */ - if (!base.MPEG2_Flag) + if ( !base.MPEG2_Flag ) { progressive_sequence = 1; progressive_frame = 1; @@ -151,39 +103,39 @@ static void Initialize_Sequence() for (cc=0; cc<3; cc++) { - if (cc==0) + if ( cc==0 ) size = Coded_Picture_Width*Coded_Picture_Height; else size = Chroma_Width*Chroma_Height; - if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size))) + if ( !(backward_reference_frame[cc] = (unsigned char *)malloc(size)) ) Error("backward_reference_frame[] malloc failed\n"); - if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size))) + if ( !(forward_reference_frame[cc] = (unsigned char *)malloc(size)) ) Error("forward_reference_frame[] malloc failed\n"); - if (!(auxframe[cc] = (unsigned char *)malloc(size))) + if ( !(auxframe[cc] = (unsigned char *)malloc(size)) ) Error("auxframe[] malloc failed\n"); - if(Ersatz_Flag) - if (!(substitute_frame[cc] = (unsigned char *)malloc(size))) + if ( Ersatz_Flag ) + if ( !(substitute_frame[cc] = (unsigned char *)malloc(size)) ) Error("substitute_frame[] malloc failed\n"); - if (base.scalable_mode==SC_SPAT) + if ( base.scalable_mode==SC_SPAT ) { /* this assumes lower layer is 4:2:0 */ - if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) + if ( !(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) Error("llframe0 malloc failed\n"); - if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) + if ( !(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) Error("llframe1 malloc failed\n"); } } /* SCALABILITY: Spatial */ - if (base.scalable_mode==SC_SPAT) + if ( base.scalable_mode==SC_SPAT ) { - if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short)))) + if ( !(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short)))) Error("lltmp malloc failed\n"); } @@ -196,57 +148,19 @@ static void Initialize_Sequence() #endif /* DISPLAY */ } -static int video_sequence(int *Bitstream_Framenumber) -//int *Bitstream_Framenumber; -{ - int Bitstream_Framenum; - int Sequence_Framenum; - int Return_Value; - Bitstream_Framenum = *Bitstream_Framenumber; - Sequence_Framenum=0; - - Initialize_Sequence(); - - /* decode picture whose header has already been parsed in - Decode_Bitstream() */ - - - Decode_Picture(Bitstream_Framenum, Sequence_Framenum); - - /* update picture numbers */ - if (!Second_Field) - { - Bitstream_Framenum++; - Sequence_Framenum++; - } - - /* loop through the rest of the pictures in the sequence */ - while ((Return_Value=Headers())) - { - Decode_Picture(Bitstream_Framenum, Sequence_Framenum); - - if (!Second_Field) - { - Bitstream_Framenum++; - Sequence_Framenum++; - } - } - - /* put last frame */ - if (Sequence_Framenum!=0) - { - Output_Last_Frame_of_Sequence(Bitstream_Framenum); - } - - Deinitialize_Sequence(); - -#ifdef VERIFY - Clear_Verify_Headers(); -#endif /* VERIFY */ +extern void Error(char *text) +{ + fprintf(stderr,text); + exit(1); +} - *Bitstream_Framenumber = Bitstream_Framenum; - return(Return_Value); +/* Trace_Flag output */ +void Print_Bits(int code, int bits, int len) +{ + int i; + for (i=0; i>(bits-1-i))&1); } static int Headers() @@ -254,8 +168,7 @@ static int Headers() int ret; ld = &base; - - + /* return when end of sequence (0) or picture header has been parsed (1) */ @@ -272,6 +185,9 @@ static int Headers() return ret; } + + + static int Decode_Bitstream() { int ret; @@ -288,7 +204,7 @@ static int Decode_Bitstream() ret = Headers(); - if(ret==1) + if ( ret==1 ) { ret = video_sequence(&Bitstream_Framenum); } @@ -299,95 +215,138 @@ static int Decode_Bitstream() } -/* IMPLEMENTATION specific routines */ -static void Initialize_Decoder() +static void Deinitialize_Sequence() { int i; - /* Clip table */ - if (!(Clip=(unsigned char *)malloc(1024))) - Error("Clip[] malloc failed\n"); + /* clear flags */ + base.MPEG2_Flag=0; - Clip += 384; + for(i=0;i<3;i++) + { + free(backward_reference_frame[i]); + free(forward_reference_frame[i]); + free(auxframe[i]); - for (i=-384; i<640; i++) - Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i); + if ( base.scalable_mode==SC_SPAT ) + { + free(llframe0[i]); + free(llframe1[i]); + } + } - /* IDCT */ - if (Reference_IDCT_Flag) - Initialize_Reference_IDCT(); - else - Initialize_Fast_IDCT(); + if ( base.scalable_mode==SC_SPAT ) + free(lltmp); +#ifdef DISPLAY + if ( Output_Type==T_X11 ) + Terminate_Display_Process(); +#endif } -bool ReadMPEGFile (std::ifstream *fp, char *image_buffer, size_t length) +static int video_sequence(int *Bitstream_Framenumber) { - std::streampos mpeg_start = fp->tellg(); // the MPEG stream in our case does not start at 0 + int Bitstream_Framenum; + int Sequence_Framenum; + int Return_Value; + + Bitstream_Framenum = *Bitstream_Framenumber; + Sequence_Framenum=0; + + Initialize_Sequence(); + + /* decode picture whose header has already been parsed in + Decode_Bitstream() */ + + + Decode_Picture(Bitstream_Framenum, Sequence_Framenum); + + /* update picture numbers */ + if ( !Second_Field ) + { + Bitstream_Framenum++; + Sequence_Framenum++; + } + + /* loop through the rest of the pictures in the sequence */ + while ((Return_Value=Headers())) + { + Decode_Picture(Bitstream_Framenum, Sequence_Framenum); + + if ( !Second_Field ) + { + Bitstream_Framenum++; + Sequence_Framenum++; + } + } + + /* put last frame */ + if (Sequence_Framenum!=0) + { + Output_Last_Frame_of_Sequence(Bitstream_Framenum); + } + + Deinitialize_Sequence(); + +#ifdef VERIFY + Clear_Verify_Headers(); +#endif /* VERIFY */ + + *Bitstream_Framenumber = Bitstream_Framenum; + return(Return_Value); +} +} // End "C" extern + +namespace GDCM_NAME_SPACE +{ +/** + * \brief routine for MPEG decompression + * @param fp pointer to an already open file descriptor + * 8 significant bits per pixel + * @param image_buffer to receive uncompressed pixels + * @param length length + * @return 1 on success, 0 on error + */ +bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t length) +{ + int ret, code; + #if 0 fp->read((char*)image_buffer, length); - std::ofstream out("/tmp/etiam.mpeg"); + ofstream out("/tmp/etiam.mpeg"); out.write((char*)image_buffer, length); out.close(); #endif - int ret, code; - istream bos,eos; - /*base.open_stream = my_open;*/ - base.seek_stream = my_seek; - base.read_stream = my_read; - base.close_stream = my_close; - - Verbose_Flag = 0; - Output_Type = T_MEM; //store in mem - Output_Picture_Filename = "/tmp/rec%d"; - hiQdither = 0; - Frame_Store_Flag = 1; - Spatial_Flag = 0; - Lower_Layer_Picture_Filename = ""; - Reference_IDCT_Flag = 1; - Trace_Flag = 0; - Quiet_Flag = 0; - Ersatz_Flag = 0; - Substitute_Picture_Filename = ""; - Two_Streams = 0; - Enhancement_Layer_Bitstream_Filename = ""; - Big_Picture_Flag = 0; - Main_Bitstream_Flag = 1; - Main_Bitstream_Filename = "/tmp/etiam.mpeg"; - Main_Bitstream_Filename = "/tmp/ts.mpg"; - Verify_Flag = 0; - Stats_Flag = 0; - User_Data_Flag = 0; - OUTMEM = (char*)image_buffer; +// Clear_Options(); + + /* decode command line arguments */ +// Process_Options(argc,argv); +#ifdef DEBUG + Print_Options(); +#endif ld = &base; /* select base layer context */ /* open MPEG base layer bitstream file(s) */ /* NOTE: this is either a base layer stream or a spatial enhancement stream */ -/* if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) */ - /*base.Infile = ld->open_stream(Main_Bitstream_Filename);*/ - base.Infile = &bos; -#ifdef FILESTAR - //base.Infile->InFd = fopen(Main_Bitstream_Filename, "rb"); - //base.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary | std::ios::in); - base.Infile->InFd = fp; -#else - base.Infile->InFd = open(Main_Bitstream_Filename,O_RDONLY|O_BINARY ); -#endif - if( !base.Infile->InFd) +#if 0 + if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) { fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename); exit(1); } +#else + base.Infile = -1; //DEBUG +#endif - if(base.Infile != 0) + if ( base.Infile != 0 ) { - Initialize_Buffer(); - - if(Show_Bits(8)==0x47) + Initialize_Buffer(); + + if ( Show_Bits(8)==0x47 ) { sprintf(Error_Text,"Decoder currently does not parse transport streams\n"); Error(Error_Text); @@ -411,34 +370,25 @@ bool ReadMPEGFile (std::ifstream *fp, char *image_buffer, size_t length) break; } - /*lseek(base.Infile, 0l, SEEK_SET);*/ - ld->seek_stream(base.Infile,mpeg_start,SEEK_SET); + //lseek(base.Infile, 0l, SEEK_SET); + //fp->seekg(mpeg_start, ios_base::beg); Initialize_Buffer(); } - if(base.Infile!=0) + if ( base.Infile!=0 ) { - /*lseek(base.Infile, 0l, SEEK_SET);*/ - ld->seek_stream(base.Infile,mpeg_start,SEEK_SET); + //lseek(base.Infile, 0l, SEEK_SET); + //fp->seekg(mpeg_start, ios_base::beg); } Initialize_Buffer(); - if(Two_Streams) + if ( Two_Streams ) { + abort(); ld = &enhan; /* select enhancement layer context */ - /*if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)*/ - /*enhan.Infile = ld->open_stream(Enhancement_Layer_Bitstream_Filename);*/ - enhan.Infile = &eos; -#ifdef FILESTAR - //enhan.Infile->InFd = fopen(Main_Bitstream_Filename, "rb"); - enhan.Infile->InFd->open(Main_Bitstream_Filename, std::ios::binary|std::ios::in); - abort(); -#else - enhan.Infile->InFd = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY); -#endif - if (enhan.Infile->InFd) + if ( (enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0) { sprintf(Error_Text,"enhancment layer bitstream file %s not found\n", Enhancement_Layer_Bitstream_Filename); @@ -454,20 +404,13 @@ bool ReadMPEGFile (std::ifstream *fp, char *image_buffer, size_t length) ret = Decode_Bitstream(); - /*close(base.Infile);*/ - ld->close_stream(base.Infile); - - if (Two_Streams) - /*close(enhan.Infile);*/ - ld->close_stream(enhan.Infile); - - DeInitialize_Decoder(); + //close(base.Infile); -#if 0 - std::ofstream out2("/tmp/etiam.raw"); - out2.write((char*)image_buffer, 352*240*3*10); - out2.close(); -#endif + if ( Two_Streams ) + { + abort(); + close(enhan.Infile); + } return ret; }