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

📄 msvc_block_decode_asm.h

📁 JPEG2000的C++实现代码
💻 H
📖 第 1 页 / 共 5 页
字号:
    __asm ADD ESI,EDX /* Add D to A */                                       \    __asm ADD ECX,EDX /* Add D to C */                                       \    __asm JL run_bit0_Clt0                                                   \      /* Upper sub-interval selected */                                      \      __asm CMP ESI,0x00560100                                               \      __asm JGE run_bit0_renorm                                              \      __asm ADD EAX,1                                                        \      __asm JMP run_bit0_renorm                                              \    __asm run_bit0_Clt0:                                                     \      /* Lower sub-interval selected */                                      \      __asm ADD ECX,0x00560100                                               \      __asm CMP ESI,0x00560100                                               \      __asm MOV ESI,0x00560100                                               \      __asm JL run_bit0_renorm                                               \      __asm ADD EAX,1                                                        \    __asm run_bit0_renorm:                                                   \    /* At this point, EBX holds A, ECX holds C and EDX and ESI are free */   \    __asm MOV EBX,t_var                                                      \    __asm run_bit0_renorm_once:                                              \      /* Come back here repeatedly until we have shifted enough bits out. */ \      __asm TEST EBX,EBX                                                     \      __asm JNZ run_bit0_have_more_bits                                      \        /* Begin `fill_lsbs' procedure */                                    \          __asm MOV EDX,temp_var                                             \          __asm CMP EDX,0xFF                                                 \          __asm JNZ run_bit0_no_ff                                           \            __asm MOV EBX,store_var                                          \            __asm MOVZX EDX,byte ptr [EBX] /* New `temp' in EDX */           \            __asm CMP EDX,0x8F                                               \            __asm JLE run_bit0_temp_le8F                                     \              /* Reached a termination marker.  Don't update `store_var' */  \              __asm MOV EDX,0xFF                                             \              __asm MOV EBX,S_var                                            \              __asm ADD EBX,1                                                \              __asm MOV S_var,EBX                                            \              __asm MOV EBX,8 /* New value of t */                           \              __asm JMP run_bit0_complete_fill_lsbs                          \            __asm run_bit0_temp_le8F:                                        \            /* No termination marker, but bit stuff required */              \              __asm ADD ECX,EDX /* Add `temp' once; another later */         \              __asm ADD EBX,1                                                \              __asm MOV store_var,EBX /* Increments the `store' pointer */   \              __asm MOV EBX,7 /* New value of t. */                          \              __asm JMP run_bit0_complete_fill_lsbs                          \          __asm run_bit0_no_ff:                                              \            __asm MOV EBX,store_var                                          \            __asm MOVZX EDX,byte ptr [EBX] /* New `temp' in EDX */           \            __asm ADD EBX,1                                                  \            __asm MOV store_var,EBX /* Increments the `store' pointer */     \            __asm MOV EBX,8 /* New value of t. */                            \          __asm run_bit0_complete_fill_lsbs:                                 \          __asm ADD ECX,EDX /* Add `temp' to C */                            \          __asm MOV temp_var,EDX /* Save `temp' */                           \      /* End `fill_lsbs' procedure */                                        \      __asm run_bit0_have_more_bits:                                         \      __asm ADD ESI,ESI /* Shift A register left */                          \      __asm ADD ECX,ECX /* Shift C register left */                          \      __asm SUB EBX,1   /* Decrement t */                                    \      __asm TEST ESI,0x00800000 /* Compare with MQD_A_MIN (test bit 23) */   \      __asm JZ run_bit0_renorm_once                                          \    __asm MOV t_var,EBX /* Save t */                                         \    /* Renormalization is complete.  Recompute D and save A and C. */        \    __asm MOV EDX,ESI /* Load EDX with A */                                  \    __asm SUB EDX,0x00800000 /* Subtract MQD_A_MIN */                        \    __asm CMP ECX,EDX                                                        \    __asm CMOVL EDX,ECX /* Move C to EDX if C < A-MQD_A_MIN */               \    __asm SUB ESI,EDX                                                        \    __asm SUB ECX,EDX                                                        \  __asm run_finished:                                                        \  __asm MOV C_var,ECX/* ========================================================================= *//*                            Coding Pass Functions                          *//* ========================================================================= *//*****************************************************************************//* STATIC                    asm_decode_sig_prop_pass                        *//*****************************************************************************/static void  asm_decode_sig_prop_pass(mq_decoder &coder, mqd_state states[],                           int p, bool causal, int orientation,                           kdu_int32 *samples, kdu_int32 *contexts,                           int width, int num_stripes, int context_row_gap){  if ((num_stripes <= 0) || (width <= 0))    return;  kdu_int32 A_var, C_var, D_var, t_var, temp_var;  kdu_byte *store_var;  int S_var;  coder.check_out(A_var,C_var,D_var,t_var,temp_var,store_var,S_var);  kdu_byte *sig_lut = significance_luts[orientation];  kdu_int32 one_point_five = 1<<p; one_point_five += (one_point_five>>1);  int is_causal = (causal)?1:0;  context_row_gap <<= 2; // Convert to number of bytes  width <<= 2; // Convert to number of bytes    /* The following offsets are used to convert a context word pointer       to a sample pointer.  The offsets are correct for the first       stripe and must be adjusted from stripe to stripe by the addition       of 3*width-EXTRA_DECODE_CWORDS. */  int cp_to_sp0 = ((int) samples)-((int) contexts); // Offset for row 0  int cp_to_sp1 = cp_to_sp0+width; // Offset for row 1  int cp_to_sp2 = cp_to_sp1+width; // Offset for row 2  int cp_to_sp3 = cp_to_sp2+width; // Offset for row 3  int cp_to_sp_adjust = 3*width-4*EXTRA_DECODE_CWORDS;  kdu_int32 *stripe_end; // Points to context word beyond end of current stripe  __asm {    MOV EDI,contexts // Set EDI aside to hold the context word pointer    MOV EDX,D_var // Set EDX aside to hold the critical MQ variable, D    MOV ESI,A_var // Set ESI aside to hold the MQ coder's A registernext_stripe:    MOV EAX,width    ADD EAX,EDI    MOV stripe_end,EAX // Set end pointer for this stripenext_stripe_column:    MOV ECX,[EDI]    TEST ECX,ECX    JNZ row0speedup_loop:    // Invoke speedup trick to skip over runs of all-zero neighbourhoods    MOV ECX,[EDI+12]    ADD EDI,12    TEST ECX,ECX    JZ speedup_loop    SUB EDI,8    CMP EDI,stripe_end    JNZ next_stripe_column    JMP advance_striperow0:      // Test for coding pass membership      MOV EBX,ECX      AND EBX,__NBRHD_MASK*1      JZ row1      TEST ECX,__SIG_PROP_MEMBER_MASK*1      JNZ row1      OR ECX,__PI_BIT*1      MOV [EDI],ECX // Save context word indicating that sample belongs to pass      // Find pointer to the relevant context state record      AND ECX,__NBRHD_MASK      ADD ECX,sig_lut      MOVZX ECX,byte ptr [ECX]      MOV EBX,states      LEA ECX,[EBX+8*ECX]      // decode symbol      MOV EAX,[ECX] // Get `p_bar_mps' to EAX      SUB EDX,EAX      AND EAX,1 // Get MPS identity in LSB of EAX      ADD EDX,EAX // Correct for the effect of the MPS      JGE significance_test0      CALL mq_non_cdpsignificance_test0:      MOV ECX,[EDI] // Get context word back again      TEST EAX,EAX // If symbol != 0      JZ row1      // If we get here, we know that stripe row 0 is newly significant      AND ECX,__CHI_BIT/8+__SIGMA_CC_BIT/8+__CHI_BIT*8+__SIGMA_CC_BIT*8      SHR ECX,1      MOV EAX,[EDI-4] // Get context word on left      AND EAX,__CHI_BIT+__SIGMA_CC_BIT      SHR EAX,2      ADD ECX,EAX      MOV EAX,[EDI+4] // Get context word on right      AND EAX,__CHI_BIT+__SIGMA_CC_BIT      ADD ECX,EAX      MOV EAX,ECX      SHR EAX,CHI_POS-1-SIGMA_CC_POS      OR ECX,EAX      AND ECX,0x000000FF      MOVZX ECX,byte ptr [sign_lut+ECX]      MOV EAX,ECX // Save the sign LUT result in EAX      SHR ECX,1 // Get context label part of the LUT result      MOV EBX,states      LEA ECX,[EBX+8*ECX+8*KAPPA_SIGN_BASE] // ECX has pointer to context state      MOV EBX,[ECX] // Get `p_bar_mps' to EBX      XOR EAX,EBX      AND EAX,1 // Leaves EAX with the MPS sign value in its LSB.      BTR EBX,0 // Leaves `p_bar' in EBX      SUB EDX,EBX      JGE row0_broadcast      CALL mq_non_cdprow0_broadcast: // Process newly significant sample; sign is in LSB of EAX      // Broadcast significance and sign to last row of previous stripe      MOV EBX,is_causal      TEST EBX,EBX      JNZ row0_skip_non_causal      MOV EBX,EDI      SUB EBX,context_row_gap      MOV ECX,[EBX-4]      OR ECX,__SIGMA_BR_BIT*512      MOV [EBX-4],ECX      MOV ECX,EAX      SHL ECX,NEXT_CHI_POS      OR ECX,[EBX]      OR ECX,__SIGMA_BC_BIT*512      MOV [EBX],ECX      MOV ECX,[EBX+4]      OR ECX,__SIGMA_BL_BIT*512      MOV [EBX+4],ECXrow0_skip_non_causal:      // Broadcast significance to left and right neighbours      MOV ECX,[EDI-4]      OR ECX,__SIGMA_CR_BIT*1      MOV [EDI-4],ECX      MOV ECX,[EDI+4]      OR ECX,__SIGMA_CL_BIT*1      MOV [EDI+4],ECX      // Recover and update context word, using ECX register      MOV ECX,EAX      SHL ECX,CHI_POS      OR ECX,[EDI]      OR ECX,__SIGMA_CC_BIT*1      MOV [EDI],ECX      // Write newly significant sample value      SHL EAX,31 // Get sign bit of result into right position      ADD EAX,one_point_five      MOV EBX,cp_to_sp0      MOV [EDI+EBX],EAXrow1:      // Test for coding pass membership      MOV EBX,ECX      AND EBX,__NBRHD_MASK*8      JZ row2      TEST ECX,__SIG_PROP_MEMBER_MASK*8      JNZ row2      OR ECX,__PI_BIT*8      MOV [EDI],ECX // Save context word indicating that sample belongs to pass      // Find pointer to the relevant context state record      SHR ECX,3      AND ECX,__NBRHD_MASK      ADD ECX,sig_lut      MOVZX ECX,byte ptr [ECX]      MOV EBX,states      LEA ECX,[EBX+8*ECX]      // Decode symbol      MOV EAX,[ECX] // Get `p_bar_mps' to EAX      SUB EDX,EAX      AND EAX,1 // Get MPS identity in LSB of EAX      ADD EDX,EAX // Correct for the effect of the MPS      JGE significance_test1      CALL mq_non_cdpsignificance_test1:      MOV ECX,[EDI] // Get context word back again      TEST EAX,EAX // If symbol != 0      JZ row2      // If we get here, we know that stripe row 1 is newly significant      AND ECX,__CHI_BIT+__SIGMA_CC_BIT+__CHI_BIT*64+__SIGMA_CC_BIT*64      SHR ECX,4      MOV EAX,[EDI-4] // Get context word on left      AND EAX,__CHI_BIT*8+__SIGMA_CC_BIT*8      SHR EAX,5      ADD ECX,EAX      MOV EAX,[EDI+4] // Get context word on right      AND EAX,__CHI_BIT*8+__SIGMA_CC_BIT*8      SHR EAX,3      ADD ECX,EAX      MOV EAX,ECX      SHR EAX,CHI_POS-1-SIGMA_CC_POS      OR ECX,EAX      AND ECX,0x000000FF      MOVZX ECX,byte ptr [sign_lut+ECX]      MOV EAX,ECX // Save the sign LUT result in EAX      SHR ECX,1 // Get context label part of the LUT result      MOV EBX,states      LEA ECX,[EBX+8*ECX+8*KAPPA_SIGN_BASE] // ECX has pointer to context state      MOV EBX,[ECX] // Get `p_bar_mps' to EBX      XOR EAX,EBX      AND EAX,1 // Leaves EAX with the MPS sign value in its LSB.      BTR EBX,0 // Leaves `p_bar' in EBX      SUB EDX,EBX      JGE row1_broadcast      CALL mq_non_cdprow1_broadcast: // Process newly significant sample; sign is in LSB of EAX      // Broadcast significance to left and right neighbours      MOV ECX,[EDI-4]      OR ECX,__SIGMA_CR_BIT*8      MOV [EDI-4],ECX      MOV ECX,[EDI+4]      OR ECX,__SIGMA_CL_BIT*8      MOV [EDI+4],ECX      // Recover and update context word, using ECX register      MOV ECX,EAX      SHL ECX,CHI_POS+3      OR ECX,[EDI]      OR ECX,__SIGMA_CC_BIT*8      MOV [EDI],ECX      // Write new significant sample value      SHL EAX,31 // Get sign bit of result into right position      ADD EAX,one_point_five

⌨️ 快捷键说明

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