/*****************************************************************************
 "This software module was originally developed by:

	Noboru Yamaguchi (TOSHIBA CORPORATION), 
	Takashi Ida (TOSHIBA CORPORATION) 

	and edited by:

 	Toshiaki Watanabe (TOSHIBA CORPORATION), 
	Yoshihiro Kikuchi (TOSHIBA CORPORATION), 
	Noel Brady (TELTEC IRELAND)

	in the course of development of the <MPEG-4 Video(ISO/IEC 14496-2)>. This
  software module is an implementation of a part of one or more <MPEG-4 Video
  (ISO/IEC 14496-2)> tools as specified by the <MPEG-4 Video(ISO/IEC 14496-2)
  >. ISO/IEC gives users of the <MPEG-4 Video(ISO/IEC 14496-2)> free license
  to this software module or modifications thereof for use in hardware or
  software products claiming conformance to the <MPEG-4 Video(ISO/IEC 14496-2
  )>. Those intending to use this software module in hardware or software
  products are advised that its use may infringe existing patents. The
  original developer of this software module and his/her company, the
  subsequent editors and their companies, and ISO/IEC have no liability for
  use of this software module or modifications thereof in an implementation.
  Copyright is not released for non <MPEG-4 Video(ISO/IEC 14496-2)>
  conforming products. TOSHIBA CORPORATION retains full right to use the code
  for his/her own purpose, assign or donate the code to a third party and to
  inhibit third parties from using the code for non <MPEG-4 Video(ISO/IEC
  14496-2)> conforming products. This copyright notice must be included in
  all copies or derivative works. Copyright (c)1996".
 *****************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "io_generic.h"
#include "momusys.h"
#include "mom_structs.h"
#include "mot_comp.h"
#include "mot_util.h"
#include "vm_dec_defs.h"
#include "mom_bitstream_d.h"
#include "alp_mv_tables.h"
#include "alp_common_def.h"
#include "alp_common_mc.h"
#include "alp_dec_util.h"
#include "alp_dec_mc.h"

#define _DECODE_DEBUG_MC

int
DecodeAlphaAndMVmei (Vop *rec_curr,
		     Int x,
		     Int y,
				Int ox,							/* added by Noel Brady */
				Int oy,							/* added by Noel Brady */
		     Image *mot_x,
		     Image *mot_y,
		     Image *motA_x,
		     Image *motA_y,
		     Image *MB_decisions, 
					Image *alpha_decisions,
		     Image *modeA,
		     SInt* prev,
		     SInt* pred,
		     Int mvda,
		     Int width,
		     UInt width_prev, 
		     UInt height_prev, 
		     SInt mb_size,
		     Bitstream *shape_stream,
				Trace *trace)
{
  Int mvbits;
  Int i, ix, iy;
  Int mvp_x, mvp_y, mvs_x, mvs_y;
  SInt tmp_pred[16][16];
	SInt binary_shape_only;
	Int error_res_disable;

#ifdef DECODE_DEBUG_MC
  fprintf(stdout, "DECODE:alphaMV (i,j)=(%2d,%2d)\n",(x/mb_size),(y/mb_size));
#endif

	if (GetVopShape(rec_curr) == BINARY_SHAPE_ONLY)   /* BSO_NOEL */
		binary_shape_only = 1;
	else
		binary_shape_only = 0;

	error_res_disable = GetVopErrorResDisable(rec_curr);

    if (GetVopPredictionType(rec_curr)==B_VOP) 
       FindMVB(x,y,mot_x,mot_y,motA_x,motA_y,MB_decisions,
				modeA,&mvp_x,&mvp_y,width,mb_size);
     else   
       FindMVP(x,y,mot_x,mot_y,motA_x,motA_y,MB_decisions,
				modeA,&mvp_x,&mvp_y,width,mb_size,
				MBM_TRANSPARENT,alpha_decisions,binary_shape_only,
				error_res_disable);
			if (trace->trace)
				fprintf(trace->fp_trace,"MVPs = (%d,%d)\n",mvp_x,mvp_y);

#ifdef DECODE_DEBUG_MC
  fprintf(stdout, "MVP=(%3d,%3d) mode=%d\n",mvp_x,mvp_y,
	  ModeMB(MB_decisions,(x/mb_size),(y/mb_size)));
#endif

  mvbits = 0;
  if( mvda == 1 ) {
    /* DmotA = ( 0, 0 ) */
    FindPredAlpha4MC (x+ox,y+oy,mvp_x,mvp_y,prev,&tmp_pred[0][0],0,
		      width_prev,height_prev,mb_size);
    FindPredAlpha4MC (x+ox,y+oy,mvp_x,mvp_y,prev,&tmp_pred[0][8],1,
		      width_prev,height_prev,mb_size);
    FindPredAlpha4MC (x+ox,y+oy,mvp_x,mvp_y,prev,&tmp_pred[8][0],2,
		      width_prev,height_prev,mb_size);
    FindPredAlpha4MC (x+ox,y+oy,mvp_x,mvp_y,prev,&tmp_pred[8][8],3,
		      width_prev,height_prev,mb_size);
    SetAlphaMV (x,y,motA_x,motA_y,mvp_x,mvp_y,width,mb_size);
  } else if( mvda == 0 ) {
    /* DmotA != ( 0, 0 ) */
    mvbits += DecodeMVDs (&ix, shape_stream, 0, trace);
    if( ix == 0 )
      mvbits += DecodeMVDs (&iy, shape_stream, 1, trace);
    else
      mvbits += DecodeMVDs (&iy, shape_stream, 0, trace);
#ifdef DECODE_DEBUG_MC
    fprintf(stdout, "MVDs=(%3d,%3d)\n",ix,iy);
#endif
    FindAdress (mvp_x,mvp_y,ix,iy,&mvs_x,&mvs_y);
		if (trace->trace)
			fprintf(trace->fp_trace,"MVs = (%d,%d)\n",mvs_x,mvs_y);
    FindPredAlpha4MC (x+ox,y+oy,mvs_x,mvs_y,prev,&tmp_pred[0][0],0,
		      width_prev,height_prev,mb_size);
    FindPredAlpha4MC (x+ox,y+oy,mvs_x,mvs_y,prev,&tmp_pred[0][8],1,
		      width_prev,height_prev,mb_size);
    FindPredAlpha4MC (x+ox,y+oy,mvs_x,mvs_y,prev,&tmp_pred[8][0],2,
		      width_prev,height_prev,mb_size);
    FindPredAlpha4MC (x+ox,y+oy,mvs_x,mvs_y,prev,&tmp_pred[8][8],3,
		      width_prev,height_prev,mb_size);
    SetAlphaMV (x,y,motA_x,motA_y,mvs_x,mvs_y,width,mb_size);    
  } else {
    fprintf (stderr, "Error in DecodeAlphaAndMVmei\n");
    exit (-1);
  }

  for( i=0; i<mb_size*mb_size; i++ ) *(pred+i) = *(&tmp_pred[0][0]+i);

  return(mvbits);
}

Int
DecodeMVDs(Int *MVDs, Bitstream *stream, Int offset, Trace *trace)
{
  Int i, bits, abs_mv;
	Int i1,j1,len;

  bits=0;
  for( i=0; i<=16; i++ ) {
		len = strlen(Cmvds[i]);
		i1 = BitstreamShowBits(stream, len);
		j1 = ConvertStoI(Cmvds[i],len);
    if(i1==j1) {
      bits = len;
      abs_mv = i + offset;
      goto EXIT;
    }
  }
  fprintf(stderr,"ERROR:DecodeMVDs\n");
  exit(0);
 EXIT:
	BitstreamReadBits(stream,bits,"abs_mvs",trace,CODE);
  if( abs_mv > 0 ) {
		i = BitstreamReadBits(stream,1,"sign_mvs_positive",trace,FLAG);
    if(i == 1) {
      *MVDs = abs_mv;
      bits++;
    } else if(i == 0) {
      *MVDs = -abs_mv;
      bits++;
    }
  } else {
    *MVDs = abs_mv;
  }
  return (bits);
}
