📄 arith_encoder_jpeg2000.asm
字号:
/*******************************************************************************
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 + -