/****************************************************************************/
/*   MPEG4 Visual Texture Coding (VTC) Mode Software                        */
/*                                                                          */
/*   This software was jointly developed by                                 */
/*   Sarnoff Coporation                   and    Texas Instruments          */
/*   Iraj Sodagar   (iraj@sarnoff.com)           Jie Liang (liang@ti.com)   */
/*   Hung-Ju Lee    (hjlee@sarnoff.com)                                     */
/*   Paul Hatrack   (hatrack@sarnoff.com)                                   */
/*   Shipeng Li     (shipeng@sarnoff.com)                                   */
/*   Bing-Bing Chai (bchai@sarnoff.com)                                     */
/*                                                                          */
/*   and                                                                    */
/*                                                                          */
/*   Oki Electric Industry Co., Ltd.                                        */
/*   Zhixiong Wu    (sgo@hlabs.oki.co.jp)                                   */
/*   Yoshihiro Ueda (yueda@hlabs.oki.co.jp)                                 */
/*   Toshifumi Kanamaru (kanamaru@hlabs.oki.co.jp)                          */
/*                                                                          */
/* In the course of development of the MPEG-4 standard. This software       */
/* module is an implementation of a part of one or more MPEG-4 tools as     */
/* specified by the MPEG-4 standard.                                        */
/*                                                                          */
/* The copyright of this software belongs to ISO/IEC. ISO/IEC gives use     */
/* of the MPEG-4 standard free license to use this  software module or      */
/* modifications thereof for hardware or software products claiming         */
/* conformance to the MPEG-4 standard.                                      */
/*                                                                          */
/* Those intending to use this software module in hardware or software      */
/* products are advised that use may infringe existing  patents. The        */
/* original developers of this software module and their companies, the     */
/* subsequent editors and their companies, and ISO/IEC have no liability    */
/* and ISO/IEC have no liability for use of this software module or         */
/* modification thereof in an implementation.                               */
/*                                                                          */
/* Permission is granted to MPEG memebers to use, copy, modify,             */
/* and distribute the software modules ( or portions thereof )              */
/* for standardization activity within ISO/IEC JTC1/SC29/WG11.              */
/*                                                                          */
/* Copyright (C) 1998  Sarnoff Coporation  and Texas Instruments            */ 
/****************************************************************************/

/****************************************************************************/
/*     Texas Instruments Predictive Embedded Zerotree (PEZW) Image Codec    */
/*     Copyright 1996, 1997, 1998 Texas Instruments	      		    */
/****************************************************************************/

#include <stdlib.h>

#include "wvtPEZW.h"
#include "PEZW_zerotree.h"

Ac_model dom_pass, dom_pass2, sub_pass, end_pass;








/* model for subordinate pass */
static Int freq_sub[No_of_symbols] = {1, 1, 0, 0, 0};

/* model for sending the EOF symbol */
static Int freq_end[No_of_symbols] = {0, 0, 0, 4, 1};


/* context models */

static Int freq_dom_IZER[No_of_symbols] =   {1, 1, 0, 0, 0};     
static Int freq_dom_ZTRZ[No_of_symbols] =   {1, 1, 1, 1, 0};     


/* model specific for last level of dominant pass encoding */
/* no zerotree possible */
static Int freq_dom2_IZER[No_of_symbols] =  {1, 1, 0, 0, 0};


Void WvtDecodePEZW_Spatial_SNR (WINT *output, Int hsize, Int vsize,
    PEZW_SPATIAL_LAYER *SPlayer, Int levels, Int Resolution, Int bitplaneOff,
/*
    Int target_bitrate,    
*/ 
	Int SNR_Len_Enable)
{
  UChar *labelimage;
  UChar *mask;
  Int *valueimage;
  Int i,j,k,l,m,n, band;
  Int currentthresh;
  Int currenthsize, currentvsize, xcorner, ycorner;
  Int countIZER=0;
  Int countIVAL=0;
  Int countZTRZ=0;
  Int countZTRV=0;
  Int cIZ[No_of_contexts];
  Int cIS[No_of_contexts];
  Int cZTRZ[No_of_contexts];
  Int cZTRS[No_of_contexts];
  Int count=0;
  Int currlevel;

  Int blocksize;
  Int outputsize;
  Int ch, symbol=0, symbol1;

  Int nbplane;
  Int bplane;
  Int *sizes, *SNRsizes;
  UChar *buff;
  UChar **streambuffer;
  Int threshold, *budget;



  Ac_decoder *AC_decoder;
  Int IsStream = 1;
  Ac_model model, model_sign;
  Int nsym=No_of_symbols, adapt=1;
  Int Noadapt;

  UChar *prev_labelimage;
  Ac_model *modelptr;
  Ac_model model_context[No_of_contexts];
  Ac_model model_sub, model_end;
  Int context, context1, context2, context3;
  Int *freq=NULL;
  Char firstplane=1;

#ifdef DEBUG_ARITHM
  File *fp;
  fp = fopen ("test.debug", "a");
#endif

  Noadapt=0;

  mask  = SPlayer->SNRlayer[0].snr_image.mask;

  /* the number of bitplane to be decoded */
  nbplane =  (bitplaneOff<SPlayer->SNR_scalability_levels)?bitplaneOff:
                SPlayer->SNR_scalability_levels;

  streambuffer = (UChar **) calloc (levels, sizeof(Char *));
  budget = (Int *) calloc (levels, sizeof (Int));
  threshold = SPlayer->SNRlayer->Quant;

  if(DEBUG_DEC_BS)
    fprintf(stdout,"\nQuant: %d\n",threshold);

  /* currbuff store the current pointer in buffer */
  sizes = (Int *) calloc (levels, sizeof(Int));
  SNRsizes = (Int *) calloc (levels, sizeof(Int));

  outputsize = 0;
  /* Initialize working images and output stream*/
  if ((labelimage = (UChar *) calloc(hsize*vsize, sizeof(UChar)))==NULL)
    {fprintf(stderr,"ERROR Unable to allocate labelimage in decode\n");
     exit(1);}
  if ((valueimage = (Int *) calloc(hsize*vsize, sizeof(Int)))==NULL)
    {fprintf(stderr,"ERROR Unable to allocate valueimage in decode\n");
     exit(1);}

  /* initialized the context image */
  if ((prev_labelimage = (UChar *) calloc(hsize*vsize, sizeof(Char)))==NULL)
    {fprintf(stderr,"ERROR Unable to allocate labelimage in decode\n");
     exit(1);}
  for (i=0; i<hsize*vsize; i++){
      prev_labelimage[i]=DZ;
/*
      labelimage[i]=Z;
*/
	  labelimage[i] = (mask[i]) ? Z : SKIP ;
  }

  /* set up buffer for coding */
  /* initialization */
  AC_decoder = (Ac_decoder *) calloc (levels, sizeof(Ac_decoder));

  Ac_model_init (&model_sign, nsym, freq_sub, Max_frequency_TI, Noadapt);
  Ac_model_init (&model_sub, nsym,  freq_sub, Max_frequency_TI, adapt);
  Ac_model_init (&model_end, nsym,  freq_end, Max_frequency_TI, adapt);
  Ac_model_init (&model, nsym,  freq_end, Max_frequency_TI, adapt);
  
  /* initialize the arithmetic codec */
  for (j=levels;j>=1;j--)                   /* subband */
      for (i=0;i<No_of_states_context1;i++)         /* parent node */
	  for (l=0;l<No_of_states_context0;l++){    /* previous label */
	      context = (j-1)*No_of_states_context0*No_of_states_context1+i*No_of_states_context0+l;
	      if (j==1){
		      freq = freq_dom2_IZER;
		      adapt= 1;                 
	      }
	      else{
		  if (l==IZER){
		      freq = freq_dom_IZER;
		      adapt= 1;                 
		  }
		  else if (l==ZTRZ){
		      freq = freq_dom_ZTRZ;     
		      adapt= 1;
		  }
		  else if (l==DS){              
		      freq = freq_dom_ZTRZ;
		      adapt= 1;
		  }
		  else if (l==DZ){              
		      freq = freq_dom_ZTRZ;
		      adapt= 1;
		  }
	      }
		  
	      Ac_model_init (&model_context[context], nsym, freq, Max_frequency_TI, adapt);
	  }
  
  for (i=0;i<No_of_contexts;i++){
      cIZ[i]=0; cIS[i]=0; cZTRZ[i]=0; cZTRS[i]=0;
  }

  currentthresh = threshold;

  /* loop: */
  /* mark all non-SIG coeffs exceeding thresh with T */
  /* in scanning order, encode string of specifications */
  /* output extra bits for all significants */
  /* decrease threshold and repeat */

currlevel = 1+Resolution;
for (bplane=0;bplane<nbplane;bplane++)
    {
#ifdef DEBUG_ARITHM
      fprintf(fp, "\n ***** ANOTHER PASS *****: \n");
#endif
      
      if(SPlayer[levels-1].SNRlayer[bplane].allzero){
	currentthresh /= 2;
	continue;
      }
      
      if(firstplane){
	/* initialization */
	firstplane=0;
	if (SNR_Len_Enable || (bplane == 0)){
	  for (i=0; i<levels; i++){
	    streambuffer[i] = (SPlayer[levels-i-1].SNRlayer)[bplane].snr_bitstream.data;
	    budget[i]       = ((SPlayer[levels-i-1].SNRlayer)[bplane].snr_bitstream.length)+Code_value_bits;
	    
	    budget[i]=1000000;
	    
	    Ac_decoder_open (&AC_decoder[i], streambuffer[i], IsStream);
	    Ac_decoder_init (&AC_decoder[i], streambuffer[i]);
	  }
	}
      }
      
      /* determine where significant values are */
      
      /* next go from lower high subbands to higher subbands */
      for (l=levels; l>=currlevel; l--)
	{
	  currenthsize = hsize/(1<<l);
	  currentvsize = vsize/(1<<l);
	  
	  
	  /* take down point positions before decoding higher bands
	     thank wanted */
	  
	  for (band=0; band<3; band++)
	    {
	      if (band==0)	  /* horiz */
		{  xcorner = currenthsize;       ycorner = 0;}
	      else if (band==1)	/* vert */
		{  xcorner = 0; ycorner = currentvsize;	}
	      else		/* diag */
		{ xcorner = currenthsize; ycorner = currentvsize;}
	      
	      for (i=ycorner; i<ycorner+currentvsize; i++)
		for (j=xcorner; j<xcorner+currenthsize; j++)
		  {
		    if ((labelimage[i*hsize+j] == S)  ||
			(labelimage[i*hsize+j] == DS)  ||
			(labelimage[i*hsize+j] == DZ)  ||
			(labelimage[i*hsize+j] == SKIP)  )
		      /* don't need to do anything */;
		    else 
		      {
			  /* decide about the context */
			  context1 = prev_labelimage[i*hsize+j];	
			  context3 = l-1;
			  context2=0;
			  context =  context3*No_of_states_context0*No_of_states_context1+
			      context2*No_of_states_context0+context1;
			  modelptr = &model_context[context];
			  
			  symbol = Ac_decode_symbol(&AC_decoder[l-1], modelptr);

			  if (symbol == IVAL){
			      symbol1 = Ac_decode_symbol(&AC_decoder[l-1], &model_sign);
			      symbol = (symbol1 == 1)?POS:NEG;
			  }
			  else if (symbol == ZTRV){
			      symbol1 = Ac_decode_symbol(&AC_decoder[l-1], &model_sign);
			      symbol = (symbol1 == 1)?ZTRPOS:ZTRNEG;
			  }
			  else if (symbol == ZTRZ)
			      symbol =ZTRZ; 
			  else
			      symbol = IZER;
			  
			  /* check for bit budget[l-1] need to add 1, because 
			   the current Char *((UChar*) get_buffer()) is also 
			   being used */
			  
			  buff = AC_decoder[l-1].stream;
			  if ( (buff - streambuffer[l-1]) > budget[l-1]){
			    if (DEBUG_ZTR_DEC)
			      printf("\n Reach budget: %d bits \n", (buff-streambuffer[l-1])*8);
			      goto cleanup;
			  }

			labelimage[i*hsize+j] = symbol ;
			
			outputsize++;
	      
			if (labelimage[i*hsize+j] == POS)
			  {
			      countIVAL++; cIS[context]++;
			      labelimage[i*hsize+j] = S; 
			      prev_labelimage[i*hsize+j]=IVAL;
			      
			      if ((context1 != IZER)&&(context1 != ZTRZ)&&(context1 != DS)&&(context1 != DZ))
				  {
				      printf("error, label = %d context1= %d\n", symbol, context1);
				      exit(-1);
				  }
			      
			      valueimage[i*hsize+j] += currentthresh;
			      valueimage[i*hsize+j] += currentthresh/2;}
			else if(labelimage[i*hsize+j] == NEG)
			    {
				countIVAL++; cIS[context]++;
				labelimage[i*hsize+j] = S; 
				prev_labelimage[i*hsize+j]=IVAL;
				
				valueimage[i*hsize+j] -= currentthresh;
				valueimage[i*hsize+j] -= currentthresh/2;}
			else if (labelimage[i*hsize+j] == ZTRPOS)
			    {
				countZTRV++; cZTRS[context]++;
				labelimage[i*hsize+j] = S;  
				prev_labelimage[i*hsize+j]=ZTRV;
				
				valueimage[i*hsize+j] += currentthresh;
				valueimage[i*hsize+j] += currentthresh/2;
				
				blocksize = 1;
				for (m=l-1; m>=1; m--)
				    {
					blocksize += blocksize;	/* mult x 2 */
					for (k=0;k<blocksize;k++)
					    for (n=0; n<blocksize;n++)
						if ((labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n] != S) &&
							(labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n] != SKIP)) {	
						    labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n]= DS;
						    /* copy the current image to prev_labelimage[] */
						    prev_labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n]= DS;
						}
				    }	/* end for m */
			    }
			else if(labelimage[i*hsize+j] == ZTRNEG)
			    {
				countZTRV++; cZTRS[context]++;
				labelimage[i*hsize+j]=S;
				prev_labelimage[i*hsize+j]=ZTRV;
				
				valueimage[i*hsize+j] -= currentthresh;
				valueimage[i*hsize+j] -= currentthresh/2;
				
				blocksize = 1;
				for (m=l-1; m>=1; m--)
				    {
					blocksize += blocksize;	/* mult x 2 */
					for (k=0;k<blocksize;k++)
					    for (n=0; n<blocksize;n++)
						if ((labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n] != S) &&
							(labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n] != SKIP)) {	
						    labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n]= DS;
						    /* copy the current image to prev_labelimage[] */
						    prev_labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n]= DS;
						}
				    }	/* end for m */
			    }
			else if (labelimage[i*hsize+j] == ZTRZ)
			    {
				countZTRZ++; cZTRZ[context]++;
				labelimage[i*hsize+j]=ZTRZ;
				prev_labelimage[i*hsize+j]=ZTRZ;

				blocksize = 1;
				for (m=l-1; m>=1; m--)
				    {
					blocksize += blocksize;	/* mult x 2 */
					for (k=0;k<blocksize;k++)
					    for (n=0; n<blocksize;n++)
						if ((labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n] != S) &&
							(labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n] != SKIP)) {	
						    labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n]= DZ;
						    /* copy the current image to prev_labelimage[] */
						    prev_labelimage[((i*blocksize)+k)*hsize+(j*blocksize)+n]= DZ;
						}
				    }	/* end for m */
			    } /* end else ZTR*/
			else if (labelimage[i*hsize+j] == IZER){
			    ch = IZER; symbol = ch;
			    countIZER++; cIZ[context]++;
			    labelimage[i*hsize+j] =    Z; /* reinit for next loop */
			    prev_labelimage[i*hsize+j]=IZER;

			    if ((context1 != IZER)&&(context1 != ZTRZ)&&(context1 != DS)&&(context1 != DZ))
				{
				    printf("error, label = %d context1= %d\n", symbol, context1);
				    exit(-1);
				}
			}
			else {
			    printf("should not be here \n");
			    exit(-1);
			}

		      }	/* end else */
		  }	/* end for */
	    } /* end band */
	  AC_free_model(&model_sign);
	  Ac_model_init (&model_sign, nsym, freq_sub, Max_frequency_TI, Noadapt);

	} /* end for l */

      if(DEBUG_ZTR_CONTEXTS_DEC){
	printf("\n stats for this pass:");
	for (i=0;i<levels;i++)
	  for (l=0;l<No_of_states_context1;l++){
	    for (j=0; j<No_of_states_context0; j++){
	      context=i*No_of_states_context0*No_of_states_context1+l*No_of_states_context0+j;
	      printf("\n context %d: IZER %d IVAL %d ZTRZ %d ZTRV %d", context, cIZ[context], 
		     cIS[context], cZTRZ[context], cZTRS[context]);
	    }
	    printf("\n");
	  }
      }
      
      if (DEBUG_ZTR_DEC)
	printf("overrall ZEROTREE STAT: IZER %d IVAL %d ZTRZ %d ZTRV %d \n", countIZER, countIVAL,
	       countZTRZ, countZTRV);

      currentthresh /= 2;
      for (j=levels;j>=currlevel; j--){

	/* set up the arithmetic coder */
	AC_free_model(&model);
	Ac_model_init (&model, nsym, freq_end, Max_frequency_TI, adapt);
	symbol = Ac_decode_symbol(&AC_decoder[j-1], &model);
      }
      
      if (symbol == EOF_symbol){
	if(DEBUG_ZTR_DEC)
	  printf("\n----EOF_SYMBOL------ \n");
	
	for (i=Resolution;i<levels;i++){
	  AC_decoder_buffer_adjust(&AC_decoder[levels-1-i]);
	  SNRsizes[i]=AC_decoder[levels-1-i].stream-streambuffer[levels-1-i];
	      /* adjust the length for parsing other color components */
	  if(SNR_Len_Enable)
	    SPlayer[i].SNRlayer[bplane].snr_bitstream.length = SNRsizes[i];
	  else  /* only one snr level */
	    SPlayer[i].SNRlayer[0].snr_bitstream.length = SNRsizes[i];
	  
	  if (DEBUG_ZTR_DEC_BS)
	    printf("Read in %d bytes (splev %d snrlev %d) \n", SNRsizes[i], i, bplane);
	}
	
	goto cleanup;
      }
      
      if(SNR_Len_Enable){
	for (i=Resolution;i<levels;i++){
	  AC_decoder_buffer_adjust(&AC_decoder[levels-1-i]);
	  SNRsizes[i]=AC_decoder[levels-1-i].stream-streambuffer[levels-1-i];
	  if (DEBUG_ZTR_DEC_BS)
	    printf("Read in %d bytes (splev %d snrlev %d) \n", SNRsizes[i], i, bplane);
	  
	  /* adjust the length for parsing other color components */
	  SPlayer[i].SNRlayer[bplane].snr_bitstream.length = SNRsizes[i];
	}
      }
      
      if (SNR_Len_Enable){
	for (i=0; i<levels; i++){
	  streambuffer[i] = (SPlayer[levels-i-1].SNRlayer)[bplane+1].snr_bitstream.data;
	  budget[i]       = ((SPlayer[levels-i-1].SNRlayer)[bplane+1].snr_bitstream.length)+Code_value_bits;
	  
	  budget[i]=1000000;
	  
	  Ac_decoder_open (&AC_decoder[i], streambuffer[i], IsStream);
	  Ac_decoder_init (&AC_decoder[i], streambuffer[i]);
	}
      }
      
      /* initialize the arithmetic codec */
      for (j=levels;j>=1;j--)                   /* subband */
	  for (i=0;i<No_of_states_context1;i++)         /* parent node */
	    for (l=0;l<No_of_states_context0;l++){    /* previous label */
	      context = (j-1)*No_of_states_context0*No_of_states_context1+i*No_of_states_context0+l;
	      if (j==1){
		freq = freq_dom2_IZER;
		adapt= 1;                   
	      }
	      else{
		if (l==IZER){
		  freq = freq_dom_IZER;
		      adapt= 1;                   
		}
		  else if (l==ZTRZ){
		    freq = freq_dom_ZTRZ;       
		    adapt= 1;
		  }
		else if (l==DS){                
		  freq = freq_dom_ZTRZ;
		  adapt= 1;
		}
		else if (l==DZ){                
		  freq = freq_dom_ZTRZ;
		  adapt= 1;
		}
	      }
	      
	      AC_free_model (&model_context[context]);	
	      Ac_model_init (&model_context[context], nsym, freq, Max_frequency_TI, adapt);
	    }
      
      
      
#ifdef AC_DEBUG
      printf("\nsubordinate pass\n");
#endif
      
      /* SUBORDINATE PASS */
      /* Now send bits for all significant numbers in scanning order*/
      /* unless currentthresh is < 1*/
      if (currentthresh >= 1)
	{
	  /* reset model since subordinate pass has different statistics */
	  AC_free_model(&model);
	  Ac_model_init (&model, nsym, freq_sub, Max_frequency_TI, adapt);

	  /* next go from lower high subbands to higher subbands */
	  for (l=levels; l>=currlevel; l--)
	    {
	      currenthsize = hsize/(1<<l);
	      currentvsize = vsize/(1<<l);
	      
	      for (band=0; band<3; band++)
		{
		  if (band==0)	  /* horiz */
		    {  xcorner = currenthsize;       ycorner = 0;}
		  else if (band==1)	/* vert */
		    {  xcorner = 0; ycorner = currentvsize;	}
		  else		/* diag */
		    { xcorner = currenthsize; ycorner = currentvsize;}
		  
		  for (i=ycorner; i<ycorner+currentvsize; i++)
		    for (j=xcorner; j<xcorner+currenthsize; j++)
		      if (valueimage[i*hsize+j] > 0)
			{
			    symbol = Ac_decode_symbol(&AC_decoder[l-1], &model);

			    if (symbol == EOF_symbol)
			      {
				goto cleanup;
			      }

			    /* check for bit budget[l-1] */
			    buff = AC_decoder[l-1].stream;
			    if (buff - streambuffer[l-1] > budget[l-1]){
			      if (DEBUG_ZTR_DEC)
				printf("\n Reach budget: %d bits \n", (buff-streambuffer[l-1])*8);
				goto cleanup;
			    }

			    ch = symbol;
			    outputsize++;
			    
			    if (ch)
				valueimage[i*hsize+j] += currentthresh/2;
			    else
				valueimage[i*hsize+j] -= currentthresh/2;
			}
		      else if (valueimage[i*hsize+j] < 0)
			{
			  symbol = Ac_decode_symbol(&AC_decoder[l-1], &model);

			  if (symbol == EOF_symbol)
			      {
				goto cleanup;
			      }

			  /* check for bit budget[l-1] */
			  buff = AC_decoder[l-1].stream;
			  if (buff - streambuffer[l-1] > budget[l-1]){
			    if (DEBUG_ZTR_DEC)
			      printf("\n Reach budget: %d bits \n", (buff-streambuffer[l-1])*8);
			      goto cleanup;
			  }

			  ch = symbol;
			  outputsize++;
			  
			  if (ch)
			    valueimage[i*hsize+j] -= currentthresh/2;
			  else
			    valueimage[i*hsize+j] += currentthresh/2;
			}
		} /* end for band */
	    } /* end for l */

	  for (i=0; i<hsize*vsize;i++)
	      if ( labelimage[i] != S && mask[i] )	
		  labelimage[i] = Z;


	} /* end if currentthresh */

    } /* threshold loop */

cleanup:

for (l=levels; l>=1+Resolution; l--){
  sizes[l-1] = (AC_decoder[l-1].stream-streambuffer[l-1])*8-Code_value_bits;
  count += sizes[l-1];
}
 
 if (DEBUG_ZTR_DEC){ 
   printf("\nRead in totally %d bits", count);
   for (i=levels; i>=1+Resolution;i--)
     printf("\nRead in %d bits (splev %d): ", sizes[i-1], i);
 }
 
#ifdef DEBUG_ARITHM
  fprintf(fp, "\n \n -------------------------------------\n");
  fclose(fp);
#endif
  
  /* change values to output values */
  for(i = 0; i < vsize; i++){
    for(j = 0; j < hsize; j++)
      if ((i>=(vsize/(1<<levels))) || (j>=(hsize/(1<<levels))))
	{
	  if (valueimage[i*hsize+j] != 0)
	    output[i*hsize+j] = valueimage[i*hsize+j];
	  else
	    output[i*hsize+j] = 0;
	}
  }

  
  if (DEBUG_ZTR_DETAILS_DEC){
    fprintf(stderr, "\n After zerotree decoding:\n");
    for(i = 0; i < vsize; i++){
      for(j = 0; j < hsize; j++)
	fprintf(stderr, "%3d ", output[i*hsize+j]);
      fprintf(stderr, "\n");
      }
  }
  
  
  /* NEED TO FREE CALLOC SPACE */
  free(labelimage);
  free(prev_labelimage);
  free(valueimage);
  free(streambuffer);
  free(AC_decoder);
  free(budget);
  
  AC_free_model(&model);
  AC_free_model(&model_sign);
  AC_free_model(&model_sub);
  AC_free_model(&model_end);
  for (j=levels;j>=1;j--)                   /* subband */
    for (i=0;i<No_of_states_context1;i++)         /* parent node */
      for (l=0;l<No_of_states_context0;l++){    /* previous label */
	context = (j-1)*No_of_states_context0*No_of_states_context1+i*No_of_states_context0+l;
	
	AC_free_model (&model_context[context]);
      }
  
  free(sizes);
  free(SNRsizes);
  
  return;
  
}






