?? unezw.c
字號:
/*
EZW解碼器
解碼器數據掃描的方式:
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
數據平面的頻段分布:
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;
}
}
//從一個輸入流中讀出一個比特位
char get_bit(void)
{
char bit; //定義讀出的比特位存儲空間
if (mask==0)
{
//從文件中讀出一個字節,存放在input_byte中
fread(&input_byte,sizeof(input_byte),1,ezw_file);
mask = 0x80; //最高位標志
}
//如果讀出字節的最高位為0,則讀出比特位的值為0
if ((input_byte&mask)==0)
{
bit = '0';
zeroes++;
}
//否則讀出比特位的值為1
else
{
bit = '1';
ones++;
}
//最高標志位右移一位
mask >>= 1;
//返回當前判斷的比特位的值
return (bit);
}
//從一個輸入流中讀出一個編碼字節
int input_code(int count)
{
switch (get_bit())
{
//如果讀出的比特位的值為0
case '0':
//假如是讀出字節的最高位,則返回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':
//假如是讀出字節的最高位,則返回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;
}
//利用主表元素和閾值解碼后填充當前矩陣元素
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
}
}
}
}
//將編碼文件數據解碼存放到工作矩陣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 main(void)
{
printf("\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);
//創建一個工作矩陣(給出高和寬)
M = matrix_2d_create(header.height,header.width);
if (M==NULL) exit(1);
//矩陣清零
matrix_2d_clear(M);
//初始值設置
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
//關閉先前的編碼文件
fclose(ezw_file);
//釋放工作矩陣占據的存儲空間
matrix_2d_destroy(M);
//釋放主表掃描過程中的臨時數據
destroy_fifo();
//清除零樹掃描過程中的臨時數據
destroy_list();
//缺省返回值
return 0;
}
1 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
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
C. Valens
Created : 07/09/1999
Last update: 29/09/1999
*/
#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:
printf("0");
break;
case ONE:
printf("1");
break;
case POS:
printf("p");
break;
case NEG:
printf("n");
break;
case ZTR:
printf("t");
break;
case IZ:
printf("z");
break;
}
}
/*
* Reads a bit from the input stream.
*/
char get_bit(void)
{
char bit;
if (mask==0) {
fread(&input_byte,sizeof(input_byte),1,ezw_file);
mask = 0x80;
}
if ((input_byte&mask)==0) {
bit = '0';
zeroes++;
}
else {
bit = '1';
ones++;
}
mask >>= 1;
return (bit);
}
/*
* Reads a code from the input stream.
*/
int input_code(int count)
{
switch (get_bit()) {
case '0':
if (count==1) return (ZERO);
else {
switch (get_bit()) {
case '0': return (ZTR);
case '1': return (POS);
}
}
break;
case '1':
if (count==1) return (ONE);
else {
switch (get_bit()) {
case '0': return (IZ);
case '1': return (NEG);
}
}
break;
}
/*
* You should never get here.
*/
return 0;
}
/*
* Builds a matrix element from dominant pass EZW-element and a threshold.
*/
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
}
}
}
}
/*
* EZW-decodes file f into matrix m.
*/
void EZW_decode(matrix_2d *m)
{
element_type threshold;
pixels = 0;
threshold = header.threshold;
while (threshold!=0) {
dominant_pass(m,threshold);
subordinate_pass(m,threshold >> 1);
threshold >>= 1;
}
}
/*
* Main.
*/
//int main(void)
//{
//}
int iEZW(void)
{
printf("\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);
M = matrix_2d_create(header.height,header.width);
if (M==NULL) exit(1);
matrix_2d_clear(M);
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
fclose(ezw_file);
matrix_2d_destroy(M);
destroy_fifo();
destroy_list();
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -