📄 encoder.cpp
字号:
assert((current_block_height > 0) && (block_indices.size.y > 0)); int offset=0; kdu_coords idx = block_indices.pos; int blocks_remaining = block_indices.size.x; kdu_coords xfer_size; kdu_block *block; kdu_uint16 estimated_slope_threshold = band.get_conservative_slope_threshold(); for (; blocks_remaining > 0; blocks_remaining--, idx.x++, offset+=xfer_size.x) { // Open the block and make sure we have enough sample buffer storage. block = band.open_block(idx); int num_stripes = (block->size.y+3) >> 2; int num_samples = (num_stripes<<2) * block->size.x; assert(num_samples > 0); if (block->max_samples < num_samples) block->set_max_samples((num_samples>4096)?num_samples:4096); /* Now quantize and transfer samples to the block, observing any required geometric transformations. */ xfer_size = block->size; assert((xfer_size.x == block->region.size.x) && (xfer_size.y == block->region.size.y) && (0 == block->region.pos.x) && (0 == block->region.pos.y)); if (block->transpose) xfer_size.transpose(); assert(xfer_size.y == current_block_height); assert((xfer_size.x+offset) <= subband_cols); int m, n; kdu_int32 *dp, *dpp = block->sample_buffer; int row_gap = block->size.x; int m_start = 0, m_inc = 1, n_start=offset, n_inc = 1; if (block->vflip) { m_start += xfer_size.y-1; m_inc = -1; } if (block->hflip) { n_start += xfer_size.x-1; n_inc = -1; } // First transfer the sample data if (lines32 != NULL) { // Working with 32-bit data types. kdu_sample32 *sp, **spp = lines32+m_start; if (reversible) { // Source data is 32-bit absolute integers. kdu_int32 val; kdu_int32 upshift = 31-K_max; if (upshift < 0) { kdu_error e; e << "Insufficient implementation " "precision available for true reversible compression!"; } if (!block->transpose) for (m=xfer_size.y; m--; spp+=m_inc, dpp+=row_gap) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp++, sp+=n_inc) { val = sp->ival; if (val < 0) *dp = ((-val)<<upshift) | KDU_INT32_MIN; else *dp = val<<upshift; } else for (m=xfer_size.y; m--; spp+=m_inc, dpp++) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp+=row_gap, sp+=n_inc) { val = sp->ival; if (val < 0) *dp = ((-val)<<upshift) | KDU_INT32_MIN; else *dp = val<<upshift; } } else { // Source data is true floating point values. float val; float scale = (1.0F / delta); if (K_max <= 31) scale *= (float)(1<<(31-K_max)); else scale /= (float)(1<<(K_max-31)); // Can't decode all planes if (!block->transpose) for (m=xfer_size.y; m--; spp+=m_inc, dpp+=row_gap) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp++, sp+=n_inc) { val = scale * sp->fval; if (val < 0.0F) *dp = ((kdu_int32)(-val)) | KDU_INT32_MIN; else *dp = (kdu_int32) val; } else for (m=xfer_size.y; m--; spp+=m_inc, dpp++) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp+=row_gap, sp+=n_inc) { val = scale * sp->fval; if (val < 0.0F) *dp = ((kdu_int32)(-val)) | KDU_INT32_MIN; else *dp = (kdu_int32) val; } } } else { // Working with 16-bit source data. kdu_sample16 *sp, **spp=lines16+m_start; if (reversible) { // Source data is 16-bit absolute integers. kdu_int32 val; kdu_int32 upshift = 31-K_max; assert(upshift >= 0); // Otherwise should not have chosen 16 bits if (!block->transpose) for (m=xfer_size.y; m--; spp+=m_inc, dpp+=row_gap) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp++, sp+=n_inc) { val = sp->ival; if (val < 0) *dp = ((-val)<<upshift) | KDU_INT32_MIN; else *dp = val<<upshift; } else for (m=xfer_size.y; m--; spp+=m_inc, dpp++) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp+=row_gap, sp+=n_inc) { val = sp->ival; if (val < 0) *dp = ((-val)<<upshift) | KDU_INT32_MIN; else *dp = val<<upshift; } } else { // Source data is 16-bit fixed point integers. float fscale = 1.0F / (delta * (float)(1<<KDU_FIX_POINT)); if (K_max <= 31) fscale *= (float)(1<<(31-K_max)); else fscale /= (float)(1<<(K_max-31)); kdu_int32 val, scale = (kdu_int32)(fscale+0.5F); if (!block->transpose) for (m=xfer_size.y; m--; spp+=m_inc, dpp+=row_gap) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp++, sp+=n_inc) { val = sp->ival; val *= scale; if (val < 0.0F) *dp = ((kdu_int32)(-val)) | KDU_INT32_MIN; else *dp = (kdu_int32) val; } else for (m=xfer_size.y; m--; spp+=m_inc, dpp++) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp+=row_gap, sp+=n_inc) { val = sp->ival; val *= scale; if (val < 0.0F) *dp = ((kdu_int32)(-val)) | KDU_INT32_MIN; else *dp = (kdu_int32) val; } } } // Now check to see if any ROI up-shift has been specified. If so, // we need to zero out sufficient LSB's to ensure that the foreground // and background regions do not get confused. if (K_max_prime > K_max) { dpp = block->sample_buffer; kdu_int32 mask = ((kdu_int32)(-1)) << (31-K_max); if ((K_max_prime - K_max) < K_max) { kdu_error e; e << "You have selected too small a value for " "the ROI up-shift parameter. The up-shift should be " "at least as large as the largest number of magnitude " "bit-planes in any subband; otherwise, the foreground and " "background regions might not be properly distinguished by " "the decompressor."; } if (!block->transpose) for (m=xfer_size.y; m--; dpp+=row_gap) for (dp=dpp, n=xfer_size.x; n--; dp++) *dp &= mask; else for (m=xfer_size.x; m--; dpp+=row_gap) for (dp=dpp, n=xfer_size.y; n--; dp++) *dp &= mask; } // Now transfer any ROI information which may be available. bool have_background = false; // If no background, code less bit-planes. bool have_foreground = false; // If no foreground, no extra MSE weighting if ((roi_lines != NULL) && (K_max_prime != K_max)) { dpp = block->sample_buffer; kdu_byte *sp, **spp=roi_lines+m_start; kdu_int32 val; kdu_int32 downshift = K_max_prime - K_max; assert(downshift >= K_max); if (!block->transpose) { for (m=xfer_size.y; m--; spp+=m_inc, dpp+=row_gap) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp++, sp+=n_inc) if (*sp == 0) { // Adjust background samples down. have_background = true; val = *dp; *dp = (val & KDU_INT32_MIN) | ((val & KDU_INT32_MAX) >> downshift); } else have_foreground = true; } else { for (m=xfer_size.y; m--; spp+=m_inc, dpp++) for (sp=(*spp)+n_start, dp=dpp, n=xfer_size.x; n--; dp+=row_gap, sp+=n_inc) if (*sp == 0) { // Adjust background samples down. have_background = true; val = *dp; *dp = (val & KDU_INT32_MIN) | ((val & KDU_INT32_MAX) >> downshift); } else have_foreground = true; } } else if (roi_lines != NULL) { kdu_byte *sp, **spp=roi_lines+m_start; for (m=xfer_size.y; m--; spp+=m_inc) for (sp=(*spp)+n_start, n=xfer_size.x; n--; sp+=n_inc) if (*sp != 0) { have_foreground = true; m=0; break; } } else have_foreground = true; // Finally, we can encode the block. int K = (have_background)?K_max_prime:K_max; K = (K>31)?31:K; block->missing_msbs = find_missing_msbs(block->sample_buffer,block->size.y,block->size.x); if (block->missing_msbs >= K) { block->missing_msbs = K; block->num_passes = 0; } else { K -= block->missing_msbs; block->num_passes = 3*K-2; } double block_msb_wmse = (have_foreground)?(msb_wmse*roi_weight):msb_wmse; block_encoder.encode(block,reversible,block_msb_wmse, estimated_slope_threshold); band.close_block(block); } // Update the buffer state to reflect what we have just done. block_indices.pos.y++; block_indices.size.y--; next_buffered_row = 0; current_block_height = nominal_block_height; if (current_block_height > subband_rows) current_block_height = subband_rows;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -