#include <vcl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include "cdhead.h"
#include "ztdef.h"
#include "ztenc.h"
//#include "ACenc.c"
//#include "cdcsub.c"
extern void Initialize_ACcoding(), Done_ACcoding();
extern void Change_ACmodel(int,int), ACencode(int);
extern int get_child(int,int,int (* )[2],int,int,int,int);
extern int SizeAdjforWT(int,int);
static void Sig_Map(int **,int,int,int);
#define put_to_stream(symbol) ACencode(symbol)
/*static int cur_pass;
static unsigned char buffer=0;
static int bits_to_go=8;
void put_to_stream(int symbol)
{ int k,bit;
//ACencode(symbol)
if(enc_byte_count>=enc_Tot_bytes) return;
if(cur_pass==DORM) k=2;
else k=1;
while(k>0){
bit=symbol&k;
k--;
buffer>>=1;
if(bit) buffer|=0x80;
bits_to_go-=1;
if(bits_to_go==0) {
enc_bit_stm[enc_byte_count]=(unsigned char)buffer;
enc_byte_count++;
bits_to_go=8;
}
}
}
*/
void processing(int **f,int i, int j)
{
int l;
if(f[i][j]>=threshold ){
if(sign[i*size+j/8]&bit_pos[j&get_bit_pos]) put_to_stream(neg);
else put_to_stream(pos);
l=1;
/*if(sign[i*size+j/8]&bit_pos[j&get_bit_pos]) {
if(big_coef_index[i*size+j/8]&bit_pos[j&get_bit_pos])
{ put_to_stream(neg); l=1; }
else put_to_stream(neg_zt);
}
else if(big_coef_index[i*size+j/8]&bit_pos[j&get_bit_pos])
{ put_to_stream(pos); l=1; }
else put_to_stream(pos_zt);
*/
big_coef_queue[queue_tail]=f[i][j]-threshold; queue_tail++;
if(l==1 && i<half_row && j<half_col)
{ work_stack[stack_top]=(short)i; stack_top++;
work_stack[stack_top]=(short)j; stack_top++; }
f[i][j]=Outdate;
}
else if(f[i][j]!=Outdate){
l=big_coef_index[i*size+j/8]&bit_pos[j&get_bit_pos];
if(l!=0) {
put_to_stream(iz);
if(i<half_row && j<half_col )
{ work_stack[stack_top]=(short)i; stack_top++;
work_stack[stack_top]=(short)j; stack_top++; }
}else put_to_stream(zr);
}
else {
if(i<half_row && j<half_col)
{ work_stack[stack_top]=(short)i; stack_top++;
work_stack[stack_top]=(short)j; stack_top++; }
}
}
void zero_coding(char *fileoutname,int **f,int row,int col,int declev,int cmp_rate,int img_mean)
{ ZTHEAD trs_head;
int child[4][2];
int mode=0;
int i,j,k,kb,ks,l,adj_row,adj_col;
float Mag;
FILE *fp;
adj_row=SizeAdjforWT(row, declev);
adj_col=SizeAdjforWT(col, declev);
Outdate=-1;
img_col=adj_col;half_row=adj_row>>1; half_col=adj_col>>1;
least_row=adj_row>>declev; least_col=adj_col>>declev;
threshold=0;
enc_Tot_bytes=(row*col+cmp_rate-1)/cmp_rate-sizeof(ZTHEAD);
enc_bit_stm=(unsigned char *)malloc(enc_Tot_bytes+10);
enc_byte_count=0;
enc_Tot_bytes--; //for counting convenience in AC coding
/*for(i=0;i<least_row;i++)for(j=0;j<least_col;j++)
img_mean+=f[i][j];
img_mean=img_mean/(least_row*least_col);
for(i=0;i<least_row;i++)for(j=0;j<least_col;j++)
f[i][j]-=img_mean;
*/
size=(adj_col+7)/8;
sign=(unsigned char *)malloc(adj_row*size);
memset(sign,0,adj_row*size);
k=0; l=0;
for(i=0;i<adj_row;i++){
for(j=0;j<adj_col;j++) {
if(f[i][j]<0) {
sign[k]=sign[k]|bit_pos[l];
f[i][j]=abs(f[i][j]);
}
l++;
if(l==8) { l=0; k++; }
if(f[i][j]>threshold) threshold=f[i][j];
}
/*if(l!=0) k++;*/
}
memset(&trs_head,0,sizeof(ZTHEAD));
Mag=(float) threshold;
trs_head.img_mean=threshold;
l=0;
threshold-=1;
while(threshold>0) {threshold>>=1; l++;}
if(l!=0) threshold=1<<(l-1);
trs_head.log2_of_threshold=(short)(l-1);
trs_head.row=(short)row; trs_head.col=(short)col;
trs_head.declev=(unsigned char)declev;
Mag=(float)(threshold*2.0-1)/Mag;
for(i=0;i<row;i++)for(j=0;j<col;j++)
f[i][j]=(int)((float)f[i][j]*Mag);
Initialize_ACcoding();
big_coef_queue=(int *)malloc(adj_row*adj_col*sizeof(int));
queue_tail=0;
//qinterval_pointer=(int *)malloc((threshold+1)*sizeof(int));
//pointer_tail=0; qinterval_pointer[0]=0;
//next_pointer=(int *)malloc((threshold+1)*sizeof(int));
Chain_End=0;
big_coef_index=(unsigned char *)malloc(adj_row*size);
ks=0;
while(threshold!=0) {
memset(big_coef_index,0,adj_row*size);
Sig_Map(f,adj_row,adj_col,declev);
work_stack=(unsigned short int *)malloc(adj_row*adj_col/4*2*sizeof(short int));
stack_bot=0; stack_top=0;
/*---- Dorminant Pass ---------*/
Change_ACmodel(DORM,mode); mode=1;
//cur_pass=DORM;
if(enc_byte_count>=enc_Tot_bytes){ free(work_stack); goto CD_Finished; }
for(i=least_row-1;i>=0;i--)for(j=0;j<least_col;j++) processing(f,i,j);
while(stack_bot!=stack_top){
i=work_stack[stack_bot]; stack_bot++;
j=work_stack[stack_bot]; stack_bot++;
k=get_child(i,j,child,least_row,least_col,half_row,half_col);
if(k>0) for(i=0;i<k;i++) processing(f,child[i][0], child[i][1]);
}
free(work_stack);
/*if(queue_tail!=qinterval_pointer[Chain_End]){
pointer_tail++;
qinterval_pointer[pointer_tail]=queue_tail;
next_pointer[Chain_End]=pointer_tail; Chain_End=pointer_tail;
}*/
kb=ks; ks=queue_tail;
/**** End of Dorminant Pass ****/
if(kb==0) goto Next_Round;
/*---- Subordinate Pass -------*/
Change_ACmodel(SUB,mode);
//cur_pass=SUB;
if(enc_byte_count>=enc_Tot_bytes) goto CD_Finished;
// change=(int *)malloc(row*col*sizeof(int));
//memset(change,0,row*col*sizeof(int));
//threshold=threshold>>1;
//if(threshold==0) goto CD_Finished;
j=0;
while(j<kb){
//kb=qinterval_pointer[i]; ks=kb;
//for(j=qinterval_pointer[i];j<qinterval_pointer[next_pointer[i]];j++){
if(big_coef_queue[j]>=threshold){
put_to_stream(big);
big_coef_queue[j]
=big_coef_queue[j]-threshold;
}
else {
put_to_stream(sml);
//change[ks++]=big_coef_queue[j];
}
j++;
//}
/*if(kb>qinterval_pointer[i] && kb<qinterval_pointer[next_pointer[i]]){
pointer_tail++; qinterval_pointer[pointer_tail]=kb;
for(j=qinterval_pointer[i];j<ks;j++)
big_coef_queue[kb++]=change[j];
l=next_pointer[i]; next_pointer[i]=pointer_tail;
next_pointer[pointer_tail]=l;
i=pointer_tail;
}*/
//i=next_pointer[i];
}
//free(change);
/**** End of Subordinate Pass ****/
Next_Round: threshold>>=1;
}/** END of WHILE **/
CD_Finished:
Done_ACcoding();
free(big_coef_index);
free(big_coef_queue);
//free(qinterval_pointer);
//free(next_pointer);
//enc_byte_count--;
/*if(bits_to_go!=8) {
enc_bit_stm[enc_byte_count]=(unsigned char)(buffer>>bits_to_go);
enc_byte_count++;
}*/
//trs_head.Total=enc_byte_count;
//trs_head.bits_left=enc_bits_left;
fp=fopen(fileoutname,"wb");
fwrite(&trs_head,sizeof(ZTHEAD),1,fp);
fwrite(enc_bit_stm,sizeof(char),enc_byte_count,fp);
fclose(fp);
free(enc_bit_stm);
free(sign);
printf("TH= %d, Uncerntainty= %d\n", (1<<trs_head.log2_of_threshold), threshold/2);
printf(" %d coefs in queue\n",queue_tail);
}
//big_coef_index=(unsigned char *)malloc(adj_row*size);
//此函数改变big_coef_index,如果一节点有重要的子接点,则把它置为1,反之,置为0;
//这要求big_coef_index是一个全局变量,且初始化为0值.
void Sig_Map(int **f, int adj_row,int adj_col,int declev)
{
int i,j,k,ii,jj;
int wklev_row,wklev_col,oldlev_row,oldlev_col;
/*---------- recording current big coefs' positions -------*/
k=declev;
wklev_row=adj_row>>1; wklev_col=adj_col>>1;
oldlev_col=adj_col; oldlev_row=adj_row;
while(k>2) {
for(i=0;i<oldlev_row;i++)for(j=wklev_col;j<oldlev_col;j++){
if(f[i][j]>=threshold ) {
//big_coef_index[i*size+j/8]|=bit_pos[j&get_bit_pos];