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

📄 msvc_block_decode_asm.h

📁 JPEG2000的C++实现代码
💻 H
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************/// File: msvc_block_decode_asm.h [scope = CORESYS/CODING]// Version: Kakadu, V2.2// Author: David Taubman// Last Revised: 20 June, 2001/*****************************************************************************/// Copyright 2001, David Taubman, The University of New South Wales (UNSW)// The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW)// Neither this copyright statement, nor the licensing details below// may be removed from this file or dissociated from its contents./*****************************************************************************/// Licensee: Book Owner// License number: 99999// The Licensee has been granted a NON-COMMERCIAL license to the contents of// this source file, said Licensee being the owner of a copy of the book,// "JPEG2000: Image Compression Fundamentals, Standards and Practice," by// Taubman and Marcellin (Kluwer Academic Publishers, 2001).  A brief summary// of the license appears below.  This summary is not to be relied upon in// preference to the full text of the license agreement, which was accepted// upon breaking the seal of the compact disc accompanying the above-mentioned// book.// 1. The Licensee has the right to Non-Commercial Use of the Kakadu software,//    Version 2.2, including distribution of one or more Applications built//    using the software, provided such distribution is not for financial//    return.// 2. The Licensee has the right to personal use of the Kakadu software,//    Version 2.2.// 3. The Licensee has the right to distribute Reusable Code (including//    source code and dynamically or statically linked libraries) to a Third//    Party, provided the Third Party possesses a license to use the Kakadu//    software, Version 2.2, and provided such distribution is not for//    financial return./******************************************************************************Description:   Provides implementations of the principle block decoding pass functions(significance propagation, magnitude refinement and cleanup) for the X86 familyof processors.  The assembly code should work on any member of the Intel X86family which provides support for MMX (the test for MMX might fail on CPU'smore ancient than the 80486).  The couple of places where MMX instructions areused here could easily be eliminated if necessary.  The code is fairly heavilyoptimized, although there may be innovative ways to squeeze a few more percentout of the throughput.  Interestingly, a decent optimizing C++ compiler canget within about 80% of the speed of these functions when compiling thecarefully optimized machine independent versions in "block_decoder.cpp".  Oneadvantage of the versions given here is that the code size is reduced bya factor of more than 2, which may improve L1 cache utilization.   For other processors, the assembly code here may still prove useful asa guide.  In particular, it provides a rough indication of the number ofinstructions which are required and suggests appropriate register assignments.Here, we use only the 6 truly general purpose registers left over by the X86family, which is rather limiting.******************************************************************************/#ifndef MSVC_BLOCK_DECODE_ASM_H#define MSVC_BLOCK_DECODE_ASM_H/* ========================================================================= *//*                            Test for MMX Support                           *//* ========================================================================= *//*****************************************************************************//* STATIC                   msvc_decoder_mmx_exists                          *//*****************************************************************************/static int msvc_decoder_mmx_exists()  {    int mmx_exists = 1;    __asm      {        MOV EAX,1        CPUID        TEST EDX,00800000h        JNZ mmx_exists_label        MOV mmx_exists,0mmx_exists_label:      }    return mmx_exists;  }/* ========================================================================= *//*                   Assembler Optimized MQ Decoding Macros                  *//* ========================================================================= *//*****************************************************************************//* __ASM                     ASM_MQ_NON_CDP_DECODE                           *//*****************************************************************************/  /* This macro contains code which implements non-CDP (not Common Decode     Path) MQ symbol decoding steps.  It may be included directly wherever     the steps are required or else it may be included inside a fast-call     function.        The internal MQ state variables manipulated here are expected to reside     in registers or on the stack (referenced via the EBP register).  The     relevant stack variables have the names C_var, D_var, t_var, temp_var     and store_var.        On entry, register EAX contains the symbol value associated with MPS     decoding.  The function should not load this value directly, but simply     flip the bit if the symbol turns out to be an LPS.  ECX contains the     address of the context state entry which is being manipulated.  EDX and     ESI contain the current values of D_var and A_var, respectively.     The EBX register is undefined and may be used without risk of corrupting     anything else.        On exit, register EAX should contain the symbol value associated     with MPS decoding.  Note that this symbol must be equal to the entry value     of EAX if an MPS was decoded (regardless of whether this agrees with     the MPS value stored at [ECX].  There is no need to preserve the original     value of ECX. */#define ASM_MQ_NON_CDP_DECODE                                                \  __asm MOV EBX,[ECX] /* Get 'p_bar_mps' to EBX */                           \  __asm ADD ESI,EDX /* Add D to the value of A, stored in ESI */             \  __asm BTR EBX,0 /* Discard MPS, leaving just 'p_bar'. */                   \  __asm ADD EDX,C_var /* Get C+D to EDX */                                   \  __asm JL non_cdp_Clt0                                                      \    /* Upper sub-interval selected */                                        \      __asm CMP ESI,EBX /* Compare A with p_bar */                           \      __asm JGE non_cdp_Cge0_AgeP                                            \        /* Conditional exchange; LPS is decoded. */                          \          __asm XOR EAX,1                                                    \          __asm MOV EBX,[ECX+4] /* Get pointer to `state->transition' */     \          __asm MOVQ MM0,[EBX+8] /* Load `state->transition->lps' */         \          __asm MOVQ [ECX],MM0 /* Save back to *state */                     \          __asm JMP non_cdp_renorm                                           \      __asm non_cdp_Cge0_AgeP:                                               \        /* MPS is decoded. */                                                \          __asm MOV EBX,[ECX+4] /* Get pointer to `state->transition' */     \          __asm MOVQ MM0,[EBX] /* Load `state->transition->mps' */           \          __asm MOVQ [ECX],MM0 /* Save back to *state */                     \          __asm JMP non_cdp_renorm                                           \  __asm non_cdp_Clt0:                                                        \    /* Lower sub-interval selected */                                        \      __asm ADD EDX,EBX /* Add `p_bar' to C in EDX */                        \      __asm CMP ESI,EBX /* Compare A with p_bar */                           \      __asm MOV ESI,EBX /* Move `p_bar' into `A' */                          \      __asm JGE non_cdp_Clt0_AgeP                                            \        /* Conditional exchange; MPS is decoded */                           \          __asm MOV EBX,[ECX+4] /* Get pointer to `state->transition' */     \          __asm MOVQ MM0,[EBX] /* Load `state->transition->mps' */           \          __asm MOVQ [ECX],MM0 /* Save back to *state */                     \          __asm JMP non_cdp_renorm                                           \      __asm non_cdp_Clt0_AgeP:                                               \        /* LPS is decoded. */                                                \          __asm XOR EAX,1                                                    \          __asm MOV EBX,[ECX+4] /* Get pointer to `state->transition' */     \          __asm MOVQ MM0,[EBX+8] /* Load `state->transition->lps' */         \          __asm MOVQ [ECX],MM0 /* Save back to *state */                     \  __asm non_cdp_renorm:                                                      \  /* At this point, ESI holds A, EDX holds C and ECX and EBX are free */     \  __asm MOV EBX,t_var                                                        \  __asm non_cdp_renorm_once:                                                 \    /* Come back here repeatedly until we have shifted enough bits out. */   \      __asm TEST EBX,EBX                                                     \      __asm JNZ non_cdp_have_more_bits                                       \        /* Begin `fill_lsbs' procedure */                                    \          __asm MOV ECX,temp_var                                             \          __asm CMP ECX,0xFF                                                 \          __asm JNZ non_cdp_no_ff                                            \            __asm MOV EBX,store_var                                          \            __asm MOVZX ECX,byte ptr [EBX] /* New `temp' in ECX */           \            __asm CMP ECX,0x8F                                               \            __asm JLE non_cdp_temp_le8F                                      \              /* Reached a termination marker.  Don't update `store_var' */  \              __asm MOV ECX,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 non_cdp_complete_fill_lsbs                           \            __asm non_cdp_temp_le8F:                                         \            /* No termination marker, but bit stuff required */              \              __asm ADD EDX,ECX /* 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 non_cdp_complete_fill_lsbs                           \          __asm non_cdp_no_ff:                                               \            __asm MOV EBX,store_var                                          \            __asm MOVZX ECX,byte ptr [EBX] /* New `temp' in ECX */           \            __asm ADD EBX,1                                                  \            __asm MOV store_var,EBX /* Increments the `store' pointer */     \            __asm MOV EBX,8 /* New value of t. */                            \          __asm non_cdp_complete_fill_lsbs:                                  \          __asm ADD EDX,ECX /* Add `temp' to C */                            \          __asm MOV temp_var,ECX /* Save `temp' */                           \      /* End `fill_lsbs' procedure */                                        \      __asm non_cdp_have_more_bits:                                          \      __asm ADD ESI,ESI /* Shift A register left */                          \      __asm ADD EDX,EDX /* Shift C register left */                          \      __asm SUB EBX,1   /* Decrement t */                                    \      __asm TEST ESI,0x00800000 /* Compare with MQD_A_MIN (test bit 23) */   \      __asm JZ non_cdp_renorm_once                                           \  __asm MOV t_var,EBX /* Save t */                                           \  /* Renormalization is complete.  Recompute D and save A and C. */          \  __asm MOV EBX,ESI /* Load EBX with A */                                    \  __asm SUB EBX,0x00800000 /* Subtract MQD_A_MIN */                          \  __asm CMP EDX,EBX /* Compare C with A-MQD_A_MIN */                         \  __asm CMOVL EBX,EDX /* Move C to ESI if C < A-MQD_A_MIN */                 \  __asm SUB ESI,EBX /* Subtract D from A */                                  \  __asm SUB EDX,EBX /* Subtract D from C */                                  \  __asm MOV C_var,EDX                                                        \  __asm MOV EDX,EBX /* Move D back into the EDX register */ /*****************************************************************************//* __ASM                       ASM_MQ_DECODE_RUN                             *//*****************************************************************************/  /* Similar to ASM_MQ_NON_CDP_DECODE, except that the full decoding is     performed, returning a 2-bit run length in EAX, and ECX is free to be     overwritten. */#define ASM_MQ_DECODE_RUN                                                    \  __asm XOR EAX,EAX                                                          \  __asm MOV ECX,C_var                                                        \  __asm SUB EDX,0x00560100                                                   \  __asm JGE run_bit0                                                         \    /* Non-CDP decoding for the first bit */                                 \    __asm ADD ESI,EDX /* Add D to A in ESI */                                \    __asm ADD ECX,EDX /* Add D to C in ECX */                                \    __asm JL run_bit1_Clt0                                                   \      /* Upper sub-interval selected */                                      \      __asm CMP ESI,0x00560100                                               \      __asm JGE run_bit1_renorm                                              \      __asm MOV EAX,2                                                        \      __asm JMP run_bit1_renorm                                              \    __asm run_bit1_Clt0:                                                     \      /* Lower sub-interval selected */                                      \      __asm ADD ECX,0x00560100                                               \      __asm CMP ESI,0x00560100                                               \      __asm MOV ESI,0x00560100                                               \      __asm JL run_bit1_renorm                                               \      __asm MOV EAX,2                                                        \    __asm run_bit1_renorm:                                                   \    /* At this point, EBX holds A, ECX holds C and EDX and ESI are free */   \    __asm MOV EBX,t_var                                                      \    __asm run_bit1_renorm_once:                                              \      /* Come back here repeatedly until we have shifted enough bits out. */ \      __asm TEST EBX,EBX                                                     \      __asm JNZ run_bit1_have_more_bits                                      \        /* Begin `fill_lsbs' procedure */                                    \          __asm MOV EDX,temp_var                                             \          __asm CMP EDX,0xFF                                                 \          __asm JNZ run_bit1_no_ff                                           \            __asm MOV EBX,store_var                                          \            __asm MOVZX EDX,byte ptr [EBX] /* New `temp' in EDX */           \            __asm CMP EDX,0x8F                                               \            __asm JLE run_bit1_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_bit1_complete_fill_lsbs                          \            __asm run_bit1_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_bit1_complete_fill_lsbs                          \          __asm run_bit1_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_bit1_complete_fill_lsbs:                                 \          __asm ADD ECX,EDX /* Add `temp' to C */                            \          __asm MOV temp_var,EDX /* Save `temp' */                           \      /* End `fill_lsbs' procedure */                                        \      __asm run_bit1_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_bit1_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 /* Subtract D from A */                                \    __asm SUB ECX,EDX /* Subtract D from C */                                \  /************************************************************************/ \  __asm run_bit0:                                                            \  __asm SUB EDX,0x00560100                                                   \  __asm JGE run_finished                                                     \    /* Non-CDP decoding for the second bit */                                \

⌨️ 快捷键说明

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