📄 irle.c
字号:
#include "dct.h"
extern short block[BLOCK_SIZE];
extern int stream[BLOCK_SIZE];
extern short Ipreblock;
extern short dcHuffman[12];
extern short acHuffman[16][11];
extern int DCbit[12];
extern int count(short run, short cat);
short symb2(short symbol, short cat); // function to calculate the original data from symbol-2
short IdcHuff(int data); // function to calculate CAT from dc codeword
void IacHuff(int data); // function to calculate RUN and CAT from ac codeword
short ac_run, ac_cat; // RUN and CAT of ac decoding
void dc_decoding(void) // function doing dc decoding
{
short dcsym1,dcsym2;
short diff,cat;
int data, bit;
cat = IdcHuff(stream[0]); // calculate CAT from dc codeword
bit = DCbit[cat];
bit += cat; // calculate number of significance bits bits
data = stream[0];
data = data >> 1;
data = data & 0x7FFFFFFF;
data = data >> (32-bit-1); // shift the data back to the least significant bit
dcsym1 = data >> cat; // separate symbol-1 and symbol-2
dcsym2 = data - (dcsym1 << cat);
diff = symb2(dcsym2, cat); // calculate diff from symbol-2
block[0] = diff + Ipreblock; // calculate the original data
Ipreblock = block[0];
}
void ac_decoding(void)
{
short acsym1,acsym2;
int i,j, position=1;
int data, bit;
for(i=1; ;i++) {
if(stream[i] == 0xA0000000) { // check EOB
block[position] = 0;
break;
}
else {
IacHuff(stream[i]); // calculate RUN and CAT from ac codeword
for(j=0;j<ac_run;j++) { // number of zeros
block[position] = 0;
position++;
}
if(ac_run==15 && ac_cat==0) { // ZRL
block[position] = 0;
position++;
}
else {
bit = count(ac_run, ac_cat);
bit += ac_cat; // calculate number of significance bits bits
data = stream[i];
data = data >> 1;
data = data & 0x7FFFFFFF;
data = data >> (32-bit-1); // shift the data back to the least significant bit
acsym1 = data >> ac_cat; // separate symbol-1 and symbol-2
acsym2 = data - (acsym1 << ac_cat);
block[position] = symb2(acsym2, ac_cat); //calculate original data from symbol-2
position++; // current position of data
}
}
} // for
for(i=position+1;i<64;i++){ // after EOB all fill with 0
block[i] = 0;
}
}
short symb2(short sym2, short cat) // calculate the original data from symbol-2
{
short code, symbol;
symbol = sym2 << (16-cat);
if((symbol & 0x8000) == 0x8000) { // if the most significant bit is 1, the data is positive
code = sym2;
}
else { // the data is negtive
code = -1 << cat;
code = sym2 | code;
code = code+1;
}
return code;
}
short IdcHuff(int data) // calculate CAT from dc codeword
{
short cate;
data = data >> 16;
if((data & 0x8000) == 0) { //first bit is 0: 0,1,2
if((data & 0x4000) ==0) {
cate=0;
}
else if((data & 0x2000) == 0) {
cate=1;
}
else {
cate=2;
}
} // 0,1,2
else {
if((data & 0x4000) == 0) { //first two bits is 10: 3,4
if((data & 0x2000) == 0){
cate=3;
}
else {
cate=4;
}
} // 3,4
else {
if((data & 0x2000) == 0) { // 110
cate=5;
}
else if((data & 0x1000) == 0) { // 1110
cate =6;
}
else if((data & 0x0800) == 0) { // 1111 0
cate =7;
}
else if((data & 0x0400) == 0) { // 1111 10
cate =8;
}
else if((data & 0x0200) == 0) { // 1111 110
cate =9;
}
else if((data & 0x0100) == 0) { // 1111 1110
cate =10;
}
else if((data & 0x0080) == 0) { // 1111 1111 0
cate =11;
}
else ;
} // 5~11
}
return cate;
}
void IacHuff(int data) // calculate RUN and CAT from ac codeword
{
int i,j,flag=0;
data = data >> 16;
data = data & 0x0000FFFF;
if((data & 0x8000) == 0) { //0...
ac_run = 0;
if((data & 0x4000) == 0) {
ac_cat = 1;
}
else {
ac_cat = 2;
}
}
else{
if((data & 0xC000) == 0x8000) { // 10...
ac_run = 0;
if((data & 0x2000) == 0)
ac_cat = 3;
else if((data & 0x1000) == 0)
ac_cat = 0;
else
ac_cat = 4;
}
else {
if((data & 0xE000) == 0xC000) { // 110...
if((data & 0x1000) == 0) {
ac_run = 1;
ac_cat = 1;
}
else if((data & 0x0800) == 0) {
ac_run = 0;
ac_cat = 5;
}
else {
ac_run = 1;
ac_cat = 2;
}
}
else {
if((data & 0xF000) == 0xE000) { //1110...
ac_cat = 1;
if((data & 0x0800) == 0)
ac_run = 2;
else if((data & 0x0400) == 0)
ac_run = 3;
else
ac_run = 4;
}
else {
if((data & 0xF800) == 0xF000) { // 1111 0...
if((data & 0x0400) == 0){
if((data & 0x0200) == 0) {
ac_run = 0;
ac_cat = 6;
}
else{
ac_run = 1;
ac_cat = 3;
}
}
else {
ac_cat = 1;
if((data & 0x0200) == 0)
ac_run = 5;
else
ac_run = 6;
}
}
else {
if((data & 0xFC00) == 0xF800) { //1111 10...
if((data & 0x0200) == 0) {
if((data & 0x0100) == 0) {
ac_run = 0;
ac_cat = 7;
}
else {
ac_run = 2;
ac_cat = 2;
}
}
else {
if((data & 0x0100) == 0) {
ac_run = 7;
ac_cat = 1;
}
else if((data & 0x0080) == 0){
ac_run = 1;
ac_cat = 4;
}
else {
ac_run = 3;
ac_cat = 2;
}
}
}
else {
if((data & 0xFE00) == 0xFC00) { //1111 110...
if((data & 0x0100) == 0) {
ac_cat = 1;
if((data & 0x0080) == 0)
ac_run = 8;
else
ac_run = 9;
}
else {
if((data & 0x0080) == 0) {
ac_run = 10;
ac_cat = 1;
}
else if((data & 0x0040) == 0) {
ac_run = 0;
ac_cat = 8;
}
else {
ac_run = 2;
ac_cat = 3;
}
}
}
else {
if((data & 0xFF00) == 0xFE00) { //1111 1110...
if((data & 0x0080) == 0) {
if((data & 0x0040) == 0) {
ac_run = 4;
ac_cat = 2;
}
else {
ac_run = 11;
ac_cat = 1;
}
}
else {
if((data & 0x0040) == 0) {
ac_run = 12;
ac_cat = 1;
}
else if((data & 0x0020) == 0) {
ac_run = 1;
ac_cat = 5;
}
else {
ac_run = 5;
ac_cat = 2;
}
}
}
else {
if((data & 0xFF80) == 0xFF00) { //1111 1111 0...
if((data & 0x0040) == 0) {
if((data & 0x0020) == 0) {
ac_run = 13;
ac_cat = 1;
}
else {
ac_run = 15;
ac_cat = 0;
}
}
else if((data & 0x0020) == 0) {
if((data & 0x0010) == 0) {
ac_run = 2;
ac_cat = 4;
}
else {
ac_run = 3;
ac_cat = 3;
}
}
else {
ac_cat = 2;
if((data & 0x0010) == 0)
ac_run = 6;
else
ac_run = 7;
}
}
else {
if((data & 0x007E) == 0) {
ac_run = 8;
ac_cat = 2;
}
else { // 16 bit
for(i=0;i<16;i++) {
if(flag == 1) {
break;
}
for(j=0;j<11;j++){
if((short)data == acHuffman[i][j]) {
ac_run = i;
ac_cat = j;
flag = 1;
break;
}
}
} // for
} // 16 bit
} // 0xFF80
} // 0xFF00
} // 0xFE00
} // 0xFC00
} // 0xF800
} // 0xF000
} // 0xE000
} // 0xC000
} //0x8000
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -