
330
gotoxy(1,3);
printf(" ");
gotoxy(1,3);
printf(" Enter file name -->");
scanf ( "%s", file_name2);
ind=access(file_name2, 0);
}
}
fptro=fopen(file_name2, "wb");
xt=wherex();
yt=wherey();
gotoxy(70,25);
textattr(RED+(LIGHTGRAY<<4)+BLINK);
cputs("WAIT");
/*Reading the header.*/
act_len=0;
M=8*sizeof(long int)-8;
for(j=0;i<4;i++)
{
ch=getc(fptr);
aux1=(unsigned long int)ch;
aux1<<=M;
act_len|=aux1;
aux1=(long int)0;
M-=8;
}
N=getc(fptr);
gray=( unsigned char * )malloc(N*sizeof(char));
L=(unsigned char *)malloc(N*sizeof(char));
code=( unsigned long int *)malloc ( N*sizeof(long
int));
for(i=0; i<N; i++)
gray[i]=getc(fptr);
for(i=0; i<N ; i++)
L[i]=getc(fptr);
mask=128;
Len=0;
aux2=0;
aux1=0;
ind=1;
i=0;
while(ind)
{
ch=getc(fptr);

331
for(k=0;k<8;k++)
{
aux1=ch&mask;
ch<<=1;
aux2<<=1;
if(aux1!=0)
aux2|=1;
Len++;
if(Len==L[i])
{
code[i]=aux2;
aux2=0;
Len=0;
i++;
if(i==N){
ind=0;
break;
}
}
}
}
Len=0;
aux1=aux2=0;
flength=0; /*a parameter to measure against actual
file length.*/
mask=128;
ind=1;
while(ind)
{
ch=getc(fptr);
for(k=0;k<8;k++)
{
/* test if the actual end of file has been
reached.*/
if(flength>act_len){ind=0; break;}
aux1=(ch&mask);
ch<<=1;
aux2<<=1;
if(aux1!=0)
aux2|=1;
Len++;
for(j=0;j<N;j++)
{
if(L[j]>Len) break;

332
if(L[j]==Len)
{
if(code[j]==aux2)
{
aux2=0;
putc((int)gray[j],fptro);
Len=0 ;
break;
}
}
}
flength++;
}
}
gotoxy(70, 25);
textattr(WHITE+(BLACK<<4));
cputs( " ");
gotoxy (xt, yt);
printf(" \ n Done decoding. ");
fcloseall();
getch();
}
Hình 13.3 Cây nhị phân giải mã Huffman hình 13.2.
Bài tập 13.3
1. Áp dụng chương trình 13.3 cho việc giải mã ảnh đã mã hoá ở bài tập
13.2.
2. Mã hoá Huffman có thể đạt được kết quả hơn nhờ sử dụng cây nhị phân.
Cây nhị phân trong hình 13.3 biểu diễn mã Huffman ở hình 13.2.
0
1
1
1
1
2
3
4
5
6
7
8
0
0
0
0
0
0
1
1
Nút
gốc
Nút
lá
Các nút gốc

333
a. Viết chương trình C sử dụng mã Huffman đặt trong phần header của
file ảnh đã mã hoá để tạo một cây nhị phân.
b. Mở rộng cho chương trình giải mã dùng cây nhị phân. Chương trình
phải đạt được một vài yêu cầu quan trọng nhanh hơn phương pháp đã
mô tả trong phần này. giải thích tại sao.
13.3 Mã chiều dài thay đổi
Mã chiều dài thay đổi (RLC) là một phương pháp nén ảnh dựa trên sự cắt
bớt các dư thừa không gian. Cho mã hoá chiều dài thay đổi một chiều, một mã
chiều dài thay đổi được định nghĩa là một số các phần tử điểm ảnh liên tục có
chung một giá trị. Một ảnh có thể mã hoá dùng một cặp (mã chiều dài thay
đổi, mã mức xám). Một chương trình như vậy sẽ không thể làm giảm kích
thước của ảnh nếu ảnh không chứa các điểm có cùng các giá trị mức xám.
Điều kiện này xuất hiện trong một ảnh nhiều chi tiết. Dù có thế đi chăng nữa
thì định nghĩa của RLC có thể là một phương pháp tốt để mã hoá mà có thể
khắc phục các vấn đề xuất hiện dựa theo các điều kiện sau:
1. Một mã chiều dài thay đổi được xác định bằng ba bít cuối cùng có ý
nghĩa của nó được xác lập bằng 1. Còn 5 bít thấp của nó cung cấp một
bộ đếm từ 1 đến 31 cho byte đi theo nó.
2. Nếu giá trị một điểm có mã chiều dài thay đổi bằng không, thì nó được
mã hoá như sau:
a. Nếu 3 bit cuối của nó đều xác lập lên 1, châửng hạn, 224, thì nó
được mã hoá thành (11100000, giá trị điểm), cụ thể, mã chiều dài thay
đổi bằng không theo sau bằng giá trị điểm.
b. Cho các trường hợp còn lại, nó được mã hoá như giá trị điểm.
Các bước trên giả thiết rằng trong một ảnh bình thường, mã chiều dài thay
đổi lớn hơn 31 ít xuất hiện, và các điểm có giá trị lớn hơn 224 cũng ít xuất
hiện. Chương trình C sau sẽ thực hiện các bước trên.
Chương trình 13.4 "RLC.C". Chương trình cho giải thuật RLC.
/*Program 13.4 "RLC.C". Program for RLC.*/
/* Run length code. */
/* This program can be used for either
coding images in RLC or decoding them. */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#define MASK 224 /* MASK=11100000 */

334
void main()
{
int buff[256],p;
int N,i,k;
FILE *fptr,*fptro;
char file_name[14],ch;
int NMASK=(~MASK);
clrscr();
printf("This program can be used for both coding");
printf("\nand decoding images using 1-D RLC.");
printf("\n\n Enter choice:");
printf("\n 1.Coding.");
printf("\n 2.Decoding --- >" );
while(((ch=getch())!='1')&&(ch!='2'));
putch(ch);
printf("\n\nEnter input file name-->");
scanf("%s",file_name);
fptr=fopen(file_name,"rb");
if(fptr==NULL)
{
printf("\n file %s does not exist.\n");
exit(1);
}
switch(ch)
{
case '1':
printf("Enter output file name-->");
scanf("%s",file_name);
fptro=fopen(file_name,"wb");
/* Read first line.*/
N=0;
while((buff[N]=getc(fptr))!=EOF)
{
N++;
if(N==256) break;
}
while(N!=0)
{
i=0;
while(i<N)
{
p=buff[i]; /*Read reference value.*/