]> Creatis software - gdcm.git/commitdiff
ENH: For the long long long long term adding the part of lib that encode in mpeg
authormalaterre <malaterre>
Sat, 21 May 2005 01:27:21 +0000 (01:27 +0000)
committermalaterre <malaterre>
Sat, 21 May 2005 01:27:21 +0000 (01:27 +0000)
26 files changed:
src/gdcmmpeg2/src/mpeg2enc/CHANGES [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/Makefile [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/Makefile.wat [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/TODO [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/config.h [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/conform.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/fdctref.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/global.h [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/idct.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/motion.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/mpeg2enc.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/mpeg2enc.h [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/predict.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/putbits.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/puthdr.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/putmpg.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/putpic.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/putseq.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/putvlc.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/quantize.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/ratectl.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/readpic.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/stats.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/transfrm.c [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/vlc.h [new file with mode: 0644]
src/gdcmmpeg2/src/mpeg2enc/writepic.c [new file with mode: 0644]

diff --git a/src/gdcmmpeg2/src/mpeg2enc/CHANGES b/src/gdcmmpeg2/src/mpeg2enc/CHANGES
new file mode 100644 (file)
index 0000000..bf1467d
--- /dev/null
@@ -0,0 +1,26 @@
+CHANGES
+=======
+
+Since July 4, 1994 edition:
+
+  Summary:
+   only very minor changes since version 1.1a, distributed two years 
+   ago.  A beta version of this program has significantly greater
+   number of changes (.par file syntax, restructured motion.c ,
+   zero-block test of Note 4.1.1, etc.)
+
+  1. as per suggestion of Peter Loje Hansen <plh@tdr.dk>:
+
+  -  corrected line 631 of motion.c so field_estimate uses 
+     backward search range variables (sxb, syb) instead of 
+     forward search range variables (sxf, syf).
+
+  -  corrected line 250 in putseq.c, replacing .sxf with .syf
+
+
+  2. many user suggestions:
+  -  prevent divide by zero in SNR calculation in stat.c.
+
+  3. general:
+  - eliminated support for non ANSI C compilers  in makefile.
+
diff --git a/src/gdcmmpeg2/src/mpeg2enc/Makefile b/src/gdcmmpeg2/src/mpeg2enc/Makefile
new file mode 100644 (file)
index 0000000..9f6dd70
--- /dev/null
@@ -0,0 +1,70 @@
+# Makefile for mpeg2encode
+
+# Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+#
+# Disclaimer of Warranty
+#
+# These software programs are available to the user without any license fee or
+# royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+# any and all warranties, whether express, implied, or statuary, including any
+# implied warranties or merchantability or of fitness for a particular
+# purpose.  In no event shall the copyright-holder be liable for any
+# incidental, punitive, or consequential damages of any kind whatsoever
+# arising from the use of these programs.
+#
+# This disclaimer of warranty extends to the user of these programs and user's
+# customers, employees, agents, transferees, successors, and assigns.
+#
+# The MPEG Software Simulation Group does not represent or warrant that the
+# programs furnished hereunder are free of infringement of any third-party
+# patents.
+#
+# Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+# are subject to royalty fees to patent holders.  Many of these patents are
+# general enough such that they are unavoidable regardless of implementation
+# design.
+#
+#
+
+# select one of the following CC CFLAGS settings
+
+#
+# GNU gcc
+#
+CC = gcc
+CFLAGS = -O2 -Wall
+
+OBJ = mpeg2enc.o conform.o putseq.o putpic.o puthdr.o putmpg.o putvlc.o putbits.o motion.o predict.o readpic.o writepic.o transfrm.o fdctref.o idct.o quantize.o ratectl.o stats.o
+
+all: mpeg2encode
+
+pc: mpeg2enc.exe
+
+clean:
+       rm -f *.o *% core mpeg2encode
+
+mpeg2enc.exe: mpeg2encode
+       coff2exe mpeg2enc
+
+mpeg2encode: $(OBJ)
+       $(CC) $(CFLAGS) -o mpeg2encode $(OBJ) -lm
+
+conform.o : conform.c config.h global.h mpeg2enc.h 
+fdctref.o : fdctref.c config.h 
+idct.o : idct.c config.h 
+motion.o : motion.c config.h global.h mpeg2enc.h 
+mpeg2enc.o : mpeg2enc.c config.h global.h mpeg2enc.h 
+predict.o : predict.c config.h global.h mpeg2enc.h 
+putbits.o : putbits.c config.h 
+puthdr.o : puthdr.c config.h global.h mpeg2enc.h 
+putmpg.o : putmpg.c config.h global.h mpeg2enc.h 
+putpic.o : putpic.c config.h global.h mpeg2enc.h 
+putseq.o : putseq.c config.h global.h mpeg2enc.h 
+putvlc.o : putvlc.c config.h global.h mpeg2enc.h vlc.h 
+quantize.o : quantize.c config.h global.h mpeg2enc.h 
+ratectl.o : ratectl.c config.h global.h mpeg2enc.h 
+readpic.o : readpic.c config.h global.h mpeg2enc.h 
+stats.o : stats.c config.h global.h mpeg2enc.h 
+transfrm.o : transfrm.c config.h global.h mpeg2enc.h 
+writepic.o : writepic.c config.h global.h mpeg2enc.h 
diff --git a/src/gdcmmpeg2/src/mpeg2enc/Makefile.wat b/src/gdcmmpeg2/src/mpeg2enc/Makefile.wat
new file mode 100644 (file)
index 0000000..57238df
--- /dev/null
@@ -0,0 +1,85 @@
+# Makefile for mpeg2encode (user contribution, untested)
+#
+# WATCOM C/386++
+#
+INC      = C:\OR386\INCLUDE
+
+LINKFILE = temp.lnk
+CC = WCC386P
+LL = WLINKP system dos4g
+
+!ifdef DEBUG
+CFLAGS = -w4 -zq -4r -d2 -I$(INC)
+!else
+CFLAGS = -w4 -zq -4r -oaxt -I$(INC)
+!endif
+
+OBJ = mpeg2enc.obj conform.obj putseq.obj putpic.obj puthdr.obj putmpg.obj 
+putvlc.obj putbits.obj motion.obj predict.obj readpic.obj 
+writepic.obj transfrm.obj fdctref.obj idct.obj quantize.obj 
+ratectl.obj stats.obj
+
+mpeg2enc.exe: $(OBJ)
+        %create $(LINKFILE)
+    %append $(LINKFILE) debug all
+    %append $(LINKFILE) opt stack=32000
+        %append $(LINKFILE) opt caseexact
+        %append $(LINKFILE) opt map=$^&.MAP
+    %append $(LINKFILE) NAME $^&
+        for %i in ($(OBJ)) do %append $(LINKFILE) FILE %i
+        $(LL) @$(LINKFILE)
+
+conform.obj: conform.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+fdctref.obj: fdctref.c config.h
+       $(CC) $(CFLAGS) $*.c
+
+idct.obj: idct.c config.h
+       $(CC) $(CFLAGS) $*.c
+
+motion.obj: motion.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+mpeg2enc.obj: mpeg2enc.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+predict.obj: predict.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+putbits.obj: putbits.c config.h
+       $(CC) $(CFLAGS) $*.c
+
+puthdr.obj: puthdr.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+putmpg.obj: putmpg.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+putpic.obj: putpic.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+putseq.obj: putseq.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+putvlc.obj: putvlc.c config.h mpeg2enc.h global.h vlc.h
+       $(CC) $(CFLAGS) $*.c
+
+quantize.obj: quantize.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+ratectl.obj: ratectl.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+readpic.obj: readpic.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+stats.obj: stats.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+transfrm.obj: transfrm.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
+writepic.obj: writepic.c config.h mpeg2enc.h global.h
+       $(CC) $(CFLAGS) $*.c
+
diff --git a/src/gdcmmpeg2/src/mpeg2enc/TODO b/src/gdcmmpeg2/src/mpeg2enc/TODO
new file mode 100644 (file)
index 0000000..acd4fad
--- /dev/null
@@ -0,0 +1,10 @@
+TODO
+====
+
+ - update vbv_delay calculation to agree with November 1994 
+   (WG11 approved IS draft of ISO/IEC 13818-2).
+
+ - allow intra only encoding of sequences (disable ipflag in
+   putseq.c)
+
+
diff --git a/src/gdcmmpeg2/src/mpeg2enc/config.h b/src/gdcmmpeg2/src/mpeg2enc/config.h
new file mode 100644 (file)
index 0000000..8548f87
--- /dev/null
@@ -0,0 +1,37 @@
+/* config.h, configuration defines                                          */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+/* define NON_ANSI_COMPILER for compilers without function prototyping */
+/* #define NON_ANSI_COMPILER */
+
+#ifdef NON_ANSI_COMPILER
+#define _ANSI_ARGS_(x) ()
+#else
+#define _ANSI_ARGS_(x) x
+#endif
diff --git a/src/gdcmmpeg2/src/mpeg2enc/conform.c b/src/gdcmmpeg2/src/mpeg2enc/conform.c
new file mode 100644 (file)
index 0000000..1c1ce27
--- /dev/null
@@ -0,0 +1,287 @@
+/* conform.c, conformance checks                                            */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "global.h"
+
+/* check for (level independent) parameter limits */
+void range_checks()
+{
+  int i;
+
+  /* range and value checks */
+
+  if (horizontal_size<1 || horizontal_size>16383)
+    error("horizontal_size must be between 1 and 16383");
+  if (mpeg1 && horizontal_size>4095)
+    error("horizontal_size must be less than 4096 (MPEG-1)");
+  if ((horizontal_size&4095)==0)
+    error("horizontal_size must not be a multiple of 4096");
+  if (chroma_format!=CHROMA444 && horizontal_size%2 != 0)
+    error("horizontal_size must be a even (4:2:0 / 4:2:2)");
+
+  if (vertical_size<1 || vertical_size>16383)
+    error("vertical_size must be between 1 and 16383");
+  if (mpeg1 && vertical_size>4095)
+    error("vertical size must be less than 4096 (MPEG-1)");
+  if ((vertical_size&4095)==0)
+    error("vertical_size must not be a multiple of 4096");
+  if (chroma_format==CHROMA420 && vertical_size%2 != 0)
+    error("vertical_size must be a even (4:2:0)");
+  if(fieldpic)
+  {
+    if (vertical_size%2 != 0)
+      error("vertical_size must be a even (field pictures)");
+    if (chroma_format==CHROMA420 && vertical_size%4 != 0)
+      error("vertical_size must be a multiple of 4 (4:2:0 field pictures)");
+  }
+
+  if (mpeg1)
+  {
+    if (aspectratio<1 || aspectratio>14)
+      error("pel_aspect_ratio must be between 1 and 14 (MPEG-1)");
+  }
+  else
+  {
+    if (aspectratio<1 || aspectratio>4)
+      error("aspect_ratio_information must be 1, 2, 3 or 4");
+  }
+
+  if (frame_rate_code<1 || frame_rate_code>8)
+    error("frame_rate code must be between 1 and 8");
+
+  if (bit_rate<=0.0)
+    error("bit_rate must be positive");
+  if (bit_rate > ((1<<30)-1)*400.0)
+    error("bit_rate must be less than 429 Gbit/s");
+  if (mpeg1 && bit_rate > ((1<<18)-1)*400.0)
+    error("bit_rate must be less than 104 Mbit/s (MPEG-1)");
+
+  if (vbv_buffer_size<1 || vbv_buffer_size>0x3ffff)
+    error("vbv_buffer_size must be in range 1..(2^18-1)");
+  if (mpeg1 && vbv_buffer_size>=1024)
+    error("vbv_buffer_size must be less than 1024 (MPEG-1)");
+
+  if (chroma_format<CHROMA420 || chroma_format>CHROMA444)
+    error("chroma_format must be in range 1...3");
+
+  if (video_format<0 || video_format>4)
+    error("video_format must be in range 0...4");
+
+  if (color_primaries<1 || color_primaries>7 || color_primaries==3)
+    error("color_primaries must be in range 1...2 or 4...7");
+
+  if (transfer_characteristics<1 || transfer_characteristics>7
+      || transfer_characteristics==3)
+    error("transfer_characteristics must be in range 1...2 or 4...7");
+
+  if (matrix_coefficients<1 || matrix_coefficients>7 || matrix_coefficients==3)
+    error("matrix_coefficients must be in range 1...2 or 4...7");
+
+  if (display_horizontal_size<0 || display_horizontal_size>16383)
+    error("display_horizontal_size must be in range 0...16383");
+  if (display_vertical_size<0 || display_vertical_size>16383)
+    error("display_vertical_size must be in range 0...16383");
+
+  if (dc_prec<0 || dc_prec>3)
+    error("intra_dc_precision must be in range 0...3");
+
+  for (i=0; i<M; i++)
+  {
+    if (motion_data[i].forw_hor_f_code<1 || motion_data[i].forw_hor_f_code>9)
+      error("f_code must be between 1 and 9");
+    if (motion_data[i].forw_vert_f_code<1 || motion_data[i].forw_vert_f_code>9)
+      error("f_code must be between 1 and 9");
+    if (mpeg1 && motion_data[i].forw_hor_f_code>7)
+      error("f_code must be le less than 8");
+    if (mpeg1 && motion_data[i].forw_vert_f_code>7)
+      error("f_code must be le less than 8");
+    if (motion_data[i].sxf<=0)
+      error("search window must be positive"); /* doesn't belong here */
+    if (motion_data[i].syf<=0)
+      error("search window must be positive");
+    if (i!=0)
+    {
+      if (motion_data[i].back_hor_f_code<1 || motion_data[i].back_hor_f_code>9)
+        error("f_code must be between 1 and 9");
+      if (motion_data[i].back_vert_f_code<1 || motion_data[i].back_vert_f_code>9)
+        error("f_code must be between 1 and 9");
+      if (mpeg1 && motion_data[i].back_hor_f_code>7)
+        error("f_code must be le less than 8");
+      if (mpeg1 && motion_data[i].back_vert_f_code>7)
+        error("f_code must be le less than 8");
+      if (motion_data[i].sxb<=0)
+        error("search window must be positive");
+      if (motion_data[i].syb<=0)
+        error("search window must be positive");
+    }
+  }
+}
+
+/* identifies valid profile / level combinations */
+static char profile_level_defined[5][4] =
+{
+/* HL   H-14 ML   LL  */
+  {1,   1,   1,   0},  /* HP   */
+  {0,   1,   0,   0},  /* Spat */
+  {0,   0,   1,   1},  /* SNR  */
+  {1,   1,   1,   1},  /* MP   */
+  {0,   0,   1,   0}   /* SP   */
+};
+
+static struct level_limits {
+  int hor_f_code;
+  int vert_f_code;
+  int hor_size;
+  int vert_size;
+  int sample_rate;
+  int bit_rate; /* Mbit/s */
+  int vbv_buffer_size; /* 16384 bit steps */
+} maxval_tab[4] =
+{
+  {9, 5, 1920, 1152, 62668800, 80, 597}, /* HL */
+  {9, 5, 1440, 1152, 47001600, 60, 448}, /* H-14 */
+  {8, 5,  720,  576, 10368000, 15, 112}, /* ML */
+  {7, 4,  352,  288,  3041280,  4,  29}  /* LL */
+};
+
+#define SP   5
+#define MP   4
+#define SNR  3
+#define SPAT 2
+#define HP   1
+
+#define LL  10
+#define ML   8
+#define H14  6
+#define HL   4
+
+void profile_and_level_checks()
+{
+  int i;
+  struct level_limits *maxval;
+
+  if (profile<0 || profile>15)
+    error("profile must be between 0 and 15");
+
+  if (level<0 || level>15)
+    error("level must be between 0 and 15");
+
+  if (profile>=8)
+  {
+    if (!quiet)
+      fprintf(stderr,"Warning: profile uses a reserved value, conformance checks skipped\n");
+    return;
+  }
+
+  if (profile<HP || profile>SP)
+    error("undefined Profile");
+
+  if (profile==SNR || profile==SPAT)
+    error("This encoder currently generates no scalable bitstreams");
+
+  if (level<HL || level>LL || level&1)
+    error("undefined Level");
+
+  maxval = &maxval_tab[(level-4) >> 1];
+
+  /* check profile@level combination */
+  if(!profile_level_defined[profile-1][(level-4) >> 1])
+    error("undefined profile@level combination");
+  
+
+  /* profile (syntax) constraints */
+
+  if (profile==SP && M!=1)
+    error("Simple Profile does not allow B pictures");
+
+  if (profile!=HP && chroma_format!=CHROMA420)
+    error("chroma format must be 4:2:0 in specified Profile");
+
+  if (profile==HP && chroma_format==CHROMA444)
+    error("chroma format must be 4:2:0 or 4:2:2 in High Profile");
+
+  if (profile>=MP) /* SP, MP: constrained repeat_first_field */
+  {
+    if (frame_rate_code<=2 && repeatfirst)
+      error("repeat_first_first must be zero");
+    if (frame_rate_code<=6 && prog_seq && repeatfirst)
+      error("repeat_first_first must be zero");
+  }
+
+  if (profile!=HP && dc_prec==3)
+    error("11 bit DC precision only allowed in High Profile");
+
+
+  /* level (parameter value) constraints */
+
+  /* Table 8-8 */
+  if (frame_rate_code>5 && level>=ML)
+    error("Picture rate greater than permitted in specified Level");
+
+  for (i=0; i<M; i++)
+  {
+    if (motion_data[i].forw_hor_f_code > maxval->hor_f_code)
+      error("forward horizontal f_code greater than permitted in specified Level");
+
+    if (motion_data[i].forw_vert_f_code > maxval->vert_f_code)
+      error("forward vertical f_code greater than permitted in specified Level");
+
+    if (i!=0)
+    {
+      if (motion_data[i].back_hor_f_code > maxval->hor_f_code)
+        error("backward horizontal f_code greater than permitted in specified Level");
+  
+      if (motion_data[i].back_vert_f_code > maxval->vert_f_code)
+        error("backward vertical f_code greater than permitted in specified Level");
+    }
+  }
+
+  /* Table 8-10 */
+  if (horizontal_size > maxval->hor_size)
+    error("Horizontal size is greater than permitted in specified Level");
+
+  if (vertical_size > maxval->vert_size)
+    error("Horizontal size is greater than permitted in specified Level");
+
+  /* Table 8-11 */
+  if (horizontal_size*vertical_size*frame_rate > maxval->sample_rate)
+    error("Sample rate is greater than permitted in specified Level");
+
+  /* Table 8-12 */
+  if (bit_rate> 1.0e6 * maxval->bit_rate)
+    error("Bit rate is greater than permitted in specified Level");
+
+  /* Table 8-13 */
+  if (vbv_buffer_size > maxval->vbv_buffer_size)
+    error("vbv_buffer_size exceeds High Level limit");
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/fdctref.c b/src/gdcmmpeg2/src/mpeg2enc/fdctref.c
new file mode 100644 (file)
index 0000000..e04981a
--- /dev/null
@@ -0,0 +1,100 @@
+/* fdctref.c, forward discrete cosine transform, double precision           */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <math.h>
+
+#include "config.h"
+
+#ifndef PI
+# ifdef M_PI
+#  define PI M_PI
+# else
+#  define PI 3.14159265358979323846
+# endif
+#endif
+
+/* global declarations */
+void init_fdct _ANSI_ARGS_((void));
+void fdct _ANSI_ARGS_((short *block));
+
+/* private data */
+static double c[8][8]; /* transform coefficients */
+
+void init_fdct()
+{
+  int i, j;
+  double s;
+
+  for (i=0; i<8; i++)
+  {
+    s = (i==0) ? sqrt(0.125) : 0.5;
+
+    for (j=0; j<8; j++)
+      c[i][j] = s * cos((PI/8.0)*i*(j+0.5));
+  }
+}
+
+void fdct(block)
+short *block;
+{
+  int i, j, k;
+  double s;
+  double tmp[64];
+
+  for (i=0; i<8; i++)
+    for (j=0; j<8; j++)
+    {
+      s = 0.0;
+
+      for (k=0; k<8; k++)
+        s += c[j][k] * block[8*i+k];
+
+      tmp[8*i+j] = s;
+    }
+
+  for (j=0; j<8; j++)
+    for (i=0; i<8; i++)
+    {
+      s = 0.0;
+
+      for (k=0; k<8; k++)
+        s += c[i][k] * tmp[8*k+j];
+
+      block[8*i+j] = (int)floor(s+0.499999);
+      /*
+       * reason for adding 0.499999 instead of 0.5:
+       * s is quite often x.5 (at least for i and/or j = 0 or 4)
+       * and setting the rounding threshold exactly to 0.5 leads to an
+       * extremely high arithmetic implementation dependency of the result;
+       * s being between x.5 and x.500001 (which is now incorrectly rounded
+       * downwards instead of upwards) is assumed to occur less often
+       * (if at all)
+       */
+    }
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/global.h b/src/gdcmmpeg2/src/mpeg2enc/global.h
new file mode 100644 (file)
index 0000000..b50a7b2
--- /dev/null
@@ -0,0 +1,334 @@
+/* global.h, global variables, function prototypes                          */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include "mpeg2enc.h"
+
+/* choose between declaration (GLOBAL undefined)
+ * and definition (GLOBAL defined)
+ * GLOBAL is defined in exactly one file (mpeg2enc.c)
+ */
+
+#ifndef GLOBAL
+#define EXTERN extern
+#else
+#define EXTERN
+#endif
+
+/* prototypes of global functions */
+
+/* conform.c */
+void range_checks _ANSI_ARGS_((void));
+void profile_and_level_checks _ANSI_ARGS_(());
+
+/* fdctref.c */
+void init_fdct _ANSI_ARGS_((void));
+void fdct _ANSI_ARGS_((short *block));
+
+/* idct.c */
+void idct _ANSI_ARGS_((short *block));
+void init_idct _ANSI_ARGS_((void));
+
+/* motion.c */
+void motion_estimation _ANSI_ARGS_((unsigned char *oldorg, unsigned char *neworg,
+  unsigned char *oldref, unsigned char *newref, unsigned char *cur,
+  unsigned char *curref, int sxf, int syf, int sxb, int syb,
+  struct mbinfo *mbi, int secondfield, int ipflag));
+
+/* mpeg2enc.c */
+void error _ANSI_ARGS_((char *text));
+
+/* predict.c */
+void predict _ANSI_ARGS_((unsigned char *reff[], unsigned char *refb[],
+  unsigned char *cur[3], int secondfield, struct mbinfo *mbi));
+
+/* putbits.c */
+void initbits _ANSI_ARGS_((void));
+void putbits _ANSI_ARGS_((int val, int n));
+void alignbits _ANSI_ARGS_((void));
+int bitcount _ANSI_ARGS_((void));
+
+/* puthdr.c */
+void putseqhdr _ANSI_ARGS_((void));
+void putseqext _ANSI_ARGS_((void));
+void putseqdispext _ANSI_ARGS_((void));
+void putuserdata _ANSI_ARGS_((char *userdata));
+void putgophdr _ANSI_ARGS_((int frame, int closed_gop));
+void putpicthdr _ANSI_ARGS_((void));
+void putpictcodext _ANSI_ARGS_((void));
+void putseqend _ANSI_ARGS_((void));
+
+/* putmpg.c */
+void putintrablk _ANSI_ARGS_((short *blk, int cc));
+void putnonintrablk _ANSI_ARGS_((short *blk));
+void putmv _ANSI_ARGS_((int dmv, int f_code));
+
+/* putpic.c */
+void putpict _ANSI_ARGS_((unsigned char *frame));
+
+/* putseq.c */
+void putseq _ANSI_ARGS_((void));
+
+/* putvlc.c */
+void putDClum _ANSI_ARGS_((int val));
+void putDCchrom _ANSI_ARGS_((int val));
+void putACfirst _ANSI_ARGS_((int run, int val));
+void putAC _ANSI_ARGS_((int run, int signed_level, int vlcformat));
+void putaddrinc _ANSI_ARGS_((int addrinc));
+void putmbtype _ANSI_ARGS_((int pict_type, int mb_type));
+void putmotioncode _ANSI_ARGS_((int motion_code));
+void putdmv _ANSI_ARGS_((int dmv));
+void putcbp _ANSI_ARGS_((int cbp));
+
+/* quantize.c */
+int quant_intra _ANSI_ARGS_((short *src, short *dst, int dc_prec,
+  unsigned char *quant_mat, int mquant));
+int quant_non_intra _ANSI_ARGS_((short *src, short *dst,
+  unsigned char *quant_mat, int mquant));
+void iquant_intra _ANSI_ARGS_((short *src, short *dst, int dc_prec,
+  unsigned char *quant_mat, int mquant));
+void iquant_non_intra _ANSI_ARGS_((short *src, short *dst,
+  unsigned char *quant_mat, int mquant));
+
+/* ratectl.c */
+void rc_init_seq _ANSI_ARGS_((void));
+void rc_init_GOP _ANSI_ARGS_((int np, int nb));
+void rc_init_pict _ANSI_ARGS_((unsigned char *frame));
+void rc_update_pict _ANSI_ARGS_((void));
+int rc_start_mb _ANSI_ARGS_((void));
+int rc_calc_mquant _ANSI_ARGS_((int j));
+void vbv_end_of_picture _ANSI_ARGS_((void));
+void calc_vbv_delay _ANSI_ARGS_((void));
+
+/* readpic.c */
+void readframe _ANSI_ARGS_((char *fname, unsigned char *frame[]));
+
+/* stats.c */
+void calcSNR _ANSI_ARGS_((unsigned char *org[3], unsigned char *rec[3]));
+void stats _ANSI_ARGS_((void));
+
+/* transfrm.c */
+void transform _ANSI_ARGS_((unsigned char *pred[], unsigned char *cur[],
+  struct mbinfo *mbi, short blocks[][64]));
+void itransform _ANSI_ARGS_((unsigned char *pred[], unsigned char *cur[],
+  struct mbinfo *mbi, short blocks[][64]));
+void dct_type_estimation _ANSI_ARGS_((unsigned char *pred, unsigned char *cur,
+  struct mbinfo *mbi));
+
+/* writepic.c */
+void writeframe _ANSI_ARGS_((char *fname, unsigned char *frame[]));
+
+
+/* global variables */
+
+EXTERN char version[]
+#ifdef GLOBAL
+  ="mpeg2encode V1.2, 96/07/19"
+#endif
+;
+
+EXTERN char author[]
+#ifdef GLOBAL
+  ="(C) 1996, MPEG Software Simulation Group"
+#endif
+;
+
+/* zig-zag scan */
+EXTERN unsigned char zig_zag_scan[64]
+#ifdef GLOBAL
+=
+{
+  0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,
+  12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,
+  35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,
+  58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63
+}
+#endif
+;
+
+/* alternate scan */
+EXTERN unsigned char alternate_scan[64]
+#ifdef GLOBAL
+=
+{
+  0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,
+  41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,
+  51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,
+  53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
+}
+#endif
+;
+
+/* default intra quantization matrix */
+EXTERN unsigned char default_intra_quantizer_matrix[64]
+#ifdef GLOBAL
+=
+{
+   8, 16, 19, 22, 26, 27, 29, 34,
+  16, 16, 22, 24, 27, 29, 34, 37,
+  19, 22, 26, 27, 29, 34, 34, 38,
+  22, 22, 26, 27, 29, 34, 37, 40,
+  22, 26, 27, 29, 32, 35, 40, 48,
+  26, 27, 29, 32, 35, 40, 48, 58,
+  26, 27, 29, 34, 38, 46, 56, 69,
+  27, 29, 35, 38, 46, 56, 69, 83
+}
+#endif
+;
+
+/* non-linear quantization coefficient table */
+EXTERN unsigned char non_linear_mquant_table[32]
+#ifdef GLOBAL
+=
+{
+   0, 1, 2, 3, 4, 5, 6, 7,
+   8,10,12,14,16,18,20,22,
+  24,28,32,36,40,44,48,52,
+  56,64,72,80,88,96,104,112
+}
+#endif
+;
+
+/* non-linear mquant table for mapping from scale to code
+ * since reconstruction levels are not bijective with the index map,
+ * it is up to the designer to determine most of the quantization levels
+ */
+
+EXTERN unsigned char map_non_linear_mquant[113] 
+#ifdef GLOBAL
+=
+{
+0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,
+16,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,
+22,22,23,23,23,23,24,24,24,24,24,24,24,25,25,25,25,25,25,25,26,26,
+26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,29,
+29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,31,31,31,31,31
+}
+#endif
+;
+
+/* picture data arrays */
+
+/* reconstructed frames */
+EXTERN unsigned char *newrefframe[3], *oldrefframe[3], *auxframe[3];
+/* original frames */
+EXTERN unsigned char *neworgframe[3], *oldorgframe[3], *auxorgframe[3];
+/* prediction of current frame */
+EXTERN unsigned char *predframe[3];
+/* 8*8 block data */
+EXTERN short (*blocks)[64];
+/* intra / non_intra quantization matrices */
+EXTERN unsigned char intra_q[64], inter_q[64];
+EXTERN unsigned char chrom_intra_q[64],chrom_inter_q[64];
+/* prediction values for DCT coefficient (0,0) */
+EXTERN int dc_dct_pred[3];
+/* macroblock side information array */
+EXTERN struct mbinfo *mbinfo;
+/* motion estimation parameters */
+EXTERN struct motion_data *motion_data;
+/* clipping (=saturation) table */
+EXTERN unsigned char *clp;
+
+/* name strings */
+EXTERN char id_string[256], tplorg[256], tplref[256];
+EXTERN char iqname[256], niqname[256];
+EXTERN char statname[256];
+EXTERN char errortext[256];
+
+EXTERN FILE *outfile, *statfile; /* file descriptors */
+EXTERN int inputtype; /* format of input frames */
+
+EXTERN int quiet; /* suppress warnings */
+
+
+/* coding model parameters */
+
+EXTERN int N; /* number of frames in Group of Pictures */
+EXTERN int M; /* distance between I/P frames */
+EXTERN int P; /* intra slice refresh interval */
+EXTERN int nframes; /* total number of frames to encode */
+EXTERN int frame0, tc0; /* number and timecode of first frame */
+EXTERN int mpeg1; /* ISO/IEC IS 11172-2 sequence */
+EXTERN int fieldpic; /* use field pictures */
+
+/* sequence specific data (sequence header) */
+
+EXTERN int horizontal_size, vertical_size; /* frame size (pels) */
+EXTERN int width, height; /* encoded frame size (pels) multiples of 16 or 32 */
+EXTERN int chrom_width,chrom_height,block_count;
+EXTERN int mb_width, mb_height; /* frame size (macroblocks) */
+EXTERN int width2, height2, mb_height2, chrom_width2; /* picture size */
+EXTERN int aspectratio; /* aspect ratio information (pel or display) */
+EXTERN int frame_rate_code; /* coded value of frame rate */
+EXTERN double frame_rate; /* frames per second */
+EXTERN double bit_rate; /* bits per second */
+EXTERN int vbv_buffer_size; /* size of VBV buffer (* 16 kbit) */
+EXTERN int constrparms; /* constrained parameters flag (MPEG-1 only) */
+EXTERN int load_iquant, load_niquant; /* use non-default quant. matrices */
+EXTERN int load_ciquant,load_cniquant;
+
+
+/* sequence specific data (sequence extension) */
+
+EXTERN int profile, level; /* syntax / parameter constraints */
+EXTERN int prog_seq; /* progressive sequence */
+EXTERN int chroma_format;
+EXTERN int low_delay; /* no B pictures, skipped pictures */
+
+
+/* sequence specific data (sequence display extension) */
+
+EXTERN int video_format; /* component, PAL, NTSC, SECAM or MAC */
+EXTERN int color_primaries; /* source primary chromaticity coordinates */
+EXTERN int transfer_characteristics; /* opto-electronic transfer char. (gamma) */
+EXTERN int matrix_coefficients; /* Eg,Eb,Er / Y,Cb,Cr matrix coefficients */
+EXTERN int display_horizontal_size, display_vertical_size; /* display size */
+
+
+/* picture specific data (picture header) */
+
+EXTERN int temp_ref; /* temporal reference */
+EXTERN int pict_type; /* picture coding type (I, P or B) */
+EXTERN int vbv_delay; /* video buffering verifier delay (1/90000 seconds) */
+
+
+/* picture specific data (picture coding extension) */
+
+EXTERN int forw_hor_f_code, forw_vert_f_code;
+EXTERN int back_hor_f_code, back_vert_f_code; /* motion vector ranges */
+EXTERN int dc_prec; /* DC coefficient precision for intra coded blocks */
+EXTERN int pict_struct; /* picture structure (frame, top / bottom field) */
+EXTERN int topfirst; /* display top field first */
+/* use only frame prediction and frame DCT (I,P,B,current) */
+EXTERN int frame_pred_dct_tab[3], frame_pred_dct;
+EXTERN int conceal_tab[3]; /* use concealment motion vectors (I,P,B) */
+EXTERN int qscale_tab[3], q_scale_type; /* linear/non-linear quantizaton table */
+EXTERN int intravlc_tab[3], intravlc; /* intra vlc format (I,P,B,current) */
+EXTERN int altscan_tab[3], altscan; /* alternate scan (I,P,B,current) */
+EXTERN int repeatfirst; /* repeat first field after second field */
+EXTERN int prog_frame; /* progressive frame */
diff --git a/src/gdcmmpeg2/src/mpeg2enc/idct.c b/src/gdcmmpeg2/src/mpeg2enc/idct.c
new file mode 100644 (file)
index 0000000..5602ad3
--- /dev/null
@@ -0,0 +1,211 @@
+/* idct.c, inverse fast discrete cosine transform                           */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+/**********************************************************/
+/* inverse two dimensional DCT, Chen-Wang algorithm       */
+/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984)             */
+/* 32-bit integer arithmetic (8 bit coefficients)         */
+/* 11 mults, 29 adds per DCT                              */
+/*                                      sE, 18.8.91       */
+/**********************************************************/
+/* coefficients extended to 12 bit for IEEE1180-1990      */
+/* compliance                           sE,  2.1.94       */
+/**********************************************************/
+
+/* this code assumes >> to be a two's-complement arithmetic */
+/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2               */
+
+#include "config.h"
+
+#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
+#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
+#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
+#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
+#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
+#define W7 565  /* 2048*sqrt(2)*cos(7*pi/16) */
+
+/* global declarations */
+void init_idct _ANSI_ARGS_((void));
+void idct _ANSI_ARGS_((short *block));
+
+/* private data */
+static short iclip[1024]; /* clipping table */
+static short *iclp;
+
+/* private prototypes */
+static void idctrow _ANSI_ARGS_((short *blk));
+static void idctcol _ANSI_ARGS_((short *blk));
+
+/* row (horizontal) IDCT
+ *
+ *           7                       pi         1
+ * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
+ *          l=0                      8          2
+ *
+ * where: c[0]    = 128
+ *        c[1..7] = 128*sqrt(2)
+ */
+
+static void idctrow(blk)
+short *blk;
+{
+  int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+  /* shortcut */
+  if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
+        (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
+  {
+    blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
+    return;
+  }
+
+  x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
+
+  /* first stage */
+  x8 = W7*(x4+x5);
+  x4 = x8 + (W1-W7)*x4;
+  x5 = x8 - (W1+W7)*x5;
+  x8 = W3*(x6+x7);
+  x6 = x8 - (W3-W5)*x6;
+  x7 = x8 - (W3+W5)*x7;
+  
+  /* second stage */
+  x8 = x0 + x1;
+  x0 -= x1;
+  x1 = W6*(x3+x2);
+  x2 = x1 - (W2+W6)*x2;
+  x3 = x1 + (W2-W6)*x3;
+  x1 = x4 + x6;
+  x4 -= x6;
+  x6 = x5 + x7;
+  x5 -= x7;
+  
+  /* third stage */
+  x7 = x8 + x3;
+  x8 -= x3;
+  x3 = x0 + x2;
+  x0 -= x2;
+  x2 = (181*(x4+x5)+128)>>8;
+  x4 = (181*(x4-x5)+128)>>8;
+  
+  /* fourth stage */
+  blk[0] = (x7+x1)>>8;
+  blk[1] = (x3+x2)>>8;
+  blk[2] = (x0+x4)>>8;
+  blk[3] = (x8+x6)>>8;
+  blk[4] = (x8-x6)>>8;
+  blk[5] = (x0-x4)>>8;
+  blk[6] = (x3-x2)>>8;
+  blk[7] = (x7-x1)>>8;
+}
+
+/* column (vertical) IDCT
+ *
+ *             7                         pi         1
+ * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
+ *            l=0                        8          2
+ *
+ * where: c[0]    = 1/1024
+ *        c[1..7] = (1/1024)*sqrt(2)
+ */
+static void idctcol(blk)
+short *blk;
+{
+  int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+  /* shortcut */
+  if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
+        (x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
+  {
+    blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
+      iclp[(blk[8*0]+32)>>6];
+    return;
+  }
+
+  x0 = (blk[8*0]<<8) + 8192;
+
+  /* first stage */
+  x8 = W7*(x4+x5) + 4;
+  x4 = (x8+(W1-W7)*x4)>>3;
+  x5 = (x8-(W1+W7)*x5)>>3;
+  x8 = W3*(x6+x7) + 4;
+  x6 = (x8-(W3-W5)*x6)>>3;
+  x7 = (x8-(W3+W5)*x7)>>3;
+  
+  /* second stage */
+  x8 = x0 + x1;
+  x0 -= x1;
+  x1 = W6*(x3+x2) + 4;
+  x2 = (x1-(W2+W6)*x2)>>3;
+  x3 = (x1+(W2-W6)*x3)>>3;
+  x1 = x4 + x6;
+  x4 -= x6;
+  x6 = x5 + x7;
+  x5 -= x7;
+  
+  /* third stage */
+  x7 = x8 + x3;
+  x8 -= x3;
+  x3 = x0 + x2;
+  x0 -= x2;
+  x2 = (181*(x4+x5)+128)>>8;
+  x4 = (181*(x4-x5)+128)>>8;
+  
+  /* fourth stage */
+  blk[8*0] = iclp[(x7+x1)>>14];
+  blk[8*1] = iclp[(x3+x2)>>14];
+  blk[8*2] = iclp[(x0+x4)>>14];
+  blk[8*3] = iclp[(x8+x6)>>14];
+  blk[8*4] = iclp[(x8-x6)>>14];
+  blk[8*5] = iclp[(x0-x4)>>14];
+  blk[8*6] = iclp[(x3-x2)>>14];
+  blk[8*7] = iclp[(x7-x1)>>14];
+}
+
+/* two dimensional inverse discrete cosine transform */
+void idct(block)
+short *block;
+{
+  int i;
+
+  for (i=0; i<8; i++)
+    idctrow(block+8*i);
+
+  for (i=0; i<8; i++)
+    idctcol(block+i);
+}
+
+void init_idct()
+{
+  int i;
+
+  iclp = iclip+512;
+  for (i= -512; i<512; i++)
+    iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/motion.c b/src/gdcmmpeg2/src/mpeg2enc/motion.c
new file mode 100644 (file)
index 0000000..30d0a30
--- /dev/null
@@ -0,0 +1,1644 @@
+/* motion.c, motion estimation                                              */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+
+static void frame_ME _ANSI_ARGS_((unsigned char *oldorg, unsigned char *neworg,
+  unsigned char *oldref, unsigned char *newref, unsigned char *cur,
+  int i, int j, int sxf, int syf, int sxb, int syb, struct mbinfo *mbi));
+
+static void field_ME _ANSI_ARGS_((unsigned char *oldorg, unsigned char *neworg,
+  unsigned char *oldref, unsigned char *newref, unsigned char *cur,
+  unsigned char *curref, int i, int j, int sxf, int syf, int sxb, int syb,
+  struct mbinfo *mbi, int secondfield, int ipflag));
+
+static void frame_estimate _ANSI_ARGS_((unsigned char *org,
+  unsigned char *ref, unsigned char *mb,
+  int i, int j,
+  int sx, int sy, int *iminp, int *jminp, int *imintp, int *jmintp,
+  int *iminbp, int *jminbp, int *dframep, int *dfieldp,
+  int *tselp, int *bselp, int imins[2][2], int jmins[2][2]));
+
+static void field_estimate _ANSI_ARGS_((unsigned char *toporg,
+  unsigned char *topref, unsigned char *botorg, unsigned char *botref,
+  unsigned char *mb, int i, int j, int sx, int sy, int ipflag,
+  int *iminp, int *jminp, int *imin8up, int *jmin8up, int *imin8lp,
+  int *jmin8lp, int *dfieldp, int *d8p, int *selp, int *sel8up, int *sel8lp,
+  int *iminsp, int *jminsp, int *dsp));
+
+static void dpframe_estimate _ANSI_ARGS_((unsigned char *ref,
+  unsigned char *mb, int i, int j, int iminf[2][2], int jminf[2][2],
+  int *iminp, int *jminp, int *imindmvp, int *jmindmvp,
+  int *dmcp, int *vmcp));
+
+static void dpfield_estimate _ANSI_ARGS_((unsigned char *topref,
+  unsigned char *botref, unsigned char *mb,
+  int i, int j, int imins, int jmins, int *imindmvp, int *jmindmvp,
+  int *dmcp, int *vmcp));
+
+static int fullsearch _ANSI_ARGS_((unsigned char *org, unsigned char *ref,
+  unsigned char *blk,
+  int lx, int i0, int j0, int sx, int sy, int h, int xmax, int ymax,
+  int *iminp, int *jminp));
+
+static int dist1 _ANSI_ARGS_((unsigned char *blk1, unsigned char *blk2,
+  int lx, int hx, int hy, int h, int distlim));
+
+static int dist2 _ANSI_ARGS_((unsigned char *blk1, unsigned char *blk2,
+  int lx, int hx, int hy, int h));
+
+static int bdist1 _ANSI_ARGS_((unsigned char *pf, unsigned char *pb,
+  unsigned char *p2, int lx, int hxf, int hyf, int hxb, int hyb, int h));
+
+static int bdist2 _ANSI_ARGS_((unsigned char *pf, unsigned char *pb,
+  unsigned char *p2, int lx, int hxf, int hyf, int hxb, int hyb, int h));
+
+static int variance _ANSI_ARGS_((unsigned char *p, int lx));
+
+/*
+ * motion estimation for progressive and interlaced frame pictures
+ *
+ * oldorg: source frame for forward prediction (used for P and B frames)
+ * neworg: source frame for backward prediction (B frames only)
+ * oldref: reconstructed frame for forward prediction (P and B frames)
+ * newref: reconstructed frame for backward prediction (B frames only)
+ * cur:    current frame (the one for which the prediction is formed)
+ * sxf,syf: forward search window (frame coordinates)
+ * sxb,syb: backward search window (frame coordinates)
+ * mbi:    pointer to macroblock info structure
+ *
+ * results:
+ * mbi->
+ *  mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD
+ *  MV[][][]: motion vectors (frame format)
+ *  mv_field_sel: top/bottom field (for field prediction)
+ *  motion_type: MC_FRAME, MC_FIELD
+ *
+ * uses global vars: pict_type, frame_pred_dct
+ */
+void motion_estimation(oldorg,neworg,oldref,newref,cur,curref,
+  sxf,syf,sxb,syb,mbi,secondfield,ipflag)
+unsigned char *oldorg,*neworg,*oldref,*newref,*cur,*curref;
+int sxf,syf,sxb,syb;
+struct mbinfo *mbi;
+int secondfield,ipflag;
+{
+  int i, j;
+
+  /* loop through all macroblocks of the picture */
+  for (j=0; j<height2; j+=16)
+  {
+    for (i=0; i<width; i+=16)
+    {
+      if (pict_struct==FRAME_PICTURE)
+        frame_ME(oldorg,neworg,oldref,newref,cur,i,j,sxf,syf,sxb,syb,mbi);
+      else
+        field_ME(oldorg,neworg,oldref,newref,cur,curref,i,j,sxf,syf,sxb,syb,
+          mbi,secondfield,ipflag);
+      mbi++;
+    }
+
+    if (!quiet)
+    {
+      putc('.',stderr);
+      fflush(stderr);
+    }
+  }
+  if (!quiet)
+    putc('\n',stderr);
+}
+
+static void frame_ME(oldorg,neworg,oldref,newref,cur,i,j,sxf,syf,sxb,syb,mbi)
+unsigned char *oldorg,*neworg,*oldref,*newref,*cur;
+int i,j,sxf,syf,sxb,syb;
+struct mbinfo *mbi;
+{
+  int imin,jmin,iminf,jminf,iminr,jminr;
+  int imint,jmint,iminb,jminb;
+  int imintf,jmintf,iminbf,jminbf;
+  int imintr,jmintr,iminbr,jminbr;
+  int var,v0;
+  int dmc,dmcf,dmcr,dmci,vmc,vmcf,vmcr,vmci;
+  int dmcfield,dmcfieldf,dmcfieldr,dmcfieldi;
+  int tsel,bsel,tself,bself,tselr,bselr;
+  unsigned char *mb;
+  int imins[2][2],jmins[2][2];
+  int imindp,jmindp,imindmv,jmindmv,dmc_dp,vmc_dp;
+
+  mb = cur + i + width*j;
+
+  var = variance(mb,width);
+
+  if (pict_type==I_TYPE)
+    mbi->mb_type = MB_INTRA;
+  else if (pict_type==P_TYPE)
+  {
+    if (frame_pred_dct)
+    {
+      dmc = fullsearch(oldorg,oldref,mb,
+                       width,i,j,sxf,syf,16,width,height,&imin,&jmin);
+      vmc = dist2(oldref+(imin>>1)+width*(jmin>>1),mb,
+                  width,imin&1,jmin&1,16);
+      mbi->motion_type = MC_FRAME;
+    }
+    else
+    {
+      frame_estimate(oldorg,oldref,mb,i,j,sxf,syf,
+        &imin,&jmin,&imint,&jmint,&iminb,&jminb,
+        &dmc,&dmcfield,&tsel,&bsel,imins,jmins);
+
+      if (M==1)
+        dpframe_estimate(oldref,mb,i,j>>1,imins,jmins,
+          &imindp,&jmindp,&imindmv,&jmindmv,&dmc_dp,&vmc_dp);
+
+      /* select between dual prime, frame and field prediction */
+      if (M==1 && dmc_dp<dmc && dmc_dp<dmcfield)
+      {
+        mbi->motion_type = MC_DMV;
+        dmc = dmc_dp;
+        vmc = vmc_dp;
+      }
+      else if (dmc<=dmcfield)
+      {
+        mbi->motion_type = MC_FRAME;
+        vmc = dist2(oldref+(imin>>1)+width*(jmin>>1),mb,
+                    width,imin&1,jmin&1,16);
+      }
+      else
+      {
+        mbi->motion_type = MC_FIELD;
+        dmc = dmcfield;
+        vmc = dist2(oldref+(tsel?width:0)+(imint>>1)+(width<<1)*(jmint>>1),
+                    mb,width<<1,imint&1,jmint&1,8);
+        vmc+= dist2(oldref+(bsel?width:0)+(iminb>>1)+(width<<1)*(jminb>>1),
+                    mb+width,width<<1,iminb&1,jminb&1,8);
+      }
+    }
+
+    /* select between intra or non-intra coding:
+     *
+     * selection is based on intra block variance (var) vs.
+     * prediction error variance (vmc)
+     *
+     * blocks with small prediction error are always coded non-intra
+     * even if variance is smaller (is this reasonable?)
+     */
+    if (vmc>var && vmc>=9*256)
+      mbi->mb_type = MB_INTRA;
+    else
+    {
+      /* select between MC / No-MC
+       *
+       * use No-MC if var(No-MC) <= 1.25*var(MC)
+       * (i.e slightly biased towards No-MC)
+       *
+       * blocks with small prediction error are always coded as No-MC
+       * (requires no motion vectors, allows skipping)
+       */
+      v0 = dist2(oldref+i+width*j,mb,width,0,0,16);
+      if (4*v0>5*vmc && v0>=9*256)
+      {
+        /* use MC */
+        var = vmc;
+        mbi->mb_type = MB_FORWARD;
+        if (mbi->motion_type==MC_FRAME)
+        {
+          mbi->MV[0][0][0] = imin - (i<<1);
+          mbi->MV[0][0][1] = jmin - (j<<1);
+        }
+        else if (mbi->motion_type==MC_DMV)
+        {
+          /* these are FRAME vectors */
+          /* same parity vector */
+          mbi->MV[0][0][0] = imindp - (i<<1);
+          mbi->MV[0][0][1] = (jmindp<<1) - (j<<1);
+
+          /* opposite parity vector */
+          mbi->dmvector[0] = imindmv;
+          mbi->dmvector[1] = jmindmv;
+        }
+        else
+        {
+          /* these are FRAME vectors */
+          mbi->MV[0][0][0] = imint - (i<<1);
+          mbi->MV[0][0][1] = (jmint<<1) - (j<<1);
+          mbi->MV[1][0][0] = iminb - (i<<1);
+          mbi->MV[1][0][1] = (jminb<<1) - (j<<1);
+          mbi->mv_field_sel[0][0] = tsel;
+          mbi->mv_field_sel[1][0] = bsel;
+        }
+      }
+      else
+      {
+        /* No-MC */
+        var = v0;
+        mbi->mb_type = 0;
+        mbi->motion_type = MC_FRAME;
+        mbi->MV[0][0][0] = 0;
+        mbi->MV[0][0][1] = 0;
+      }
+    }
+  }
+  else /* if (pict_type==B_TYPE) */
+  {
+    if (frame_pred_dct)
+    {
+      /* forward */
+      dmcf = fullsearch(oldorg,oldref,mb,
+                        width,i,j,sxf,syf,16,width,height,&iminf,&jminf);
+      vmcf = dist2(oldref+(iminf>>1)+width*(jminf>>1),mb,
+                   width,iminf&1,jminf&1,16);
+
+      /* backward */
+      dmcr = fullsearch(neworg,newref,mb,
+                        width,i,j,sxb,syb,16,width,height,&iminr,&jminr);
+      vmcr = dist2(newref+(iminr>>1)+width*(jminr>>1),mb,
+                   width,iminr&1,jminr&1,16);
+
+      /* interpolated (bidirectional) */
+      vmci = bdist2(oldref+(iminf>>1)+width*(jminf>>1),
+                    newref+(iminr>>1)+width*(jminr>>1),
+                    mb,width,iminf&1,jminf&1,iminr&1,jminr&1,16);
+
+      /* decisions */
+
+      /* select between forward/backward/interpolated prediction:
+       * use the one with smallest mean sqaured prediction error
+       */
+      if (vmcf<=vmcr && vmcf<=vmci)
+      {
+        vmc = vmcf;
+        mbi->mb_type = MB_FORWARD;
+      }
+      else if (vmcr<=vmci)
+      {
+        vmc = vmcr;
+        mbi->mb_type = MB_BACKWARD;
+      }
+      else
+      {
+        vmc = vmci;
+        mbi->mb_type = MB_FORWARD|MB_BACKWARD;
+      }
+
+      mbi->motion_type = MC_FRAME;
+    }
+    else
+    {
+      /* forward prediction */
+      frame_estimate(oldorg,oldref,mb,i,j,sxf,syf,
+        &iminf,&jminf,&imintf,&jmintf,&iminbf,&jminbf,
+        &dmcf,&dmcfieldf,&tself,&bself,imins,jmins);
+
+      /* backward prediction */
+      frame_estimate(neworg,newref,mb,i,j,sxb,syb,
+        &iminr,&jminr,&imintr,&jmintr,&iminbr,&jminbr,
+        &dmcr,&dmcfieldr,&tselr,&bselr,imins,jmins);
+
+      /* calculate interpolated distance */
+      /* frame */
+      dmci = bdist1(oldref+(iminf>>1)+width*(jminf>>1),
+                    newref+(iminr>>1)+width*(jminr>>1),
+                    mb,width,iminf&1,jminf&1,iminr&1,jminr&1,16);
+
+      /* top field */
+      dmcfieldi = bdist1(
+                    oldref+(imintf>>1)+(tself?width:0)+(width<<1)*(jmintf>>1),
+                    newref+(imintr>>1)+(tselr?width:0)+(width<<1)*(jmintr>>1),
+                    mb,width<<1,imintf&1,jmintf&1,imintr&1,jmintr&1,8);
+
+      /* bottom field */
+      dmcfieldi+= bdist1(
+                    oldref+(iminbf>>1)+(bself?width:0)+(width<<1)*(jminbf>>1),
+                    newref+(iminbr>>1)+(bselr?width:0)+(width<<1)*(jminbr>>1),
+                    mb+width,width<<1,iminbf&1,jminbf&1,iminbr&1,jminbr&1,8);
+
+      /* select prediction type of minimum distance from the
+       * six candidates (field/frame * forward/backward/interpolated)
+       */
+      if (dmci<dmcfieldi && dmci<dmcf && dmci<dmcfieldf
+          && dmci<dmcr && dmci<dmcfieldr)
+      {
+        /* frame, interpolated */
+        mbi->mb_type = MB_FORWARD|MB_BACKWARD;
+        mbi->motion_type = MC_FRAME;
+        vmc = bdist2(oldref+(iminf>>1)+width*(jminf>>1),
+                     newref+(iminr>>1)+width*(jminr>>1),
+                     mb,width,iminf&1,jminf&1,iminr&1,jminr&1,16);
+      }
+      else if (dmcfieldi<dmcf && dmcfieldi<dmcfieldf
+               && dmcfieldi<dmcr && dmcfieldi<dmcfieldr)
+      {
+        /* field, interpolated */
+        mbi->mb_type = MB_FORWARD|MB_BACKWARD;
+        mbi->motion_type = MC_FIELD;
+        vmc = bdist2(oldref+(imintf>>1)+(tself?width:0)+(width<<1)*(jmintf>>1),
+                     newref+(imintr>>1)+(tselr?width:0)+(width<<1)*(jmintr>>1),
+                     mb,width<<1,imintf&1,jmintf&1,imintr&1,jmintr&1,8);
+        vmc+= bdist2(oldref+(iminbf>>1)+(bself?width:0)+(width<<1)*(jminbf>>1),
+                     newref+(iminbr>>1)+(bselr?width:0)+(width<<1)*(jminbr>>1),
+                     mb+width,width<<1,iminbf&1,jminbf&1,iminbr&1,jminbr&1,8);
+      }
+      else if (dmcf<dmcfieldf && dmcf<dmcr && dmcf<dmcfieldr)
+      {
+        /* frame, forward */
+        mbi->mb_type = MB_FORWARD;
+        mbi->motion_type = MC_FRAME;
+        vmc = dist2(oldref+(iminf>>1)+width*(jminf>>1),mb,
+                    width,iminf&1,jminf&1,16);
+      }
+      else if (dmcfieldf<dmcr && dmcfieldf<dmcfieldr)
+      {
+        /* field, forward */
+        mbi->mb_type = MB_FORWARD;
+        mbi->motion_type = MC_FIELD;
+        vmc = dist2(oldref+(tself?width:0)+(imintf>>1)+(width<<1)*(jmintf>>1),
+                    mb,width<<1,imintf&1,jmintf&1,8);
+        vmc+= dist2(oldref+(bself?width:0)+(iminbf>>1)+(width<<1)*(jminbf>>1),
+                    mb+width,width<<1,iminbf&1,jminbf&1,8);
+      }
+      else if (dmcr<dmcfieldr)
+      {
+        /* frame, backward */
+        mbi->mb_type = MB_BACKWARD;
+        mbi->motion_type = MC_FRAME;
+        vmc = dist2(newref+(iminr>>1)+width*(jminr>>1),mb,
+                    width,iminr&1,jminr&1,16);
+      }
+      else
+      {
+        /* field, backward */
+        mbi->mb_type = MB_BACKWARD;
+        mbi->motion_type = MC_FIELD;
+        vmc = dist2(newref+(tselr?width:0)+(imintr>>1)+(width<<1)*(jmintr>>1),
+                    mb,width<<1,imintr&1,jmintr&1,8);
+        vmc+= dist2(newref+(bselr?width:0)+(iminbr>>1)+(width<<1)*(jminbr>>1),
+                    mb+width,width<<1,iminbr&1,jminbr&1,8);
+      }
+    }
+
+    /* select between intra or non-intra coding:
+     *
+     * selection is based on intra block variance (var) vs.
+     * prediction error variance (vmc)
+     *
+     * blocks with small prediction error are always coded non-intra
+     * even if variance is smaller (is this reasonable?)
+     */
+    if (vmc>var && vmc>=9*256)
+      mbi->mb_type = MB_INTRA;
+    else
+    {
+      var = vmc;
+      if (mbi->motion_type==MC_FRAME)
+      {
+        /* forward */
+        mbi->MV[0][0][0] = iminf - (i<<1);
+        mbi->MV[0][0][1] = jminf - (j<<1);
+        /* backward */
+        mbi->MV[0][1][0] = iminr - (i<<1);
+        mbi->MV[0][1][1] = jminr - (j<<1);
+      }
+      else
+      {
+        /* these are FRAME vectors */
+        /* forward */
+        mbi->MV[0][0][0] = imintf - (i<<1);
+        mbi->MV[0][0][1] = (jmintf<<1) - (j<<1);
+        mbi->MV[1][0][0] = iminbf - (i<<1);
+        mbi->MV[1][0][1] = (jminbf<<1) - (j<<1);
+        mbi->mv_field_sel[0][0] = tself;
+        mbi->mv_field_sel[1][0] = bself;
+        /* backward */
+        mbi->MV[0][1][0] = imintr - (i<<1);
+        mbi->MV[0][1][1] = (jmintr<<1) - (j<<1);
+        mbi->MV[1][1][0] = iminbr - (i<<1);
+        mbi->MV[1][1][1] = (jminbr<<1) - (j<<1);
+        mbi->mv_field_sel[0][1] = tselr;
+        mbi->mv_field_sel[1][1] = bselr;
+      }
+    }
+  }
+
+  mbi->var = var;
+}
+
+/*
+ * motion estimation for field pictures
+ *
+ * oldorg: original frame for forward prediction (P and B frames)
+ * neworg: original frame for backward prediction (B frames only)
+ * oldref: reconstructed frame for forward prediction (P and B frames)
+ * newref: reconstructed frame for backward prediction (B frames only)
+ * cur:    current original frame (the one for which the prediction is formed)
+ * curref: current reconstructed frame (to predict second field from first)
+ * sxf,syf: forward search window (frame coordinates)
+ * sxb,syb: backward search window (frame coordinates)
+ * mbi:    pointer to macroblock info structure
+ * secondfield: indicates second field of a frame (in P fields this means
+ *              that reference field of opposite parity is in curref instead
+ *              of oldref)
+ * ipflag: indicates a P type field which is the second field of a frame
+ *         in which the first field is I type (this restricts predictions
+ *         to be based only on the opposite parity (=I) field)
+ *
+ * results:
+ * mbi->
+ *  mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD
+ *  MV[][][]: motion vectors (field format)
+ *  mv_field_sel: top/bottom field
+ *  motion_type: MC_FIELD, MC_16X8
+ *
+ * uses global vars: pict_type, pict_struct
+ */
+static void field_ME(oldorg,neworg,oldref,newref,cur,curref,i,j,
+  sxf,syf,sxb,syb,mbi,secondfield,ipflag)
+unsigned char *oldorg,*neworg,*oldref,*newref,*cur,*curref;
+int i,j,sxf,syf,sxb,syb;
+struct mbinfo *mbi;
+int secondfield,ipflag;
+{
+  int w2;
+  unsigned char *mb, *toporg, *topref, *botorg, *botref;
+  int var,vmc,v0,dmc,dmcfieldi,dmc8i;
+  int imin,jmin,imin8u,jmin8u,imin8l,jmin8l,dmcfield,dmc8,sel,sel8u,sel8l;
+  int iminf,jminf,imin8uf,jmin8uf,imin8lf,jmin8lf,dmcfieldf,dmc8f,self,sel8uf,sel8lf;
+  int iminr,jminr,imin8ur,jmin8ur,imin8lr,jmin8lr,dmcfieldr,dmc8r,selr,sel8ur,sel8lr;
+  int imins,jmins,ds,imindmv,jmindmv,vmc_dp,dmc_dp;
+
+  w2 = width<<1;
+
+  mb = cur + i + w2*j;
+  if (pict_struct==BOTTOM_FIELD)
+    mb += width;
+
+  var = variance(mb,w2);
+
+  if (pict_type==I_TYPE)
+    mbi->mb_type = MB_INTRA;
+  else if (pict_type==P_TYPE)
+  {
+    toporg = oldorg;
+    topref = oldref;
+    botorg = oldorg + width;
+    botref = oldref + width;
+
+    if (secondfield)
+    {
+      /* opposite parity field is in same frame */
+      if (pict_struct==TOP_FIELD)
+      {
+        /* current is top field */
+        botorg = cur + width;
+        botref = curref + width;
+      }
+      else
+      {
+        /* current is bottom field */
+        toporg = cur;
+        topref = curref;
+      }
+    }
+
+    field_estimate(toporg,topref,botorg,botref,mb,i,j,sxf,syf,ipflag,
+                   &imin,&jmin,&imin8u,&jmin8u,&imin8l,&jmin8l,
+                   &dmcfield,&dmc8,&sel,&sel8u,&sel8l,&imins,&jmins,&ds);
+
+    if (M==1 && !ipflag)  /* generic condition which permits Dual Prime */
+      dpfield_estimate(topref,botref,mb,i,j,imins,jmins,&imindmv,&jmindmv,
+        &dmc_dp,&vmc_dp);
+
+    /* select between dual prime, field and 16x8 prediction */
+    if (M==1 && !ipflag && dmc_dp<dmc8 && dmc_dp<dmcfield)
+    {
+      /* Dual Prime prediction */
+      mbi->motion_type = MC_DMV;
+      dmc = dmc_dp;     /* L1 metric */
+      vmc = vmc_dp;     /* we already calculated L2 error for Dual */
+
+    }
+    else if (dmc8<dmcfield)
+    {
+      /* 16x8 prediction */
+      mbi->motion_type = MC_16X8;
+      /* upper half block */
+      vmc = dist2((sel8u?botref:topref) + (imin8u>>1) + w2*(jmin8u>>1),
+                  mb,w2,imin8u&1,jmin8u&1,8);
+      /* lower half block */
+      vmc+= dist2((sel8l?botref:topref) + (imin8l>>1) + w2*(jmin8l>>1),
+                  mb+8*w2,w2,imin8l&1,jmin8l&1,8);
+    }
+    else
+    {
+      /* field prediction */
+      mbi->motion_type = MC_FIELD;
+      vmc = dist2((sel?botref:topref) + (imin>>1) + w2*(jmin>>1),
+                  mb,w2,imin&1,jmin&1,16);
+    }
+
+    /* select between intra and non-intra coding */
+    if (vmc>var && vmc>=9*256)
+      mbi->mb_type = MB_INTRA;
+    else
+    {
+      /* zero MV field prediction from same parity ref. field
+       * (not allowed if ipflag is set)
+       */
+      if (!ipflag)
+        v0 = dist2(((pict_struct==BOTTOM_FIELD)?botref:topref) + i + w2*j,
+                   mb,w2,0,0,16);
+      if (ipflag || (4*v0>5*vmc && v0>=9*256))
+      {
+        var = vmc;
+        mbi->mb_type = MB_FORWARD;
+        if (mbi->motion_type==MC_FIELD)
+        {
+          mbi->MV[0][0][0] = imin - (i<<1);
+          mbi->MV[0][0][1] = jmin - (j<<1);
+          mbi->mv_field_sel[0][0] = sel;
+        }
+        else if (mbi->motion_type==MC_DMV)
+        {
+          /* same parity vector */
+          mbi->MV[0][0][0] = imins - (i<<1);
+          mbi->MV[0][0][1] = jmins - (j<<1);
+
+          /* opposite parity vector */
+          mbi->dmvector[0] = imindmv;
+          mbi->dmvector[1] = jmindmv;
+        }
+        else
+        {
+          mbi->MV[0][0][0] = imin8u - (i<<1);
+          mbi->MV[0][0][1] = jmin8u - (j<<1);
+          mbi->MV[1][0][0] = imin8l - (i<<1);
+          mbi->MV[1][0][1] = jmin8l - ((j+8)<<1);
+          mbi->mv_field_sel[0][0] = sel8u;
+          mbi->mv_field_sel[1][0] = sel8l;
+        }
+      }
+      else
+      {
+        /* No MC */
+        var = v0;
+        mbi->mb_type = 0;
+        mbi->motion_type = MC_FIELD;
+        mbi->MV[0][0][0] = 0;
+        mbi->MV[0][0][1] = 0;
+        mbi->mv_field_sel[0][0] = (pict_struct==BOTTOM_FIELD);
+      }
+    }
+  }
+  else /* if (pict_type==B_TYPE) */
+  {
+    /* forward prediction */
+    field_estimate(oldorg,oldref,oldorg+width,oldref+width,mb,
+                   i,j,sxf,syf,0,
+                   &iminf,&jminf,&imin8uf,&jmin8uf,&imin8lf,&jmin8lf,
+                   &dmcfieldf,&dmc8f,&self,&sel8uf,&sel8lf,&imins,&jmins,&ds);
+
+    /* backward prediction */
+    field_estimate(neworg,newref,neworg+width,newref+width,mb,
+                   i,j,sxb,syb,0,
+                   &iminr,&jminr,&imin8ur,&jmin8ur,&imin8lr,&jmin8lr,
+                   &dmcfieldr,&dmc8r,&selr,&sel8ur,&sel8lr,&imins,&jmins,&ds);
+
+    /* calculate distances for bidirectional prediction */
+    /* field */
+    dmcfieldi = bdist1(oldref + (self?width:0) + (iminf>>1) + w2*(jminf>>1),
+                       newref + (selr?width:0) + (iminr>>1) + w2*(jminr>>1),
+                       mb,w2,iminf&1,jminf&1,iminr&1,jminr&1,16);
+
+    /* 16x8 upper half block */
+    dmc8i = bdist1(oldref + (sel8uf?width:0) + (imin8uf>>1) + w2*(jmin8uf>>1),
+                   newref + (sel8ur?width:0) + (imin8ur>>1) + w2*(jmin8ur>>1),
+                   mb,w2,imin8uf&1,jmin8uf&1,imin8ur&1,jmin8ur&1,8);
+
+    /* 16x8 lower half block */
+    dmc8i+= bdist1(oldref + (sel8lf?width:0) + (imin8lf>>1) + w2*(jmin8lf>>1),
+                   newref + (sel8lr?width:0) + (imin8lr>>1) + w2*(jmin8lr>>1),
+                   mb+8*w2,w2,imin8lf&1,jmin8lf&1,imin8lr&1,jmin8lr&1,8);
+
+    /* select prediction type of minimum distance */
+    if (dmcfieldi<dmc8i && dmcfieldi<dmcfieldf && dmcfieldi<dmc8f
+        && dmcfieldi<dmcfieldr && dmcfieldi<dmc8r)
+    {
+      /* field, interpolated */
+      mbi->mb_type = MB_FORWARD|MB_BACKWARD;
+      mbi->motion_type = MC_FIELD;
+      vmc = bdist2(oldref + (self?width:0) + (iminf>>1) + w2*(jminf>>1),
+                   newref + (selr?width:0) + (iminr>>1) + w2*(jminr>>1),
+                   mb,w2,iminf&1,jminf&1,iminr&1,jminr&1,16);
+    }
+    else if (dmc8i<dmcfieldf && dmc8i<dmc8f
+             && dmc8i<dmcfieldr && dmc8i<dmc8r)
+    {
+      /* 16x8, interpolated */
+      mbi->mb_type = MB_FORWARD|MB_BACKWARD;
+      mbi->motion_type = MC_16X8;
+
+      /* upper half block */
+      vmc = bdist2(oldref + (sel8uf?width:0) + (imin8uf>>1) + w2*(jmin8uf>>1),
+                   newref + (sel8ur?width:0) + (imin8ur>>1) + w2*(jmin8ur>>1),
+                   mb,w2,imin8uf&1,jmin8uf&1,imin8ur&1,jmin8ur&1,8);
+
+      /* lower half block */
+      vmc+= bdist2(oldref + (sel8lf?width:0) + (imin8lf>>1) + w2*(jmin8lf>>1),
+                   newref + (sel8lr?width:0) + (imin8lr>>1) + w2*(jmin8lr>>1),
+                   mb+8*w2,w2,imin8lf&1,jmin8lf&1,imin8lr&1,jmin8lr&1,8);
+    }
+    else if (dmcfieldf<dmc8f && dmcfieldf<dmcfieldr && dmcfieldf<dmc8r)
+    {
+      /* field, forward */
+      mbi->mb_type = MB_FORWARD;
+      mbi->motion_type = MC_FIELD;
+      vmc = dist2(oldref + (self?width:0) + (iminf>>1) + w2*(jminf>>1),
+                  mb,w2,iminf&1,jminf&1,16);
+    }
+    else if (dmc8f<dmcfieldr && dmc8f<dmc8r)
+    {
+      /* 16x8, forward */
+      mbi->mb_type = MB_FORWARD;
+      mbi->motion_type = MC_16X8;
+
+      /* upper half block */
+      vmc = dist2(oldref + (sel8uf?width:0) + (imin8uf>>1) + w2*(jmin8uf>>1),
+                  mb,w2,imin8uf&1,jmin8uf&1,8);
+
+      /* lower half block */
+      vmc+= dist2(oldref + (sel8lf?width:0) + (imin8lf>>1) + w2*(jmin8lf>>1),
+                  mb+8*w2,w2,imin8lf&1,jmin8lf&1,8);
+    }
+    else if (dmcfieldr<dmc8r)
+    {
+      /* field, backward */
+      mbi->mb_type = MB_BACKWARD;
+      mbi->motion_type = MC_FIELD;
+      vmc = dist2(newref + (selr?width:0) + (iminr>>1) + w2*(jminr>>1),
+                  mb,w2,iminr&1,jminr&1,16);
+    }
+    else
+    {
+      /* 16x8, backward */
+      mbi->mb_type = MB_BACKWARD;
+      mbi->motion_type = MC_16X8;
+
+      /* upper half block */
+      vmc = dist2(newref + (sel8ur?width:0) + (imin8ur>>1) + w2*(jmin8ur>>1),
+                  mb,w2,imin8ur&1,jmin8ur&1,8);
+
+      /* lower half block */
+      vmc+= dist2(newref + (sel8lr?width:0) + (imin8lr>>1) + w2*(jmin8lr>>1),
+                  mb+8*w2,w2,imin8lr&1,jmin8lr&1,8);
+    }
+
+    /* select between intra and non-intra coding */
+    if (vmc>var && vmc>=9*256)
+      mbi->mb_type = MB_INTRA;
+    else
+    {
+      var = vmc;
+      if (mbi->motion_type==MC_FIELD)
+      {
+        /* forward */
+        mbi->MV[0][0][0] = iminf - (i<<1);
+        mbi->MV[0][0][1] = jminf - (j<<1);
+        mbi->mv_field_sel[0][0] = self;
+        /* backward */
+        mbi->MV[0][1][0] = iminr - (i<<1);
+        mbi->MV[0][1][1] = jminr - (j<<1);
+        mbi->mv_field_sel[0][1] = selr;
+      }
+      else /* MC_16X8 */
+      {
+        /* forward */
+        mbi->MV[0][0][0] = imin8uf - (i<<1);
+        mbi->MV[0][0][1] = jmin8uf - (j<<1);
+        mbi->mv_field_sel[0][0] = sel8uf;
+        mbi->MV[1][0][0] = imin8lf - (i<<1);
+        mbi->MV[1][0][1] = jmin8lf - ((j+8)<<1);
+        mbi->mv_field_sel[1][0] = sel8lf;
+        /* backward */
+        mbi->MV[0][1][0] = imin8ur - (i<<1);
+        mbi->MV[0][1][1] = jmin8ur - (j<<1);
+        mbi->mv_field_sel[0][1] = sel8ur;
+        mbi->MV[1][1][0] = imin8lr - (i<<1);
+        mbi->MV[1][1][1] = jmin8lr - ((j+8)<<1);
+        mbi->mv_field_sel[1][1] = sel8lr;
+      }
+    }
+  }
+
+  mbi->var = var;
+}
+
+/*
+ * frame picture motion estimation
+ *
+ * org: top left pel of source reference frame
+ * ref: top left pel of reconstructed reference frame
+ * mb:  macroblock to be matched
+ * i,j: location of mb relative to ref (=center of search window)
+ * sx,sy: half widths of search window
+ * iminp,jminp,dframep: location and value of best frame prediction
+ * imintp,jmintp,tselp: location of best field pred. for top field of mb
+ * iminbp,jminbp,bselp: location of best field pred. for bottom field of mb
+ * dfieldp: value of field prediction
+ */
+static void frame_estimate(org,ref,mb,i,j,sx,sy,
+  iminp,jminp,imintp,jmintp,iminbp,jminbp,dframep,dfieldp,tselp,bselp,
+  imins,jmins)
+unsigned char *org,*ref,*mb;
+int i,j,sx,sy;
+int *iminp,*jminp;
+int *imintp,*jmintp,*iminbp,*jminbp;
+int *dframep,*dfieldp;
+int *tselp,*bselp;
+int imins[2][2],jmins[2][2];
+{
+  int dt,db,dmint,dminb;
+  int imint,iminb,jmint,jminb;
+
+  /* frame prediction */
+  *dframep = fullsearch(org,ref,mb,width,i,j,sx,sy,16,width,height,
+                        iminp,jminp);
+
+  /* predict top field from top field */
+  dt = fullsearch(org,ref,mb,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1,
+                  &imint,&jmint);
+
+  /* predict top field from bottom field */
+  db = fullsearch(org+width,ref+width,mb,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1,
+                  &iminb,&jminb);
+
+  imins[0][0] = imint;
+  jmins[0][0] = jmint;
+  imins[1][0] = iminb;
+  jmins[1][0] = jminb;
+
+  /* select prediction for top field */
+  if (dt<=db)
+  {
+    dmint=dt; *imintp=imint; *jmintp=jmint; *tselp=0;
+  }
+  else
+  {
+    dmint=db; *imintp=iminb; *jmintp=jminb; *tselp=1;
+  }
+
+  /* predict bottom field from top field */
+  dt = fullsearch(org,ref,mb+width,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1,
+                  &imint,&jmint);
+
+  /* predict bottom field from bottom field */
+  db = fullsearch(org+width,ref+width,mb+width,width<<1,i,j>>1,sx,sy>>1,8,width,height>>1,
+                  &iminb,&jminb);
+
+  imins[0][1] = imint;
+  jmins[0][1] = jmint;
+  imins[1][1] = iminb;
+  jmins[1][1] = jminb;
+
+  /* select prediction for bottom field */
+  if (db<=dt)
+  {
+    dminb=db; *iminbp=iminb; *jminbp=jminb; *bselp=1;
+  }
+  else
+  {
+    dminb=dt; *iminbp=imint; *jminbp=jmint; *bselp=0;
+  }
+
+  *dfieldp=dmint+dminb;
+}
+
+/*
+ * field picture motion estimation subroutine
+ *
+ * toporg: address of original top reference field
+ * topref: address of reconstructed top reference field
+ * botorg: address of original bottom reference field
+ * botref: address of reconstructed bottom reference field
+ * mb:  macroblock to be matched
+ * i,j: location of mb (=center of search window)
+ * sx,sy: half width/height of search window
+ *
+ * iminp,jminp,selp,dfieldp: location and distance of best field prediction
+ * imin8up,jmin8up,sel8up: location of best 16x8 pred. for upper half of mb
+ * imin8lp,jmin8lp,sel8lp: location of best 16x8 pred. for lower half of mb
+ * d8p: distance of best 16x8 prediction
+ * iminsp,jminsp,dsp: location and distance of best same parity field
+ *                    prediction (needed for dual prime, only valid if
+ *                    ipflag==0)
+ */
+static void field_estimate(toporg,topref,botorg,botref,mb,i,j,sx,sy,ipflag,
+  iminp,jminp,imin8up,jmin8up,imin8lp,jmin8lp,dfieldp,d8p,selp,sel8up,sel8lp,
+  iminsp,jminsp,dsp)
+unsigned char *toporg, *topref, *botorg, *botref, *mb;
+int i,j,sx,sy;
+int ipflag;
+int *iminp, *jminp;
+int *imin8up, *jmin8up, *imin8lp, *jmin8lp;
+int *dfieldp,*d8p;
+int *selp, *sel8up, *sel8lp;
+int *iminsp, *jminsp, *dsp;
+{
+  int dt, db, imint, jmint, iminb, jminb, notop, nobot;
+
+  /* if ipflag is set, predict from field of opposite parity only */
+  notop = ipflag && (pict_struct==TOP_FIELD);
+  nobot = ipflag && (pict_struct==BOTTOM_FIELD);
+
+  /* field prediction */
+
+  /* predict current field from top field */
+  if (notop)
+    dt = 65536; /* infinity */
+  else
+    dt = fullsearch(toporg,topref,mb,width<<1,
+                    i,j,sx,sy>>1,16,width,height>>1,
+                    &imint,&jmint);
+
+  /* predict current field from bottom field */
+  if (nobot)
+    db = 65536; /* infinity */
+  else
+    db = fullsearch(botorg,botref,mb,width<<1,
+                    i,j,sx,sy>>1,16,width,height>>1,
+                    &iminb,&jminb);
+
+  /* same parity prediction (only valid if ipflag==0) */
+  if (pict_struct==TOP_FIELD)
+  {
+    *iminsp = imint; *jminsp = jmint; *dsp = dt;
+  }
+  else
+  {
+    *iminsp = iminb; *jminsp = jminb; *dsp = db;
+  }
+
+  /* select field prediction */
+  if (dt<=db)
+  {
+    *dfieldp = dt; *iminp = imint; *jminp = jmint; *selp = 0;
+  }
+  else
+  {
+    *dfieldp = db; *iminp = iminb; *jminp = jminb; *selp = 1;
+  }
+
+
+  /* 16x8 motion compensation */
+
+  /* predict upper half field from top field */
+  if (notop)
+    dt = 65536;
+  else
+    dt = fullsearch(toporg,topref,mb,width<<1,
+                    i,j,sx,sy>>1,8,width,height>>1,
+                    &imint,&jmint);
+
+  /* predict upper half field from bottom field */
+  if (nobot)
+    db = 65536;
+  else
+    db = fullsearch(botorg,botref,mb,width<<1,
+                    i,j,sx,sy>>1,8,width,height>>1,
+                    &iminb,&jminb);
+
+  /* select prediction for upper half field */
+  if (dt<=db)
+  {
+    *d8p = dt; *imin8up = imint; *jmin8up = jmint; *sel8up = 0;
+  }
+  else
+  {
+    *d8p = db; *imin8up = iminb; *jmin8up = jminb; *sel8up = 1;
+  }
+
+  /* predict lower half field from top field */
+  if (notop)
+    dt = 65536;
+  else
+    dt = fullsearch(toporg,topref,mb+(width<<4),width<<1,
+                    i,j+8,sx,sy>>1,8,width,height>>1,
+                    &imint,&jmint);
+
+  /* predict lower half field from bottom field */
+  if (nobot)
+    db = 65536;
+  else
+    db = fullsearch(botorg,botref,mb+(width<<4),width<<1,
+                    i,j+8,sx,sy>>1,8,width,height>>1,
+                    &iminb,&jminb);
+
+  /* select prediction for lower half field */
+  if (dt<=db)
+  {
+    *d8p += dt; *imin8lp = imint; *jmin8lp = jmint; *sel8lp = 0;
+  }
+  else
+  {
+    *d8p += db; *imin8lp = iminb; *jmin8lp = jminb; *sel8lp = 1;
+  }
+}
+
+static void dpframe_estimate(ref,mb,i,j,iminf,jminf,
+  iminp,jminp,imindmvp, jmindmvp, dmcp, vmcp)
+unsigned char *ref, *mb;
+int i,j;
+int iminf[2][2], jminf[2][2];
+int *iminp, *jminp;
+int *imindmvp, *jmindmvp;
+int *dmcp,*vmcp;
+{
+  int pref,ppred,delta_x,delta_y;
+  int is,js,it,jt,ib,jb,it0,jt0,ib0,jb0;
+  int imins,jmins,imint,jmint,iminb,jminb,imindmv,jmindmv;
+  int vmc,local_dist;
+
+  /* Calculate Dual Prime distortions for 9 delta candidates
+   * for each of the four minimum field vectors
+   * Note: only for P pictures!
+   */
+
+  /* initialize minimum dual prime distortion to large value */
+  vmc = 1 << 30;
+
+  for (pref=0; pref<2; pref++)
+  {
+    for (ppred=0; ppred<2; ppred++)
+    {
+      /* convert Cartesian absolute to relative motion vector
+       * values (wrt current macroblock address (i,j)
+       */
+      is = iminf[pref][ppred] - (i<<1);
+      js = jminf[pref][ppred] - (j<<1);
+
+      if (pref!=ppred)
+      {
+        /* vertical field shift adjustment */
+        if (ppred==0)
+          js++;
+        else
+          js--;
+
+        /* mvxs and mvys scaling*/
+        is<<=1;
+        js<<=1;
+        if (topfirst == ppred)
+        {
+          /* second field: scale by 1/3 */
+          is = (is>=0) ? (is+1)/3 : -((-is+1)/3);
+          js = (js>=0) ? (js+1)/3 : -((-js+1)/3);
+        }
+        else
+          continue;
+      }
+
+      /* vector for prediction from field of opposite 'parity' */
+      if (topfirst)
+      {
+        /* vector for prediction of top field from bottom field */
+        it0 = ((is+(is>0))>>1);
+        jt0 = ((js+(js>0))>>1) - 1;
+
+        /* vector for prediction of bottom field from top field */
+        ib0 = ((3*is+(is>0))>>1);
+        jb0 = ((3*js+(js>0))>>1) + 1;
+      }
+      else
+      {
+        /* vector for prediction of top field from bottom field */
+        it0 = ((3*is+(is>0))>>1);
+        jt0 = ((3*js+(js>0))>>1) - 1;
+
+        /* vector for prediction of bottom field from top field */
+        ib0 = ((is+(is>0))>>1);
+        jb0 = ((js+(js>0))>>1) + 1;
+      }
+
+      /* convert back to absolute half-pel field picture coordinates */
+      is += i<<1;
+      js += j<<1;
+      it0 += i<<1;
+      jt0 += j<<1;
+      ib0 += i<<1;
+      jb0 += j<<1;
+
+      if (is >= 0 && is <= (width-16)<<1 &&
+          js >= 0 && js <= (height-16))
+      {
+        for (delta_y=-1; delta_y<=1; delta_y++)
+        {
+          for (delta_x=-1; delta_x<=1; delta_x++)
+          {
+            /* opposite field coordinates */
+            it = it0 + delta_x;
+            jt = jt0 + delta_y;
+            ib = ib0 + delta_x;
+            jb = jb0 + delta_y;
+
+            if (it >= 0 && it <= (width-16)<<1 &&
+                jt >= 0 && jt <= (height-16) &&
+                ib >= 0 && ib <= (width-16)<<1 &&
+                jb >= 0 && jb <= (height-16))
+            {
+              /* compute prediction error */
+              local_dist = bdist2(
+                ref + (is>>1) + (width<<1)*(js>>1),
+                ref + width + (it>>1) + (width<<1)*(jt>>1),
+                mb,             /* current mb location */
+                width<<1,       /* adjacent line distance */
+                is&1, js&1, it&1, jt&1, /* half-pel flags */
+                8);             /* block height */
+              local_dist += bdist2(
+                ref + width + (is>>1) + (width<<1)*(js>>1),
+                ref + (ib>>1) + (width<<1)*(jb>>1),
+                mb + width,     /* current mb location */
+                width<<1,       /* adjacent line distance */
+                is&1, js&1, ib&1, jb&1, /* half-pel flags */
+                8);             /* block height */
+
+              /* update delta with least distortion vector */
+              if (local_dist < vmc)
+              {
+                imins = is;
+                jmins = js;
+                imint = it;
+                jmint = jt;
+                iminb = ib;
+                jminb = jb;
+                imindmv = delta_x;
+                jmindmv = delta_y;
+                vmc = local_dist;
+              }
+            }
+          }  /* end delta x loop */
+        } /* end delta y loop */
+      }
+    }
+  }
+
+  /* Compute L1 error for decision purposes */
+  local_dist = bdist1(
+    ref + (imins>>1) + (width<<1)*(jmins>>1),
+    ref + width + (imint>>1) + (width<<1)*(jmint>>1),
+    mb,
+    width<<1,
+    imins&1, jmins&1, imint&1, jmint&1,
+    8);
+  local_dist += bdist1(
+    ref + width + (imins>>1) + (width<<1)*(jmins>>1),
+    ref + (iminb>>1) + (width<<1)*(jminb>>1),
+    mb + width,
+    width<<1,
+    imins&1, jmins&1, iminb&1, jminb&1,
+    8);
+
+  *dmcp = local_dist;
+  *iminp = imins;
+  *jminp = jmins;
+  *imindmvp = imindmv;
+  *jmindmvp = jmindmv;
+  *vmcp = vmc;
+}
+
+static void dpfield_estimate(topref,botref,mb,i,j,imins,jmins,
+  imindmvp, jmindmvp, dmcp, vmcp)
+unsigned char *topref, *botref, *mb;
+int i,j;
+int imins, jmins;
+int *imindmvp, *jmindmvp;
+int *dmcp,*vmcp;
+{
+  unsigned char *sameref, *oppref;
+  int io0,jo0,io,jo,delta_x,delta_y,mvxs,mvys,mvxo0,mvyo0;
+  int imino,jmino,imindmv,jmindmv,vmc_dp,local_dist;
+
+  /* Calculate Dual Prime distortions for 9 delta candidates */
+  /* Note: only for P pictures! */
+
+  /* Assign opposite and same reference pointer */
+  if (pict_struct==TOP_FIELD)
+  {
+    sameref = topref;    
+    oppref = botref;
+  }
+  else 
+  {
+    sameref = botref;
+    oppref = topref;
+  }
+
+  /* convert Cartesian absolute to relative motion vector
+   * values (wrt current macroblock address (i,j)
+   */
+  mvxs = imins - (i<<1);
+  mvys = jmins - (j<<1);
+
+  /* vector for prediction from field of opposite 'parity' */
+  mvxo0 = (mvxs+(mvxs>0)) >> 1;  /* mvxs // 2 */
+  mvyo0 = (mvys+(mvys>0)) >> 1;  /* mvys // 2 */
+
+  /* vertical field shift correction */
+  if (pict_struct==TOP_FIELD)
+    mvyo0--;
+  else
+    mvyo0++;
+
+  /* convert back to absolute coordinates */
+  io0 = mvxo0 + (i<<1);
+  jo0 = mvyo0 + (j<<1);
+
+  /* initialize minimum dual prime distortion to large value */
+  vmc_dp = 1 << 30;
+
+  for (delta_y = -1; delta_y <= 1; delta_y++)
+  {
+    for (delta_x = -1; delta_x <=1; delta_x++)
+    {
+      /* opposite field coordinates */
+      io = io0 + delta_x;
+      jo = jo0 + delta_y;
+
+      if (io >= 0 && io <= (width-16)<<1 &&
+          jo >= 0 && jo <= (height2-16)<<1)
+      {
+        /* compute prediction error */
+        local_dist = bdist2(
+          sameref + (imins>>1) + width2*(jmins>>1),
+          oppref  + (io>>1)    + width2*(jo>>1),
+          mb,             /* current mb location */
+          width2,         /* adjacent line distance */
+          imins&1, jmins&1, io&1, jo&1, /* half-pel flags */
+          16);            /* block height */
+
+        /* update delta with least distortion vector */
+        if (local_dist < vmc_dp)
+        {
+          imino = io;
+          jmino = jo;
+          imindmv = delta_x;
+          jmindmv = delta_y;
+          vmc_dp = local_dist;
+        }
+      }
+    }  /* end delta x loop */
+  } /* end delta y loop */
+
+  /* Compute L1 error for decision purposes */
+  *dmcp = bdist1(
+    sameref + (imins>>1) + width2*(jmins>>1),
+    oppref  + (imino>>1) + width2*(jmino>>1),
+    mb,             /* current mb location */
+    width2,         /* adjacent line distance */
+    imins&1, jmins&1, imino&1, jmino&1, /* half-pel flags */
+    16);            /* block height */
+
+  *imindmvp = imindmv;
+  *jmindmvp = jmindmv;
+  *vmcp = vmc_dp;
+}
+
+/*
+ * full search block matching
+ *
+ * blk: top left pel of (16*h) block
+ * h: height of block
+ * lx: distance (in bytes) of vertically adjacent pels in ref,blk
+ * org: top left pel of source reference picture
+ * ref: top left pel of reconstructed reference picture
+ * i0,j0: center of search window
+ * sx,sy: half widths of search window
+ * xmax,ymax: right/bottom limits of search area
+ * iminp,jminp: pointers to where the result is stored
+ *              result is given as half pel offset from ref(0,0)
+ *              i.e. NOT relative to (i0,j0)
+ */
+static int fullsearch(org,ref,blk,lx,i0,j0,sx,sy,h,xmax,ymax,iminp,jminp)
+unsigned char *org,*ref,*blk;
+int lx,i0,j0,sx,sy,h,xmax,ymax;
+int *iminp,*jminp;
+{
+  int i,j,imin,jmin,ilow,ihigh,jlow,jhigh;
+  int d,dmin;
+  int k,l,sxy;
+
+  ilow = i0 - sx;
+  ihigh = i0 + sx;
+
+  if (ilow<0)
+    ilow = 0;
+
+  if (ihigh>xmax-16)
+    ihigh = xmax-16;
+
+  jlow = j0 - sy;
+  jhigh = j0 + sy;
+
+  if (jlow<0)
+    jlow = 0;
+
+  if (jhigh>ymax-h)
+    jhigh = ymax-h;
+
+  /* full pel search, spiraling outwards */
+
+  imin = i0;
+  jmin = j0;
+  dmin = dist1(org+imin+lx*jmin,blk,lx,0,0,h,65536);
+
+  sxy = (sx>sy) ? sx : sy;
+
+  for (l=1; l<=sxy; l++)
+  {
+    i = i0 - l;
+    j = j0 - l;
+    for (k=0; k<8*l; k++)
+    {
+      if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh)
+      {
+        d = dist1(org+i+lx*j,blk,lx,0,0,h,dmin);
+
+        if (d<dmin)
+        {
+          dmin = d;
+          imin = i;
+          jmin = j;
+        }
+      }
+
+      if      (k<2*l) i++;
+      else if (k<4*l) j++;
+      else if (k<6*l) i--;
+      else            j--;
+    }
+  }
+
+  /* half pel */
+  dmin = 65536;
+  imin <<= 1;
+  jmin <<= 1;
+  ilow = imin - (imin>0);
+  ihigh = imin + (imin<((xmax-16)<<1));
+  jlow = jmin - (jmin>0);
+  jhigh = jmin + (jmin<((ymax-h)<<1));
+
+  for (j=jlow; j<=jhigh; j++)
+    for (i=ilow; i<=ihigh; i++)
+    {
+      d = dist1(ref+(i>>1)+lx*(j>>1),blk,lx,i&1,j&1,h,dmin);
+
+      if (d<dmin)
+      {
+        dmin = d;
+        imin = i;
+        jmin = j;
+      }
+    }
+
+  *iminp = imin;
+  *jminp = jmin;
+
+  return dmin;
+}
+
+/*
+ * total absolute difference between two (16*h) blocks
+ * including optional half pel interpolation of blk1 (hx,hy)
+ * blk1,blk2: addresses of top left pels of both blocks
+ * lx:        distance (in bytes) of vertically adjacent pels
+ * hx,hy:     flags for horizontal and/or vertical interpolation
+ * h:         height of block (usually 8 or 16)
+ * distlim:   bail out if sum exceeds this value
+ */
+static int dist1(blk1,blk2,lx,hx,hy,h,distlim)
+unsigned char *blk1,*blk2;
+int lx,hx,hy,h;
+int distlim;
+{
+  unsigned char *p1,*p1a,*p2;
+  int i,j;
+  int s,v;
+
+  s = 0;
+  p1 = blk1;
+  p2 = blk2;
+
+  if (!hx && !hy)
+    for (j=0; j<h; j++)
+    {
+      if ((v = p1[0]  - p2[0])<0)  v = -v; s+= v;
+      if ((v = p1[1]  - p2[1])<0)  v = -v; s+= v;
+      if ((v = p1[2]  - p2[2])<0)  v = -v; s+= v;
+      if ((v = p1[3]  - p2[3])<0)  v = -v; s+= v;
+      if ((v = p1[4]  - p2[4])<0)  v = -v; s+= v;
+      if ((v = p1[5]  - p2[5])<0)  v = -v; s+= v;
+      if ((v = p1[6]  - p2[6])<0)  v = -v; s+= v;
+      if ((v = p1[7]  - p2[7])<0)  v = -v; s+= v;
+      if ((v = p1[8]  - p2[8])<0)  v = -v; s+= v;
+      if ((v = p1[9]  - p2[9])<0)  v = -v; s+= v;
+      if ((v = p1[10] - p2[10])<0) v = -v; s+= v;
+      if ((v = p1[11] - p2[11])<0) v = -v; s+= v;
+      if ((v = p1[12] - p2[12])<0) v = -v; s+= v;
+      if ((v = p1[13] - p2[13])<0) v = -v; s+= v;
+      if ((v = p1[14] - p2[14])<0) v = -v; s+= v;
+      if ((v = p1[15] - p2[15])<0) v = -v; s+= v;
+
+      if (s >= distlim)
+        break;
+
+      p1+= lx;
+      p2+= lx;
+    }
+  else if (hx && !hy)
+    for (j=0; j<h; j++)
+    {
+      for (i=0; i<16; i++)
+      {
+        v = ((unsigned int)(p1[i]+p1[i+1]+1)>>1) - p2[i];
+        if (v>=0)
+          s+= v;
+        else
+          s-= v;
+      }
+      p1+= lx;
+      p2+= lx;
+    }
+  else if (!hx && hy)
+  {
+    p1a = p1 + lx;
+    for (j=0; j<h; j++)
+    {
+      for (i=0; i<16; i++)
+      {
+        v = ((unsigned int)(p1[i]+p1a[i]+1)>>1) - p2[i];
+        if (v>=0)
+          s+= v;
+        else
+          s-= v;
+      }
+      p1 = p1a;
+      p1a+= lx;
+      p2+= lx;
+    }
+  }
+  else /* if (hx && hy) */
+  {
+    p1a = p1 + lx;
+    for (j=0; j<h; j++)
+    {
+      for (i=0; i<16; i++)
+      {
+        v = ((unsigned int)(p1[i]+p1[i+1]+p1a[i]+p1a[i+1]+2)>>2) - p2[i];
+        if (v>=0)
+          s+= v;
+        else
+          s-= v;
+      }
+      p1 = p1a;
+      p1a+= lx;
+      p2+= lx;
+    }
+  }
+
+  return s;
+}
+
+/*
+ * total squared difference between two (16*h) blocks
+ * including optional half pel interpolation of blk1 (hx,hy)
+ * blk1,blk2: addresses of top left pels of both blocks
+ * lx:        distance (in bytes) of vertically adjacent pels
+ * hx,hy:     flags for horizontal and/or vertical interpolation
+ * h:         height of block (usually 8 or 16)
+ */
+static int dist2(blk1,blk2,lx,hx,hy,h)
+unsigned char *blk1,*blk2;
+int lx,hx,hy,h;
+{
+  unsigned char *p1,*p1a,*p2;
+  int i,j;
+  int s,v;
+
+  s = 0;
+  p1 = blk1;
+  p2 = blk2;
+  if (!hx && !hy)
+    for (j=0; j<h; j++)
+    {
+      for (i=0; i<16; i++)
+      {
+        v = p1[i] - p2[i];
+        s+= v*v;
+      }
+      p1+= lx;
+      p2+= lx;
+    }
+  else if (hx && !hy)
+    for (j=0; j<h; j++)
+    {
+      for (i=0; i<16; i++)
+      {
+        v = ((unsigned int)(p1[i]+p1[i+1]+1)>>1) - p2[i];
+        s+= v*v;
+      }
+      p1+= lx;
+      p2+= lx;
+    }
+  else if (!hx && hy)
+  {
+    p1a = p1 + lx;
+    for (j=0; j<h; j++)
+    {
+      for (i=0; i<16; i++)
+      {
+        v = ((unsigned int)(p1[i]+p1a[i]+1)>>1) - p2[i];
+        s+= v*v;
+      }
+      p1 = p1a;
+      p1a+= lx;
+      p2+= lx;
+    }
+  }
+  else /* if (hx && hy) */
+  {
+    p1a = p1 + lx;
+    for (j=0; j<h; j++)
+    {
+      for (i=0; i<16; i++)
+      {
+        v = ((unsigned int)(p1[i]+p1[i+1]+p1a[i]+p1a[i+1]+2)>>2) - p2[i];
+        s+= v*v;
+      }
+      p1 = p1a;
+      p1a+= lx;
+      p2+= lx;
+    }
+  }
+
+  return s;
+}
+
+/*
+ * absolute difference error between a (16*h) block and a bidirectional
+ * prediction
+ *
+ * p2: address of top left pel of block
+ * pf,hxf,hyf: address and half pel flags of forward ref. block
+ * pb,hxb,hyb: address and half pel flags of backward ref. block
+ * h: height of block
+ * lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb
+ */
+static int bdist1(pf,pb,p2,lx,hxf,hyf,hxb,hyb,h)
+unsigned char *pf,*pb,*p2;
+int lx,hxf,hyf,hxb,hyb,h;
+{
+  unsigned char *pfa,*pfb,*pfc,*pba,*pbb,*pbc;
+  int i,j;
+  int s,v;
+
+  pfa = pf + hxf;
+  pfb = pf + lx*hyf;
+  pfc = pfb + hxf;
+
+  pba = pb + hxb;
+  pbb = pb + lx*hyb;
+  pbc = pbb + hxb;
+
+  s = 0;
+
+  for (j=0; j<h; j++)
+  {
+    for (i=0; i<16; i++)
+    {
+      v = ((((unsigned int)(*pf++ + *pfa++ + *pfb++ + *pfc++ + 2)>>2) +
+            ((unsigned int)(*pb++ + *pba++ + *pbb++ + *pbc++ + 2)>>2) + 1)>>1)
+           - *p2++;
+      if (v>=0)
+        s+= v;
+      else
+        s-= v;
+    }
+    p2+= lx-16;
+    pf+= lx-16;
+    pfa+= lx-16;
+    pfb+= lx-16;
+    pfc+= lx-16;
+    pb+= lx-16;
+    pba+= lx-16;
+    pbb+= lx-16;
+    pbc+= lx-16;
+  }
+
+  return s;
+}
+
+/*
+ * squared error between a (16*h) block and a bidirectional
+ * prediction
+ *
+ * p2: address of top left pel of block
+ * pf,hxf,hyf: address and half pel flags of forward ref. block
+ * pb,hxb,hyb: address and half pel flags of backward ref. block
+ * h: height of block
+ * lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb
+ */
+static int bdist2(pf,pb,p2,lx,hxf,hyf,hxb,hyb,h)
+unsigned char *pf,*pb,*p2;
+int lx,hxf,hyf,hxb,hyb,h;
+{
+  unsigned char *pfa,*pfb,*pfc,*pba,*pbb,*pbc;
+  int i,j;
+  int s,v;
+
+  pfa = pf + hxf;
+  pfb = pf + lx*hyf;
+  pfc = pfb + hxf;
+
+  pba = pb + hxb;
+  pbb = pb + lx*hyb;
+  pbc = pbb + hxb;
+
+  s = 0;
+
+  for (j=0; j<h; j++)
+  {
+    for (i=0; i<16; i++)
+    {
+      v = ((((unsigned int)(*pf++ + *pfa++ + *pfb++ + *pfc++ + 2)>>2) +
+            ((unsigned int)(*pb++ + *pba++ + *pbb++ + *pbc++ + 2)>>2) + 1)>>1)
+          - *p2++;
+      s+=v*v;
+    }
+    p2+= lx-16;
+    pf+= lx-16;
+    pfa+= lx-16;
+    pfb+= lx-16;
+    pfc+= lx-16;
+    pb+= lx-16;
+    pba+= lx-16;
+    pbb+= lx-16;
+    pbc+= lx-16;
+  }
+
+  return s;
+}
+
+/*
+ * variance of a (16*16) block, multiplied by 256
+ * p:  address of top left pel of block
+ * lx: distance (in bytes) of vertically adjacent pels
+ */
+static int variance(p,lx)
+unsigned char *p;
+int lx;
+{
+  int i,j;
+  unsigned int v,s,s2;
+
+  s = s2 = 0;
+
+  for (j=0; j<16; j++)
+  {
+    for (i=0; i<16; i++)
+    {
+      v = *p++;
+      s+= v;
+      s2+= v*v;
+    }
+    p+= lx-16;
+  }
+  return s2 - (s*s)/256;
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/mpeg2enc.c b/src/gdcmmpeg2/src/mpeg2enc/mpeg2enc.c
new file mode 100644 (file)
index 0000000..175b0f1
--- /dev/null
@@ -0,0 +1,558 @@
+/* mpeg2enc.c, main() and parameter file reading                            */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define GLOBAL /* used by global.h */
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+static void init _ANSI_ARGS_((void));
+static void readparmfile _ANSI_ARGS_((char *fname));
+static void readquantmat _ANSI_ARGS_((void));
+
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+  if (argc!=3)
+  {
+    printf("\n%s, %s\n",version,author);
+    printf("Usage: mpeg2encode in.par out.m2v\n");
+    exit(0);
+  }
+
+  /* read parameter file */
+  readparmfile(argv[1]);
+
+  /* read quantization matrices */
+  readquantmat();
+
+  /* open output file */
+  if (!(outfile=fopen(argv[2],"wb")))
+  {
+    sprintf(errortext,"Couldn't create output file %s",argv[2]);
+    error(errortext);
+  }
+
+  init();
+  putseq();
+
+  fclose(outfile);
+  fclose(statfile);
+
+  return 0;
+}
+
+static void init()
+{
+  int i, size;
+  static int block_count_tab[3] = {6,8,12};
+
+  initbits();
+  init_fdct();
+  init_idct();
+
+  /* round picture dimensions to nearest multiple of 16 or 32 */
+  mb_width = (horizontal_size+15)/16;
+  mb_height = prog_seq ? (vertical_size+15)/16 : 2*((vertical_size+31)/32);
+  mb_height2 = fieldpic ? mb_height>>1 : mb_height; /* for field pictures */
+  width = 16*mb_width;
+  height = 16*mb_height;
+
+  chrom_width = (chroma_format==CHROMA444) ? width : width>>1;
+  chrom_height = (chroma_format!=CHROMA420) ? height : height>>1;
+
+  height2 = fieldpic ? height>>1 : height;
+  width2 = fieldpic ? width<<1 : width;
+  chrom_width2 = fieldpic ? chrom_width<<1 : chrom_width;
+  
+  block_count = block_count_tab[chroma_format-1];
+
+  /* clip table */
+  if (!(clp = (unsigned char *)malloc(1024)))
+    error("malloc failed\n");
+  clp+= 384;
+  for (i=-384; i<640; i++)
+    clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
+
+  for (i=0; i<3; i++)
+  {
+    size = (i==0) ? width*height : chrom_width*chrom_height;
+
+    if (!(newrefframe[i] = (unsigned char *)malloc(size)))
+      error("malloc failed\n");
+    if (!(oldrefframe[i] = (unsigned char *)malloc(size)))
+      error("malloc failed\n");
+    if (!(auxframe[i] = (unsigned char *)malloc(size)))
+      error("malloc failed\n");
+    if (!(neworgframe[i] = (unsigned char *)malloc(size)))
+      error("malloc failed\n");
+    if (!(oldorgframe[i] = (unsigned char *)malloc(size)))
+      error("malloc failed\n");
+    if (!(auxorgframe[i] = (unsigned char *)malloc(size)))
+      error("malloc failed\n");
+    if (!(predframe[i] = (unsigned char *)malloc(size)))
+      error("malloc failed\n");
+  }
+
+  mbinfo = (struct mbinfo *)malloc(mb_width*mb_height2*sizeof(struct mbinfo));
+
+  if (!mbinfo)
+    error("malloc failed\n");
+
+  blocks =
+    (short (*)[64])malloc(mb_width*mb_height2*block_count*sizeof(short [64]));
+
+  if (!blocks)
+    error("malloc failed\n");
+
+  /* open statistics output file */
+  if (statname[0]=='-')
+    statfile = stdout;
+  else if (!(statfile = fopen(statname,"w")))
+  {
+    sprintf(errortext,"Couldn't create statistics output file %s",statname);
+    error(errortext);
+  }
+}
+
+void error(text)
+char *text;
+{
+  fprintf(stderr,text);
+  putc('\n',stderr);
+  exit(1);
+}
+
+static void readparmfile(fname)
+char *fname;
+{
+  int i;
+  int h,m,s,f;
+  FILE *fd;
+  char line[256];
+  static double ratetab[8]=
+    {24000.0/1001.0,24.0,25.0,30000.0/1001.0,30.0,50.0,60000.0/1001.0,60.0};
+  extern int r,Xi,Xb,Xp,d0i,d0p,d0b; /* rate control */
+  extern double avg_act; /* rate control */
+
+  if (!(fd = fopen(fname,"r")))
+  {
+    sprintf(errortext,"Couldn't open parameter file %s",fname);
+    error(errortext);
+  }
+
+  fgets(id_string,254,fd);
+  fgets(line,254,fd); sscanf(line,"%s",tplorg);
+  fgets(line,254,fd); sscanf(line,"%s",tplref);
+  fgets(line,254,fd); sscanf(line,"%s",iqname);
+  fgets(line,254,fd); sscanf(line,"%s",niqname);
+  fgets(line,254,fd); sscanf(line,"%s",statname);
+  fgets(line,254,fd); sscanf(line,"%d",&inputtype);
+  fgets(line,254,fd); sscanf(line,"%d",&nframes);
+  fgets(line,254,fd); sscanf(line,"%d",&frame0);
+  fgets(line,254,fd); sscanf(line,"%d:%d:%d:%d",&h,&m,&s,&f);
+  fgets(line,254,fd); sscanf(line,"%d",&N);
+  fgets(line,254,fd); sscanf(line,"%d",&M);
+  fgets(line,254,fd); sscanf(line,"%d",&mpeg1);
+  fgets(line,254,fd); sscanf(line,"%d",&fieldpic);
+  fgets(line,254,fd); sscanf(line,"%d",&horizontal_size);
+  fgets(line,254,fd); sscanf(line,"%d",&vertical_size);
+  fgets(line,254,fd); sscanf(line,"%d",&aspectratio);
+  fgets(line,254,fd); sscanf(line,"%d",&frame_rate_code);
+  fgets(line,254,fd); sscanf(line,"%lf",&bit_rate);
+  fgets(line,254,fd); sscanf(line,"%d",&vbv_buffer_size);   
+  fgets(line,254,fd); sscanf(line,"%d",&low_delay);     
+  fgets(line,254,fd); sscanf(line,"%d",&constrparms);
+  fgets(line,254,fd); sscanf(line,"%d",&profile);
+  fgets(line,254,fd); sscanf(line,"%d",&level);
+  fgets(line,254,fd); sscanf(line,"%d",&prog_seq);
+  fgets(line,254,fd); sscanf(line,"%d",&chroma_format);
+  fgets(line,254,fd); sscanf(line,"%d",&video_format);
+  fgets(line,254,fd); sscanf(line,"%d",&color_primaries);
+  fgets(line,254,fd); sscanf(line,"%d",&transfer_characteristics);
+  fgets(line,254,fd); sscanf(line,"%d",&matrix_coefficients);
+  fgets(line,254,fd); sscanf(line,"%d",&display_horizontal_size);
+  fgets(line,254,fd); sscanf(line,"%d",&display_vertical_size);
+  fgets(line,254,fd); sscanf(line,"%d",&dc_prec);
+  fgets(line,254,fd); sscanf(line,"%d",&topfirst);
+  fgets(line,254,fd); sscanf(line,"%d %d %d",
+    frame_pred_dct_tab,frame_pred_dct_tab+1,frame_pred_dct_tab+2);
+  
+  fgets(line,254,fd); sscanf(line,"%d %d %d",
+    conceal_tab,conceal_tab+1,conceal_tab+2);
+  
+  fgets(line,254,fd); sscanf(line,"%d %d %d",
+    qscale_tab,qscale_tab+1,qscale_tab+2);
+
+  fgets(line,254,fd); sscanf(line,"%d %d %d",
+    intravlc_tab,intravlc_tab+1,intravlc_tab+2);
+  fgets(line,254,fd); sscanf(line,"%d %d %d",
+    altscan_tab,altscan_tab+1,altscan_tab+2);
+  fgets(line,254,fd); sscanf(line,"%d",&repeatfirst);
+  fgets(line,254,fd); sscanf(line,"%d",&prog_frame);
+/* intra slice interval refresh period */  
+  fgets(line,254,fd); sscanf(line,"%d",&P);
+  fgets(line,254,fd); sscanf(line,"%d",&r);
+  fgets(line,254,fd); sscanf(line,"%lf",&avg_act);
+  fgets(line,254,fd); sscanf(line,"%d",&Xi);
+  fgets(line,254,fd); sscanf(line,"%d",&Xp);
+  fgets(line,254,fd); sscanf(line,"%d",&Xb);
+  fgets(line,254,fd); sscanf(line,"%d",&d0i);
+  fgets(line,254,fd); sscanf(line,"%d",&d0p);
+  fgets(line,254,fd); sscanf(line,"%d",&d0b);
+
+  if (N<1)
+    error("N must be positive");
+  if (M<1)
+    error("M must be positive");
+  if (N%M != 0)
+    error("N must be an integer multiple of M");
+
+  motion_data = (struct motion_data *)malloc(M*sizeof(struct motion_data));
+  if (!motion_data)
+    error("malloc failed\n");
+
+  for (i=0; i<M; i++)
+  {
+    fgets(line,254,fd);
+    sscanf(line,"%d %d %d %d",
+      &motion_data[i].forw_hor_f_code, &motion_data[i].forw_vert_f_code,
+      &motion_data[i].sxf, &motion_data[i].syf);
+
+    if (i!=0)
+    {
+      fgets(line,254,fd);
+      sscanf(line,"%d %d %d %d",
+        &motion_data[i].back_hor_f_code, &motion_data[i].back_vert_f_code,
+        &motion_data[i].sxb, &motion_data[i].syb);
+    }
+  }
+
+  fclose(fd);
+
+  /* make flags boolean (x!=0 -> x=1) */
+  mpeg1 = !!mpeg1;
+  fieldpic = !!fieldpic;
+  low_delay = !!low_delay;
+  constrparms = !!constrparms;
+  prog_seq = !!prog_seq;
+  topfirst = !!topfirst;
+
+  for (i=0; i<3; i++)
+  {
+    frame_pred_dct_tab[i] = !!frame_pred_dct_tab[i];
+    conceal_tab[i] = !!conceal_tab[i];
+    qscale_tab[i] = !!qscale_tab[i];
+    intravlc_tab[i] = !!intravlc_tab[i];
+    altscan_tab[i] = !!altscan_tab[i];
+  }
+  repeatfirst = !!repeatfirst;
+  prog_frame = !!prog_frame;
+
+  /* make sure MPEG specific parameters are valid */
+  range_checks();
+
+  frame_rate = ratetab[frame_rate_code-1];
+
+  /* timecode -> frame number */
+  tc0 = h;
+  tc0 = 60*tc0 + m;
+  tc0 = 60*tc0 + s;
+  tc0 = (int)(frame_rate+0.5)*tc0 + f;
+
+  if (!mpeg1)
+  {
+    profile_and_level_checks();
+  }
+  else
+  {
+    /* MPEG-1 */
+    if (constrparms)
+    {
+      if (horizontal_size>768
+          || vertical_size>576
+          || ((horizontal_size+15)/16)*((vertical_size+15)/16)>396
+          || ((horizontal_size+15)/16)*((vertical_size+15)/16)*frame_rate>396*25.0
+          || frame_rate>30.0)
+      {
+        if (!quiet)
+          fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
+        constrparms = 0;
+      }
+    }
+
+    if (constrparms)
+    {
+      for (i=0; i<M; i++)
+      {
+        if (motion_data[i].forw_hor_f_code>4)
+        {
+          if (!quiet)
+            fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
+          constrparms = 0;
+          break;
+        }
+
+        if (motion_data[i].forw_vert_f_code>4)
+        {
+          if (!quiet)
+            fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
+          constrparms = 0;
+          break;
+        }
+
+        if (i!=0)
+        {
+          if (motion_data[i].back_hor_f_code>4)
+          {
+            if (!quiet)
+              fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
+            constrparms = 0;
+            break;
+          }
+
+          if (motion_data[i].back_vert_f_code>4)
+          {
+            if (!quiet)
+              fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
+            constrparms = 0;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  /* relational checks */
+
+  if (mpeg1)
+  {
+    if (!prog_seq)
+    {
+      if (!quiet)
+        fprintf(stderr,"Warning: setting progressive_sequence = 1\n");
+      prog_seq = 1;
+    }
+
+    if (chroma_format!=CHROMA420)
+    {
+      if (!quiet)
+        fprintf(stderr,"Warning: setting chroma_format = 1 (4:2:0)\n");
+      chroma_format = CHROMA420;
+    }
+
+    if (dc_prec!=0)
+    {
+      if (!quiet)
+        fprintf(stderr,"Warning: setting intra_dc_precision = 0\n");
+      dc_prec = 0;
+    }
+
+    for (i=0; i<3; i++)
+      if (qscale_tab[i])
+      {
+        if (!quiet)
+          fprintf(stderr,"Warning: setting qscale_tab[%d] = 0\n",i);
+        qscale_tab[i] = 0;
+      }
+
+    for (i=0; i<3; i++)
+      if (intravlc_tab[i])
+      {
+        if (!quiet)
+          fprintf(stderr,"Warning: setting intravlc_tab[%d] = 0\n",i);
+        intravlc_tab[i] = 0;
+      }
+
+    for (i=0; i<3; i++)
+      if (altscan_tab[i])
+      {
+        if (!quiet)
+          fprintf(stderr,"Warning: setting altscan_tab[%d] = 0\n",i);
+        altscan_tab[i] = 0;
+      }
+  }
+
+  if (!mpeg1 && constrparms)
+  {
+    if (!quiet)
+      fprintf(stderr,"Warning: setting constrained_parameters_flag = 0\n");
+    constrparms = 0;
+  }
+
+  if (prog_seq && !prog_frame)
+  {
+    if (!quiet)
+      fprintf(stderr,"Warning: setting progressive_frame = 1\n");
+    prog_frame = 1;
+  }
+
+  if (prog_frame && fieldpic)
+  {
+    if (!quiet)
+      fprintf(stderr,"Warning: setting field_pictures = 0\n");
+    fieldpic = 0;
+  }
+
+  if (!prog_frame && repeatfirst)
+  {
+    if (!quiet)
+      fprintf(stderr,"Warning: setting repeat_first_field = 0\n");
+    repeatfirst = 0;
+  }
+
+  if (prog_frame)
+  {
+    for (i=0; i<3; i++)
+      if (!frame_pred_dct_tab[i])
+      {
+        if (!quiet)
+          fprintf(stderr,"Warning: setting frame_pred_frame_dct[%d] = 1\n",i);
+        frame_pred_dct_tab[i] = 1;
+      }
+  }
+
+  if (prog_seq && !repeatfirst && topfirst)
+  {
+    if (!quiet)
+      fprintf(stderr,"Warning: setting top_field_first = 0\n");
+    topfirst = 0;
+  }
+
+  /* search windows */
+  for (i=0; i<M; i++)
+  {
+    if (motion_data[i].sxf > (4<<motion_data[i].forw_hor_f_code)-1)
+    {
+      if (!quiet)
+        fprintf(stderr,
+          "Warning: reducing forward horizontal search width to %d\n",
+          (4<<motion_data[i].forw_hor_f_code)-1);
+      motion_data[i].sxf = (4<<motion_data[i].forw_hor_f_code)-1;
+    }
+
+    if (motion_data[i].syf > (4<<motion_data[i].forw_vert_f_code)-1)
+    {
+      if (!quiet)
+        fprintf(stderr,
+          "Warning: reducing forward vertical search width to %d\n",
+          (4<<motion_data[i].forw_vert_f_code)-1);
+      motion_data[i].syf = (4<<motion_data[i].forw_vert_f_code)-1;
+    }
+
+    if (i!=0)
+    {
+      if (motion_data[i].sxb > (4<<motion_data[i].back_hor_f_code)-1)
+      {
+        if (!quiet)
+          fprintf(stderr,
+            "Warning: reducing backward horizontal search width to %d\n",
+            (4<<motion_data[i].back_hor_f_code)-1);
+        motion_data[i].sxb = (4<<motion_data[i].back_hor_f_code)-1;
+      }
+
+      if (motion_data[i].syb > (4<<motion_data[i].back_vert_f_code)-1)
+      {
+        if (!quiet)
+          fprintf(stderr,
+            "Warning: reducing backward vertical search width to %d\n",
+            (4<<motion_data[i].back_vert_f_code)-1);
+        motion_data[i].syb = (4<<motion_data[i].back_vert_f_code)-1;
+      }
+    }
+  }
+
+}
+
+static void readquantmat()
+{
+  int i,v;
+  FILE *fd;
+
+  if (iqname[0]=='-')
+  {
+    /* use default intra matrix */
+    load_iquant = 0;
+    for (i=0; i<64; i++)
+      intra_q[i] = default_intra_quantizer_matrix[i];
+  }
+  else
+  {
+    /* read customized intra matrix */
+    load_iquant = 1;
+    if (!(fd = fopen(iqname,"r")))
+    {
+      sprintf(errortext,"Couldn't open quant matrix file %s",iqname);
+      error(errortext);
+    }
+
+    for (i=0; i<64; i++)
+    {
+      fscanf(fd,"%d",&v);
+      if (v<1 || v>255)
+        error("invalid value in quant matrix");
+      intra_q[i] = v;
+    }
+
+    fclose(fd);
+  }
+
+  if (niqname[0]=='-')
+  {
+    /* use default non-intra matrix */
+    load_niquant = 0;
+    for (i=0; i<64; i++)
+      inter_q[i] = 16;
+  }
+  else
+  {
+    /* read customized non-intra matrix */
+    load_niquant = 1;
+    if (!(fd = fopen(niqname,"r")))
+    {
+      sprintf(errortext,"Couldn't open quant matrix file %s",niqname);
+      error(errortext);
+    }
+
+    for (i=0; i<64; i++)
+    {
+      fscanf(fd,"%d",&v);
+      if (v<1 || v>255)
+        error("invalid value in quant matrix");
+      inter_q[i] = v;
+    }
+
+    fclose(fd);
+  }
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/mpeg2enc.h b/src/gdcmmpeg2/src/mpeg2enc/mpeg2enc.h
new file mode 100644 (file)
index 0000000..d2402e8
--- /dev/null
@@ -0,0 +1,112 @@
+/* mpg2enc.h, defines and types                                             */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#define PICTURE_START_CODE 0x100L
+#define SLICE_MIN_START    0x101L
+#define SLICE_MAX_START    0x1AFL
+#define USER_START_CODE    0x1B2L
+#define SEQ_START_CODE     0x1B3L
+#define EXT_START_CODE     0x1B5L
+#define SEQ_END_CODE       0x1B7L
+#define GOP_START_CODE     0x1B8L
+#define ISO_END_CODE       0x1B9L
+#define PACK_START_CODE    0x1BAL
+#define SYSTEM_START_CODE  0x1BBL
+
+/* picture coding type */
+#define I_TYPE 1
+#define P_TYPE 2
+#define B_TYPE 3
+#define D_TYPE 4
+
+/* picture structure */
+#define TOP_FIELD     1
+#define BOTTOM_FIELD  2
+#define FRAME_PICTURE 3
+
+/* macroblock type */
+#define MB_INTRA    1
+#define MB_PATTERN  2
+#define MB_BACKWARD 4
+#define MB_FORWARD  8
+#define MB_QUANT    16
+
+/* motion_type */
+#define MC_FIELD 1
+#define MC_FRAME 2
+#define MC_16X8  2
+#define MC_DMV   3
+
+/* mv_format */
+#define MV_FIELD 0
+#define MV_FRAME 1
+
+/* chroma_format */
+#define CHROMA420 1
+#define CHROMA422 2
+#define CHROMA444 3
+
+/* extension start code IDs */
+
+#define SEQ_ID       1
+#define DISP_ID      2
+#define QUANT_ID     3
+#define SEQSCAL_ID   5
+#define PANSCAN_ID   7
+#define CODING_ID    8
+#define SPATSCAL_ID  9
+#define TEMPSCAL_ID 10
+
+/* inputtype */
+#define T_Y_U_V 0
+#define T_YUV   1
+#define T_PPM   2
+
+/* macroblock information */
+struct mbinfo {
+  int mb_type; /* intra/forward/backward/interpolated */
+  int motion_type; /* frame/field/16x8/dual_prime */
+  int dct_type; /* field/frame DCT */
+  int mquant; /* quantization parameter */
+  int cbp; /* coded block pattern */
+  int skipped; /* skipped macroblock */
+  int MV[2][2][2]; /* motion vectors */
+  int mv_field_sel[2][2]; /* motion vertical field select */
+  int dmvector[2]; /* dual prime vectors */
+  double act; /* activity measure */
+  int var; /* for debugging */
+};
+
+/* motion data */
+struct motion_data {
+  int forw_hor_f_code,forw_vert_f_code; /* vector range */
+  int sxf,syf; /* search range */
+  int back_hor_f_code,back_vert_f_code;
+  int sxb,syb;
+};
diff --git a/src/gdcmmpeg2/src/mpeg2enc/predict.c b/src/gdcmmpeg2/src/mpeg2enc/predict.c
new file mode 100644 (file)
index 0000000..8faf8da
--- /dev/null
@@ -0,0 +1,589 @@
+/* predict.c, motion compensated prediction                                 */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+static void predict_mb _ANSI_ARGS_((
+  unsigned char *oldref[], unsigned char *newref[], unsigned char *cur[],
+  int lx, int bx, int by, int pict_type, int pict_struct, int mb_type,
+  int motion_type, int secondfield,
+  int PMV[2][2][2], int mv_field_sel[2][2], int dmvector[2]));
+
+static void pred _ANSI_ARGS_((unsigned char *src[], int sfield,
+  unsigned char *dst[], int dfield,
+  int lx, int w, int h, int x, int y, int dx, int dy, int addflag));
+
+static void pred_comp _ANSI_ARGS_((unsigned char *src, unsigned char *dst,
+  int lx, int w, int h, int x, int y, int dx, int dy, int addflag));
+
+static void calc_DMV _ANSI_ARGS_((int DMV[][2], int *dmvector, int mvx,
+  int mvy));
+
+static void clearblock _ANSI_ARGS_((unsigned char *cur[], int i0, int j0));
+
+
+/* form prediction for a complete picture (frontend for predict_mb)
+ *
+ * reff: reference frame for forward prediction
+ * refb: reference frame for backward prediction
+ * cur:  destination (current) frame
+ * secondfield: predict second field of a frame
+ * mbi:  macroblock info
+ *
+ * Notes:
+ * - cf. predict_mb
+ */
+
+void predict(reff,refb,cur,secondfield,mbi)
+unsigned char *reff[],*refb[],*cur[3];
+int secondfield;
+struct mbinfo *mbi;
+{
+  int i, j, k;
+
+  k = 0;
+
+  /* loop through all macroblocks of the picture */
+  for (j=0; j<height2; j+=16)
+    for (i=0; i<width; i+=16)
+    {
+      predict_mb(reff,refb,cur,width,i,j,pict_type,pict_struct,
+                 mbi[k].mb_type,mbi[k].motion_type,secondfield,
+                 mbi[k].MV,mbi[k].mv_field_sel,mbi[k].dmvector);
+
+      k++;
+    }
+}
+
+/* form prediction for one macroblock
+ *
+ * oldref: reference frame for forward prediction
+ * newref: reference frame for backward prediction
+ * cur:    destination (current) frame
+ * lx:     frame width (identical to global var `width')
+ * bx,by:  picture (field or frame) coordinates of macroblock to be predicted
+ * pict_type: I, P or B
+ * pict_struct: FRAME_PICTURE, TOP_FIELD, BOTTOM_FIELD
+ * mb_type:     MB_FORWARD, MB_BACKWARD, MB_INTRA
+ * motion_type: MC_FRAME, MC_FIELD, MC_16X8, MC_DMV
+ * secondfield: predict second field of a frame
+ * PMV[2][2][2]: motion vectors (in half pel picture coordinates)
+ * mv_field_sel[2][2]: motion vertical field selects (for field predictions)
+ * dmvector: differential motion vectors (for dual prime)
+ *
+ * Notes:
+ * - when predicting a P type picture which is the second field of
+ *   a frame, the same parity reference field is in oldref, while the
+ *   opposite parity reference field is assumed to be in newref!
+ * - intra macroblocks are modelled to have a constant prediction of 128
+ *   for all pels; this results in a DC DCT coefficient symmetric to 0
+ * - vectors for field prediction in frame pictures are in half pel frame
+ *   coordinates (vertical component is twice the field value and always
+ *   even)
+ *
+ * already covers dual prime (not yet used)
+ */
+
+static void predict_mb(oldref,newref,cur,lx,bx,by,pict_type,pict_struct,
+  mb_type,motion_type,secondfield,PMV,mv_field_sel,dmvector)
+unsigned char *oldref[],*newref[],*cur[];
+int lx;
+int bx,by;
+int pict_type;
+int pict_struct;
+int mb_type;
+int motion_type;
+int secondfield;
+int PMV[2][2][2], mv_field_sel[2][2], dmvector[2];
+{
+  int addflag, currentfield;
+  unsigned char **predframe;
+  int DMV[2][2];
+
+  if (mb_type&MB_INTRA)
+  {
+    clearblock(cur,bx,by);
+    return;
+  }
+
+  addflag = 0; /* first prediction is stored, second is added and averaged */
+
+  if ((mb_type & MB_FORWARD) || (pict_type==P_TYPE))
+  {
+    /* forward prediction, including zero MV in P pictures */
+
+    if (pict_struct==FRAME_PICTURE)
+    {
+      /* frame picture */
+
+      if ((motion_type==MC_FRAME) || !(mb_type & MB_FORWARD))
+      {
+        /* frame-based prediction in frame picture */
+        pred(oldref,0,cur,0,
+          lx,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
+      }
+      else if (motion_type==MC_FIELD)
+      {
+        /* field-based prediction in frame picture
+         *
+         * note scaling of the vertical coordinates (by, PMV[][0][1])
+         * from frame to field!
+         */
+
+        /* top field prediction */
+        pred(oldref,mv_field_sel[0][0],cur,0,
+          lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
+
+        /* bottom field prediction */
+        pred(oldref,mv_field_sel[1][0],cur,1,
+          lx<<1,16,8,bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,0);
+      }
+      else if (motion_type==MC_DMV)
+      {
+        /* dual prime prediction */
+
+        /* calculate derived motion vectors */
+        calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1);
+
+        /* predict top field from top field */
+        pred(oldref,0,cur,0,
+          lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
+
+        /* predict bottom field from bottom field */
+        pred(oldref,1,cur,1,
+          lx<<1,16,8,bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,0);
+
+        /* predict and add to top field from bottom field */
+        pred(oldref,1,cur,0,
+          lx<<1,16,8,bx,by>>1,DMV[0][0],DMV[0][1],1);
+
+        /* predict and add to bottom field from top field */
+        pred(oldref,0,cur,1,
+          lx<<1,16,8,bx,by>>1,DMV[1][0],DMV[1][1],1);
+      }
+      else
+      {
+        /* invalid motion_type in frame picture */
+        if (!quiet)
+          fprintf(stderr,"invalid motion_type\n");
+      }
+    }
+    else /* TOP_FIELD or BOTTOM_FIELD */
+    {
+      /* field picture */
+
+      currentfield = (pict_struct==BOTTOM_FIELD);
+
+      /* determine which frame to use for prediction */
+      if ((pict_type==P_TYPE) && secondfield
+          && (currentfield!=mv_field_sel[0][0]))
+        predframe = newref; /* same frame */
+      else
+        predframe = oldref; /* previous frame */
+
+      if ((motion_type==MC_FIELD) || !(mb_type & MB_FORWARD))
+      {
+        /* field-based prediction in field picture */
+        pred(predframe,mv_field_sel[0][0],cur,currentfield,
+          lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
+      }
+      else if (motion_type==MC_16X8)
+      {
+        /* 16 x 8 motion compensation in field picture */
+
+        /* upper half */
+        pred(predframe,mv_field_sel[0][0],cur,currentfield,
+          lx<<1,16,8,bx,by,PMV[0][0][0],PMV[0][0][1],0);
+
+        /* determine which frame to use for lower half prediction */
+        if ((pict_type==P_TYPE) && secondfield
+            && (currentfield!=mv_field_sel[1][0]))
+          predframe = newref; /* same frame */
+        else
+          predframe = oldref; /* previous frame */
+
+        /* lower half */
+        pred(predframe,mv_field_sel[1][0],cur,currentfield,
+          lx<<1,16,8,bx,by+8,PMV[1][0][0],PMV[1][0][1],0);
+      }
+      else if (motion_type==MC_DMV)
+      {
+        /* dual prime prediction */
+
+        /* determine which frame to use for prediction */
+        if (secondfield)
+          predframe = newref; /* same frame */
+        else
+          predframe = oldref; /* previous frame */
+
+        /* calculate derived motion vectors */
+        calc_DMV(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]);
+
+        /* predict from field of same parity */
+        pred(oldref,currentfield,cur,currentfield,
+          lx<<1,16,16,bx,by,PMV[0][0][0],PMV[0][0][1],0);
+
+        /* predict from field of opposite parity */
+        pred(predframe,!currentfield,cur,currentfield,
+          lx<<1,16,16,bx,by,DMV[0][0],DMV[0][1],1);
+      }
+      else
+      {
+        /* invalid motion_type in field picture */
+        if (!quiet)
+          fprintf(stderr,"invalid motion_type\n");
+      }
+    }
+    addflag = 1; /* next prediction (if any) will be averaged with this one */
+  }
+
+  if (mb_type & MB_BACKWARD)
+  {
+    /* backward prediction */
+
+    if (pict_struct==FRAME_PICTURE)
+    {
+      /* frame picture */
+
+      if (motion_type==MC_FRAME)
+      {
+        /* frame-based prediction in frame picture */
+        pred(newref,0,cur,0,
+          lx,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
+      }
+      else
+      {
+        /* field-based prediction in frame picture
+         *
+         * note scaling of the vertical coordinates (by, PMV[][1][1])
+         * from frame to field!
+         */
+
+        /* top field prediction */
+        pred(newref,mv_field_sel[0][1],cur,0,
+          lx<<1,16,8,bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,addflag);
+
+        /* bottom field prediction */
+        pred(newref,mv_field_sel[1][1],cur,1,
+          lx<<1,16,8,bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,addflag);
+      }
+    }
+    else /* TOP_FIELD or BOTTOM_FIELD */
+    {
+      /* field picture */
+
+      currentfield = (pict_struct==BOTTOM_FIELD);
+
+      if (motion_type==MC_FIELD)
+      {
+        /* field-based prediction in field picture */
+        pred(newref,mv_field_sel[0][1],cur,currentfield,
+          lx<<1,16,16,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
+      }
+      else if (motion_type==MC_16X8)
+      {
+        /* 16 x 8 motion compensation in field picture */
+
+        /* upper half */
+        pred(newref,mv_field_sel[0][1],cur,currentfield,
+          lx<<1,16,8,bx,by,PMV[0][1][0],PMV[0][1][1],addflag);
+
+        /* lower half */
+        pred(newref,mv_field_sel[1][1],cur,currentfield,
+          lx<<1,16,8,bx,by+8,PMV[1][1][0],PMV[1][1][1],addflag);
+      }
+      else
+      {
+        /* invalid motion_type in field picture */
+        if (!quiet)
+          fprintf(stderr,"invalid motion_type\n");
+      }
+    }
+  }
+}
+
+/* predict a rectangular block (all three components)
+ *
+ * src:     source frame (Y,U,V)
+ * sfield:  source field select (0: frame or top field, 1: bottom field)
+ * dst:     destination frame (Y,U,V)
+ * dfield:  destination field select (0: frame or top field, 1: bottom field)
+ *
+ * the following values are in luminance picture (frame or field) dimensions
+ * lx:      distance of vertically adjacent pels (selects frame or field pred.)
+ * w,h:     width and height of block (only 16x16 or 16x8 are used)
+ * x,y:     coordinates of destination block
+ * dx,dy:   half pel motion vector
+ * addflag: store or add (= average) prediction
+ */
+static void pred(src,sfield,dst,dfield,lx,w,h,x,y,dx,dy,addflag)
+unsigned char *src[];
+int sfield;
+unsigned char *dst[];
+int dfield;
+int lx;
+int w, h;
+int x, y;
+int dx, dy;
+int addflag;
+{
+  int cc;
+
+  for (cc=0; cc<3; cc++)
+  {
+    if (cc==1)
+    {
+      /* scale for color components */
+      if (chroma_format==CHROMA420)
+      {
+        /* vertical */
+        h >>= 1; y >>= 1; dy /= 2;
+      }
+      if (chroma_format!=CHROMA444)
+      {
+        /* horizontal */
+        w >>= 1; x >>= 1; dx /= 2;
+        lx >>= 1;
+      }
+    }
+    pred_comp(src[cc]+(sfield?lx>>1:0),dst[cc]+(dfield?lx>>1:0),
+      lx,w,h,x,y,dx,dy,addflag);
+  }
+}
+
+/* low level prediction routine
+ *
+ * src:     prediction source
+ * dst:     prediction destination
+ * lx:      line width (for both src and dst)
+ * x,y:     destination coordinates
+ * dx,dy:   half pel motion vector
+ * w,h:     size of prediction block
+ * addflag: store or add prediction
+ */
+
+static void pred_comp(src,dst,lx,w,h,x,y,dx,dy,addflag)
+unsigned char *src;
+unsigned char *dst;
+int lx;
+int w, h;
+int x, y;
+int dx, dy;
+int addflag;
+{
+  int xint, xh, yint, yh;
+  int i, j;
+  unsigned char *s, *d;
+
+  /* half pel scaling */
+  xint = dx>>1; /* integer part */
+  xh = dx & 1;  /* half pel flag */
+  yint = dy>>1;
+  yh = dy & 1;
+
+  /* origins */
+  s = src + lx*(y+yint) + (x+xint); /* motion vector */
+  d = dst + lx*y + x;
+
+  if (!xh && !yh)
+    if (addflag)
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = (unsigned int)(d[i]+s[i]+1)>>1;
+        s+= lx;
+        d+= lx;
+      }
+    else
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = s[i];
+        s+= lx;
+        d+= lx;
+      }
+  else if (!xh && yh)
+    if (addflag)
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = (d[i] + ((unsigned int)(s[i]+s[i+lx]+1)>>1)+1)>>1;
+        s+= lx;
+        d+= lx;
+      }
+    else
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = (unsigned int)(s[i]+s[i+lx]+1)>>1;
+        s+= lx;
+        d+= lx;
+      }
+  else if (xh && !yh)
+    if (addflag)
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+1)>>1)+1)>>1;
+        s+= lx;
+        d+= lx;
+      }
+    else
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = (unsigned int)(s[i]+s[i+1]+1)>>1;
+        s+= lx;
+        d+= lx;
+      }
+  else /* if (xh && yh) */
+    if (addflag)
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2)+1)>>1;
+        s+= lx;
+        d+= lx;
+      }
+    else
+      for (j=0; j<h; j++)
+      {
+        for (i=0; i<w; i++)
+          d[i] = (unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2;
+        s+= lx;
+        d+= lx;
+      }
+}
+
+
+/* calculate derived motion vectors (DMV) for dual prime prediction
+ * dmvector[2]: differential motion vectors (-1,0,+1)
+ * mvx,mvy: motion vector (for same parity)
+ *
+ * DMV[2][2]: derived motion vectors (for opposite parity)
+ *
+ * uses global variables pict_struct and topfirst
+ *
+ * Notes:
+ *  - all vectors are in field coordinates (even for frame pictures)
+ */
+
+static void calc_DMV(DMV,dmvector,mvx,mvy)
+int DMV[][2];
+int *dmvector;
+int mvx, mvy;
+{
+  if (pict_struct==FRAME_PICTURE)
+  {
+    if (topfirst)
+    {
+      /* vector for prediction of top field from bottom field */
+      DMV[0][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
+      DMV[0][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] - 1;
+
+      /* vector for prediction of bottom field from top field */
+      DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
+      DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
+    }
+    else
+    {
+      /* vector for prediction of top field from bottom field */
+      DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
+      DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
+
+      /* vector for prediction of bottom field from top field */
+      DMV[1][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
+      DMV[1][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] + 1;
+    }
+  }
+  else
+  {
+    /* vector for prediction from field of opposite 'parity' */
+    DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
+    DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
+
+    /* correct for vertical field shift */
+    if (pict_struct==TOP_FIELD)
+      DMV[0][1]--;
+    else
+      DMV[0][1]++;
+  }
+}
+
+static void clearblock(cur,i0,j0)
+unsigned char *cur[];
+int i0, j0;
+{
+  int i, j, w, h;
+  unsigned char *p;
+
+  p = cur[0] + ((pict_struct==BOTTOM_FIELD) ? width : 0) + i0 + width2*j0;
+
+  for (j=0; j<16; j++)
+  {
+    for (i=0; i<16; i++)
+      p[i] = 128;
+    p+= width2;
+  }
+
+  w = h = 16;
+
+  if (chroma_format!=CHROMA444)
+  {
+    i0>>=1; w>>=1;
+  }
+
+  if (chroma_format==CHROMA420)
+  {
+    j0>>=1; h>>=1;
+  }
+
+  p = cur[1] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
+             + chrom_width2*j0;
+
+  for (j=0; j<h; j++)
+  {
+    for (i=0; i<w; i++)
+      p[i] = 128;
+    p+= chrom_width2;
+  }
+
+  p = cur[2] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
+             + chrom_width2*j0;
+
+  for (j=0; j<h; j++)
+  {
+    for (i=0; i<w; i++)
+      p[i] = 128;
+    p+= chrom_width2;
+  }
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/putbits.c b/src/gdcmmpeg2/src/mpeg2enc/putbits.c
new file mode 100644 (file)
index 0000000..4497177
--- /dev/null
@@ -0,0 +1,87 @@
+/* putbits.c, bit-level output                                              */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+
+extern FILE *outfile; /* the only global var we need here */
+
+/* private data */
+static unsigned char outbfr;
+static int outcnt;
+static int bytecnt;
+
+/* initialize buffer, call once before first putbits or alignbits */
+void initbits()
+{
+  outcnt = 8;
+  bytecnt = 0;
+}
+
+/* write rightmost n (0<=n<=32) bits of val to outfile */
+void putbits(val,n)
+int val;
+int n;
+{
+  int i;
+  unsigned int mask;
+
+  mask = 1 << (n-1); /* selects first (leftmost) bit */
+
+  for (i=0; i<n; i++)
+  {
+    outbfr <<= 1;
+
+    if (val & mask)
+      outbfr|= 1;
+
+    mask >>= 1; /* select next bit */
+    outcnt--;
+
+    if (outcnt==0) /* 8 bit buffer full */
+    {
+      putc(outbfr,outfile);
+      outcnt = 8;
+      bytecnt++;
+    }
+  }
+}
+
+/* zero bit stuffing to next byte boundary (5.2.3, 6.2.1) */
+void alignbits()
+{
+  if (outcnt!=8)
+    putbits(0,outcnt);
+}
+
+/* return total number of generated bits */
+int bitcount()
+{
+  return 8*bytecnt + (8-outcnt);
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/puthdr.c b/src/gdcmmpeg2/src/mpeg2enc/puthdr.c
new file mode 100644 (file)
index 0000000..2acd159
--- /dev/null
@@ -0,0 +1,221 @@
+/* puthdr.c, generation of headers                                          */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+static int frametotc _ANSI_ARGS_((int frame));
+
+/* generate sequence header (6.2.2.1, 6.3.3)
+ *
+ * matrix download not implemented
+ */
+void putseqhdr()
+{
+  int i;
+
+  alignbits();
+  putbits(SEQ_START_CODE,32); /* sequence_header_code */
+  putbits(horizontal_size,12); /* horizontal_size_value */
+  putbits(vertical_size,12); /* vertical_size_value */
+  putbits(aspectratio,4); /* aspect_ratio_information */
+  putbits(frame_rate_code,4); /* frame_rate_code */
+  putbits((int)ceil(bit_rate/400.0),18); /* bit_rate_value */
+  putbits(1,1); /* marker_bit */
+  putbits(vbv_buffer_size,10); /* vbv_buffer_size_value */
+  putbits(constrparms,1); /* constrained_parameters_flag */
+
+  putbits(load_iquant,1); /* load_intra_quantizer_matrix */
+  if (load_iquant)
+    for (i=0; i<64; i++)  /* matrices are always downloaded in zig-zag order */
+      putbits(intra_q[zig_zag_scan[i]],8); /* intra_quantizer_matrix */
+
+  putbits(load_niquant,1); /* load_non_intra_quantizer_matrix */
+  if (load_niquant)
+    for (i=0; i<64; i++)
+      putbits(inter_q[zig_zag_scan[i]],8); /* non_intra_quantizer_matrix */
+}
+
+/* generate sequence extension (6.2.2.3, 6.3.5) header (MPEG-2 only) */
+void putseqext()
+{
+  alignbits();
+  putbits(EXT_START_CODE,32); /* extension_start_code */
+  putbits(SEQ_ID,4); /* extension_start_code_identifier */
+  putbits((profile<<4)|level,8); /* profile_and_level_indication */
+  putbits(prog_seq,1); /* progressive sequence */
+  putbits(chroma_format,2); /* chroma_format */
+  putbits(horizontal_size>>12,2); /* horizontal_size_extension */
+  putbits(vertical_size>>12,2); /* vertical_size_extension */
+  putbits(((int)ceil(bit_rate/400.0))>>18,12); /* bit_rate_extension */
+  putbits(1,1); /* marker_bit */
+  putbits(vbv_buffer_size>>10,8); /* vbv_buffer_size_extension */
+  putbits(0,1); /* low_delay  -- currently not implemented */
+  putbits(0,2); /* frame_rate_extension_n */
+  putbits(0,5); /* frame_rate_extension_d */
+}
+
+/* generate sequence display extension (6.2.2.4, 6.3.6)
+ *
+ * content not yet user setable
+ */
+void putseqdispext()
+{
+  alignbits();
+  putbits(EXT_START_CODE,32); /* extension_start_code */
+  putbits(DISP_ID,4); /* extension_start_code_identifier */
+  putbits(video_format,3); /* video_format */
+  putbits(1,1); /* colour_description */
+  putbits(color_primaries,8); /* colour_primaries */
+  putbits(transfer_characteristics,8); /* transfer_characteristics */
+  putbits(matrix_coefficients,8); /* matrix_coefficients */
+  putbits(display_horizontal_size,14); /* display_horizontal_size */
+  putbits(1,1); /* marker_bit */
+  putbits(display_vertical_size,14); /* display_vertical_size */
+}
+
+/* output a zero terminated string as user data (6.2.2.2.2, 6.3.4.1)
+ *
+ * string must not emulate start codes
+ */
+void putuserdata(userdata)
+char *userdata;
+{
+  alignbits();
+  putbits(USER_START_CODE,32); /* user_data_start_code */
+  while (*userdata)
+    putbits(*userdata++,8);
+}
+
+/* generate group of pictures header (6.2.2.6, 6.3.9)
+ *
+ * uses tc0 (timecode of first frame) and frame0 (number of first frame)
+ */
+void putgophdr(frame,closed_gop)
+int frame,closed_gop;
+{
+  int tc;
+
+  alignbits();
+  putbits(GOP_START_CODE,32); /* group_start_code */
+  tc = frametotc(tc0+frame);
+  putbits(tc,25); /* time_code */
+  putbits(closed_gop,1); /* closed_gop */
+  putbits(0,1); /* broken_link */
+}
+
+/* convert frame number to time_code
+ *
+ * drop_frame not implemented
+ */
+static int frametotc(frame)
+int frame;
+{
+  int fps, pict, sec, minute, hour, tc;
+
+  fps = (int)(frame_rate+0.5);
+  pict = frame%fps;
+  frame = (frame-pict)/fps;
+  sec = frame%60;
+  frame = (frame-sec)/60;
+  minute = frame%60;
+  frame = (frame-minute)/60;
+  hour = frame%24;
+  tc = (hour<<19) | (minute<<13) | (1<<12) | (sec<<6) | pict;
+
+  return tc;
+}
+
+/* generate picture header (6.2.3, 6.3.10) */
+void putpicthdr()
+{
+  alignbits();
+  putbits(PICTURE_START_CODE,32); /* picture_start_code */
+  calc_vbv_delay();
+  putbits(temp_ref,10); /* temporal_reference */
+  putbits(pict_type,3); /* picture_coding_type */
+  putbits(vbv_delay,16); /* vbv_delay */
+
+  if (pict_type==P_TYPE || pict_type==B_TYPE)
+  {
+    putbits(0,1); /* full_pel_forward_vector */
+    if (mpeg1)
+      putbits(forw_hor_f_code,3);
+    else
+      putbits(7,3); /* forward_f_code */
+  }
+
+  if (pict_type==B_TYPE)
+  {
+    putbits(0,1); /* full_pel_backward_vector */
+    if (mpeg1)
+      putbits(back_hor_f_code,3);
+    else
+      putbits(7,3); /* backward_f_code */
+  }
+
+  putbits(0,1); /* extra_bit_picture */
+}
+
+/* generate picture coding extension (6.2.3.1, 6.3.11)
+ *
+ * composite display information (v_axis etc.) not implemented
+ */
+void putpictcodext()
+{
+  alignbits();
+  putbits(EXT_START_CODE,32); /* extension_start_code */
+  putbits(CODING_ID,4); /* extension_start_code_identifier */
+  putbits(forw_hor_f_code,4); /* forward_horizontal_f_code */
+  putbits(forw_vert_f_code,4); /* forward_vertical_f_code */
+  putbits(back_hor_f_code,4); /* backward_horizontal_f_code */
+  putbits(back_vert_f_code,4); /* backward_vertical_f_code */
+  putbits(dc_prec,2); /* intra_dc_precision */
+  putbits(pict_struct,2); /* picture_structure */
+  putbits((pict_struct==FRAME_PICTURE)?topfirst:0,1); /* top_field_first */
+  putbits(frame_pred_dct,1); /* frame_pred_frame_dct */
+  putbits(0,1); /* concealment_motion_vectors  -- currently not implemented */
+  putbits(q_scale_type,1); /* q_scale_type */
+  putbits(intravlc,1); /* intra_vlc_format */
+  putbits(altscan,1); /* alternate_scan */
+  putbits(repeatfirst,1); /* repeat_first_field */
+  putbits(prog_frame,1); /* chroma_420_type */
+  putbits(prog_frame,1); /* progressive_frame */
+  putbits(0,1); /* composite_display_flag */
+}
+
+/* generate sequence_end_code (6.2.2) */
+void putseqend()
+{
+  alignbits();
+  putbits(SEQ_END_CODE,32);
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/putmpg.c b/src/gdcmmpeg2/src/mpeg2enc/putmpg.c
new file mode 100644 (file)
index 0000000..34889ac
--- /dev/null
@@ -0,0 +1,141 @@
+/* putmpg.c, block and motion vector encoding routines                      */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+#include "global.h"
+
+/* generate variable length codes for an intra-coded block (6.2.6, 6.3.17) */
+void putintrablk(blk,cc)
+short *blk;
+int cc;
+{
+  int n, dct_diff, run, signed_level;
+
+  /* DC coefficient (7.2.1) */
+  dct_diff = blk[0] - dc_dct_pred[cc]; /* difference to previous block */
+  dc_dct_pred[cc] = blk[0];
+
+  if (cc==0)
+    putDClum(dct_diff);
+  else
+    putDCchrom(dct_diff);
+
+  /* AC coefficients (7.2.2) */
+  run = 0;
+  for (n=1; n<64; n++)
+  {
+    /* use appropriate entropy scanning pattern */
+    signed_level = blk[(altscan ? alternate_scan : zig_zag_scan)[n]];
+    if (signed_level!=0)
+    {
+      putAC(run,signed_level,intravlc);
+      run = 0;
+    }
+    else
+      run++; /* count zero coefficients */
+  }
+
+  /* End of Block -- normative block punctuation */
+  if (intravlc)
+    putbits(6,4); /* 0110 (Table B-15) */
+  else
+    putbits(2,2); /* 10 (Table B-14) */
+}
+
+/* generate variable length codes for a non-intra-coded block (6.2.6, 6.3.17) */
+void putnonintrablk(blk)
+short *blk;
+{
+  int n, run, signed_level, first;
+
+  run = 0;
+  first = 1;
+
+  for (n=0; n<64; n++)
+  {
+    /* use appropriate entropy scanning pattern */
+    signed_level = blk[(altscan ? alternate_scan : zig_zag_scan)[n]];
+
+    if (signed_level!=0)
+    {
+      if (first)
+      {
+        /* first coefficient in non-intra block */
+        putACfirst(run,signed_level);
+        first = 0;
+      }
+      else
+        putAC(run,signed_level,0);
+
+      run = 0;
+    }
+    else
+      run++; /* count zero coefficients */
+  }
+
+  /* End of Block -- normative block punctuation  */
+  putbits(2,2);
+}
+
+/* generate variable length code for a motion vector component (7.6.3.1) */
+void putmv(dmv,f_code)
+int dmv,f_code;
+{
+  int r_size, f, vmin, vmax, dv, temp, motion_code, motion_residual;
+
+  r_size = f_code - 1; /* number of fixed length code ('residual') bits */
+  f = 1<<r_size;
+  vmin = -16*f; /* lower range limit */
+  vmax = 16*f - 1; /* upper range limit */
+  dv = 32*f;
+
+  /* fold vector difference into [vmin...vmax] */
+  if (dmv>vmax)
+    dmv-= dv;
+  else if (dmv<vmin)
+    dmv+= dv;
+
+  /* check value */
+  if (dmv<vmin || dmv>vmax)
+    if (!quiet)
+      fprintf(stderr,"invalid motion vector\n");
+
+  /* split dmv into motion_code and motion_residual */
+  temp = ((dmv<0) ? -dmv : dmv) + f - 1;
+  motion_code = temp>>r_size;
+  if (dmv<0)
+    motion_code = -motion_code;
+  motion_residual = temp & (f-1);
+
+  putmotioncode(motion_code); /* variable length code */
+
+  if (r_size!=0 && motion_code!=0)
+    putbits(motion_residual,r_size); /* fixed length code */
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/putpic.c b/src/gdcmmpeg2/src/mpeg2enc/putpic.c
new file mode 100644 (file)
index 0000000..8fb7d95
--- /dev/null
@@ -0,0 +1,376 @@
+/* putpic.c, block and motion vector encoding routines                      */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+static void putmvs _ANSI_ARGS_((int MV[2][2][2], int PMV[2][2][2],
+  int mv_field_sel[2][2], int dmvector[2], int s, int motion_type,
+  int hor_f_code, int vert_f_code));
+
+/* quantization / variable length encoding of a complete picture */
+void putpict(frame)
+unsigned char *frame;
+{
+  int i, j, k, comp, cc;
+  int mb_type;
+  int PMV[2][2][2];
+  int prev_mquant;
+  int cbp, MBAinc;
+
+  rc_init_pict(frame); /* set up rate control */
+
+  /* picture header and picture coding extension */
+  putpicthdr();
+
+  if (!mpeg1)
+    putpictcodext();
+
+  prev_mquant = rc_start_mb(); /* initialize quantization parameter */
+
+  k = 0;
+
+  for (j=0; j<mb_height2; j++)
+  {
+    /* macroblock row loop */
+
+    for (i=0; i<mb_width; i++)
+    {
+      /* macroblock loop */
+      if (i==0)
+      {
+        /* slice header (6.2.4) */
+        alignbits();
+
+        if (mpeg1 || vertical_size<=2800)
+          putbits(SLICE_MIN_START+j,32); /* slice_start_code */
+        else
+        {
+          putbits(SLICE_MIN_START+(j&127),32); /* slice_start_code */
+          putbits(j>>7,3); /* slice_vertical_position_extension */
+        }
+  
+        /* quantiser_scale_code */
+        putbits(q_scale_type ? map_non_linear_mquant[prev_mquant]
+                             : prev_mquant >> 1, 5);
+  
+        putbits(0,1); /* extra_bit_slice */
+  
+        /* reset predictors */
+
+        for (cc=0; cc<3; cc++)
+          dc_dct_pred[cc] = 0;
+
+        PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
+        PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
+  
+        MBAinc = i + 1; /* first MBAinc denotes absolute position */
+      }
+
+      mb_type = mbinfo[k].mb_type;
+
+      /* determine mquant (rate control) */
+      mbinfo[k].mquant = rc_calc_mquant(k);
+
+      /* quantize macroblock */
+      if (mb_type & MB_INTRA)
+      {
+        for (comp=0; comp<block_count; comp++)
+          quant_intra(blocks[k*block_count+comp],blocks[k*block_count+comp],
+                      dc_prec,intra_q,mbinfo[k].mquant);
+        mbinfo[k].cbp = cbp = (1<<block_count) - 1;
+      }
+      else
+      {
+        cbp = 0;
+        for (comp=0;comp<block_count;comp++)
+          cbp = (cbp<<1) | quant_non_intra(blocks[k*block_count+comp],
+                                           blocks[k*block_count+comp],
+                                           inter_q,mbinfo[k].mquant);
+
+        mbinfo[k].cbp = cbp;
+
+        if (cbp)
+          mb_type|= MB_PATTERN;
+      }
+
+      /* output mquant if it has changed */
+      if (cbp && prev_mquant!=mbinfo[k].mquant)
+        mb_type|= MB_QUANT;
+
+      /* check if macroblock can be skipped */
+      if (i!=0 && i!=mb_width-1 && !cbp)
+      {
+        /* no DCT coefficients and neither first nor last macroblock of slice */
+
+        if (pict_type==P_TYPE && !(mb_type&MB_FORWARD))
+        {
+          /* P picture, no motion vectors -> skip */
+
+          /* reset predictors */
+
+          for (cc=0; cc<3; cc++)
+            dc_dct_pred[cc] = 0;
+
+          PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
+          PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
+
+          mbinfo[k].mb_type = mb_type;
+          mbinfo[k].skipped = 1;
+          MBAinc++;
+          k++;
+          continue;
+        }
+
+        if (pict_type==B_TYPE && pict_struct==FRAME_PICTURE
+            && mbinfo[k].motion_type==MC_FRAME
+            && ((mbinfo[k-1].mb_type^mb_type)&(MB_FORWARD|MB_BACKWARD))==0
+            && (!(mb_type&MB_FORWARD) ||
+                (PMV[0][0][0]==mbinfo[k].MV[0][0][0] &&
+                 PMV[0][0][1]==mbinfo[k].MV[0][0][1]))
+            && (!(mb_type&MB_BACKWARD) ||
+                (PMV[0][1][0]==mbinfo[k].MV[0][1][0] &&
+                 PMV[0][1][1]==mbinfo[k].MV[0][1][1])))
+        {
+          /* conditions for skipping in B frame pictures:
+           * - must be frame predicted
+           * - must be the same prediction type (forward/backward/interp.)
+           *   as previous macroblock
+           * - relevant vectors (forward/backward/both) have to be the same
+           *   as in previous macroblock
+           */
+
+          mbinfo[k].mb_type = mb_type;
+          mbinfo[k].skipped = 1;
+          MBAinc++;
+          k++;
+          continue;
+        }
+
+        if (pict_type==B_TYPE && pict_struct!=FRAME_PICTURE
+            && mbinfo[k].motion_type==MC_FIELD
+            && ((mbinfo[k-1].mb_type^mb_type)&(MB_FORWARD|MB_BACKWARD))==0
+            && (!(mb_type&MB_FORWARD) ||
+                (PMV[0][0][0]==mbinfo[k].MV[0][0][0] &&
+                 PMV[0][0][1]==mbinfo[k].MV[0][0][1] &&
+                 mbinfo[k].mv_field_sel[0][0]==(pict_struct==BOTTOM_FIELD)))
+            && (!(mb_type&MB_BACKWARD) ||
+                (PMV[0][1][0]==mbinfo[k].MV[0][1][0] &&
+                 PMV[0][1][1]==mbinfo[k].MV[0][1][1] &&
+                 mbinfo[k].mv_field_sel[0][1]==(pict_struct==BOTTOM_FIELD))))
+        {
+          /* conditions for skipping in B field pictures:
+           * - must be field predicted
+           * - must be the same prediction type (forward/backward/interp.)
+           *   as previous macroblock
+           * - relevant vectors (forward/backward/both) have to be the same
+           *   as in previous macroblock
+           * - relevant motion_vertical_field_selects have to be of same
+           *   parity as current field
+           */
+
+          mbinfo[k].mb_type = mb_type;
+          mbinfo[k].skipped = 1;
+          MBAinc++;
+          k++;
+          continue;
+        }
+      }
+
+      /* macroblock cannot be skipped */
+      mbinfo[k].skipped = 0;
+
+      /* there's no VLC for 'No MC, Not Coded':
+       * we have to transmit (0,0) motion vectors
+       */
+      if (pict_type==P_TYPE && !cbp && !(mb_type&MB_FORWARD))
+        mb_type|= MB_FORWARD;
+
+      putaddrinc(MBAinc); /* macroblock_address_increment */
+      MBAinc = 1;
+
+      putmbtype(pict_type,mb_type); /* macroblock type */
+
+      if (mb_type & (MB_FORWARD|MB_BACKWARD) && !frame_pred_dct)
+        putbits(mbinfo[k].motion_type,2);
+
+      if (pict_struct==FRAME_PICTURE && cbp && !frame_pred_dct)
+        putbits(mbinfo[k].dct_type,1);
+
+      if (mb_type & MB_QUANT)
+      {
+        putbits(q_scale_type ? map_non_linear_mquant[mbinfo[k].mquant]
+                             : mbinfo[k].mquant>>1,5);
+        prev_mquant = mbinfo[k].mquant;
+      }
+
+      if (mb_type & MB_FORWARD)
+      {
+        /* forward motion vectors, update predictors */
+        putmvs(mbinfo[k].MV,PMV,mbinfo[k].mv_field_sel,mbinfo[k].dmvector,0,
+          mbinfo[k].motion_type,forw_hor_f_code,forw_vert_f_code);
+      }
+
+      if (mb_type & MB_BACKWARD)
+      {
+        /* backward motion vectors, update predictors */
+        putmvs(mbinfo[k].MV,PMV,mbinfo[k].mv_field_sel,mbinfo[k].dmvector,1,
+          mbinfo[k].motion_type,back_hor_f_code,back_vert_f_code);
+      }
+
+      if (mb_type & MB_PATTERN)
+      {
+        putcbp((cbp >> (block_count-6)) & 63);
+        if (chroma_format!=CHROMA420)
+          putbits(cbp,block_count-6);
+      }
+
+      for (comp=0; comp<block_count; comp++)
+      {
+        /* block loop */
+        if (cbp & (1<<(block_count-1-comp)))
+        {
+          if (mb_type & MB_INTRA)
+          {
+            cc = (comp<4) ? 0 : (comp&1)+1;
+            putintrablk(blocks[k*block_count+comp],cc);
+          }
+          else
+            putnonintrablk(blocks[k*block_count+comp]);
+        }
+      }
+
+      /* reset predictors */
+      if (!(mb_type & MB_INTRA))
+        for (cc=0; cc<3; cc++)
+          dc_dct_pred[cc] = 0;
+
+      if (mb_type & MB_INTRA || (pict_type==P_TYPE && !(mb_type & MB_FORWARD)))
+      {
+        PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
+        PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
+      }
+
+      mbinfo[k].mb_type = mb_type;
+      k++;
+    }
+  }
+
+  rc_update_pict();
+  vbv_end_of_picture();
+}
+
+
+/* output motion vectors (6.2.5.2, 6.3.16.2)
+ *
+ * this routine also updates the predictions for motion vectors (PMV)
+ */
+static void putmvs(MV,PMV,mv_field_sel,dmvector,s,motion_type,
+  hor_f_code,vert_f_code)
+int MV[2][2][2],PMV[2][2][2];
+int mv_field_sel[2][2];
+int dmvector[2];
+int s,motion_type,hor_f_code,vert_f_code;
+{
+  if (pict_struct==FRAME_PICTURE)
+  {
+    if (motion_type==MC_FRAME)
+    {
+      /* frame prediction */
+      putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code);
+      putmv(MV[0][s][1]-PMV[0][s][1],vert_f_code);
+      PMV[0][s][0]=PMV[1][s][0]=MV[0][s][0];
+      PMV[0][s][1]=PMV[1][s][1]=MV[0][s][1];
+    }
+    else if (motion_type==MC_FIELD)
+    {
+      /* field prediction */
+      putbits(mv_field_sel[0][s],1);
+      putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code);
+      putmv((MV[0][s][1]>>1)-(PMV[0][s][1]>>1),vert_f_code);
+      putbits(mv_field_sel[1][s],1);
+      putmv(MV[1][s][0]-PMV[1][s][0],hor_f_code);
+      putmv((MV[1][s][1]>>1)-(PMV[1][s][1]>>1),vert_f_code);
+      PMV[0][s][0]=MV[0][s][0];
+      PMV[0][s][1]=MV[0][s][1];
+      PMV[1][s][0]=MV[1][s][0];
+      PMV[1][s][1]=MV[1][s][1];
+    }
+    else
+    {
+      /* dual prime prediction */
+      putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code);
+      putdmv(dmvector[0]);
+      putmv((MV[0][s][1]>>1)-(PMV[0][s][1]>>1),vert_f_code);
+      putdmv(dmvector[1]);
+      PMV[0][s][0]=PMV[1][s][0]=MV[0][s][0];
+      PMV[0][s][1]=PMV[1][s][1]=MV[0][s][1];
+    }
+  }
+  else
+  {
+    /* field picture */
+    if (motion_type==MC_FIELD)
+    {
+      /* field prediction */
+      putbits(mv_field_sel[0][s],1);
+      putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code);
+      putmv(MV[0][s][1]-PMV[0][s][1],vert_f_code);
+      PMV[0][s][0]=PMV[1][s][0]=MV[0][s][0];
+      PMV[0][s][1]=PMV[1][s][1]=MV[0][s][1];
+    }
+    else if (motion_type==MC_16X8)
+    {
+      /* 16x8 prediction */
+      putbits(mv_field_sel[0][s],1);
+      putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code);
+      putmv(MV[0][s][1]-PMV[0][s][1],vert_f_code);
+      putbits(mv_field_sel[1][s],1);
+      putmv(MV[1][s][0]-PMV[1][s][0],hor_f_code);
+      putmv(MV[1][s][1]-PMV[1][s][1],vert_f_code);
+      PMV[0][s][0]=MV[0][s][0];
+      PMV[0][s][1]=MV[0][s][1];
+      PMV[1][s][0]=MV[1][s][0];
+      PMV[1][s][1]=MV[1][s][1];
+    }
+    else
+    {
+      /* dual prime prediction */
+      putmv(MV[0][s][0]-PMV[0][s][0],hor_f_code);
+      putdmv(dmvector[0]);
+      putmv(MV[0][s][1]-PMV[0][s][1],vert_f_code);
+      putdmv(dmvector[1]);
+      PMV[0][s][0]=PMV[1][s][0]=MV[0][s][0];
+      PMV[0][s][1]=PMV[1][s][1]=MV[0][s][1];
+    }
+  }
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/putseq.c b/src/gdcmmpeg2/src/mpeg2enc/putseq.c
new file mode 100644 (file)
index 0000000..d41387a
--- /dev/null
@@ -0,0 +1,324 @@
+/* putseq.c, sequence level routines                                        */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+#include "global.h"
+
+void putseq()
+{
+  /* this routine assumes (N % M) == 0 */
+  int i, j, k, f, f0, n, np, nb, sxf, syf, sxb, syb;
+  int ipflag;
+  FILE *fd;
+  char name[256];
+  unsigned char *neworg[3], *newref[3];
+  static char ipb[5] = {' ','I','P','B','D'};
+
+  rc_init_seq(); /* initialize rate control */
+
+  /* sequence header, sequence extension and sequence display extension */
+  putseqhdr();
+  if (!mpeg1)
+  {
+    putseqext();
+    putseqdispext();
+  }
+
+  /* optionally output some text data (description, copyright or whatever) */
+  if (strlen(id_string) > 1)
+    putuserdata(id_string);
+
+  /* loop through all frames in encoding/decoding order */
+  for (i=0; i<nframes; i++)
+  {
+    if (!quiet)
+    {
+      fprintf(stderr,"Encoding frame %d ",i);
+      fflush(stderr);
+    }
+
+    /* f0: lowest frame number in current GOP
+     *
+     * first GOP contains N-(M-1) frames,
+     * all other GOPs contain N frames
+     */
+    f0 = N*((i+(M-1))/N) - (M-1);
+
+    if (f0<0)
+      f0=0;
+
+    if (i==0 || (i-1)%M==0)
+    {
+      /* I or P frame */
+      for (j=0; j<3; j++)
+      {
+        /* shuffle reference frames */
+        neworg[j] = oldorgframe[j];
+        newref[j] = oldrefframe[j];
+        oldorgframe[j] = neworgframe[j];
+        oldrefframe[j] = newrefframe[j];
+        neworgframe[j] = neworg[j];
+        newrefframe[j] = newref[j];
+      }
+
+      /* f: frame number in display order */
+      f = (i==0) ? 0 : i+M-1;
+      if (f>=nframes)
+        f = nframes - 1;
+
+      if (i==f0) /* first displayed frame in GOP is I */
+      {
+        /* I frame */
+        pict_type = I_TYPE;
+        forw_hor_f_code = forw_vert_f_code = 15;
+        back_hor_f_code = back_vert_f_code = 15;
+
+        /* n: number of frames in current GOP
+         *
+         * first GOP contains (M-1) less (B) frames
+         */
+        n = (i==0) ? N-(M-1) : N;
+
+        /* last GOP may contain less frames */
+        if (n > nframes-f0)
+          n = nframes-f0;
+
+        /* number of P frames */
+        if (i==0)
+          np = (n + 2*(M-1))/M - 1; /* first GOP */
+        else
+          np = (n + (M-1))/M - 1;
+
+        /* number of B frames */
+        nb = n - np - 1;
+
+        rc_init_GOP(np,nb);
+
+        putgophdr(f0,i==0); /* set closed_GOP in first GOP only */
+      }
+      else
+      {
+        /* P frame */
+        pict_type = P_TYPE;
+        forw_hor_f_code = motion_data[0].forw_hor_f_code;
+        forw_vert_f_code = motion_data[0].forw_vert_f_code;
+        back_hor_f_code = back_vert_f_code = 15;
+        sxf = motion_data[0].sxf;
+        syf = motion_data[0].syf;
+      }
+    }
+    else
+    {
+      /* B frame */
+      for (j=0; j<3; j++)
+      {
+        neworg[j] = auxorgframe[j];
+        newref[j] = auxframe[j];
+      }
+
+      /* f: frame number in display order */
+      f = i - 1;
+      pict_type = B_TYPE;
+      n = (i-2)%M + 1; /* first B: n=1, second B: n=2, ... */
+      forw_hor_f_code = motion_data[n].forw_hor_f_code;
+      forw_vert_f_code = motion_data[n].forw_vert_f_code;
+      back_hor_f_code = motion_data[n].back_hor_f_code;
+      back_vert_f_code = motion_data[n].back_vert_f_code;
+      sxf = motion_data[n].sxf;
+      syf = motion_data[n].syf;
+      sxb = motion_data[n].sxb;
+      syb = motion_data[n].syb;
+    }
+
+    temp_ref = f - f0;
+    frame_pred_dct = frame_pred_dct_tab[pict_type-1];
+    q_scale_type = qscale_tab[pict_type-1];
+    intravlc = intravlc_tab[pict_type-1];
+    altscan = altscan_tab[pict_type-1];
+
+    fprintf(statfile,"\nFrame %d (#%d in display order):\n",i,f);
+    fprintf(statfile," picture_type=%c\n",ipb[pict_type]);
+    fprintf(statfile," temporal_reference=%d\n",temp_ref);
+    fprintf(statfile," frame_pred_frame_dct=%d\n",frame_pred_dct);
+    fprintf(statfile," q_scale_type=%d\n",q_scale_type);
+    fprintf(statfile," intra_vlc_format=%d\n",intravlc);
+    fprintf(statfile," alternate_scan=%d\n",altscan);
+
+    if (pict_type!=I_TYPE)
+    {
+      fprintf(statfile," forward search window: %d...%d / %d...%d\n",
+        -sxf,sxf,-syf,syf);
+      fprintf(statfile," forward vector range: %d...%d.5 / %d...%d.5\n",
+        -(4<<forw_hor_f_code),(4<<forw_hor_f_code)-1,
+        -(4<<forw_vert_f_code),(4<<forw_vert_f_code)-1);
+    }
+
+    if (pict_type==B_TYPE)
+    {
+      fprintf(statfile," backward search window: %d...%d / %d...%d\n",
+        -sxb,sxb,-syb,syb);
+      fprintf(statfile," backward vector range: %d...%d.5 / %d...%d.5\n",
+        -(4<<back_hor_f_code),(4<<back_hor_f_code)-1,
+        -(4<<back_vert_f_code),(4<<back_vert_f_code)-1);
+    }
+
+    sprintf(name,tplorg,f+frame0);
+    readframe(name,neworg);
+
+    if (fieldpic)
+    {
+      if (!quiet)
+      {
+        fprintf(stderr,"\nfirst field  (%s) ",topfirst ? "top" : "bot");
+        fflush(stderr);
+      }
+
+      pict_struct = topfirst ? TOP_FIELD : BOTTOM_FIELD;
+
+      motion_estimation(oldorgframe[0],neworgframe[0],
+                        oldrefframe[0],newrefframe[0],
+                        neworg[0],newref[0],
+                        sxf,syf,sxb,syb,mbinfo,0,0);
+
+      predict(oldrefframe,newrefframe,predframe,0,mbinfo);
+      dct_type_estimation(predframe[0],neworg[0],mbinfo);
+      transform(predframe,neworg,mbinfo,blocks);
+
+      putpict(neworg[0]);
+
+      for (k=0; k<mb_height2*mb_width; k++)
+      {
+        if (mbinfo[k].mb_type & MB_INTRA)
+          for (j=0; j<block_count; j++)
+            iquant_intra(blocks[k*block_count+j],blocks[k*block_count+j],
+                         dc_prec,intra_q,mbinfo[k].mquant);
+        else
+          for (j=0;j<block_count;j++)
+            iquant_non_intra(blocks[k*block_count+j],blocks[k*block_count+j],
+                             inter_q,mbinfo[k].mquant);
+      }
+
+      itransform(predframe,newref,mbinfo,blocks);
+      calcSNR(neworg,newref);
+      stats();
+
+      if (!quiet)
+      {
+        fprintf(stderr,"second field (%s) ",topfirst ? "bot" : "top");
+        fflush(stderr);
+      }
+
+      pict_struct = topfirst ? BOTTOM_FIELD : TOP_FIELD;
+
+      ipflag = (pict_type==I_TYPE);
+      if (ipflag)
+      {
+        /* first field = I, second field = P */
+        pict_type = P_TYPE;
+        forw_hor_f_code = motion_data[0].forw_hor_f_code;
+        forw_vert_f_code = motion_data[0].forw_vert_f_code;
+        back_hor_f_code = back_vert_f_code = 15;
+        sxf = motion_data[0].sxf;
+        syf = motion_data[0].syf;
+      }
+
+      motion_estimation(oldorgframe[0],neworgframe[0],
+                        oldrefframe[0],newrefframe[0],
+                        neworg[0],newref[0],
+                        sxf,syf,sxb,syb,mbinfo,1,ipflag);
+
+      predict(oldrefframe,newrefframe,predframe,1,mbinfo);
+      dct_type_estimation(predframe[0],neworg[0],mbinfo);
+      transform(predframe,neworg,mbinfo,blocks);
+
+      putpict(neworg[0]);
+
+      for (k=0; k<mb_height2*mb_width; k++)
+      {
+        if (mbinfo[k].mb_type & MB_INTRA)
+          for (j=0; j<block_count; j++)
+            iquant_intra(blocks[k*block_count+j],blocks[k*block_count+j],
+                         dc_prec,intra_q,mbinfo[k].mquant);
+        else
+          for (j=0;j<block_count;j++)
+            iquant_non_intra(blocks[k*block_count+j],blocks[k*block_count+j],
+                             inter_q,mbinfo[k].mquant);
+      }
+
+      itransform(predframe,newref,mbinfo,blocks);
+      calcSNR(neworg,newref);
+      stats();
+    }
+    else
+    {
+      pict_struct = FRAME_PICTURE;
+
+      /* do motion_estimation
+       *
+       * uses source frames (...orgframe) for full pel search
+       * and reconstructed frames (...refframe) for half pel search
+       */
+
+      motion_estimation(oldorgframe[0],neworgframe[0],
+                        oldrefframe[0],newrefframe[0],
+                        neworg[0],newref[0],
+                        sxf,syf,sxb,syb,mbinfo,0,0);
+
+      predict(oldrefframe,newrefframe,predframe,0,mbinfo);
+      dct_type_estimation(predframe[0],neworg[0],mbinfo);
+      transform(predframe,neworg,mbinfo,blocks);
+
+      putpict(neworg[0]);
+
+      for (k=0; k<mb_height*mb_width; k++)
+      {
+        if (mbinfo[k].mb_type & MB_INTRA)
+          for (j=0; j<block_count; j++)
+            iquant_intra(blocks[k*block_count+j],blocks[k*block_count+j],
+                         dc_prec,intra_q,mbinfo[k].mquant);
+        else
+          for (j=0;j<block_count;j++)
+            iquant_non_intra(blocks[k*block_count+j],blocks[k*block_count+j],
+                             inter_q,mbinfo[k].mquant);
+      }
+
+      itransform(predframe,newref,mbinfo,blocks);
+      calcSNR(neworg,newref);
+      stats();
+    }
+
+    sprintf(name,tplref,f+frame0);
+    writeframe(name,newref);
+
+  }
+
+  putseqend();
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/putvlc.c b/src/gdcmmpeg2/src/mpeg2enc/putvlc.c
new file mode 100644 (file)
index 0000000..cd4b8fa
--- /dev/null
@@ -0,0 +1,223 @@
+/* putvlc.c, generation of variable length codes                            */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+
+#include "config.h"
+#include "global.h"
+#include "vlc.h"
+
+/* private prototypes */
+static void putDC _ANSI_ARGS_((sVLCtable *tab, int val));
+
+/* generate variable length code for luminance DC coefficient */
+void putDClum(val)
+int val;
+{
+  putDC(DClumtab,val);
+}
+
+/* generate variable length code for chrominance DC coefficient */
+void putDCchrom(val)
+int val;
+{
+  putDC(DCchromtab,val);
+}
+
+/* generate variable length code for DC coefficient (7.2.1) */
+static void putDC(tab,val)
+sVLCtable *tab;
+int val;
+{
+  int absval, size;
+
+  absval = (val<0) ? -val : val; /* abs(val) */
+
+  if (absval>2047 || (mpeg1 && absval>255))
+  {
+    /* should never happen */
+    sprintf(errortext,"DC value out of range (%d)\n",val);
+    error(errortext);
+  }
+
+  /* compute dct_dc_size */
+  size = 0;
+
+  while (absval)
+  {
+    absval >>= 1;
+    size++;
+  }
+
+  /* generate VLC for dct_dc_size (Table B-12 or B-13) */
+  putbits(tab[size].code,tab[size].len);
+
+  /* append fixed length code (dc_dct_differential) */
+  if (size!=0)
+  {
+    if (val>=0)
+      absval = val;
+    else
+      absval = val + (1<<size) - 1; /* val + (2 ^ size) - 1 */
+    putbits(absval,size);
+  }
+}
+
+/* generate variable length code for first coefficient
+ * of a non-intra block (7.2.2.2) */
+void putACfirst(run,val)
+int run,val;
+{
+  if (run==0 && (val==1 || val==-1)) /* these are treated differently */
+    putbits(2|(val<0),2); /* generate '1s' (s=sign), (Table B-14, line 2) */
+  else
+    putAC(run,val,0); /* no difference for all others */
+}
+
+/* generate variable length code for other DCT coefficients (7.2.2) */
+void putAC(run,signed_level,vlcformat)
+int run,signed_level,vlcformat;
+{
+  int level, len;
+  VLCtable *ptab;
+
+  level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */
+
+  /* make sure run and level are valid */
+  if (run<0 || run>63 || level==0 || level>2047 || (mpeg1 && level>255))
+  {
+    sprintf(errortext,"AC value out of range (run=%d, signed_level=%d)\n",
+      run,signed_level);
+    error(errortext);
+  }
+
+  len = 0;
+
+  if (run<2 && level<41)
+  {
+    /* vlcformat selects either of Table B-14 / B-15 */
+    if (vlcformat)
+      ptab = &dct_code_tab1a[run][level-1];
+    else
+      ptab = &dct_code_tab1[run][level-1];
+
+    len = ptab->len;
+  }
+  else if (run<32 && level<6)
+  {
+    /* vlcformat selects either of Table B-14 / B-15 */
+    if (vlcformat)
+      ptab = &dct_code_tab2a[run-2][level-1];
+    else
+      ptab = &dct_code_tab2[run-2][level-1];
+
+    len = ptab->len;
+  }
+
+  if (len!=0) /* a VLC code exists */
+  {
+    putbits(ptab->code,len);
+    putbits(signed_level<0,1); /* sign */
+  }
+  else
+  {
+    /* no VLC for this (run, level) combination: use escape coding (7.2.2.3) */
+    putbits(1l,6); /* Escape */
+    putbits(run,6); /* 6 bit code for run */
+    if (mpeg1)
+    {
+      /* ISO/IEC 11172-2 uses a 8 or 16 bit code */
+      if (signed_level>127)
+        putbits(0,8);
+      if (signed_level<-127)
+        putbits(128,8);
+      putbits(signed_level,8);
+    }
+    else
+    {
+      /* ISO/IEC 13818-2 uses a 12 bit code, Table B-16 */
+      putbits(signed_level,12);
+    }
+  }
+}
+
+/* generate variable length code for macroblock_address_increment (6.3.16) */
+void putaddrinc(addrinc)
+int addrinc;
+{
+  while (addrinc>33)
+  {
+    putbits(0x08,11); /* macroblock_escape */
+    addrinc-= 33;
+  }
+
+  putbits(addrinctab[addrinc-1].code,addrinctab[addrinc-1].len);
+}
+
+/* generate variable length code for macroblock_type (6.3.16.1) */
+void putmbtype(pict_type,mb_type)
+int pict_type,mb_type;
+{
+  putbits(mbtypetab[pict_type-1][mb_type].code,
+          mbtypetab[pict_type-1][mb_type].len);
+}
+
+/* generate variable length code for motion_code (6.3.16.3) */
+void putmotioncode(motion_code)
+int motion_code;
+{
+  int abscode;
+
+  abscode = (motion_code>=0) ? motion_code : -motion_code; /* abs(motion_code) */
+  putbits(motionvectab[abscode].code,motionvectab[abscode].len);
+  if (motion_code!=0)
+    putbits(motion_code<0,1); /* sign, 0=positive, 1=negative */
+}
+
+/* generate variable length code for dmvector[t] (6.3.16.3), Table B-11 */
+void putdmv(dmv)
+int dmv;
+{
+  if (dmv==0)
+    putbits(0,1);
+  else if (dmv>0)
+    putbits(2,2);
+  else
+    putbits(3,2);
+}
+
+/* generate variable length code for coded_block_pattern (6.3.16.4)
+ *
+ * 4:2:2, 4:4:4 not implemented
+ */
+void putcbp(cbp)
+int cbp;
+{
+  putbits(cbptable[cbp].code,cbptable[cbp].len);
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/quantize.c b/src/gdcmmpeg2/src/mpeg2enc/quantize.c
new file mode 100644 (file)
index 0000000..4afeafb
--- /dev/null
@@ -0,0 +1,220 @@
+/* quantize.c, quantization / inverse quantization                          */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+#include "global.h"
+
+static void iquant1_intra _ANSI_ARGS_((short *src, short *dst,
+  int dc_prec, unsigned char *quant_mat, int mquant));
+static void iquant1_non_intra _ANSI_ARGS_((short *src, short *dst,
+  unsigned char *quant_mat, int mquant));
+
+/* Test Model 5 quantization
+ *
+ * this quantizer has a bias of 1/8 stepsize towards zero
+ * (except for the DC coefficient)
+ */
+int quant_intra(src,dst,dc_prec,quant_mat,mquant)
+short *src, *dst;
+int dc_prec;
+unsigned char *quant_mat;
+int mquant;
+{
+  int i;
+  int x, y, d;
+
+  x = src[0];
+  d = 8>>dc_prec; /* intra_dc_mult */
+  dst[0] = (x>=0) ? (x+(d>>1))/d : -((-x+(d>>1))/d); /* round(x/d) */
+
+  for (i=1; i<64; i++)
+  {
+    x = src[i];
+    d = quant_mat[i];
+    y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */
+    d = (3*mquant+2)>>2;
+    y = (y+d)/(2*mquant); /* (y+0.75*mquant) / (2*mquant) */
+
+    /* clip to syntax limits */
+    if (y > 255)
+    {
+      if (mpeg1)
+        y = 255;
+      else if (y > 2047)
+        y = 2047;
+    }
+
+    dst[i] = (x>=0) ? y : -y;
+
+#if 0
+    /* this quantizer is virtually identical to the above */
+    if (x<0)
+      x = -x;
+    d = mquant*quant_mat[i];
+    y = (16*x + ((3*d)>>3)) / d;
+    dst[i] = (src[i]<0) ? -y : y;
+#endif
+  }
+
+  return 1;
+}
+
+int quant_non_intra(src,dst,quant_mat,mquant)
+short *src, *dst;
+unsigned char *quant_mat;
+int mquant;
+{
+  int i;
+  int x, y, d;
+  int nzflag;
+
+  nzflag = 0;
+
+  for (i=0; i<64; i++)
+  {
+    x = src[i];
+    d = quant_mat[i];
+    y = (32*(x>=0 ? x : -x) + (d>>1))/d; /* round(32*x/quant_mat) */
+    y /= (2*mquant);
+
+    /* clip to syntax limits */
+    if (y > 255)
+    {
+      if (mpeg1)
+        y = 255;
+      else if (y > 2047)
+        y = 2047;
+    }
+
+    if ((dst[i] = (x>=0 ? y : -y)) != 0)
+      nzflag=1;
+  }
+
+  return nzflag;
+}
+
+/* MPEG-2 inverse quantization */
+void iquant_intra(src,dst,dc_prec,quant_mat,mquant)
+short *src, *dst;
+int dc_prec;
+unsigned char *quant_mat;
+int mquant;
+{
+  int i, val, sum;
+
+  if (mpeg1)
+    iquant1_intra(src,dst,dc_prec,quant_mat,mquant);
+  else
+  {
+    sum = dst[0] = src[0] << (3-dc_prec);
+    for (i=1; i<64; i++)
+    {
+      val = (int)(src[i]*quant_mat[i]*mquant)/16;
+      sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
+    }
+
+    /* mismatch control */
+    if ((sum&1)==0)
+      dst[63]^= 1;
+  }
+}
+
+void iquant_non_intra(src,dst,quant_mat,mquant)
+short *src, *dst;
+unsigned char *quant_mat;
+int mquant;
+{
+  int i, val, sum;
+
+  if (mpeg1)
+    iquant1_non_intra(src,dst,quant_mat,mquant);
+  else
+  {
+    sum = 0;
+    for (i=0; i<64; i++)
+    {
+      val = src[i];
+      if (val!=0)
+        val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32;
+      sum+= dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
+    }
+
+    /* mismatch control */
+    if ((sum&1)==0)
+      dst[63]^= 1;
+  }
+}
+
+/* MPEG-1 inverse quantization */
+static void iquant1_intra(src,dst,dc_prec,quant_mat,mquant)
+short *src, *dst;
+int dc_prec;
+unsigned char *quant_mat;
+int mquant;
+{
+  int i, val;
+
+  dst[0] = src[0] << (3-dc_prec);
+  for (i=1; i<64; i++)
+  {
+    val = (int)(src[i]*quant_mat[i]*mquant)/16;
+
+    /* mismatch control */
+    if ((val&1)==0 && val!=0)
+      val+= (val>0) ? -1 : 1;
+
+    /* saturation */
+    dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
+  }
+}
+
+static void iquant1_non_intra(src,dst,quant_mat,mquant)
+short *src, *dst;
+unsigned char *quant_mat;
+int mquant;
+{
+  int i, val;
+
+  for (i=0; i<64; i++)
+  {
+    val = src[i];
+    if (val!=0)
+    {
+      val = (int)((2*val+(val>0 ? 1 : -1))*quant_mat[i]*mquant)/32;
+
+      /* mismatch control */
+      if ((val&1)==0 && val!=0)
+        val+= (val>0) ? -1 : 1;
+    }
+
+    /* saturation */
+    dst[i] = (val>2047) ? 2047 : ((val<-2048) ? -2048 : val);
+  }
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/ratectl.c b/src/gdcmmpeg2/src/mpeg2enc/ratectl.c
new file mode 100644 (file)
index 0000000..28c3e53
--- /dev/null
@@ -0,0 +1,519 @@
+/* ratectl.c, bitrate control routines (linear quantization only currently) */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+static void calc_actj _ANSI_ARGS_((unsigned char *frame));
+static double var_sblk _ANSI_ARGS_((unsigned char *p, int lx));
+
+/* rate control variables */
+int Xi, Xp, Xb, r, d0i, d0p, d0b;
+double avg_act;
+static int R, T, d;
+static double actsum;
+static int Np, Nb, S, Q;
+static int prev_mquant;
+
+void rc_init_seq()
+{
+  /* reaction parameter (constant) */
+  if (r==0)  r = (int)floor(2.0*bit_rate/frame_rate + 0.5);
+
+  /* average activity */
+  if (avg_act==0.0)  avg_act = 400.0;
+
+  /* remaining # of bits in GOP */
+  R = 0;
+
+  /* global complexity measure */
+  if (Xi==0) Xi = (int)floor(160.0*bit_rate/115.0 + 0.5);
+  if (Xp==0) Xp = (int)floor( 60.0*bit_rate/115.0 + 0.5);
+  if (Xb==0) Xb = (int)floor( 42.0*bit_rate/115.0 + 0.5);
+
+  /* virtual buffer fullness */
+  if (d0i==0) d0i = (int)floor(10.0*r/31.0 + 0.5);
+  if (d0p==0) d0p = (int)floor(10.0*r/31.0 + 0.5);
+  if (d0b==0) d0b = (int)floor(1.4*10.0*r/31.0 + 0.5);
+/*
+  if (d0i==0) d0i = (int)floor(10.0*r/(qscale_tab[0] ? 56.0 : 31.0) + 0.5);
+  if (d0p==0) d0p = (int)floor(10.0*r/(qscale_tab[1] ? 56.0 : 31.0) + 0.5);
+  if (d0b==0) d0b = (int)floor(1.4*10.0*r/(qscale_tab[2] ? 56.0 : 31.0) + 0.5);
+*/
+
+  fprintf(statfile,"\nrate control: sequence initialization\n");
+  fprintf(statfile,
+    " initial global complexity measures (I,P,B): Xi=%d, Xp=%d, Xb=%d\n",
+    Xi, Xp, Xb);
+  fprintf(statfile," reaction parameter: r=%d\n", r);
+  fprintf(statfile,
+    " initial virtual buffer fullness (I,P,B): d0i=%d, d0p=%d, d0b=%d\n",
+    d0i, d0p, d0b);
+  fprintf(statfile," initial average activity: avg_act=%.1f\n", avg_act);
+}
+
+void rc_init_GOP(np,nb)
+int np,nb;
+{
+  R += (int) floor((1 + np + nb) * bit_rate / frame_rate + 0.5);
+  Np = fieldpic ? 2*np+1 : np;
+  Nb = fieldpic ? 2*nb : nb;
+
+  fprintf(statfile,"\nrate control: new group of pictures (GOP)\n");
+  fprintf(statfile," target number of bits for GOP: R=%d\n",R);
+  fprintf(statfile," number of P pictures in GOP: Np=%d\n",Np);
+  fprintf(statfile," number of B pictures in GOP: Nb=%d\n",Nb);
+}
+
+/* Note: we need to substitute K for the 1.4 and 1.0 constants -- this can
+   be modified to fit image content */
+
+/* Step 1: compute target bits for current picture being coded */
+void rc_init_pict(frame)
+unsigned char *frame;
+{
+  double Tmin;
+
+  switch (pict_type)
+  {
+  case I_TYPE:
+    T = (int) floor(R/(1.0+Np*Xp/(Xi*1.0)+Nb*Xb/(Xi*1.4)) + 0.5);
+    d = d0i;
+    break;
+  case P_TYPE:
+    T = (int) floor(R/(Np+Nb*1.0*Xb/(1.4*Xp)) + 0.5);
+    d = d0p;
+    break;
+  case B_TYPE:
+    T = (int) floor(R/(Nb+Np*1.4*Xp/(1.0*Xb)) + 0.5);
+    d = d0b;
+    break;
+  }
+
+  Tmin = (int) floor(bit_rate/(8.0*frame_rate) + 0.5);
+
+  if (T<Tmin)
+    T = Tmin;
+
+  S = bitcount();
+  Q = 0;
+
+  calc_actj(frame);
+  actsum = 0.0;
+
+  fprintf(statfile,"\nrate control: start of picture\n");
+  fprintf(statfile," target number of bits: T=%d\n",T);
+}
+
+static void calc_actj(frame)
+unsigned char *frame;
+{
+  int i,j,k;
+  unsigned char *p;
+  double actj,var;
+
+  k = 0;
+
+  for (j=0; j<height2; j+=16)
+    for (i=0; i<width; i+=16)
+    {
+      p = frame + ((pict_struct==BOTTOM_FIELD)?width:0) + i + width2*j;
+
+      /* take minimum spatial activity measure of luminance blocks */
+
+      actj = var_sblk(p,width2);
+      var = var_sblk(p+8,width2);
+      if (var<actj) actj = var;
+      var = var_sblk(p+8*width2,width2);
+      if (var<actj) actj = var;
+      var = var_sblk(p+8*width2+8,width2);
+      if (var<actj) actj = var;
+
+      if (!fieldpic && !prog_seq)
+      {
+        /* field */
+        var = var_sblk(p,width<<1);
+        if (var<actj) actj = var;
+        var = var_sblk(p+8,width<<1);
+        if (var<actj) actj = var;
+        var = var_sblk(p+width,width<<1);
+        if (var<actj) actj = var;
+        var = var_sblk(p+width+8,width<<1);
+        if (var<actj) actj = var;
+      }
+
+      actj+= 1.0;
+
+      mbinfo[k++].act = actj;
+    }
+}
+
+void rc_update_pict()
+{
+  double X;
+
+  S = bitcount() - S; /* total # of bits in picture */
+  R-= S; /* remaining # of bits in GOP */
+  X = (int) floor(S*((0.5*(double)Q)/(mb_width*mb_height2)) + 0.5);
+  d+= S - T;
+  avg_act = actsum/(mb_width*mb_height2);
+
+  switch (pict_type)
+  {
+  case I_TYPE:
+    Xi = X;
+    d0i = d;
+    break;
+  case P_TYPE:
+    Xp = X;
+    d0p = d;
+    Np--;
+    break;
+  case B_TYPE:
+    Xb = X;
+    d0b = d;
+    Nb--;
+    break;
+  }
+
+  fprintf(statfile,"\nrate control: end of picture\n");
+  fprintf(statfile," actual number of bits: S=%d\n",S);
+  fprintf(statfile," average quantization parameter Q=%.1f\n",
+    (double)Q/(mb_width*mb_height2));
+  fprintf(statfile," remaining number of bits in GOP: R=%d\n",R);
+  fprintf(statfile,
+    " global complexity measures (I,P,B): Xi=%d, Xp=%d, Xb=%d\n",
+    Xi, Xp, Xb);
+  fprintf(statfile,
+    " virtual buffer fullness (I,P,B): d0i=%d, d0p=%d, d0b=%d\n",
+    d0i, d0p, d0b);
+  fprintf(statfile," remaining number of P pictures in GOP: Np=%d\n",Np);
+  fprintf(statfile," remaining number of B pictures in GOP: Nb=%d\n",Nb);
+  fprintf(statfile," average activity: avg_act=%.1f\n", avg_act);
+}
+
+/* compute initial quantization stepsize (at the beginning of picture) */
+int rc_start_mb()
+{
+  int mquant;
+
+  if (q_scale_type)
+  {
+    mquant = (int) floor(2.0*d*31.0/r + 0.5);
+
+    /* clip mquant to legal (linear) range */
+    if (mquant<1)
+      mquant = 1;
+    if (mquant>112)
+      mquant = 112;
+
+    /* map to legal quantization level */
+    mquant = non_linear_mquant_table[map_non_linear_mquant[mquant]];
+  }
+  else
+  {
+    mquant = (int) floor(d*31.0/r + 0.5);
+    mquant <<= 1;
+
+    /* clip mquant to legal (linear) range */
+    if (mquant<2)
+      mquant = 2;
+    if (mquant>62)
+      mquant = 62;
+
+    prev_mquant = mquant;
+  }
+
+/*
+  fprintf(statfile,"rc_start_mb:\n");
+  fprintf(statfile,"mquant=%d\n",mquant);
+*/
+
+  return mquant;
+}
+
+/* Step 2: measure virtual buffer - estimated buffer discrepancy */
+int rc_calc_mquant(j)
+int j;
+{
+  int mquant;
+  double dj, Qj, actj, N_actj;
+
+  /* measure virtual buffer discrepancy from uniform distribution model */
+  dj = d + (bitcount()-S) - j*(T/(mb_width*mb_height2));
+
+  /* scale against dynamic range of mquant and the bits/picture count */
+  Qj = dj*31.0/r;
+/*Qj = dj*(q_scale_type ? 56.0 : 31.0)/r;  */
+
+  actj = mbinfo[j].act;
+  actsum+= actj;
+
+  /* compute normalized activity */
+  N_actj = (2.0*actj+avg_act)/(actj+2.0*avg_act);
+
+  if (q_scale_type)
+  {
+    /* modulate mquant with combined buffer and local activity measures */
+    mquant = (int) floor(2.0*Qj*N_actj + 0.5);
+
+    /* clip mquant to legal (linear) range */
+    if (mquant<1)
+      mquant = 1;
+    if (mquant>112)
+      mquant = 112;
+
+    /* map to legal quantization level */
+    mquant = non_linear_mquant_table[map_non_linear_mquant[mquant]];
+  }
+  else
+  {
+    /* modulate mquant with combined buffer and local activity measures */
+    mquant = (int) floor(Qj*N_actj + 0.5);
+    mquant <<= 1;
+
+    /* clip mquant to legal (linear) range */
+    if (mquant<2)
+      mquant = 2;
+    if (mquant>62)
+      mquant = 62;
+
+    /* ignore small changes in mquant */
+    if (mquant>=8 && (mquant-prev_mquant)>=-4 && (mquant-prev_mquant)<=4)
+      mquant = prev_mquant;
+
+    prev_mquant = mquant;
+  }
+
+  Q+= mquant; /* for calculation of average mquant */
+
+/*
+  fprintf(statfile,"rc_calc_mquant(%d): ",j);
+  fprintf(statfile,"bitcount=%d, dj=%f, Qj=%f, actj=%f, N_actj=%f, mquant=%d\n",
+    bitcount(),dj,Qj,actj,N_actj,mquant);
+*/
+
+  return mquant;
+}
+
+/* compute variance of 8x8 block */
+static double var_sblk(p,lx)
+unsigned char *p;
+int lx;
+{
+  int i, j;
+  unsigned int v, s, s2;
+
+  s = s2 = 0;
+
+  for (j=0; j<8; j++)
+  {
+    for (i=0; i<8; i++)
+    {
+      v = *p++;
+      s+= v;
+      s2+= v*v;
+    }
+    p+= lx - 8;
+  }
+
+  return s2/64.0 - (s/64.0)*(s/64.0);
+}
+
+/* VBV calculations
+ *
+ * generates warnings if underflow or overflow occurs
+ */
+
+/* vbv_end_of_picture
+ *
+ * - has to be called directly after writing picture_data()
+ * - needed for accurate VBV buffer overflow calculation
+ * - assumes there is no byte stuffing prior to the next start code
+ */
+
+static int bitcnt_EOP;
+
+void vbv_end_of_picture()
+{
+  bitcnt_EOP = bitcount();
+  bitcnt_EOP = (bitcnt_EOP + 7) & ~7; /* account for bit stuffing */
+}
+
+/* calc_vbv_delay
+ *
+ * has to be called directly after writing the picture start code, the
+ * reference point for vbv_delay
+ */
+
+void calc_vbv_delay()
+{
+  double picture_delay;
+  static double next_ip_delay; /* due to frame reordering delay */
+  static double decoding_time;
+
+  /* number of 1/90000 s ticks until next picture is to be decoded */
+  if (pict_type == B_TYPE)
+  {
+    if (prog_seq)
+    {
+      if (!repeatfirst)
+        picture_delay = 90000.0/frame_rate; /* 1 frame */
+      else
+      {
+        if (!topfirst)
+          picture_delay = 90000.0*2.0/frame_rate; /* 2 frames */
+        else
+          picture_delay = 90000.0*3.0/frame_rate; /* 3 frames */
+      }
+    }
+    else
+    {
+      /* interlaced */
+      if (fieldpic)
+        picture_delay = 90000.0/(2.0*frame_rate); /* 1 field */
+      else
+      {
+        if (!repeatfirst)
+          picture_delay = 90000.0*2.0/(2.0*frame_rate); /* 2 flds */
+        else
+          picture_delay = 90000.0*3.0/(2.0*frame_rate); /* 3 flds */
+      }
+    }
+  }
+  else
+  {
+    /* I or P picture */
+    if (fieldpic)
+    {
+      if(topfirst==(pict_struct==TOP_FIELD))
+      {
+        /* first field */
+        picture_delay = 90000.0/(2.0*frame_rate);
+      }
+      else
+      {
+        /* second field */
+        /* take frame reordering delay into account */
+        picture_delay = next_ip_delay - 90000.0/(2.0*frame_rate);
+      }
+    }
+    else
+    {
+      /* frame picture */
+      /* take frame reordering delay into account*/
+      picture_delay = next_ip_delay;
+    }
+
+    if (!fieldpic || topfirst!=(pict_struct==TOP_FIELD))
+    {
+      /* frame picture or second field */
+      if (prog_seq)
+      {
+        if (!repeatfirst)
+          next_ip_delay = 90000.0/frame_rate;
+        else
+        {
+          if (!topfirst)
+            next_ip_delay = 90000.0*2.0/frame_rate;
+          else
+            next_ip_delay = 90000.0*3.0/frame_rate;
+        }
+      }
+      else
+      {
+        if (fieldpic)
+          next_ip_delay = 90000.0/(2.0*frame_rate);
+        else
+        {
+          if (!repeatfirst)
+            next_ip_delay = 90000.0*2.0/(2.0*frame_rate);
+          else
+            next_ip_delay = 90000.0*3.0/(2.0*frame_rate);
+        }
+      }
+    }
+  }
+
+  if (decoding_time==0.0)
+  {
+    /* first call of calc_vbv_delay */
+    /* we start with a 7/8 filled VBV buffer (12.5% back-off) */
+    picture_delay = ((vbv_buffer_size*16384*7)/8)*90000.0/bit_rate;
+    if (fieldpic)
+      next_ip_delay = (int)(90000.0/frame_rate+0.5);
+  }
+
+  /* VBV checks */
+
+  /* check for underflow (previous picture) */
+  if (!low_delay && (decoding_time < bitcnt_EOP*90000.0/bit_rate))
+  {
+    /* picture not completely in buffer at intended decoding time */
+    if (!quiet)
+      fprintf(stderr,"vbv_delay underflow! (decoding_time=%.1f, t_EOP=%.1f\n)",
+        decoding_time, bitcnt_EOP*90000.0/bit_rate);
+  }
+
+  /* when to decode current frame */
+  decoding_time += picture_delay;
+
+  /* warning: bitcount() may overflow (e.g. after 9 min. at 8 Mbit/s */
+  vbv_delay = (int)(decoding_time - bitcount()*90000.0/bit_rate);
+
+  /* check for overflow (current picture) */
+  if ((decoding_time - bitcnt_EOP*90000.0/bit_rate)
+      > (vbv_buffer_size*16384)*90000.0/bit_rate)
+  {
+    if (!quiet)
+      fprintf(stderr,"vbv_delay overflow!\n");
+  }
+
+  fprintf(statfile,
+    "\nvbv_delay=%d (bitcount=%d, decoding_time=%.2f, bitcnt_EOP=%d)\n",
+    vbv_delay,bitcount(),decoding_time,bitcnt_EOP);
+
+  if (vbv_delay<0)
+  {
+    if (!quiet)
+      fprintf(stderr,"vbv_delay underflow: %d\n",vbv_delay);
+    vbv_delay = 0;
+  }
+
+  if (vbv_delay>65535)
+  {
+    if (!quiet)
+      fprintf(stderr,"vbv_delay overflow: %d\n",vbv_delay);
+    vbv_delay = 65535;
+  }
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/readpic.c b/src/gdcmmpeg2/src/mpeg2enc/readpic.c
new file mode 100644 (file)
index 0000000..3247e67
--- /dev/null
@@ -0,0 +1,494 @@
+/* readpic.c, read source pictures                                          */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+static void read_y_u_v _ANSI_ARGS_((char *fname, unsigned char *frame[]));
+static void read_yuv _ANSI_ARGS_((char *fname, unsigned char *frame[]));
+static void read_ppm _ANSI_ARGS_((char *fname, unsigned char *frame[]));
+static void border_extend _ANSI_ARGS_((unsigned char *frame, int w1, int h1,
+  int w2, int h2));
+static void conv444to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
+static void conv422to420 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
+
+void readframe(fname,frame)
+char *fname;
+unsigned char *frame[];
+{
+  switch (inputtype)
+  {
+  case T_Y_U_V:
+    read_y_u_v(fname,frame);
+    break;
+  case T_YUV:
+    read_yuv(fname,frame);
+    break;
+  case T_PPM:
+    read_ppm(fname,frame);
+    break;
+  default:
+    break;
+  }
+}
+
+static void read_y_u_v(fname,frame)
+char *fname;
+unsigned char *frame[];
+{
+  int i;
+  int chrom_hsize, chrom_vsize;
+  char name[128];
+  FILE *fd;
+
+  chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
+                                           : horizontal_size>>1;
+  chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
+                                           : vertical_size>>1;
+
+  sprintf(name,"%s.Y",fname);
+  if (!(fd = fopen(name,"rb")))
+  {
+    sprintf(errortext,"Couldn't open %s\n",name);
+    error(errortext);
+  }
+  for (i=0; i<vertical_size; i++)
+    fread(frame[0]+i*width,1,horizontal_size,fd);
+  fclose(fd);
+  border_extend(frame[0],horizontal_size,vertical_size,width,height);
+
+  sprintf(name,"%s.U",fname);
+  if (!(fd = fopen(name,"rb")))
+  {
+    sprintf(errortext,"Couldn't open %s\n",name);
+    error(errortext);
+  }
+  for (i=0; i<chrom_vsize; i++)
+    fread(frame[1]+i*chrom_width,1,chrom_hsize,fd);
+  fclose(fd);
+  border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
+
+  sprintf(name,"%s.V",fname);
+  if (!(fd = fopen(name,"rb")))
+  {
+    sprintf(errortext,"Couldn't open %s\n",name);
+    error(errortext);
+  }
+  for (i=0; i<chrom_vsize; i++)
+    fread(frame[2]+i*chrom_width,1,chrom_hsize,fd);
+  fclose(fd);
+  border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
+}
+
+static void read_yuv(fname,frame)
+char *fname;
+unsigned char *frame[];
+{
+  int i;
+  int chrom_hsize, chrom_vsize;
+  char name[128];
+  FILE *fd;
+
+  chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
+                                           : horizontal_size>>1;
+  chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
+                                           : vertical_size>>1;
+
+  sprintf(name,"%s.yuv",fname);
+  if (!(fd = fopen(name,"rb")))
+  {
+    sprintf(errortext,"Couldn't open %s\n",name);
+    error(errortext);
+  }
+
+  /* Y */
+  for (i=0; i<vertical_size; i++)
+    fread(frame[0]+i*width,1,horizontal_size,fd);
+  border_extend(frame[0],horizontal_size,vertical_size,width,height);
+
+  /* Cb */
+  for (i=0; i<chrom_vsize; i++)
+    fread(frame[1]+i*chrom_width,1,chrom_hsize,fd);
+  border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
+
+  /* Cr */
+  for (i=0; i<chrom_vsize; i++)
+    fread(frame[2]+i*chrom_width,1,chrom_hsize,fd);
+  border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
+
+  fclose(fd);
+}
+
+static void read_ppm(fname,frame)
+char *fname;
+unsigned char *frame[];
+{
+  int i, j;
+  int r, g, b;
+  double y, u, v;
+  double cr, cg, cb, cu, cv;
+  char name[128];
+  FILE *fd;
+  unsigned char *yp, *up, *vp;
+  static unsigned char *u444, *v444, *u422, *v422;
+  static double coef[7][3] = {
+    {0.2125,0.7154,0.0721}, /* ITU-R Rec. 709 (1990) */
+    {0.299, 0.587, 0.114},  /* unspecified */
+    {0.299, 0.587, 0.114},  /* reserved */
+    {0.30,  0.59,  0.11},   /* FCC */
+    {0.299, 0.587, 0.114},  /* ITU-R Rec. 624-4 System B, G */
+    {0.299, 0.587, 0.114},  /* SMPTE 170M */
+    {0.212, 0.701, 0.087}}; /* SMPTE 240M (1987) */
+
+  i = matrix_coefficients;
+  if (i>8)
+    i = 3;
+
+  cr = coef[i-1][0];
+  cg = coef[i-1][1];
+  cb = coef[i-1][2];
+  cu = 0.5/(1.0-cb);
+  cv = 0.5/(1.0-cr);
+
+  if (chroma_format==CHROMA444)
+  {
+    u444 = frame[1];
+    v444 = frame[2];
+  }
+  else
+  {
+    if (!u444)
+    {
+      if (!(u444 = (unsigned char *)malloc(width*height)))
+        error("malloc failed");
+      if (!(v444 = (unsigned char *)malloc(width*height)))
+        error("malloc failed");
+      if (chroma_format==CHROMA420)
+      {
+        if (!(u422 = (unsigned char *)malloc((width>>1)*height)))
+          error("malloc failed");
+        if (!(v422 = (unsigned char *)malloc((width>>1)*height)))
+          error("malloc failed");
+      }
+    }
+  }
+
+  sprintf(name,"%s.ppm",fname);
+
+  if (!(fd = fopen(name,"rb")))
+  {
+    sprintf(errortext,"Couldn't open %s\n",name);
+    error(errortext);
+  }
+
+  /* skip header */
+  getc(fd); getc(fd); /* magic number (P6) */
+  pbm_getint(fd); pbm_getint(fd); pbm_getint(fd); /* width height maxcolors */
+
+  for (i=0; i<vertical_size; i++)
+  {
+    yp = frame[0] + i*width;
+    up = u444 + i*width;
+    vp = v444 + i*width;
+
+    for (j=0; j<horizontal_size; j++)
+    {
+      r=getc(fd); g=getc(fd); b=getc(fd);
+      /* convert to YUV */
+      y = cr*r + cg*g + cb*b;
+      u = cu*(b-y);
+      v = cv*(r-y);
+      yp[j] = (219.0/256.0)*y + 16.5;  /* nominal range: 16..235 */
+      up[j] = (224.0/256.0)*u + 128.5; /* 16..240 */
+      vp[j] = (224.0/256.0)*v + 128.5; /* 16..240 */
+    }
+  }
+  fclose(fd);
+
+  border_extend(frame[0],horizontal_size,vertical_size,width,height);
+  border_extend(u444,horizontal_size,vertical_size,width,height);
+  border_extend(v444,horizontal_size,vertical_size,width,height);
+
+  if (chroma_format==CHROMA422)
+  {
+    conv444to422(u444,frame[1]);
+    conv444to422(v444,frame[2]);
+  }
+
+  if (chroma_format==CHROMA420)
+  {
+    conv444to422(u444,u422);
+    conv444to422(v444,v422);
+    conv422to420(u422,frame[1]);
+    conv422to420(v422,frame[2]);
+  }
+}
+
+static void border_extend(frame,w1,h1,w2,h2)
+unsigned char *frame;
+int w1,h1,w2,h2;
+{
+  int i, j;
+  unsigned char *fp;
+
+  /* horizontal pixel replication (right border) */
+
+  for (j=0; j<h1; j++)
+  {
+    fp = frame + j*w2;
+    for (i=w1; i<w2; i++)
+      fp[i] = fp[i-1];
+  }
+
+  /* vertical pixel replication (bottom border) */
+
+  for (j=h1; j<h2; j++)
+  {
+    fp = frame + j*w2;
+    for (i=0; i<w2; i++)
+      fp[i] = fp[i-w2];
+  }
+}
+
+/* horizontal filter and 2:1 subsampling */
+static void conv444to422(src,dst)
+unsigned char *src, *dst;
+{
+  int i, j, im5, im4, im3, im2, im1, ip1, ip2, ip3, ip4, ip5, ip6;
+
+  if (mpeg1)
+  {
+    for (j=0; j<height; j++)
+    {
+      for (i=0; i<width; i+=2)
+      {
+        im5 = (i<5) ? 0 : i-5;
+        im4 = (i<4) ? 0 : i-4;
+        im3 = (i<3) ? 0 : i-3;
+        im2 = (i<2) ? 0 : i-2;
+        im1 = (i<1) ? 0 : i-1;
+        ip1 = (i<width-1) ? i+1 : width-1;
+        ip2 = (i<width-2) ? i+2 : width-1;
+        ip3 = (i<width-3) ? i+3 : width-1;
+        ip4 = (i<width-4) ? i+4 : width-1;
+        ip5 = (i<width-5) ? i+5 : width-1;
+        ip6 = (i<width-5) ? i+6 : width-1;
+
+        /* FIR filter with 0.5 sample interval phase shift */
+        dst[i>>1] = clp[(int)(228*(src[i]+src[ip1])
+                         +70*(src[im1]+src[ip2])
+                         -37*(src[im2]+src[ip3])
+                         -21*(src[im3]+src[ip4])
+                         +11*(src[im4]+src[ip5])
+                         + 5*(src[im5]+src[ip6])+256)>>9];
+      }
+      src+= width;
+      dst+= width>>1;
+    }
+  }
+  else
+  {
+    /* MPEG-2 */
+    for (j=0; j<height; j++)
+    {
+      for (i=0; i<width; i+=2)
+      {
+        im5 = (i<5) ? 0 : i-5;
+        im3 = (i<3) ? 0 : i-3;
+        im1 = (i<1) ? 0 : i-1;
+        ip1 = (i<width-1) ? i+1 : width-1;
+        ip3 = (i<width-3) ? i+3 : width-1;
+        ip5 = (i<width-5) ? i+5 : width-1;
+
+        /* FIR filter coefficients (*512): 22 0 -52 0 159 256 159 0 -52 0 22 */
+        dst[i>>1] = clp[(int)(  22*(src[im5]+src[ip5])-52*(src[im3]+src[ip3])
+                         +159*(src[im1]+src[ip1])+256*src[i]+256)>>9];
+      }
+      src+= width;
+      dst+= width>>1;
+    }
+  }
+}
+
+/* vertical filter and 2:1 subsampling */
+static void conv422to420(src,dst)
+unsigned char *src, *dst;
+{
+  int w, i, j, jm6, jm5, jm4, jm3, jm2, jm1;
+  int jp1, jp2, jp3, jp4, jp5, jp6;
+
+  w = width>>1;
+
+  if (prog_frame)
+  {
+    /* intra frame */
+    for (i=0; i<w; i++)
+    {
+      for (j=0; j<height; j+=2)
+      {
+        jm5 = (j<5) ? 0 : j-5;
+        jm4 = (j<4) ? 0 : j-4;
+        jm3 = (j<3) ? 0 : j-3;
+        jm2 = (j<2) ? 0 : j-2;
+        jm1 = (j<1) ? 0 : j-1;
+        jp1 = (j<height-1) ? j+1 : height-1;
+        jp2 = (j<height-2) ? j+2 : height-1;
+        jp3 = (j<height-3) ? j+3 : height-1;
+        jp4 = (j<height-4) ? j+4 : height-1;
+        jp5 = (j<height-5) ? j+5 : height-1;
+        jp6 = (j<height-5) ? j+6 : height-1;
+
+        /* FIR filter with 0.5 sample interval phase shift */
+        dst[w*(j>>1)] = clp[(int)(228*(src[w*j]+src[w*jp1])
+                             +70*(src[w*jm1]+src[w*jp2])
+                             -37*(src[w*jm2]+src[w*jp3])
+                             -21*(src[w*jm3]+src[w*jp4])
+                             +11*(src[w*jm4]+src[w*jp5])
+                             + 5*(src[w*jm5]+src[w*jp6])+256)>>9];
+      }
+      src++;
+      dst++;
+    }
+  }
+  else
+  {
+    /* intra field */
+    for (i=0; i<w; i++)
+    {
+      for (j=0; j<height; j+=4)
+      {
+        /* top field */
+        jm5 = (j<10) ? 0 : j-10;
+        jm4 = (j<8) ? 0 : j-8;
+        jm3 = (j<6) ? 0 : j-6;
+        jm2 = (j<4) ? 0 : j-4;
+        jm1 = (j<2) ? 0 : j-2;
+        jp1 = (j<height-2) ? j+2 : height-2;
+        jp2 = (j<height-4) ? j+4 : height-2;
+        jp3 = (j<height-6) ? j+6 : height-2;
+        jp4 = (j<height-8) ? j+8 : height-2;
+        jp5 = (j<height-10) ? j+10 : height-2;
+        jp6 = (j<height-12) ? j+12 : height-2;
+
+        /* FIR filter with 0.25 sample interval phase shift */
+        dst[w*(j>>1)] = clp[(int)(8*src[w*jm5]
+                            +5*src[w*jm4]
+                           -30*src[w*jm3]
+                           -18*src[w*jm2]
+                          +113*src[w*jm1]
+                          +242*src[w*j]
+                          +192*src[w*jp1]
+                           +35*src[w*jp2]
+                           -38*src[w*jp3]
+                           -10*src[w*jp4]
+                           +11*src[w*jp5]
+                            +2*src[w*jp6]+256)>>9];
+
+        /* bottom field */
+        jm6 = (j<9) ? 1 : j-9;
+        jm5 = (j<7) ? 1 : j-7;
+        jm4 = (j<5) ? 1 : j-5;
+        jm3 = (j<3) ? 1 : j-3;
+        jm2 = (j<1) ? 1 : j-1;
+        jm1 = (j<height-1) ? j+1 : height-1;
+        jp1 = (j<height-3) ? j+3 : height-1;
+        jp2 = (j<height-5) ? j+5 : height-1;
+        jp3 = (j<height-7) ? j+7 : height-1;
+        jp4 = (j<height-9) ? j+9 : height-1;
+        jp5 = (j<height-11) ? j+11 : height-1;
+        jp6 = (j<height-13) ? j+13 : height-1;
+
+        /* FIR filter with 0.25 sample interval phase shift */
+        dst[w*((j>>1)+1)] = clp[(int)(8*src[w*jp6]
+                                +5*src[w*jp5]
+                               -30*src[w*jp4]
+                               -18*src[w*jp3]
+                              +113*src[w*jp2]
+                              +242*src[w*jp1]
+                              +192*src[w*jm1]
+                               +35*src[w*jm2]
+                               -38*src[w*jm3]
+                               -10*src[w*jm4]
+                               +11*src[w*jm5]
+                                +2*src[w*jm6]+256)>>9];
+      }
+      src++;
+      dst++;
+    }
+  }
+}
+
+/* pbm_getc() and pbm_getint() are essentially taken from
+ * PBMPLUS (C) Jef Poskanzer
+ * but without error/EOF checking
+ */
+char pbm_getc(file)
+FILE* file;
+{
+  char ch;
+
+  ch = getc(file);
+
+  if (ch=='#')
+  {
+    do
+    {
+      ch = getc(file);
+    }
+    while (ch!='\n' && ch!='\r');
+  }
+
+  return ch;
+}
+
+int pbm_getint(file)
+FILE* file;
+{
+  char ch;
+  int i;
+
+  do
+  {
+    ch = pbm_getc(file);
+  }
+  while (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r');
+
+  i = 0;
+  do
+  {
+    i = i*10 + ch-'0';
+    ch = pbm_getc(file);
+  }
+  while (ch>='0' && ch<='9');
+
+  return i;
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/stats.c b/src/gdcmmpeg2/src/mpeg2enc/stats.c
new file mode 100644 (file)
index 0000000..0061655
--- /dev/null
@@ -0,0 +1,446 @@
+/* stats.c, coding statistics                                               */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "config.h"
+#include "global.h"
+
+/* private prototypes */
+static void calcSNR1 _ANSI_ARGS_((unsigned char *org, unsigned char *rec,
+  int lx, int w, int h, double *pv, double *pe));
+
+
+void calcSNR(org,rec)
+unsigned char *org[3];
+unsigned char *rec[3];
+{
+  int w,h,offs;
+  double v,e;
+
+  w = horizontal_size;
+  h = (pict_struct==FRAME_PICTURE) ? vertical_size : (vertical_size>>1);
+  offs = (pict_struct==BOTTOM_FIELD) ? width : 0;
+
+  calcSNR1(org[0]+offs,rec[0]+offs,width2,w,h,&v,&e);
+  fprintf(statfile,"Y: variance=%4.4g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n",
+    v, e, 10.0*log10(255.0*255.0/e), 10.0*log10(v/e));
+
+  if (chroma_format!=CHROMA444)
+  {
+    w >>= 1;
+    offs >>= 1;
+  }
+
+  if (chroma_format==CHROMA420)
+    h >>= 1;
+
+  calcSNR1(org[1]+offs,rec[1]+offs,chrom_width2,w,h,&v,&e);
+  fprintf(statfile,"U: variance=%4.4g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n",
+    v, e, 10.0*log10(255.0*255.0/e), 10.0*log10(v/e));
+
+  calcSNR1(org[2]+offs,rec[2]+offs,chrom_width2,w,h,&v,&e);
+  fprintf(statfile,"V: variance=%4.4g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n",
+    v, e, 10.0*log10(255.0*255.0/e), 10.0*log10(v/e));
+}
+
+static void calcSNR1(org,rec,lx,w,h,pv,pe)
+unsigned char *org;
+unsigned char *rec;
+int lx,w,h;
+double *pv,*pe;
+{
+  int i, j;
+  double v1, s1, s2, e2;
+
+  s1 = s2 = e2 = 0.0;
+
+  for (j=0; j<h; j++)
+  {
+    for (i=0; i<w; i++)
+    {
+      v1 = org[i];
+      s1+= v1;
+      s2+= v1*v1;
+      v1-= rec[i];
+      e2+= v1*v1;
+    }
+    org += lx;
+    rec += lx;
+  }
+
+  s1 /= w*h;
+  s2 /= w*h;
+  e2 /= w*h;
+
+  /* prevent division by zero in calcSNR() */
+  if(e2==0.0)
+    e2 = 0.00001;
+
+  *pv = s2 - s1*s1; /* variance */
+  *pe = e2;         /* MSE */
+}
+
+void stats()
+{
+  int i, j, k, nmb, mb_type;
+  int n_skipped, n_intra, n_ncoded, n_blocks, n_interp, n_forward, n_backward;
+  struct mbinfo *mbi;
+
+  nmb = mb_width*mb_height2;
+
+  n_skipped=n_intra=n_ncoded=n_blocks=n_interp=n_forward=n_backward=0;
+
+  for (k=0; k<nmb; k++)
+  {
+    mbi = mbinfo+k;
+    if (mbi->skipped)
+      n_skipped++;
+    else if (mbi->mb_type & MB_INTRA)
+      n_intra++;
+    else if (!(mbi->mb_type & MB_PATTERN))
+      n_ncoded++;
+
+    for (i=0; i<block_count; i++)
+      if (mbi->cbp & (1<<i))
+        n_blocks++;
+
+    if (mbi->mb_type & MB_FORWARD)
+    {
+      if (mbi->mb_type & MB_BACKWARD)
+        n_interp++;
+      else
+        n_forward++;
+    }
+    else if (mbi->mb_type & MB_BACKWARD)
+      n_backward++;
+  }
+
+  fprintf(statfile,"\npicture statistics:\n");
+  fprintf(statfile," # of intra coded macroblocks:  %4d (%.1f%%)\n",
+    n_intra,100.0*(double)n_intra/nmb);
+  fprintf(statfile," # of coded blocks:             %4d (%.1f%%)\n",
+    n_blocks,100.0*(double)n_blocks/(block_count*nmb));
+  fprintf(statfile," # of not coded macroblocks:    %4d (%.1f%%)\n",
+    n_ncoded,100.0*(double)n_ncoded/nmb);
+  fprintf(statfile," # of skipped macroblocks:      %4d (%.1f%%)\n",
+    n_skipped,100.0*(double)n_skipped/nmb);
+  fprintf(statfile," # of forw. pred. macroblocks:  %4d (%.1f%%)\n",
+    n_forward,100.0*(double)n_forward/nmb);
+  fprintf(statfile," # of backw. pred. macroblocks: %4d (%.1f%%)\n",
+    n_backward,100.0*(double)n_backward/nmb);
+  fprintf(statfile," # of interpolated macroblocks: %4d (%.1f%%)\n",
+    n_interp,100.0*(double)n_interp/nmb);
+
+  fprintf(statfile,"\nmacroblock_type map:\n");
+
+  k = 0;
+
+  for (j=0; j<mb_height2; j++)
+  {
+    for (i=0; i<mb_width; i++)
+    {
+      mbi = mbinfo + k;
+      mb_type = mbi->mb_type;
+      if (mbi->skipped)
+        putc('S',statfile);
+      else if (mb_type & MB_INTRA)
+        putc('I',statfile);
+      else switch (mb_type & (MB_FORWARD|MB_BACKWARD))
+      {
+      case MB_FORWARD:
+        putc(mbi->motion_type==MC_FIELD ? 'f' :
+             mbi->motion_type==MC_DMV   ? 'p' :
+                                          'F',statfile); break;
+      case MB_BACKWARD:
+        putc(mbi->motion_type==MC_FIELD ? 'b' :
+                                          'B',statfile); break;
+      case MB_FORWARD|MB_BACKWARD:
+        putc(mbi->motion_type==MC_FIELD ? 'd' :
+                                          'D',statfile); break;
+      default:
+        putc('0',statfile); break;
+      }
+
+      if (mb_type & MB_QUANT)
+        putc('Q',statfile);
+      else if (mb_type & (MB_PATTERN|MB_INTRA))
+        putc(' ',statfile);
+      else
+        putc('N',statfile);
+
+      putc(' ',statfile);
+
+      k++;
+    }
+    putc('\n',statfile);
+  }
+
+  fprintf(statfile,"\nmquant map:\n");
+
+  k=0;
+  for (j=0; j<mb_height2; j++)
+  {
+    for (i=0; i<mb_width; i++)
+    {
+      if (i==0 || mbinfo[k].mquant!=mbinfo[k-1].mquant)
+        fprintf(statfile,"%3d",mbinfo[k].mquant);
+      else
+        fprintf(statfile,"   ");
+
+      k++;
+    }
+    putc('\n',statfile);
+  }
+
+#if 0
+  fprintf(statfile,"\ncbp map:\n");
+
+  k=0;
+  for (j=0; j<mb_height2; j++)
+  {
+    for (i=0; i<mb_width; i++)
+    {
+      fprintf(statfile,"%02x ",mbinfo[k].cbp);
+
+      k++;
+    }
+    putc('\n',statfile);
+  }
+
+  if (pict_struct==FRAME_PICTURE && !frame_pred_dct)
+  {
+    fprintf(statfile,"\ndct_type map:\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & (MB_PATTERN|MB_INTRA))
+          fprintf(statfile,"%d  ",mbinfo[k].dct_type);
+        else
+          fprintf(statfile,"   ");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+  }
+
+  if (pict_type!=I_TYPE)
+  {
+    fprintf(statfile,"\nforward motion vectors (first vector, horizontal):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_FORWARD)
+          fprintf(statfile,"%4d",mbinfo[k].MV[0][0][0]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+    fprintf(statfile,"\nforward motion vectors (first vector, vertical):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_FORWARD)
+          fprintf(statfile,"%4d",mbinfo[k].MV[0][0][1]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+    fprintf(statfile,"\nforward motion vectors (second vector, horizontal):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_FORWARD
+            && ((pict_struct==FRAME_PICTURE && mbinfo[k].motion_type==MC_FIELD) ||
+                (pict_struct!=FRAME_PICTURE && mbinfo[k].motion_type==MC_16X8)))
+          fprintf(statfile,"%4d",mbinfo[k].MV[1][0][0]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+    fprintf(statfile,"\nforward motion vectors (second vector, vertical):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_FORWARD
+            && ((pict_struct==FRAME_PICTURE && mbinfo[k].motion_type==MC_FIELD) ||
+                (pict_struct!=FRAME_PICTURE && mbinfo[k].motion_type==MC_16X8)))
+          fprintf(statfile,"%4d",mbinfo[k].MV[1][0][1]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+
+  }
+    
+  if (pict_type==B_TYPE)
+  {
+    fprintf(statfile,"\nbackward motion vectors (first vector, horizontal):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_BACKWARD)
+          fprintf(statfile,"%4d",mbinfo[k].MV[0][1][0]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+    fprintf(statfile,"\nbackward motion vectors (first vector, vertical):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_BACKWARD)
+          fprintf(statfile,"%4d",mbinfo[k].MV[0][1][1]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+    fprintf(statfile,"\nbackward motion vectors (second vector, horizontal):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_BACKWARD
+            && ((pict_struct==FRAME_PICTURE && mbinfo[k].motion_type==MC_FIELD) ||
+                (pict_struct!=FRAME_PICTURE && mbinfo[k].motion_type==MC_16X8)))
+          fprintf(statfile,"%4d",mbinfo[k].MV[1][1][0]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+    fprintf(statfile,"\nbackward motion vectors (second vector, vertical):\n");
+
+    k=0;
+    for (j=0; j<mb_height2; j++)
+    {
+      for (i=0; i<mb_width; i++)
+      {
+        if (mbinfo[k].mb_type & MB_BACKWARD
+            && ((pict_struct==FRAME_PICTURE && mbinfo[k].motion_type==MC_FIELD) ||
+                (pict_struct!=FRAME_PICTURE && mbinfo[k].motion_type==MC_16X8)))
+          fprintf(statfile,"%4d",mbinfo[k].MV[1][1][1]);
+        else
+          fprintf(statfile,"   .");
+  
+        k++;
+      }
+      putc('\n',statfile);
+    }
+
+
+  }
+#endif
+    
+#if 0
+  /* useful for debugging */
+  fprintf(statfile,"\nmacroblock info dump:\n");
+
+  k=0;
+  for (j=0; j<mb_height2; j++)
+  {
+    for (i=0; i<mb_width; i++)
+    {
+      fprintf(statfile,"%d: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+      k,
+      mbinfo[k].mb_type,
+      mbinfo[k].motion_type,
+      mbinfo[k].dct_type,
+      mbinfo[k].mquant,
+      mbinfo[k].cbp,
+      mbinfo[k].skipped,
+      mbinfo[k].MV[0][0][0],
+      mbinfo[k].MV[0][0][1],
+      mbinfo[k].MV[0][1][0],
+      mbinfo[k].MV[0][1][1],
+      mbinfo[k].MV[1][0][0],
+      mbinfo[k].MV[1][0][1],
+      mbinfo[k].MV[1][1][0],
+      mbinfo[k].MV[1][1][1],
+      mbinfo[k].mv_field_sel[0][0],
+      mbinfo[k].mv_field_sel[0][1],
+      mbinfo[k].mv_field_sel[1][0],
+      mbinfo[k].mv_field_sel[1][1]);
+
+      k++;
+    }
+  }
+#endif
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/transfrm.c b/src/gdcmmpeg2/src/mpeg2enc/transfrm.c
new file mode 100644 (file)
index 0000000..38677a0
--- /dev/null
@@ -0,0 +1,280 @@
+/* transfrm.c,  forward / inverse transformation                            */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "config.h"
+#include "global.h"
+
+/* private prototypes*/
+static void add_pred _ANSI_ARGS_((unsigned char *pred, unsigned char *cur,
+  int lx, short *blk));
+static void sub_pred _ANSI_ARGS_((unsigned char *pred, unsigned char *cur,
+  int lx, short *blk));
+
+/* subtract prediction and transform prediction error */
+void transform(pred,cur,mbi,blocks)
+unsigned char *pred[], *cur[];
+struct mbinfo *mbi;
+short blocks[][64];
+{
+  int i, j, i1, j1, k, n, cc, offs, lx;
+
+  k = 0;
+
+  for (j=0; j<height2; j+=16)
+    for (i=0; i<width; i+=16)
+    {
+      for (n=0; n<block_count; n++)
+      {
+        cc = (n<4) ? 0 : (n&1)+1; /* color component index */
+        if (cc==0)
+        {
+          /* luminance */
+          if ((pict_struct==FRAME_PICTURE) && mbi[k].dct_type)
+          {
+            /* field DCT */
+            offs = i + ((n&1)<<3) + width*(j+((n&2)>>1));
+            lx = width<<1;
+          }
+          else
+          {
+            /* frame DCT */
+            offs = i + ((n&1)<<3) + width2*(j+((n&2)<<2));
+            lx = width2;
+          }
+
+          if (pict_struct==BOTTOM_FIELD)
+            offs += width;
+        }
+        else
+        {
+          /* chrominance */
+
+          /* scale coordinates */
+          i1 = (chroma_format==CHROMA444) ? i : i>>1;
+          j1 = (chroma_format!=CHROMA420) ? j : j>>1;
+
+          if ((pict_struct==FRAME_PICTURE) && mbi[k].dct_type
+              && (chroma_format!=CHROMA420))
+          {
+            /* field DCT */
+            offs = i1 + (n&8) + chrom_width*(j1+((n&2)>>1));
+            lx = chrom_width<<1;
+          }
+          else
+          {
+            /* frame DCT */
+            offs = i1 + (n&8) + chrom_width2*(j1+((n&2)<<2));
+            lx = chrom_width2;
+          }
+
+          if (pict_struct==BOTTOM_FIELD)
+            offs += chrom_width;
+        }
+
+        sub_pred(pred[cc]+offs,cur[cc]+offs,lx,blocks[k*block_count+n]);
+        fdct(blocks[k*block_count+n]);
+      }
+
+      k++;
+    }
+}
+
+/* inverse transform prediction error and add prediction */
+void itransform(pred,cur,mbi,blocks)
+unsigned char *pred[],*cur[];
+struct mbinfo *mbi;
+short blocks[][64];
+{
+  int i, j, i1, j1, k, n, cc, offs, lx;
+
+  k = 0;
+
+  for (j=0; j<height2; j+=16)
+    for (i=0; i<width; i+=16)
+    {
+      for (n=0; n<block_count; n++)
+      {
+        cc = (n<4) ? 0 : (n&1)+1; /* color component index */
+
+        if (cc==0)
+        {
+          /* luminance */
+          if ((pict_struct==FRAME_PICTURE) && mbi[k].dct_type)
+          {
+            /* field DCT */
+            offs = i + ((n&1)<<3) + width*(j+((n&2)>>1));
+            lx = width<<1;
+          }
+          else
+          {
+            /* frame DCT */
+            offs = i + ((n&1)<<3) + width2*(j+((n&2)<<2));
+            lx = width2;
+          }
+
+          if (pict_struct==BOTTOM_FIELD)
+            offs += width;
+        }
+        else
+        {
+          /* chrominance */
+
+          /* scale coordinates */
+          i1 = (chroma_format==CHROMA444) ? i : i>>1;
+          j1 = (chroma_format!=CHROMA420) ? j : j>>1;
+
+          if ((pict_struct==FRAME_PICTURE) && mbi[k].dct_type
+              && (chroma_format!=CHROMA420))
+          {
+            /* field DCT */
+            offs = i1 + (n&8) + chrom_width*(j1+((n&2)>>1));
+            lx = chrom_width<<1;
+          }
+          else
+          {
+            /* frame DCT */
+            offs = i1 + (n&8) + chrom_width2*(j1+((n&2)<<2));
+            lx = chrom_width2;
+          }
+
+          if (pict_struct==BOTTOM_FIELD)
+            offs += chrom_width;
+        }
+
+        idct(blocks[k*block_count+n]);
+        add_pred(pred[cc]+offs,cur[cc]+offs,lx,blocks[k*block_count+n]);
+      }
+
+      k++;
+    }
+}
+
+/* add prediction and prediction error, saturate to 0...255 */
+static void add_pred(pred,cur,lx,blk)
+unsigned char *pred, *cur;
+int lx;
+short *blk;
+{
+  int i, j;
+
+  for (j=0; j<8; j++)
+  {
+    for (i=0; i<8; i++)
+      cur[i] = clp[blk[i] + pred[i]];
+    blk+= 8;
+    cur+= lx;
+    pred+= lx;
+  }
+}
+
+/* subtract prediction from block data */
+static void sub_pred(pred,cur,lx,blk)
+unsigned char *pred, *cur;
+int lx;
+short *blk;
+{
+  int i, j;
+
+  for (j=0; j<8; j++)
+  {
+    for (i=0; i<8; i++)
+      blk[i] = cur[i] - pred[i];
+    blk+= 8;
+    cur+= lx;
+    pred+= lx;
+  }
+}
+
+/*
+ * select between frame and field DCT
+ *
+ * preliminary version: based on inter-field correlation
+ */
+void dct_type_estimation(pred,cur,mbi)
+unsigned char *pred,*cur;
+struct mbinfo *mbi;
+{
+  short blk0[128], blk1[128];
+  int i, j, i0, j0, k, offs, s0, s1, sq0, sq1, s01;
+  double d, r;
+
+  k = 0;
+
+  for (j0=0; j0<height2; j0+=16)
+    for (i0=0; i0<width; i0+=16)
+    {
+      if (frame_pred_dct || pict_struct!=FRAME_PICTURE)
+        mbi[k].dct_type = 0;
+      else
+      {
+        /* interlaced frame picture */
+        /*
+         * calculate prediction error (cur-pred) for top (blk0)
+         * and bottom field (blk1)
+         */
+        for (j=0; j<8; j++)
+        {
+          offs = width*((j<<1)+j0) + i0;
+          for (i=0; i<16; i++)
+          {
+            blk0[16*j+i] = cur[offs] - pred[offs];
+            blk1[16*j+i] = cur[offs+width] - pred[offs+width];
+            offs++;
+          }
+        }
+        /* correlate fields */
+        s0=s1=sq0=sq1=s01=0;
+
+        for (i=0; i<128; i++)
+        {
+          s0+= blk0[i];
+          sq0+= blk0[i]*blk0[i];
+          s1+= blk1[i];
+          sq1+= blk1[i]*blk1[i];
+          s01+= blk0[i]*blk1[i];
+        }
+
+        d = (sq0-(s0*s0)/128.0)*(sq1-(s1*s1)/128.0);
+
+        if (d>0.0)
+        {
+          r = (s01-(s0*s1)/128.0)/sqrt(d);
+          if (r>0.5)
+            mbi[k].dct_type = 0; /* frame DCT */
+          else
+            mbi[k].dct_type = 1; /* field DCT */
+        }
+        else
+          mbi[k].dct_type = 1; /* field DCT */
+      }
+      k++;
+    }
+}
diff --git a/src/gdcmmpeg2/src/mpeg2enc/vlc.h b/src/gdcmmpeg2/src/mpeg2enc/vlc.h
new file mode 100644 (file)
index 0000000..284bb15
--- /dev/null
@@ -0,0 +1,321 @@
+/* vlc.h, variable length code tables (used by routines in putvlc.c)        */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+/* type definitions for variable length code table entries */
+
+typedef struct
+{
+  unsigned char code; /* right justified */
+  char len;
+} VLCtable;
+
+/* for codes longer than 8 bits (excluding leading zeroes) */
+typedef struct
+{
+  unsigned short code; /* right justified */
+  char len;
+} sVLCtable;
+
+
+/* data from ISO/IEC 13818-2 DIS, Annex B, variable length code tables */
+
+/* Table B-1, variable length codes for macroblock_address_increment
+ *
+ * indexed by [macroblock_address_increment-1]
+ * 'macroblock_escape' is treated elsewhere
+ */
+
+static VLCtable addrinctab[33]=
+{
+  {0x01,1},  {0x03,3},  {0x02,3},  {0x03,4},
+  {0x02,4},  {0x03,5},  {0x02,5},  {0x07,7},
+  {0x06,7},  {0x0b,8},  {0x0a,8},  {0x09,8},
+  {0x08,8},  {0x07,8},  {0x06,8},  {0x17,10},
+  {0x16,10}, {0x15,10}, {0x14,10}, {0x13,10},
+  {0x12,10}, {0x23,11}, {0x22,11}, {0x21,11},
+  {0x20,11}, {0x1f,11}, {0x1e,11}, {0x1d,11},
+  {0x1c,11}, {0x1b,11}, {0x1a,11}, {0x19,11},
+  {0x18,11}
+};
+
+
+/* Table B-2, B-3, B-4 variable length codes for macroblock_type
+ *
+ * indexed by [macroblock_type]
+ */
+
+static VLCtable mbtypetab[3][32]=
+{
+ /* I */
+ {
+  {0,0}, {1,1}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+  {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+  {0,0}, {1,2}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+  {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}
+ },
+ /* P */
+ {
+  {0,0}, {3,5}, {1,2}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+  {1,3}, {0,0}, {1,1}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+  {0,0}, {1,6}, {1,5}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+  {0,0}, {0,0}, {2,5}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}
+ },
+ /* B */
+ {
+  {0,0}, {3,5}, {0,0}, {0,0}, {2,3}, {0,0}, {3,3}, {0,0},
+  {2,4}, {0,0}, {3,4}, {0,0}, {2,2}, {0,0}, {3,2}, {0,0},
+  {0,0}, {1,6}, {0,0}, {0,0}, {0,0}, {0,0}, {2,6}, {0,0},
+  {0,0}, {0,0}, {3,6}, {0,0}, {0,0}, {0,0}, {2,5}, {0,0}
+ }
+};
+
+
+/* Table B-5 ... B-8 variable length codes for macroblock_type in
+ *  scalable sequences
+ *
+ * not implemented
+ */
+
+/* Table B-9, variable length codes for coded_block_pattern
+ *
+ * indexed by [coded_block_pattern]
+ */
+
+static VLCtable cbptable[64]=
+{
+  {0x01,9}, {0x0b,5}, {0x09,5}, {0x0d,6}, 
+  {0x0d,4}, {0x17,7}, {0x13,7}, {0x1f,8}, 
+  {0x0c,4}, {0x16,7}, {0x12,7}, {0x1e,8}, 
+  {0x13,5}, {0x1b,8}, {0x17,8}, {0x13,8}, 
+  {0x0b,4}, {0x15,7}, {0x11,7}, {0x1d,8}, 
+  {0x11,5}, {0x19,8}, {0x15,8}, {0x11,8}, 
+  {0x0f,6}, {0x0f,8}, {0x0d,8}, {0x03,9}, 
+  {0x0f,5}, {0x0b,8}, {0x07,8}, {0x07,9}, 
+  {0x0a,4}, {0x14,7}, {0x10,7}, {0x1c,8}, 
+  {0x0e,6}, {0x0e,8}, {0x0c,8}, {0x02,9}, 
+  {0x10,5}, {0x18,8}, {0x14,8}, {0x10,8}, 
+  {0x0e,5}, {0x0a,8}, {0x06,8}, {0x06,9}, 
+  {0x12,5}, {0x1a,8}, {0x16,8}, {0x12,8}, 
+  {0x0d,5}, {0x09,8}, {0x05,8}, {0x05,9}, 
+  {0x0c,5}, {0x08,8}, {0x04,8}, {0x04,9},
+  {0x07,3}, {0x0a,5}, {0x08,5}, {0x0c,6}
+};
+
+
+/* Table B-10, variable length codes for motion_code
+ *
+ * indexed by [abs(motion_code)]
+ * sign of motion_code is treated elsewhere
+ */
+
+static VLCtable motionvectab[17]=
+{
+  {0x01,1},  {0x01,2},  {0x01,3},  {0x01,4},
+  {0x03,6},  {0x05,7},  {0x04,7},  {0x03,7},
+  {0x0b,9},  {0x0a,9},  {0x09,9},  {0x11,10},
+  {0x10,10}, {0x0f,10}, {0x0e,10}, {0x0d,10},
+  {0x0c,10}
+};
+
+
+/* Table B-11, variable length codes for dmvector
+ *
+ * treated elsewhere
+ */
+
+/* Table B-12, variable length codes for dct_dc_size_luminance
+ *
+ * indexed by [dct_dc_size_luminance]
+ */
+
+static sVLCtable DClumtab[12]=
+{
+  {0x0004,3}, {0x0000,2}, {0x0001,2}, {0x0005,3}, {0x0006,3}, {0x000e,4},
+  {0x001e,5}, {0x003e,6}, {0x007e,7}, {0x00fe,8}, {0x01fe,9}, {0x01ff,9}
+};
+
+
+/* Table B-13, variable length codes for dct_dc_size_chrominance
+ *
+ * indexed by [dct_dc_size_chrominance]
+ */
+
+static sVLCtable DCchromtab[12]=
+{
+  {0x0000,2}, {0x0001,2}, {0x0002,2}, {0x0006,3}, {0x000e,4}, {0x001e,5},
+  {0x003e,6}, {0x007e,7}, {0x00fe,8}, {0x01fe,9}, {0x03fe,10},{0x03ff,10}
+};
+
+
+/* Table B-14, DCT coefficients table zero
+ *
+ * indexed by [run][level-1]
+ * split into two tables (dct_code_tab1, dct_code_tab2) to reduce size
+ * 'first DCT coefficient' condition and 'End of Block' are treated elsewhere
+ * codes do not include s (sign bit)
+ */
+
+static VLCtable dct_code_tab1[2][40]=
+{
+ /* run = 0, level = 1...40 */
+ {
+  {0x03, 2}, {0x04, 4}, {0x05, 5}, {0x06, 7},
+  {0x26, 8}, {0x21, 8}, {0x0a,10}, {0x1d,12},
+  {0x18,12}, {0x13,12}, {0x10,12}, {0x1a,13},
+  {0x19,13}, {0x18,13}, {0x17,13}, {0x1f,14},
+  {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},
+  {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},
+  {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},
+  {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},
+  {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},
+  {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15}
+ },
+ /* run = 1, level = 1...18 */
+ {
+  {0x03, 3}, {0x06, 6}, {0x25, 8}, {0x0c,10},
+  {0x1b,12}, {0x16,13}, {0x15,13}, {0x1f,15},
+  {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},
+  {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},
+  {0x11,16}, {0x10,16}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}
+ }
+};
+
+static VLCtable dct_code_tab2[30][5]=
+{
+  /* run = 2...31, level = 1...5 */
+  {{0x05, 4}, {0x04, 7}, {0x0b,10}, {0x14,12}, {0x14,13}},
+  {{0x07, 5}, {0x24, 8}, {0x1c,12}, {0x13,13}, {0x00, 0}},
+  {{0x06, 5}, {0x0f,10}, {0x12,12}, {0x00, 0}, {0x00, 0}},
+  {{0x07, 6}, {0x09,10}, {0x12,13}, {0x00, 0}, {0x00, 0}},
+  {{0x05, 6}, {0x1e,12}, {0x14,16}, {0x00, 0}, {0x00, 0}},
+  {{0x04, 6}, {0x15,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x07, 7}, {0x11,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x05, 7}, {0x11,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x27, 8}, {0x10,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x23, 8}, {0x1a,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x22, 8}, {0x19,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x20, 8}, {0x18,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x0e,10}, {0x17,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x0d,10}, {0x16,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x08,10}, {0x15,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1f,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1a,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x19,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x17,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x16,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1f,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1e,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1d,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1c,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1b,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1f,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1e,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1d,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1c,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1b,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}
+};
+
+
+/* Table B-15, DCT coefficients table one
+ *
+ * indexed by [run][level-1]
+ * split into two tables (dct_code_tab1a, dct_code_tab2a) to reduce size
+ * 'End of Block' is treated elsewhere
+ * codes do not include s (sign bit)
+ */
+
+static VLCtable dct_code_tab1a[2][40]=
+{
+ /* run = 0, level = 1...40 */
+ {
+  {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},
+  {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},
+  {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},
+  {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},
+  {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},
+  {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},
+  {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},
+  {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},
+  {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},
+  {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15}
+ },
+ /* run = 1, level = 1...18 */
+ {
+  {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},
+  {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},
+  {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},
+  {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},
+  {0x11,16}, {0x10,16}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
+  {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}
+ }
+};
+
+static VLCtable dct_code_tab2a[30][5]=
+{
+  /* run = 2...31, level = 1...5 */
+  {{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10}, {0x14,13}},
+  {{0x07, 5}, {0x26, 8}, {0x1c,12}, {0x13,13}, {0x00, 0}},
+  {{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x00, 0}, {0x00, 0}},
+  {{0x07, 6}, {0x04, 9}, {0x12,13}, {0x00, 0}, {0x00, 0}},
+  {{0x06, 7}, {0x1e,12}, {0x14,16}, {0x00, 0}, {0x00, 0}},
+  {{0x04, 7}, {0x15,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x05, 7}, {0x11,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x78, 7}, {0x11,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x7a, 7}, {0x10,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x21, 8}, {0x1a,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x25, 8}, {0x19,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x24, 8}, {0x18,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x05, 9}, {0x17,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x07, 9}, {0x16,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x0d,10}, {0x15,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1f,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1a,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x19,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x17,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x16,12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1f,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1e,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1d,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1c,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1b,13}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1f,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1e,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1d,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1c,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}},
+  {{0x1b,16}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}}
+};
diff --git a/src/gdcmmpeg2/src/mpeg2enc/writepic.c b/src/gdcmmpeg2/src/mpeg2enc/writepic.c
new file mode 100644 (file)
index 0000000..5914034
--- /dev/null
@@ -0,0 +1,81 @@
+/* writepic.c, write reconstructed pictures                                 */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose.  In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders.  Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.h"
+#include "global.h"
+
+void writeframe(fname,frame)
+char *fname;
+unsigned char *frame[];
+{
+  int chrom_hsize, chrom_vsize;
+  char name[128];
+  FILE *fd;
+
+  chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
+                                           : horizontal_size>>1;
+
+  chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
+                                           : vertical_size>>1;
+
+  if (fname[0]=='-')
+    return;
+
+  /* Y */
+  sprintf(name,"%s.Y",fname);
+  if (!(fd = fopen(name,"wb")))
+  {
+    sprintf(errortext,"Couldn't create %s\n",name);
+    error(errortext);
+  }
+  fwrite(frame[0],1,horizontal_size*vertical_size,fd);
+  fclose(fd);
+
+  /* Cb */
+  sprintf(name,"%s.U",fname);
+  if (!(fd = fopen(name,"wb")))
+  {
+    sprintf(errortext,"Couldn't create %s\n",name);
+    error(errortext);
+  }
+  fwrite(frame[1],1,chrom_hsize*chrom_vsize,fd);
+  fclose(fd);
+
+  /* Cr */
+  sprintf(name,"%s.V",fname);
+  if (!(fd = fopen(name,"wb")))
+  {
+    sprintf(errortext,"Couldn't create %s\n",name);
+    error(errortext);
+  }
+  fwrite(frame[2],1,chrom_hsize*chrom_vsize,fd);
+  fclose(fd);
+}