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

📄 block_decoder.cpp

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
row_0_significant:            // Decode sign bit            sym = cword & ((CHI_BIT>>3) | (SIGMA_CC_BIT>>3) |                           (CHI_BIT<<3) | (SIGMA_CC_BIT<<3));            sym >>= 1; // Shift down so that top sigma bit has address 0            sym |= (cp[-1] & ((CHI_BIT<<0) | (SIGMA_CC_BIT<<0))) >> (1+1);            sym |= (cp[ 1] & ((CHI_BIT<<0) | (SIGMA_CC_BIT<<0))) >> (1-1);            sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma            val = sign_lut[sym & 0x000000FF];            state_ref = states + KAPPA_SIGN_BASE + (val>>1);            _mq_dec_(coder,sym,*state_ref);            sym ^= (val & 1); // Sign bit recovered in LSB.            // Broadcast neighbourhood context changes            if (!causal)              {                cp[-context_row_gap-1] |=(SIGMA_BR_BIT<<9);                cp[-context_row_gap  ] |=(SIGMA_BC_BIT<<9)|(sym<<NEXT_CHI_POS);                cp[-context_row_gap+1] |=(SIGMA_BL_BIT<<9);              }            cp[-1] |= (SIGMA_CR_BIT<<0);            cp[1]  |= (SIGMA_CL_BIT<<0);            cword |= (SIGMA_CC_BIT<<0) | (sym<<CHI_POS);            sp[0] = (sym<<31) + one_point_five;          }row_1:        if (!(cword & (CLEANUP_MEMBER_MASK<<3)))          { // Process second row of stripe column (row 1)            state_ref = states+KAPPA_SIG_BASE+sig_lut[(cword>>3) & NBRHD_MASK];            _mq_dec_(coder,sym,*state_ref);            if (!sym)              goto row_2;row_1_significant:            // Decode sign bit            sym = cword & ((CHI_BIT<<0) | (SIGMA_CC_BIT<<0) |                           (CHI_BIT<<6) | (SIGMA_CC_BIT<<6));            sym >>= 4; // Shift down so that top sigma bit has address 0            sym |= (cp[-1] & ((CHI_BIT<<3) | (SIGMA_CC_BIT<<3))) >> (4+1);            sym |= (cp[ 1] & ((CHI_BIT<<3) | (SIGMA_CC_BIT<<3))) >> (4-1);            sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma            val = sign_lut[sym & 0x000000FF];            state_ref = states + KAPPA_SIGN_BASE + (val>>1);            _mq_dec_(coder,sym,*state_ref);            sym ^= (val & 1); // Sign bit recovered in LSB.            // Broadcast neighbourhood context changes            cp[-1] |= (SIGMA_CR_BIT<<3);            cp[1]  |= (SIGMA_CL_BIT<<3);            cword |= (SIGMA_CC_BIT<<3) | (sym<<(CHI_POS+3));            sp[width] = (sym<<31) + one_point_five;          }row_2:        if (!(cword & (CLEANUP_MEMBER_MASK<<6)))          { // Process third row of stripe column (row 2)            state_ref = states+KAPPA_SIG_BASE+sig_lut[(cword>>6) & NBRHD_MASK];            _mq_dec_(coder,sym,*state_ref);            if (!sym)              goto row_3;row_2_significant:            // Decode sign bit            sym = cword & ((CHI_BIT<<3) | (SIGMA_CC_BIT<<3) |                           (CHI_BIT<<9) | (SIGMA_CC_BIT<<9));            sym >>= 7; // Shift down so that top sigma bit has address 0            sym |= (cp[-1] & ((CHI_BIT<<6) | (SIGMA_CC_BIT<<6))) >> (7+1);            sym |= (cp[ 1] & ((CHI_BIT<<6) | (SIGMA_CC_BIT<<6))) >> (7-1);            sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma            val = sign_lut[sym & 0x000000FF];            state_ref = states + KAPPA_SIGN_BASE + (val>>1);            _mq_dec_(coder,sym,*state_ref);            sym ^= (val & 1); // Sign bit recovered in LSB.            // Broadcast neighbourhood context changes            cp[-1] |= (SIGMA_CR_BIT<<6);            cp[1]  |= (SIGMA_CL_BIT<<6);            cword |= (SIGMA_CC_BIT<<6) | (sym << (CHI_POS+6));            sp[width_by2] = (sym<<31) + one_point_five;          }row_3:        if (!(cword & (CLEANUP_MEMBER_MASK<<9)))          { // Process fourth row of stripe column (row 3)            state_ref = states+KAPPA_SIG_BASE+sig_lut[(cword>>9) & NBRHD_MASK];            _mq_dec_(coder,sym,*state_ref);            if (!sym)              goto done;row_3_significant:            // Decode sign bit            sym = cword & ((CHI_BIT<<6) | (SIGMA_CC_BIT<<6) |                                0       | (SIGMA_CC_BIT<<12));            sym >>= 10; // Shift down so that top sigma bit has address 0            if (cword < 0) // Use the fact that NEXT_CHI_BIT = 31              sym |= CHI_BIT<<(12-10);            sym |= (cp[-1] & ((CHI_BIT<<9) | (SIGMA_CC_BIT<<9))) >> (10+1);            sym |= (cp[ 1] & ((CHI_BIT<<9) | (SIGMA_CC_BIT<<9))) >> (10-1);            sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma            val = sign_lut[sym & 0x000000FF];            state_ref = states + KAPPA_SIGN_BASE + (val>>1);            _mq_dec_(coder,sym,*state_ref);            sym ^= (val & 1); // Sign bit recovered in LSB.            // Broadcast neighbourhood context changes            cp[context_row_gap-1] |= SIGMA_TR_BIT;            cp[context_row_gap  ] |= SIGMA_TC_BIT | (sym<<PREV_CHI_POS);            cp[context_row_gap+1] |= SIGMA_TL_BIT;            cp[-1] |= (SIGMA_CR_BIT<<9);            cp[1]  |= (SIGMA_CL_BIT<<9);            cword |= (SIGMA_CC_BIT<<9) | (sym<<(CHI_POS+9));            sp[width_by3] = (sym<<31) + one_point_five;          }done:        cword |= (cword << (MU_POS - SIGMA_CC_POS)) &                 ((MU_BIT<<0)|(MU_BIT<<3)|(MU_BIT<<6)|(MU_BIT<<9));        cword &= ~((PI_BIT<<0)|(PI_BIT<<3)|(PI_BIT<<6)|(PI_BIT<<9));        *cp = cword;      }  states[KAPPA_RUN_BASE] = run_state;  _mq_check_in_(coder);}/* ========================================================================= *//*                             kdu_block_decoder                             *//* ========================================================================= *//*****************************************************************************//*                   kdu_block_decoder::kdu_block_decoder                    *//*****************************************************************************/kdu_block_decoder::kdu_block_decoder(){  state = new kd_block_decoder;}/* ========================================================================= *//*                             kd_block_decoder                              *//* ========================================================================= *//*****************************************************************************//*                         kd_block_decoder::decode                          *//*****************************************************************************/void  kd_block_decoder::decode(kdu_block *block){  // Get dimensions.  int num_cols = block->size.x;  int num_rows = block->size.y;  int num_stripes = (num_rows+3)>>2;  int num_samples = (num_stripes<<2)*num_cols;  int context_row_gap = num_cols + EXTRA_DECODE_CWORDS;  int num_context_words = (num_stripes+2)*context_row_gap+1;    // Prepare enough storage.  if (block->max_samples < num_samples)    block->set_max_samples((num_samples > 4096)?num_samples:4096);  if (block->max_contexts < num_context_words)    block->set_max_contexts((num_context_words > 1600)?num_context_words:1600);  // Start timing loop here, if there is any need for one.  int cpu_counter = block->start_timing();  bool error_found;  do {      error_found = false;      // Initialize sample and context word contents      kdu_int32 *samples = block->sample_buffer;      memset(samples,0,(size_t)(num_samples<<2));      kdu_int32 *context_words = block->context_buffer + context_row_gap + 1;      memset(context_words-1,0,(size_t)((num_stripes*context_row_gap+1)<<2));      if (num_rows & 3)        {          kdu_int32 oob_marker;          if ((num_rows & 3) == 1) // Last 3 rows of last stripe unoccupied            oob_marker = (OOB_MARKER<<3) | (OOB_MARKER<<6) | (OOB_MARKER<<9);          else if ((num_rows & 3) == 2) // Last 2 rows of last stripe are empty            oob_marker = (OOB_MARKER << 6) | (OOB_MARKER << 9);          else            oob_marker = (OOB_MARKER << 9);          kdu_int32 *cp = context_words + (num_stripes-1)*context_row_gap;          for (int k=num_cols; k > 0; k--)            *(cp++) = oob_marker;        }      if (context_row_gap > num_cols)        { // Initialize the extra context words between lines to OOB          kdu_int32 oob_marker =            OOB_MARKER | (OOB_MARKER<<3) | (OOB_MARKER<<6) | (OOB_MARKER<<9);          assert(context_row_gap >= (num_cols+3));          kdu_int32 *cp = context_words + num_cols;          for (int k=num_stripes; k > 0; k--, cp+=context_row_gap)            cp[0] = cp[1] = cp[2] = oob_marker; // Need 3 OOB words after line        }      // Determine which passes we can decode and where to put them.      int p_max = 30 - block->missing_msbs; // Index of most significant plane      int num_passes = 3*p_max-2; // 1 plane for dequantization signalling      if (num_passes > block->num_passes)        num_passes = block->num_passes;      // Now decode the passes one by one.      int p = p_max; // Bit-plane counter      int z = 0; // Coding pass index      int k=2; // Coding pass category; start with cleanup pass      int segment_start_z;      int segment_passes = 0; // Num coding passes in current codeword segment.      bool segment_truncated = false;      int segment_bytes = 0;      kdu_byte *buf = block->byte_buffer;      bool bypass = false;      bool causal = (block->modes & Cmodes_CAUSAL) != 0;      bool er_check = (block->modes & Cmodes_ERTERM) &&                      (block->fussy || block->resilient);      for (; z < num_passes; z++, k++)        {          if (k == 3)            { k=0; p--; } // Move on to next bit-plane.          if (segment_passes == 0)            { // Need to start a new codeword segment.              segment_start_z = z;              segment_passes = 3*(block->K_max_prime-block->missing_msbs) - 2;              if (block->modes & Cmodes_BYPASS)                {                  if (z < 10)                    segment_passes = 10-z;                  else if (k == 2) // Cleanup pass.                    { segment_passes = 1; bypass = false; }                  else                    {                      segment_passes = 2;                      bypass = true;                    }                }              if (block->modes & Cmodes_RESTART)                segment_passes = 1;              segment_truncated = false;              if ((z+segment_passes) > num_passes)                {                  segment_truncated = true;                  segment_passes = num_passes - z;                }              segment_bytes = 0;              for (int n=0; n < segment_passes; n++)                segment_bytes += block->pass_lengths[z+n];              coder.start(buf,segment_bytes,!bypass);              buf += segment_bytes;            }          if ((z == 0) || (block->modes & Cmodes_RESET))            reset_states();#ifdef KDU_ASM_OPTIMIZATIONS          if (mmx_exists)            { // Invoke highly optimized machine-specific forms where available              if ((k == 0) && !bypass)                asm_decode_sig_prop_pass(coder,states,p,causal,                          block->orientation,samples,context_words,                          num_cols,num_stripes,context_row_gap);              else if (k == 0)                decode_sig_prop_pass_raw(coder,p,causal,samples,                          context_words,num_cols,num_stripes,context_row_gap);              else if ((k == 1) && !bypass)                asm_decode_mag_ref_pass(coder,states,p,causal,samples,                          context_words,num_cols,num_stripes,context_row_gap);              else if (k == 1)                decode_mag_ref_pass_raw(coder,p,causal,samples,                          context_words,num_cols,num_stripes,context_row_gap);              else                asm_decode_cleanup_pass(coder,states,p,causal,                          block->orientation,samples,context_words,                          num_cols,num_stripes,context_row_gap);            }          else#endif // KDU_ASM_OPTIMIZATIONS          if ((k == 0) && !bypass)            decode_sig_prop_pass(coder,states,p,causal,                          block->orientation,samples,context_words,                          num_cols,num_stripes,context_row_gap);          else if (k == 0)            decode_sig_prop_pass_raw(coder,p,causal,samples,                          context_words,num_cols,num_stripes,context_row_gap);          else if ((k == 1) && !bypass)            decode_mag_ref_pass(coder,states,p,causal,samples,                          context_words,num_cols,num_stripes,context_row_gap);          else if (k == 1)            decode_mag_ref_pass_raw(coder,p,causal,samples,                          context_words,num_cols,num_stripes,context_row_gap);          else            decode_cleanup_pass(coder,states,p,causal,                          block->orientation,samples,context_words,                          num_cols,num_stripes,context_row_gap);          if ((block->modes & Cmodes_SEGMARK) && (k==2))            {              kdu_int32 run, segmark;              coder.mq_decode_run(run); segmark = run<<2;              coder.mq_decode_run(run); segmark += run;              if ((segmark != 0x0A) && (block->fussy || block->resilient))                { // Segmark not detected correctly.                  error_found = true;                  block->num_passes = (z > 2)?(z-2):0;                  break;                }            }          segment_passes--;          if (segment_passes == 0)            {              if (!coder.finish(er_check && !segment_truncated))                { // Error has been detected in the current codeword segment.                  error_found = true;                  block->num_passes = segment_start_z;                  break;                }            }        }      if (error_found)        {          if (block->fussy)            { kdu_error e; e << "Encountered incorrectly terminated codeword "              "segment, or invalid SEGMARK symbol in code-block bit-stream.  "              "You may like to use the \"resilient\" mode to recover from "              "and conceal such errors."; }            else              { kdu_warning w; w << "Corrupted block bit-stream detected.\n"; }        }    } while (error_found || ((--cpu_counter) > 0));  block->finish_timing();}

⌨️ 快捷键说明

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