/*****************************************************************************
 *
 * This software module was originally developed by
 *
 *   Noel Brady (TELTEC IRELAND / ACTS-MoMuSys)
 *
 * in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
 * 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) standard.
 *
 * ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard 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) standard.
 *
 * 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) Standard conforming
 * products.
 *
 * ACTS-MoMuSys partners retain 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) Standard
 * conforming products. This copyright notice must be included in all copies or
 * derivative works.
 *
 * Copyright (c) 1997
 *
 *****************************************************************************/


/***********************************************************HeaderBegin*******
 *                                                                         
 * File:	alp_dec_cae.c
 *
 * Author:	Noel Brady Teltec Irl.
 * Created:	11-04-97
 *                                                                         
 * Description: Contains functions used to implement block-based CAE
 *							decoding.
 *
 *
 *                                 
 ***********************************************************HeaderEnd*********/

/************************    INCLUDE FILES    ********************************/

#include<stdio.h>
#ifndef WIN32
#include<values.h>
#endif
#include <string.h>
#include "momusys.h"
#include "mom_structs.h"
#include "mom_bitstream_d.h"
#include "vm_dec_defs.h"
#include "alp_common_def.h"
#include "alp_common_cae.h"
#include "alp_dec_cae.h"
#include "bin_ar_decode.h"
#include "alp_dec_mom.h"
#include "alp_common_util.h"
#include "alp_dec_util.h"
	
#include "cae_intra.h"
#include "cae_inter.h"



/***********************************************************CommentBegin******
 *
 * -- ShapeDecodingCAE -- Decodes a binary alpha block using intraCAE.
 *
 * Author :		
 *	Noel Brady Teltec Irl.
 *
 * Created :		
 *	11-04-97
 * 
 * Arguments: 	
 *			stream  				: input bitstream
 *			alpha_dmb				: reconstructed alpha block 
 *			alpha_mb_comp,	:	MC alpha block
 * 			rec_curr_alpha  : reconstructed alpha plane
 *			x,y							:	address of binary alpha block in pixels
 *  		fixed_cr				: =0, CR must be decoded for the block
 *											: =1, CR is assumed fixed (=1)
 *			mb_type					: alpha block type/coding mode
 *
 * Return values :	
 *
 * Side effects :	
 *	-
 *
 * Description : decodes CR, ST and BAC and upsamples if necessary
 *
 * See also :
 *
 * Modified:
 *      10.12.97 Luis Ducla-Soares: added 'Int *error_flag' to the arguments
 *                                   list.
 *
 ***********************************************************CommentEnd********/

Int ShapeDecodingCAE(Bitstream *stream, 
		     UChar *alpha_dmb, 
		     UChar *alpha_mb_comp,
		     Image *rec_curr_alpha,
		     Image *alpha_rec_packet,	
		     Int 	x,
		     Int 	y,
		     Int 	fixed_cr,
		     Int *mb_type,
		     Int error_res_disable,
		     Trace *trace,
		     Int *error_flag)
{
  Image *top_border=NULL,
				*left_border=NULL,
				*bordered_smb=NULL,
				*bordered_smb_v=NULL,
				*top_sborder,
				*left_sborder,
				*tmp_im;
  
  UChar alpha_smb[MB_SIZE*MB_SIZE];
  Int i, j, ret, ret_mb, mb_s;
  Int width, height, bsize;
  Int st=0;

	SInt *p;

  ret = 0;

  for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
    alpha_smb[i*MB_SIZE+j] = 0;

  if( *mb_type == -1 ) 
  {
	for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
      		alpha_dmb[i*MB_SIZE+j] = f1bit(BINARISE(alpha_mb_comp[i*MB_SIZE+j]));
  } 
  else if( *mb_type == 0 ) 
  {
	for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ ) 	
		alpha_dmb[i*MB_SIZE+j] = 1;
  } 
  else if ( *mb_type == 1 ) 
  {
	for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ ) 	
		alpha_dmb[i*MB_SIZE+j] = 0;
  } 
  else 
  {

        /* decode header */
    	ret_mb = Decode_CR_ST(stream, mb_type, &mb_s, &st, fixed_cr, trace);
	ret += ret_mb;

	/* construct the bordered and subsampled MB */

	bordered_smb = AllocImage(mb_s+4,mb_s+4,SHORT_TYPE);

	top_border = AllocImage(MB_SIZE+4,2,SHORT_TYPE);
	left_border = AllocImage(2,MB_SIZE,SHORT_TYPE);

	if (error_res_disable)
	{
		if (y>1) GetSubImage(rec_curr_alpha,top_border,x-2,y-2);
		else SetConstantImage(top_border,0);
		if (x>1) GetSubImage(rec_curr_alpha,left_border,x-2,y);
		else SetConstantImage(left_border,0);
	}
	else
	{
		if (y>1) GetSubImage(alpha_rec_packet,top_border,x-2,y-2);
		else SetConstantImage(top_border,0);
		if (x>1) GetSubImage(alpha_rec_packet,left_border,x-2,y);
		else SetConstantImage(left_border,0);
	}
					
	BinariseImage(top_border);
	BinariseImage(left_border);

	if (mb_s != MB_SIZE) 
	{
		top_sborder=TopBorderDecimate(top_border,MB_SIZE/mb_s);
		left_sborder=LeftBorderDecimate(left_border,MB_SIZE/mb_s);

		PutSubImage(bordered_smb,top_sborder,0,0);
		PutSubImage(bordered_smb,left_sborder,0,2);
	
		FreeImage(top_sborder);
		FreeImage(left_sborder);
	}
	else 
	{
		PutSubImage(bordered_smb,top_border,0,0);
		PutSubImage(bordered_smb,left_border,0,2);
	}
	FreeImage(top_border);
	FreeImage(left_border);

	tmp_im = AllocImage(2,1,SHORT_TYPE);
	GetSubImage(bordered_smb,tmp_im,0,mb_s+1);
	PutSubImage(bordered_smb,tmp_im,0,mb_s+2);
	PutSubImage(bordered_smb,tmp_im,0,mb_s+3);
	FreeImage(tmp_im);

	/* transpose the MB */

	if (st==0) {
		bordered_smb_v = AllocSameImage(bordered_smb);
		TransposeImage(bordered_smb,bordered_smb_v);
	}

	/* decode the subsampled MB */
	if (st==0)
	{
	    ret_mb = CAE_DecodeIntra(stream, bordered_smb_v, error_res_disable, 
				     trace, error_flag);
	    TransposeImage(bordered_smb_v,bordered_smb);
				FreeImage(bordered_smb_v);
	}
	else 
	    ret_mb = CAE_DecodeIntra(stream, bordered_smb, error_res_disable, 
							 trace, error_flag);

	ret += ret_mb;	


	/* extract alpha_smb and upsample it */
	/**** SAIT begin ***/
	/****comment out 
		p = (SInt *) GetImageData(bordered_smb) 
						+ 2*GetImageSizeX(bordered_smb)
						+ 2;

  		for( i=0; i<mb_s; i++, p+=GetImageSizeX(bordered_smb)-mb_s ) 
			for( j=0; j<mb_s; j++, p++ ) {
   		 		alpha_smb[i*mb_s+j] = (UChar) (*p);
  			}
		FreeImage(bordered_smb);
	**************/
	/**** SAIT end ****/

    	bsize = mb_s;
    	width = mb_s;
    	height = mb_s;

#ifndef _VM7_FILTER_
        if(MB_SIZE>bsize)
        {
		/** SAIT begin **/
		/* Noel/E14 */
		/***** comment out
		if (error_res_disable) 
		{
       			UpSampling(alpha_smb,alpha_dmb,width,height,
       						        rec_curr_alpha,
                   					GetImageSizeX(rec_curr_alpha),
							GetImageSizeY(rec_curr_alpha),
                   					x,y,
                   					bsize,MB_SIZE );
		}
		else 
		{
        		UpSampling(alpha_smb,alpha_dmb,width,height,
               					        alpha_rec_packet,
                   					GetImageSizeX(rec_curr_alpha),
							GetImageSizeY(rec_curr_alpha),
                   					x,y,
                   					bsize,MB_SIZE );
		}
		******/
       		UpSampling(bordered_smb,alpha_dmb,width,height,
                 				GetImageSizeX(rec_curr_alpha),
						GetImageSizeY(rec_curr_alpha),
                   				x,y,
                   				bsize,MB_SIZE );
		/** SAIT end **/
      	}
	else if(MB_SIZE==bsize)
	{
		/* SAIT begin */
		/***** comment out
        	for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
       	   		alpha_dmb[i*MB_SIZE+j] = alpha_smb[i*MB_SIZE+j];
		********/
          	p = (SInt *) GetImageData(bordered_smb)
            			+ 2*GetImageSizeX(bordered_smb)
              			+ 2;
 
          	for( i=0; i<mb_s; i++, p+=GetImageSizeX(bordered_smb)-mb_s )
            		for( j=0; j<mb_s; j++, p++ ) {
              			alpha_dmb[i*mb_s+j] = (UChar) (*p);
            		}

		/* SAIT end */
      	}
	else
	{
        	fprintf(stderr,"MB_SIZE=%d bsize=%d in ShapeDecodingCAE()\n",
                MB_SIZE,bsize);
        	exit(0);
        }
#else
      /*** SAIT begin ***/
      p = (SInt *) GetImageData(bordered_smb)
        + 2*GetImageSizeX(bordered_smb)
          + 2;
 
      for( i=0; i<mb_s; i++, p+=GetImageSizeX(bordered_smb)-mb_s )
        for( j=0; j<mb_s; j++, p++ ) {
          alpha_smb[i*mb_s+j] = (UChar) (*p);
        }
      /*** SAIT end ***/

    	ChangeSamplingRate( alpha_smb, alpha_dmb, width, height, bsize, MB_SIZE );
			if (mb_s<MB_SIZE) MedianFilterBAB(rec_curr_alpha,x,y,alpha_dmb);
#endif
      FreeImage(bordered_smb); /* SAIT */

		}
    
	for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
		alpha_dmb[i*MB_SIZE+j] = f8bit(alpha_dmb[i*MB_SIZE+j]);

	return ret;
}


/***********************************************************CommentBegin******
 *
 * -- ShapeDecodingInterCAE -- Decodes a binary alpha block using interCAE.
 *
 * Author :		
 *	Noel Brady Teltec Irl.
 *
 * Created :		
 *	11-04-97
 * 
 * Arguments: 	
 *			stream  				: input bitstream
 *			alpha_dmb				: reconstructed alpha block 
 *			alpha_mb_comp,	:	MC alpha block
 * 			rec_curr_alpha  : reconstructed alpha plane
 *			rec_prev_alpha  : previously reconstructed alpha plane
 *			motA_x,mot_Ay		: motion vector field for shape
 *			x,y							:	address of binary alpha block in pixels
 *			ox,oy						: differential offset between sptial refs of
 *												previous and current VOPs
 *  		fixed_cr				: =0, CR must be decoded for the block
 *											: =1, CR is assumed fixed (=1)
 *			mb_type					: alpha block type/coding mode
 *
 * Return values :	
 *
 * Side effects :	
 *	-
 *
 * Description : decodes CR, ST and BAC and upsamples if necessary.
 *
 * See also :
 *
 * Modified:
 *      10.12.97 Luis Ducla-Soares: added 'Int *error_flag' to the arguments
 *                                   list.
 *
 ***********************************************************CommentEnd********/

Int ShapeDecodingInterCAE(Bitstream *stream, 
			  UChar *alpha_dmb, 
			  UChar *alpha_mb_comp,
			  Image *rec_curr_alpha,
			  Image *rec_prev_alpha,
			  Image *alpha_rec_packet,
			  Image *motA_x,
			  Image *motA_y,
			  Int 	x,
			  Int 	y,
			  Int 	ox,
			  Int 	oy,
			  Int 	fixed_cr,
			  Int *mb_type,
			  Int error_res_disable,
			  Trace *trace,
			  Int *error_flag)
{
	Image *top_border = NULL,
				*left_border = NULL,
				*bordered_smb,
				*bordered_smb_v=NULL,
				*top_sborder,
				*left_sborder;

	Image *alpha_smb_mc,
				*alpha_smb_mc_v=NULL,
				*tmp_im;

  UChar
			alpha_smb_comp[MB_SIZE*MB_SIZE],
			alpha_smb[MB_SIZE*MB_SIZE];

  Int i, j, ret, ret_mb, mb_s;
  Int width, height, bsize;
  Int st=0;

	Int		ii,jj,
				mb_x,mb_y,
				mvx,mvy;

	SInt *p;

  ret = 0;

  for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
    alpha_smb[i*MB_SIZE+j] = 0;

  if( *mb_type == -1 ) 
		{
  	  for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
   	   alpha_dmb[i*MB_SIZE+j] = f1bit(BINARISE(alpha_mb_comp[i*MB_SIZE+j]));
		} 
	else if( *mb_type == 0 ) 
		{
    	for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
      	alpha_dmb[i*MB_SIZE+j] = 1;
		} 
	else if ( *mb_type == 1 ) 
		{
    	for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
      	alpha_dmb[i*MB_SIZE+j] = 0;
		} 
	else 
		{

			/* decode header */
			ret_mb = Decode_CR_ST(stream, mb_type, &mb_s, &st, fixed_cr, trace);
			ret += ret_mb;

			/* construct the bordered and subsampled MB */

			bordered_smb = AllocImage(mb_s+4,mb_s+4,SHORT_TYPE);

			top_border = AllocImage(MB_SIZE+4,2,SHORT_TYPE);
			left_border = AllocImage(2,MB_SIZE,SHORT_TYPE);

			if (error_res_disable)
				{
					if (y>1) GetSubImage(rec_curr_alpha,top_border,x-2,y-2);
					else SetConstantImage(top_border,0);
					if (x>1) GetSubImage(rec_curr_alpha,left_border,x-2,y);
					else SetConstantImage(left_border,0);
				}
			else 
				{
					if (y>1) GetSubImage(alpha_rec_packet,top_border,x-2,y-2);
					else SetConstantImage(top_border,0);
					if (x>1) GetSubImage(alpha_rec_packet,left_border,x-2,y);
					else SetConstantImage(left_border,0);
				}
			BinariseImage(top_border);
			BinariseImage(left_border);

			if (mb_s != MB_SIZE) 
				{
					top_sborder=TopBorderDecimate(top_border,MB_SIZE/mb_s);
					left_sborder=LeftBorderDecimate(left_border,MB_SIZE/mb_s);

					PutSubImage(bordered_smb,top_sborder,0,0);
					PutSubImage(bordered_smb,left_sborder,0,2);
	
					FreeImage(top_sborder);
					FreeImage(left_sborder);
				}
			else 
				{
					PutSubImage(bordered_smb,top_border,0,0);
					PutSubImage(bordered_smb,left_border,0,2);
				}
			FreeImage(top_border);
			FreeImage(left_border);

			tmp_im = AllocImage(2,1,SHORT_TYPE);
			GetSubImage(bordered_smb,tmp_im,0,mb_s+1);
			PutSubImage(bordered_smb,tmp_im,0,mb_s+2);
			PutSubImage(bordered_smb,tmp_im,0,mb_s+3);
			FreeImage(tmp_im);
	
			/* get the subsampled MC block */
			mb_x = x/MB_SIZE; mb_y = y/MB_SIZE;
			p = (SInt *) GetImageData(motA_x) 
									+ mb_y*GetImageSizeX(motA_x)
									+ mb_x;
			mvx = *p;
			p = (SInt *) GetImageData(motA_y) 
									+ mb_y*GetImageSizeX(motA_y)
									+ mb_x;
			mvy = *p;
	
			alpha_smb_mc = AllocImage(mb_s+4,mb_s+4,SHORT_TYPE);

			GetBorderedMC(rec_prev_alpha,x+ox,y+oy,mvx,mvy,
							MB_SIZE/mb_s,alpha_smb_mc); 

#ifndef _VM7_FILTER_
	    if(mb_s<MB_SIZE){
	      DownSampling( alpha_mb_comp, alpha_smb_comp, MB_SIZE, MB_SIZE,
			   MB_SIZE, mb_s );
	    } else if(mb_s==MB_SIZE){
	      for(i=0;i<MB_SIZE*MB_SIZE;i++) alpha_smb_comp[i]=alpha_mb_comp[i];
	    } else {
	      fprintf(stderr,"MB_SIZE=%d mb_s=%d in ShapeDecodingInterCAE()\n",
		      MB_SIZE,mb_s);
	      exit(0);
	    }
#else
  		ChangeSamplingRate( alpha_mb_comp, alpha_smb_comp, MB_SIZE, MB_SIZE,
                       MB_SIZE, mb_s );
#endif

			p = (SInt *) GetImageData(alpha_smb_mc)+2*GetImageSizeX(alpha_smb_mc)+2;
  		for( ii=0; ii<mb_s; ii++,p+=4) 
				for( jj=0; jj<mb_s; jj++, p++ ) {
    			*p = (SInt) f1bit(alpha_smb_comp[ii*mb_s+jj]);
  			}


			/* transpose the MB and MC Block*/

			if (st==0) {
				bordered_smb_v = AllocSameImage(bordered_smb);
				TransposeImage(bordered_smb,bordered_smb_v);
				alpha_smb_mc_v = AllocSameImage(alpha_smb_mc);
				TransposeImage(alpha_smb_mc,alpha_smb_mc_v);
			}


			/* decode the subsampled MB */
			if (st==0) 
			  {
			    ret_mb = CAE_DecodeInter(stream, bordered_smb_v,
						     alpha_smb_mc_v, 
						     error_res_disable,
						     trace, error_flag);
					TransposeImage(bordered_smb_v,bordered_smb);
					FreeImage(bordered_smb_v);
					FreeImage(alpha_smb_mc_v);
				}
			else 
			  ret_mb = CAE_DecodeInter(stream, bordered_smb, alpha_smb_mc, 
						   error_res_disable, trace,
						   error_flag);
			
			ret += ret_mb;	

			/* extract alpha_smb and upsample it */
		/** SAIT begin ***/
		/***** comment out 
			p = (SInt *) GetImageData(bordered_smb) 
						+ 2*GetImageSizeX(bordered_smb)
						+ 2;

		  for( i=0; i<mb_s; i++, p+=GetImageSizeX(bordered_smb)-mb_s ) 
				for( j=0; j<mb_s; j++, p++ ) {
		    	alpha_smb[i*mb_s+j] = (UChar) (*p);
		  	}

			FreeImage(bordered_smb);
		*****************/

		  bsize = mb_s;
		  width = mb_s;
		  height = mb_s;

#ifndef _VM7_FILTER_
	    if(MB_SIZE>bsize){
		/**** SAIT begin ****/
		/**** comment out 
				if (error_res_disable)
	      		UpSampling(alpha_smb,alpha_dmb,width,height,
			 						rec_curr_alpha,
			 						GetImageSizeX(rec_curr_alpha),GetImageSizeY(rec_curr_alpha),
			 						x,y,
			 						bsize,MB_SIZE);
				else 
	      		UpSampling(alpha_smb,alpha_dmb,width,height,
			 						alpha_rec_packet,
			 						GetImageSizeX(rec_curr_alpha),GetImageSizeY(rec_curr_alpha),
			 						x,y,
			 						bsize,MB_SIZE);
		*****************/
        	UpSampling(bordered_smb,alpha_dmb,width,height,
                   GetImageSizeX(rec_curr_alpha),
                   GetImageSizeY(rec_curr_alpha),
                   x,y,
                   bsize,MB_SIZE );
		/**** SAIT end ****/

	    }else if(MB_SIZE==bsize){
	      /*** SAIT begin ****/
	      /**** comment out
	      for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
		alpha_dmb[i*MB_SIZE+j] = alpha_smb[i*MB_SIZE+j];
	      **************/
              p = (SInt *) GetImageData(bordered_smb)
          		+ 2*GetImageSizeX(bordered_smb)
            		+ 2;
 
              for( i=0; i<mb_s; i++, p+=GetImageSizeX(bordered_smb)-mb_s )
          	for( j=0; j<mb_s; j++, p++ ) {
            		alpha_dmb[i*mb_s+j] = (UChar) (*p);
              }
              /*** SAIT end ***/

	    }else{
	      fprintf(stderr,"MB_SIZE=%d bsize=%d in ShapeDecodingCAE()\n",
		      MB_SIZE,bsize);
	      exit(0);
	    }
#else
      /*** SAIT begin ***/
      p = (SInt *) GetImageData(bordered_smb)
        + 2*GetImageSizeX(bordered_smb)
          + 2;
 
      for( i=0; i<mb_s; i++, p+=GetImageSizeX(bordered_smb)-mb_s )
        for( j=0; j<mb_s; j++, p++ ) {
          alpha_smb[i*mb_s+j] = (UChar) (*p);
        }
      /*** SAIT end ***/

		  ChangeSamplingRate( alpha_smb, alpha_dmb, width, height, bsize, MB_SIZE );
			if (mb_s<MB_SIZE) MedianFilterBAB(rec_curr_alpha,x,y,alpha_dmb);
#endif
    
			for( i=0; i<MB_SIZE; i++ ) for( j=0; j<MB_SIZE; j++ )
 		     alpha_dmb[i*MB_SIZE+j] = f8bit(alpha_dmb[i*MB_SIZE+j]);

			FreeImage(alpha_smb_mc);
      FreeImage(bordered_smb); /* SAIT */
		}
	return ret;
}


/* VLC decoding for CR and ST */

Int Decode_CR_ST( Bitstream *stream, Int *mb_type, Int *mb_s, Int *st,
									Int fixed_cr, Trace *trace )
{
  Int  cr_ret,st_ret,i;

  cr_ret = 0;

	if (!fixed_cr)
		{
  		if ((i=BitstreamShowBits(stream,1)) == 0)
				{
    			*mb_s = MB_SIZE;
    			*mb_type = 2;
     			cr_ret++;
  			} 
			else if ((i=BitstreamShowBits(stream,2)) == 2) 
				{
    			*mb_s = MB_SIZE>>1;
    			*mb_type = 3;
    			cr_ret+=2;
  			} 
			else if ((i=BitstreamShowBits(stream,2)) == 3) 
				{
    			*mb_s = MB_SIZE>>2;
    			*mb_type = 4;
    			cr_ret+=2;
  			} 
			else 
				{
    			fprintf(stderr,"\nERROR: CR\n");
    			exit(1);
  			}
			BitstreamReadBits(stream,cr_ret,"CR",trace,CODE);
		}
	else 
		{
    	*mb_s = MB_SIZE;
    	*mb_type = 2;
		}

	st_ret = 0;
	if ((i=BitstreamShowBits(stream,1)) == 0) 
		{
      *st = 0;
      st_ret++;
    } 
	else if ((i=BitstreamShowBits(stream,1)) == 1) 
		{
      *st = 1;
      st_ret++;
    }

	BitstreamReadBits(stream,st_ret,"ST",trace,CODE);

  return cr_ret+st_ret;
}


/* CAE decoding of Intra binary alpha block */

Int CAE_DecodeIntra( Bitstream *bitstream, Image *image,
		     Int error_res_disable, Trace *trace, Int *error_flag)
{
	ArDecoder ar_decoder;

	Int		width = GetImageSizeX(image),
				height = GetImageSizeY(image);

	Int 	i,j,
				context,
				bit;

	USInt q;

	SInt 	*p_image = (SInt *) GetImageData(image);

	StartArDecoder(&ar_decoder, error_res_disable, bitstream, error_flag);
	for (i=2; i<height-2; i++)
		{
			for (j=2; j<width-2; j++) 
				{
					context = GetContextIntra(p_image,j,i,width-3,2,width);
					q = intra_prob[context];		
					bit = ArDecodeSymbol(q,&ar_decoder,bitstream,
							 trace, error_flag);
					p_image[i*width+j] = bit;				
				}
		}

	StopArDecoder(&ar_decoder,bitstream,trace, error_flag);
	return 0;
}

/* CAE decoding of Inter binary alpha block */

Int CAE_DecodeInter( Bitstream *bitstream, Image *image, Image *mc_image,
		     Int error_res_disable,Trace *trace, Int *error_flag)
{
	ArDecoder ar_decoder;

	Int		width = GetImageSizeX(image),
				height = GetImageSizeY(image);

	Int 	i,j,
				context,
				bit;

	USInt q;

	SInt 	*p_image = (SInt *) GetImageData(image),
				*p_mc_image = (SInt *) GetImageData(mc_image);

	StartArDecoder(&ar_decoder, error_res_disable, bitstream, error_flag);
	for (i=2; i<height-2; i++)
		{
			for (j=2; j<width-2; j++) 
				{
					context = GetContextInter(p_image,p_mc_image,j,i,width-3,2,width);
					q = inter_prob[context];		
					bit = ArDecodeSymbol(q,&ar_decoder,bitstream,
							 trace, error_flag);
					p_image[i*width+j] = bit;				
				}

		}

	StopArDecoder(&ar_decoder,bitstream,trace, error_flag);
	return 0;
}
