www.pudn.com > ezw_davis.rar > unezwdos.c
/*
UNEZWDOS.C
Example for Embedded ZEROtree Wavelet (EZW) decoding in ANSI-C.
This file is part of my Embedded ZEROtree Wavelet Encoder Tutorial.
Based on "Embedded Image Coding Using ZEROtrees of Wavelet Coefficients"
by Jerome M. Shapiro, IEEE Transactions on Signal Processing, Vol.41, No.12,
December 1993, pp 3445-3462.
A fifo is used in the dominant pass which results in a so-called Morton order
scan instead of Shapiro's raster scan (see figure 2 in "Analysis Based Coding
of Image Transform and Subband Coefficients" by V. Ralph Algazi and Robert
R. Estes, Jr.).
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
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
#include
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)//得到输入bit流的一位信息
{
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)//对从输入bit流中数据进行译码操作
{
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; im[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)
{
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;
}