Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / mpeg2enc / putmpg.c
diff --git a/cinelerra-5.1/mpeg2enc/putmpg.c b/cinelerra-5.1/mpeg2enc/putmpg.c
new file mode 100644 (file)
index 0000000..f76d824
--- /dev/null
@@ -0,0 +1,145 @@
+/* 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(slice_engine_t *engine, 
+       pict_data_s *picture, 
+       short *blk, 
+       int cc)
+{
+       int n, dct_diff, run, signed_level;
+
+/* DC coefficient (7.2.1) */
+       dct_diff = blk[0] - engine->dc_dct_pred[cc]; /* difference to previous block */
+       engine->dc_dct_pred[cc] = blk[0];
+
+       if(cc == 0)
+       putDClum(engine, dct_diff);
+       else
+       putDCchrom(engine, dct_diff);
+
+/* AC coefficients (7.2.2) */
+       run = 0;
+       for(n = 1; n < 64; n++)
+       {
+/* use appropriate entropy scanning pattern */
+       signed_level = blk[(picture->altscan ? alternate_scan_hv : mpeg2_zig_zag_scan)[n]];
+       if (signed_level!=0)
+       {
+//printf("putintrablk 1 %d\n", picture->altscan);slice_testbits(engine);
+               putAC(engine, run, signed_level, picture->intravlc);
+//printf("putintrablk 2\n");slice_testbits(engine);
+               run = 0;
+       }
+       else
+               run++; /* count zero coefficients */
+       }
+
+/* End of Block -- normative block punctuation */
+       if (picture->intravlc)
+       slice_putbits(engine, 6, 4); /* 0110 (Table B-15) */
+       else
+       slice_putbits(engine, 2, 2); /* 10 (Table B-14) */
+}
+
+/* generate variable length codes for a non-intra-coded block (6.2.6, 6.3.17) */
+void putnonintrablk(slice_engine_t *engine, 
+       pict_data_s *picture, 
+       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[(picture->altscan ? alternate_scan_hv : mpeg2_zig_zag_scan)[n]];
+
+      if (signed_level!=0)
+      {
+         if (first)
+         {
+/* first coefficient in non-intra block */
+                 putACfirst(engine, run, signed_level);
+                 first = 0;
+         }
+         else
+               putAC(engine, run, signed_level, 0);
+
+         run = 0;
+      }
+      else
+          run++; /* count zero coefficients */
+       }
+
+/* End of Block -- normative block punctuation  */
+       slice_putbits(engine, 2, 2);
+}
+
+/* generate variable length code for a motion vector component (7.6.3.1) */
+void putmv(slice_engine_t *engine, int dmv, int 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(engine, motion_code); /* variable length code */
+
+       if (r_size != 0 && motion_code != 0)
+       slice_putbits(engine, motion_residual, r_size); /* fixed length code */
+}