?? unezw.c
字號:
/*
EZW解碼器
解碼器數(shù)據(jù)掃描的方式:
Morton order scan:
====================================
1 | 2 | 5 6 | 17 18 21 22
---+---| |
3 | 4 | 7 8 | 19 20 23 24
-------+--------|
9 10 | 13 14 | 25 26 29 30
| |
11 12 | 15 16 | 27 28 31 32
----------------+---------------
33 34 37 38 | 49 50 53 54
|
35 36 39 40 | 51 52 55 56
|
41 42 45 46 | 57 58 61 62
|
43 44 47 48 | 59 60 63 64
Raster scan:
========================
1 | 2 | 5 6 | 17 18 19 20
---+---| |
3 | 4 | 7 8 | 21 22 23 24
-------+--------|
9 10 | 13 14 | 25 26 27 28
| |
11 12 | 15 16 | 29 30 31 32
----------------+---------------
33 34 35 36 | 49 50 51 52
|
37 38 39 40 | 53 54 55 56
|
41 42 43 44 | 57 58 59 60
|
45 46 47 48 | 61 62 63 64
數(shù)據(jù)平面的頻段分布:
Subband distribution:
==========================================
LL | HL | HL HL | HL HL HL HL
---+--- | |
LH | HH | HL HL | HL HL HL HL
--------+---------|
LH LH | HH HH | HL HL HL HL
| |
LH LH | HH HH | HL HL HL HL
------------------+------------------
LH LH LH LH | HH HH HH HH
|
LH LH LH LH | HH HH HH HH
|
LH LH LH LH | HH HH HH HH
|
LH LH LH LH | HH HH HH HH
*/
#define debug
#include "ezw.h"
#include "fifo.h"
#include "list.h"
#include "matrix2d.h"
#include <stdlib.h>
#include <stdio.h>
matrix_2d *M; //定義工作矩陣
char error; //定義誤差
FILE *ezw_file; //已編碼文件
ezw_file_header header; //文件頭
long int pixels;
long int zeroes, ones;
unsigned char input_byte, mask;
void show_code(int code)
{
switch (code)
{
case ZERO: //如果編碼為ZERO,則輸出為0
printf("0");
break;
case ONE: //如果編碼為ONE,則輸出為1
printf("1");
break;
case POS: //如果編碼為POS,則輸出為p
printf("p");
break;
case NEG: //如果編碼為NEG,則輸出為n
printf("n");
break;
case ZTR: //如果編碼為ZTR,則輸出為t
printf("t");
break;
case IZ: //如果編碼為IZ,則輸出為z
printf("z");
break;
}
}
//從一個(gè)輸入流中讀出一個(gè)比特位
char get_bit(void)
{
char bit; //定義讀出的比特位存儲空間
if (mask==0)
{
//從文件中讀出一個(gè)字節(jié),存放在input_byte中
fread(&input_byte,sizeof(input_byte),1,ezw_file);
mask = 0x80; //最高位標(biāo)志
}
//如果讀出字節(jié)的最高位為0,則讀出比特位的值為0
if ((input_byte&mask)==0)
{
bit = '0';
zeroes++;
}
//否則讀出比特位的值為1
else
{
bit = '1';
ones++;
}
//最高標(biāo)志位右移一位
mask >>= 1;
//返回當(dāng)前判斷的比特位的值
return (bit);
}
//從一個(gè)輸入流中讀出一個(gè)編碼字節(jié)
int input_code(int count)
{
switch (get_bit())
{
//如果讀出的比特位的值為0
case '0':
//假如是讀出字節(jié)的最高位,則返回ZERO
if (count==1) return (ZERO);
//否則,讀取比特位
else
{
switch (get_bit())
{
case '0': return (ZTR); //如果讀出為0,返回為ZTR
case '1': return (POS); //如果讀出為1,返回為POS
}
}
break;
//如果讀出的比特位的值為1
case '1':
//假如是讀出字節(jié)的最高位,則返回ONE
if (count==1) return (ONE);
//否則,讀取比特位
else
{
switch (get_bit())
{
case '0': return (IZ); //如果讀出為0,返回為IZ
case '1': return (NEG); //如果讀出為1,返回為NEG
}
}
break;
}
//缺省返回值,不可返回
return 0;
}
//利用主表元素和閾值解碼后填充當(dāng)前矩陣元素
void input_element(matrix_2d *m, element_type t, ezw_element *s)
{
list_type d;
d.x = s->x;
d.y = s->y;
s->code = input_code(2);
#ifdef debug
show_code(s->code);
#endif
if ((s->code==POS))
{
m->m[s->y][s->x] = t;
append_to_list(d);
}
else if ((s->code==NEG))
{
m->m[s->y][s->x] = -t;
append_to_list(d);
}
}
/*
* Performs one dominant pass.
*/
void dominant_pass(matrix_2d *m, element_type threshold)
{
ezw_element s;
int min_x, max_x, min_y, max_y;
s.x = 0;
s.y = 0;
input_element(m,threshold,&s);
if ((s.code==POS) || (s.code==NEG)) pixels++;
s.x = 1;
s.y = 0;
input_element(m,threshold,&s);
put_in_fifo(s);
s.x = 0;
s.y = 1;
input_element(m,threshold,&s);
put_in_fifo(s);
s.x = 1;
s.y = 1;
input_element(m,threshold,&s);
put_in_fifo(s);
s = get_from_fifo();
if (fifo_empty==0)
{
if ((s.code==POS) || (s.code==NEG)) pixels++;
}
while (fifo_empty==0)
{
if (s.code!=ZTR)
{
min_x = s.x << 1;
max_x = min_x+1;
min_y = s.y << 1;
max_y = min_y+1;
if ((max_x<=m->col) && (max_y<=m->row))
{
for (s.y=min_y; s.y<=max_y; s.y++)
{
for (s.x=min_x; s.x<=max_x; s.x++)
{
input_element(m,threshold,&s);
put_in_fifo(s);
}
}
}
}
s = get_from_fifo();
if (fifo_empty==0)
{
if ((s.code==POS) || (s.code==NEG)) pixels++;
}
}
}
/*
* Performs one subordinate pass.
*/
void subordinate_pass(matrix_2d *m, element_type threshold)
{
long int i;
element_type temp;
list_type d;
char found;
if (threshold>0)
{
for (i=0; i<pixels; i++)
{
d = get_list_element(i,&found);
if (found==1)
{
temp = m->m[d.y][d.x];
if (input_code(1)==ONE)
{
#ifdef debug
show_code(ONE);
#endif
if (temp<0)
{
m->m[d.y][d.x] = temp - threshold;
}
else
{
m->m[d.y][d.x] = temp + threshold;
}
}
#ifdef debug
else show_code(ZERO);
#endif
}
}
}
}
//將編碼文件數(shù)據(jù)解碼存放到工作矩陣m中
void EZW_decode(matrix_2d *m)
{
element_type threshold; //閾值
pixels = 0;
threshold = header.threshold;
//從初始閾值開始知道閾值為0
while (threshold!=0)
{
dominant_pass(m,threshold);
subordinate_pass(m,threshold >> 1);
threshold >>= 1; //閾值減半
}
}
int iEZW(void)
{
printf("\n");
//以二進(jìn)制只讀模式打開編碼文件
if ((ezw_file=fopen("out.ezw","rb"))==NULL) {
printf("Could not open input file.\n");
exit(1);
};
//讀文件的頭信息
fread(&header,sizeof(header),1,ezw_file);
//創(chuàng)建一個(gè)工作矩陣(給出高和寬)
M = matrix_2d_create(header.height,header.width);
if (M==NULL) exit(1);
//矩陣清零
matrix_2d_clear(M);
//初始值設(shè)置
zeroes = 0;
ones = 0;
input_byte = 0;
mask = 0;
EZW_decode(M);
#ifdef debug
printf("\n");
//工作矩陣賦值(寫操作)
matrix_2d_write(M);
printf("%ld bits: %ld zeroes, %ld ones\n", zeroes+ones, zeroes, ones);
#endif
//關(guān)閉先前的編碼文件
fclose(ezw_file);
//釋放工作矩陣占據(jù)的存儲空間
matrix_2d_destroy(M);
//釋放主表掃描過程中的臨時(shí)數(shù)據(jù)
destroy_fifo();
//清除零樹掃描過程中的臨時(shí)數(shù)據(jù)
destroy_list();
return 0;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -