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

📄 arith_encoder_jpeg2000.asm

📁 JPEG2000 ADI BLACKFIN 压缩解压程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
Copyright(c) 2000 - 2002 Analog Devices. All Rights Reserved.
Developed by Joint Development Software Application Team, IPDC, Bangalore, India
for Blackfin DSPs  ( Micro Signal Architecture 1.0 specification).

By using this module you agree to the terms of the Analog Devices License
Agreement for DSP Software. 
********************************************************************************
Module Name     : arith_encoder_JPEG2000.asm
Label Name      : __arith_encoder_JPEG2000
Version         :   2.0
Change History  :

                Version     Date          Author         Comments
                2.0	    01/09/2007    Arjun	        Tested with VDSP++4.5
							Compiler 7.2.3.2
		1.3         11/18/2002    Swarnalatha    Tested with VDSP++ 3.0
                                                         compiler 6.2.2 on 
                                                         ADSP-21535 Rev.0.2
                1.2         11/13/2002    Swarnalatha    Tested with VDSP++ 3.0
                                                         on ADSP-21535 Rev. 0.2
                1.1         03/20/2002    Raghavendra    Modified to match
                                                         silicon cycle count
                1.0         08/29/2001    Raghavendra    Original 

Description     : The  arithmetic coding works on the basis of recursive 
                  probability interval sub division. With each binary decision 
                  the current probability interval is subdivided into two sub 
                  intervals and  code string is modified so that it points to 
                  base of the probability sub interval. Sub-interval for most 
                  probable symbol(MPS) is ordered above the sub-interval for 
                  less probable interval(LPS). Therefore, when MPS coded, LPS 
                  sub-interval is added to code string.
                  Since the coding process involves addition of binary fractions
                  rather than concatenation of integer words, the more probable 
                  binary decisions are coded much less than one bit per 
                  decision. Decision (D) and Context (CX) are supplied to the 
                  encoder and compressed data are stored in output array. One 
                  block of data is processed at a time. Each block can have any 
                  number of D and CX pairs.

                  The  following structures are  used for arithmetic encoding. 
                  1.
                       struct  mq_enc
                         {
                           int A;              -> interval register 
                                                  (range:0,75 <=A<1,5)
                           int C;              -> code register
                           int CT;             -> bit counter register
                           int B;              -> byte value
                           int first_byte;     -> firstbyte flag
                           unsigned char *out; -> array where compressed data to
                                                  be stored
                          }enc_reg;

                 2. struct contexts
                    {
                       int index;       -> index to probability estimation table
                                           for a context
                       int mps;         -> MPS value for particular context.
                    } contexts[18];     -> array of context( 18 for JPEG 2000)
                 
              
                3. struct mqstates
                     {
                       int Qe;         -> value of probability of LPS
                       int NMPS;       -> Next index when MPS is coded
                       int NLPS;       -> Next index when LPS is coded
                       int SWITCH;     -> To change mps value when LPS is coded
                     }mqstates_s[47];

Assumptions : 1. mqstates_s[47] table and   struct  mq_enc variable are in 
                 different banks.  
              2. mqstates_s[47] is initialized with probability values as 
                 specified in Table C-2 of Annex-C, ISO/IEC FCD15444-1:2000
                 (V1.0,16 March 2000)
              3. Index and MPS values for each context is initialized before 
                 starting encoder.
              
Prototypes  : void  arith_encoder_JPEG2000(unsigned char D, unsigned char CX,
                           struct *mq_enc, struct * mqstates,struct * contexts);

              void  arith_enc_renorme(struct *mq_enc);

              void  arith_enc_byteout(struct *mq_enc);

              void  arith_enc_init(struct *mq_enc,unsigned char *arrayOut);

              void  arith_enc_flush(struct *mq_enc);

Calling sequence : Arith_enc_init function is called for initialization. 
              arith_encoder_JPEG2000 function is called for each context with a 
              decision bit. Finally arith_enc_flush function is called. 
              Following C code explains calling sequence.
                     
                  main() or func()
                   { 
                      int i;
                      struct enc_reg mq_enc;
                        :                                             
                        :
                        :
                        arith_enc_init(&mq_enc,&arrayOut[0]);
                      for(i=0;i<NUMBER_OF_CONTEXT;i++)
                      {
                        D=decision[i];
                        CX=context_input[i];
                        arith_encoder_JPEG2000(D,CX,struct *mq_enc, mqstates,
                                                                    contexts);
                      }
                        arith_enc_flush(struct *mq_enc);
                      :
                      :
                  }
                                   
Performance     :
                Code  Size   :  arith_encoder_JPEG2000       : 188 bytes
                                arith_enc_renorme  :  62 bytes
                                arith_enc_byteout  : 128 bytes
                                arith_enc_init     :  36 bytes
                                arith_enc_flush    : 102 bytes

                                                    Best case      Worst case  
                Cycle count  :  arith_encoder_JPEG2000  :  41        196 cycles
                                arith_enc_init          :  15         15 cycles
                                arith_enc_flush         :  127       127 cycles 

                 Cycle count mentioned is for a particular input sequence.
                 As the algorithm is data dependant, Cycle count may vary.

                 For e.g , Cycle count for 5760 input symbols which gives output
                 of 23 bytes is 288161(i.e 50.02 cycles per input symbol),
                
 Reference      :  Annex - C Arithmetic entropy encoding (JPEG-2000)
                   ISO/IEC FCD15444-1:2000(V1.0,16 March 2000)
 
*******************************************************************************/

/* When D and MPS of the context are equal, then input D is coded as MPS and 
otherwise coded as LPS symbol. The probability estimate of LPS, Qe is determined
by the index I stored for context CX. The upper interval is calculated, so that 
it can be compared with lower interval to confirm that Qe has smaller size. When
it is coded as LPS, it is followed by renormalization. If the switch flag for 
index I(CX) is set than mps is inverted. A new index I is saved at CX as 
determined by NLPS. When coded as MPS, size of the interval to the MPS sub-
interval is reduced and code register (C) is adjusted so that it points to base 
of the MPS interval. If the interval sizes are inverted, LPS subinterval is 
coded. This size inversion is always followed by renormalization. The 
probability estimate index I(CX) is updated as indicated by NMPS.

Registers Used  : R0-R7, I0, M0, M1, L0, P0-P2, P4, P5.
******************************************************************************/
.section              L1_code;
.global               __arith_encoder_JPEG2000;
.align                       8;
    
__arith_encoder_JPEG2000:

    [--SP]=(R7:5,P5:4);     // Push R7,P5
    R1 = R1 << 3;
    P4 = [SP+36];
                            // Multiplied by 8 to get present context value 
    
    P0 = R1;    
    L0 = 0;                   
    P5 = R2;                // Address of struct  mq_enc
    R3 = [SP+32];           // Address to struct mqstates
    I0 = R3;                       
    P4 = P4+P0;             // Modify P4 to get Index and MPS of current context
    R7 = [P4++];            // get index value
    R7 = R7 << 4; 
    
    M0 = R7;                      
    R3 = [P4--];
                            // multiply index by 16 to get Qe and fetch MPS(CX) 
    P1 = R2;                // Address of struct  mq_enc
    M1 = 8;
    CC = R0==R3;            // check if D==MPS(CX)
    I0+=M0;         // modify pointer to fetch Qe
    R7 = [I0++M1]  || R2 = [P5++];
                            // fetch Qe and  interval reg. A 
    R2 = R2-R7(NS) || R5 = [P5--];
                            // reduce interval by Qe (A-QE(I(CX)) and fetch 
                            //code reg.
    R2 = ABS R2;            // get abs value
    IF !CC JUMP CODELPS;    // if (D==MPS(CX))==0 code as LPS else code as MPS

/************    CODE MPS           ******************************************/
    CC = BITTST(R2,15);     // check if (A & 0x8000)==1
    IF CC JUMP ADD_C;       // if true add Qe to code reg. C
    R6 = R1 - R1(NS) || I0-= 4;
                            // clear R6 and modify I to fetch NMPS 
    CC = R2<R7;             // check if A<QE(I(CX))
    IF CC  R2 = R7;         // if true A=Qe(I(CX))
    IF !CC R6 = R7;         // else add Qe to C
    R5 = R5+R6(NS) || R0 = [I0] || [P5++] = R2;
                            // fetch NMPS and store A reg. 
    [P5++] = R5;            // store C reg.
    [P4++] = R0;            // store NMPS
    R0 = P1;                // Address of struct mq_enc to renorme function
    [--SP] = RETS;

    CALL __arith_enc_renorme;         
    RETS = [SP++];
    (R7:5,P5:4) = [SP++];
    RTS;

ADD_C:
    R5 = R5+R7(NS) || [P5++] = R2;
                            // add Qe value to C and store A reg. 
    [P5++] = R5;            // store C reg
    (R7:5,P5:4) = [SP++];   // Pop R7,P5
    RTS;
/***************    CODE LPS    ***************************************/
CODELPS:
    R6 = R1-R1(NS) || R0 = [I0++];
                            // fetch code reg. NLPS and clear R6 
    CC = R2<R7;             // check if A<QE(I(CX))
    IF CC R6 = R7;          // if true add Qe to C
    IF !CC R2 = R7;         // if false  A=QE(I(CX))
    R5 = R5 + R6(NS) || R1 = [I0];
                            // fetch switch flag 
    CC = R1 == 1;           // check if switch is set
    R1 = CC;   
    [P4++] = R0;            // store NLPS value as next Index
    R0 = P1;                // address of structure mq_enc
    R3 = R3 - R1(NS) || [P5++] = R2;
                            // store interval reg. A 
    R3 = ABS R3 || [P5++] = R5;
                            // store code reg. C 
    [P4] = R3;              // store modified MPS value
    [--SP] = RETS;

    CALL __arith_enc_renorme;
    RETS = [SP++];
    (R7:5,P5:4) = [SP++];   // Pop R7,P5
    RTS;
    
__arith_encoder_JPEG2000.end:    

⌨️ 快捷键说明

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