⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arith_encoder_jpeg2000.asm

📁 JPEG2000 ADI BLACKFIN 压缩解压程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
Prototype        :void  arith_enc_renorme(struct * enc_reg);

In renormalization function both interval reg. A and code reg. C are shifted, 
one bit at a time. The number of shift is counted by register CT. When CT 
becomes zero ,a compressed data is copied to output buffer by calling function 
arith_enc_byteout.  Renormalization is done until A is no longer less than 
0x8000.

Registers Used  : R0-R2, P0, P5.
*******************************************************************************/
.section              program;
.global               __arith_enc_renorme;
.align                       8;
    
__arith_enc_renorme:
    P0 = R0;                // Address of structure mq_enc
    [--SP] = P5;            // push P5
    P5 = R0;                   
    R0 = [P0++];            // fetch interval reg. A
    R1 = [P0++];            // fetch code reg.  C
    R2 = [P0] ;             // fetch counter reg. CT
DECREMENT:
    R0 <<=1;               // shift both A and C reg by 1 bit
    R1 <<=1;
    R2 += -1;               // decrement CT
    CC=R2==0;               // check if CT==0
    IF CC JUMP GET_BYTE_1;  // if true call byteout else check if A<0x8000

TEST_0X8000:
    CC = BITTST(R0,15);     // check if A & 0x8000==1
    IF !CC JUMP DECREMENT;  // if false jump to decrement
    [P5++] = R0;
    [P5++] = R1;
    [P5++] = R2;            // store A,C,CT
    P5 = [SP++];
    RTS;
GET_BYTE_1:
    [P0--] = R2;
    [P0--] = R1;
    [P0--] = R0;            // store A,C ,CT
    R0 = P5;
    [--SP] = RETS; 

    CALL __arith_enc_byteout;
                            // call byteout to store byte to output buffer 
    RETS = [SP++];
    R0 = [P5];
    R1 = [P5+4];            // get updated A,C,CT
    R2 = [P5+8];
    JUMP TEST_0X8000;
    
__arith_enc_renorme.end:    
    
/*****************************************************************************
Prototype         : void arith_enc_byteout(struct * enc_reg);

This routine contains bit-stuffing procedures which are needed to limit carry 
propagation into  the completed bytes of compressed data. B register holds the 
compressed data. If B == 0xFF , bit stuffing is done ,otherwise carry bit is 
checked. If carry bit is set it is added to B and again checked if B==0xff to 
see if a bit stuffing is needed. After need for bit stuffing has determined, B 
value is stored and new value of B is derived from C register and CT register is
set accordingly.

Registers Used  : R0-R3, R7, P0, P2.
*******************************************************************************/
.section                 program;
.global                 __arith_enc_byteout;
.align                          8;
    
__arith_enc_byteout:
    P0 = R0;                // Address of structure mq_enc
    [--SP] = R7;
    R3 = 255;               // Initialize to compare with 255
    R0 = [P0+4];            // fetch value of Code register  C
    R7 = R1-R1(NS) || R1 = [P0+12];
                            // fetch value of compressed data B 
    R2 = [P0+16];           // get value of first byte
    P2 = [P0+20];           // address of output buffer
    CC = R1 == R3;          // check if B = 0xff
    IF CC JUMP BIT_STUFF;   // if true do bit stuffing
    R7.H = 0X800;
    CC = R0<R7;             // check if carry bit is set in C
    IF CC JUMP NO_BIT_STUFF;// if true no bit stuffing required
    R1+= 1;                 // Add carry to B register
    CC = R1==R3;            // compare B register  with 0xff
    IF !CC JUMP NO_BIT_STUFF;
    BITCLR(R0,27);          // clear carry bit

BIT_STUFF:
    CC = R2 == 0;           // check if first_byte flag==0
    IF CC JUMP CP_OUTPUT;
    R2 = 0;                 // clear first_byte flag
    JUMP GET_NEXT_B;

CP_OUTPUT:
    B[P2++] = R1;           // store B register to output buffer

GET_NEXT_B:
    R1 = R0 >> 20 || [P0+20] = P2;
                            // get next B from C register and store output 
                            // buffer address 
    R7.L = -1;
    R7.H = 0XF;
    R0 = R0&R7;
    R7 = 7;                 // initialize count register CT to 7
    [P0+16] = R2;           // store first_byte flag
    [P0+12] = R1;           // store B register
    [P0+8] = R7;            // store CT register
    [P0+4] = R0;            // store C register
    R7 = [SP++];
    RTS;
    
NO_BIT_STUFF:
    CC = R2==0;             // check if first_byte flag is set
    IF CC JUMP CP_OUTPUT1;
    R2 = 0;                 // clear first_byte
    JUMP GET_NEXT_B1;

CP_OUTPUT1:
    B[P2++] = R1;           // store B register to output buffer

GET_NEXT_B1:
    R1 = R0 >> 19;			//Change from 535 to 533
    [P0+20] = P2;
                            // get next B value from C register and store output
                            // buff address 
    R7.L = -1;
    R7.H = 7;
    R0 = R0&R7;
    R7 = 8;
    [P0+16] = R2;           // store fist_byte flag
    [P0+12] = R1;           // store B register
    [P0+8] = R7;            // store CT register
    [P0+4] = R0;            // store C register
    R7 = [SP++];
    RTS;

__arith_enc_byteout.end:        

/******************************************************************************
Prototype   : void  arith_enc_flush(struct * enc_reg);

This procedure is used to terminate the encoding operation and generate the 
required terminating marker. This procedure guarantees that 0xff prefix to the 
marker code overlaps the final bits of compressed data. This routine sets as may
bits in the C register to 1 as possible. The exclusive upper bound for the C reg
is sum of C register and interval register A. The low order 16 bits of C are 
forced to 1, and the result is compared to upper bound. If C reg is too big 
leading 1 bit is removed, reducing C to a value is within the interval. If the 
Byte B is 0xff then it is discarded, otherwise stored to output buffer.

Registers Used  : R0-R3, R7, P0, P2, P5.
*****************************************************************************/
.section             program;
.global              __arith_enc_flush;
.align                     8;
    
__arith_enc_flush:

    P0 = R0;                // address of structure mq_enc
    [--SP] = (R7:7,P5:5);     
    P5 = R0;                                 
    R2 = R1-R1(NS) || R0 = [P0++];
                            // clear R2 and fetch interval register A 
    R7 = R1-R1(NS) || R1 = [P0++];
                            // clear R7 and fetch code register C 
    R2.L = -1;                               
    R7.L = 0X8000;                     
    R0 = R1+R0(NS) || R3 = [P0--];
                            // temp=C + A, fetch CT 
    R1 = R1|R2;             // set as many lower bits of C to 1
    CC = R0<=R1;            // check if TEMP<=C
    R0 = 0;
    IF CC R0 = R7;
    R1 = R1-R0;             // if C register is too big remove leading bit
    R1 = LSHIFT R1 BY R3.L; // shift C  by CT
    [P0] = R1;              // store value of C
    R0 = P5;
    [--SP] = RETS;

    CALL __arith_enc_byteout;
                            // call byteout to store compressed data 
    R1 = [P5+4];            // get updated C
    R2 = [P5+8];            // fetch value of  CT
    R1 = LSHIFT R1 BY R2.L; // shift left C value by CT
    [P5+4] = R1;            // store C register
    R0 = P5;

    CALL __arith_enc_byteout;
                            // call byteout to store the compressed data 
    R0 = [P5+12];           // fetch B value
    P2 = [P5+20];           // Address of output buffer to store last byte
    R2 = 255;
    RETS = [SP++];
    (R7:7,P5:5) = [SP++];
    CC = R0==R2;            // check if B==0xff5
    IF !CC JUMP WRITE_BYTE; // if true discard the value
    RTS;

WRITE_BYTE:
    B[P2++] = R0;           // else store the last byte
    RTS;
    
__arith_enc_flush.end:    

/******************************************************************************
Prototype:   void arith_init(struct mq_enc*,unsigned char *);

In this routine A,C,CT,B registers are initialized. Interval register A  is 
initialized to 0x8000. Code register C and Byte register B are set to zero. 
Count register is set to 12.First_byte flag is set to one.

Registers Used  : R0-R3, P0.
*******************************************************************************/
.section                     program;
.global                 __arith_enc_init;
.align                             8;
    
__arith_enc_init:

    P0 = R0;                // Address of structure mq_enc
    R2.L = 0x8000;               
    R2.H = 0;
    R3 = 12;
    R0 = R1-R1(NS) || [P0++] = R2;
                            // Initialize A to 0X8000 
    [P0++] = R0;            // Initialize C reg. to 0
    [P0++] = R3;            // Initialize CT register to 12
    [P0++] = R0;            // Initialize B register to 0
    R0 = 1;
    [P0++] = R0;            // set first_byte flag to 1
    [P0++] = R1;            // store address of output buffer address
    RTS;
    NOP;

__arith_enc_init.end:        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -