]> Creatis software - gdcm.git/commitdiff
ENH: Initial checkin of gdcmMpeg, the code is still messy but it compiles finally
authormalaterre <malaterre>
Sat, 21 May 2005 18:43:52 +0000 (18:43 +0000)
committermalaterre <malaterre>
Sat, 21 May 2005 18:43:52 +0000 (18:43 +0000)
src/CMakeLists.txt
src/gdcmMpeg.cxx [new file with mode: 0644]
src/gdcmPixelReadConvert.cxx

index b989b979923c2c5f3991891acfe6d22e858f4d38..0ff6cfb63366a1bf791d4486683e465ac4fe81b3 100644 (file)
@@ -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 (file)
index 0000000..5218371
--- /dev/null
@@ -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 <fstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <fcntl.h>
+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<len; i++)
+    printf("%d",(code>>(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
index 45bb58e7b69e35bd12a2240db1b91c68a1175d49..66bcbfdeaad67b93616528281824a9b9730fbe7a 100644 (file)
@@ -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
    {