/*****************************************************************************
 "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), 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".
 *****************************************************************************/

/***************** M4R codec ***************
       shape encoder/decoder modules
         ( ME/MC common modules )

*********************************************/

#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_est.h"
#include "mot_padding.h"
#include "mot_util.h"
#include "vm_common_defs.h"
#include "vm_enc_defs.h"
#include "vm_stats.h"
#include "vm_vop_bound.h"
#include "alp_common_def.h"
#include "alp_common_mc.h"

Void
FindPredAlpha4MC (Int x,
 	          Int y,
	          Int  motA_x,
	          Int  motA_y,
	          SInt* prev,
	          SInt* pred,
	          SInt comp,
	          UInt width_prev, 
	          UInt height_prev, 
	          SInt mb_size)
{
  Int m, n;
  Int pc;
  Int nxc;
  Int nyc;
  Int lx, ly;

  lx = width_prev;
  ly = height_prev;

  nxc = x + ((comp&1)<<3);
  nyc = y + ((comp&2)<<2);

  nxc += motA_x;
  nyc += motA_y;

  /* Fill pred. data */
  for (n = 0; n < 8; n++) {
    for (m = 0; m < 8; m++) {
      if( (nyc + n) >= ly || (nyc + n) < 0
	 || (nxc + m) >= lx || (nxc + m) < 0 )
	pc = 0;
      else
	pc = *(prev + nxc + m + (nyc + n)*lx);
      *(pred + m + n*mb_size) = pc;
    }	
  }
  return;
}

Void
FindAdress (Int mvp_x,
	    Int mvp_y,
	    Int dmv_x,
	    Int dmv_y,
	    Int *mvs_x,
	    Int *mvs_y)
{

  *mvs_x = mvp_x + dmv_x;
  *mvs_y = mvp_y + dmv_y;

  return;
}

Void
SetAlphaMV (Int x,
	    Int y,
	    Image *motA_x,
	    Image *motA_y,
	    Int    mvs_x,
	    Int    mvs_y,
	    UInt width, 
	    SInt mb_size)
{

  motA_x->data->s[(y/mb_size)*(width/mb_size)+x/mb_size] = mvs_x;
  motA_y->data->s[(y/mb_size)*(width/mb_size)+x/mb_size] = mvs_y;
}

Void
FindMVP (Int x,
	 Int y,
	 Image *mot_x,
	 Image *mot_y,
	 Image *motA_x,
	 Image *motA_y,
	 Image *mode,
	 Image *modeA,
	 Int   *mvp_x,
	 Int   *mvp_y,
	 Int 	width,
	 SInt mb_size,
	 SInt transparent_value,
	 Image *alpha_decisions,
	 SInt binary_shape_only,					/* BSO_NOEL */
	 Int error_res_disable
	)
{
  Int cols, i, j, xB;

	SInt *dcsn_data;

  cols = width/mb_size;

  /* get MV */
  i = y/mb_size;
  j = x/mb_size;

  if( i == 0 && j== 0 ) {
    *mvp_x = *mvp_y = 0;
  } else if( j != 0 && ModeAMB(modeA,(j-1),i) == 1 ) {
    *mvp_x = motA_x->data->s[i*cols+(j-1)];
    *mvp_y = motA_y->data->s[i*cols+(j-1)];
  } else if( i != 0 && ModeAMB(modeA,j,(i-1)) == 1 ) {
    *mvp_x = motA_x->data->s[(i-1)*cols+j];
    *mvp_y = motA_y->data->s[(i-1)*cols+j];
  } else if( i != 0 && j != (cols-1) && ModeAMB(modeA,(j+1),(i-1)) == 1 ) {
    *mvp_x = motA_x->data->s[(i-1)*cols+(j+1)];
    *mvp_y = motA_y->data->s[(i-1)*cols+(j+1)];
  } else 
			{
				if (!binary_shape_only && error_res_disable)				/* BSO_ONLY */
					{
						xB = cols*2;
						dcsn_data = (SInt *) GetImageData(alpha_decisions);

						if( j != 0 &&
	    					ValidCandidateMVP(j,i,j-1,i,1,xB,transparent_value
													,mode ,dcsn_data) ) 
							{
    						*mvp_x = (int)(mot_x->data->f[i*2*cols*2+(j-1)*2+1]);
    						*mvp_y = (int)(mot_y->data->f[i*2*cols*2+(j-1)*2+1]);
  						} 
						else if( i != 0 &&
	    				 	ValidCandidateMVP(j,i,j,i-1,2,xB,transparent_value
													,mode ,dcsn_data) ) 
							{
    						*mvp_x = (int)(mot_x->data->f[((i-1)*2+1)*cols*2+j*2]);
    						*mvp_y = (int)(mot_y->data->f[((i-1)*2+1)*cols*2+j*2]);
  						} 
						else if( i != 0 && j != (cols-1) &&
	    					ValidCandidateMVP(j,i,j+1,i-1,2,xB,transparent_value
													,mode ,dcsn_data) ) 
							{
    						*mvp_x = (int)(mot_x->data->f[((i-1)*2+1)*cols*2+(j+1)*2]);
    						*mvp_y = (int)(mot_y->data->f[((i-1)*2+1)*cols*2+(j+1)*2]);
  						} 
						else 
							{
    						*mvp_x = *mvp_y = 0;
  						}
					}
				else *mvp_x = *mvp_y = 0;				/* BSO_NOEL */
			}

  return;
}


Void
FindMVB (Int x,
	 Int y,
	 Image *mot_x,
	 Image *mot_y,
	 Image *motA_x,
	 Image *motA_y,
	 Image *mode,
	 Image *modeA,
	 Int   *mvp_x,
	 Int   *mvp_y,
	 Int width,
	 SInt mb_size)
{
  Int cols, i, j;

  cols = width/mb_size;

  /* get MV */
  i = y/mb_size;
  j = x/mb_size;

  if( i == 0 && j== 0 ) {
    *mvp_x = *mvp_y = 0;
  } else if( j != 0 && ModeAMB(modeA,(j-1),i) == 1 ) {
    *mvp_x = motA_x->data->s[i*cols+(j-1)];
    *mvp_y = motA_y->data->s[i*cols+(j-1)];
  } else if( i != 0 && ModeAMB(modeA,j,(i-1)) == 1 ) {
    *mvp_x = motA_x->data->s[(i-1)*cols+j];
    *mvp_y = motA_y->data->s[(i-1)*cols+j];
  } else if( i != 0 && j != (cols-1) && ModeAMB(modeA,(j+1),(i-1)) == 1 ) {
    *mvp_x = motA_x->data->s[(i-1)*cols+(j+1)];
    *mvp_y = motA_y->data->s[(i-1)*cols+(j+1)];
   }  else {
    *mvp_x = *mvp_y = 0;
  }
  return;
}




SInt
ModeAMB (Image *modeA, Int i, Int j)
{
  Int	width = modeA->x;
  SInt	*p = (SInt *)GetImageData(modeA);

  return p[width*j+i];
}

