www.pudn.com > encore50src.zip > mom_util.c


 
/************************************************************************** 
 *                                                                        * 
 * This code is developed by Adam Li.  This software is an                * 
 * implementation of a part of one or more MPEG-4 Video tools as          * 
 * specified in 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 or copyrights, and any such use      * 
 * would be at such party's own risk.  The original developer of this     * 
 * software module and his/her company, and subsequent editors and their  * 
 * companies (including Project Mayo), will have no liability for use of  * 
 * this software or modifications or derivatives thereof.                 * 
 *                                                                        * 
 * Project Mayo gives users of the Codec a license to this software       * 
 * module or modifications thereof for use in hardware or software        * 
 * products claiming conformance to the MPEG-4 Video Standard as          * 
 * described in the Open DivX license.                                    * 
 *                                                                        * 
 * The complete Open DivX license can be found at                         * 
 * http://www.projectmayo.com/opendivx/license.php .                      * 
 *                                                                        * 
 **************************************************************************/ 
 
/************************************************************************** 
 * 
 *  mom_util.c 
 * 
 *  Copyright (C) 2001  Project Mayo 
 * 
 *  Adam Li 
 * 
 *  DivX Advance Research Center  
 * 
 **************************************************************************/ 
 
/* This file contains some utility functions to manipulate Image data     */ 
/* structures.                                                            */ 
/* Some codes of this project come from MoMuSys MPEG-4 implementation.    */ 
/* Please see seperate acknowledgement file for a list of contributors.   */ 
 
#include "mom_util.h" 
 
/* private prototypes */ 
Char *emalloc(Int n); 
Char *ecalloc(Int n, Int s); 
Char *erealloc(Char *p, Int n); 
Void CopyImageI(ImageI *image_in, ImageI *image_out); 
Void CopyImageF(ImageF *image_in, ImageF *image_out); 
Void SetConstantImageI(ImageI *image, SInt val); 
Void SetConstantImageF(ImageF *image, Float val); 
Void SubImageI(ImageI *image_in1, ImageI *image_in2, ImageI *image_out); 
Void SubImageF(ImageF *image_in1, ImageF *image_in2, ImageF *image_out); 
 
 
/* The following is the Image maintance functions. */ 
 
/***********************************************************CommentBegin****** 
 * 
 * -- AllocImage -- Allocates memory for an Image structure 
 * 
 * Purpose :		 
 *	Allocates memory for an Image structure, including memory 
 *	for the actual image pixels. The image pixels can be of type 
 *	UChar, SInt or Float depending on the parameter	type. 
 *  
 * Return values :	 
 *	A pointer to the allocated Image structure. 
 * 
 * Description :	 
 *	Allocates memory for the Image if possible, otherwise a  
 *	memory allocation error is signalled and the program will 
 *	exit. 
 * 
 ***********************************************************CommentEnd********/ 
 
Image * 
AllocImage(UInt size_x, UInt size_y, ImageType type) 
{ 
  Image *image; 
   
  image = (Image *) emalloc(sizeof(Image)); 
   
  image->version = VERSION; 
  image->x = size_x; 
  image->y = size_y; 
  image->upperodd = 0; 
  image->grid = 's'; 
  image->type = type; 
  image->data = (ImageData *) emalloc(sizeof(ImageData));  
   
  switch(type) 
    { 
    case SHORT_TYPE: 
      image->data->s = (SInt *) ecalloc(size_x*size_y,sizeof(SInt)); 
      break; 
 
    case FLOAT_TYPE: 
      image->data->f = (Float *) ecalloc(size_x*size_y,sizeof(Float)); 
      break; 
 
    case UCHAR_TYPE: 
      image->data->u = (UChar *) ecalloc(size_x*size_y,sizeof(UChar)); 
      break; 
    } 
   
  image->f = image->data->s;	/* For compatibility with KHOROS */ 
   
  return(image); 
} 
 
 
/***********************************************************CommentBegin****** 
 * 
 * -- FreeImage -- Frees up all the memory associated with an Image structure 
 * 
 * Purpose :		 
 *	Frees up all the memory associated with an Image structure 
 *  
 ***********************************************************CommentEnd********/ 
 
Void 
FreeImage(Image *image) 
{ 
  SInt	*ps; 
  Float	*pf; 
  UChar 	*pu; 
 
  if (image == NULL) return; 
 
  switch(image->type) 
    { 
    case SHORT_TYPE: 
      ps = (SInt *)GetImageData(image); 
      if(ps != NULL) free((Char *)ps); 
      free((Char *) image->data); 
      free((Char *)image); 
      break; 
 
    case FLOAT_TYPE: 
      pf = (Float *)GetImageData(image); 
      if(pf != NULL) free((Char *)pf); 
      free((Char *) image->data); 
      free((Char *)image); 
      break; 
 
    case UCHAR_TYPE: 
      pu = (UChar *)GetImageData(image); 
      if(pu != NULL) free((Char *)pu); 
      free((Char *) image->data); 
      free((Char *)image); 
      break; 
    } 
} 
 
 
/***********************************************************CommentBegin****** 
 * 
 * -- CopyImage -- Copies the pixel values of one image to another image 
 * 
 * Purpose :		 
 *	Copies the pixel values of one image to another image. 
 *  
 * Description :	 
 *	Currently, the function exits with an error if 
 *	the source and destination images are not of the same allocated 
 *	size and type. 
 * 
 *	Also, the images of type UChar are not yet supported. 
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
CopyImage(Image *image_in, Image *image_out) 
{ 
  switch(image_out->type) 
    { 
    case SHORT_TYPE: 
      CopyImageI(image_in,image_out); 
      break; 
 
    case FLOAT_TYPE: 
      CopyImageF(image_in,image_out); 
      break; 
 
    } 
} 
 
 
/***********************************************************CommentBegin****** 
 * 
 * -- CopyImageI --  
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
CopyImageI(ImageI *image_in, ImageI *image_out) 
{ 
  SInt 	*p_in  = image_in->data->s, 
		*p_out = image_out->data->s, 
		*p_end; 
 
  UInt	sx_in  = image_in->x, 
		sx_out = image_out->x, 
		sy_in  = image_in->y, 
		sy_out = image_out->y, 
		sxy_in = sx_in * sy_in; 
 
  p_end = p_in + sxy_in; 
 
  while (p_in != p_end)  
    { 
      *p_out = *p_in; 
      p_in++; 
      p_out++; 
    } 
 
} 
 
 
/***********************************************************CommentBegin****** 
 * 
 * -- CopyImageF -- Copies image_in to image_out 
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
CopyImageF(ImageF *image_in, ImageF *image_out) 
{ 
  Float *p_in  = image_in->data->f, 
		*p_out = image_out->data->f, 
		*p_end; 
 
  UInt  sx_in = image_in->x, 
		sx_out = image_out->x, 
		sy_in = image_in->y, 
		sy_out = image_out->y, 
		sxy_in = sx_in * sy_in; 
 
  p_end = p_in + sxy_in; 
 
  while (p_in != p_end)  
    { 
      *p_out = *p_in; 
      p_in++; 
      p_out++; 
    } 
 
} 
 
 
/***********************************************************CommentBegin****** 
 * 
 * -- SetConstantImage -- Sets each pixel in the Image to val 
 * 
 * Purpose :		 
 *	Sets each pixel in the Image to val. 
 *  
 * Side effects :	 
 *	Note val is a Float. If image is not a Float image then 
 *	val is cast to the appropriate type i.e. SInt, unsigned 
 *	Char. 
 * 
 * Description :	 
 *	Images of type UChar are not yet supported. 
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
SetConstantImage(Image *image, Float val) 
{ 
  switch(image->type) 
    { 
    case SHORT_TYPE: 
      SetConstantImageI(image,(SInt)val); 
      break; 
 
    case FLOAT_TYPE: 
      SetConstantImageF(image,val); 
      break; 
    } 
} 
 
 
 
/***********************************************************CommentBegin****** 
 * 
 * -- SetConstantImageI --  
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
SetConstantImageI(ImageI *image, SInt val) 
{ 
  SInt	*p  = image->data->s, 
        *p_end; 
 
  UInt	sxy = image->x * image->y; 
 
  if (val == 0) 
	  memset (p, 0, sxy * 2); 
  else 
  { 
	p_end = p + sxy; 
 
	while (p != p_end) 
	{ 
		*p = val; 
		p++; 
    } 
  } 
 
} 
 
/***********************************************************CommentBegin****** 
 * 
 * -- SetConstantImageF --  
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
SetConstantImageF(ImageF *image, Float val) 
{ 
  Float		*p  = image->data->f, 
            *p_end; 
 
  UInt	sxy = image->x * image->y; 
 
  p_end = p + sxy; 
 
  while (p != p_end) 
    { 
      *p = val; 
      p++; 
    } 
 
} 
 
 
/***********************************************************CommentBegin****** 
 * 
 * -- SubImage -- Subtracts two images 
 * 
 * Purpose :		 
 *	Subtracts two images and stores the result in the third 
 * 	i.e. image_out = image_in1 - image_in2 
 *  
 * Description :	 
 *	Currently, the function exits with an error if 
 *	the source and destination images are not of the same allocated 
 *	size and type. 
 * 
 *	Also, the images of type UChar are not yet supported. 
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
SubImage(Image *image_in1, Image *image_in2, Image *image_out) 
{ 
  switch(image_in1->type) 
    { 
    case SHORT_TYPE: 
      SubImageI(image_in1,image_in2,image_out); 
      break; 
 
    case FLOAT_TYPE: 
      SubImageF(image_in1,image_in2,image_out); 
      break; 
    } 
} 
 
/***********************************************************CommentBegin****** 
 * 
 * -- SubImageI --  
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
SubImageI(ImageI *image_in1, ImageI *image_in2, ImageI *image_out) 
{ 
  SInt	*p  = image_out->data->s, 
		*p1 = image_in1->data->s, 
		*p2 = image_in2->data->s, 
		*p_end; 
 
  UInt	sx_in1 = image_in1->x, 
		sx_in2 = image_in2->x, 
		sx_out = image_out->x, 
		sy_in1 = image_in1->y, 
		sy_in2 = image_in2->y, 
		sy_out = image_out->y, 
		sxy    = sx_out * sy_out; 
 
  p_end = p + sxy; 
 
  while (p != p_end) 
    { 
      *p = *p1 - *p2; 
      p++; 
      p1++; 
      p2++; 
    } 
 
} 
 
/***********************************************************CommentBegin****** 
 * 
 * -- SubImageF --  
 * 
 ***********************************************************CommentEnd********/ 
 
Void 
SubImageF(ImageF *image_in1, ImageF *image_in2, ImageF *image_out) 
{ 
  Float	*p  = image_out->data->f, 
		*p1 = image_in1->data->f, 
		*p2 = image_in2->data->f, 
		*p_end; 
 
  UInt	sx_in1 = image_in1->x, 
		sx_in2 = image_in2->x, 
		sx_out = image_out->x,							 
		sy_in1 = image_in1->y, 
		sy_in2 = image_in2->y, 
		sy_out = image_out->y, 
		sxy    = sx_out * sy_out; 
 
  p_end = p + sxy; 
 
  while (p != p_end) 
    { 
      *p = *p1 - *p2; 
      p++; 
      p1++; 
      p2++; 
    } 
 
} 
 
/* The following is Vop maintance functions. */ 
 
Vop * 
SallocVop() 
{ 
	Vop   *vop; 
 
	vop = (Vop *)ecalloc(1,sizeof(Vop)); 
 
	return(vop); 
} 
 
 
Vop * 
AllocVop(UInt x, UInt y) 
{ 
  Vop		*vop; 
 
  Image	*y_chan, 
		*u_chan, 
		*v_chan;  
 
  /* first allocate memory for the data structure */ 
  vop = SallocVop(); 
 
  vop->width = x; 
  vop->height = y; 
 
  /* Allocate image fields */ 
  y_chan = AllocImage(x,y,SHORT_TYPE); 
  u_chan = AllocImage(x/2,y/2,SHORT_TYPE); 
  v_chan = AllocImage(x/2,y/2,SHORT_TYPE); 
 
  /* Include image fields in structure */ 
  FreeImage(vop->y_chan); 
  vop->y_chan = y_chan; 
 
  FreeImage(vop->u_chan); 
  vop->u_chan = u_chan; 
 
  FreeImage(vop->v_chan); 
  vop->v_chan = v_chan; 
 
  return(vop); 
} 
 
 
Void 
SfreeVop (Vop *vop) 
{ 
	free ((Char*)vop); 
	/* vop = NULL; */ 
	return; 
} 
 
 
Void 
FreeVop(Vop *vop) 
{ 
  Image		*data=NULL; /*SpSc: added the initialization */ 
 
  if(vop != NULL) { 
 
    /* Deallocate memory for image fields */ 
 
    data = vop->y_chan; 
    FreeImage(data); 
 
    data = vop->u_chan; 
    FreeImage(data); 
 
    data = vop->v_chan; 
    FreeImage(data); 
 
    SfreeVop(vop); 
  } 
 
  return; 
} 
 
 
Void 
CopyVopNonImageField(Vop *in,Vop *out) 
{ 
/*	out->quant_precision = in->quant_precision; 
	out->bits_per_pixel = in->bits_per_pixel; 
*/ 
//	out->mod_time_base = in->mod_time_base; 
//	out->time_inc = in->time_inc; 
	out->prediction_type = in->prediction_type; 
/*	out->rounding_type = in->rounding_type; 
	out->width = in->width; 
	out->height = in->height; 
	out->hor_spat_ref = in->hor_spat_ref; 
	out->ver_spat_ref = in->ver_spat_ref; 
	out->quantizer = in->quantizer; 
	out->intra_quantizer = in->intra_quantizer; 
	out->time_increment_resolution = in->time_increment_resolution; 
 
	out->intra_acdc_pred_disable = in->intra_acdc_pred_disable; 
	out->fcode_for = in->fcode_for; 
	out->sr_for = in->sr_for; 
 
	out->intra_dc_vlc_thr = in->intra_dc_vlc_thr; 
*/ 
} 
 
 
/* The following is Memory allocation functions. */ 
 
/***********************************************************CommentBegin****** 
 * 
 * -- emalloc -- Memory allocation with error handling 
 * 
 * Purpose :		 
 *	Memory allocation with error handling. 
 *  
 * Description :	 
 *	WARNING: There is a problem when you want to allocate more memory 
 *	than size can handle.  Malloc gets as argument an unsigned.  It poses 
 *	a problem when sizeof(unsigned) < sizeof(Char *)... 
 * 
 ***********************************************************CommentEnd********/ 
 
Char * 
emalloc(Int n) 
{ 
  Char 	*p; 
	 
  p = (Char *) malloc((UInt)n); 
  return p; 
} 
 
/***********************************************************CommentBegin****** 
 * 
 * -- ecalloc -- Memory allocation with error handling 
 * 
 * Purpose :		 
 *	Memory allocation with error handling. 
 *  
 * Description :	 
 *	WARNING: There is a problem when you want to allocate more memory 
 *	than size can handle.  Malloc gets as argument an unsigned.  It poses 
 *	a problem when sizeof(unsigned) < sizeof(Char *)... 
 * 
 ***********************************************************CommentEnd********/ 
 
Char * 
ecalloc(Int n, Int s) 
{ 
  Char 	*p; 
	 
  p = (Char *) calloc((UInt)n,(UInt)s); 
	 
  return p; 
} 
 
/***********************************************************CommentBegin****** 
 * 
 * -- erealloc -- Memory re-allocation with error handling. 
 * 
 * Purpose :		 
 *	Memory re-allocation with error handling 
 *  
 * Description :	 
 *	WARNING: There is a problem when you want to allocate more memory 
 *	than size can handle.  Malloc gets as argument an unsigned.  It poses 
 *	a problem when sizeof(unsigned) < sizeof(Char *)... 
 * 
 ***********************************************************CommentEnd********/ 
 
Char * 
erealloc(Char *p, Int n) 
{	 
  p = (Char *) realloc(p,(UInt)n); 
  return p; 
}