📄 ezw.cpp
字号:
//#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 + -