⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ezw.cpp

📁 单独的ezw编解码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//#include "stdafx.h"
#include "ezw.h"
#include <string.h>

#undef calloc
#undef realloc
#undef malloc
#undef free

#include <malloc.h>
#include <stdio.h>
/*--------------------------------------------------------------------------------------------*/
#define _REFINEMENT_SAME_PASS_      0
#define _MERGE_NODE_CONTEXT_        1
#define _MERGE_REFI_CONTEXT_        1
#define _RESET_MODELS_              1

/*--------------------------------------------------------------------------------------------*/
//#define DEFAULT_MEAN 128

/*--------------------------------------------------------------------------------------------*/
#define SSIG_MAX	256
#define REFI_MAX	256

#define nSSigModel   4
#define nRefiModel   1

/*--------------------------------------------------------------------------------------------*/


/*--------------------------------------------------------------------------------------------*/
/* Code alphabet */
#define _PS_ 0x0
#define _NG_ 0x1
#define _ZS_ 0x2
#define _IZ_ 0x3

/*--------------------------------------------------------------------------------------------*/
/* Hilbert scan paths */
#define RS  0
#define LS  1
#define US  2
#define DS  3

#define MoveUp(px, py)     ((*py)--)
#define MoveDown(px, py)   ((*py)++)
#define MoveLeft(px, py)   ((*px)--)
#define MoveRight(px, py)  ((*px)++)

/*--------------------------------------------------------------------------------------------*/
#define CHKBIT(x, y) (((x) & (y))? 1 : 0)
#define SETBIT(x, y) ((x) | (y))
#define CLRBIT(x, y) ((x) & (~(y)))

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void EZWChildrenPareCtxBitUpdate(Coder *coder, int n, int x, int y);
void EZWSSigContextUpdate(Coder *coder, int i, int x, int y, int n);
void EZWCSigContextUpdate(Coder *coder, int i, int x, int y, int n);
int  EZWCSigContext(Coder *coder, int i, int n, int LastScanSig);
/*--------------------------------------------------------------------------------------------*/

int EZWEncode(Coder *coder,int *ezwcomp)
{
	coder->Mode = ENCODE;
	coder->CodedSymbols = 0;	


	/* compute target bits, assume data is 8 bits per sample */
	coder->TargetBits = (int)(coder->TargetBitRate*coder->FXSize*coder->FYSize);
	coder->TargetBits = ((coder->TargetBits+7)>>3)<<3;
	
	
	/* coding structures */
	//allocate coder->subband size ,magnitude, maxmagnitude, and state
	EZWBuildCodingArrays(coder,ezwcomp);
	//compute coder->magnitude, maxmagnitude, max/current bitplane, and max/current threshold
	EZWComputeMaxMagnitudeTree(coder);	
	
	
	sprintf(coder->EncodeImageFileName, "%s.%s", "Encoded", "txt");
	if((coder->file = fopen(coder->EncodeImageFileName,"w")) == NULL)
		printf("The file can not open!");

	
	EZWMainCodingPass(coder);
	
	fclose(coder->file);
	
	//与BuildCodingArrays对应,free
	EZWDestroyCodingArrays(coder);

   return 0;
}
/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
int EZWDecode(Coder *coder)
{
	struct stat statistics; 
	int EncodedImageFileSize;
	
	coder->Mode = DECODE;
	coder->CodedSymbols = 0;

	/* get the encoded stream size - for maximum decode bits count */
 	if(stat(coder->EncodeImageFileName, &statistics) == -1){
		EncodedImageFileSize = 0;
	}
	else{
		EncodedImageFileSize = (int)statistics.st_size;
	}
	EncodedImageFileSize <<= 3;
	/* temporary for reading header */
	coder->TargetBits = EncodedImageFileSize;

	
	coder->TargetBits = (int)(coder->TargetBitRate*coder->FXSize*coder->FYSize);
	coder->TargetBits = ((coder->TargetBits+7)>>3)<<3;
	
	if (coder->TargetBits == 0 || coder->TargetBits > EncodedImageFileSize){
		coder->TargetBits = EncodedImageFileSize;
		coder->TargetBitRate = (double)coder->TargetBits/(coder->FXSize*coder->FYSize);
	}
		
	
	fprintf(stdout, "Decoding : %s (%d x %d)\n", coder->EncodeImageFileName, 
		coder->ImageXSize, coder->ImageYSize);

	/* Coding structures */
	EZWDeBuildCodingArrays(coder);
	if((coder->file=fopen(coder->EncodeImageFileName,"r")) == NULL)
		printf( "The file was not opened\n" );

	EZWMainCodingPass(coder);
	
	fclose(coder->file);

	EZWDestroyCodingArrays(coder);
	
	return 0;
}
/*----------------------------------------------------------------------------*/
void EZWMainCodingPass(Coder *coder)
{	
   int i, n;

   coder->nPS = 0;
   coder->nNG = 0;
   coder->nIZ = 0;
   coder->nZS = 0;
   coder->nRF = 0;

   EZWDListInit(&coder->LSP, EZWDeleteData, NULL, NULL);
   coder->RefinementMark[0] = NULL;

   fprintf(stdout, "BitP: %-2d LSP: %-8d\n", coder->CurrentBitPlane+1, DListSize(&coder->LSP));
   
   while (coder->CurrentThreshold > 0) {

      if (EZWSortingPass(coder)){
         fprintf(stdout, "End at sorting pass.\n");
         break;
      }
      
      fprintf(stdout, "BitP: %-2d LSP: %-8d\n", coder->CurrentBitPlane, DListSize(&coder->LSP));

      if (EZWRefinementPass(coder)){
         fprintf(stdout, "End at refinement pass.\n");
			break;
      }
     
      for (n=0; n<coder->nSubbands; n++){
         for (i=0; i<coder->SubbandSize[n]; i++){
            coder->State[n][i] = CLRBIT(coder->State[n][i], SCAN_CTX_BIT);
         }
      }

      
      coder->CurrentThreshold>>=1;
		coder->CurrentBitPlane--;


   }

	fprintf(stdout, "BitP: %-2d LSP: %-8d\n", coder->CurrentBitPlane, DListSize(&coder->LSP));

	EZWDListDestroy(&coder->LSP);

	fprintf(stdout, "Coded Symbols = %2d\n", coder->CodedSymbols);
	fprintf(stdout, "PS=%d, NG=%d, IZ=%d, ZS=%d, RF=%d\n", 
      coder->nPS, coder->nNG, coder->nIZ, coder->nZS, coder->nRF);

}
/*--------------------------------------------------------------------------------------------*/
void EZWSetResidualScanState(Coder *coder, int x, int y, int n)
{
   int bx, by, bsize, i;

   x <<=1;
   y <<=1;
   n+=3;
   bsize = 2;
   
   while (n<coder->nSubbands){
      
      for (by=y; by<y+bsize; by++){
         for (bx=x; bx<x+bsize; bx++){
            i = by*coder->SubbandXSize[n] + bx;
            coder->State[n][i] = SETBIT(coder->State[n][i], SCAN_CTX_BIT);
         }
      }
      
      bsize<<=1; 
      x<<=1;
      y<<=1;
      n+=3; // next child subband
      
   }
}

/*--------------------------------------------------------------------------------------------*/
int EZWProcessNode(Coder *coder, int n, int x, int y, int *LastScanSig)
{
   int i, s, ctx;
   ListData *Data;
   int scan, sig;
   
   // check if out of bound 
   if (x>=coder->SubbandXSize[n] || y>=coder->SubbandYSize[n]){
      // no processing
      return 0;
   }

   i = y*coder->SubbandXSize[n]+x;

   scan = CHKBIT(coder->State[n][i], SCAN_CTX_BIT);
   sig  = CHKBIT(coder->State[n][i], CSIG_CTX_BIT);

   if (scan==0 && sig==0){
         
      // marked as scanned
      coder->State[n][i] = SETBIT(coder->State[n][i], SCAN_CTX_BIT);

      ctx = EZWCSigContext(coder, i, n, *LastScanSig);

      if (coder->Mode==ENCODE){

         if (coder->MaxMagnitude[n][i] & coder->CurrentThreshold){
            // significant set
            
            if (coder->Magnitude[n][i] >= coder->CurrentThreshold){
               
               coder->State[n][i] = SETBIT(coder->State[n][i], CSIG_CTX_BIT);
               
               // significant root                         
               if (CHKBIT(coder->State[n][i], SIGN_CTX_BIT)){
                  // positive
                  s = _PS_;
               }
               else{
                  // negative
                  s = _NG_;	
               }
               
               EZWCSigContextUpdate(coder, i, x, y, n);
               
            }
            else {
               // significant residual 
               s = _IZ_;
            }

            *LastScanSig = 1;

         }
         else{
            // zero set
            s = _ZS_;
            *LastScanSig = 0;
            
            // marked all residual coefficients as scanned
            if (n==0){
               coder->State[1][i] = SETBIT(coder->State[1][i], SCAN_CTX_BIT);
               coder->State[2][i] = SETBIT(coder->State[2][i], SCAN_CTX_BIT);
               coder->State[3][i] = SETBIT(coder->State[3][i], SCAN_CTX_BIT);
               EZWSetResidualScanState(coder, x, y, 1);
               EZWSetResidualScanState(coder, x, y, 2);
               EZWSetResidualScanState(coder, x, y, 3);
            }
            else{
               EZWSetResidualScanState(coder, x, y, n);
            }
         }

         if(EZWWSymbol(coder,s)){
			 return 1;
         }

         
      }
	  //coder->Mode==DECODE
      else{
         
		  if (EZWRSymbol(coder,&s)) {
			return 1;
		  }
         
         if (s==_ZS_){
            *LastScanSig = 0;
            // marked all residual coefficients as scanned
            if (n==0){
               coder->State[1][i] = SETBIT(coder->State[1][i], SCAN_CTX_BIT);
               coder->State[2][i] = SETBIT(coder->State[2][i], SCAN_CTX_BIT);
               coder->State[3][i] = SETBIT(coder->State[3][i], SCAN_CTX_BIT);
               EZWSetResidualScanState(coder, x, y, 1);
               EZWSetResidualScanState(coder, x, y, 2);
               EZWSetResidualScanState(coder, x, y, 3);
            }
            else{
               EZWSetResidualScanState(coder, x, y, n);
            }
         }
         else{
            if (s==_IZ_){               
            }
            else {
               // significant root
               coder->State[n][i] = SETBIT(coder->State[n][i], CSIG_CTX_BIT);               
               coder->Magnitude[n][i] = 1;
               
               coder->SubbandPtr[n][i]
                  = (int)EZWDequantize(1, coder->CurrentThreshold, MSB_GAMMA);
               
               if (s==_PS_){
                  coder->State[n][i] = SETBIT(coder->State[n][i], SIGN_CTX_BIT);                          
               }
               else{
                  // inverse the sign
                  coder->SubbandPtr[n][i] *= -1;
               }
               
               EZWCSigContextUpdate(coder, i, x, y, n);
               
            }

            *LastScanSig = 1;
         }
      }

      if (s==_PS_ || s==_NG_){
         // send to LSP
         Data = EZWCreateData(i, x, y, (char)n);
         EZWDListAppend(&coder->LSP, Data);
      }

      //-----------------------------------------
      // update the counts
      if (s==_PS_){
         coder->nPS++;
      }
      else if (s==_NG_){
         coder->nNG++;
      }
      else if (s==_IZ_){
         coder->nIZ++;
      }
      else{
         coder->nZS++;
      }
      //-----------------------------------------

   }
   else{
      *LastScanSig = sig;
   }

   return 0;
}

/*--------------------------------------------------------------------------------------------*/
int EZWSortingPassVerticalScan(Coder *coder, int n)
{
   int x, y;
   int LastScanSig;
   
   LastScanSig = 0;

   for (x=0; x<coder->SubbandXSize[n]; x++){
      
      if (x%2){
         for (y=coder->SubbandYSize[n]-1; y>=0; y--){
            if (EZWProcessNode(coder, n, x, y, &LastScanSig)){
               return 1;
            }
         }
      }
      else{         
         for (y=0; y<coder->SubbandYSize[n]; y++){            
            if (EZWProcessNode(coder, n, x, y, &LastScanSig)){
               return 1;
            }         
         }
      }
   }   

   return 0;
}

/*--------------------------------------------------------------------------------------------*/
int EZWSortingPassHorizontalScan(Coder *coder, int n)
{
   int x, y;
   int LastScanSig;
         
   LastScanSig = 0;
   
   for (y=0; y<coder->SubbandYSize[n]; y++){
      if (y%2){
         for (x=coder->SubbandXSize[n]-1; x>=0; x--){         
            if (EZWProcessNode(coder, n, x, y, &LastScanSig)){
               return 1;
            }         
         }
      }
      else{
         for (x=0; x<coder->SubbandXSize[n]; x++){         
            if (EZWProcessNode(coder, n, x, y, &LastScanSig)){
               return 1;
            }         
         }
      }
   }

   return 0;
}


/*--------------------------------------------------------------------------------------------*/
int EZWHilbertScan(Coder *coder, int level, int scan, int n, 
                           int *x, int *y, int *LastScanSig)
{
   switch (scan){
   case RS:
      if (level<2){
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }         
         MoveRight(x, y);         
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }         
         MoveDown(x, y);         
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }
         MoveLeft(x, y);         
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }         
      }
      else{
         if (EZWHilbertScan(coder, level-1, DS, n, x, y, LastScanSig)){
            return 1;
         }                  
         MoveRight(x, y);                  
         if (EZWHilbertScan(coder, level-1, RS, n, x, y, LastScanSig)){
            return 1;
         }
         MoveDown(x, y);                  
         if (EZWHilbertScan(coder, level-1, RS, n, x, y, LastScanSig)){
            return 1;
         }       
         MoveLeft(x, y);         
         if (EZWHilbertScan(coder, level-1, US, n, x, y, LastScanSig)){
            return 1;
         }
      }
      break;

   case LS:
      if (level<2){
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }
         MoveLeft(x, y);
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }
         MoveUp(x, y);
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }
         MoveRight(x, y);
         if (EZWProcessNode(coder, n, *x, *y, LastScanSig)){
            return 1;
         }
      }
      else{
         if (EZWHilbertScan(coder, level-1, US, n, x, y, LastScanSig)){
            return 1;
         }
         MoveLeft(x, y);         
         if (EZWHilbertScan(coder, level-1, LS, n, x, y, LastScanSig)){
            return 1;
         }
         MoveUp(x, y);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -