From: malaterre Date: Sat, 21 May 2005 18:43:52 +0000 (+0000) Subject: ENH: Initial checkin of gdcmMpeg, the code is still messy but it compiles finally X-Git-Tag: Version1.2.bp~687 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=9b08ef2e93023e33dad3326a0c7d6b5db7b72cd4;p=gdcm.git ENH: Initial checkin of gdcmMpeg, the code is still messy but it compiles finally --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b989b979..0ff6cfb6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,7 @@ SUBDIRS( # "jpeglib.h" is defined here: INCLUDE_DIRECTORIES( ${GDCM_SOURCE_DIR}/src + ${GDCM_SOURCE_DIR}/src/gdcmmpeg2/src/mpeg2dec ${GDCM_BINARY_DIR}/ #for gdcmConfigure.h ${GDCM_BINARY_DIR}/src #for gdcmjpeg 8, 12 and 16 ) @@ -55,6 +56,7 @@ SET(libgdcm_la_SOURCES gdcmJpeg12.cxx gdcmJpeg16.cxx gdcmJpeg2000.cxx + gdcmMpeg.cxx gdcmPixelReadConvert.cxx gdcmPixelWriteConvert.cxx gdcmRLEFrame.cxx @@ -74,6 +76,7 @@ TARGET_LINK_LIBRARIES(gdcm gdcmjpeg8 gdcmjpeg12 gdcmjpeg16 + gdcmmpeg2 ) IF(WIN32) IF(NOT BORLAND) diff --git a/src/gdcmMpeg.cxx b/src/gdcmMpeg.cxx new file mode 100644 index 00000000..52183719 --- /dev/null +++ b/src/gdcmMpeg.cxx @@ -0,0 +1,410 @@ +/*========================================================================= + + Program: gdcm + Module: $RCSfile: gdcmMpeg.cxx,v $ + Language: C++ + Date: $Date: 2005/05/21 18:43:52 $ + Version: $Revision: 1.1 $ + + Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de + l'Image). All rights reserved. See Doc/License.txt or + http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "gdcmDebug.h" + +#include +#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[])); + +/* IMPLEMENTAION specific rouintes */ +static void Initialize_Decoder() +{ + int i; + + /* Clip table */ + if (!(Clip=(unsigned char *)malloc(1024))) + Error("Clip[] malloc failed\n"); + + Clip += 384; + + for (i=-384; i<640; i++) + Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i); + + /* IDCT */ + if (Reference_IDCT_Flag) + Initialize_Reference_IDCT(); + else + Initialize_Fast_IDCT(); + +} + +/* mostly IMPLEMENTAION specific rouintes */ +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"); + + /* force MPEG-1 parameters for proper decoder behavior */ + /* see ISO/IEC 13818-2 section D.9.14 */ + if (!base.MPEG2_Flag) + { + progressive_sequence = 1; + progressive_frame = 1; + picture_structure = FRAME_PICTURE; + frame_pred_frame_dct = 1; + chroma_format = CHROMA420; + matrix_coefficients = 5; + } + + /* round to nearest multiple of coded macroblocks */ + /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */ + mb_width = (horizontal_size+15)/16; + mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32) + : (vertical_size+15)/16; + + Coded_Picture_Width = 16*mb_width; + Coded_Picture_Height = 16*mb_height; + + /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */ + Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width + : Coded_Picture_Width>>1; + Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height + : Coded_Picture_Height>>1; + + /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */ + block_count = Table_6_20[chroma_format-1]; + + for (cc=0; cc<3; cc++) + { + 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))) + Error("backward_reference_frame[] malloc failed\n"); + + if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size))) + Error("forward_reference_frame[] malloc failed\n"); + + if (!(auxframe[cc] = (unsigned char *)malloc(size))) + Error("auxframe[] malloc failed\n"); + + if(Ersatz_Flag) + if (!(substitute_frame[cc] = (unsigned char *)malloc(size))) + Error("substitute_frame[] malloc failed\n"); + + + 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)))) + Error("llframe0 malloc failed\n"); + 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 (!(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"); + } + +#ifdef DISPLAY + if (Output_Type==T_X11) + { + Initialize_Display_Process(""); + Initialize_Dither_Matrix(); + } +#endif /* DISPLAY */ + +} + +extern void Error(char *text) +{ + fprintf(stderr,text); + exit(1); +} + +/* 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() +{ + int ret; + + ld = &base; + + + /* return when end of sequence (0) or picture + header has been parsed (1) */ + + ret = Get_Hdr(); + + + if (Two_Streams) + { + ld = &enhan; + if (Get_Hdr()!=ret && !Quiet_Flag) + fprintf(stderr,"streams out of sync\n"); + ld = &base; + } + + return ret; +} + + + +static int Decode_Bitstream() +{ + int ret; + int Bitstream_Framenum; + + Bitstream_Framenum = 0; + + for(;;) + { + +#ifdef VERIFY + Clear_Verify_Headers(); +#endif /* VERIFY */ + + ret = Headers(); + + if(ret==1) + { + ret = video_sequence(&Bitstream_Framenum); + } + else + return(ret); + } + +} + + +static void Deinitialize_Sequence() +{ + int i; + + /* clear flags */ + base.MPEG2_Flag=0; + + for(i=0;i<3;i++) + { + free(backward_reference_frame[i]); + free(forward_reference_frame[i]); + free(auxframe[i]); + + if (base.scalable_mode==SC_SPAT) + { + free(llframe0[i]); + free(llframe1[i]); + } + } + + if (base.scalable_mode==SC_SPAT) + free(lltmp); + +#ifdef DISPLAY + if (Output_Type==T_X11) + Terminate_Display_Process(); +#endif +} + + +static int video_sequence(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 */ + + *Bitstream_Framenumber = Bitstream_Framenum; + return(Return_Value); +} +} // End "C" extern + +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 statesuspension Suspension State basically it should be 3 otherwise more complex to handle + * @return 1 on success, 0 on error + */ +bool ReadMPEGFile (std::ifstream *fp, void *image_buffer) +{ + int ret, code; + +// 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 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) + { + Initialize_Buffer(); + + if(Show_Bits(8)==0x47) + { + sprintf(Error_Text,"Decoder currently does not parse transport streams\n"); + Error(Error_Text); + } + + next_start_code(); + code = Show_Bits(32); + + switch(code) + { + case SEQUENCE_HEADER_CODE: + break; + case PACK_START_CODE: + System_Stream_Flag = 1; + case VIDEO_ELEMENTARY_STREAM: + System_Stream_Flag = 1; + break; + default: + sprintf(Error_Text,"Unable to recognize stream type\n"); + Error(Error_Text); + break; + } + + //lseek(base.Infile, 0l, SEEK_SET); + //fp->seekg(mpeg_start, ios_base::beg); + Initialize_Buffer(); + } + + if(base.Infile!=0) + { + //lseek(base.Infile, 0l, SEEK_SET); + //fp->seekg(mpeg_start, ios_base::beg); + } + + Initialize_Buffer(); + + if(Two_Streams) + { + abort(); + ld = &enhan; /* select enhancement layer context */ + + 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); + + Error(Error_Text); + } + + Initialize_Buffer(); + ld = &base; + } + + Initialize_Decoder(); + + ret = Decode_Bitstream(); + + //close(base.Infile); + + if (Two_Streams) + { + abort(); + close(enhan.Infile); + } + + return ret; +} + +} // end namespace gdcm diff --git a/src/gdcmPixelReadConvert.cxx b/src/gdcmPixelReadConvert.cxx index 45bb58e7..66bcbfde 100644 --- a/src/gdcmPixelReadConvert.cxx +++ b/src/gdcmPixelReadConvert.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelReadConvert.cxx,v $ Language: C++ - Date: $Date: 2005/04/26 16:25:49 $ - Version: $Revision: 1.55 $ + Date: $Date: 2005/05/21 18:43:53 $ + Version: $Revision: 1.56 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -30,6 +30,8 @@ namespace gdcm { + +extern bool ReadMPEGFile (std::ifstream *fp, void *image_buffer); //----------------------------------------------------------------------------- #define str2num(str, typeNum) *((typeNum *)(str)) @@ -253,8 +255,10 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp ) } else if ( IsMPEG ) { - gdcmWarningMacro( "Sorry, MPEG not yet taken into account" ); - return false; + //gdcmWarningMacro( "Sorry, MPEG not yet taken into account" ); + //return false; + ReadMPEGFile(fp, Raw); // fp has already been seek to start of mpeg + return true; } else {