/*****************************************************************************
 "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)
        Minhua Zhou (HHI Berlin)

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

/***********************************************************HeaderBegin*******
 *                                                                         
 * File:	alp_code_header.c
 *
 * Author:	TOSHIBA + Noel Brady Teltec Irl.
 * Created:	11-04-97
 *                                                                         
 * Description: Contains functions for encoding the first_shape_code in 
 *							I/P/B Vops
 *
 *                                 
 ***********************************************************HeaderEnd*********/


#include<stdio.h>
#ifndef WIN32
#include<values.h>
#endif
#include <string.h>
#include "momusys.h"
#include "alp_common_def.h"
#include "alp_mode_tables.h"
#include "vm_common_defs.h"
#include "alp_common_util.h"
#include "alp_code_header.h"

#define _ENCODE_DEBUG_FIRST
#define _MB_TYPE_DEBUG


/* ######### VM7 Shape Mode Encoding (I-VOP) ########## */

Int CodeIntraMBtype( UChar *stream, Int mb_type, Int i,
	Int j, Vop *vop)
{
  Int 	context;
  Int  total, max_stream;
  Char tmp[6];
  Int		a=3,b=3,c=3,d=3;
  Int last_col = GetVopWidth(vop)/MB_SIZE - 1;
  SInt *cur_shape_mode = (SInt *)GetImageData(GetVopShapeMode(vop));
  Int  hsize = GetImageSizeX(GetVopShapeMode(vop));

  max_stream = MAX_STREAM;
 
  total = 0;
	if (i>0)
		{
			if (j>0) a = cur_shape_mode[(i-1)*hsize+j-1]+1;
			b = cur_shape_mode[(i-1)*hsize+j]+1;
			if (j<last_col)	c = cur_shape_mode[(i-1)*hsize+j+1]+1;
		}
	if (j>0) d = cur_shape_mode[i*hsize+j-1]+1;

	context = 27*(a-3) +	9*(b-3) +	3*(c-3) + d-3;

 	strcpy(tmp, IMB_TYPE[context][cur_shape_mode[i*hsize+j]-2]);
  StreamOut(stream, &total, &max_stream, tmp);
  return total;
}


Int CodeIntraMBtype_ER( UChar *stream, Int mb_type, Int i,
	Int j, Vop *vop, Image *alpha_mode_packet)
{
  Int 	context;
  Int  total, max_stream;
  Char tmp[6];
  Int		a=3,b=3,c=3,d=3;
	Int width = GetImageSizeX(alpha_mode_packet);
  Int last_col = GetVopWidth(vop)/MB_SIZE - 1;
	SInt *p = (SInt *) GetImageData(alpha_mode_packet);
  SInt *cur_shape_mode = (SInt *)GetImageData(GetVopShapeMode(vop));
  Int  hsize = GetImageSizeX(GetVopShapeMode(vop));
  max_stream = MAX_STREAM;

  total = 0;
	if (i>0)
		{
			if (j>0 && p[(i-1)*width+j-1]) a = cur_shape_mode[(i-1)*hsize+j-1]+1;
			if (p[(i-1)*width+j])  b = cur_shape_mode[(i-1)*hsize+j]+1;
			if (j<last_col && p[(i-1)*width+j+1])	c = cur_shape_mode[(i-1)*hsize+j+1]+1;
		}
	if (j>0 && p[i*width+j-1]) d = cur_shape_mode[i*hsize+j-1]+1;

	p[i*width+j] = 1;

	context = 27*(a-3) +	9*(b-3) +	3*(c-3) + d-3;

 	strcpy(tmp, IMB_TYPE[context][cur_shape_mode[i*hsize+j]-2]);
  StreamOut(stream, &total, &max_stream, tmp);
  return total;
}

/* ######### VM7 Shape Mode Encoding (INTER) ########## */

Int
CodeInterMBtype(
				Int i,
				Int j,
				UChar *stream,
                                Vop *vop,
                                Vop *ref_vop
		   )
{
  Char
    tmp[9];

  Int
    max_stream=7,
    prei,prej,
    bits=0,
    curr_mode,
    prev_mode;
  SInt *cur_shape_mode = (SInt *)GetImageData(GetVopShapeMode(vop));
  Int  hsize = GetImageSizeX(GetVopShapeMode(vop));
  SInt *ref_shape_mode = (SInt *)GetImageData(GetVopShapeMode(ref_vop));
  Int  hsize_ref = GetImageSizeX(GetVopShapeMode(ref_vop));
  Int  vsize_ref = GetImageSizeY(GetVopShapeMode(ref_vop));


  if(i<vsize_ref) prei=i;   else prei=vsize_ref-1;

  if(j<hsize_ref) prej=j;  else prej=hsize_ref-1;

	prev_mode = ref_shape_mode[prei*hsize_ref+prej];

	curr_mode = cur_shape_mode[i*hsize+j];

	switch (prev_mode)
		{
			case 0: strcpy( tmp, MMB_TYPE0[curr_mode]);	
							break;
			case 1: strcpy( tmp, MMB_TYPE1[curr_mode]);	
							break;
			case 2: strcpy( tmp, MMB_TYPE2[curr_mode]);	
							break;
			case 3: strcpy( tmp, MMB_TYPE3[curr_mode]);	
							break;
			case 4: strcpy( tmp, MMB_TYPE4[curr_mode]);	
							break;
			case 5: strcpy( tmp, MMB_TYPE5[curr_mode]);	
							break;
			case 6: strcpy( tmp, MMB_TYPE6[curr_mode]);	
							break;
			default: printf("Error in PRE_MB_TYPE\n");
							 exit(-1);
	}

  StreamOut(stream, &bits, &max_stream, tmp);

  return bits;
}


void
MakeMBtype(
	   Int mb_type,
	   Int mvda,
	   Int i,
	   Int j,
           Vop *vop
	   )
{

  SInt *cur_shape_mode = (SInt *)GetImageData(GetVopShapeMode(vop));
  Int  hsize = GetImageSizeX(GetVopShapeMode(vop));


  if(mb_type==-1) 
		{
    	if(mvda==1) {
      	/* MVDs==0 */
      	cur_shape_mode[i*hsize+j]=0;
    	}else {
      	/* MVDs!=0 */
      	cur_shape_mode[i*hsize+j]=1;
    	}
		}
	else if(mb_type==0){
    /* all255 */
    cur_shape_mode[i*hsize+j]=3;
  }else if(mb_type==1){
    /* all0  */
    cur_shape_mode[i*hsize+j]=2;
  }else if(mb_type>=2 && mb_type<=6){
    /* MMR */
    if (mb_type<=4) cur_shape_mode[i*hsize+j]=4;
		else 
			{
				if (mvda==1) cur_shape_mode[i*hsize+j]=5;
				else cur_shape_mode[i*hsize+j]=6;
			}
  }
	else{
    printf("wrong mb_type=%d: i j=%d %d\n",mb_type,i,j);
    exit(0);
  }

}



Int GetModeCodeLength(
		      Int mode,
		      Int j,
		      Int i,
                      Vop *ref_vop
		   )
{
  Int
    prei,prej,
		curr_mode=4,
		prev_mode;
  SInt *ref_shape_mode = (SInt *)GetImageData(GetVopShapeMode(ref_vop));
  Int  hsize_ref = GetImageSizeX(GetVopShapeMode(ref_vop));
  Int  vsize_ref = GetImageSizeY(GetVopShapeMode(ref_vop));


 if(i<vsize_ref) prei=i;   else prei=vsize_ref-1;

  if(j<hsize_ref) prej=j;  else prej=hsize_ref-1;

	prev_mode = ref_shape_mode[prei*hsize_ref+prej];
	
	if (mode==2) curr_mode = 4;
	if (mode==5) curr_mode = 6;
	if (mode==6) curr_mode = 5;

	switch (prev_mode)
		{
			case 0: return strlen(MMB_TYPE0[curr_mode]);	
							break;
			case 1: return strlen(MMB_TYPE1[curr_mode]);	
							break;
			case 2: return strlen(MMB_TYPE2[curr_mode]);	
							break;
			case 3: return strlen(MMB_TYPE3[curr_mode]);	
							break;
			case 4: return strlen(MMB_TYPE4[curr_mode]);	
							break;
			case 5: return strlen(MMB_TYPE5[curr_mode]);	
							break;
			case 6: return strlen(MMB_TYPE6[curr_mode]);	
							break;
			default: printf("Error in PRE_MB_TYPE\n");
							 exit(-1);
	}
}







